mb/google/brya: Create rull variant
[coreboot2.git] / src / vendorcode / wuffs / wuffs-v0.4.c
blob0c6616a652b71edd223301a48ca3742705ed6929
1 #ifndef WUFFS_INCLUDE_GUARD
2 #define WUFFS_INCLUDE_GUARD
4 // Wuffs ships as a "single file C library" or "header file library" as per
5 // https://github.com/nothings/stb/blob/master/docs/stb_howto.txt
6 //
7 // To use that single file as a "foo.c"-like implementation, instead of a
8 // "foo.h"-like header, #define WUFFS_IMPLEMENTATION before #include'ing or
9 // compiling it.
11 // Wuffs' C code is generated automatically, not hand-written. These warnings'
12 // costs outweigh the benefits.
14 // The "elif defined(__clang__)" isn't redundant. While vanilla clang defines
15 // __GNUC__, clang-cl (which mimics MSVC's cl.exe) does not.
16 #if defined(__GNUC__)
17 #pragma GCC diagnostic push
18 #pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
19 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
20 #pragma GCC diagnostic ignored "-Wunreachable-code"
21 #pragma GCC diagnostic ignored "-Wunused-function"
22 #pragma GCC diagnostic ignored "-Wunused-parameter"
23 #if defined(__cplusplus)
24 #pragma GCC diagnostic ignored "-Wold-style-cast"
25 #endif
26 #elif defined(__clang__)
27 #pragma clang diagnostic push
28 #pragma clang diagnostic ignored "-Wimplicit-fallthrough"
29 #pragma clang diagnostic ignored "-Wmissing-field-initializers"
30 #pragma clang diagnostic ignored "-Wunreachable-code"
31 #pragma clang diagnostic ignored "-Wunused-function"
32 #pragma clang diagnostic ignored "-Wunused-parameter"
33 #if defined(__cplusplus)
34 #pragma clang diagnostic ignored "-Wold-style-cast"
35 #endif
36 #endif
38 // Copyright 2017 The Wuffs Authors.
40 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
41 // https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
42 // <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
43 // option. This file may not be copied, modified, or distributed
44 // except according to those terms.
46 // SPDX-License-Identifier: Apache-2.0 OR MIT
48 #include <stdbool.h>
49 #include <stdint.h>
50 #include <stdlib.h>
51 #include <string.h>
53 #ifdef __cplusplus
54 #if (__cplusplus >= 201103L) || defined(_MSC_VER)
55 #include <memory>
56 #define WUFFS_BASE__HAVE_EQ_DELETE
57 #define WUFFS_BASE__HAVE_UNIQUE_PTR
58 // The "defined(__clang__)" isn't redundant. While vanilla clang defines
59 // __GNUC__, clang-cl (which mimics MSVC's cl.exe) does not.
60 #elif defined(__GNUC__) || defined(__clang__)
61 #warning "Wuffs' C++ code expects -std=c++11 or later"
62 #endif
64 extern "C" {
65 #endif
67 // ---------------- Version
69 // WUFFS_VERSION is the major.minor.patch version, as per https://semver.org/,
70 // as a uint64_t. The major number is the high 32 bits. The minor number is the
71 // middle 16 bits. The patch number is the low 16 bits. The pre-release label
72 // and build metadata are part of the string representation (such as
73 // "1.2.3-beta+456.20181231") but not the uint64_t representation.
75 // WUFFS_VERSION_PRE_RELEASE_LABEL (such as "", "beta" or "rc.1") being
76 // non-empty denotes a developer preview, not a release version, and has no
77 // backwards or forwards compatibility guarantees.
79 // WUFFS_VERSION_BUILD_METADATA_XXX, if non-zero, are the number of commits and
80 // the last commit date in the repository used to build this library. Within
81 // each major.minor branch, the commit count should increase monotonically.
83 // WUFFS_VERSION was overridden by "wuffs gen -version" based on revision
84 // 5d69840f8e7ca481551b02c7e8d4c5fb69521bb9 committed on 2024-08-12.
85 #define WUFFS_VERSION 0x000040000
86 #define WUFFS_VERSION_MAJOR 0
87 #define WUFFS_VERSION_MINOR 4
88 #define WUFFS_VERSION_PATCH 0
89 #define WUFFS_VERSION_PRE_RELEASE_LABEL "alpha.8"
90 #define WUFFS_VERSION_BUILD_METADATA_COMMIT_COUNT 3796
91 #define WUFFS_VERSION_BUILD_METADATA_COMMIT_DATE 20240812
92 #define WUFFS_VERSION_STRING "0.4.0-alpha.8+3796.20240812"
94 // ---------------- Private Implementation Macros Re-definition Check
96 // Users (those who #include the "wuffs-vM.N.c" file) should not define any
97 // WUFFS_PRIVATE_IMPL__ETC macros, only WUFFS_CONFIG__ETC macros (and
98 // WUFFS_IMPLEMENTATION). Mucking about with the private implementation macros
99 // is not supported and may break when upgrading to newer Wuffs versions.
101 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_CRC32) || \
102 defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON) || \
103 defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64) || \
104 defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) || \
105 defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3) || \
106 defined(WUFFS_PRIVATE_IMPL__HPD__DECIMAL_POINT__RANGE) || \
107 defined(WUFFS_PRIVATE_IMPL__HPD__DIGITS_PRECISION) || \
108 defined(WUFFS_PRIVATE_IMPL__HPD__SHIFT__MAX_INCL) || \
109 defined(WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U16) || \
110 defined(WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U32) || \
111 defined(WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U64) || \
112 defined(WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U8)
114 #if defined(__GNUC__) || defined(__clang__)
115 #warning "Defining WUFFS_PRIVATE_IMPL__ETC yourself is not supported"
116 #elif defined(_MSC_VER)
117 #pragma message("Defining WUFFS_PRIVATE_IMPL__ETC yourself is not supported")
118 #endif
120 #endif
122 // ---------------- Configuration
124 // Define WUFFS_CONFIG__AVOID_CPU_ARCH to avoid any code tied to a specific CPU
125 // architecture, such as SSE SIMD for the x86 CPU family.
126 #if defined(WUFFS_CONFIG__AVOID_CPU_ARCH) // (#if-chain ref AVOID_CPU_ARCH_0)
127 // No-op.
128 #else // (#if-chain ref AVOID_CPU_ARCH_0)
130 // The "defined(__clang__)" isn't redundant. While vanilla clang defines
131 // __GNUC__, clang-cl (which mimics MSVC's cl.exe) does not.
132 #if defined(__GNUC__) || defined(__clang__)
133 #define WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET(arg) __attribute__((target(arg)))
134 #else
135 #define WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET(arg)
136 #endif // defined(__GNUC__) || defined(__clang__)
138 #if defined(__GNUC__) // (#if-chain ref AVOID_CPU_ARCH_1)
140 // To simplify Wuffs code, "cpu_arch >= arm_xxx" requires xxx but also
141 // unaligned little-endian load/stores.
142 #if defined(__ARM_FEATURE_UNALIGNED) && !defined(__native_client__) && \
143 defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
144 // Not all gcc versions define __ARM_ACLE, even if they support crc32
145 // intrinsics. Look for __ARM_FEATURE_CRC32 instead.
146 #if defined(__ARM_FEATURE_CRC32)
147 #include <arm_acle.h>
148 #define WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_CRC32
149 #endif // defined(__ARM_FEATURE_CRC32)
150 #if defined(__ARM_NEON)
151 #include <arm_neon.h>
152 #define WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON
153 #endif // defined(__ARM_NEON)
154 #endif // defined(__ARM_FEATURE_UNALIGNED) etc
156 // Similarly, "cpu_arch >= x86_sse42" requires SSE4.2 but also PCLMUL and
157 // POPCNT. This is checked at runtime via cpuid, not at compile time.
159 // Likewise, "cpu_arch >= x86_avx2" also requires PCLMUL, POPCNT and SSE4.2.
161 // ----
163 // Technically, we could use the SSE family on 32-bit x86, not just 64-bit x86.
164 // But some intrinsics don't compile in 32-bit mode. It's not worth the hassle.
165 // https://github.com/google/wuffs/issues/145
166 #if defined(__x86_64__)
167 #if !defined(__native_client__)
168 #include <cpuid.h>
169 #include <x86intrin.h>
170 #define WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64
171 #define WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2
172 #define WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3
173 #endif // !defined(__native_client__)
174 #endif // defined(__x86_64__)
176 #elif defined(_MSC_VER) // (#if-chain ref AVOID_CPU_ARCH_1)
178 #if defined(_M_X64)
180 // On X86_64, Microsoft Visual C/C++ (MSVC) only supports SSE2 by default.
181 // There are /arch:SSE2, /arch:AVX and /arch:AVX2 compiler flags (the AVX2 one
182 // is roughly equivalent to X86_64_V3), but there is no /arch:SSE42 compiler
183 // flag that's equivalent to X86_64_V2.
185 // For getting maximum performance with X86_64 MSVC and Wuffs, pass /arch:AVX2
186 // (and then test on the oldest hardware you intend to support).
188 // Absent that compiler flag, either define one of the three macros listed
189 // below or else the X86_64 SIMD code will be disabled and you'll get a #pragma
190 // message stating this library "performs best with /arch:AVX2". This message
191 // is harmless and ignorable, in that the non-SIMD code is still correct and
192 // reasonably performant, but is a reminder that when combining Wuffs and MSVC,
193 // some compiler configuration is required for maximum performance.
195 // - WUFFS_CONFIG__DISABLE_MSVC_CPU_ARCH__X86_64_FAMILY
196 // - WUFFS_CONFIG__ENABLE_MSVC_CPU_ARCH__X86_64_V2 (enables SSE4.2 and below)
197 // - WUFFS_CONFIG__ENABLE_MSVC_CPU_ARCH__X86_64_V3 (enables AVX2 and below)
199 // Defining the first one (WUFFS_CONFIG__DISABLE_MSVC_CPU_ARCH__X86_64_FAMILY)
200 // or defining none of those three (the default state) are equivalent (in that
201 // both disable the SIMD code paths), other than that pragma message.
203 // When defining these WUFFS_CONFIG__ENABLE_ETC macros with MSVC, be aware that
204 // some users report it leading to ICEs (Internal Compiler Errors), but other
205 // users report no problems at all (and improved performance). It's unclear
206 // exactly what combination of SIMD code and MSVC configuration lead to ICEs.
207 // Do your own testing with your own MSVC version and configuration.
209 // https://github.com/google/wuffs/issues/148
210 // https://github.com/google/wuffs/issues/151
211 // https://developercommunity.visualstudio.com/t/fatal--error-C1001:-Internal-compiler-er/10703305
213 // Clang (including clang-cl) and GCC don't need this WUFFS_CONFIG__ETC macro
214 // machinery, or having the Wuffs-the-library user to fiddle with compiler
215 // flags, because they support "__attribute__((target(arg)))".
216 #if defined(__AVX2__) || defined(__clang__) || \
217 defined(WUFFS_CONFIG__ENABLE_MSVC_CPU_ARCH__X86_64_V3)
218 #define WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64
219 #define WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2
220 #define WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3
221 #elif defined(WUFFS_CONFIG__ENABLE_MSVC_CPU_ARCH__X86_64_V2)
222 #define WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64
223 #define WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2
224 #elif !defined(WUFFS_CONFIG__DISABLE_MSVC_CPU_ARCH__X86_64_FAMILY)
225 #pragma message("Wuffs with MSVC+X64 performs best with /arch:AVX2")
226 #endif // defined(__AVX2__) || defined(__clang__) || etc
228 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64)
230 #if defined(WUFFS_CONFIG__DISABLE_MSVC_CPU_ARCH__X86_64_FAMILY)
231 #error "MSVC_CPU_ARCH simultaneously enabled and disabled"
232 #endif
234 #include <intrin.h>
235 // intrin.h isn't enough for X64 SIMD, with clang-cl, if we want to use
236 // "__attribute__((target(arg)))" without e.g. "/arch:AVX".
238 // Some web pages suggest that <immintrin.h> is all you need, as it pulls in
239 // the earlier SIMD families like SSE4.2, but that doesn't seem to work in
240 // practice, possibly for the same reason that just <intrin.h> doesn't work.
241 #include <immintrin.h> // AVX, AVX2, FMA, POPCNT
242 #include <nmmintrin.h> // SSE4.2
243 #include <wmmintrin.h> // AES, PCLMUL
245 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64)
246 #endif // defined(_M_X64)
247 #endif // (#if-chain ref AVOID_CPU_ARCH_1)
248 #endif // (#if-chain ref AVOID_CPU_ARCH_0)
250 // --------
252 // Define WUFFS_CONFIG__STATIC_FUNCTIONS (combined with WUFFS_IMPLEMENTATION)
253 // to make all of Wuffs' functions have static storage.
255 // This can help the compiler ignore or discard unused code, which can produce
256 // faster compiles and smaller binaries. Other motivations are discussed in the
257 // "ALLOW STATIC IMPLEMENTATION" section of
258 // https://raw.githubusercontent.com/nothings/stb/master/docs/stb_howto.txt
259 #if defined(WUFFS_CONFIG__STATIC_FUNCTIONS)
260 #define WUFFS_BASE__MAYBE_STATIC static
261 #else
262 #define WUFFS_BASE__MAYBE_STATIC
263 #endif // defined(WUFFS_CONFIG__STATIC_FUNCTIONS)
265 // ---------------- CPU Architecture
267 static inline bool //
268 wuffs_base__cpu_arch__have_arm_crc32(void) {
269 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_CRC32)
270 return true;
271 #else
272 return false;
273 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_CRC32)
276 static inline bool //
277 wuffs_base__cpu_arch__have_arm_neon(void) {
278 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON)
279 return true;
280 #else
281 return false;
282 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON)
285 static inline bool //
286 wuffs_base__cpu_arch__have_x86_avx2(void) {
287 #if defined(__PCLMUL__) && defined(__POPCNT__) && defined(__SSE4_2__) && \
288 defined(__AVX2__)
289 return true;
290 #else
291 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64)
292 // GCC defines these macros but MSVC does not.
293 // - bit_AVX2 = (1 << 5)
294 const unsigned int avx2_ebx7 = 0x00000020;
295 // GCC defines these macros but MSVC does not.
296 // - bit_PCLMUL = (1 << 1)
297 // - bit_POPCNT = (1 << 23)
298 // - bit_SSE4_2 = (1 << 20)
299 const unsigned int avx2_ecx1 = 0x00900002;
301 // clang defines __GNUC__ and clang-cl defines _MSC_VER (but not __GNUC__).
302 #if defined(__GNUC__)
303 unsigned int eax7 = 0;
304 unsigned int ebx7 = 0;
305 unsigned int ecx7 = 0;
306 unsigned int edx7 = 0;
307 if (__get_cpuid_count(7, 0, &eax7, &ebx7, &ecx7, &edx7) &&
308 ((ebx7 & avx2_ebx7) == avx2_ebx7)) {
309 unsigned int eax1 = 0;
310 unsigned int ebx1 = 0;
311 unsigned int ecx1 = 0;
312 unsigned int edx1 = 0;
313 if (__get_cpuid(1, &eax1, &ebx1, &ecx1, &edx1) &&
314 ((ecx1 & avx2_ecx1) == avx2_ecx1)) {
315 return true;
318 #elif defined(_MSC_VER) // defined(__GNUC__)
319 int x7[4];
320 __cpuidex(x7, 7, 0);
321 if ((((unsigned int)(x7[1])) & avx2_ebx7) == avx2_ebx7) {
322 int x1[4];
323 __cpuid(x1, 1);
324 if ((((unsigned int)(x1[2])) & avx2_ecx1) == avx2_ecx1) {
325 return true;
328 #else
329 #error "WUFFS_PRIVATE_IMPL__CPU_ARCH__ETC combined with an unsupported compiler"
330 #endif // defined(__GNUC__); defined(_MSC_VER)
331 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64)
332 return false;
333 #endif // defined(__PCLMUL__) && defined(__POPCNT__) && defined(__SSE4_2__) &&
334 // defined(__AVX2__)
337 static inline bool //
338 wuffs_base__cpu_arch__have_x86_bmi2(void) {
339 #if defined(__BMI2__)
340 return true;
341 #else
342 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64)
343 // GCC defines these macros but MSVC does not.
344 // - bit_BMI2 = (1 << 8)
345 const unsigned int bmi2_ebx7 = 0x00000100;
347 // clang defines __GNUC__ and clang-cl defines _MSC_VER (but not __GNUC__).
348 #if defined(__GNUC__)
349 unsigned int eax7 = 0;
350 unsigned int ebx7 = 0;
351 unsigned int ecx7 = 0;
352 unsigned int edx7 = 0;
353 if (__get_cpuid_count(7, 0, &eax7, &ebx7, &ecx7, &edx7) &&
354 ((ebx7 & bmi2_ebx7) == bmi2_ebx7)) {
355 return true;
357 #elif defined(_MSC_VER) // defined(__GNUC__)
358 int x7[4];
359 __cpuidex(x7, 7, 0);
360 if ((((unsigned int)(x7[1])) & bmi2_ebx7) == bmi2_ebx7) {
361 return true;
363 #else
364 #error "WUFFS_PRIVATE_IMPL__CPU_ARCH__ETC combined with an unsupported compiler"
365 #endif // defined(__GNUC__); defined(_MSC_VER)
366 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64)
367 return false;
368 #endif // defined(__BMI2__)
371 static inline bool //
372 wuffs_base__cpu_arch__have_x86_sse42(void) {
373 #if defined(__PCLMUL__) && defined(__POPCNT__) && defined(__SSE4_2__)
374 return true;
375 #else
376 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64)
377 // GCC defines these macros but MSVC does not.
378 // - bit_PCLMUL = (1 << 1)
379 // - bit_POPCNT = (1 << 23)
380 // - bit_SSE4_2 = (1 << 20)
381 const unsigned int sse42_ecx1 = 0x00900002;
383 // clang defines __GNUC__ and clang-cl defines _MSC_VER (but not __GNUC__).
384 #if defined(__GNUC__)
385 unsigned int eax1 = 0;
386 unsigned int ebx1 = 0;
387 unsigned int ecx1 = 0;
388 unsigned int edx1 = 0;
389 if (__get_cpuid(1, &eax1, &ebx1, &ecx1, &edx1) &&
390 ((ecx1 & sse42_ecx1) == sse42_ecx1)) {
391 return true;
393 #elif defined(_MSC_VER) // defined(__GNUC__)
394 int x1[4];
395 __cpuid(x1, 1);
396 if ((((unsigned int)(x1[2])) & sse42_ecx1) == sse42_ecx1) {
397 return true;
399 #else
400 #error "WUFFS_PRIVATE_IMPL__CPU_ARCH__ETC combined with an unsupported compiler"
401 #endif // defined(__GNUC__); defined(_MSC_VER)
402 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64)
403 return false;
404 #endif // defined(__PCLMUL__) && defined(__POPCNT__) && defined(__SSE4_2__)
407 // ---------------- Fundamentals
409 // Wuffs assumes that:
410 // - converting a uint32_t to a size_t will never overflow.
411 // - converting a size_t to a uint64_t will never overflow.
412 #if defined(__WORDSIZE)
413 #if (__WORDSIZE != 32) && (__WORDSIZE != 64)
414 #error "Wuffs requires a word size of either 32 or 64 bits"
415 #endif
416 #endif
418 // The "defined(__clang__)" isn't redundant. While vanilla clang defines
419 // __GNUC__, clang-cl (which mimics MSVC's cl.exe) does not.
420 #if defined(__GNUC__) || defined(__clang__)
421 #define WUFFS_BASE__FORCE_INLINE __attribute__((__always_inline__))
422 #define WUFFS_BASE__POTENTIALLY_UNUSED __attribute__((unused))
423 #define WUFFS_BASE__WARN_UNUSED_RESULT __attribute__((warn_unused_result))
424 #elif defined(_MSC_VER)
425 #define WUFFS_BASE__FORCE_INLINE __forceinline
426 #define WUFFS_BASE__POTENTIALLY_UNUSED
427 #define WUFFS_BASE__WARN_UNUSED_RESULT
428 #else
429 #define WUFFS_BASE__FORCE_INLINE
430 #define WUFFS_BASE__POTENTIALLY_UNUSED
431 #define WUFFS_BASE__WARN_UNUSED_RESULT
432 #endif
434 // Clang's "-fsanitize=integer" checks for "unsigned-integer-overflow" even
435 // though, for *unsigned* integers, it is *not* undefined behavior. The check
436 // is still made because unsigned integer overflow "is often unintentional".
437 // https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html
439 // However, for Wuffs' generated C code, unsigned overflow is intentional. The
440 // programmer has to use "~mod+" instead of a plain "+" operator in Wuffs code.
441 // Further runtime checks for unsigned integer overflow can add performance
442 // overhead (fuzzers can then time out) and can raise false negatives, without
443 // generating much benefits. We disable the "unsigned-integer-overflow" check.
444 #if defined(__has_feature)
445 #if __has_feature(undefined_behavior_sanitizer)
446 #define WUFFS_BASE__GENERATED_C_CODE \
447 __attribute__((no_sanitize("unsigned-integer-overflow")))
448 #endif
449 #endif
450 #if !defined(WUFFS_BASE__GENERATED_C_CODE)
451 #define WUFFS_BASE__GENERATED_C_CODE
452 #endif
454 // --------
456 // Options (bitwise or'ed together) for wuffs_foo__bar__initialize functions.
458 #define WUFFS_INITIALIZE__DEFAULT_OPTIONS ((uint32_t)0x00000000)
460 // WUFFS_INITIALIZE__ALREADY_ZEROED means that the "self" receiver struct value
461 // has already been set to all zeroes.
462 #define WUFFS_INITIALIZE__ALREADY_ZEROED ((uint32_t)0x00000001)
464 // WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED means that, absent
465 // WUFFS_INITIALIZE__ALREADY_ZEROED, only some of the "self" receiver struct
466 // value will be set to all zeroes. Internal buffers, which tend to be a large
467 // proportion of the struct's size, will be left uninitialized. Internal means
468 // that the buffer is contained by the receiver struct, as opposed to being
469 // passed as a separately allocated "work buffer".
471 // For more detail, see:
472 // https://github.com/google/wuffs/blob/main/doc/note/initialization.md
473 #define WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED \
474 ((uint32_t)0x00000002)
476 // --------
478 #ifdef __cplusplus
479 // Wuffs structs are just data, not resources (in the RAII sense). They don't
480 // subclass anything. They don't have virtual destructors. They don't contain
481 // pointers to dynamically allocated memory. They don't contain file
482 // descriptors. And so on. Destroying such a struct (e.g. via a
483 // wuffs_foo__bar::unique_ptr) can just call free, especially as
484 // sizeof(wuffs_foo__bar) isn't supposed to be part of the public (stable) API.
485 struct wuffs_unique_ptr_deleter {
486 void operator()(void* p) { free(p); }
488 #endif // __cplusplus
490 // --------
492 #if defined(__GNUC__)
493 #pragma GCC diagnostic push
494 #pragma GCC diagnostic ignored "-Wcast-qual"
495 #endif
497 static inline uint8_t* //
498 wuffs_base__strip_const_from_u8_ptr(const uint8_t* ptr) {
499 return (uint8_t*)ptr;
502 static inline uint16_t* //
503 wuffs_base__strip_const_from_u16_ptr(const uint16_t* ptr) {
504 return (uint16_t*)ptr;
507 static inline uint32_t* //
508 wuffs_base__strip_const_from_u32_ptr(const uint32_t* ptr) {
509 return (uint32_t*)ptr;
512 static inline uint64_t* //
513 wuffs_base__strip_const_from_u64_ptr(const uint64_t* ptr) {
514 return (uint64_t*)ptr;
517 #if defined(__GNUC__)
518 #pragma GCC diagnostic pop
519 #endif
521 // --------
523 // wuffs_base__empty_struct is used when a Wuffs function returns an empty
524 // struct. In C, if a function f returns void, you can't say "x = f()", but in
525 // Wuffs, if a function g returns empty, you can say "y = g()".
526 typedef struct wuffs_base__empty_struct__struct {
527 // private_impl is a placeholder field. It isn't explicitly used, except that
528 // without it, the sizeof a struct with no fields can differ across C/C++
529 // compilers, and it is undefined behavior in C99. For example, gcc says that
530 // the sizeof an empty struct is 0, and g++ says that it is 1. This leads to
531 // ABI incompatibility if a Wuffs .c file is processed by one compiler and
532 // its .h file with another compiler.
534 // Instead, we explicitly insert an otherwise unused field, so that the
535 // sizeof this struct is always 1.
536 uint8_t private_impl;
537 } wuffs_base__empty_struct;
539 static inline wuffs_base__empty_struct //
540 wuffs_base__make_empty_struct(void) {
541 wuffs_base__empty_struct ret;
542 ret.private_impl = 0;
543 return ret;
546 // wuffs_base__utility is a placeholder receiver type. It enables what Java
547 // calls static methods, as opposed to regular methods.
548 typedef struct wuffs_base__utility__struct {
549 // private_impl is a placeholder field. It isn't explicitly used, except that
550 // without it, the sizeof a struct with no fields can differ across C/C++
551 // compilers, and it is undefined behavior in C99. For example, gcc says that
552 // the sizeof an empty struct is 0, and g++ says that it is 1. This leads to
553 // ABI incompatibility if a Wuffs .c file is processed by one compiler and
554 // its .h file with another compiler.
556 // Instead, we explicitly insert an otherwise unused field, so that the
557 // sizeof this struct is always 1.
558 uint8_t private_impl;
559 } wuffs_base__utility;
561 typedef struct wuffs_base__vtable__struct {
562 const char* vtable_name;
563 const void* function_pointers;
564 } wuffs_base__vtable;
566 // --------
568 // See https://github.com/google/wuffs/blob/main/doc/note/statuses.md
569 typedef struct wuffs_base__status__struct {
570 const char* repr;
572 #ifdef __cplusplus
573 inline bool is_complete() const;
574 inline bool is_error() const;
575 inline bool is_note() const;
576 inline bool is_ok() const;
577 inline bool is_suspension() const;
578 inline bool is_truncated_input_error() const;
579 inline const char* message() const;
580 #endif // __cplusplus
582 } wuffs_base__status;
584 extern const char wuffs_base__note__i_o_redirect[];
585 extern const char wuffs_base__note__end_of_data[];
586 extern const char wuffs_base__note__metadata_reported[];
587 extern const char wuffs_base__suspension__even_more_information[];
588 extern const char wuffs_base__suspension__mispositioned_read[];
589 extern const char wuffs_base__suspension__mispositioned_write[];
590 extern const char wuffs_base__suspension__short_read[];
591 extern const char wuffs_base__suspension__short_workbuf[];
592 extern const char wuffs_base__suspension__short_write[];
593 extern const char wuffs_base__error__bad_i_o_position[];
594 extern const char wuffs_base__error__bad_argument_length_too_short[];
595 extern const char wuffs_base__error__bad_argument[];
596 extern const char wuffs_base__error__bad_call_sequence[];
597 extern const char wuffs_base__error__bad_data[];
598 extern const char wuffs_base__error__bad_receiver[];
599 extern const char wuffs_base__error__bad_restart[];
600 extern const char wuffs_base__error__bad_sizeof_receiver[];
601 extern const char wuffs_base__error__bad_vtable[];
602 extern const char wuffs_base__error__bad_workbuf_length[];
603 extern const char wuffs_base__error__bad_wuffs_version[];
604 extern const char wuffs_base__error__cannot_return_a_suspension[];
605 extern const char wuffs_base__error__disabled_by_wuffs_config_dst_pixel_format_enable_allowlist[];
606 extern const char wuffs_base__error__disabled_by_previous_error[];
607 extern const char wuffs_base__error__initialize_falsely_claimed_already_zeroed[];
608 extern const char wuffs_base__error__initialize_not_called[];
609 extern const char wuffs_base__error__insufficient_history[];
610 extern const char wuffs_base__error__interleaved_coroutine_calls[];
611 extern const char wuffs_base__error__no_more_information[];
612 extern const char wuffs_base__error__not_enough_data[];
613 extern const char wuffs_base__error__out_of_bounds[];
614 extern const char wuffs_base__error__unsupported_image_dimension[];
615 extern const char wuffs_base__error__unsupported_method[];
616 extern const char wuffs_base__error__unsupported_option[];
617 extern const char wuffs_base__error__unsupported_pixel_swizzler_option[];
618 extern const char wuffs_base__error__too_much_data[];
620 static inline wuffs_base__status //
621 wuffs_base__make_status(const char* repr) {
622 wuffs_base__status z;
623 z.repr = repr;
624 return z;
627 static inline bool //
628 wuffs_base__status__is_complete(const wuffs_base__status* z) {
629 return (z->repr == NULL) || ((*z->repr != '$') && (*z->repr != '#'));
632 static inline bool //
633 wuffs_base__status__is_error(const wuffs_base__status* z) {
634 return z->repr && (*z->repr == '#');
637 static inline bool //
638 wuffs_base__status__is_note(const wuffs_base__status* z) {
639 return z->repr && (*z->repr != '$') && (*z->repr != '#');
642 static inline bool //
643 wuffs_base__status__is_ok(const wuffs_base__status* z) {
644 return z->repr == NULL;
647 static inline bool //
648 wuffs_base__status__is_suspension(const wuffs_base__status* z) {
649 return z->repr && (*z->repr == '$');
652 static inline bool //
653 wuffs_base__status__is_truncated_input_error(const wuffs_base__status* z) {
654 const char* p = z->repr;
655 if (!p || (*p != '#')) {
656 return false;
658 p++;
659 while (1) {
660 if (*p == 0) {
661 return false;
662 } else if (*p++ == ':') {
663 break;
666 return strcmp(p, " truncated input") == 0;
669 // wuffs_base__status__message strips the leading '$', '#' or '@'.
670 static inline const char* //
671 wuffs_base__status__message(const wuffs_base__status* z) {
672 if (z->repr) {
673 if ((*z->repr == '$') || (*z->repr == '#') || (*z->repr == '@')) {
674 return z->repr + 1;
677 return z->repr;
680 #ifdef __cplusplus
682 inline bool //
683 wuffs_base__status::is_complete() const {
684 return wuffs_base__status__is_complete(this);
687 inline bool //
688 wuffs_base__status::is_error() const {
689 return wuffs_base__status__is_error(this);
692 inline bool //
693 wuffs_base__status::is_note() const {
694 return wuffs_base__status__is_note(this);
697 inline bool //
698 wuffs_base__status::is_ok() const {
699 return wuffs_base__status__is_ok(this);
702 inline bool //
703 wuffs_base__status::is_suspension() const {
704 return wuffs_base__status__is_suspension(this);
707 inline bool //
708 wuffs_base__status::is_truncated_input_error() const {
709 return wuffs_base__status__is_truncated_input_error(this);
712 inline const char* //
713 wuffs_base__status::message() const {
714 return wuffs_base__status__message(this);
717 #endif // __cplusplus
719 // --------
721 // WUFFS_BASE__RESULT is a result type: either a status (an error) or a value.
723 // A result with all fields NULL or zero is as valid as a zero-valued T.
724 #define WUFFS_BASE__RESULT(T) \
725 struct { \
726 wuffs_base__status status; \
727 T value; \
730 typedef WUFFS_BASE__RESULT(double) wuffs_base__result_f64;
731 typedef WUFFS_BASE__RESULT(int64_t) wuffs_base__result_i64;
732 typedef WUFFS_BASE__RESULT(uint64_t) wuffs_base__result_u64;
734 // --------
736 // wuffs_base__transform__output is the result of transforming from a src slice
737 // to a dst slice.
738 typedef struct wuffs_base__transform__output__struct {
739 wuffs_base__status status;
740 size_t num_dst;
741 size_t num_src;
742 } wuffs_base__transform__output;
744 // --------
746 // FourCC constants. Four Character Codes are literally four ASCII characters
747 // (sometimes padded with ' ' spaces) that pack neatly into a signed or
748 // unsigned 32-bit integer. ASCII letters are conventionally upper case.
750 // They are often used to identify video codecs (e.g. "H265") and pixel formats
751 // (e.g. "YV12"). Wuffs uses them for that but also generally for naming
752 // various things: compression formats (e.g. "BZ2 "), image metadata (e.g.
753 // "EXIF"), file formats (e.g. "HTML"), etc.
755 // Wuffs' u32 values are big-endian ("JPEG" is 0x4A504547 not 0x4745504A) to
756 // preserve ordering: "JPEG" < "MP3 " and 0x4A504547 < 0x4D503320.
758 // Background Color.
759 #define WUFFS_BASE__FOURCC__BGCL 0x4247434C
761 // Bitmap.
762 #define WUFFS_BASE__FOURCC__BMP 0x424D5020
764 // Brotli.
765 #define WUFFS_BASE__FOURCC__BRTL 0x4252544C
767 // Bzip2.
768 #define WUFFS_BASE__FOURCC__BZ2 0x425A3220
770 // Concise Binary Object Representation.
771 #define WUFFS_BASE__FOURCC__CBOR 0x43424F52
773 // Primary Chromaticities and White Point.
774 #define WUFFS_BASE__FOURCC__CHRM 0x4348524D
776 // Cascading Style Sheets.
777 #define WUFFS_BASE__FOURCC__CSS 0x43535320
779 // Encapsulated PostScript.
780 #define WUFFS_BASE__FOURCC__EPS 0x45505320
782 // Exchangeable Image File Format.
783 #define WUFFS_BASE__FOURCC__EXIF 0x45584946
785 // Free Lossless Audio Codec.
786 #define WUFFS_BASE__FOURCC__FLAC 0x464C4143
788 // Gamma Correction.
789 #define WUFFS_BASE__FOURCC__GAMA 0x47414D41
791 // Graphics Interchange Format.
792 #define WUFFS_BASE__FOURCC__GIF 0x47494620
794 // GNU Zip.
795 #define WUFFS_BASE__FOURCC__GZ 0x475A2020
797 // High Efficiency Image File.
798 #define WUFFS_BASE__FOURCC__HEIF 0x48454946
800 // Hypertext Markup Language.
801 #define WUFFS_BASE__FOURCC__HTML 0x48544D4C
803 // International Color Consortium Profile.
804 #define WUFFS_BASE__FOURCC__ICCP 0x49434350
806 // Icon.
807 #define WUFFS_BASE__FOURCC__ICO 0x49434F20
809 // Icon Vector Graphics.
810 #define WUFFS_BASE__FOURCC__ICVG 0x49435647
812 // Initialization.
813 #define WUFFS_BASE__FOURCC__INI 0x494E4920
815 // Joint Photographic Experts Group.
816 #define WUFFS_BASE__FOURCC__JPEG 0x4A504547
818 // JavaScript.
819 #define WUFFS_BASE__FOURCC__JS 0x4A532020
821 // JavaScript Object Notation.
822 #define WUFFS_BASE__FOURCC__JSON 0x4A534F4E
824 // JSON With Commas and Comments.
825 #define WUFFS_BASE__FOURCC__JWCC 0x4A574343
827 // Key-Value Pair.
828 #define WUFFS_BASE__FOURCC__KVP 0x4B565020
830 // Key-Value Pair (Key).
831 #define WUFFS_BASE__FOURCC__KVPK 0x4B56504B
833 // Key-Value Pair (Value).
834 #define WUFFS_BASE__FOURCC__KVPV 0x4B565056
836 // Lempel–Ziv 4.
837 #define WUFFS_BASE__FOURCC__LZ4 0x4C5A3420
839 // Lzip.
840 #define WUFFS_BASE__FOURCC__LZIP 0x4C5A4950
842 // Lempel–Ziv Markov-chain Algorithm.
843 #define WUFFS_BASE__FOURCC__LZMA 0x4C5A4D41
845 // Markdown.
846 #define WUFFS_BASE__FOURCC__MD 0x4D442020
848 // Modification Time.
849 #define WUFFS_BASE__FOURCC__MTIM 0x4D54494D
851 // MPEG-1 Audio Layer III.
852 #define WUFFS_BASE__FOURCC__MP3 0x4D503320
854 // Naive Image.
855 #define WUFFS_BASE__FOURCC__NIE 0x4E494520
857 // Netpbm (Portable Anymap).
858 #define WUFFS_BASE__FOURCC__NPBM 0x4E50424D
860 // Offset (2-Dimensional).
861 #define WUFFS_BASE__FOURCC__OFS2 0x4F465332
863 // Open Type Format.
864 #define WUFFS_BASE__FOURCC__OTF 0x4F544620
866 // Portable Document Format.
867 #define WUFFS_BASE__FOURCC__PDF 0x50444620
869 // Physical Dimensions.
870 #define WUFFS_BASE__FOURCC__PHYD 0x50485944
872 // Portable Network Graphics.
873 #define WUFFS_BASE__FOURCC__PNG 0x504E4720
875 // PostScript.
876 #define WUFFS_BASE__FOURCC__PS 0x50532020
878 // Quite OK Image.
879 #define WUFFS_BASE__FOURCC__QOI 0x514F4920
881 // Random Access Compression.
882 #define WUFFS_BASE__FOURCC__RAC 0x52414320
884 // Raw.
885 #define WUFFS_BASE__FOURCC__RAW 0x52415720
887 // Resource Interchange File Format.
888 #define WUFFS_BASE__FOURCC__RIFF 0x52494646
890 // Riegeli Records.
891 #define WUFFS_BASE__FOURCC__RIGL 0x5249474C
893 // Snappy.
894 #define WUFFS_BASE__FOURCC__SNPY 0x534E5059
896 // Standard Red Green Blue (Rendering Intent).
897 #define WUFFS_BASE__FOURCC__SRGB 0x53524742
899 // Scalable Vector Graphics.
900 #define WUFFS_BASE__FOURCC__SVG 0x53564720
902 // Tape Archive.
903 #define WUFFS_BASE__FOURCC__TAR 0x54415220
905 // Text.
906 #define WUFFS_BASE__FOURCC__TEXT 0x54455854
908 // Truevision Advanced Raster Graphics Adapter.
909 #define WUFFS_BASE__FOURCC__TGA 0x54474120
911 // Tagged Image File Format.
912 #define WUFFS_BASE__FOURCC__TIFF 0x54494646
914 // Tom's Obvious Minimal Language.
915 #define WUFFS_BASE__FOURCC__TOML 0x544F4D4C
917 // Waveform.
918 #define WUFFS_BASE__FOURCC__WAVE 0x57415645
920 // Wireless Bitmap.
921 #define WUFFS_BASE__FOURCC__WBMP 0x57424D50
923 // Web Picture.
924 #define WUFFS_BASE__FOURCC__WEBP 0x57454250
926 // Web Open Font Format.
927 #define WUFFS_BASE__FOURCC__WOFF 0x574F4646
929 // Extensible Markup Language.
930 #define WUFFS_BASE__FOURCC__XML 0x584D4C20
932 // Extensible Metadata Platform.
933 #define WUFFS_BASE__FOURCC__XMP 0x584D5020
935 // Xz.
936 #define WUFFS_BASE__FOURCC__XZ 0x585A2020
938 // Zip.
939 #define WUFFS_BASE__FOURCC__ZIP 0x5A495020
941 // Zlib.
942 #define WUFFS_BASE__FOURCC__ZLIB 0x5A4C4942
944 // Zstandard.
945 #define WUFFS_BASE__FOURCC__ZSTD 0x5A535444
947 // --------
949 // Quirks.
951 #define WUFFS_BASE__QUIRK_IGNORE_CHECKSUM 1
953 #define WUFFS_BASE__QUIRK_QUALITY 2
955 // --------
957 // Flicks are a unit of time. One flick (frame-tick) is 1 / 705_600_000 of a
958 // second. See https://github.com/OculusVR/Flicks
959 typedef int64_t wuffs_base__flicks;
961 #define WUFFS_BASE__FLICKS_PER_SECOND ((uint64_t)705600000)
962 #define WUFFS_BASE__FLICKS_PER_MILLISECOND ((uint64_t)705600)
964 // ---------------- Numeric Types
966 // The helpers below are functions, instead of macros, because their arguments
967 // can be an expression that we shouldn't evaluate more than once.
969 // They are static, so that linking multiple wuffs .o files won't complain about
970 // duplicate function definitions.
972 // They are explicitly marked inline, even if modern compilers don't use the
973 // inline attribute to guide optimizations such as inlining, to avoid the
974 // -Wunused-function warning, and we like to compile with -Wall -Werror.
976 static inline int8_t //
977 wuffs_base__i8__min(int8_t x, int8_t y) {
978 return x < y ? x : y;
981 static inline int8_t //
982 wuffs_base__i8__max(int8_t x, int8_t y) {
983 return x > y ? x : y;
986 static inline int16_t //
987 wuffs_base__i16__min(int16_t x, int16_t y) {
988 return x < y ? x : y;
991 static inline int16_t //
992 wuffs_base__i16__max(int16_t x, int16_t y) {
993 return x > y ? x : y;
996 static inline int32_t //
997 wuffs_base__i32__min(int32_t x, int32_t y) {
998 return x < y ? x : y;
1001 static inline int32_t //
1002 wuffs_base__i32__max(int32_t x, int32_t y) {
1003 return x > y ? x : y;
1006 static inline int64_t //
1007 wuffs_base__i64__min(int64_t x, int64_t y) {
1008 return x < y ? x : y;
1011 static inline int64_t //
1012 wuffs_base__i64__max(int64_t x, int64_t y) {
1013 return x > y ? x : y;
1016 static inline uint8_t //
1017 wuffs_base__u8__min(uint8_t x, uint8_t y) {
1018 return x < y ? x : y;
1021 static inline uint8_t //
1022 wuffs_base__u8__max(uint8_t x, uint8_t y) {
1023 return x > y ? x : y;
1026 static inline uint16_t //
1027 wuffs_base__u16__min(uint16_t x, uint16_t y) {
1028 return x < y ? x : y;
1031 static inline uint16_t //
1032 wuffs_base__u16__max(uint16_t x, uint16_t y) {
1033 return x > y ? x : y;
1036 static inline uint32_t //
1037 wuffs_base__u32__min(uint32_t x, uint32_t y) {
1038 return x < y ? x : y;
1041 static inline uint32_t //
1042 wuffs_base__u32__max(uint32_t x, uint32_t y) {
1043 return x > y ? x : y;
1046 static inline uint64_t //
1047 wuffs_base__u64__min(uint64_t x, uint64_t y) {
1048 return x < y ? x : y;
1051 static inline uint64_t //
1052 wuffs_base__u64__max(uint64_t x, uint64_t y) {
1053 return x > y ? x : y;
1056 // --------
1058 static inline uint8_t //
1059 wuffs_base__u8__rotate_left(uint8_t x, uint32_t n) {
1060 n &= 7;
1061 return ((uint8_t)(x << n)) | ((uint8_t)(x >> (8 - n)));
1064 static inline uint8_t //
1065 wuffs_base__u8__rotate_right(uint8_t x, uint32_t n) {
1066 n &= 7;
1067 return ((uint8_t)(x >> n)) | ((uint8_t)(x << (8 - n)));
1070 static inline uint16_t //
1071 wuffs_base__u16__rotate_left(uint16_t x, uint32_t n) {
1072 n &= 15;
1073 return ((uint16_t)(x << n)) | ((uint16_t)(x >> (16 - n)));
1076 static inline uint16_t //
1077 wuffs_base__u16__rotate_right(uint16_t x, uint32_t n) {
1078 n &= 15;
1079 return ((uint16_t)(x >> n)) | ((uint16_t)(x << (16 - n)));
1082 static inline uint32_t //
1083 wuffs_base__u32__rotate_left(uint32_t x, uint32_t n) {
1084 n &= 31;
1085 return ((uint32_t)(x << n)) | ((uint32_t)(x >> (32 - n)));
1088 static inline uint32_t //
1089 wuffs_base__u32__rotate_right(uint32_t x, uint32_t n) {
1090 n &= 31;
1091 return ((uint32_t)(x >> n)) | ((uint32_t)(x << (32 - n)));
1094 static inline uint64_t //
1095 wuffs_base__u64__rotate_left(uint64_t x, uint32_t n) {
1096 n &= 63;
1097 return ((uint64_t)(x << n)) | ((uint64_t)(x >> (64 - n)));
1100 static inline uint64_t //
1101 wuffs_base__u64__rotate_right(uint64_t x, uint32_t n) {
1102 n &= 63;
1103 return ((uint64_t)(x >> n)) | ((uint64_t)(x << (64 - n)));
1106 // --------
1108 // Saturating arithmetic (sat_add, sat_sub) branchless bit-twiddling algorithms
1109 // are per https://locklessinc.com/articles/sat_arithmetic/
1111 // It is important that the underlying types are unsigned integers, as signed
1112 // integer arithmetic overflow is undefined behavior in C.
1114 static inline uint8_t //
1115 wuffs_base__u8__sat_add(uint8_t x, uint8_t y) {
1116 uint8_t res = (uint8_t)(x + y);
1117 res |= (uint8_t)(-(res < x));
1118 return res;
1121 static inline uint8_t //
1122 wuffs_base__u8__sat_sub(uint8_t x, uint8_t y) {
1123 uint8_t res = (uint8_t)(x - y);
1124 res &= (uint8_t)(-(res <= x));
1125 return res;
1128 static inline uint16_t //
1129 wuffs_base__u16__sat_add(uint16_t x, uint16_t y) {
1130 uint16_t res = (uint16_t)(x + y);
1131 res |= (uint16_t)(-(res < x));
1132 return res;
1135 static inline uint16_t //
1136 wuffs_base__u16__sat_sub(uint16_t x, uint16_t y) {
1137 uint16_t res = (uint16_t)(x - y);
1138 res &= (uint16_t)(-(res <= x));
1139 return res;
1142 static inline uint32_t //
1143 wuffs_base__u32__sat_add(uint32_t x, uint32_t y) {
1144 uint32_t res = (uint32_t)(x + y);
1145 res |= (uint32_t)(-(res < x));
1146 return res;
1149 static inline uint32_t //
1150 wuffs_base__u32__sat_sub(uint32_t x, uint32_t y) {
1151 uint32_t res = (uint32_t)(x - y);
1152 res &= (uint32_t)(-(res <= x));
1153 return res;
1156 static inline uint64_t //
1157 wuffs_base__u64__sat_add(uint64_t x, uint64_t y) {
1158 uint64_t res = (uint64_t)(x + y);
1159 res |= (uint64_t)(-(res < x));
1160 return res;
1163 static inline uint64_t //
1164 wuffs_base__u64__sat_sub(uint64_t x, uint64_t y) {
1165 uint64_t res = (uint64_t)(x - y);
1166 res &= (uint64_t)(-(res <= x));
1167 return res;
1170 // --------
1172 typedef struct wuffs_base__multiply_u64__output__struct {
1173 uint64_t lo;
1174 uint64_t hi;
1175 } wuffs_base__multiply_u64__output;
1177 // wuffs_base__multiply_u64 returns x*y as a 128-bit value.
1179 // The maximum inclusive output hi_lo is 0xFFFFFFFFFFFFFFFE_0000000000000001.
1180 static inline wuffs_base__multiply_u64__output //
1181 wuffs_base__multiply_u64(uint64_t x, uint64_t y) {
1182 #if defined(__SIZEOF_INT128__)
1183 __uint128_t z = ((__uint128_t)x) * ((__uint128_t)y);
1184 wuffs_base__multiply_u64__output o;
1185 o.lo = ((uint64_t)(z));
1186 o.hi = ((uint64_t)(z >> 64));
1187 return o;
1188 #else
1189 // TODO: consider using the _mul128 intrinsic if defined(_MSC_VER).
1190 uint64_t x0 = x & 0xFFFFFFFF;
1191 uint64_t x1 = x >> 32;
1192 uint64_t y0 = y & 0xFFFFFFFF;
1193 uint64_t y1 = y >> 32;
1194 uint64_t w0 = x0 * y0;
1195 uint64_t t = (x1 * y0) + (w0 >> 32);
1196 uint64_t w1 = t & 0xFFFFFFFF;
1197 uint64_t w2 = t >> 32;
1198 w1 += x0 * y1;
1199 wuffs_base__multiply_u64__output o;
1200 o.lo = x * y;
1201 o.hi = (x1 * y1) + w2 + (w1 >> 32);
1202 return o;
1203 #endif
1206 // --------
1208 typedef struct wuffs_base__bitvec256__struct {
1209 // elements_u64[0] holds the LSBs (least significant bits) and
1210 // elements_u64[3] holds the MSBs (most significant bits).
1211 uint64_t elements_u64[4];
1212 } wuffs_base__bitvec256;
1214 static inline wuffs_base__bitvec256 //
1215 wuffs_base__make_bitvec256(uint64_t e00,
1216 uint64_t e01,
1217 uint64_t e02,
1218 uint64_t e03) {
1219 wuffs_base__bitvec256 res;
1220 res.elements_u64[0] = e00;
1221 res.elements_u64[1] = e01;
1222 res.elements_u64[2] = e02;
1223 res.elements_u64[3] = e03;
1224 return res;
1227 static inline uint64_t //
1228 wuffs_base__bitvec256__get_u64(const wuffs_base__bitvec256* b, uint32_t i) {
1229 return b->elements_u64[i & 3];
1232 // --------
1234 // wuffs_base__optional_u63 is like a std::optional<uint64_t>, but for C (not
1235 // just C++) and the value can only hold 63 bits (not 64).
1237 // Do not manipulate repr directly; it is a private implementation detail.
1238 typedef struct wuffs_base__optional_u63__struct {
1239 uint64_t repr;
1241 #ifdef __cplusplus
1242 inline bool has_value() const;
1243 inline uint64_t value() const;
1244 inline uint64_t value_or(uint64_t default_value) const;
1245 #endif // __cplusplus
1247 } wuffs_base__optional_u63;
1249 // wuffs_base__make_optional_u63 ignores value when has_value is false.
1251 // Preconditions:
1252 // - value < (1 << 63).
1253 static inline wuffs_base__optional_u63 //
1254 wuffs_base__make_optional_u63(bool has_value, uint64_t value) {
1255 wuffs_base__optional_u63 res;
1256 res.repr = has_value ? ((value << 1u) | 1u) : 0u;
1257 return res;
1260 static inline bool //
1261 wuffs_base__optional_u63__has_value(const wuffs_base__optional_u63* o) {
1262 return o->repr;
1265 // wuffs_base__optional_u63__value returns zero when o does not have a value.
1266 static inline uint64_t //
1267 wuffs_base__optional_u63__value(const wuffs_base__optional_u63* o) {
1268 return o->repr >> 1u;
1271 static inline uint64_t //
1272 wuffs_base__optional_u63__value_or(const wuffs_base__optional_u63* o,
1273 uint64_t default_value) {
1274 return o->repr ? (o->repr >> 1u) : default_value;
1277 #ifdef __cplusplus
1279 inline bool //
1280 wuffs_base__optional_u63::has_value() const {
1281 return wuffs_base__optional_u63__has_value(this);
1284 inline uint64_t //
1285 wuffs_base__optional_u63::value() const {
1286 return wuffs_base__optional_u63__value(this);
1289 inline uint64_t //
1290 wuffs_base__optional_u63::value_or(uint64_t default_value) const {
1291 return wuffs_base__optional_u63__value_or(this, default_value);
1294 #endif // __cplusplus
1296 // --------
1298 // The "defined(__clang__)" isn't redundant. While vanilla clang defines
1299 // __GNUC__, clang-cl (which mimics MSVC's cl.exe) does not.
1300 #if (defined(__GNUC__) || defined(__clang__)) && (__SIZEOF_LONG__ == 8)
1302 static inline uint32_t //
1303 wuffs_base__count_leading_zeroes_u64(uint64_t u) {
1304 return u ? ((uint32_t)(__builtin_clzl(u))) : 64u;
1307 #else
1308 // TODO: consider using the _BitScanReverse intrinsic if defined(_MSC_VER).
1310 static inline uint32_t //
1311 wuffs_base__count_leading_zeroes_u64(uint64_t u) {
1312 if (u == 0) {
1313 return 64;
1316 uint32_t n = 0;
1317 if ((u >> 32) == 0) {
1318 n |= 32;
1319 u <<= 32;
1321 if ((u >> 48) == 0) {
1322 n |= 16;
1323 u <<= 16;
1325 if ((u >> 56) == 0) {
1326 n |= 8;
1327 u <<= 8;
1329 if ((u >> 60) == 0) {
1330 n |= 4;
1331 u <<= 4;
1333 if ((u >> 62) == 0) {
1334 n |= 2;
1335 u <<= 2;
1337 if ((u >> 63) == 0) {
1338 n |= 1;
1339 u <<= 1;
1341 return n;
1344 #endif // (defined(__GNUC__) || defined(__clang__)) && (__SIZEOF_LONG__ == 8)
1346 // --------
1348 // Normally, the wuffs_base__peek_etc and wuffs_base__poke_etc implementations
1349 // are both (1) correct regardless of CPU endianness and (2) very fast (e.g. an
1350 // inlined wuffs_base__peek_u32le__no_bounds_check call, in an optimized clang
1351 // or gcc build, is a single MOV instruction on x86_64).
1353 // However, the endian-agnostic implementations are slow on Microsoft's C
1354 // compiler (MSC). Alternative memcpy-based implementations restore speed, but
1355 // they are only correct on little-endian CPU architectures. Defining
1356 // WUFFS_BASE__USE_MEMCPY_LE_PEEK_POKE opts in to these implementations.
1358 // https://godbolt.org/z/q4MfjzTPh
1359 #if defined(_MSC_VER) && !defined(__clang__) && \
1360 (defined(_M_ARM64) || defined(_M_X64))
1361 #define WUFFS_BASE__USE_MEMCPY_LE_PEEK_POKE
1362 #endif
1364 #define wuffs_base__peek_u8be__no_bounds_check \
1365 wuffs_base__peek_u8__no_bounds_check
1366 #define wuffs_base__peek_u8le__no_bounds_check \
1367 wuffs_base__peek_u8__no_bounds_check
1369 static inline uint8_t //
1370 wuffs_base__peek_u8__no_bounds_check(const uint8_t* p) {
1371 return p[0];
1374 static inline uint16_t //
1375 wuffs_base__peek_u16be__no_bounds_check(const uint8_t* p) {
1376 #if defined(WUFFS_BASE__USE_MEMCPY_LE_PEEK_POKE)
1377 uint16_t x;
1378 memcpy(&x, p, 2);
1379 return _byteswap_ushort(x);
1380 #else
1381 return (uint16_t)(((uint16_t)(p[0]) << 8) | ((uint16_t)(p[1]) << 0));
1382 #endif
1385 static inline uint16_t //
1386 wuffs_base__peek_u16le__no_bounds_check(const uint8_t* p) {
1387 #if defined(WUFFS_BASE__USE_MEMCPY_LE_PEEK_POKE)
1388 uint16_t x;
1389 memcpy(&x, p, 2);
1390 return x;
1391 #else
1392 return (uint16_t)(((uint16_t)(p[0]) << 0) | ((uint16_t)(p[1]) << 8));
1393 #endif
1396 static inline uint32_t //
1397 wuffs_base__peek_u24be__no_bounds_check(const uint8_t* p) {
1398 return ((uint32_t)(p[0]) << 16) | ((uint32_t)(p[1]) << 8) |
1399 ((uint32_t)(p[2]) << 0);
1402 static inline uint32_t //
1403 wuffs_base__peek_u24le__no_bounds_check(const uint8_t* p) {
1404 return ((uint32_t)(p[0]) << 0) | ((uint32_t)(p[1]) << 8) |
1405 ((uint32_t)(p[2]) << 16);
1408 static inline uint32_t //
1409 wuffs_base__peek_u32be__no_bounds_check(const uint8_t* p) {
1410 #if defined(WUFFS_BASE__USE_MEMCPY_LE_PEEK_POKE)
1411 uint32_t x;
1412 memcpy(&x, p, 4);
1413 return _byteswap_ulong(x);
1414 #else
1415 return ((uint32_t)(p[0]) << 24) | ((uint32_t)(p[1]) << 16) |
1416 ((uint32_t)(p[2]) << 8) | ((uint32_t)(p[3]) << 0);
1417 #endif
1420 static inline uint32_t //
1421 wuffs_base__peek_u32le__no_bounds_check(const uint8_t* p) {
1422 #if defined(WUFFS_BASE__USE_MEMCPY_LE_PEEK_POKE)
1423 uint32_t x;
1424 memcpy(&x, p, 4);
1425 return x;
1426 #else
1427 return ((uint32_t)(p[0]) << 0) | ((uint32_t)(p[1]) << 8) |
1428 ((uint32_t)(p[2]) << 16) | ((uint32_t)(p[3]) << 24);
1429 #endif
1432 static inline uint64_t //
1433 wuffs_base__peek_u40be__no_bounds_check(const uint8_t* p) {
1434 return ((uint64_t)(p[0]) << 32) | ((uint64_t)(p[1]) << 24) |
1435 ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 8) |
1436 ((uint64_t)(p[4]) << 0);
1439 static inline uint64_t //
1440 wuffs_base__peek_u40le__no_bounds_check(const uint8_t* p) {
1441 return ((uint64_t)(p[0]) << 0) | ((uint64_t)(p[1]) << 8) |
1442 ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
1443 ((uint64_t)(p[4]) << 32);
1446 static inline uint64_t //
1447 wuffs_base__peek_u48be__no_bounds_check(const uint8_t* p) {
1448 return ((uint64_t)(p[0]) << 40) | ((uint64_t)(p[1]) << 32) |
1449 ((uint64_t)(p[2]) << 24) | ((uint64_t)(p[3]) << 16) |
1450 ((uint64_t)(p[4]) << 8) | ((uint64_t)(p[5]) << 0);
1453 static inline uint64_t //
1454 wuffs_base__peek_u48le__no_bounds_check(const uint8_t* p) {
1455 return ((uint64_t)(p[0]) << 0) | ((uint64_t)(p[1]) << 8) |
1456 ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
1457 ((uint64_t)(p[4]) << 32) | ((uint64_t)(p[5]) << 40);
1460 static inline uint64_t //
1461 wuffs_base__peek_u56be__no_bounds_check(const uint8_t* p) {
1462 return ((uint64_t)(p[0]) << 48) | ((uint64_t)(p[1]) << 40) |
1463 ((uint64_t)(p[2]) << 32) | ((uint64_t)(p[3]) << 24) |
1464 ((uint64_t)(p[4]) << 16) | ((uint64_t)(p[5]) << 8) |
1465 ((uint64_t)(p[6]) << 0);
1468 static inline uint64_t //
1469 wuffs_base__peek_u56le__no_bounds_check(const uint8_t* p) {
1470 return ((uint64_t)(p[0]) << 0) | ((uint64_t)(p[1]) << 8) |
1471 ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
1472 ((uint64_t)(p[4]) << 32) | ((uint64_t)(p[5]) << 40) |
1473 ((uint64_t)(p[6]) << 48);
1476 static inline uint64_t //
1477 wuffs_base__peek_u64be__no_bounds_check(const uint8_t* p) {
1478 #if defined(WUFFS_BASE__USE_MEMCPY_LE_PEEK_POKE)
1479 uint64_t x;
1480 memcpy(&x, p, 8);
1481 return _byteswap_uint64(x);
1482 #else
1483 return ((uint64_t)(p[0]) << 56) | ((uint64_t)(p[1]) << 48) |
1484 ((uint64_t)(p[2]) << 40) | ((uint64_t)(p[3]) << 32) |
1485 ((uint64_t)(p[4]) << 24) | ((uint64_t)(p[5]) << 16) |
1486 ((uint64_t)(p[6]) << 8) | ((uint64_t)(p[7]) << 0);
1487 #endif
1490 static inline uint64_t //
1491 wuffs_base__peek_u64le__no_bounds_check(const uint8_t* p) {
1492 #if defined(WUFFS_BASE__USE_MEMCPY_LE_PEEK_POKE)
1493 uint64_t x;
1494 memcpy(&x, p, 8);
1495 return x;
1496 #else
1497 return ((uint64_t)(p[0]) << 0) | ((uint64_t)(p[1]) << 8) |
1498 ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
1499 ((uint64_t)(p[4]) << 32) | ((uint64_t)(p[5]) << 40) |
1500 ((uint64_t)(p[6]) << 48) | ((uint64_t)(p[7]) << 56);
1501 #endif
1504 // --------
1506 #define wuffs_base__poke_u8be__no_bounds_check \
1507 wuffs_base__poke_u8__no_bounds_check
1508 #define wuffs_base__poke_u8le__no_bounds_check \
1509 wuffs_base__poke_u8__no_bounds_check
1511 static inline void //
1512 wuffs_base__poke_u8__no_bounds_check(uint8_t* p, uint8_t x) {
1513 p[0] = x;
1516 static inline void //
1517 wuffs_base__poke_u16be__no_bounds_check(uint8_t* p, uint16_t x) {
1518 p[0] = (uint8_t)(x >> 8);
1519 p[1] = (uint8_t)(x >> 0);
1522 static inline void //
1523 wuffs_base__poke_u16le__no_bounds_check(uint8_t* p, uint16_t x) {
1524 #if defined(WUFFS_BASE__USE_MEMCPY_LE_PEEK_POKE) || \
1525 (defined(__GNUC__) && !defined(__clang__) && defined(__x86_64__))
1526 // This seems to perform better on gcc 10 (but not clang 9). Clang also
1527 // defines "__GNUC__".
1528 memcpy(p, &x, 2);
1529 #else
1530 p[0] = (uint8_t)(x >> 0);
1531 p[1] = (uint8_t)(x >> 8);
1532 #endif
1535 static inline void //
1536 wuffs_base__poke_u24be__no_bounds_check(uint8_t* p, uint32_t x) {
1537 p[0] = (uint8_t)(x >> 16);
1538 p[1] = (uint8_t)(x >> 8);
1539 p[2] = (uint8_t)(x >> 0);
1542 static inline void //
1543 wuffs_base__poke_u24le__no_bounds_check(uint8_t* p, uint32_t x) {
1544 p[0] = (uint8_t)(x >> 0);
1545 p[1] = (uint8_t)(x >> 8);
1546 p[2] = (uint8_t)(x >> 16);
1549 static inline void //
1550 wuffs_base__poke_u32be__no_bounds_check(uint8_t* p, uint32_t x) {
1551 p[0] = (uint8_t)(x >> 24);
1552 p[1] = (uint8_t)(x >> 16);
1553 p[2] = (uint8_t)(x >> 8);
1554 p[3] = (uint8_t)(x >> 0);
1557 static inline void //
1558 wuffs_base__poke_u32le__no_bounds_check(uint8_t* p, uint32_t x) {
1559 #if defined(WUFFS_BASE__USE_MEMCPY_LE_PEEK_POKE) || \
1560 (defined(__GNUC__) && !defined(__clang__) && defined(__x86_64__))
1561 // This seems to perform better on gcc 10 (but not clang 9). Clang also
1562 // defines "__GNUC__".
1563 memcpy(p, &x, 4);
1564 #else
1565 p[0] = (uint8_t)(x >> 0);
1566 p[1] = (uint8_t)(x >> 8);
1567 p[2] = (uint8_t)(x >> 16);
1568 p[3] = (uint8_t)(x >> 24);
1569 #endif
1572 static inline void //
1573 wuffs_base__poke_u40be__no_bounds_check(uint8_t* p, uint64_t x) {
1574 p[0] = (uint8_t)(x >> 32);
1575 p[1] = (uint8_t)(x >> 24);
1576 p[2] = (uint8_t)(x >> 16);
1577 p[3] = (uint8_t)(x >> 8);
1578 p[4] = (uint8_t)(x >> 0);
1581 static inline void //
1582 wuffs_base__poke_u40le__no_bounds_check(uint8_t* p, uint64_t x) {
1583 p[0] = (uint8_t)(x >> 0);
1584 p[1] = (uint8_t)(x >> 8);
1585 p[2] = (uint8_t)(x >> 16);
1586 p[3] = (uint8_t)(x >> 24);
1587 p[4] = (uint8_t)(x >> 32);
1590 static inline void //
1591 wuffs_base__poke_u48be__no_bounds_check(uint8_t* p, uint64_t x) {
1592 p[0] = (uint8_t)(x >> 40);
1593 p[1] = (uint8_t)(x >> 32);
1594 p[2] = (uint8_t)(x >> 24);
1595 p[3] = (uint8_t)(x >> 16);
1596 p[4] = (uint8_t)(x >> 8);
1597 p[5] = (uint8_t)(x >> 0);
1600 static inline void //
1601 wuffs_base__poke_u48le__no_bounds_check(uint8_t* p, uint64_t x) {
1602 p[0] = (uint8_t)(x >> 0);
1603 p[1] = (uint8_t)(x >> 8);
1604 p[2] = (uint8_t)(x >> 16);
1605 p[3] = (uint8_t)(x >> 24);
1606 p[4] = (uint8_t)(x >> 32);
1607 p[5] = (uint8_t)(x >> 40);
1610 static inline void //
1611 wuffs_base__poke_u56be__no_bounds_check(uint8_t* p, uint64_t x) {
1612 p[0] = (uint8_t)(x >> 48);
1613 p[1] = (uint8_t)(x >> 40);
1614 p[2] = (uint8_t)(x >> 32);
1615 p[3] = (uint8_t)(x >> 24);
1616 p[4] = (uint8_t)(x >> 16);
1617 p[5] = (uint8_t)(x >> 8);
1618 p[6] = (uint8_t)(x >> 0);
1621 static inline void //
1622 wuffs_base__poke_u56le__no_bounds_check(uint8_t* p, uint64_t x) {
1623 p[0] = (uint8_t)(x >> 0);
1624 p[1] = (uint8_t)(x >> 8);
1625 p[2] = (uint8_t)(x >> 16);
1626 p[3] = (uint8_t)(x >> 24);
1627 p[4] = (uint8_t)(x >> 32);
1628 p[5] = (uint8_t)(x >> 40);
1629 p[6] = (uint8_t)(x >> 48);
1632 static inline void //
1633 wuffs_base__poke_u64be__no_bounds_check(uint8_t* p, uint64_t x) {
1634 p[0] = (uint8_t)(x >> 56);
1635 p[1] = (uint8_t)(x >> 48);
1636 p[2] = (uint8_t)(x >> 40);
1637 p[3] = (uint8_t)(x >> 32);
1638 p[4] = (uint8_t)(x >> 24);
1639 p[5] = (uint8_t)(x >> 16);
1640 p[6] = (uint8_t)(x >> 8);
1641 p[7] = (uint8_t)(x >> 0);
1644 static inline void //
1645 wuffs_base__poke_u64le__no_bounds_check(uint8_t* p, uint64_t x) {
1646 #if defined(WUFFS_BASE__USE_MEMCPY_LE_PEEK_POKE) || \
1647 (defined(__GNUC__) && !defined(__clang__) && defined(__x86_64__))
1648 // This seems to perform better on gcc 10 (but not clang 9). Clang also
1649 // defines "__GNUC__".
1650 memcpy(p, &x, 8);
1651 #else
1652 p[0] = (uint8_t)(x >> 0);
1653 p[1] = (uint8_t)(x >> 8);
1654 p[2] = (uint8_t)(x >> 16);
1655 p[3] = (uint8_t)(x >> 24);
1656 p[4] = (uint8_t)(x >> 32);
1657 p[5] = (uint8_t)(x >> 40);
1658 p[6] = (uint8_t)(x >> 48);
1659 p[7] = (uint8_t)(x >> 56);
1660 #endif
1663 // ---------------- Slices and Tables
1665 // WUFFS_BASE__SLICE is a 1-dimensional buffer.
1667 // len measures a number of elements, not necessarily a size in bytes.
1669 // A value with all fields NULL or zero is a valid, empty slice.
1670 #define WUFFS_BASE__SLICE(T) \
1671 struct { \
1672 T* ptr; \
1673 size_t len; \
1676 // WUFFS_BASE__TABLE is a 2-dimensional buffer.
1678 // width, height and stride measure a number of elements, not necessarily a
1679 // size in bytes.
1681 // A value with all fields NULL or zero is a valid, empty table.
1682 #define WUFFS_BASE__TABLE(T) \
1683 struct { \
1684 T* ptr; \
1685 size_t width; \
1686 size_t height; \
1687 size_t stride; \
1690 typedef WUFFS_BASE__SLICE(uint8_t) wuffs_base__slice_u8;
1691 typedef WUFFS_BASE__SLICE(uint16_t) wuffs_base__slice_u16;
1692 typedef WUFFS_BASE__SLICE(uint32_t) wuffs_base__slice_u32;
1693 typedef WUFFS_BASE__SLICE(uint64_t) wuffs_base__slice_u64;
1695 typedef WUFFS_BASE__TABLE(uint8_t) wuffs_base__table_u8;
1696 typedef WUFFS_BASE__TABLE(uint16_t) wuffs_base__table_u16;
1697 typedef WUFFS_BASE__TABLE(uint32_t) wuffs_base__table_u32;
1698 typedef WUFFS_BASE__TABLE(uint64_t) wuffs_base__table_u64;
1700 static inline wuffs_base__slice_u8 //
1701 wuffs_base__make_slice_u8(uint8_t* ptr, size_t len) {
1702 wuffs_base__slice_u8 ret;
1703 ret.ptr = ptr;
1704 ret.len = len;
1705 return ret;
1708 static inline wuffs_base__slice_u16 //
1709 wuffs_base__make_slice_u16(uint16_t* ptr, size_t len) {
1710 wuffs_base__slice_u16 ret;
1711 ret.ptr = ptr;
1712 ret.len = len;
1713 return ret;
1716 static inline wuffs_base__slice_u32 //
1717 wuffs_base__make_slice_u32(uint32_t* ptr, size_t len) {
1718 wuffs_base__slice_u32 ret;
1719 ret.ptr = ptr;
1720 ret.len = len;
1721 return ret;
1724 static inline wuffs_base__slice_u64 //
1725 wuffs_base__make_slice_u64(uint64_t* ptr, size_t len) {
1726 wuffs_base__slice_u64 ret;
1727 ret.ptr = ptr;
1728 ret.len = len;
1729 return ret;
1732 static inline wuffs_base__slice_u8 //
1733 wuffs_base__make_slice_u8_ij(uint8_t* ptr, size_t i, size_t j) {
1734 wuffs_base__slice_u8 ret;
1735 ret.ptr = ptr ? (ptr + i) : NULL;
1736 ret.len = (j >= i) ? (j - i) : 0;
1737 return ret;
1740 static inline wuffs_base__slice_u16 //
1741 wuffs_base__make_slice_u16_ij(uint16_t* ptr, size_t i, size_t j) {
1742 wuffs_base__slice_u16 ret;
1743 ret.ptr = ptr ? (ptr + i) : NULL;
1744 ret.len = (j >= i) ? (j - i) : 0;
1745 return ret;
1748 static inline wuffs_base__slice_u32 //
1749 wuffs_base__make_slice_u32_ij(uint32_t* ptr, size_t i, size_t j) {
1750 wuffs_base__slice_u32 ret;
1751 ret.ptr = ptr ? (ptr + i) : NULL;
1752 ret.len = (j >= i) ? (j - i) : 0;
1753 return ret;
1756 static inline wuffs_base__slice_u64 //
1757 wuffs_base__make_slice_u64_ij(uint64_t* ptr, size_t i, size_t j) {
1758 wuffs_base__slice_u64 ret;
1759 ret.ptr = ptr ? (ptr + i) : NULL;
1760 ret.len = (j >= i) ? (j - i) : 0;
1761 return ret;
1764 static inline wuffs_base__slice_u8 //
1765 wuffs_base__empty_slice_u8(void) {
1766 wuffs_base__slice_u8 ret;
1767 ret.ptr = NULL;
1768 ret.len = 0;
1769 return ret;
1772 static inline wuffs_base__slice_u16 //
1773 wuffs_base__empty_slice_u16(void) {
1774 wuffs_base__slice_u16 ret;
1775 ret.ptr = NULL;
1776 ret.len = 0;
1777 return ret;
1780 static inline wuffs_base__slice_u32 //
1781 wuffs_base__empty_slice_u32(void) {
1782 wuffs_base__slice_u32 ret;
1783 ret.ptr = NULL;
1784 ret.len = 0;
1785 return ret;
1788 static inline wuffs_base__slice_u64 //
1789 wuffs_base__empty_slice_u64(void) {
1790 wuffs_base__slice_u64 ret;
1791 ret.ptr = NULL;
1792 ret.len = 0;
1793 return ret;
1796 static inline wuffs_base__table_u8 //
1797 wuffs_base__make_table_u8(uint8_t* ptr,
1798 size_t width,
1799 size_t height,
1800 size_t stride) {
1801 wuffs_base__table_u8 ret;
1802 ret.ptr = ptr;
1803 ret.width = width;
1804 ret.height = height;
1805 ret.stride = stride;
1806 return ret;
1809 static inline wuffs_base__table_u16 //
1810 wuffs_base__make_table_u16(uint16_t* ptr,
1811 size_t width,
1812 size_t height,
1813 size_t stride) {
1814 wuffs_base__table_u16 ret;
1815 ret.ptr = ptr;
1816 ret.width = width;
1817 ret.height = height;
1818 ret.stride = stride;
1819 return ret;
1822 static inline wuffs_base__table_u32 //
1823 wuffs_base__make_table_u32(uint32_t* ptr,
1824 size_t width,
1825 size_t height,
1826 size_t stride) {
1827 wuffs_base__table_u32 ret;
1828 ret.ptr = ptr;
1829 ret.width = width;
1830 ret.height = height;
1831 ret.stride = stride;
1832 return ret;
1835 static inline wuffs_base__table_u64 //
1836 wuffs_base__make_table_u64(uint64_t* ptr,
1837 size_t width,
1838 size_t height,
1839 size_t stride) {
1840 wuffs_base__table_u64 ret;
1841 ret.ptr = ptr;
1842 ret.width = width;
1843 ret.height = height;
1844 ret.stride = stride;
1845 return ret;
1848 static inline wuffs_base__table_u8 //
1849 wuffs_base__empty_table_u8(void) {
1850 wuffs_base__table_u8 ret;
1851 ret.ptr = NULL;
1852 ret.width = 0;
1853 ret.height = 0;
1854 ret.stride = 0;
1855 return ret;
1858 static inline wuffs_base__table_u16 //
1859 wuffs_base__empty_table_u16(void) {
1860 wuffs_base__table_u16 ret;
1861 ret.ptr = NULL;
1862 ret.width = 0;
1863 ret.height = 0;
1864 ret.stride = 0;
1865 return ret;
1868 static inline wuffs_base__table_u32 //
1869 wuffs_base__empty_table_u32(void) {
1870 wuffs_base__table_u32 ret;
1871 ret.ptr = NULL;
1872 ret.width = 0;
1873 ret.height = 0;
1874 ret.stride = 0;
1875 return ret;
1878 static inline wuffs_base__table_u64 //
1879 wuffs_base__empty_table_u64(void) {
1880 wuffs_base__table_u64 ret;
1881 ret.ptr = NULL;
1882 ret.width = 0;
1883 ret.height = 0;
1884 ret.stride = 0;
1885 return ret;
1888 static inline bool //
1889 wuffs_base__slice_u8__overlaps(wuffs_base__slice_u8 s, wuffs_base__slice_u8 t) {
1890 return ((s.ptr <= t.ptr) && (t.ptr < (s.ptr + s.len))) ||
1891 ((t.ptr <= s.ptr) && (s.ptr < (t.ptr + t.len)));
1894 // wuffs_base__slice_u8__subslice_i returns s[i:].
1896 // It returns an empty slice if i is out of bounds.
1897 static inline wuffs_base__slice_u8 //
1898 wuffs_base__slice_u8__subslice_i(wuffs_base__slice_u8 s, uint64_t i) {
1899 if ((i <= SIZE_MAX) && (i <= s.len)) {
1900 return wuffs_base__make_slice_u8(s.ptr + i, ((size_t)(s.len - i)));
1902 return wuffs_base__empty_slice_u8();
1905 // wuffs_base__slice_u8__subslice_j returns s[:j].
1907 // It returns an empty slice if j is out of bounds.
1908 static inline wuffs_base__slice_u8 //
1909 wuffs_base__slice_u8__subslice_j(wuffs_base__slice_u8 s, uint64_t j) {
1910 if ((j <= SIZE_MAX) && (j <= s.len)) {
1911 return wuffs_base__make_slice_u8(s.ptr, ((size_t)j));
1913 return wuffs_base__empty_slice_u8();
1916 // wuffs_base__slice_u8__subslice_ij returns s[i:j].
1918 // It returns an empty slice if i or j is out of bounds.
1919 static inline wuffs_base__slice_u8 //
1920 wuffs_base__slice_u8__subslice_ij(wuffs_base__slice_u8 s,
1921 uint64_t i,
1922 uint64_t j) {
1923 if ((i <= j) && (j <= SIZE_MAX) && (j <= s.len)) {
1924 return wuffs_base__make_slice_u8(s.ptr + i, ((size_t)(j - i)));
1926 return wuffs_base__empty_slice_u8();
1929 // wuffs_base__table_u8__subtable_ij returns t[ix:jx, iy:jy].
1931 // It returns an empty table if i or j is out of bounds.
1932 static inline wuffs_base__table_u8 //
1933 wuffs_base__table_u8__subtable_ij(wuffs_base__table_u8 t,
1934 uint64_t ix,
1935 uint64_t iy,
1936 uint64_t jx,
1937 uint64_t jy) {
1938 if ((ix <= jx) && (jx <= SIZE_MAX) && (jx <= t.width) && //
1939 (iy <= jy) && (jy <= SIZE_MAX) && (jy <= t.height)) {
1940 return wuffs_base__make_table_u8(t.ptr + ix + (iy * t.stride), //
1941 ((size_t)(jx - ix)), //
1942 ((size_t)(jy - iy)), //
1943 t.stride); //
1945 return wuffs_base__make_table_u8(NULL, 0, 0, 0);
1948 // wuffs_base__table__flattened_length returns the number of elements covered
1949 // by the 1-dimensional span that backs a 2-dimensional table. This counts the
1950 // elements inside the table and, when width != stride, the elements outside
1951 // the table but between its rows.
1953 // For example, consider a width 10, height 4, stride 10 table. Mark its first
1954 // and last (inclusive) elements with 'a' and 'z'. This function returns 40.
1956 // a123456789
1957 // 0123456789
1958 // 0123456789
1959 // 012345678z
1961 // Now consider the sub-table of that from (2, 1) inclusive to (8, 4) exclusive.
1963 // a123456789
1964 // 01iiiiiioo
1965 // ooiiiiiioo
1966 // ooiiiiii8z
1968 // This function (called with width 6, height 3, stride 10) returns 26: 18 'i'
1969 // inside elements plus 8 'o' outside elements. Note that 26 is less than a
1970 // naive (height * stride = 30) computation. Indeed, advancing 29 elements from
1971 // the first 'i' would venture past 'z', out of bounds of the original table.
1973 // It does not check for overflow, but if the arguments come from a table that
1974 // exists in memory and each element occupies a positive number of bytes then
1975 // the result should be bounded by the amount of allocatable memory (which
1976 // shouldn't overflow SIZE_MAX).
1977 static inline size_t //
1978 wuffs_base__table__flattened_length(size_t width,
1979 size_t height,
1980 size_t stride) {
1981 if (height == 0) {
1982 return 0;
1984 return ((height - 1) * stride) + width;
1987 // ---------------- Magic Numbers
1989 // wuffs_base__magic_number_guess_fourcc guesses the file format of some data,
1990 // given its starting bytes (the prefix_data argument) and whether or not there
1991 // may be further bytes (the prefix_closed argument; true means that
1992 // prefix_data is the entire data).
1994 // It returns a positive FourCC value on success.
1996 // It returns zero if nothing matches its hard-coded list of 'magic numbers'.
1998 // It returns a negative value if prefix_closed is false and a longer prefix is
1999 // required for a conclusive result. For example, a single 'B' byte (without
2000 // further data) is not enough to discriminate the BMP and BPG image file
2001 // formats. Similarly, a single '\xFF' byte might be the start of JPEG data or
2002 // it might be the start of some other binary data.
2004 // It does not do a full validity check. Like any guess made from a short
2005 // prefix of the data, it may return false positives. Data that starts with 99
2006 // bytes of valid JPEG followed by corruption or truncation is an invalid JPEG
2007 // image overall, but this function will still return WUFFS_BASE__FOURCC__JPEG.
2009 // Another source of false positives is that some 'magic numbers' are valid
2010 // ASCII data. A file starting with "GIF87a and GIF89a are the two versions of
2011 // GIF" will match GIF's 'magic number' even if it's plain text, not an image.
2013 // For modular builds that divide the base module into sub-modules, using this
2014 // function requires the WUFFS_CONFIG__MODULE__BASE__MAGIC sub-module, not just
2015 // WUFFS_CONFIG__MODULE__BASE__CORE.
2016 WUFFS_BASE__MAYBE_STATIC int32_t //
2017 wuffs_base__magic_number_guess_fourcc(wuffs_base__slice_u8 prefix_data,
2018 bool prefix_closed);
2020 // ---------------- Quirk Values
2022 // These constants are the value half of a key-value pair, where the key is
2023 // WUFFS_BASE__QUIRK_QUALITY.
2025 // In the Wuffs API, set_quirk takes a u64 value. These macro definitions are
2026 // likewise unsigned values (uint64_t) but for this particular key, they are
2027 // best interpreted as signed values (int64_t). "Lower-than-default quality"
2028 // and "higher-than-default quality", as signed values, are -1 and +1.
2030 // See doc/note/quirks.md for some more discussion about trade-offs.
2031 #define WUFFS_BASE__QUIRK_QUALITY__VALUE__LOWER_QUALITY UINT64_MAX
2032 #define WUFFS_BASE__QUIRK_QUALITY__VALUE__HIGHER_QUALITY ((uint64_t)1)
2034 // ---------------- Ranges and Rects
2036 // See https://github.com/google/wuffs/blob/main/doc/note/ranges-and-rects.md
2038 typedef struct wuffs_base__range_ii_u32__struct {
2039 uint32_t min_incl;
2040 uint32_t max_incl;
2042 #ifdef __cplusplus
2043 inline bool is_empty() const;
2044 inline bool equals(wuffs_base__range_ii_u32__struct s) const;
2045 inline wuffs_base__range_ii_u32__struct intersect(
2046 wuffs_base__range_ii_u32__struct s) const;
2047 inline wuffs_base__range_ii_u32__struct unite(
2048 wuffs_base__range_ii_u32__struct s) const;
2049 inline bool contains(uint32_t x) const;
2050 inline bool contains_range(wuffs_base__range_ii_u32__struct s) const;
2051 #endif // __cplusplus
2053 } wuffs_base__range_ii_u32;
2055 static inline wuffs_base__range_ii_u32 //
2056 wuffs_base__empty_range_ii_u32(void) {
2057 wuffs_base__range_ii_u32 ret;
2058 ret.min_incl = 0;
2059 ret.max_incl = 0;
2060 return ret;
2063 static inline wuffs_base__range_ii_u32 //
2064 wuffs_base__make_range_ii_u32(uint32_t min_incl, uint32_t max_incl) {
2065 wuffs_base__range_ii_u32 ret;
2066 ret.min_incl = min_incl;
2067 ret.max_incl = max_incl;
2068 return ret;
2071 static inline bool //
2072 wuffs_base__range_ii_u32__is_empty(const wuffs_base__range_ii_u32* r) {
2073 return r->min_incl > r->max_incl;
2076 static inline bool //
2077 wuffs_base__range_ii_u32__equals(const wuffs_base__range_ii_u32* r,
2078 wuffs_base__range_ii_u32 s) {
2079 return (r->min_incl == s.min_incl && r->max_incl == s.max_incl) ||
2080 (wuffs_base__range_ii_u32__is_empty(r) &&
2081 wuffs_base__range_ii_u32__is_empty(&s));
2084 static inline wuffs_base__range_ii_u32 //
2085 wuffs_base__range_ii_u32__intersect(const wuffs_base__range_ii_u32* r,
2086 wuffs_base__range_ii_u32 s) {
2087 wuffs_base__range_ii_u32 t;
2088 t.min_incl = wuffs_base__u32__max(r->min_incl, s.min_incl);
2089 t.max_incl = wuffs_base__u32__min(r->max_incl, s.max_incl);
2090 return t;
2093 static inline wuffs_base__range_ii_u32 //
2094 wuffs_base__range_ii_u32__unite(const wuffs_base__range_ii_u32* r,
2095 wuffs_base__range_ii_u32 s) {
2096 if (wuffs_base__range_ii_u32__is_empty(r)) {
2097 return s;
2099 if (wuffs_base__range_ii_u32__is_empty(&s)) {
2100 return *r;
2102 wuffs_base__range_ii_u32 t;
2103 t.min_incl = wuffs_base__u32__min(r->min_incl, s.min_incl);
2104 t.max_incl = wuffs_base__u32__max(r->max_incl, s.max_incl);
2105 return t;
2108 static inline bool //
2109 wuffs_base__range_ii_u32__contains(const wuffs_base__range_ii_u32* r,
2110 uint32_t x) {
2111 return (r->min_incl <= x) && (x <= r->max_incl);
2114 static inline bool //
2115 wuffs_base__range_ii_u32__contains_range(const wuffs_base__range_ii_u32* r,
2116 wuffs_base__range_ii_u32 s) {
2117 return wuffs_base__range_ii_u32__equals(
2118 &s, wuffs_base__range_ii_u32__intersect(r, s));
2121 #ifdef __cplusplus
2123 inline bool //
2124 wuffs_base__range_ii_u32::is_empty() const {
2125 return wuffs_base__range_ii_u32__is_empty(this);
2128 inline bool //
2129 wuffs_base__range_ii_u32::equals(wuffs_base__range_ii_u32 s) const {
2130 return wuffs_base__range_ii_u32__equals(this, s);
2133 inline wuffs_base__range_ii_u32 //
2134 wuffs_base__range_ii_u32::intersect(wuffs_base__range_ii_u32 s) const {
2135 return wuffs_base__range_ii_u32__intersect(this, s);
2138 inline wuffs_base__range_ii_u32 //
2139 wuffs_base__range_ii_u32::unite(wuffs_base__range_ii_u32 s) const {
2140 return wuffs_base__range_ii_u32__unite(this, s);
2143 inline bool //
2144 wuffs_base__range_ii_u32::contains(uint32_t x) const {
2145 return wuffs_base__range_ii_u32__contains(this, x);
2148 inline bool //
2149 wuffs_base__range_ii_u32::contains_range(wuffs_base__range_ii_u32 s) const {
2150 return wuffs_base__range_ii_u32__contains_range(this, s);
2153 #endif // __cplusplus
2155 // --------
2157 typedef struct wuffs_base__range_ie_u32__struct {
2158 uint32_t min_incl;
2159 uint32_t max_excl;
2161 #ifdef __cplusplus
2162 inline bool is_empty() const;
2163 inline bool equals(wuffs_base__range_ie_u32__struct s) const;
2164 inline wuffs_base__range_ie_u32__struct intersect(
2165 wuffs_base__range_ie_u32__struct s) const;
2166 inline wuffs_base__range_ie_u32__struct unite(
2167 wuffs_base__range_ie_u32__struct s) const;
2168 inline bool contains(uint32_t x) const;
2169 inline bool contains_range(wuffs_base__range_ie_u32__struct s) const;
2170 inline uint32_t length() const;
2171 #endif // __cplusplus
2173 } wuffs_base__range_ie_u32;
2175 static inline wuffs_base__range_ie_u32 //
2176 wuffs_base__empty_range_ie_u32(void) {
2177 wuffs_base__range_ie_u32 ret;
2178 ret.min_incl = 0;
2179 ret.max_excl = 0;
2180 return ret;
2183 static inline wuffs_base__range_ie_u32 //
2184 wuffs_base__make_range_ie_u32(uint32_t min_incl, uint32_t max_excl) {
2185 wuffs_base__range_ie_u32 ret;
2186 ret.min_incl = min_incl;
2187 ret.max_excl = max_excl;
2188 return ret;
2191 static inline bool //
2192 wuffs_base__range_ie_u32__is_empty(const wuffs_base__range_ie_u32* r) {
2193 return r->min_incl >= r->max_excl;
2196 static inline bool //
2197 wuffs_base__range_ie_u32__equals(const wuffs_base__range_ie_u32* r,
2198 wuffs_base__range_ie_u32 s) {
2199 return (r->min_incl == s.min_incl && r->max_excl == s.max_excl) ||
2200 (wuffs_base__range_ie_u32__is_empty(r) &&
2201 wuffs_base__range_ie_u32__is_empty(&s));
2204 static inline wuffs_base__range_ie_u32 //
2205 wuffs_base__range_ie_u32__intersect(const wuffs_base__range_ie_u32* r,
2206 wuffs_base__range_ie_u32 s) {
2207 wuffs_base__range_ie_u32 t;
2208 t.min_incl = wuffs_base__u32__max(r->min_incl, s.min_incl);
2209 t.max_excl = wuffs_base__u32__min(r->max_excl, s.max_excl);
2210 return t;
2213 static inline wuffs_base__range_ie_u32 //
2214 wuffs_base__range_ie_u32__unite(const wuffs_base__range_ie_u32* r,
2215 wuffs_base__range_ie_u32 s) {
2216 if (wuffs_base__range_ie_u32__is_empty(r)) {
2217 return s;
2219 if (wuffs_base__range_ie_u32__is_empty(&s)) {
2220 return *r;
2222 wuffs_base__range_ie_u32 t;
2223 t.min_incl = wuffs_base__u32__min(r->min_incl, s.min_incl);
2224 t.max_excl = wuffs_base__u32__max(r->max_excl, s.max_excl);
2225 return t;
2228 static inline bool //
2229 wuffs_base__range_ie_u32__contains(const wuffs_base__range_ie_u32* r,
2230 uint32_t x) {
2231 return (r->min_incl <= x) && (x < r->max_excl);
2234 static inline bool //
2235 wuffs_base__range_ie_u32__contains_range(const wuffs_base__range_ie_u32* r,
2236 wuffs_base__range_ie_u32 s) {
2237 return wuffs_base__range_ie_u32__equals(
2238 &s, wuffs_base__range_ie_u32__intersect(r, s));
2241 static inline uint32_t //
2242 wuffs_base__range_ie_u32__length(const wuffs_base__range_ie_u32* r) {
2243 return wuffs_base__u32__sat_sub(r->max_excl, r->min_incl);
2246 #ifdef __cplusplus
2248 inline bool //
2249 wuffs_base__range_ie_u32::is_empty() const {
2250 return wuffs_base__range_ie_u32__is_empty(this);
2253 inline bool //
2254 wuffs_base__range_ie_u32::equals(wuffs_base__range_ie_u32 s) const {
2255 return wuffs_base__range_ie_u32__equals(this, s);
2258 inline wuffs_base__range_ie_u32 //
2259 wuffs_base__range_ie_u32::intersect(wuffs_base__range_ie_u32 s) const {
2260 return wuffs_base__range_ie_u32__intersect(this, s);
2263 inline wuffs_base__range_ie_u32 //
2264 wuffs_base__range_ie_u32::unite(wuffs_base__range_ie_u32 s) const {
2265 return wuffs_base__range_ie_u32__unite(this, s);
2268 inline bool //
2269 wuffs_base__range_ie_u32::contains(uint32_t x) const {
2270 return wuffs_base__range_ie_u32__contains(this, x);
2273 inline bool //
2274 wuffs_base__range_ie_u32::contains_range(wuffs_base__range_ie_u32 s) const {
2275 return wuffs_base__range_ie_u32__contains_range(this, s);
2278 inline uint32_t //
2279 wuffs_base__range_ie_u32::length() const {
2280 return wuffs_base__range_ie_u32__length(this);
2283 #endif // __cplusplus
2285 // --------
2287 typedef struct wuffs_base__range_ii_u64__struct {
2288 uint64_t min_incl;
2289 uint64_t max_incl;
2291 #ifdef __cplusplus
2292 inline bool is_empty() const;
2293 inline bool equals(wuffs_base__range_ii_u64__struct s) const;
2294 inline wuffs_base__range_ii_u64__struct intersect(
2295 wuffs_base__range_ii_u64__struct s) const;
2296 inline wuffs_base__range_ii_u64__struct unite(
2297 wuffs_base__range_ii_u64__struct s) const;
2298 inline bool contains(uint64_t x) const;
2299 inline bool contains_range(wuffs_base__range_ii_u64__struct s) const;
2300 #endif // __cplusplus
2302 } wuffs_base__range_ii_u64;
2304 static inline wuffs_base__range_ii_u64 //
2305 wuffs_base__empty_range_ii_u64(void) {
2306 wuffs_base__range_ii_u64 ret;
2307 ret.min_incl = 0;
2308 ret.max_incl = 0;
2309 return ret;
2312 static inline wuffs_base__range_ii_u64 //
2313 wuffs_base__make_range_ii_u64(uint64_t min_incl, uint64_t max_incl) {
2314 wuffs_base__range_ii_u64 ret;
2315 ret.min_incl = min_incl;
2316 ret.max_incl = max_incl;
2317 return ret;
2320 static inline bool //
2321 wuffs_base__range_ii_u64__is_empty(const wuffs_base__range_ii_u64* r) {
2322 return r->min_incl > r->max_incl;
2325 static inline bool //
2326 wuffs_base__range_ii_u64__equals(const wuffs_base__range_ii_u64* r,
2327 wuffs_base__range_ii_u64 s) {
2328 return (r->min_incl == s.min_incl && r->max_incl == s.max_incl) ||
2329 (wuffs_base__range_ii_u64__is_empty(r) &&
2330 wuffs_base__range_ii_u64__is_empty(&s));
2333 static inline wuffs_base__range_ii_u64 //
2334 wuffs_base__range_ii_u64__intersect(const wuffs_base__range_ii_u64* r,
2335 wuffs_base__range_ii_u64 s) {
2336 wuffs_base__range_ii_u64 t;
2337 t.min_incl = wuffs_base__u64__max(r->min_incl, s.min_incl);
2338 t.max_incl = wuffs_base__u64__min(r->max_incl, s.max_incl);
2339 return t;
2342 static inline wuffs_base__range_ii_u64 //
2343 wuffs_base__range_ii_u64__unite(const wuffs_base__range_ii_u64* r,
2344 wuffs_base__range_ii_u64 s) {
2345 if (wuffs_base__range_ii_u64__is_empty(r)) {
2346 return s;
2348 if (wuffs_base__range_ii_u64__is_empty(&s)) {
2349 return *r;
2351 wuffs_base__range_ii_u64 t;
2352 t.min_incl = wuffs_base__u64__min(r->min_incl, s.min_incl);
2353 t.max_incl = wuffs_base__u64__max(r->max_incl, s.max_incl);
2354 return t;
2357 static inline bool //
2358 wuffs_base__range_ii_u64__contains(const wuffs_base__range_ii_u64* r,
2359 uint64_t x) {
2360 return (r->min_incl <= x) && (x <= r->max_incl);
2363 static inline bool //
2364 wuffs_base__range_ii_u64__contains_range(const wuffs_base__range_ii_u64* r,
2365 wuffs_base__range_ii_u64 s) {
2366 return wuffs_base__range_ii_u64__equals(
2367 &s, wuffs_base__range_ii_u64__intersect(r, s));
2370 #ifdef __cplusplus
2372 inline bool //
2373 wuffs_base__range_ii_u64::is_empty() const {
2374 return wuffs_base__range_ii_u64__is_empty(this);
2377 inline bool //
2378 wuffs_base__range_ii_u64::equals(wuffs_base__range_ii_u64 s) const {
2379 return wuffs_base__range_ii_u64__equals(this, s);
2382 inline wuffs_base__range_ii_u64 //
2383 wuffs_base__range_ii_u64::intersect(wuffs_base__range_ii_u64 s) const {
2384 return wuffs_base__range_ii_u64__intersect(this, s);
2387 inline wuffs_base__range_ii_u64 //
2388 wuffs_base__range_ii_u64::unite(wuffs_base__range_ii_u64 s) const {
2389 return wuffs_base__range_ii_u64__unite(this, s);
2392 inline bool //
2393 wuffs_base__range_ii_u64::contains(uint64_t x) const {
2394 return wuffs_base__range_ii_u64__contains(this, x);
2397 inline bool //
2398 wuffs_base__range_ii_u64::contains_range(wuffs_base__range_ii_u64 s) const {
2399 return wuffs_base__range_ii_u64__contains_range(this, s);
2402 #endif // __cplusplus
2404 // --------
2406 typedef struct wuffs_base__range_ie_u64__struct {
2407 uint64_t min_incl;
2408 uint64_t max_excl;
2410 #ifdef __cplusplus
2411 inline bool is_empty() const;
2412 inline bool equals(wuffs_base__range_ie_u64__struct s) const;
2413 inline wuffs_base__range_ie_u64__struct intersect(
2414 wuffs_base__range_ie_u64__struct s) const;
2415 inline wuffs_base__range_ie_u64__struct unite(
2416 wuffs_base__range_ie_u64__struct s) const;
2417 inline bool contains(uint64_t x) const;
2418 inline bool contains_range(wuffs_base__range_ie_u64__struct s) const;
2419 inline uint64_t length() const;
2420 #endif // __cplusplus
2422 } wuffs_base__range_ie_u64;
2424 static inline wuffs_base__range_ie_u64 //
2425 wuffs_base__empty_range_ie_u64(void) {
2426 wuffs_base__range_ie_u64 ret;
2427 ret.min_incl = 0;
2428 ret.max_excl = 0;
2429 return ret;
2432 static inline wuffs_base__range_ie_u64 //
2433 wuffs_base__make_range_ie_u64(uint64_t min_incl, uint64_t max_excl) {
2434 wuffs_base__range_ie_u64 ret;
2435 ret.min_incl = min_incl;
2436 ret.max_excl = max_excl;
2437 return ret;
2440 static inline bool //
2441 wuffs_base__range_ie_u64__is_empty(const wuffs_base__range_ie_u64* r) {
2442 return r->min_incl >= r->max_excl;
2445 static inline bool //
2446 wuffs_base__range_ie_u64__equals(const wuffs_base__range_ie_u64* r,
2447 wuffs_base__range_ie_u64 s) {
2448 return (r->min_incl == s.min_incl && r->max_excl == s.max_excl) ||
2449 (wuffs_base__range_ie_u64__is_empty(r) &&
2450 wuffs_base__range_ie_u64__is_empty(&s));
2453 static inline wuffs_base__range_ie_u64 //
2454 wuffs_base__range_ie_u64__intersect(const wuffs_base__range_ie_u64* r,
2455 wuffs_base__range_ie_u64 s) {
2456 wuffs_base__range_ie_u64 t;
2457 t.min_incl = wuffs_base__u64__max(r->min_incl, s.min_incl);
2458 t.max_excl = wuffs_base__u64__min(r->max_excl, s.max_excl);
2459 return t;
2462 static inline wuffs_base__range_ie_u64 //
2463 wuffs_base__range_ie_u64__unite(const wuffs_base__range_ie_u64* r,
2464 wuffs_base__range_ie_u64 s) {
2465 if (wuffs_base__range_ie_u64__is_empty(r)) {
2466 return s;
2468 if (wuffs_base__range_ie_u64__is_empty(&s)) {
2469 return *r;
2471 wuffs_base__range_ie_u64 t;
2472 t.min_incl = wuffs_base__u64__min(r->min_incl, s.min_incl);
2473 t.max_excl = wuffs_base__u64__max(r->max_excl, s.max_excl);
2474 return t;
2477 static inline bool //
2478 wuffs_base__range_ie_u64__contains(const wuffs_base__range_ie_u64* r,
2479 uint64_t x) {
2480 return (r->min_incl <= x) && (x < r->max_excl);
2483 static inline bool //
2484 wuffs_base__range_ie_u64__contains_range(const wuffs_base__range_ie_u64* r,
2485 wuffs_base__range_ie_u64 s) {
2486 return wuffs_base__range_ie_u64__equals(
2487 &s, wuffs_base__range_ie_u64__intersect(r, s));
2490 static inline uint64_t //
2491 wuffs_base__range_ie_u64__length(const wuffs_base__range_ie_u64* r) {
2492 return wuffs_base__u64__sat_sub(r->max_excl, r->min_incl);
2495 #ifdef __cplusplus
2497 inline bool //
2498 wuffs_base__range_ie_u64::is_empty() const {
2499 return wuffs_base__range_ie_u64__is_empty(this);
2502 inline bool //
2503 wuffs_base__range_ie_u64::equals(wuffs_base__range_ie_u64 s) const {
2504 return wuffs_base__range_ie_u64__equals(this, s);
2507 inline wuffs_base__range_ie_u64 //
2508 wuffs_base__range_ie_u64::intersect(wuffs_base__range_ie_u64 s) const {
2509 return wuffs_base__range_ie_u64__intersect(this, s);
2512 inline wuffs_base__range_ie_u64 //
2513 wuffs_base__range_ie_u64::unite(wuffs_base__range_ie_u64 s) const {
2514 return wuffs_base__range_ie_u64__unite(this, s);
2517 inline bool //
2518 wuffs_base__range_ie_u64::contains(uint64_t x) const {
2519 return wuffs_base__range_ie_u64__contains(this, x);
2522 inline bool //
2523 wuffs_base__range_ie_u64::contains_range(wuffs_base__range_ie_u64 s) const {
2524 return wuffs_base__range_ie_u64__contains_range(this, s);
2527 inline uint64_t //
2528 wuffs_base__range_ie_u64::length() const {
2529 return wuffs_base__range_ie_u64__length(this);
2532 #endif // __cplusplus
2534 // --------
2536 typedef struct wuffs_base__rect_ii_u32__struct {
2537 uint32_t min_incl_x;
2538 uint32_t min_incl_y;
2539 uint32_t max_incl_x;
2540 uint32_t max_incl_y;
2542 #ifdef __cplusplus
2543 inline bool is_empty() const;
2544 inline bool equals(wuffs_base__rect_ii_u32__struct s) const;
2545 inline wuffs_base__rect_ii_u32__struct intersect(
2546 wuffs_base__rect_ii_u32__struct s) const;
2547 inline wuffs_base__rect_ii_u32__struct unite(
2548 wuffs_base__rect_ii_u32__struct s) const;
2549 inline bool contains(uint32_t x, uint32_t y) const;
2550 inline bool contains_rect(wuffs_base__rect_ii_u32__struct s) const;
2551 #endif // __cplusplus
2553 } wuffs_base__rect_ii_u32;
2555 static inline wuffs_base__rect_ii_u32 //
2556 wuffs_base__empty_rect_ii_u32(void) {
2557 wuffs_base__rect_ii_u32 ret;
2558 ret.min_incl_x = 0;
2559 ret.min_incl_y = 0;
2560 ret.max_incl_x = 0;
2561 ret.max_incl_y = 0;
2562 return ret;
2565 static inline wuffs_base__rect_ii_u32 //
2566 wuffs_base__make_rect_ii_u32(uint32_t min_incl_x,
2567 uint32_t min_incl_y,
2568 uint32_t max_incl_x,
2569 uint32_t max_incl_y) {
2570 wuffs_base__rect_ii_u32 ret;
2571 ret.min_incl_x = min_incl_x;
2572 ret.min_incl_y = min_incl_y;
2573 ret.max_incl_x = max_incl_x;
2574 ret.max_incl_y = max_incl_y;
2575 return ret;
2578 static inline bool //
2579 wuffs_base__rect_ii_u32__is_empty(const wuffs_base__rect_ii_u32* r) {
2580 return (r->min_incl_x > r->max_incl_x) || (r->min_incl_y > r->max_incl_y);
2583 static inline bool //
2584 wuffs_base__rect_ii_u32__equals(const wuffs_base__rect_ii_u32* r,
2585 wuffs_base__rect_ii_u32 s) {
2586 return (r->min_incl_x == s.min_incl_x && r->min_incl_y == s.min_incl_y &&
2587 r->max_incl_x == s.max_incl_x && r->max_incl_y == s.max_incl_y) ||
2588 (wuffs_base__rect_ii_u32__is_empty(r) &&
2589 wuffs_base__rect_ii_u32__is_empty(&s));
2592 static inline wuffs_base__rect_ii_u32 //
2593 wuffs_base__rect_ii_u32__intersect(const wuffs_base__rect_ii_u32* r,
2594 wuffs_base__rect_ii_u32 s) {
2595 wuffs_base__rect_ii_u32 t;
2596 t.min_incl_x = wuffs_base__u32__max(r->min_incl_x, s.min_incl_x);
2597 t.min_incl_y = wuffs_base__u32__max(r->min_incl_y, s.min_incl_y);
2598 t.max_incl_x = wuffs_base__u32__min(r->max_incl_x, s.max_incl_x);
2599 t.max_incl_y = wuffs_base__u32__min(r->max_incl_y, s.max_incl_y);
2600 return t;
2603 static inline wuffs_base__rect_ii_u32 //
2604 wuffs_base__rect_ii_u32__unite(const wuffs_base__rect_ii_u32* r,
2605 wuffs_base__rect_ii_u32 s) {
2606 if (wuffs_base__rect_ii_u32__is_empty(r)) {
2607 return s;
2609 if (wuffs_base__rect_ii_u32__is_empty(&s)) {
2610 return *r;
2612 wuffs_base__rect_ii_u32 t;
2613 t.min_incl_x = wuffs_base__u32__min(r->min_incl_x, s.min_incl_x);
2614 t.min_incl_y = wuffs_base__u32__min(r->min_incl_y, s.min_incl_y);
2615 t.max_incl_x = wuffs_base__u32__max(r->max_incl_x, s.max_incl_x);
2616 t.max_incl_y = wuffs_base__u32__max(r->max_incl_y, s.max_incl_y);
2617 return t;
2620 static inline bool //
2621 wuffs_base__rect_ii_u32__contains(const wuffs_base__rect_ii_u32* r,
2622 uint32_t x,
2623 uint32_t y) {
2624 return (r->min_incl_x <= x) && (x <= r->max_incl_x) && (r->min_incl_y <= y) &&
2625 (y <= r->max_incl_y);
2628 static inline bool //
2629 wuffs_base__rect_ii_u32__contains_rect(const wuffs_base__rect_ii_u32* r,
2630 wuffs_base__rect_ii_u32 s) {
2631 return wuffs_base__rect_ii_u32__equals(
2632 &s, wuffs_base__rect_ii_u32__intersect(r, s));
2635 #ifdef __cplusplus
2637 inline bool //
2638 wuffs_base__rect_ii_u32::is_empty() const {
2639 return wuffs_base__rect_ii_u32__is_empty(this);
2642 inline bool //
2643 wuffs_base__rect_ii_u32::equals(wuffs_base__rect_ii_u32 s) const {
2644 return wuffs_base__rect_ii_u32__equals(this, s);
2647 inline wuffs_base__rect_ii_u32 //
2648 wuffs_base__rect_ii_u32::intersect(wuffs_base__rect_ii_u32 s) const {
2649 return wuffs_base__rect_ii_u32__intersect(this, s);
2652 inline wuffs_base__rect_ii_u32 //
2653 wuffs_base__rect_ii_u32::unite(wuffs_base__rect_ii_u32 s) const {
2654 return wuffs_base__rect_ii_u32__unite(this, s);
2657 inline bool //
2658 wuffs_base__rect_ii_u32::contains(uint32_t x, uint32_t y) const {
2659 return wuffs_base__rect_ii_u32__contains(this, x, y);
2662 inline bool //
2663 wuffs_base__rect_ii_u32::contains_rect(wuffs_base__rect_ii_u32 s) const {
2664 return wuffs_base__rect_ii_u32__contains_rect(this, s);
2667 #endif // __cplusplus
2669 // --------
2671 typedef struct wuffs_base__rect_ie_u32__struct {
2672 uint32_t min_incl_x;
2673 uint32_t min_incl_y;
2674 uint32_t max_excl_x;
2675 uint32_t max_excl_y;
2677 #ifdef __cplusplus
2678 inline bool is_empty() const;
2679 inline bool equals(wuffs_base__rect_ie_u32__struct s) const;
2680 inline wuffs_base__rect_ie_u32__struct intersect(
2681 wuffs_base__rect_ie_u32__struct s) const;
2682 inline wuffs_base__rect_ie_u32__struct unite(
2683 wuffs_base__rect_ie_u32__struct s) const;
2684 inline bool contains(uint32_t x, uint32_t y) const;
2685 inline bool contains_rect(wuffs_base__rect_ie_u32__struct s) const;
2686 inline uint32_t width() const;
2687 inline uint32_t height() const;
2688 #endif // __cplusplus
2690 } wuffs_base__rect_ie_u32;
2692 static inline wuffs_base__rect_ie_u32 //
2693 wuffs_base__empty_rect_ie_u32(void) {
2694 wuffs_base__rect_ie_u32 ret;
2695 ret.min_incl_x = 0;
2696 ret.min_incl_y = 0;
2697 ret.max_excl_x = 0;
2698 ret.max_excl_y = 0;
2699 return ret;
2702 static inline wuffs_base__rect_ie_u32 //
2703 wuffs_base__make_rect_ie_u32(uint32_t min_incl_x,
2704 uint32_t min_incl_y,
2705 uint32_t max_excl_x,
2706 uint32_t max_excl_y) {
2707 wuffs_base__rect_ie_u32 ret;
2708 ret.min_incl_x = min_incl_x;
2709 ret.min_incl_y = min_incl_y;
2710 ret.max_excl_x = max_excl_x;
2711 ret.max_excl_y = max_excl_y;
2712 return ret;
2715 static inline bool //
2716 wuffs_base__rect_ie_u32__is_empty(const wuffs_base__rect_ie_u32* r) {
2717 return (r->min_incl_x >= r->max_excl_x) || (r->min_incl_y >= r->max_excl_y);
2720 static inline bool //
2721 wuffs_base__rect_ie_u32__equals(const wuffs_base__rect_ie_u32* r,
2722 wuffs_base__rect_ie_u32 s) {
2723 return (r->min_incl_x == s.min_incl_x && r->min_incl_y == s.min_incl_y &&
2724 r->max_excl_x == s.max_excl_x && r->max_excl_y == s.max_excl_y) ||
2725 (wuffs_base__rect_ie_u32__is_empty(r) &&
2726 wuffs_base__rect_ie_u32__is_empty(&s));
2729 static inline wuffs_base__rect_ie_u32 //
2730 wuffs_base__rect_ie_u32__intersect(const wuffs_base__rect_ie_u32* r,
2731 wuffs_base__rect_ie_u32 s) {
2732 wuffs_base__rect_ie_u32 t;
2733 t.min_incl_x = wuffs_base__u32__max(r->min_incl_x, s.min_incl_x);
2734 t.min_incl_y = wuffs_base__u32__max(r->min_incl_y, s.min_incl_y);
2735 t.max_excl_x = wuffs_base__u32__min(r->max_excl_x, s.max_excl_x);
2736 t.max_excl_y = wuffs_base__u32__min(r->max_excl_y, s.max_excl_y);
2737 return t;
2740 static inline wuffs_base__rect_ie_u32 //
2741 wuffs_base__rect_ie_u32__unite(const wuffs_base__rect_ie_u32* r,
2742 wuffs_base__rect_ie_u32 s) {
2743 if (wuffs_base__rect_ie_u32__is_empty(r)) {
2744 return s;
2746 if (wuffs_base__rect_ie_u32__is_empty(&s)) {
2747 return *r;
2749 wuffs_base__rect_ie_u32 t;
2750 t.min_incl_x = wuffs_base__u32__min(r->min_incl_x, s.min_incl_x);
2751 t.min_incl_y = wuffs_base__u32__min(r->min_incl_y, s.min_incl_y);
2752 t.max_excl_x = wuffs_base__u32__max(r->max_excl_x, s.max_excl_x);
2753 t.max_excl_y = wuffs_base__u32__max(r->max_excl_y, s.max_excl_y);
2754 return t;
2757 static inline bool //
2758 wuffs_base__rect_ie_u32__contains(const wuffs_base__rect_ie_u32* r,
2759 uint32_t x,
2760 uint32_t y) {
2761 return (r->min_incl_x <= x) && (x < r->max_excl_x) && (r->min_incl_y <= y) &&
2762 (y < r->max_excl_y);
2765 static inline bool //
2766 wuffs_base__rect_ie_u32__contains_rect(const wuffs_base__rect_ie_u32* r,
2767 wuffs_base__rect_ie_u32 s) {
2768 return wuffs_base__rect_ie_u32__equals(
2769 &s, wuffs_base__rect_ie_u32__intersect(r, s));
2772 static inline uint32_t //
2773 wuffs_base__rect_ie_u32__width(const wuffs_base__rect_ie_u32* r) {
2774 return wuffs_base__u32__sat_sub(r->max_excl_x, r->min_incl_x);
2777 static inline uint32_t //
2778 wuffs_base__rect_ie_u32__height(const wuffs_base__rect_ie_u32* r) {
2779 return wuffs_base__u32__sat_sub(r->max_excl_y, r->min_incl_y);
2782 #ifdef __cplusplus
2784 inline bool //
2785 wuffs_base__rect_ie_u32::is_empty() const {
2786 return wuffs_base__rect_ie_u32__is_empty(this);
2789 inline bool //
2790 wuffs_base__rect_ie_u32::equals(wuffs_base__rect_ie_u32 s) const {
2791 return wuffs_base__rect_ie_u32__equals(this, s);
2794 inline wuffs_base__rect_ie_u32 //
2795 wuffs_base__rect_ie_u32::intersect(wuffs_base__rect_ie_u32 s) const {
2796 return wuffs_base__rect_ie_u32__intersect(this, s);
2799 inline wuffs_base__rect_ie_u32 //
2800 wuffs_base__rect_ie_u32::unite(wuffs_base__rect_ie_u32 s) const {
2801 return wuffs_base__rect_ie_u32__unite(this, s);
2804 inline bool //
2805 wuffs_base__rect_ie_u32::contains(uint32_t x, uint32_t y) const {
2806 return wuffs_base__rect_ie_u32__contains(this, x, y);
2809 inline bool //
2810 wuffs_base__rect_ie_u32::contains_rect(wuffs_base__rect_ie_u32 s) const {
2811 return wuffs_base__rect_ie_u32__contains_rect(this, s);
2814 inline uint32_t //
2815 wuffs_base__rect_ie_u32::width() const {
2816 return wuffs_base__rect_ie_u32__width(this);
2819 inline uint32_t //
2820 wuffs_base__rect_ie_u32::height() const {
2821 return wuffs_base__rect_ie_u32__height(this);
2824 #endif // __cplusplus
2826 // ---------------- More Information
2828 // wuffs_base__more_information holds additional fields, typically when a Wuffs
2829 // method returns a [note status](/doc/note/statuses.md).
2831 // The flavor field follows the base38 namespace
2832 // convention](/doc/note/base38-and-fourcc.md). The other fields' semantics
2833 // depends on the flavor.
2834 typedef struct wuffs_base__more_information__struct {
2835 uint32_t flavor;
2836 uint32_t w;
2837 uint64_t x;
2838 uint64_t y;
2839 uint64_t z;
2841 #ifdef __cplusplus
2842 inline void set(uint32_t flavor_arg,
2843 uint32_t w_arg,
2844 uint64_t x_arg,
2845 uint64_t y_arg,
2846 uint64_t z_arg);
2847 inline uint32_t io_redirect__fourcc() const;
2848 inline wuffs_base__range_ie_u64 io_redirect__range() const;
2849 inline uint64_t io_seek__position() const;
2850 inline uint32_t metadata__fourcc() const;
2851 inline wuffs_base__range_ie_u64 metadata_raw_passthrough__range() const;
2852 inline int32_t metadata_parsed__chrm(uint32_t component) const;
2853 inline uint32_t metadata_parsed__gama() const;
2854 inline uint32_t metadata_parsed__srgb() const;
2855 #endif // __cplusplus
2857 } wuffs_base__more_information;
2859 #define WUFFS_BASE__MORE_INFORMATION__FLAVOR__IO_REDIRECT 1
2860 #define WUFFS_BASE__MORE_INFORMATION__FLAVOR__IO_SEEK 2
2861 #define WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_RAW_PASSTHROUGH 3
2862 #define WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_RAW_TRANSFORM 4
2863 #define WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_PARSED 5
2865 static inline wuffs_base__more_information //
2866 wuffs_base__empty_more_information(void) {
2867 wuffs_base__more_information ret;
2868 ret.flavor = 0;
2869 ret.w = 0;
2870 ret.x = 0;
2871 ret.y = 0;
2872 ret.z = 0;
2873 return ret;
2876 static inline void //
2877 wuffs_base__more_information__set(wuffs_base__more_information* m,
2878 uint32_t flavor,
2879 uint32_t w,
2880 uint64_t x,
2881 uint64_t y,
2882 uint64_t z) {
2883 if (!m) {
2884 return;
2886 m->flavor = flavor;
2887 m->w = w;
2888 m->x = x;
2889 m->y = y;
2890 m->z = z;
2893 static inline uint32_t //
2894 wuffs_base__more_information__io_redirect__fourcc(
2895 const wuffs_base__more_information* m) {
2896 return m->w;
2899 static inline wuffs_base__range_ie_u64 //
2900 wuffs_base__more_information__io_redirect__range(
2901 const wuffs_base__more_information* m) {
2902 wuffs_base__range_ie_u64 ret;
2903 ret.min_incl = m->y;
2904 ret.max_excl = m->z;
2905 return ret;
2908 static inline uint64_t //
2909 wuffs_base__more_information__io_seek__position(
2910 const wuffs_base__more_information* m) {
2911 return m->x;
2914 static inline uint32_t //
2915 wuffs_base__more_information__metadata__fourcc(
2916 const wuffs_base__more_information* m) {
2917 return m->w;
2920 static inline wuffs_base__range_ie_u64 //
2921 wuffs_base__more_information__metadata_raw_passthrough__range(
2922 const wuffs_base__more_information* m) {
2923 wuffs_base__range_ie_u64 ret;
2924 ret.min_incl = m->y;
2925 ret.max_excl = m->z;
2926 return ret;
2929 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__WHITE_X 0
2930 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__WHITE_Y 1
2931 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__RED_X 2
2932 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__RED_Y 3
2933 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__GREEN_X 4
2934 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__GREEN_Y 5
2935 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__BLUE_X 6
2936 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__BLUE_Y 7
2938 // wuffs_base__more_information__metadata_parsed__chrm returns chromaticity
2939 // values (scaled by 100000) like the PNG "cHRM" chunk. For example, the sRGB
2940 // color space corresponds to:
2941 // - ETC__CHRM__WHITE_X 31270
2942 // - ETC__CHRM__WHITE_Y 32900
2943 // - ETC__CHRM__RED_X 64000
2944 // - ETC__CHRM__RED_Y 33000
2945 // - ETC__CHRM__GREEN_X 30000
2946 // - ETC__CHRM__GREEN_Y 60000
2947 // - ETC__CHRM__BLUE_X 15000
2948 // - ETC__CHRM__BLUE_Y 6000
2950 // See
2951 // https://ciechanow.ski/color-spaces/#chromaticity-and-white-point-coordinates
2952 static inline int32_t //
2953 wuffs_base__more_information__metadata_parsed__chrm(
2954 const wuffs_base__more_information* m,
2955 uint32_t component) {
2956 // After the flavor and the w field (holding a FourCC), a
2957 // wuffs_base__more_information holds 24 bytes of data in three uint64_t
2958 // typed fields (x, y and z). We pack the eight chromaticity values (wx, wy,
2959 // rx, ..., by), basically int24_t values, into 24 bytes like this:
2960 // - LSB MSB
2961 // - x: wx wx wx wy wy wy rx rx
2962 // - y: rx ry ry ry gx gx gx gy
2963 // - z: gy gy bx bx bx by by by
2964 uint32_t u = 0;
2965 switch (component & 7) {
2966 case 0:
2967 u = ((uint32_t)(m->x >> 0));
2968 break;
2969 case 1:
2970 u = ((uint32_t)(m->x >> 24));
2971 break;
2972 case 2:
2973 u = ((uint32_t)((m->x >> 48) | (m->y << 16)));
2974 break;
2975 case 3:
2976 u = ((uint32_t)(m->y >> 8));
2977 break;
2978 case 4:
2979 u = ((uint32_t)(m->y >> 32));
2980 break;
2981 case 5:
2982 u = ((uint32_t)((m->y >> 56) | (m->z << 8)));
2983 break;
2984 case 6:
2985 u = ((uint32_t)(m->z >> 16));
2986 break;
2987 case 7:
2988 u = ((uint32_t)(m->z >> 40));
2989 break;
2991 // The left-right shifts sign-extend from 24-bit to 32-bit integers.
2992 return ((int32_t)(u << 8)) >> 8;
2995 // wuffs_base__more_information__metadata_parsed__gama returns inverse gamma
2996 // correction values (scaled by 100000) like the PNG "gAMA" chunk. For example,
2997 // for gamma = 2.2, this returns 45455 (approximating 100000 / 2.2).
2998 static inline uint32_t //
2999 wuffs_base__more_information__metadata_parsed__gama(
3000 const wuffs_base__more_information* m) {
3001 return ((uint32_t)(m->x));
3004 #define WUFFS_BASE__SRGB_RENDERING_INTENT__PERCEPTUAL 0
3005 #define WUFFS_BASE__SRGB_RENDERING_INTENT__RELATIVE_COLORIMETRIC 1
3006 #define WUFFS_BASE__SRGB_RENDERING_INTENT__SATURATION 2
3007 #define WUFFS_BASE__SRGB_RENDERING_INTENT__ABSOLUTE_COLORIMETRIC 3
3009 // wuffs_base__more_information__metadata_parsed__srgb returns the sRGB
3010 // rendering intent like the PNG "sRGB" chunk.
3011 static inline uint32_t //
3012 wuffs_base__more_information__metadata_parsed__srgb(
3013 const wuffs_base__more_information* m) {
3014 return m->x & 3;
3017 #ifdef __cplusplus
3019 inline void //
3020 wuffs_base__more_information::set(uint32_t flavor_arg,
3021 uint32_t w_arg,
3022 uint64_t x_arg,
3023 uint64_t y_arg,
3024 uint64_t z_arg) {
3025 wuffs_base__more_information__set(this, flavor_arg, w_arg, x_arg, y_arg,
3026 z_arg);
3029 inline uint32_t //
3030 wuffs_base__more_information::io_redirect__fourcc() const {
3031 return wuffs_base__more_information__io_redirect__fourcc(this);
3034 inline wuffs_base__range_ie_u64 //
3035 wuffs_base__more_information::io_redirect__range() const {
3036 return wuffs_base__more_information__io_redirect__range(this);
3039 inline uint64_t //
3040 wuffs_base__more_information::io_seek__position() const {
3041 return wuffs_base__more_information__io_seek__position(this);
3044 inline uint32_t //
3045 wuffs_base__more_information::metadata__fourcc() const {
3046 return wuffs_base__more_information__metadata__fourcc(this);
3049 inline wuffs_base__range_ie_u64 //
3050 wuffs_base__more_information::metadata_raw_passthrough__range() const {
3051 return wuffs_base__more_information__metadata_raw_passthrough__range(this);
3054 inline int32_t //
3055 wuffs_base__more_information::metadata_parsed__chrm(uint32_t component) const {
3056 return wuffs_base__more_information__metadata_parsed__chrm(this, component);
3059 inline uint32_t //
3060 wuffs_base__more_information::metadata_parsed__gama() const {
3061 return wuffs_base__more_information__metadata_parsed__gama(this);
3064 inline uint32_t //
3065 wuffs_base__more_information::metadata_parsed__srgb() const {
3066 return wuffs_base__more_information__metadata_parsed__srgb(this);
3069 #endif // __cplusplus
3071 // ---------------- I/O
3073 // See (/doc/note/io-input-output.md).
3075 // wuffs_base__io_buffer_meta is the metadata for a wuffs_base__io_buffer's
3076 // data.
3077 typedef struct wuffs_base__io_buffer_meta__struct {
3078 size_t wi; // Write index. Invariant: wi <= len.
3079 size_t ri; // Read index. Invariant: ri <= wi.
3080 uint64_t pos; // Buffer position (relative to the start of stream).
3081 bool closed; // No further writes are expected.
3082 } wuffs_base__io_buffer_meta;
3084 // wuffs_base__io_buffer is a 1-dimensional buffer (a pointer and length) plus
3085 // additional metadata.
3087 // A value with all fields zero is a valid, empty buffer.
3088 typedef struct wuffs_base__io_buffer__struct {
3089 wuffs_base__slice_u8 data;
3090 wuffs_base__io_buffer_meta meta;
3092 #ifdef __cplusplus
3093 inline bool is_valid() const;
3094 inline void compact();
3095 inline void compact_retaining(uint64_t history_retain_length);
3096 inline size_t reader_length() const;
3097 inline uint8_t* reader_pointer() const;
3098 inline uint64_t reader_position() const;
3099 inline wuffs_base__slice_u8 reader_slice() const;
3100 inline size_t writer_length() const;
3101 inline uint8_t* writer_pointer() const;
3102 inline uint64_t writer_position() const;
3103 inline wuffs_base__slice_u8 writer_slice() const;
3104 #endif // __cplusplus
3106 } wuffs_base__io_buffer;
3108 static inline wuffs_base__io_buffer //
3109 wuffs_base__make_io_buffer(wuffs_base__slice_u8 data,
3110 wuffs_base__io_buffer_meta meta) {
3111 wuffs_base__io_buffer ret;
3112 ret.data = data;
3113 ret.meta = meta;
3114 return ret;
3117 static inline wuffs_base__io_buffer_meta //
3118 wuffs_base__make_io_buffer_meta(size_t wi,
3119 size_t ri,
3120 uint64_t pos,
3121 bool closed) {
3122 wuffs_base__io_buffer_meta ret;
3123 ret.wi = wi;
3124 ret.ri = ri;
3125 ret.pos = pos;
3126 ret.closed = closed;
3127 return ret;
3130 static inline wuffs_base__io_buffer //
3131 wuffs_base__ptr_u8__reader(uint8_t* ptr, size_t len, bool closed) {
3132 wuffs_base__io_buffer ret;
3133 ret.data.ptr = ptr;
3134 ret.data.len = len;
3135 ret.meta.wi = len;
3136 ret.meta.ri = 0;
3137 ret.meta.pos = 0;
3138 ret.meta.closed = closed;
3139 return ret;
3142 static inline wuffs_base__io_buffer //
3143 wuffs_base__ptr_u8__writer(uint8_t* ptr, size_t len) {
3144 wuffs_base__io_buffer ret;
3145 ret.data.ptr = ptr;
3146 ret.data.len = len;
3147 ret.meta.wi = 0;
3148 ret.meta.ri = 0;
3149 ret.meta.pos = 0;
3150 ret.meta.closed = false;
3151 return ret;
3154 static inline wuffs_base__io_buffer //
3155 wuffs_base__slice_u8__reader(wuffs_base__slice_u8 s, bool closed) {
3156 wuffs_base__io_buffer ret;
3157 ret.data.ptr = s.ptr;
3158 ret.data.len = s.len;
3159 ret.meta.wi = s.len;
3160 ret.meta.ri = 0;
3161 ret.meta.pos = 0;
3162 ret.meta.closed = closed;
3163 return ret;
3166 static inline wuffs_base__io_buffer //
3167 wuffs_base__slice_u8__writer(wuffs_base__slice_u8 s) {
3168 wuffs_base__io_buffer ret;
3169 ret.data.ptr = s.ptr;
3170 ret.data.len = s.len;
3171 ret.meta.wi = 0;
3172 ret.meta.ri = 0;
3173 ret.meta.pos = 0;
3174 ret.meta.closed = false;
3175 return ret;
3178 static inline wuffs_base__io_buffer //
3179 wuffs_base__empty_io_buffer(void) {
3180 wuffs_base__io_buffer ret;
3181 ret.data.ptr = NULL;
3182 ret.data.len = 0;
3183 ret.meta.wi = 0;
3184 ret.meta.ri = 0;
3185 ret.meta.pos = 0;
3186 ret.meta.closed = false;
3187 return ret;
3190 static inline wuffs_base__io_buffer_meta //
3191 wuffs_base__empty_io_buffer_meta(void) {
3192 wuffs_base__io_buffer_meta ret;
3193 ret.wi = 0;
3194 ret.ri = 0;
3195 ret.pos = 0;
3196 ret.closed = false;
3197 return ret;
3200 static inline bool //
3201 wuffs_base__io_buffer__is_valid(const wuffs_base__io_buffer* buf) {
3202 if (buf) {
3203 if (buf->data.ptr) {
3204 return (buf->meta.ri <= buf->meta.wi) && (buf->meta.wi <= buf->data.len);
3205 } else {
3206 return (buf->meta.ri == 0) && (buf->meta.wi == 0) && (buf->data.len == 0);
3209 return false;
3212 // wuffs_base__io_buffer__compact moves any written but unread bytes to the
3213 // start of the buffer.
3214 static inline void //
3215 wuffs_base__io_buffer__compact(wuffs_base__io_buffer* buf) {
3216 if (!buf || (buf->meta.ri == 0)) {
3217 return;
3219 buf->meta.pos = wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.ri);
3220 size_t new_wi = buf->meta.wi - buf->meta.ri;
3221 if (new_wi != 0) {
3222 memmove(buf->data.ptr, buf->data.ptr + buf->meta.ri, new_wi);
3224 buf->meta.wi = new_wi;
3225 buf->meta.ri = 0;
3228 // wuffs_base__io_buffer__compact_retaining moves any written but unread bytes
3229 // closer to the start of the buffer. It retains H bytes of history (the most
3230 // recently read bytes), where H is min(buf->meta.ri, history_retain_length).
3231 // It is therefore a no-op if history_retain_length is UINT64_MAX. A
3232 // postcondition is that buf->meta.ri == H.
3234 // wuffs_base__io_buffer__compact_retaining(0) is equivalent to
3235 // wuffs_base__io_buffer__compact().
3237 // For example, if buf started like this:
3239 // +--- ri = 3
3240 // v
3241 // abcdefgh?? len = 10, pos = 900
3242 // ^
3243 // +--- wi = 8
3245 // Then, depending on history_retain_length, the resultant buf would be:
3247 // HRL = 0 defgh????? ri = 0 wi = 5 pos = 903
3248 // HRL = 1 cdefgh???? ri = 1 wi = 6 pos = 902
3249 // HRL = 2 bcdefgh??? ri = 2 wi = 7 pos = 901
3250 // HRL = 3 abcdefgh?? ri = 3 wi = 8 pos = 900
3251 // HRL = 4+ abcdefgh?? ri = 3 wi = 8 pos = 900
3252 static inline void //
3253 wuffs_base__io_buffer__compact_retaining(wuffs_base__io_buffer* buf,
3254 uint64_t history_retain_length) {
3255 if (!buf || (buf->meta.ri == 0)) {
3256 return;
3258 size_t old_ri = buf->meta.ri;
3259 size_t new_ri = (size_t)(wuffs_base__u64__min(old_ri, history_retain_length));
3260 size_t memmove_start = old_ri - new_ri;
3261 buf->meta.pos = wuffs_base__u64__sat_add(buf->meta.pos, memmove_start);
3262 size_t new_wi = buf->meta.wi - memmove_start;
3263 if ((new_wi != 0) && (memmove_start != 0)) {
3264 memmove(buf->data.ptr, buf->data.ptr + memmove_start, new_wi);
3266 buf->meta.wi = new_wi;
3267 buf->meta.ri = new_ri;
3270 static inline size_t //
3271 wuffs_base__io_buffer__reader_length(const wuffs_base__io_buffer* buf) {
3272 return buf ? buf->meta.wi - buf->meta.ri : 0;
3275 static inline uint8_t* //
3276 wuffs_base__io_buffer__reader_pointer(const wuffs_base__io_buffer* buf) {
3277 return (buf && buf->data.ptr) ? (buf->data.ptr + buf->meta.ri) : NULL;
3280 static inline uint64_t //
3281 wuffs_base__io_buffer__reader_position(const wuffs_base__io_buffer* buf) {
3282 return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.ri) : 0;
3285 static inline wuffs_base__slice_u8 //
3286 wuffs_base__io_buffer__reader_slice(const wuffs_base__io_buffer* buf) {
3287 return (buf && buf->data.ptr)
3288 ? wuffs_base__make_slice_u8(buf->data.ptr + buf->meta.ri,
3289 buf->meta.wi - buf->meta.ri)
3290 : wuffs_base__empty_slice_u8();
3293 static inline size_t //
3294 wuffs_base__io_buffer__writer_length(const wuffs_base__io_buffer* buf) {
3295 return buf ? buf->data.len - buf->meta.wi : 0;
3298 static inline uint8_t* //
3299 wuffs_base__io_buffer__writer_pointer(const wuffs_base__io_buffer* buf) {
3300 return (buf && buf->data.ptr) ? (buf->data.ptr + buf->meta.wi) : NULL;
3303 static inline uint64_t //
3304 wuffs_base__io_buffer__writer_position(const wuffs_base__io_buffer* buf) {
3305 return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.wi) : 0;
3308 static inline wuffs_base__slice_u8 //
3309 wuffs_base__io_buffer__writer_slice(const wuffs_base__io_buffer* buf) {
3310 return (buf && buf->data.ptr)
3311 ? wuffs_base__make_slice_u8(buf->data.ptr + buf->meta.wi,
3312 buf->data.len - buf->meta.wi)
3313 : wuffs_base__empty_slice_u8();
3316 #ifdef __cplusplus
3318 inline bool //
3319 wuffs_base__io_buffer::is_valid() const {
3320 return wuffs_base__io_buffer__is_valid(this);
3323 inline void //
3324 wuffs_base__io_buffer::compact() {
3325 wuffs_base__io_buffer__compact(this);
3328 inline void //
3329 wuffs_base__io_buffer::compact_retaining(uint64_t history_retain_length) {
3330 wuffs_base__io_buffer__compact_retaining(this, history_retain_length);
3333 inline size_t //
3334 wuffs_base__io_buffer::reader_length() const {
3335 return wuffs_base__io_buffer__reader_length(this);
3338 inline uint8_t* //
3339 wuffs_base__io_buffer::reader_pointer() const {
3340 return wuffs_base__io_buffer__reader_pointer(this);
3343 inline uint64_t //
3344 wuffs_base__io_buffer::reader_position() const {
3345 return wuffs_base__io_buffer__reader_position(this);
3348 inline wuffs_base__slice_u8 //
3349 wuffs_base__io_buffer::reader_slice() const {
3350 return wuffs_base__io_buffer__reader_slice(this);
3353 inline size_t //
3354 wuffs_base__io_buffer::writer_length() const {
3355 return wuffs_base__io_buffer__writer_length(this);
3358 inline uint8_t* //
3359 wuffs_base__io_buffer::writer_pointer() const {
3360 return wuffs_base__io_buffer__writer_pointer(this);
3363 inline uint64_t //
3364 wuffs_base__io_buffer::writer_position() const {
3365 return wuffs_base__io_buffer__writer_position(this);
3368 inline wuffs_base__slice_u8 //
3369 wuffs_base__io_buffer::writer_slice() const {
3370 return wuffs_base__io_buffer__writer_slice(this);
3373 #endif // __cplusplus
3375 // ---------------- Tokens
3377 // wuffs_base__token is an element of a byte stream's tokenization.
3379 // See https://github.com/google/wuffs/blob/main/doc/note/tokens.md
3380 typedef struct wuffs_base__token__struct {
3381 uint64_t repr;
3383 #ifdef __cplusplus
3384 inline int64_t value() const;
3385 inline int64_t value_extension() const;
3386 inline int64_t value_major() const;
3387 inline int64_t value_base_category() const;
3388 inline uint64_t value_minor() const;
3389 inline uint64_t value_base_detail() const;
3390 inline int64_t value_base_detail__sign_extended() const;
3391 inline bool continued() const;
3392 inline uint64_t length() const;
3393 #endif // __cplusplus
3395 } wuffs_base__token;
3397 static inline wuffs_base__token //
3398 wuffs_base__make_token(uint64_t repr) {
3399 wuffs_base__token ret;
3400 ret.repr = repr;
3401 return ret;
3404 // --------
3406 // clang-format off
3408 // --------
3410 #define WUFFS_BASE__TOKEN__LENGTH__MAX_INCL 0xFFFF
3412 #define WUFFS_BASE__TOKEN__VALUE__SHIFT 17
3413 #define WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT 17
3414 #define WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT 42
3415 #define WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT 17
3416 #define WUFFS_BASE__TOKEN__VALUE_BASE_CATEGORY__SHIFT 38
3417 #define WUFFS_BASE__TOKEN__VALUE_BASE_DETAIL__SHIFT 17
3418 #define WUFFS_BASE__TOKEN__CONTINUED__SHIFT 16
3419 #define WUFFS_BASE__TOKEN__LENGTH__SHIFT 0
3421 #define WUFFS_BASE__TOKEN__VALUE_EXTENSION__NUM_BITS 46
3423 // --------
3425 #define WUFFS_BASE__TOKEN__VBC__FILLER 0
3426 #define WUFFS_BASE__TOKEN__VBC__STRUCTURE 1
3427 #define WUFFS_BASE__TOKEN__VBC__STRING 2
3428 #define WUFFS_BASE__TOKEN__VBC__UNICODE_CODE_POINT 3
3429 #define WUFFS_BASE__TOKEN__VBC__LITERAL 4
3430 #define WUFFS_BASE__TOKEN__VBC__NUMBER 5
3431 #define WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_SIGNED 6
3432 #define WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_UNSIGNED 7
3434 // --------
3436 #define WUFFS_BASE__TOKEN__VBD__FILLER__PUNCTUATION 0x00001
3437 #define WUFFS_BASE__TOKEN__VBD__FILLER__COMMENT_BLOCK 0x00002
3438 #define WUFFS_BASE__TOKEN__VBD__FILLER__COMMENT_LINE 0x00004
3440 // COMMENT_ANY is a bit-wise or of COMMENT_BLOCK AND COMMENT_LINE.
3441 #define WUFFS_BASE__TOKEN__VBD__FILLER__COMMENT_ANY 0x00006
3443 // --------
3445 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH 0x00001
3446 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__POP 0x00002
3447 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_NONE 0x00010
3448 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_LIST 0x00020
3449 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_DICT 0x00040
3450 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_NONE 0x01000
3451 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_LIST 0x02000
3452 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_DICT 0x04000
3454 // --------
3456 // DEFINITELY_FOO means that the destination bytes (and also the source bytes,
3457 // for 1_DST_1_SRC_COPY) are in the FOO format. Definitely means that the lack
3458 // of the bit means "maybe FOO". It does not necessarily mean "not FOO".
3460 // CHAIN_ETC means that decoding the entire token chain forms a UTF-8 or ASCII
3461 // string, not just this current token. CHAIN_ETC_UTF_8 therefore distinguishes
3462 // Unicode (UTF-8) strings from byte strings. MUST means that the the token
3463 // producer (e.g. parser) must verify this. SHOULD means that the token
3464 // consumer (e.g. renderer) should verify this.
3466 // When a CHAIN_ETC_UTF_8 bit is set, the parser must ensure that non-ASCII
3467 // code points (with multi-byte UTF-8 encodings) do not straddle token
3468 // boundaries. Checking UTF-8 validity can inspect each token separately.
3470 // The lack of any particular bit is conservative: it is valid for all-ASCII
3471 // strings, in a single- or multi-token chain, to have none of these bits set.
3472 #define WUFFS_BASE__TOKEN__VBD__STRING__DEFINITELY_UTF_8 0x00001
3473 #define WUFFS_BASE__TOKEN__VBD__STRING__CHAIN_MUST_BE_UTF_8 0x00002
3474 #define WUFFS_BASE__TOKEN__VBD__STRING__CHAIN_SHOULD_BE_UTF_8 0x00004
3475 #define WUFFS_BASE__TOKEN__VBD__STRING__DEFINITELY_ASCII 0x00010
3476 #define WUFFS_BASE__TOKEN__VBD__STRING__CHAIN_MUST_BE_ASCII 0x00020
3477 #define WUFFS_BASE__TOKEN__VBD__STRING__CHAIN_SHOULD_BE_ASCII 0x00040
3479 // CONVERT_D_DST_S_SRC means that multiples of S source bytes (possibly padded)
3480 // produces multiples of D destination bytes. For example,
3481 // CONVERT_1_DST_4_SRC_BACKSLASH_X means a source like "\\x23\\x67\\xAB", where
3482 // 12 src bytes encode 3 dst bytes.
3484 // Post-processing may further transform those D destination bytes (e.g. treat
3485 // "\\xFF" as the Unicode code point U+00FF instead of the byte 0xFF), but that
3486 // is out of scope of this VBD's semantics.
3488 // When src is the empty string, multiple conversion algorithms are applicable
3489 // (so these bits are not necessarily mutually exclusive), all producing the
3490 // same empty dst string.
3491 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_0_DST_1_SRC_DROP 0x00100
3492 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_1_SRC_COPY 0x00200
3493 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_2_SRC_HEXADECIMAL 0x00400
3494 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_4_SRC_BACKSLASH_X 0x00800
3495 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_3_DST_4_SRC_BASE_64_STD 0x01000
3496 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_3_DST_4_SRC_BASE_64_URL 0x02000
3497 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_4_DST_5_SRC_ASCII_85 0x04000
3498 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_5_DST_8_SRC_BASE_32_HEX 0x08000
3499 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_5_DST_8_SRC_BASE_32_STD 0x10000
3501 // --------
3503 #define WUFFS_BASE__TOKEN__VBD__LITERAL__UNDEFINED 0x00001
3504 #define WUFFS_BASE__TOKEN__VBD__LITERAL__NULL 0x00002
3505 #define WUFFS_BASE__TOKEN__VBD__LITERAL__FALSE 0x00004
3506 #define WUFFS_BASE__TOKEN__VBD__LITERAL__TRUE 0x00008
3508 // --------
3510 // For a source string of "123" or "0x9A", it is valid for a tokenizer to
3511 // return any combination of:
3512 // - WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_FLOATING_POINT.
3513 // - WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_SIGNED.
3514 // - WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_UNSIGNED.
3516 // For a source string of "+123" or "-0x9A", only the first two are valid.
3518 // For a source string of "123.", only the first one is valid.
3519 #define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_FLOATING_POINT 0x00001
3520 #define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_SIGNED 0x00002
3521 #define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_UNSIGNED 0x00004
3523 #define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_NEG_INF 0x00010
3524 #define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_POS_INF 0x00020
3525 #define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_NEG_NAN 0x00040
3526 #define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_POS_NAN 0x00080
3528 // The number 300 might be represented as "\x01\x2C", "\x2C\x01\x00\x00" or
3529 // "300", which are big-endian, little-endian or text. For binary formats, the
3530 // token length (after adjusting for FORMAT_IGNORE_ETC) discriminates
3531 // e.g. u16 little-endian vs u32 little-endian.
3532 #define WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_BINARY_BIG_ENDIAN 0x00100
3533 #define WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_BINARY_LITTLE_ENDIAN 0x00200
3534 #define WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_TEXT 0x00400
3536 #define WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_IGNORE_FIRST_BYTE 0x01000
3538 // --------
3540 // clang-format on
3542 // --------
3544 // wuffs_base__token__value returns the token's high 46 bits, sign-extended. A
3545 // negative value means an extended token, non-negative means a simple token.
3546 static inline int64_t //
3547 wuffs_base__token__value(const wuffs_base__token* t) {
3548 return ((int64_t)(t->repr)) >> WUFFS_BASE__TOKEN__VALUE__SHIFT;
3551 // wuffs_base__token__value_extension returns a negative value if the token was
3552 // not an extended token.
3553 static inline int64_t //
3554 wuffs_base__token__value_extension(const wuffs_base__token* t) {
3555 return (~(int64_t)(t->repr)) >> WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT;
3558 // wuffs_base__token__value_major returns a negative value if the token was not
3559 // a simple token.
3560 static inline int64_t //
3561 wuffs_base__token__value_major(const wuffs_base__token* t) {
3562 return ((int64_t)(t->repr)) >> WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT;
3565 // wuffs_base__token__value_base_category returns a negative value if the token
3566 // was not a simple token.
3567 static inline int64_t //
3568 wuffs_base__token__value_base_category(const wuffs_base__token* t) {
3569 return ((int64_t)(t->repr)) >> WUFFS_BASE__TOKEN__VALUE_BASE_CATEGORY__SHIFT;
3572 static inline uint64_t //
3573 wuffs_base__token__value_minor(const wuffs_base__token* t) {
3574 return (t->repr >> WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) & 0x1FFFFFF;
3577 static inline uint64_t //
3578 wuffs_base__token__value_base_detail(const wuffs_base__token* t) {
3579 return (t->repr >> WUFFS_BASE__TOKEN__VALUE_BASE_DETAIL__SHIFT) & 0x1FFFFF;
3582 static inline int64_t //
3583 wuffs_base__token__value_base_detail__sign_extended(
3584 const wuffs_base__token* t) {
3585 // The VBD is 21 bits in the middle of t->repr. Left shift the high (64 - 21
3586 // - ETC__SHIFT) bits off, then right shift (sign-extending) back down.
3587 uint64_t u = t->repr << (43 - WUFFS_BASE__TOKEN__VALUE_BASE_DETAIL__SHIFT);
3588 return ((int64_t)u) >> 43;
3591 static inline bool //
3592 wuffs_base__token__continued(const wuffs_base__token* t) {
3593 return t->repr & 0x10000;
3596 static inline uint64_t //
3597 wuffs_base__token__length(const wuffs_base__token* t) {
3598 return (t->repr >> WUFFS_BASE__TOKEN__LENGTH__SHIFT) & 0xFFFF;
3601 #ifdef __cplusplus
3603 inline int64_t //
3604 wuffs_base__token::value() const {
3605 return wuffs_base__token__value(this);
3608 inline int64_t //
3609 wuffs_base__token::value_extension() const {
3610 return wuffs_base__token__value_extension(this);
3613 inline int64_t //
3614 wuffs_base__token::value_major() const {
3615 return wuffs_base__token__value_major(this);
3618 inline int64_t //
3619 wuffs_base__token::value_base_category() const {
3620 return wuffs_base__token__value_base_category(this);
3623 inline uint64_t //
3624 wuffs_base__token::value_minor() const {
3625 return wuffs_base__token__value_minor(this);
3628 inline uint64_t //
3629 wuffs_base__token::value_base_detail() const {
3630 return wuffs_base__token__value_base_detail(this);
3633 inline int64_t //
3634 wuffs_base__token::value_base_detail__sign_extended() const {
3635 return wuffs_base__token__value_base_detail__sign_extended(this);
3638 inline bool //
3639 wuffs_base__token::continued() const {
3640 return wuffs_base__token__continued(this);
3643 inline uint64_t //
3644 wuffs_base__token::length() const {
3645 return wuffs_base__token__length(this);
3648 #endif // __cplusplus
3650 // --------
3652 #if defined(__GNUC__)
3653 #pragma GCC diagnostic push
3654 #pragma GCC diagnostic ignored "-Wcast-qual"
3655 #endif
3657 static inline wuffs_base__token* //
3658 wuffs_base__strip_const_from_token_ptr(const wuffs_base__token* ptr) {
3659 return (wuffs_base__token*)ptr;
3662 #if defined(__GNUC__)
3663 #pragma GCC diagnostic pop
3664 #endif
3666 // --------
3668 typedef WUFFS_BASE__SLICE(wuffs_base__token) wuffs_base__slice_token;
3670 static inline wuffs_base__slice_token //
3671 wuffs_base__make_slice_token(wuffs_base__token* ptr, size_t len) {
3672 wuffs_base__slice_token ret;
3673 ret.ptr = ptr;
3674 ret.len = len;
3675 return ret;
3678 static inline wuffs_base__slice_token //
3679 wuffs_base__empty_slice_token(void) {
3680 wuffs_base__slice_token ret;
3681 ret.ptr = NULL;
3682 ret.len = 0;
3683 return ret;
3686 // --------
3688 // wuffs_base__token_buffer_meta is the metadata for a
3689 // wuffs_base__token_buffer's data.
3690 typedef struct wuffs_base__token_buffer_meta__struct {
3691 size_t wi; // Write index. Invariant: wi <= len.
3692 size_t ri; // Read index. Invariant: ri <= wi.
3693 uint64_t pos; // Position of the buffer start relative to the stream start.
3694 bool closed; // No further writes are expected.
3695 } wuffs_base__token_buffer_meta;
3697 // wuffs_base__token_buffer is a 1-dimensional buffer (a pointer and length)
3698 // plus additional metadata.
3700 // A value with all fields zero is a valid, empty buffer.
3701 typedef struct wuffs_base__token_buffer__struct {
3702 wuffs_base__slice_token data;
3703 wuffs_base__token_buffer_meta meta;
3705 #ifdef __cplusplus
3706 inline bool is_valid() const;
3707 inline void compact();
3708 inline void compact_retaining(uint64_t history_retain_length);
3709 inline uint64_t reader_length() const;
3710 inline wuffs_base__token* reader_pointer() const;
3711 inline wuffs_base__slice_token reader_slice() const;
3712 inline uint64_t reader_token_position() const;
3713 inline uint64_t writer_length() const;
3714 inline uint64_t writer_token_position() const;
3715 inline wuffs_base__token* writer_pointer() const;
3716 inline wuffs_base__slice_token writer_slice() const;
3717 #endif // __cplusplus
3719 } wuffs_base__token_buffer;
3721 static inline wuffs_base__token_buffer //
3722 wuffs_base__make_token_buffer(wuffs_base__slice_token data,
3723 wuffs_base__token_buffer_meta meta) {
3724 wuffs_base__token_buffer ret;
3725 ret.data = data;
3726 ret.meta = meta;
3727 return ret;
3730 static inline wuffs_base__token_buffer_meta //
3731 wuffs_base__make_token_buffer_meta(size_t wi,
3732 size_t ri,
3733 uint64_t pos,
3734 bool closed) {
3735 wuffs_base__token_buffer_meta ret;
3736 ret.wi = wi;
3737 ret.ri = ri;
3738 ret.pos = pos;
3739 ret.closed = closed;
3740 return ret;
3743 static inline wuffs_base__token_buffer //
3744 wuffs_base__slice_token__reader(wuffs_base__slice_token s, bool closed) {
3745 wuffs_base__token_buffer ret;
3746 ret.data.ptr = s.ptr;
3747 ret.data.len = s.len;
3748 ret.meta.wi = s.len;
3749 ret.meta.ri = 0;
3750 ret.meta.pos = 0;
3751 ret.meta.closed = closed;
3752 return ret;
3755 static inline wuffs_base__token_buffer //
3756 wuffs_base__slice_token__writer(wuffs_base__slice_token s) {
3757 wuffs_base__token_buffer ret;
3758 ret.data.ptr = s.ptr;
3759 ret.data.len = s.len;
3760 ret.meta.wi = 0;
3761 ret.meta.ri = 0;
3762 ret.meta.pos = 0;
3763 ret.meta.closed = false;
3764 return ret;
3767 static inline wuffs_base__token_buffer //
3768 wuffs_base__empty_token_buffer(void) {
3769 wuffs_base__token_buffer ret;
3770 ret.data.ptr = NULL;
3771 ret.data.len = 0;
3772 ret.meta.wi = 0;
3773 ret.meta.ri = 0;
3774 ret.meta.pos = 0;
3775 ret.meta.closed = false;
3776 return ret;
3779 static inline wuffs_base__token_buffer_meta //
3780 wuffs_base__empty_token_buffer_meta(void) {
3781 wuffs_base__token_buffer_meta ret;
3782 ret.wi = 0;
3783 ret.ri = 0;
3784 ret.pos = 0;
3785 ret.closed = false;
3786 return ret;
3789 static inline bool //
3790 wuffs_base__token_buffer__is_valid(const wuffs_base__token_buffer* buf) {
3791 if (buf) {
3792 if (buf->data.ptr) {
3793 return (buf->meta.ri <= buf->meta.wi) && (buf->meta.wi <= buf->data.len);
3794 } else {
3795 return (buf->meta.ri == 0) && (buf->meta.wi == 0) && (buf->data.len == 0);
3798 return false;
3801 // wuffs_base__token_buffer__compact moves any written but unread tokens to the
3802 // start of the buffer.
3803 static inline void //
3804 wuffs_base__token_buffer__compact(wuffs_base__token_buffer* buf) {
3805 if (!buf || (buf->meta.ri == 0)) {
3806 return;
3808 buf->meta.pos = wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.ri);
3809 size_t new_wi = buf->meta.wi - buf->meta.ri;
3810 if (new_wi != 0) {
3811 memmove(buf->data.ptr, buf->data.ptr + buf->meta.ri,
3812 new_wi * sizeof(wuffs_base__token));
3814 buf->meta.wi = new_wi;
3815 buf->meta.ri = 0;
3818 // wuffs_base__token_buffer__compact_retaining moves any written but unread
3819 // tokens closer to the start of the buffer. It retains H tokens of history
3820 // (the most recently read tokens), where H is min(buf->meta.ri,
3821 // history_retain_length). It is therefore a no-op if history_retain_length is
3822 // UINT64_MAX. A postcondition is that buf->meta.ri == H.
3824 // wuffs_base__token_buffer__compact_retaining(0) is equivalent to
3825 // wuffs_base__token_buffer__compact().
3827 // For example, if buf started like this:
3829 // +--- ri = 3
3830 // v
3831 // abcdefgh?? len = 10, pos = 900
3832 // ^
3833 // +--- wi = 8
3835 // Then, depending on history_retain_length, the resultant buf would be:
3837 // HRL = 0 defgh????? ri = 0 wi = 5 pos = 903
3838 // HRL = 1 cdefgh???? ri = 1 wi = 6 pos = 902
3839 // HRL = 2 bcdefgh??? ri = 2 wi = 7 pos = 901
3840 // HRL = 3 abcdefgh?? ri = 3 wi = 8 pos = 900
3841 // HRL = 4+ abcdefgh?? ri = 3 wi = 8 pos = 900
3842 static inline void //
3843 wuffs_base__token_buffer__compact_retaining(wuffs_base__token_buffer* buf,
3844 uint64_t history_retain_length) {
3845 if (!buf || (buf->meta.ri == 0)) {
3846 return;
3848 size_t old_ri = buf->meta.ri;
3849 size_t new_ri = (size_t)(wuffs_base__u64__min(old_ri, history_retain_length));
3850 size_t memmove_start = old_ri - new_ri;
3851 buf->meta.pos = wuffs_base__u64__sat_add(buf->meta.pos, memmove_start);
3852 size_t new_wi = buf->meta.wi - memmove_start;
3853 if ((new_wi != 0) && (memmove_start != 0)) {
3854 memmove(buf->data.ptr, buf->data.ptr + memmove_start,
3855 new_wi * sizeof(wuffs_base__token));
3857 buf->meta.wi = new_wi;
3858 buf->meta.ri = new_ri;
3861 static inline uint64_t //
3862 wuffs_base__token_buffer__reader_length(const wuffs_base__token_buffer* buf) {
3863 return buf ? buf->meta.wi - buf->meta.ri : 0;
3866 static inline wuffs_base__token* //
3867 wuffs_base__token_buffer__reader_pointer(const wuffs_base__token_buffer* buf) {
3868 return buf ? (buf->data.ptr + buf->meta.ri) : NULL;
3871 static inline wuffs_base__slice_token //
3872 wuffs_base__token_buffer__reader_slice(const wuffs_base__token_buffer* buf) {
3873 return buf ? wuffs_base__make_slice_token(buf->data.ptr + buf->meta.ri,
3874 buf->meta.wi - buf->meta.ri)
3875 : wuffs_base__empty_slice_token();
3878 static inline uint64_t //
3879 wuffs_base__token_buffer__reader_token_position(
3880 const wuffs_base__token_buffer* buf) {
3881 return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.ri) : 0;
3884 static inline uint64_t //
3885 wuffs_base__token_buffer__writer_length(const wuffs_base__token_buffer* buf) {
3886 return buf ? buf->data.len - buf->meta.wi : 0;
3889 static inline wuffs_base__token* //
3890 wuffs_base__token_buffer__writer_pointer(const wuffs_base__token_buffer* buf) {
3891 return buf ? (buf->data.ptr + buf->meta.wi) : NULL;
3894 static inline wuffs_base__slice_token //
3895 wuffs_base__token_buffer__writer_slice(const wuffs_base__token_buffer* buf) {
3896 return buf ? wuffs_base__make_slice_token(buf->data.ptr + buf->meta.wi,
3897 buf->data.len - buf->meta.wi)
3898 : wuffs_base__empty_slice_token();
3901 static inline uint64_t //
3902 wuffs_base__token_buffer__writer_token_position(
3903 const wuffs_base__token_buffer* buf) {
3904 return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.wi) : 0;
3907 #ifdef __cplusplus
3909 inline bool //
3910 wuffs_base__token_buffer::is_valid() const {
3911 return wuffs_base__token_buffer__is_valid(this);
3914 inline void //
3915 wuffs_base__token_buffer::compact() {
3916 wuffs_base__token_buffer__compact(this);
3919 inline void //
3920 wuffs_base__token_buffer::compact_retaining(uint64_t history_retain_length) {
3921 wuffs_base__token_buffer__compact_retaining(this, history_retain_length);
3924 inline uint64_t //
3925 wuffs_base__token_buffer::reader_length() const {
3926 return wuffs_base__token_buffer__reader_length(this);
3929 inline wuffs_base__token* //
3930 wuffs_base__token_buffer::reader_pointer() const {
3931 return wuffs_base__token_buffer__reader_pointer(this);
3934 inline wuffs_base__slice_token //
3935 wuffs_base__token_buffer::reader_slice() const {
3936 return wuffs_base__token_buffer__reader_slice(this);
3939 inline uint64_t //
3940 wuffs_base__token_buffer::reader_token_position() const {
3941 return wuffs_base__token_buffer__reader_token_position(this);
3944 inline uint64_t //
3945 wuffs_base__token_buffer::writer_length() const {
3946 return wuffs_base__token_buffer__writer_length(this);
3949 inline wuffs_base__token* //
3950 wuffs_base__token_buffer::writer_pointer() const {
3951 return wuffs_base__token_buffer__writer_pointer(this);
3954 inline wuffs_base__slice_token //
3955 wuffs_base__token_buffer::writer_slice() const {
3956 return wuffs_base__token_buffer__writer_slice(this);
3959 inline uint64_t //
3960 wuffs_base__token_buffer::writer_token_position() const {
3961 return wuffs_base__token_buffer__writer_token_position(this);
3964 #endif // __cplusplus
3966 // ---------------- Memory Allocation
3968 // The memory allocation related functions in this section aren't used by Wuffs
3969 // per se, but they may be helpful to the code that uses Wuffs.
3971 // wuffs_base__malloc_slice_uxx wraps calling a malloc-like function, except
3972 // that it takes a uint64_t number of elements instead of a size_t size in
3973 // bytes, and it returns a slice (a pointer and a length) instead of just a
3974 // pointer.
3976 // You can pass the C stdlib's malloc as the malloc_func.
3978 // It returns an empty slice (containing a NULL ptr field) if num_uxx is zero
3979 // or if (num_uxx * sizeof(uintxx_t)) would overflow SIZE_MAX.
3981 static inline wuffs_base__slice_u8 //
3982 wuffs_base__malloc_slice_u8(void* (*malloc_func)(size_t), uint64_t num_u8) {
3983 if (malloc_func && num_u8 && (num_u8 <= (SIZE_MAX / sizeof(uint8_t)))) {
3984 void* p = (*malloc_func)((size_t)(num_u8 * sizeof(uint8_t)));
3985 if (p) {
3986 return wuffs_base__make_slice_u8((uint8_t*)(p), (size_t)num_u8);
3989 return wuffs_base__empty_slice_u8();
3992 static inline wuffs_base__slice_u16 //
3993 wuffs_base__malloc_slice_u16(void* (*malloc_func)(size_t), uint64_t num_u16) {
3994 if (malloc_func && num_u16 && (num_u16 <= (SIZE_MAX / sizeof(uint16_t)))) {
3995 void* p = (*malloc_func)((size_t)(num_u16 * sizeof(uint16_t)));
3996 if (p) {
3997 return wuffs_base__make_slice_u16((uint16_t*)(p), (size_t)num_u16);
4000 return wuffs_base__empty_slice_u16();
4003 static inline wuffs_base__slice_u32 //
4004 wuffs_base__malloc_slice_u32(void* (*malloc_func)(size_t), uint64_t num_u32) {
4005 if (malloc_func && num_u32 && (num_u32 <= (SIZE_MAX / sizeof(uint32_t)))) {
4006 void* p = (*malloc_func)((size_t)(num_u32 * sizeof(uint32_t)));
4007 if (p) {
4008 return wuffs_base__make_slice_u32((uint32_t*)(p), (size_t)num_u32);
4011 return wuffs_base__empty_slice_u32();
4014 static inline wuffs_base__slice_u64 //
4015 wuffs_base__malloc_slice_u64(void* (*malloc_func)(size_t), uint64_t num_u64) {
4016 if (malloc_func && num_u64 && (num_u64 <= (SIZE_MAX / sizeof(uint64_t)))) {
4017 void* p = (*malloc_func)((size_t)(num_u64 * sizeof(uint64_t)));
4018 if (p) {
4019 return wuffs_base__make_slice_u64((uint64_t*)(p), (size_t)num_u64);
4022 return wuffs_base__empty_slice_u64();
4025 // ---------------- Images
4027 #define WUFFS_BASE__IMAGE__DIMENSION_MAX_INCL 0xFFFFFF
4029 // wuffs_base__color_u32_argb_premul is an 8 bit per channel premultiplied
4030 // Alpha, Red, Green, Blue color, as a uint32_t value. Its value is always
4031 // 0xAARRGGBB (Alpha most significant, Blue least), regardless of endianness.
4032 typedef uint32_t wuffs_base__color_u32_argb_premul;
4034 // wuffs_base__color_u32_argb_premul__is_valid returns whether c's Red, Green
4035 // and Blue channels are all less than or equal to its Alpha channel. c uses
4036 // premultiplied alpha, so 50% opaque 100% saturated red is 0x7F7F_0000 and a
4037 // value like 0x7F80_0000 is invalid.
4038 static inline bool //
4039 wuffs_base__color_u32_argb_premul__is_valid(
4040 wuffs_base__color_u32_argb_premul c) {
4041 uint32_t a = 0xFF & (c >> 24);
4042 uint32_t r = 0xFF & (c >> 16);
4043 uint32_t g = 0xFF & (c >> 8);
4044 uint32_t b = 0xFF & (c >> 0);
4045 return (a >= r) && (a >= g) && (a >= b);
4048 static inline uint16_t //
4049 wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
4050 wuffs_base__color_u32_argb_premul c) {
4051 uint32_t r5 = 0xF800 & (c >> 8);
4052 uint32_t g6 = 0x07E0 & (c >> 5);
4053 uint32_t b5 = 0x001F & (c >> 3);
4054 return (uint16_t)(r5 | g6 | b5);
4057 static inline wuffs_base__color_u32_argb_premul //
4058 wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(uint16_t rgb_565) {
4059 uint32_t b5 = 0x1F & (rgb_565 >> 0);
4060 uint32_t b = (b5 << 3) | (b5 >> 2);
4061 uint32_t g6 = 0x3F & (rgb_565 >> 5);
4062 uint32_t g = (g6 << 2) | (g6 >> 4);
4063 uint32_t r5 = 0x1F & (rgb_565 >> 11);
4064 uint32_t r = (r5 << 3) | (r5 >> 2);
4065 return 0xFF000000 | (r << 16) | (g << 8) | (b << 0);
4068 static inline uint8_t //
4069 wuffs_base__color_u32_argb_premul__as__color_u8_gray(
4070 wuffs_base__color_u32_argb_premul c) {
4071 // Work in 16-bit color.
4072 uint32_t cr = 0x101 * (0xFF & (c >> 16));
4073 uint32_t cg = 0x101 * (0xFF & (c >> 8));
4074 uint32_t cb = 0x101 * (0xFF & (c >> 0));
4076 // These coefficients (the fractions 0.299, 0.587 and 0.114) are the same
4077 // as those given by the JFIF specification.
4079 // Note that 19595 + 38470 + 7471 equals 65536, also known as (1 << 16). We
4080 // shift by 24, not just by 16, because the return value is 8-bit color, not
4081 // 16-bit color.
4082 uint32_t weighted_average = (19595 * cr) + (38470 * cg) + (7471 * cb) + 32768;
4083 return (uint8_t)(weighted_average >> 24);
4086 static inline uint16_t //
4087 wuffs_base__color_u32_argb_premul__as__color_u16_alpha_gray_nonpremul(
4088 wuffs_base__color_u32_argb_premul c) {
4089 uint32_t a = 0xFF & (c >> 24);
4090 if (a == 0) {
4091 return 0;
4093 uint32_t a16 = a * 0x101;
4095 uint32_t cr = 0xFF & (c >> 16);
4096 cr = (cr * (0x101 * 0xFFFF)) / a16;
4097 uint32_t cg = 0xFF & (c >> 8);
4098 cg = (cg * (0x101 * 0xFFFF)) / a16;
4099 uint32_t cb = 0xFF & (c >> 0);
4100 cb = (cb * (0x101 * 0xFFFF)) / a16;
4102 uint32_t weighted_average = (19595 * cr) + (38470 * cg) + (7471 * cb) + 32768;
4103 return (uint16_t)((a16 & 0xFF00) | (weighted_average >> 24));
4106 static inline uint16_t //
4107 wuffs_base__color_u32_argb_premul__as__color_u16_gray(
4108 wuffs_base__color_u32_argb_premul c) {
4109 // Work in 16-bit color.
4110 uint32_t cr = 0x101 * (0xFF & (c >> 16));
4111 uint32_t cg = 0x101 * (0xFF & (c >> 8));
4112 uint32_t cb = 0x101 * (0xFF & (c >> 0));
4114 // These coefficients (the fractions 0.299, 0.587 and 0.114) are the same
4115 // as those given by the JFIF specification.
4117 // Note that 19595 + 38470 + 7471 equals 65536, also known as (1 << 16).
4118 uint32_t weighted_average = (19595 * cr) + (38470 * cg) + (7471 * cb) + 32768;
4119 return (uint16_t)(weighted_average >> 16);
4122 // wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul converts
4123 // from non-premultiplied alpha to premultiplied alpha.
4124 static inline wuffs_base__color_u32_argb_premul //
4125 wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
4126 uint32_t argb_nonpremul) {
4127 // Multiplying by 0x101 (twice, once for alpha and once for color) converts
4128 // from 8-bit to 16-bit color. Shifting right by 8 undoes that.
4130 // Working in the higher bit depth can produce slightly different (and
4131 // arguably slightly more accurate) results. For example, given 8-bit blue
4132 // and alpha of 0x80 and 0x81:
4134 // - ((0x80 * 0x81 ) / 0xFF ) = 0x40 = 0x40
4135 // - ((0x8080 * 0x8181) / 0xFFFF) >> 8 = 0x4101 >> 8 = 0x41
4136 uint32_t a = 0xFF & (argb_nonpremul >> 24);
4137 uint32_t a16 = a * (0x101 * 0x101);
4139 uint32_t r = 0xFF & (argb_nonpremul >> 16);
4140 r = ((r * a16) / 0xFFFF) >> 8;
4141 uint32_t g = 0xFF & (argb_nonpremul >> 8);
4142 g = ((g * a16) / 0xFFFF) >> 8;
4143 uint32_t b = 0xFF & (argb_nonpremul >> 0);
4144 b = ((b * a16) / 0xFFFF) >> 8;
4146 return (a << 24) | (r << 16) | (g << 8) | (b << 0);
4149 // wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul converts
4150 // from premultiplied alpha to non-premultiplied alpha.
4151 static inline uint32_t //
4152 wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
4153 wuffs_base__color_u32_argb_premul c) {
4154 uint32_t a = 0xFF & (c >> 24);
4155 if (a == 0xFF) {
4156 return c;
4157 } else if (a == 0) {
4158 return 0;
4160 uint32_t a16 = a * 0x101;
4162 uint32_t r = 0xFF & (c >> 16);
4163 r = ((r * (0x101 * 0xFFFF)) / a16) >> 8;
4164 uint32_t g = 0xFF & (c >> 8);
4165 g = ((g * (0x101 * 0xFFFF)) / a16) >> 8;
4166 uint32_t b = 0xFF & (c >> 0);
4167 b = ((b * (0x101 * 0xFFFF)) / a16) >> 8;
4169 return (a << 24) | (r << 16) | (g << 8) | (b << 0);
4172 // wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul converts
4173 // from 4x16LE non-premultiplied alpha to 4x8 premultiplied alpha.
4174 static inline wuffs_base__color_u32_argb_premul //
4175 wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(
4176 uint64_t argb_nonpremul) {
4177 uint32_t a16 = ((uint32_t)(0xFFFF & (argb_nonpremul >> 48)));
4179 uint32_t r16 = ((uint32_t)(0xFFFF & (argb_nonpremul >> 32)));
4180 r16 = (r16 * a16) / 0xFFFF;
4181 uint32_t g16 = ((uint32_t)(0xFFFF & (argb_nonpremul >> 16)));
4182 g16 = (g16 * a16) / 0xFFFF;
4183 uint32_t b16 = ((uint32_t)(0xFFFF & (argb_nonpremul >> 0)));
4184 b16 = (b16 * a16) / 0xFFFF;
4186 return ((a16 >> 8) << 24) | ((r16 >> 8) << 16) | ((g16 >> 8) << 8) |
4187 ((b16 >> 8) << 0);
4190 // wuffs_base__color_u32_argb_premul__as__color_u64_argb_nonpremul converts
4191 // from 4x8 premultiplied alpha to 4x16LE non-premultiplied alpha.
4192 static inline uint64_t //
4193 wuffs_base__color_u32_argb_premul__as__color_u64_argb_nonpremul(
4194 wuffs_base__color_u32_argb_premul c) {
4195 uint32_t a = 0xFF & (c >> 24);
4196 if (a == 0xFF) {
4197 uint64_t r16 = 0x101 * (0xFF & (c >> 16));
4198 uint64_t g16 = 0x101 * (0xFF & (c >> 8));
4199 uint64_t b16 = 0x101 * (0xFF & (c >> 0));
4200 return 0xFFFF000000000000u | (r16 << 32) | (g16 << 16) | (b16 << 0);
4201 } else if (a == 0) {
4202 return 0;
4204 uint64_t a16 = a * 0x101;
4206 uint64_t r = 0xFF & (c >> 16);
4207 uint64_t r16 = (r * (0x101 * 0xFFFF)) / a16;
4208 uint64_t g = 0xFF & (c >> 8);
4209 uint64_t g16 = (g * (0x101 * 0xFFFF)) / a16;
4210 uint64_t b = 0xFF & (c >> 0);
4211 uint64_t b16 = (b * (0x101 * 0xFFFF)) / a16;
4213 return (a16 << 48) | (r16 << 32) | (g16 << 16) | (b16 << 0);
4216 static inline uint64_t //
4217 wuffs_base__color_u32__as__color_u64(uint32_t c) {
4218 uint64_t a16 = 0x101 * (0xFF & (c >> 24));
4219 uint64_t r16 = 0x101 * (0xFF & (c >> 16));
4220 uint64_t g16 = 0x101 * (0xFF & (c >> 8));
4221 uint64_t b16 = 0x101 * (0xFF & (c >> 0));
4222 return (a16 << 48) | (r16 << 32) | (g16 << 16) | (b16 << 0);
4225 static inline uint32_t //
4226 wuffs_base__color_u64__as__color_u32(uint64_t c) {
4227 uint32_t a = ((uint32_t)(0xFF & (c >> 56)));
4228 uint32_t r = ((uint32_t)(0xFF & (c >> 40)));
4229 uint32_t g = ((uint32_t)(0xFF & (c >> 24)));
4230 uint32_t b = ((uint32_t)(0xFF & (c >> 8)));
4231 return (a << 24) | (r << 16) | (g << 8) | (b << 0);
4234 // wuffs_base__color_ycc__as__color_u32 converts from YCbCr to 0xAARRGGBB. The
4235 // alpha bits are always 0xFF.
4236 static inline wuffs_base__color_u32_argb_premul //
4237 wuffs_base__color_ycc__as__color_u32(uint8_t yy, uint8_t cb, uint8_t cr) {
4238 // Work in 16.16 fixed point arithmetic (so that 'one half' is (1 << 15)) and
4239 // bias the chroma values by 0x80.
4240 uint32_t yy32 = (((uint32_t)yy) << 16) | (1 << 15);
4241 uint32_t cb32 = (((uint32_t)cb) - 0x80);
4242 uint32_t cr32 = (((uint32_t)cr) - 0x80);
4244 // The formulae:
4246 // R = Y + 1.40200 * Cr
4247 // G = Y - 0.34414 * Cb - 0.71414 * Cr
4248 // B = Y + 1.77200 * Cb
4250 // When scaled by 1<<16:
4252 // 0.34414 becomes 0x0581A = 22554.
4253 // 0.71414 becomes 0x0B6D2 = 46802.
4254 // 1.40200 becomes 0x166E9 = 91881.
4255 // 1.77200 becomes 0x1C5A2 = 116130.
4257 // Since we're working in 16.16 fixed point arithmetic, masking by 0x00FF0000
4258 // (possibly followed by a shift) gives the relevant 8 bits per channel.
4260 // However, we need to saturate for overflow (above 0x00FFFFFF, but not so
4261 // high that the MSB Most Significant Bit is set) or for underflow (below
4262 // 0x00000000 as int32_t, which means that the MSB is set as uint32_t). In
4263 // both cases, some of the high 8 bits (bits 24 ..= 31) will be set.
4265 // "((uint32_t)(((int32_t)x) >> 31))" just replicates x's MSB across all 32
4266 // bits. Prepending that with "~" inverts those bits. Thus, "~(etc)" is
4267 // either 0xFFFFFFFF (for overflow) or 0x00000000 (for underflow).
4268 uint32_t rr32 = yy32 + (0x166E9 * cr32);
4269 uint32_t gg32 = yy32 - (0x0581A * cb32) - (0x0B6D2 * cr32);
4270 uint32_t bb32 = yy32 + (0x1C5A2 * cb32);
4271 if (rr32 >> 24) {
4272 rr32 = ~((uint32_t)(((int32_t)rr32) >> 31));
4274 if (gg32 >> 24) {
4275 gg32 = ~((uint32_t)(((int32_t)gg32) >> 31));
4277 if (bb32 >> 24) {
4278 bb32 = ~((uint32_t)(((int32_t)bb32) >> 31));
4280 return 0xFF000000 | //
4281 ((0x00FF0000 & rr32) >> 0) | //
4282 ((0x00FF0000 & gg32) >> 8) | //
4283 ((0x00FF0000 & bb32) >> 16);
4286 // wuffs_base__color_ycc__as__color_u32_abgr is like
4287 // wuffs_base__color_ycc__as__color_u32 but the uint32_t returned is in
4288 // 0xAABBGGRR order, not 0xAARRGGBB.
4289 static inline uint32_t //
4290 wuffs_base__color_ycc__as__color_u32_abgr(uint8_t yy, uint8_t cb, uint8_t cr) {
4291 uint32_t yy32 = (((uint32_t)yy) << 16) | (1 << 15);
4292 uint32_t cb32 = (((uint32_t)cb) - 0x80);
4293 uint32_t cr32 = (((uint32_t)cr) - 0x80);
4294 uint32_t rr32 = yy32 + (0x166E9 * cr32);
4295 uint32_t gg32 = yy32 - (0x0581A * cb32) - (0x0B6D2 * cr32);
4296 uint32_t bb32 = yy32 + (0x1C5A2 * cb32);
4297 if (rr32 >> 24) {
4298 rr32 = ~((uint32_t)(((int32_t)rr32) >> 31));
4300 if (gg32 >> 24) {
4301 gg32 = ~((uint32_t)(((int32_t)gg32) >> 31));
4303 if (bb32 >> 24) {
4304 bb32 = ~((uint32_t)(((int32_t)bb32) >> 31));
4306 return 0xFF000000 | //
4307 ((0x00FF0000 & bb32) >> 0) | //
4308 ((0x00FF0000 & gg32) >> 8) | //
4309 ((0x00FF0000 & rr32) >> 16);
4312 // --------
4314 typedef uint8_t wuffs_base__pixel_blend;
4316 // wuffs_base__pixel_blend encodes how to blend source and destination pixels,
4317 // accounting for transparency. It encompasses the Porter-Duff compositing
4318 // operators as well as the other blending modes defined by PDF.
4320 // TODO: implement the other modes.
4321 #define WUFFS_BASE__PIXEL_BLEND__SRC ((wuffs_base__pixel_blend)0)
4322 #define WUFFS_BASE__PIXEL_BLEND__SRC_OVER ((wuffs_base__pixel_blend)1)
4324 // --------
4326 // wuffs_base__pixel_alpha_transparency is a pixel format's alpha channel
4327 // model. It is a property of the pixel format in general, not of a specific
4328 // pixel. An RGBA pixel format (with alpha) can still have fully opaque pixels.
4329 typedef uint32_t wuffs_base__pixel_alpha_transparency;
4331 #define WUFFS_BASE__PIXEL_ALPHA_TRANSPARENCY__OPAQUE 0
4332 #define WUFFS_BASE__PIXEL_ALPHA_TRANSPARENCY__NONPREMULTIPLIED_ALPHA 1
4333 #define WUFFS_BASE__PIXEL_ALPHA_TRANSPARENCY__PREMULTIPLIED_ALPHA 2
4334 #define WUFFS_BASE__PIXEL_ALPHA_TRANSPARENCY__BINARY_ALPHA 3
4336 // --------
4338 // Deprecated: use WUFFS_BASE__PIXEL_FORMAT__NUM_PLANES_MAX_INCL.
4339 #define WUFFS_BASE__PIXEL_FORMAT__NUM_PLANES_MAX 4
4341 #define WUFFS_BASE__PIXEL_FORMAT__NUM_PLANES_MAX_INCL 4
4343 #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__INDEX_PLANE 0
4344 #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE 3
4346 // A palette is 256 entries × 4 bytes per entry (e.g. BGRA).
4347 #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH 1024
4349 // wuffs_base__pixel_format encodes the format of the bytes that constitute an
4350 // image frame's pixel data.
4352 // See https://github.com/google/wuffs/blob/main/doc/note/pixel-formats.md
4354 // Do not manipulate its bits directly; they are private implementation
4355 // details. Use methods such as wuffs_base__pixel_format__num_planes instead.
4356 typedef struct wuffs_base__pixel_format__struct {
4357 uint32_t repr;
4359 #ifdef __cplusplus
4360 inline bool is_valid() const;
4361 inline uint32_t bits_per_pixel() const;
4362 inline bool is_direct() const;
4363 inline bool is_indexed() const;
4364 inline bool is_interleaved() const;
4365 inline bool is_planar() const;
4366 inline uint32_t num_planes() const;
4367 inline wuffs_base__pixel_alpha_transparency transparency() const;
4368 #endif // __cplusplus
4370 } wuffs_base__pixel_format;
4372 static inline wuffs_base__pixel_format //
4373 wuffs_base__make_pixel_format(uint32_t repr) {
4374 wuffs_base__pixel_format f;
4375 f.repr = repr;
4376 return f;
4379 // Common 8-bit-depth pixel formats. This list is not exhaustive; not all valid
4380 // wuffs_base__pixel_format values are present.
4382 // clang-format off
4384 #define WUFFS_BASE__PIXEL_FORMAT__INVALID 0x00000000
4386 #define WUFFS_BASE__PIXEL_FORMAT__A 0x02000008
4388 #define WUFFS_BASE__PIXEL_FORMAT__Y 0x20000008
4389 #define WUFFS_BASE__PIXEL_FORMAT__Y_16LE 0x2000000B
4390 #define WUFFS_BASE__PIXEL_FORMAT__Y_16BE 0x2010000B
4391 #define WUFFS_BASE__PIXEL_FORMAT__YA_NONPREMUL 0x21000088
4392 #define WUFFS_BASE__PIXEL_FORMAT__YA_PREMUL 0x22000088
4394 #define WUFFS_BASE__PIXEL_FORMAT__YCBCR 0x40020888
4395 #define WUFFS_BASE__PIXEL_FORMAT__YCBCRA_NONPREMUL 0x41038888
4396 #define WUFFS_BASE__PIXEL_FORMAT__YCBCRK 0x50038888
4398 #define WUFFS_BASE__PIXEL_FORMAT__YCOCG 0x60020888
4399 #define WUFFS_BASE__PIXEL_FORMAT__YCOCGA_NONPREMUL 0x61038888
4400 #define WUFFS_BASE__PIXEL_FORMAT__YCOCGK 0x70038888
4402 #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL 0x81040008
4403 #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL 0x82040008
4404 #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY 0x83040008
4406 #define WUFFS_BASE__PIXEL_FORMAT__BGR_565 0x80000565
4407 #define WUFFS_BASE__PIXEL_FORMAT__BGR 0x80000888
4408 #define WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL 0x81008888
4409 #define WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE 0x8100BBBB
4410 #define WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL 0x82008888
4411 #define WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE 0x8200BBBB
4412 #define WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY 0x83008888
4413 #define WUFFS_BASE__PIXEL_FORMAT__BGRX 0x90008888
4415 #define WUFFS_BASE__PIXEL_FORMAT__RGB 0xA0000888
4416 #define WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL 0xA1008888
4417 #define WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL_4X16LE 0xA100BBBB
4418 #define WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL 0xA2008888
4419 #define WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL_4X16LE 0xA200BBBB
4420 #define WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY 0xA3008888
4421 #define WUFFS_BASE__PIXEL_FORMAT__RGBX 0xB0008888
4423 #define WUFFS_BASE__PIXEL_FORMAT__CMY 0xC0020888
4424 #define WUFFS_BASE__PIXEL_FORMAT__CMYK 0xD0038888
4426 // clang-format on
4428 extern const uint32_t wuffs_private_impl__pixel_format__bits_per_channel[16];
4430 static inline bool //
4431 wuffs_base__pixel_format__is_valid(const wuffs_base__pixel_format* f) {
4432 return f->repr != 0;
4435 // wuffs_base__pixel_format__bits_per_pixel returns the number of bits per
4436 // pixel for interleaved pixel formats, and returns 0 for planar pixel formats.
4437 static inline uint32_t //
4438 wuffs_base__pixel_format__bits_per_pixel(const wuffs_base__pixel_format* f) {
4439 if (((f->repr >> 16) & 0x03) != 0) {
4440 return 0;
4442 return wuffs_private_impl__pixel_format__bits_per_channel[0x0F &
4443 (f->repr >> 0)] +
4444 wuffs_private_impl__pixel_format__bits_per_channel[0x0F &
4445 (f->repr >> 4)] +
4446 wuffs_private_impl__pixel_format__bits_per_channel[0x0F &
4447 (f->repr >> 8)] +
4448 wuffs_private_impl__pixel_format__bits_per_channel[0x0F &
4449 (f->repr >> 12)];
4452 static inline bool //
4453 wuffs_base__pixel_format__is_direct(const wuffs_base__pixel_format* f) {
4454 return ((f->repr >> 18) & 0x01) == 0;
4457 static inline bool //
4458 wuffs_base__pixel_format__is_indexed(const wuffs_base__pixel_format* f) {
4459 return ((f->repr >> 18) & 0x01) != 0;
4462 static inline bool //
4463 wuffs_base__pixel_format__is_interleaved(const wuffs_base__pixel_format* f) {
4464 return ((f->repr >> 16) & 0x03) == 0;
4467 static inline bool //
4468 wuffs_base__pixel_format__is_planar(const wuffs_base__pixel_format* f) {
4469 return ((f->repr >> 16) & 0x03) != 0;
4472 static inline uint32_t //
4473 wuffs_base__pixel_format__num_planes(const wuffs_base__pixel_format* f) {
4474 return ((f->repr >> 16) & 0x03) + 1;
4477 static inline wuffs_base__pixel_alpha_transparency //
4478 wuffs_base__pixel_format__transparency(const wuffs_base__pixel_format* f) {
4479 return (wuffs_base__pixel_alpha_transparency)((f->repr >> 24) & 0x03);
4482 #ifdef __cplusplus
4484 inline bool //
4485 wuffs_base__pixel_format::is_valid() const {
4486 return wuffs_base__pixel_format__is_valid(this);
4489 inline uint32_t //
4490 wuffs_base__pixel_format::bits_per_pixel() const {
4491 return wuffs_base__pixel_format__bits_per_pixel(this);
4494 inline bool //
4495 wuffs_base__pixel_format::is_direct() const {
4496 return wuffs_base__pixel_format__is_direct(this);
4499 inline bool //
4500 wuffs_base__pixel_format::is_indexed() const {
4501 return wuffs_base__pixel_format__is_indexed(this);
4504 inline bool //
4505 wuffs_base__pixel_format::is_interleaved() const {
4506 return wuffs_base__pixel_format__is_interleaved(this);
4509 inline bool //
4510 wuffs_base__pixel_format::is_planar() const {
4511 return wuffs_base__pixel_format__is_planar(this);
4514 inline uint32_t //
4515 wuffs_base__pixel_format::num_planes() const {
4516 return wuffs_base__pixel_format__num_planes(this);
4519 inline wuffs_base__pixel_alpha_transparency //
4520 wuffs_base__pixel_format::transparency() const {
4521 return wuffs_base__pixel_format__transparency(this);
4524 #endif // __cplusplus
4526 // --------
4528 // wuffs_base__pixel_subsampling encodes whether sample values cover one pixel
4529 // or cover multiple pixels.
4531 // See https://github.com/google/wuffs/blob/main/doc/note/pixel-subsampling.md
4533 // Do not manipulate its bits directly; they are private implementation
4534 // details. Use methods such as wuffs_base__pixel_subsampling__bias_x instead.
4535 typedef struct wuffs_base__pixel_subsampling__struct {
4536 uint32_t repr;
4538 #ifdef __cplusplus
4539 inline uint32_t bias_x(uint32_t plane) const;
4540 inline uint32_t denominator_x(uint32_t plane) const;
4541 inline uint32_t bias_y(uint32_t plane) const;
4542 inline uint32_t denominator_y(uint32_t plane) const;
4543 #endif // __cplusplus
4545 } wuffs_base__pixel_subsampling;
4547 static inline wuffs_base__pixel_subsampling //
4548 wuffs_base__make_pixel_subsampling(uint32_t repr) {
4549 wuffs_base__pixel_subsampling s;
4550 s.repr = repr;
4551 return s;
4554 #define WUFFS_BASE__PIXEL_SUBSAMPLING__NONE 0x00000000
4556 #define WUFFS_BASE__PIXEL_SUBSAMPLING__444 0x000000
4557 #define WUFFS_BASE__PIXEL_SUBSAMPLING__440 0x010100
4558 #define WUFFS_BASE__PIXEL_SUBSAMPLING__422 0x101000
4559 #define WUFFS_BASE__PIXEL_SUBSAMPLING__420 0x111100
4560 #define WUFFS_BASE__PIXEL_SUBSAMPLING__411 0x303000
4561 #define WUFFS_BASE__PIXEL_SUBSAMPLING__410 0x313100
4563 static inline uint32_t //
4564 wuffs_base__pixel_subsampling__bias_x(const wuffs_base__pixel_subsampling* s,
4565 uint32_t plane) {
4566 uint32_t shift = ((plane & 0x03) * 8) + 6;
4567 return (s->repr >> shift) & 0x03;
4570 static inline uint32_t //
4571 wuffs_base__pixel_subsampling__denominator_x(
4572 const wuffs_base__pixel_subsampling* s,
4573 uint32_t plane) {
4574 uint32_t shift = ((plane & 0x03) * 8) + 4;
4575 return ((s->repr >> shift) & 0x03) + 1;
4578 static inline uint32_t //
4579 wuffs_base__pixel_subsampling__bias_y(const wuffs_base__pixel_subsampling* s,
4580 uint32_t plane) {
4581 uint32_t shift = ((plane & 0x03) * 8) + 2;
4582 return (s->repr >> shift) & 0x03;
4585 static inline uint32_t //
4586 wuffs_base__pixel_subsampling__denominator_y(
4587 const wuffs_base__pixel_subsampling* s,
4588 uint32_t plane) {
4589 uint32_t shift = ((plane & 0x03) * 8) + 0;
4590 return ((s->repr >> shift) & 0x03) + 1;
4593 #ifdef __cplusplus
4595 inline uint32_t //
4596 wuffs_base__pixel_subsampling::bias_x(uint32_t plane) const {
4597 return wuffs_base__pixel_subsampling__bias_x(this, plane);
4600 inline uint32_t //
4601 wuffs_base__pixel_subsampling::denominator_x(uint32_t plane) const {
4602 return wuffs_base__pixel_subsampling__denominator_x(this, plane);
4605 inline uint32_t //
4606 wuffs_base__pixel_subsampling::bias_y(uint32_t plane) const {
4607 return wuffs_base__pixel_subsampling__bias_y(this, plane);
4610 inline uint32_t //
4611 wuffs_base__pixel_subsampling::denominator_y(uint32_t plane) const {
4612 return wuffs_base__pixel_subsampling__denominator_y(this, plane);
4615 #endif // __cplusplus
4617 // --------
4619 typedef struct wuffs_base__pixel_config__struct {
4620 // Do not access the private_impl's fields directly. There is no API/ABI
4621 // compatibility or safety guarantee if you do so.
4622 struct {
4623 wuffs_base__pixel_format pixfmt;
4624 wuffs_base__pixel_subsampling pixsub;
4625 uint32_t width;
4626 uint32_t height;
4627 } private_impl;
4629 #ifdef __cplusplus
4630 inline void set(uint32_t pixfmt_repr,
4631 uint32_t pixsub_repr,
4632 uint32_t width,
4633 uint32_t height);
4634 inline void invalidate();
4635 inline bool is_valid() const;
4636 inline wuffs_base__pixel_format pixel_format() const;
4637 inline wuffs_base__pixel_subsampling pixel_subsampling() const;
4638 inline wuffs_base__rect_ie_u32 bounds() const;
4639 inline uint32_t width() const;
4640 inline uint32_t height() const;
4641 inline uint64_t pixbuf_len() const;
4642 #endif // __cplusplus
4644 } wuffs_base__pixel_config;
4646 static inline wuffs_base__pixel_config //
4647 wuffs_base__null_pixel_config(void) {
4648 wuffs_base__pixel_config ret;
4649 ret.private_impl.pixfmt.repr = 0;
4650 ret.private_impl.pixsub.repr = 0;
4651 ret.private_impl.width = 0;
4652 ret.private_impl.height = 0;
4653 return ret;
4656 // TODO: Should this function return bool? An error type?
4657 static inline void //
4658 wuffs_base__pixel_config__set(wuffs_base__pixel_config* c,
4659 uint32_t pixfmt_repr,
4660 uint32_t pixsub_repr,
4661 uint32_t width,
4662 uint32_t height) {
4663 if (!c) {
4664 return;
4666 if (pixfmt_repr) {
4667 do {
4668 #if SIZE_MAX < 0xFFFFFFFFFFFFFFFFull
4669 uint64_t wh = ((uint64_t)width) * ((uint64_t)height);
4670 // TODO: handle things other than 1 byte per pixel.
4671 if (wh > ((uint64_t)SIZE_MAX)) {
4672 break;
4674 #endif
4675 c->private_impl.pixfmt.repr = pixfmt_repr;
4676 c->private_impl.pixsub.repr = pixsub_repr;
4677 c->private_impl.width = width;
4678 c->private_impl.height = height;
4679 return;
4680 } while (0);
4683 c->private_impl.pixfmt.repr = 0;
4684 c->private_impl.pixsub.repr = 0;
4685 c->private_impl.width = 0;
4686 c->private_impl.height = 0;
4689 static inline void //
4690 wuffs_base__pixel_config__invalidate(wuffs_base__pixel_config* c) {
4691 if (c) {
4692 c->private_impl.pixfmt.repr = 0;
4693 c->private_impl.pixsub.repr = 0;
4694 c->private_impl.width = 0;
4695 c->private_impl.height = 0;
4699 static inline bool //
4700 wuffs_base__pixel_config__is_valid(const wuffs_base__pixel_config* c) {
4701 return c && c->private_impl.pixfmt.repr;
4704 static inline wuffs_base__pixel_format //
4705 wuffs_base__pixel_config__pixel_format(const wuffs_base__pixel_config* c) {
4706 return c ? c->private_impl.pixfmt : wuffs_base__make_pixel_format(0);
4709 static inline wuffs_base__pixel_subsampling //
4710 wuffs_base__pixel_config__pixel_subsampling(const wuffs_base__pixel_config* c) {
4711 return c ? c->private_impl.pixsub : wuffs_base__make_pixel_subsampling(0);
4714 static inline wuffs_base__rect_ie_u32 //
4715 wuffs_base__pixel_config__bounds(const wuffs_base__pixel_config* c) {
4716 if (c) {
4717 wuffs_base__rect_ie_u32 ret;
4718 ret.min_incl_x = 0;
4719 ret.min_incl_y = 0;
4720 ret.max_excl_x = c->private_impl.width;
4721 ret.max_excl_y = c->private_impl.height;
4722 return ret;
4725 wuffs_base__rect_ie_u32 ret;
4726 ret.min_incl_x = 0;
4727 ret.min_incl_y = 0;
4728 ret.max_excl_x = 0;
4729 ret.max_excl_y = 0;
4730 return ret;
4733 static inline uint32_t //
4734 wuffs_base__pixel_config__width(const wuffs_base__pixel_config* c) {
4735 return c ? c->private_impl.width : 0;
4738 static inline uint32_t //
4739 wuffs_base__pixel_config__height(const wuffs_base__pixel_config* c) {
4740 return c ? c->private_impl.height : 0;
4743 // TODO: this is the right API for planar (not interleaved) pixbufs? Should it
4744 // allow decoding into a color model different from the format's intrinsic one?
4745 // For example, decoding a JPEG image straight to RGBA instead of to YCbCr?
4746 static inline uint64_t //
4747 wuffs_base__pixel_config__pixbuf_len(const wuffs_base__pixel_config* c) {
4748 if (!c) {
4749 return 0;
4751 if (wuffs_base__pixel_format__is_planar(&c->private_impl.pixfmt)) {
4752 // TODO: support planar pixel formats, concious of pixel subsampling.
4753 return 0;
4755 uint32_t bits_per_pixel =
4756 wuffs_base__pixel_format__bits_per_pixel(&c->private_impl.pixfmt);
4757 if ((bits_per_pixel == 0) || ((bits_per_pixel % 8) != 0)) {
4758 // TODO: support fraction-of-byte pixels, e.g. 1 bit per pixel?
4759 return 0;
4761 uint64_t bytes_per_pixel = bits_per_pixel / 8;
4763 uint64_t n =
4764 ((uint64_t)c->private_impl.width) * ((uint64_t)c->private_impl.height);
4765 if (n > (UINT64_MAX / bytes_per_pixel)) {
4766 return 0;
4768 n *= bytes_per_pixel;
4770 if (wuffs_base__pixel_format__is_indexed(&c->private_impl.pixfmt)) {
4771 if (n >
4772 (UINT64_MAX - WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH)) {
4773 return 0;
4775 n += WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
4778 return n;
4781 #ifdef __cplusplus
4783 inline void //
4784 wuffs_base__pixel_config::set(uint32_t pixfmt_repr,
4785 uint32_t pixsub_repr,
4786 uint32_t width,
4787 uint32_t height) {
4788 wuffs_base__pixel_config__set(this, pixfmt_repr, pixsub_repr, width, height);
4791 inline void //
4792 wuffs_base__pixel_config::invalidate() {
4793 wuffs_base__pixel_config__invalidate(this);
4796 inline bool //
4797 wuffs_base__pixel_config::is_valid() const {
4798 return wuffs_base__pixel_config__is_valid(this);
4801 inline wuffs_base__pixel_format //
4802 wuffs_base__pixel_config::pixel_format() const {
4803 return wuffs_base__pixel_config__pixel_format(this);
4806 inline wuffs_base__pixel_subsampling //
4807 wuffs_base__pixel_config::pixel_subsampling() const {
4808 return wuffs_base__pixel_config__pixel_subsampling(this);
4811 inline wuffs_base__rect_ie_u32 //
4812 wuffs_base__pixel_config::bounds() const {
4813 return wuffs_base__pixel_config__bounds(this);
4816 inline uint32_t //
4817 wuffs_base__pixel_config::width() const {
4818 return wuffs_base__pixel_config__width(this);
4821 inline uint32_t //
4822 wuffs_base__pixel_config::height() const {
4823 return wuffs_base__pixel_config__height(this);
4826 inline uint64_t //
4827 wuffs_base__pixel_config::pixbuf_len() const {
4828 return wuffs_base__pixel_config__pixbuf_len(this);
4831 #endif // __cplusplus
4833 // --------
4835 typedef struct wuffs_base__image_config__struct {
4836 wuffs_base__pixel_config pixcfg;
4838 // Do not access the private_impl's fields directly. There is no API/ABI
4839 // compatibility or safety guarantee if you do so.
4840 struct {
4841 uint64_t first_frame_io_position;
4842 bool first_frame_is_opaque;
4843 } private_impl;
4845 #ifdef __cplusplus
4846 inline void set(uint32_t pixfmt_repr,
4847 uint32_t pixsub_repr,
4848 uint32_t width,
4849 uint32_t height,
4850 uint64_t first_frame_io_position,
4851 bool first_frame_is_opaque);
4852 inline void invalidate();
4853 inline bool is_valid() const;
4854 inline uint64_t first_frame_io_position() const;
4855 inline bool first_frame_is_opaque() const;
4856 #endif // __cplusplus
4858 } wuffs_base__image_config;
4860 static inline wuffs_base__image_config //
4861 wuffs_base__null_image_config(void) {
4862 wuffs_base__image_config ret;
4863 ret.pixcfg = wuffs_base__null_pixel_config();
4864 ret.private_impl.first_frame_io_position = 0;
4865 ret.private_impl.first_frame_is_opaque = false;
4866 return ret;
4869 // TODO: Should this function return bool? An error type?
4870 static inline void //
4871 wuffs_base__image_config__set(wuffs_base__image_config* c,
4872 uint32_t pixfmt_repr,
4873 uint32_t pixsub_repr,
4874 uint32_t width,
4875 uint32_t height,
4876 uint64_t first_frame_io_position,
4877 bool first_frame_is_opaque) {
4878 if (!c) {
4879 return;
4881 if (pixfmt_repr) {
4882 c->pixcfg.private_impl.pixfmt.repr = pixfmt_repr;
4883 c->pixcfg.private_impl.pixsub.repr = pixsub_repr;
4884 c->pixcfg.private_impl.width = width;
4885 c->pixcfg.private_impl.height = height;
4886 c->private_impl.first_frame_io_position = first_frame_io_position;
4887 c->private_impl.first_frame_is_opaque = first_frame_is_opaque;
4888 return;
4891 c->pixcfg.private_impl.pixfmt.repr = 0;
4892 c->pixcfg.private_impl.pixsub.repr = 0;
4893 c->pixcfg.private_impl.width = 0;
4894 c->pixcfg.private_impl.height = 0;
4895 c->private_impl.first_frame_io_position = 0;
4896 c->private_impl.first_frame_is_opaque = 0;
4899 static inline void //
4900 wuffs_base__image_config__invalidate(wuffs_base__image_config* c) {
4901 if (c) {
4902 c->pixcfg.private_impl.pixfmt.repr = 0;
4903 c->pixcfg.private_impl.pixsub.repr = 0;
4904 c->pixcfg.private_impl.width = 0;
4905 c->pixcfg.private_impl.height = 0;
4906 c->private_impl.first_frame_io_position = 0;
4907 c->private_impl.first_frame_is_opaque = 0;
4911 static inline bool //
4912 wuffs_base__image_config__is_valid(const wuffs_base__image_config* c) {
4913 return c && wuffs_base__pixel_config__is_valid(&(c->pixcfg));
4916 static inline uint64_t //
4917 wuffs_base__image_config__first_frame_io_position(
4918 const wuffs_base__image_config* c) {
4919 return c ? c->private_impl.first_frame_io_position : 0;
4922 static inline bool //
4923 wuffs_base__image_config__first_frame_is_opaque(
4924 const wuffs_base__image_config* c) {
4925 return c ? c->private_impl.first_frame_is_opaque : false;
4928 #ifdef __cplusplus
4930 inline void //
4931 wuffs_base__image_config::set(uint32_t pixfmt_repr,
4932 uint32_t pixsub_repr,
4933 uint32_t width,
4934 uint32_t height,
4935 uint64_t first_frame_io_position,
4936 bool first_frame_is_opaque) {
4937 wuffs_base__image_config__set(this, pixfmt_repr, pixsub_repr, width, height,
4938 first_frame_io_position, first_frame_is_opaque);
4941 inline void //
4942 wuffs_base__image_config::invalidate() {
4943 wuffs_base__image_config__invalidate(this);
4946 inline bool //
4947 wuffs_base__image_config::is_valid() const {
4948 return wuffs_base__image_config__is_valid(this);
4951 inline uint64_t //
4952 wuffs_base__image_config::first_frame_io_position() const {
4953 return wuffs_base__image_config__first_frame_io_position(this);
4956 inline bool //
4957 wuffs_base__image_config::first_frame_is_opaque() const {
4958 return wuffs_base__image_config__first_frame_is_opaque(this);
4961 #endif // __cplusplus
4963 // --------
4965 // wuffs_base__animation_disposal encodes, for an animated image, how to
4966 // dispose of a frame after displaying it:
4967 // - None means to draw the next frame on top of this one.
4968 // - Restore Background means to clear the frame's dirty rectangle to "the
4969 // background color" (in practice, this means transparent black) before
4970 // drawing the next frame.
4971 // - Restore Previous means to undo the current frame, so that the next frame
4972 // is drawn on top of the previous one.
4973 typedef uint8_t wuffs_base__animation_disposal;
4975 #define WUFFS_BASE__ANIMATION_DISPOSAL__NONE ((wuffs_base__animation_disposal)0)
4976 #define WUFFS_BASE__ANIMATION_DISPOSAL__RESTORE_BACKGROUND \
4977 ((wuffs_base__animation_disposal)1)
4978 #define WUFFS_BASE__ANIMATION_DISPOSAL__RESTORE_PREVIOUS \
4979 ((wuffs_base__animation_disposal)2)
4981 // --------
4983 typedef struct wuffs_base__frame_config__struct {
4984 // Do not access the private_impl's fields directly. There is no API/ABI
4985 // compatibility or safety guarantee if you do so.
4986 struct {
4987 wuffs_base__rect_ie_u32 bounds;
4988 wuffs_base__flicks duration;
4989 uint64_t index;
4990 uint64_t io_position;
4991 wuffs_base__animation_disposal disposal;
4992 bool opaque_within_bounds;
4993 bool overwrite_instead_of_blend;
4994 wuffs_base__color_u32_argb_premul background_color;
4995 } private_impl;
4997 #ifdef __cplusplus
4998 inline void set(wuffs_base__rect_ie_u32 bounds,
4999 wuffs_base__flicks duration,
5000 uint64_t index,
5001 uint64_t io_position,
5002 wuffs_base__animation_disposal disposal,
5003 bool opaque_within_bounds,
5004 bool overwrite_instead_of_blend,
5005 wuffs_base__color_u32_argb_premul background_color);
5006 inline wuffs_base__rect_ie_u32 bounds() const;
5007 inline uint32_t width() const;
5008 inline uint32_t height() const;
5009 inline wuffs_base__flicks duration() const;
5010 inline uint64_t index() const;
5011 inline uint64_t io_position() const;
5012 inline wuffs_base__animation_disposal disposal() const;
5013 inline bool opaque_within_bounds() const;
5014 inline bool overwrite_instead_of_blend() const;
5015 inline wuffs_base__color_u32_argb_premul background_color() const;
5016 #endif // __cplusplus
5018 } wuffs_base__frame_config;
5020 static inline wuffs_base__frame_config //
5021 wuffs_base__null_frame_config(void) {
5022 wuffs_base__frame_config ret;
5023 ret.private_impl.bounds = wuffs_base__make_rect_ie_u32(0, 0, 0, 0);
5024 ret.private_impl.duration = 0;
5025 ret.private_impl.index = 0;
5026 ret.private_impl.io_position = 0;
5027 ret.private_impl.disposal = 0;
5028 ret.private_impl.opaque_within_bounds = false;
5029 ret.private_impl.overwrite_instead_of_blend = false;
5030 return ret;
5033 static inline void //
5034 wuffs_base__frame_config__set(
5035 wuffs_base__frame_config* c,
5036 wuffs_base__rect_ie_u32 bounds,
5037 wuffs_base__flicks duration,
5038 uint64_t index,
5039 uint64_t io_position,
5040 wuffs_base__animation_disposal disposal,
5041 bool opaque_within_bounds,
5042 bool overwrite_instead_of_blend,
5043 wuffs_base__color_u32_argb_premul background_color) {
5044 if (!c) {
5045 return;
5048 c->private_impl.bounds = bounds;
5049 c->private_impl.duration = duration;
5050 c->private_impl.index = index;
5051 c->private_impl.io_position = io_position;
5052 c->private_impl.disposal = disposal;
5053 c->private_impl.opaque_within_bounds = opaque_within_bounds;
5054 c->private_impl.overwrite_instead_of_blend = overwrite_instead_of_blend;
5055 c->private_impl.background_color = background_color;
5058 static inline wuffs_base__rect_ie_u32 //
5059 wuffs_base__frame_config__bounds(const wuffs_base__frame_config* c) {
5060 if (c) {
5061 return c->private_impl.bounds;
5064 wuffs_base__rect_ie_u32 ret;
5065 ret.min_incl_x = 0;
5066 ret.min_incl_y = 0;
5067 ret.max_excl_x = 0;
5068 ret.max_excl_y = 0;
5069 return ret;
5072 static inline uint32_t //
5073 wuffs_base__frame_config__width(const wuffs_base__frame_config* c) {
5074 return c ? wuffs_base__rect_ie_u32__width(&c->private_impl.bounds) : 0;
5077 static inline uint32_t //
5078 wuffs_base__frame_config__height(const wuffs_base__frame_config* c) {
5079 return c ? wuffs_base__rect_ie_u32__height(&c->private_impl.bounds) : 0;
5082 // wuffs_base__frame_config__duration returns the amount of time to display
5083 // this frame. Zero means to display forever - a still (non-animated) image.
5084 static inline wuffs_base__flicks //
5085 wuffs_base__frame_config__duration(const wuffs_base__frame_config* c) {
5086 return c ? c->private_impl.duration : 0;
5089 // wuffs_base__frame_config__index returns the index of this frame. The first
5090 // frame in an image has index 0, the second frame has index 1, and so on.
5091 static inline uint64_t //
5092 wuffs_base__frame_config__index(const wuffs_base__frame_config* c) {
5093 return c ? c->private_impl.index : 0;
5096 // wuffs_base__frame_config__io_position returns the I/O stream position before
5097 // the frame config.
5098 static inline uint64_t //
5099 wuffs_base__frame_config__io_position(const wuffs_base__frame_config* c) {
5100 return c ? c->private_impl.io_position : 0;
5103 // wuffs_base__frame_config__disposal returns, for an animated image, how to
5104 // dispose of this frame after displaying it.
5105 static inline wuffs_base__animation_disposal //
5106 wuffs_base__frame_config__disposal(const wuffs_base__frame_config* c) {
5107 return c ? c->private_impl.disposal : 0;
5110 // wuffs_base__frame_config__opaque_within_bounds returns whether all pixels
5111 // within the frame's bounds are fully opaque. It makes no claim about pixels
5112 // outside the frame bounds but still inside the overall image. The two
5113 // bounding rectangles can differ for animated images.
5115 // Its semantics are conservative. It is valid for a fully opaque frame to have
5116 // this value be false: a false negative.
5118 // If true, drawing the frame with WUFFS_BASE__PIXEL_BLEND__SRC and
5119 // WUFFS_BASE__PIXEL_BLEND__SRC_OVER should be equivalent, in terms of
5120 // resultant pixels, but the former may be faster.
5121 static inline bool //
5122 wuffs_base__frame_config__opaque_within_bounds(
5123 const wuffs_base__frame_config* c) {
5124 return c && c->private_impl.opaque_within_bounds;
5127 // wuffs_base__frame_config__overwrite_instead_of_blend returns, for an
5128 // animated image, whether to ignore the previous image state (within the frame
5129 // bounds) when drawing this incremental frame. Equivalently, whether to use
5130 // WUFFS_BASE__PIXEL_BLEND__SRC instead of WUFFS_BASE__PIXEL_BLEND__SRC_OVER.
5132 // The WebP spec (https://developers.google.com/speed/webp/docs/riff_container)
5133 // calls this the "Blending method" bit. WebP's "Do not blend" corresponds to
5134 // Wuffs' "overwrite_instead_of_blend".
5135 static inline bool //
5136 wuffs_base__frame_config__overwrite_instead_of_blend(
5137 const wuffs_base__frame_config* c) {
5138 return c && c->private_impl.overwrite_instead_of_blend;
5141 static inline wuffs_base__color_u32_argb_premul //
5142 wuffs_base__frame_config__background_color(const wuffs_base__frame_config* c) {
5143 return c ? c->private_impl.background_color : 0;
5146 #ifdef __cplusplus
5148 inline void //
5149 wuffs_base__frame_config::set(
5150 wuffs_base__rect_ie_u32 bounds,
5151 wuffs_base__flicks duration,
5152 uint64_t index,
5153 uint64_t io_position,
5154 wuffs_base__animation_disposal disposal,
5155 bool opaque_within_bounds,
5156 bool overwrite_instead_of_blend,
5157 wuffs_base__color_u32_argb_premul background_color) {
5158 wuffs_base__frame_config__set(this, bounds, duration, index, io_position,
5159 disposal, opaque_within_bounds,
5160 overwrite_instead_of_blend, background_color);
5163 inline wuffs_base__rect_ie_u32 //
5164 wuffs_base__frame_config::bounds() const {
5165 return wuffs_base__frame_config__bounds(this);
5168 inline uint32_t //
5169 wuffs_base__frame_config::width() const {
5170 return wuffs_base__frame_config__width(this);
5173 inline uint32_t //
5174 wuffs_base__frame_config::height() const {
5175 return wuffs_base__frame_config__height(this);
5178 inline wuffs_base__flicks //
5179 wuffs_base__frame_config::duration() const {
5180 return wuffs_base__frame_config__duration(this);
5183 inline uint64_t //
5184 wuffs_base__frame_config::index() const {
5185 return wuffs_base__frame_config__index(this);
5188 inline uint64_t //
5189 wuffs_base__frame_config::io_position() const {
5190 return wuffs_base__frame_config__io_position(this);
5193 inline wuffs_base__animation_disposal //
5194 wuffs_base__frame_config::disposal() const {
5195 return wuffs_base__frame_config__disposal(this);
5198 inline bool //
5199 wuffs_base__frame_config::opaque_within_bounds() const {
5200 return wuffs_base__frame_config__opaque_within_bounds(this);
5203 inline bool //
5204 wuffs_base__frame_config::overwrite_instead_of_blend() const {
5205 return wuffs_base__frame_config__overwrite_instead_of_blend(this);
5208 inline wuffs_base__color_u32_argb_premul //
5209 wuffs_base__frame_config::background_color() const {
5210 return wuffs_base__frame_config__background_color(this);
5213 #endif // __cplusplus
5215 // --------
5217 typedef struct wuffs_base__pixel_buffer__struct {
5218 wuffs_base__pixel_config pixcfg;
5220 // Do not access the private_impl's fields directly. There is no API/ABI
5221 // compatibility or safety guarantee if you do so.
5222 struct {
5223 wuffs_base__table_u8 planes[WUFFS_BASE__PIXEL_FORMAT__NUM_PLANES_MAX_INCL];
5224 // TODO: color spaces.
5225 } private_impl;
5227 #ifdef __cplusplus
5228 inline wuffs_base__status set_interleaved(
5229 const wuffs_base__pixel_config* pixcfg,
5230 wuffs_base__table_u8 primary_memory,
5231 wuffs_base__slice_u8 palette_memory);
5232 inline wuffs_base__status set_from_slice(
5233 const wuffs_base__pixel_config* pixcfg,
5234 wuffs_base__slice_u8 pixbuf_memory);
5235 inline wuffs_base__slice_u8 palette();
5236 inline wuffs_base__slice_u8 palette_or_else(wuffs_base__slice_u8 fallback);
5237 inline wuffs_base__pixel_format pixel_format() const;
5238 inline wuffs_base__table_u8 plane(uint32_t p);
5239 inline wuffs_base__color_u32_argb_premul color_u32_at(uint32_t x,
5240 uint32_t y) const;
5241 inline wuffs_base__status set_color_u32_at(
5242 uint32_t x,
5243 uint32_t y,
5244 wuffs_base__color_u32_argb_premul color);
5245 inline wuffs_base__status set_color_u32_fill_rect(
5246 wuffs_base__rect_ie_u32 rect,
5247 wuffs_base__color_u32_argb_premul color);
5248 #endif // __cplusplus
5250 } wuffs_base__pixel_buffer;
5252 static inline wuffs_base__pixel_buffer //
5253 wuffs_base__null_pixel_buffer(void) {
5254 wuffs_base__pixel_buffer ret;
5255 ret.pixcfg = wuffs_base__null_pixel_config();
5256 ret.private_impl.planes[0] = wuffs_base__empty_table_u8();
5257 ret.private_impl.planes[1] = wuffs_base__empty_table_u8();
5258 ret.private_impl.planes[2] = wuffs_base__empty_table_u8();
5259 ret.private_impl.planes[3] = wuffs_base__empty_table_u8();
5260 return ret;
5263 static inline wuffs_base__status //
5264 wuffs_base__pixel_buffer__set_interleaved(
5265 wuffs_base__pixel_buffer* pb,
5266 const wuffs_base__pixel_config* pixcfg,
5267 wuffs_base__table_u8 primary_memory,
5268 wuffs_base__slice_u8 palette_memory) {
5269 if (!pb) {
5270 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
5272 memset(pb, 0, sizeof(*pb));
5273 if (!pixcfg ||
5274 wuffs_base__pixel_format__is_planar(&pixcfg->private_impl.pixfmt)) {
5275 return wuffs_base__make_status(wuffs_base__error__bad_argument);
5277 if (wuffs_base__pixel_format__is_indexed(&pixcfg->private_impl.pixfmt) &&
5278 (palette_memory.len <
5279 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH)) {
5280 return wuffs_base__make_status(
5281 wuffs_base__error__bad_argument_length_too_short);
5283 uint32_t bits_per_pixel =
5284 wuffs_base__pixel_format__bits_per_pixel(&pixcfg->private_impl.pixfmt);
5285 if ((bits_per_pixel == 0) || ((bits_per_pixel % 8) != 0)) {
5286 // TODO: support fraction-of-byte pixels, e.g. 1 bit per pixel?
5287 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
5289 uint64_t bytes_per_pixel = bits_per_pixel / 8;
5291 uint64_t width_in_bytes =
5292 ((uint64_t)pixcfg->private_impl.width) * bytes_per_pixel;
5293 if ((width_in_bytes > primary_memory.width) ||
5294 (pixcfg->private_impl.height > primary_memory.height)) {
5295 return wuffs_base__make_status(wuffs_base__error__bad_argument);
5298 pb->pixcfg = *pixcfg;
5299 pb->private_impl.planes[0] = primary_memory;
5300 if (wuffs_base__pixel_format__is_indexed(&pixcfg->private_impl.pixfmt)) {
5301 wuffs_base__table_u8* tab =
5302 &pb->private_impl
5303 .planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE];
5304 tab->ptr = palette_memory.ptr;
5305 tab->width = WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
5306 tab->height = 1;
5307 tab->stride = WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
5309 return wuffs_base__make_status(NULL);
5312 static inline wuffs_base__status //
5313 wuffs_base__pixel_buffer__set_from_slice(wuffs_base__pixel_buffer* pb,
5314 const wuffs_base__pixel_config* pixcfg,
5315 wuffs_base__slice_u8 pixbuf_memory) {
5316 if (!pb) {
5317 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
5319 memset(pb, 0, sizeof(*pb));
5320 if (!pixcfg) {
5321 return wuffs_base__make_status(wuffs_base__error__bad_argument);
5323 if (wuffs_base__pixel_format__is_planar(&pixcfg->private_impl.pixfmt)) {
5324 // TODO: support planar pixel formats, concious of pixel subsampling.
5325 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
5327 uint32_t bits_per_pixel =
5328 wuffs_base__pixel_format__bits_per_pixel(&pixcfg->private_impl.pixfmt);
5329 if ((bits_per_pixel == 0) || ((bits_per_pixel % 8) != 0)) {
5330 // TODO: support fraction-of-byte pixels, e.g. 1 bit per pixel?
5331 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
5333 uint64_t bytes_per_pixel = bits_per_pixel / 8;
5335 uint8_t* ptr = pixbuf_memory.ptr;
5336 uint64_t len = pixbuf_memory.len;
5337 if (wuffs_base__pixel_format__is_indexed(&pixcfg->private_impl.pixfmt)) {
5338 // Split a WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH byte
5339 // chunk (1024 bytes = 256 palette entries × 4 bytes per entry) from the
5340 // start of pixbuf_memory. We split from the start, not the end, so that
5341 // the both chunks' pointers have the same alignment as the original
5342 // pointer, up to an alignment of 1024.
5343 if (len < WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
5344 return wuffs_base__make_status(
5345 wuffs_base__error__bad_argument_length_too_short);
5347 wuffs_base__table_u8* tab =
5348 &pb->private_impl
5349 .planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE];
5350 tab->ptr = ptr;
5351 tab->width = WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
5352 tab->height = 1;
5353 tab->stride = WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
5354 ptr += WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
5355 len -= WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
5358 uint64_t wh = ((uint64_t)pixcfg->private_impl.width) *
5359 ((uint64_t)pixcfg->private_impl.height);
5360 size_t width = (size_t)(pixcfg->private_impl.width);
5361 if ((wh > (UINT64_MAX / bytes_per_pixel)) ||
5362 (width > (SIZE_MAX / bytes_per_pixel))) {
5363 return wuffs_base__make_status(wuffs_base__error__bad_argument);
5365 wh *= bytes_per_pixel;
5366 width = ((size_t)(width * bytes_per_pixel));
5367 if (wh > len) {
5368 return wuffs_base__make_status(
5369 wuffs_base__error__bad_argument_length_too_short);
5372 pb->pixcfg = *pixcfg;
5373 wuffs_base__table_u8* tab = &pb->private_impl.planes[0];
5374 tab->ptr = ptr;
5375 tab->width = width;
5376 tab->height = pixcfg->private_impl.height;
5377 tab->stride = width;
5378 return wuffs_base__make_status(NULL);
5381 // wuffs_base__pixel_buffer__palette returns the palette color data. If
5382 // non-empty, it will have length
5383 // WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH.
5384 static inline wuffs_base__slice_u8 //
5385 wuffs_base__pixel_buffer__palette(wuffs_base__pixel_buffer* pb) {
5386 if (pb &&
5387 wuffs_base__pixel_format__is_indexed(&pb->pixcfg.private_impl.pixfmt)) {
5388 wuffs_base__table_u8* tab =
5389 &pb->private_impl
5390 .planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE];
5391 if ((tab->width ==
5392 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) &&
5393 (tab->height == 1)) {
5394 return wuffs_base__make_slice_u8(
5395 tab->ptr, WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH);
5398 return wuffs_base__empty_slice_u8();
5401 static inline wuffs_base__slice_u8 //
5402 wuffs_base__pixel_buffer__palette_or_else(wuffs_base__pixel_buffer* pb,
5403 wuffs_base__slice_u8 fallback) {
5404 if (pb &&
5405 wuffs_base__pixel_format__is_indexed(&pb->pixcfg.private_impl.pixfmt)) {
5406 wuffs_base__table_u8* tab =
5407 &pb->private_impl
5408 .planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE];
5409 if ((tab->width ==
5410 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) &&
5411 (tab->height == 1)) {
5412 return wuffs_base__make_slice_u8(
5413 tab->ptr, WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH);
5416 return fallback;
5419 static inline wuffs_base__pixel_format //
5420 wuffs_base__pixel_buffer__pixel_format(const wuffs_base__pixel_buffer* pb) {
5421 if (pb) {
5422 return pb->pixcfg.private_impl.pixfmt;
5424 return wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__INVALID);
5427 static inline wuffs_base__table_u8 //
5428 wuffs_base__pixel_buffer__plane(wuffs_base__pixel_buffer* pb, uint32_t p) {
5429 if (pb && (p < WUFFS_BASE__PIXEL_FORMAT__NUM_PLANES_MAX_INCL)) {
5430 return pb->private_impl.planes[p];
5433 wuffs_base__table_u8 ret;
5434 ret.ptr = NULL;
5435 ret.width = 0;
5436 ret.height = 0;
5437 ret.stride = 0;
5438 return ret;
5441 WUFFS_BASE__MAYBE_STATIC wuffs_base__color_u32_argb_premul //
5442 wuffs_base__pixel_buffer__color_u32_at(const wuffs_base__pixel_buffer* pb,
5443 uint32_t x,
5444 uint32_t y);
5446 WUFFS_BASE__MAYBE_STATIC wuffs_base__status //
5447 wuffs_base__pixel_buffer__set_color_u32_at(
5448 wuffs_base__pixel_buffer* pb,
5449 uint32_t x,
5450 uint32_t y,
5451 wuffs_base__color_u32_argb_premul color);
5453 WUFFS_BASE__MAYBE_STATIC wuffs_base__status //
5454 wuffs_base__pixel_buffer__set_color_u32_fill_rect(
5455 wuffs_base__pixel_buffer* pb,
5456 wuffs_base__rect_ie_u32 rect,
5457 wuffs_base__color_u32_argb_premul color);
5459 #ifdef __cplusplus
5461 inline wuffs_base__status //
5462 wuffs_base__pixel_buffer::set_interleaved(
5463 const wuffs_base__pixel_config* pixcfg_arg,
5464 wuffs_base__table_u8 primary_memory,
5465 wuffs_base__slice_u8 palette_memory) {
5466 return wuffs_base__pixel_buffer__set_interleaved(
5467 this, pixcfg_arg, primary_memory, palette_memory);
5470 inline wuffs_base__status //
5471 wuffs_base__pixel_buffer::set_from_slice(
5472 const wuffs_base__pixel_config* pixcfg_arg,
5473 wuffs_base__slice_u8 pixbuf_memory) {
5474 return wuffs_base__pixel_buffer__set_from_slice(this, pixcfg_arg,
5475 pixbuf_memory);
5478 inline wuffs_base__slice_u8 //
5479 wuffs_base__pixel_buffer::palette() {
5480 return wuffs_base__pixel_buffer__palette(this);
5483 inline wuffs_base__slice_u8 //
5484 wuffs_base__pixel_buffer::palette_or_else(wuffs_base__slice_u8 fallback) {
5485 return wuffs_base__pixel_buffer__palette_or_else(this, fallback);
5488 inline wuffs_base__pixel_format //
5489 wuffs_base__pixel_buffer::pixel_format() const {
5490 return wuffs_base__pixel_buffer__pixel_format(this);
5493 inline wuffs_base__table_u8 //
5494 wuffs_base__pixel_buffer::plane(uint32_t p) {
5495 return wuffs_base__pixel_buffer__plane(this, p);
5498 inline wuffs_base__color_u32_argb_premul //
5499 wuffs_base__pixel_buffer::color_u32_at(uint32_t x, uint32_t y) const {
5500 return wuffs_base__pixel_buffer__color_u32_at(this, x, y);
5503 inline wuffs_base__status //
5504 wuffs_base__pixel_buffer::set_color_u32_at(
5505 uint32_t x,
5506 uint32_t y,
5507 wuffs_base__color_u32_argb_premul color) {
5508 return wuffs_base__pixel_buffer__set_color_u32_at(this, x, y, color);
5511 inline wuffs_base__status //
5512 wuffs_base__pixel_buffer::set_color_u32_fill_rect(
5513 wuffs_base__rect_ie_u32 rect,
5514 wuffs_base__color_u32_argb_premul color) {
5515 return wuffs_base__pixel_buffer__set_color_u32_fill_rect(this, rect, color);
5518 #endif // __cplusplus
5520 // --------
5522 typedef struct wuffs_base__decode_frame_options__struct {
5523 // Do not access the private_impl's fields directly. There is no API/ABI
5524 // compatibility or safety guarantee if you do so.
5525 struct {
5526 uint8_t TODO;
5527 } private_impl;
5529 #ifdef __cplusplus
5530 #endif // __cplusplus
5532 } wuffs_base__decode_frame_options;
5534 #ifdef __cplusplus
5536 #endif // __cplusplus
5538 // --------
5540 // wuffs_base__pixel_palette__closest_element returns the index of the palette
5541 // element that minimizes the sum of squared differences of the four ARGB
5542 // channels, working in premultiplied alpha. Ties favor the smaller index.
5544 // The palette_slice.len may equal (N*4), for N less than 256, which means that
5545 // only the first N palette elements are considered. It returns 0 when N is 0.
5547 // Applying this function on a per-pixel basis will not produce whole-of-image
5548 // dithering.
5549 WUFFS_BASE__MAYBE_STATIC uint8_t //
5550 wuffs_base__pixel_palette__closest_element(
5551 wuffs_base__slice_u8 palette_slice,
5552 wuffs_base__pixel_format palette_format,
5553 wuffs_base__color_u32_argb_premul c);
5555 // --------
5557 // TODO: should the func type take restrict pointers?
5558 typedef uint64_t (*wuffs_base__pixel_swizzler__func)(uint8_t* dst_ptr,
5559 size_t dst_len,
5560 uint8_t* dst_palette_ptr,
5561 size_t dst_palette_len,
5562 const uint8_t* src_ptr,
5563 size_t src_len);
5565 typedef uint64_t (*wuffs_base__pixel_swizzler__transparent_black_func)(
5566 uint8_t* dst_ptr,
5567 size_t dst_len,
5568 uint8_t* dst_palette_ptr,
5569 size_t dst_palette_len,
5570 uint64_t num_pixels,
5571 uint32_t dst_pixfmt_bytes_per_pixel);
5573 typedef struct wuffs_base__pixel_swizzler__struct {
5574 // Do not access the private_impl's fields directly. There is no API/ABI
5575 // compatibility or safety guarantee if you do so.
5576 struct {
5577 wuffs_base__pixel_swizzler__func func;
5578 wuffs_base__pixel_swizzler__transparent_black_func transparent_black_func;
5579 uint32_t dst_pixfmt_bytes_per_pixel;
5580 uint32_t src_pixfmt_bytes_per_pixel;
5581 } private_impl;
5583 #ifdef __cplusplus
5584 inline wuffs_base__status prepare(wuffs_base__pixel_format dst_pixfmt,
5585 wuffs_base__slice_u8 dst_palette,
5586 wuffs_base__pixel_format src_pixfmt,
5587 wuffs_base__slice_u8 src_palette,
5588 wuffs_base__pixel_blend blend);
5589 inline uint64_t swizzle_interleaved_from_slice(
5590 wuffs_base__slice_u8 dst,
5591 wuffs_base__slice_u8 dst_palette,
5592 wuffs_base__slice_u8 src) const;
5593 #endif // __cplusplus
5595 } wuffs_base__pixel_swizzler;
5597 // wuffs_base__pixel_swizzler__prepare readies the pixel swizzler so that its
5598 // other methods may be called.
5600 // For modular builds that divide the base module into sub-modules, using this
5601 // function requires the WUFFS_CONFIG__MODULE__BASE__PIXCONV sub-module, not
5602 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5603 WUFFS_BASE__MAYBE_STATIC wuffs_base__status //
5604 wuffs_base__pixel_swizzler__prepare(wuffs_base__pixel_swizzler* p,
5605 wuffs_base__pixel_format dst_pixfmt,
5606 wuffs_base__slice_u8 dst_palette,
5607 wuffs_base__pixel_format src_pixfmt,
5608 wuffs_base__slice_u8 src_palette,
5609 wuffs_base__pixel_blend blend);
5611 // wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice converts pixels
5612 // from a source format to a destination format.
5614 // For modular builds that divide the base module into sub-modules, using this
5615 // function requires the WUFFS_CONFIG__MODULE__BASE__PIXCONV sub-module, not
5616 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5617 WUFFS_BASE__MAYBE_STATIC uint64_t //
5618 wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(
5619 const wuffs_base__pixel_swizzler* p,
5620 wuffs_base__slice_u8 dst,
5621 wuffs_base__slice_u8 dst_palette,
5622 wuffs_base__slice_u8 src);
5624 #ifdef __cplusplus
5626 inline wuffs_base__status //
5627 wuffs_base__pixel_swizzler::prepare(wuffs_base__pixel_format dst_pixfmt,
5628 wuffs_base__slice_u8 dst_palette,
5629 wuffs_base__pixel_format src_pixfmt,
5630 wuffs_base__slice_u8 src_palette,
5631 wuffs_base__pixel_blend blend) {
5632 return wuffs_base__pixel_swizzler__prepare(this, dst_pixfmt, dst_palette,
5633 src_pixfmt, src_palette, blend);
5636 uint64_t //
5637 wuffs_base__pixel_swizzler::swizzle_interleaved_from_slice(
5638 wuffs_base__slice_u8 dst,
5639 wuffs_base__slice_u8 dst_palette,
5640 wuffs_base__slice_u8 src) const {
5641 return wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(
5642 this, dst, dst_palette, src);
5645 #endif // __cplusplus
5647 // ---------------- String Conversions
5649 // Options (bitwise or'ed together) for wuffs_base__parse_number_xxx
5650 // functions. The XXX options apply to both integer and floating point. The FXX
5651 // options apply only to floating point.
5653 #define WUFFS_BASE__PARSE_NUMBER_XXX__DEFAULT_OPTIONS ((uint32_t)0x00000000)
5655 // WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_MULTIPLE_LEADING_ZEROES means to accept
5656 // inputs like "00", "0644" and "00.7". By default, they are rejected.
5657 #define WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_MULTIPLE_LEADING_ZEROES \
5658 ((uint32_t)0x00000001)
5660 // WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES means to accept inputs like
5661 // "1__2" and "_3.141_592". By default, they are rejected.
5662 #define WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES ((uint32_t)0x00000002)
5664 // WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA means to accept
5665 // "1,5" and not "1.5" as one-and-a-half.
5667 // If the caller wants to accept either, it is responsible for canonicalizing
5668 // the input before calling wuffs_base__parse_number_fxx. The caller also has
5669 // more context on e.g. exactly how to treat something like "$1,234".
5670 #define WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA \
5671 ((uint32_t)0x00000010)
5673 // WUFFS_BASE__PARSE_NUMBER_FXX__REJECT_INF_AND_NAN means to reject inputs that
5674 // would lead to infinite or Not-a-Number floating point values. By default,
5675 // they are accepted.
5677 // This affects the literal "inf" as input, but also affects inputs like
5678 // "1e999" that would overflow double-precision floating point.
5679 #define WUFFS_BASE__PARSE_NUMBER_FXX__REJECT_INF_AND_NAN ((uint32_t)0x00000020)
5681 // --------
5683 // Options (bitwise or'ed together) for wuffs_base__render_number_xxx
5684 // functions. The XXX options apply to both integer and floating point. The FXX
5685 // options apply only to floating point.
5687 #define WUFFS_BASE__RENDER_NUMBER_XXX__DEFAULT_OPTIONS ((uint32_t)0x00000000)
5689 // WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT means to render to the right side
5690 // (higher indexes) of the destination slice, leaving any untouched bytes on
5691 // the left side (lower indexes). The default is vice versa: rendering on the
5692 // left with slack on the right.
5693 #define WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT ((uint32_t)0x00000100)
5695 // WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN means to render the leading
5696 // "+" for non-negative numbers: "+0" and "+12.3" instead of "0" and "12.3".
5697 #define WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN ((uint32_t)0x00000200)
5699 // WUFFS_BASE__RENDER_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA means to render
5700 // one-and-a-half as "1,5" instead of "1.5".
5701 #define WUFFS_BASE__RENDER_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA \
5702 ((uint32_t)0x00001000)
5704 // WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_ETC means whether to never
5705 // (EXPONENT_ABSENT, equivalent to printf's "%f") or to always
5706 // (EXPONENT_PRESENT, equivalent to printf's "%e") render a floating point
5707 // number as "1.23e+05" instead of "123000".
5709 // Having both bits set is the same has having neither bit set, where the
5710 // notation used depends on whether the exponent is sufficiently large: "0.5"
5711 // is preferred over "5e-01" but "5e-09" is preferred over "0.000000005".
5712 #define WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_ABSENT ((uint32_t)0x00002000)
5713 #define WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_PRESENT ((uint32_t)0x00004000)
5715 // WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION means to render the
5716 // smallest number of digits so that parsing the resultant string will recover
5717 // the same double-precision floating point number.
5719 // For example, double-precision cannot distinguish between 0.3 and
5720 // 0.299999999999999988897769753748434595763683319091796875, so when this bit
5721 // is set, rendering the latter will produce "0.3" but rendering
5722 // 0.3000000000000000444089209850062616169452667236328125 will produce
5723 // "0.30000000000000004".
5724 #define WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION \
5725 ((uint32_t)0x00008000)
5727 // ---------------- IEEE 754 Floating Point
5729 // wuffs_base__ieee_754_bit_representation__etc converts between a double
5730 // precision numerical value and its IEEE 754 representations:
5731 // - 16-bit: 1 sign bit, 5 exponent bits, 10 explicit significand bits.
5732 // - 32-bit: 1 sign bit, 8 exponent bits, 23 explicit significand bits.
5733 // - 64-bit: 1 sign bit, 11 exponent bits, 52 explicit significand bits.
5735 // For example, it converts between:
5736 // - +1.0 and 0x3C00, 0x3F80_0000 or 0x3FF0_0000_0000_0000.
5737 // - +5.5 and 0x4580, 0x40B0_0000 or 0x4016_0000_0000_0000.
5738 // - -inf and 0xFC00, 0xFF80_0000 or 0xFFF0_0000_0000_0000.
5740 // Converting from f64 to shorter formats (f16 or f32, represented in C as
5741 // uint16_t and uint32_t) may be lossy. Such functions have names that look
5742 // like etc_truncate, as converting finite numbers produce equal or smaller
5743 // (closer-to-zero) finite numbers. For example, 1048576.0 is a perfectly valid
5744 // f64 number, but converting it to a f16 (with truncation) produces 65504.0,
5745 // the largest finite f16 number. Truncating a f64-typed value d to f32 does
5746 // not always produce the same result as the C-style cast ((float)d), as
5747 // casting can convert from finite numbers to infinite ones.
5749 // Converting infinities or NaNs produces infinities or NaNs and always report
5750 // no loss, even though there a multiple NaN representations so that round-
5751 // tripping a f64-typed NaN may produce a different 64 bits. Nonetheless, the
5752 // etc_truncate functions preserve a NaN's "quiet vs signaling" bit.
5754 // See https://en.wikipedia.org/wiki/Double-precision_floating-point_format
5756 typedef struct wuffs_base__lossy_value_u16__struct {
5757 uint16_t value;
5758 bool lossy;
5759 } wuffs_base__lossy_value_u16;
5761 typedef struct wuffs_base__lossy_value_u32__struct {
5762 uint32_t value;
5763 bool lossy;
5764 } wuffs_base__lossy_value_u32;
5766 WUFFS_BASE__MAYBE_STATIC wuffs_base__lossy_value_u16 //
5767 wuffs_base__ieee_754_bit_representation__from_f64_to_u16_truncate(double f);
5769 WUFFS_BASE__MAYBE_STATIC wuffs_base__lossy_value_u32 //
5770 wuffs_base__ieee_754_bit_representation__from_f64_to_u32_truncate(double f);
5772 static inline uint64_t //
5773 wuffs_base__ieee_754_bit_representation__from_f64_to_u64(double f) {
5774 uint64_t u = 0;
5775 if (sizeof(uint64_t) == sizeof(double)) {
5776 memcpy(&u, &f, sizeof(uint64_t));
5778 return u;
5781 static inline double //
5782 wuffs_base__ieee_754_bit_representation__from_u16_to_f64(uint16_t u) {
5783 uint64_t v = ((uint64_t)(u & 0x8000)) << 48;
5785 do {
5786 uint64_t exp = (u >> 10) & 0x1F;
5787 uint64_t man = u & 0x3FF;
5788 if (exp == 0x1F) { // Infinity or NaN.
5789 exp = 2047;
5790 } else if (exp != 0) { // Normal.
5791 exp += 1008; // 1008 = 1023 - 15, the difference in biases.
5792 } else if (man != 0) { // Subnormal but non-zero.
5793 uint32_t clz = wuffs_base__count_leading_zeroes_u64(man);
5794 exp = 1062 - clz; // 1062 = 1008 + 64 - 10.
5795 man = 0x3FF & (man << (clz - 53));
5796 } else { // Zero.
5797 break;
5799 v |= (exp << 52) | (man << 42);
5800 } while (0);
5802 double f = 0;
5803 if (sizeof(uint64_t) == sizeof(double)) {
5804 memcpy(&f, &v, sizeof(uint64_t));
5806 return f;
5809 static inline double //
5810 wuffs_base__ieee_754_bit_representation__from_u32_to_f64(uint32_t u) {
5811 float f = 0;
5812 if (sizeof(uint32_t) == sizeof(float)) {
5813 memcpy(&f, &u, sizeof(uint32_t));
5815 return (double)f;
5818 static inline double //
5819 wuffs_base__ieee_754_bit_representation__from_u64_to_f64(uint64_t u) {
5820 double f = 0;
5821 if (sizeof(uint64_t) == sizeof(double)) {
5822 memcpy(&f, &u, sizeof(uint64_t));
5824 return f;
5827 // ---------------- Parsing and Rendering Numbers
5829 // wuffs_base__parse_number_f64 parses the floating point number in s. For
5830 // example, if s contains the bytes "1.5" then it will return the double 1.5.
5832 // It returns an error if s does not contain a floating point number.
5834 // It does not necessarily return an error if the conversion is lossy, e.g. if
5835 // s is "0.3", which double-precision floating point cannot represent exactly.
5837 // Similarly, the returned value may be infinite (and no error returned) even
5838 // if s was not "inf", when the input is nominally finite but sufficiently
5839 // larger than DBL_MAX, about 1.8e+308.
5841 // It is similar to the C standard library's strtod function, but:
5842 // - Errors are returned in-band (in a result type), not out-of-band (errno).
5843 // - It takes a slice (a pointer and length), not a NUL-terminated C string.
5844 // - It does not take an optional endptr argument. It does not allow a partial
5845 // parse: it returns an error unless all of s is consumed.
5846 // - It does not allow whitespace, leading or otherwise.
5847 // - It does not allow hexadecimal floating point numbers.
5848 // - It is not affected by i18n / l10n settings such as environment variables.
5850 // The options argument can change these, but by default, it:
5851 // - Allows "inf", "+Infinity" and "-NAN", case insensitive. Similarly,
5852 // without an explicit opt-out, it would successfully parse "1e999" as
5853 // infinity, even though it overflows double-precision floating point.
5854 // - Rejects underscores. With an explicit opt-in, "_3.141_592" would
5855 // successfully parse as an approximation to π.
5856 // - Rejects unnecessary leading zeroes: "00", "0644" and "00.7".
5857 // - Uses a dot '1.5' instead of a comma '1,5' for the decimal separator.
5859 // For modular builds that divide the base module into sub-modules, using this
5860 // function requires the WUFFS_CONFIG__MODULE__BASE__FLOATCONV sub-module, not
5861 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5862 WUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64 //
5863 wuffs_base__parse_number_f64(wuffs_base__slice_u8 s, uint32_t options);
5865 // wuffs_base__parse_number_i64 parses the ASCII integer in s. For example, if
5866 // s contains the bytes "-123" then it will return the int64_t -123.
5868 // It returns an error if s does not contain an integer or if the integer
5869 // within would overflow an int64_t.
5871 // It is similar to wuffs_base__parse_number_u64 but it returns a signed
5872 // integer, not an unsigned integer. It also allows a leading '+' or '-'.
5874 // For modular builds that divide the base module into sub-modules, using this
5875 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5876 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5877 WUFFS_BASE__MAYBE_STATIC wuffs_base__result_i64 //
5878 wuffs_base__parse_number_i64(wuffs_base__slice_u8 s, uint32_t options);
5880 // wuffs_base__parse_number_u64 parses the ASCII integer in s. For example, if
5881 // s contains the bytes "123" then it will return the uint64_t 123.
5883 // It returns an error if s does not contain an integer or if the integer
5884 // within would overflow a uint64_t.
5886 // It is similar to the C standard library's strtoull function, but:
5887 // - Errors are returned in-band (in a result type), not out-of-band (errno).
5888 // - It takes a slice (a pointer and length), not a NUL-terminated C string.
5889 // - It does not take an optional endptr argument. It does not allow a partial
5890 // parse: it returns an error unless all of s is consumed.
5891 // - It does not allow whitespace, leading or otherwise.
5892 // - It does not allow a leading '+' or '-'.
5893 // - It does not take a base argument (e.g. base 10 vs base 16). Instead, it
5894 // always accepts both decimal (e.g "1234", "0d5678") and hexadecimal (e.g.
5895 // "0x9aBC"). The caller is responsible for prior filtering of e.g. hex
5896 // numbers if they are unwanted. For example, Wuffs' JSON decoder will only
5897 // produce a wuffs_base__token for decimal numbers, not hexadecimal.
5898 // - It is not affected by i18n / l10n settings such as environment variables.
5900 // The options argument can change these, but by default, it:
5901 // - Rejects underscores. With an explicit opt-in, "__0D_1_002" would
5902 // successfully parse as "one thousand and two". Underscores are still
5903 // rejected inside the optional 2-byte opening "0d" or "0X" that denotes
5904 // base-10 or base-16.
5905 // - Rejects unnecessary leading zeroes: "00" and "0644".
5907 // For modular builds that divide the base module into sub-modules, using this
5908 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5909 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5910 WUFFS_BASE__MAYBE_STATIC wuffs_base__result_u64 //
5911 wuffs_base__parse_number_u64(wuffs_base__slice_u8 s, uint32_t options);
5913 // --------
5915 // WUFFS_BASE__I64__BYTE_LENGTH__MAX_INCL is the string length of
5916 // "-9223372036854775808" and "+9223372036854775807", INT64_MIN and INT64_MAX.
5917 #define WUFFS_BASE__I64__BYTE_LENGTH__MAX_INCL 20
5919 // WUFFS_BASE__U64__BYTE_LENGTH__MAX_INCL is the string length of
5920 // "+18446744073709551615", UINT64_MAX.
5921 #define WUFFS_BASE__U64__BYTE_LENGTH__MAX_INCL 21
5923 // wuffs_base__render_number_f64 writes the decimal encoding of x to dst and
5924 // returns the number of bytes written. If dst is shorter than the entire
5925 // encoding, it returns 0 (and no bytes are written).
5927 // For those familiar with C's printf or Go's fmt.Printf functions:
5928 // - "%e" means the WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_PRESENT option.
5929 // - "%f" means the WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_ABSENT option.
5930 // - "%g" means neither or both bits are set.
5932 // The precision argument controls the number of digits rendered, excluding the
5933 // exponent (the "e+05" in "1.23e+05"):
5934 // - for "%e" and "%f" it is the number of digits after the decimal separator,
5935 // - for "%g" it is the number of significant digits (and trailing zeroes are
5936 // removed).
5938 // A precision of 6 gives similar output to printf's defaults.
5940 // A precision greater than 4095 is equivalent to 4095.
5942 // The precision argument is ignored when the
5943 // WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION option is set. This is
5944 // similar to Go's strconv.FormatFloat with a negative (i.e. non-sensical)
5945 // precision, but there is no corresponding feature in C's printf.
5947 // Extreme values of x will be rendered as "NaN", "Inf" (or "+Inf" if the
5948 // WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN option is set) or "-Inf".
5950 // For modular builds that divide the base module into sub-modules, using this
5951 // function requires the WUFFS_CONFIG__MODULE__BASE__FLOATCONV sub-module, not
5952 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5953 WUFFS_BASE__MAYBE_STATIC size_t //
5954 wuffs_base__render_number_f64(wuffs_base__slice_u8 dst,
5955 double x,
5956 uint32_t precision,
5957 uint32_t options);
5959 // wuffs_base__render_number_i64 writes the decimal encoding of x to dst and
5960 // returns the number of bytes written. If dst is shorter than the entire
5961 // encoding, it returns 0 (and no bytes are written).
5963 // dst will never be too short if its length is at least 20, also known as
5964 // WUFFS_BASE__I64__BYTE_LENGTH__MAX_INCL.
5966 // For modular builds that divide the base module into sub-modules, using this
5967 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5968 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5969 WUFFS_BASE__MAYBE_STATIC size_t //
5970 wuffs_base__render_number_i64(wuffs_base__slice_u8 dst,
5971 int64_t x,
5972 uint32_t options);
5974 // wuffs_base__render_number_u64 writes the decimal encoding of x to dst and
5975 // returns the number of bytes written. If dst is shorter than the entire
5976 // encoding, it returns 0 (and no bytes are written).
5978 // dst will never be too short if its length is at least 21, also known as
5979 // WUFFS_BASE__U64__BYTE_LENGTH__MAX_INCL.
5981 // For modular builds that divide the base module into sub-modules, using this
5982 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5983 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5984 WUFFS_BASE__MAYBE_STATIC size_t //
5985 wuffs_base__render_number_u64(wuffs_base__slice_u8 dst,
5986 uint64_t x,
5987 uint32_t options);
5989 // ---------------- Base-16
5991 // Options (bitwise or'ed together) for wuffs_base__base_16__xxx functions.
5993 #define WUFFS_BASE__BASE_16__DEFAULT_OPTIONS ((uint32_t)0x00000000)
5995 // wuffs_base__base_16__decode2 converts "6A6b" to "jk", where e.g. 'j' is
5996 // U+006A. There are 2 src bytes for every dst byte.
5998 // It assumes that the src bytes are two hexadecimal digits (0-9, A-F, a-f),
5999 // repeated. It may write nonsense bytes if not, although it will not read or
6000 // write out of bounds.
6002 // For modular builds that divide the base module into sub-modules, using this
6003 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
6004 // just WUFFS_CONFIG__MODULE__BASE__CORE.
6005 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output //
6006 wuffs_base__base_16__decode2(wuffs_base__slice_u8 dst,
6007 wuffs_base__slice_u8 src,
6008 bool src_closed,
6009 uint32_t options);
6011 // wuffs_base__base_16__decode4 converts both "\\x6A\\x6b" and "??6a??6B" to
6012 // "jk", where e.g. 'j' is U+006A. There are 4 src bytes for every dst byte.
6014 // It assumes that the src bytes are two ignored bytes and then two hexadecimal
6015 // digits (0-9, A-F, a-f), repeated. It may write nonsense bytes if not,
6016 // although it will not read or write out of bounds.
6018 // For modular builds that divide the base module into sub-modules, using this
6019 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
6020 // just WUFFS_CONFIG__MODULE__BASE__CORE.
6021 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output //
6022 wuffs_base__base_16__decode4(wuffs_base__slice_u8 dst,
6023 wuffs_base__slice_u8 src,
6024 bool src_closed,
6025 uint32_t options);
6027 // wuffs_base__base_16__encode2 converts "jk" to "6A6B", where e.g. 'j' is
6028 // U+006A. There are 2 dst bytes for every src byte.
6030 // For modular builds that divide the base module into sub-modules, using this
6031 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
6032 // just WUFFS_CONFIG__MODULE__BASE__CORE.
6033 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output //
6034 wuffs_base__base_16__encode2(wuffs_base__slice_u8 dst,
6035 wuffs_base__slice_u8 src,
6036 bool src_closed,
6037 uint32_t options);
6039 // wuffs_base__base_16__encode4 converts "jk" to "\\x6A\\x6B", where e.g. 'j'
6040 // is U+006A. There are 4 dst bytes for every src byte.
6042 // For modular builds that divide the base module into sub-modules, using this
6043 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
6044 // just WUFFS_CONFIG__MODULE__BASE__CORE.
6045 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output //
6046 wuffs_base__base_16__encode4(wuffs_base__slice_u8 dst,
6047 wuffs_base__slice_u8 src,
6048 bool src_closed,
6049 uint32_t options);
6051 // ---------------- Base-64
6053 // Options (bitwise or'ed together) for wuffs_base__base_64__xxx functions.
6055 #define WUFFS_BASE__BASE_64__DEFAULT_OPTIONS ((uint32_t)0x00000000)
6057 // WUFFS_BASE__BASE_64__DECODE_ALLOW_PADDING means that, when decoding base-64,
6058 // the input may (but does not need to) be padded with '=' bytes so that the
6059 // overall encoded length in bytes is a multiple of 4. A successful decoding
6060 // will return a num_src that includes those padding bytes.
6062 // Excess padding (e.g. three final '='s) will be rejected as bad data.
6063 #define WUFFS_BASE__BASE_64__DECODE_ALLOW_PADDING ((uint32_t)0x00000001)
6065 // WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING means that, when encoding base-64,
6066 // the output will be padded with '=' bytes so that the overall encoded length
6067 // in bytes is a multiple of 4.
6068 #define WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING ((uint32_t)0x00000002)
6070 // WUFFS_BASE__BASE_64__URL_ALPHABET means that, for base-64, the URL-friendly
6071 // and file-name-friendly alphabet be used, as per RFC 4648 section 5. When
6072 // this option bit is off, the standard alphabet from section 4 is used.
6073 #define WUFFS_BASE__BASE_64__URL_ALPHABET ((uint32_t)0x00000100)
6075 // wuffs_base__base_64__decode transforms base-64 encoded bytes from src to
6076 // arbitrary bytes in dst.
6078 // It will not permit line breaks or other whitespace in src. Filtering those
6079 // out is the responsibility of the caller.
6081 // For modular builds that divide the base module into sub-modules, using this
6082 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
6083 // just WUFFS_CONFIG__MODULE__BASE__CORE.
6084 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output //
6085 wuffs_base__base_64__decode(wuffs_base__slice_u8 dst,
6086 wuffs_base__slice_u8 src,
6087 bool src_closed,
6088 uint32_t options);
6090 // wuffs_base__base_64__encode transforms arbitrary bytes from src to base-64
6091 // encoded bytes in dst.
6093 // For modular builds that divide the base module into sub-modules, using this
6094 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
6095 // just WUFFS_CONFIG__MODULE__BASE__CORE.
6096 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output //
6097 wuffs_base__base_64__encode(wuffs_base__slice_u8 dst,
6098 wuffs_base__slice_u8 src,
6099 bool src_closed,
6100 uint32_t options);
6102 // ---------------- Unicode and UTF-8
6104 #define WUFFS_BASE__UNICODE_CODE_POINT__MIN_INCL 0x00000000
6105 #define WUFFS_BASE__UNICODE_CODE_POINT__MAX_INCL 0x0010FFFF
6107 #define WUFFS_BASE__UNICODE_REPLACEMENT_CHARACTER 0x0000FFFD
6109 #define WUFFS_BASE__UNICODE_SURROGATE__MIN_INCL 0x0000D800
6110 #define WUFFS_BASE__UNICODE_SURROGATE__MAX_INCL 0x0000DFFF
6112 #define WUFFS_BASE__ASCII__MIN_INCL 0x00
6113 #define WUFFS_BASE__ASCII__MAX_INCL 0x7F
6115 #define WUFFS_BASE__UTF_8__BYTE_LENGTH__MIN_INCL 1
6116 #define WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL 4
6118 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_1__CODE_POINT__MIN_INCL 0x00000000
6119 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_1__CODE_POINT__MAX_INCL 0x0000007F
6120 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_2__CODE_POINT__MIN_INCL 0x00000080
6121 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_2__CODE_POINT__MAX_INCL 0x000007FF
6122 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_3__CODE_POINT__MIN_INCL 0x00000800
6123 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_3__CODE_POINT__MAX_INCL 0x0000FFFF
6124 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_4__CODE_POINT__MIN_INCL 0x00010000
6125 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_4__CODE_POINT__MAX_INCL 0x0010FFFF
6127 // --------
6129 // wuffs_base__utf_8__next__output is the type returned by
6130 // wuffs_base__utf_8__next.
6131 typedef struct wuffs_base__utf_8__next__output__struct {
6132 uint32_t code_point;
6133 uint32_t byte_length;
6135 #ifdef __cplusplus
6136 inline bool is_valid() const;
6137 #endif // __cplusplus
6139 } wuffs_base__utf_8__next__output;
6141 static inline wuffs_base__utf_8__next__output //
6142 wuffs_base__make_utf_8__next__output(uint32_t code_point,
6143 uint32_t byte_length) {
6144 wuffs_base__utf_8__next__output ret;
6145 ret.code_point = code_point;
6146 ret.byte_length = byte_length;
6147 return ret;
6150 static inline bool //
6151 wuffs_base__utf_8__next__output__is_valid(
6152 const wuffs_base__utf_8__next__output* o) {
6153 if (o) {
6154 uint32_t cp = o->code_point;
6155 switch (o->byte_length) {
6156 case 1:
6157 return (cp <= 0x7F);
6158 case 2:
6159 return (0x080 <= cp) && (cp <= 0x7FF);
6160 case 3:
6161 // Avoid the 0xD800 ..= 0xDFFF surrogate range.
6162 return ((0x0800 <= cp) && (cp <= 0xD7FF)) ||
6163 ((0xE000 <= cp) && (cp <= 0xFFFF));
6164 case 4:
6165 return (0x00010000 <= cp) && (cp <= 0x0010FFFF);
6168 return false;
6171 #ifdef __cplusplus
6173 inline bool //
6174 wuffs_base__utf_8__next__output::is_valid() const {
6175 return wuffs_base__utf_8__next__output__is_valid(this);
6178 #endif // __cplusplus
6180 // --------
6182 // wuffs_base__utf_8__encode writes the UTF-8 encoding of code_point to s and
6183 // returns the number of bytes written. If code_point is invalid, or if s is
6184 // shorter than the entire encoding, it returns 0 (and no bytes are written).
6186 // s will never be too short if its length is at least 4, also known as
6187 // WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL.
6189 // For modular builds that divide the base module into sub-modules, using this
6190 // function requires the WUFFS_CONFIG__MODULE__BASE__UTF8 sub-module, not just
6191 // WUFFS_CONFIG__MODULE__BASE__CORE.
6192 WUFFS_BASE__MAYBE_STATIC size_t //
6193 wuffs_base__utf_8__encode(wuffs_base__slice_u8 dst, uint32_t code_point);
6195 // wuffs_base__utf_8__next returns the next UTF-8 code point (and that code
6196 // point's byte length) at the start of the read-only slice (s_ptr, s_len).
6198 // There are exactly two cases in which this function returns something where
6199 // wuffs_base__utf_8__next__output__is_valid is false:
6200 // - If s is empty then it returns {.code_point=0, .byte_length=0}.
6201 // - If s is non-empty and starts with invalid UTF-8 then it returns
6202 // {.code_point=WUFFS_BASE__UNICODE_REPLACEMENT_CHARACTER, .byte_length=1}.
6204 // Otherwise, it returns something where
6205 // wuffs_base__utf_8__next__output__is_valid is true.
6207 // In any case, it always returns an output that satisfies both of:
6208 // - (output.code_point <= WUFFS_BASE__UNICODE_CODE_POINT__MAX_INCL).
6209 // - (output.byte_length <= s_len).
6211 // If s is a sub-slice of a larger slice of valid UTF-8, but that sub-slice
6212 // boundary occurs in the middle of a multi-byte UTF-8 encoding of a single
6213 // code point, then this function may return something invalid. It is the
6214 // caller's responsibility to split on or otherwise manage UTF-8 boundaries.
6216 // For modular builds that divide the base module into sub-modules, using this
6217 // function requires the WUFFS_CONFIG__MODULE__BASE__UTF8 sub-module, not just
6218 // WUFFS_CONFIG__MODULE__BASE__CORE.
6219 WUFFS_BASE__MAYBE_STATIC wuffs_base__utf_8__next__output //
6220 wuffs_base__utf_8__next(const uint8_t* s_ptr, size_t s_len);
6222 // wuffs_base__utf_8__next_from_end is like wuffs_base__utf_8__next except that
6223 // it looks at the end of (s_ptr, s_len) instead of the start.
6225 // For modular builds that divide the base module into sub-modules, using this
6226 // function requires the WUFFS_CONFIG__MODULE__BASE__UTF8 sub-module, not just
6227 // WUFFS_CONFIG__MODULE__BASE__CORE.
6228 WUFFS_BASE__MAYBE_STATIC wuffs_base__utf_8__next__output //
6229 wuffs_base__utf_8__next_from_end(const uint8_t* s_ptr, size_t s_len);
6231 // wuffs_base__utf_8__longest_valid_prefix returns the largest n such that the
6232 // sub-slice s[..n] is valid UTF-8, where s is the read-only slice (s_ptr,
6233 // s_len).
6235 // In particular, it returns s_len if and only if all of s is valid UTF-8.
6237 // If s is a sub-slice of a larger slice of valid UTF-8, but that sub-slice
6238 // boundary occurs in the middle of a multi-byte UTF-8 encoding of a single
6239 // code point, then this function will return less than s_len. It is the
6240 // caller's responsibility to split on or otherwise manage UTF-8 boundaries.
6242 // For modular builds that divide the base module into sub-modules, using this
6243 // function requires the WUFFS_CONFIG__MODULE__BASE__UTF8 sub-module, not just
6244 // WUFFS_CONFIG__MODULE__BASE__CORE.
6245 WUFFS_BASE__MAYBE_STATIC size_t //
6246 wuffs_base__utf_8__longest_valid_prefix(const uint8_t* s_ptr, size_t s_len);
6248 // wuffs_base__ascii__longest_valid_prefix returns the largest n such that the
6249 // sub-slice s[..n] is valid ASCII, where s is the read-only slice (s_ptr,
6250 // s_len).
6252 // In particular, it returns s_len if and only if all of s is valid ASCII.
6253 // Equivalently, when none of the bytes in s have the 0x80 high bit set.
6255 // For modular builds that divide the base module into sub-modules, using this
6256 // function requires the WUFFS_CONFIG__MODULE__BASE__UTF8 sub-module, not just
6257 // WUFFS_CONFIG__MODULE__BASE__CORE.
6258 WUFFS_BASE__MAYBE_STATIC size_t //
6259 wuffs_base__ascii__longest_valid_prefix(const uint8_t* s_ptr, size_t s_len);
6261 // ---------------- Interface Declarations.
6263 // For modular builds that divide the base module into sub-modules, using these
6264 // functions require the WUFFS_CONFIG__MODULE__BASE__INTERFACES sub-module, not
6265 // just WUFFS_CONFIG__MODULE__BASE__CORE.
6267 // --------
6269 extern const char wuffs_base__hasher_u32__vtable_name[];
6271 typedef struct wuffs_base__hasher_u32__func_ptrs__struct {
6272 uint32_t (*checksum_u32)(
6273 const void* self);
6274 uint64_t (*get_quirk)(
6275 const void* self,
6276 uint32_t a_key);
6277 wuffs_base__status (*set_quirk)(
6278 void* self,
6279 uint32_t a_key,
6280 uint64_t a_value);
6281 wuffs_base__empty_struct (*update)(
6282 void* self,
6283 wuffs_base__slice_u8 a_x);
6284 uint32_t (*update_u32)(
6285 void* self,
6286 wuffs_base__slice_u8 a_x);
6287 } wuffs_base__hasher_u32__func_ptrs;
6289 typedef struct wuffs_base__hasher_u32__struct wuffs_base__hasher_u32;
6291 WUFFS_BASE__GENERATED_C_CODE
6292 WUFFS_BASE__MAYBE_STATIC uint32_t
6293 wuffs_base__hasher_u32__checksum_u32(
6294 const wuffs_base__hasher_u32* self);
6296 WUFFS_BASE__GENERATED_C_CODE
6297 WUFFS_BASE__MAYBE_STATIC uint64_t
6298 wuffs_base__hasher_u32__get_quirk(
6299 const wuffs_base__hasher_u32* self,
6300 uint32_t a_key);
6302 WUFFS_BASE__GENERATED_C_CODE
6303 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6304 wuffs_base__hasher_u32__set_quirk(
6305 wuffs_base__hasher_u32* self,
6306 uint32_t a_key,
6307 uint64_t a_value);
6309 WUFFS_BASE__GENERATED_C_CODE
6310 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
6311 wuffs_base__hasher_u32__update(
6312 wuffs_base__hasher_u32* self,
6313 wuffs_base__slice_u8 a_x);
6315 WUFFS_BASE__GENERATED_C_CODE
6316 WUFFS_BASE__MAYBE_STATIC uint32_t
6317 wuffs_base__hasher_u32__update_u32(
6318 wuffs_base__hasher_u32* self,
6319 wuffs_base__slice_u8 a_x);
6321 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6323 struct wuffs_base__hasher_u32__struct {
6324 struct {
6325 uint32_t magic;
6326 uint32_t active_coroutine;
6327 wuffs_base__vtable first_vtable;
6328 } private_impl;
6330 #ifdef __cplusplus
6331 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6332 using unique_ptr = std::unique_ptr<wuffs_base__hasher_u32, wuffs_unique_ptr_deleter>;
6333 #endif
6335 inline uint32_t
6336 checksum_u32() const {
6337 return wuffs_base__hasher_u32__checksum_u32(this);
6340 inline uint64_t
6341 get_quirk(
6342 uint32_t a_key) const {
6343 return wuffs_base__hasher_u32__get_quirk(
6344 this, a_key);
6347 inline wuffs_base__status
6348 set_quirk(
6349 uint32_t a_key,
6350 uint64_t a_value) {
6351 return wuffs_base__hasher_u32__set_quirk(
6352 this, a_key, a_value);
6355 inline wuffs_base__empty_struct
6356 update(
6357 wuffs_base__slice_u8 a_x) {
6358 return wuffs_base__hasher_u32__update(
6359 this, a_x);
6362 inline uint32_t
6363 update_u32(
6364 wuffs_base__slice_u8 a_x) {
6365 return wuffs_base__hasher_u32__update_u32(
6366 this, a_x);
6369 #endif // __cplusplus
6370 }; // struct wuffs_base__hasher_u32__struct
6372 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6374 // --------
6376 extern const char wuffs_base__hasher_u64__vtable_name[];
6378 typedef struct wuffs_base__hasher_u64__func_ptrs__struct {
6379 uint64_t (*checksum_u64)(
6380 const void* self);
6381 uint64_t (*get_quirk)(
6382 const void* self,
6383 uint32_t a_key);
6384 wuffs_base__status (*set_quirk)(
6385 void* self,
6386 uint32_t a_key,
6387 uint64_t a_value);
6388 wuffs_base__empty_struct (*update)(
6389 void* self,
6390 wuffs_base__slice_u8 a_x);
6391 uint64_t (*update_u64)(
6392 void* self,
6393 wuffs_base__slice_u8 a_x);
6394 } wuffs_base__hasher_u64__func_ptrs;
6396 typedef struct wuffs_base__hasher_u64__struct wuffs_base__hasher_u64;
6398 WUFFS_BASE__GENERATED_C_CODE
6399 WUFFS_BASE__MAYBE_STATIC uint64_t
6400 wuffs_base__hasher_u64__checksum_u64(
6401 const wuffs_base__hasher_u64* self);
6403 WUFFS_BASE__GENERATED_C_CODE
6404 WUFFS_BASE__MAYBE_STATIC uint64_t
6405 wuffs_base__hasher_u64__get_quirk(
6406 const wuffs_base__hasher_u64* self,
6407 uint32_t a_key);
6409 WUFFS_BASE__GENERATED_C_CODE
6410 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6411 wuffs_base__hasher_u64__set_quirk(
6412 wuffs_base__hasher_u64* self,
6413 uint32_t a_key,
6414 uint64_t a_value);
6416 WUFFS_BASE__GENERATED_C_CODE
6417 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
6418 wuffs_base__hasher_u64__update(
6419 wuffs_base__hasher_u64* self,
6420 wuffs_base__slice_u8 a_x);
6422 WUFFS_BASE__GENERATED_C_CODE
6423 WUFFS_BASE__MAYBE_STATIC uint64_t
6424 wuffs_base__hasher_u64__update_u64(
6425 wuffs_base__hasher_u64* self,
6426 wuffs_base__slice_u8 a_x);
6428 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6430 struct wuffs_base__hasher_u64__struct {
6431 struct {
6432 uint32_t magic;
6433 uint32_t active_coroutine;
6434 wuffs_base__vtable first_vtable;
6435 } private_impl;
6437 #ifdef __cplusplus
6438 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6439 using unique_ptr = std::unique_ptr<wuffs_base__hasher_u64, wuffs_unique_ptr_deleter>;
6440 #endif
6442 inline uint64_t
6443 checksum_u64() const {
6444 return wuffs_base__hasher_u64__checksum_u64(this);
6447 inline uint64_t
6448 get_quirk(
6449 uint32_t a_key) const {
6450 return wuffs_base__hasher_u64__get_quirk(
6451 this, a_key);
6454 inline wuffs_base__status
6455 set_quirk(
6456 uint32_t a_key,
6457 uint64_t a_value) {
6458 return wuffs_base__hasher_u64__set_quirk(
6459 this, a_key, a_value);
6462 inline wuffs_base__empty_struct
6463 update(
6464 wuffs_base__slice_u8 a_x) {
6465 return wuffs_base__hasher_u64__update(
6466 this, a_x);
6469 inline uint64_t
6470 update_u64(
6471 wuffs_base__slice_u8 a_x) {
6472 return wuffs_base__hasher_u64__update_u64(
6473 this, a_x);
6476 #endif // __cplusplus
6477 }; // struct wuffs_base__hasher_u64__struct
6479 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6481 // --------
6483 extern const char wuffs_base__hasher_bitvec256__vtable_name[];
6485 typedef struct wuffs_base__hasher_bitvec256__func_ptrs__struct {
6486 wuffs_base__bitvec256 (*checksum_bitvec256)(
6487 const void* self);
6488 uint64_t (*get_quirk)(
6489 const void* self,
6490 uint32_t a_key);
6491 wuffs_base__status (*set_quirk)(
6492 void* self,
6493 uint32_t a_key,
6494 uint64_t a_value);
6495 wuffs_base__empty_struct (*update)(
6496 void* self,
6497 wuffs_base__slice_u8 a_x);
6498 wuffs_base__bitvec256 (*update_bitvec256)(
6499 void* self,
6500 wuffs_base__slice_u8 a_x);
6501 } wuffs_base__hasher_bitvec256__func_ptrs;
6503 typedef struct wuffs_base__hasher_bitvec256__struct wuffs_base__hasher_bitvec256;
6505 WUFFS_BASE__GENERATED_C_CODE
6506 WUFFS_BASE__MAYBE_STATIC wuffs_base__bitvec256
6507 wuffs_base__hasher_bitvec256__checksum_bitvec256(
6508 const wuffs_base__hasher_bitvec256* self);
6510 WUFFS_BASE__GENERATED_C_CODE
6511 WUFFS_BASE__MAYBE_STATIC uint64_t
6512 wuffs_base__hasher_bitvec256__get_quirk(
6513 const wuffs_base__hasher_bitvec256* self,
6514 uint32_t a_key);
6516 WUFFS_BASE__GENERATED_C_CODE
6517 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6518 wuffs_base__hasher_bitvec256__set_quirk(
6519 wuffs_base__hasher_bitvec256* self,
6520 uint32_t a_key,
6521 uint64_t a_value);
6523 WUFFS_BASE__GENERATED_C_CODE
6524 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
6525 wuffs_base__hasher_bitvec256__update(
6526 wuffs_base__hasher_bitvec256* self,
6527 wuffs_base__slice_u8 a_x);
6529 WUFFS_BASE__GENERATED_C_CODE
6530 WUFFS_BASE__MAYBE_STATIC wuffs_base__bitvec256
6531 wuffs_base__hasher_bitvec256__update_bitvec256(
6532 wuffs_base__hasher_bitvec256* self,
6533 wuffs_base__slice_u8 a_x);
6535 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6537 struct wuffs_base__hasher_bitvec256__struct {
6538 struct {
6539 uint32_t magic;
6540 uint32_t active_coroutine;
6541 wuffs_base__vtable first_vtable;
6542 } private_impl;
6544 #ifdef __cplusplus
6545 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6546 using unique_ptr = std::unique_ptr<wuffs_base__hasher_bitvec256, wuffs_unique_ptr_deleter>;
6547 #endif
6549 inline wuffs_base__bitvec256
6550 checksum_bitvec256() const {
6551 return wuffs_base__hasher_bitvec256__checksum_bitvec256(this);
6554 inline uint64_t
6555 get_quirk(
6556 uint32_t a_key) const {
6557 return wuffs_base__hasher_bitvec256__get_quirk(
6558 this, a_key);
6561 inline wuffs_base__status
6562 set_quirk(
6563 uint32_t a_key,
6564 uint64_t a_value) {
6565 return wuffs_base__hasher_bitvec256__set_quirk(
6566 this, a_key, a_value);
6569 inline wuffs_base__empty_struct
6570 update(
6571 wuffs_base__slice_u8 a_x) {
6572 return wuffs_base__hasher_bitvec256__update(
6573 this, a_x);
6576 inline wuffs_base__bitvec256
6577 update_bitvec256(
6578 wuffs_base__slice_u8 a_x) {
6579 return wuffs_base__hasher_bitvec256__update_bitvec256(
6580 this, a_x);
6583 #endif // __cplusplus
6584 }; // struct wuffs_base__hasher_bitvec256__struct
6586 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6588 // --------
6590 extern const char wuffs_base__image_decoder__vtable_name[];
6592 typedef struct wuffs_base__image_decoder__func_ptrs__struct {
6593 wuffs_base__status (*decode_frame)(
6594 void* self,
6595 wuffs_base__pixel_buffer* a_dst,
6596 wuffs_base__io_buffer* a_src,
6597 wuffs_base__pixel_blend a_blend,
6598 wuffs_base__slice_u8 a_workbuf,
6599 wuffs_base__decode_frame_options* a_opts);
6600 wuffs_base__status (*decode_frame_config)(
6601 void* self,
6602 wuffs_base__frame_config* a_dst,
6603 wuffs_base__io_buffer* a_src);
6604 wuffs_base__status (*decode_image_config)(
6605 void* self,
6606 wuffs_base__image_config* a_dst,
6607 wuffs_base__io_buffer* a_src);
6608 wuffs_base__rect_ie_u32 (*frame_dirty_rect)(
6609 const void* self);
6610 uint64_t (*get_quirk)(
6611 const void* self,
6612 uint32_t a_key);
6613 uint32_t (*num_animation_loops)(
6614 const void* self);
6615 uint64_t (*num_decoded_frame_configs)(
6616 const void* self);
6617 uint64_t (*num_decoded_frames)(
6618 const void* self);
6619 wuffs_base__status (*restart_frame)(
6620 void* self,
6621 uint64_t a_index,
6622 uint64_t a_io_position);
6623 wuffs_base__status (*set_quirk)(
6624 void* self,
6625 uint32_t a_key,
6626 uint64_t a_value);
6627 wuffs_base__empty_struct (*set_report_metadata)(
6628 void* self,
6629 uint32_t a_fourcc,
6630 bool a_report);
6631 wuffs_base__status (*tell_me_more)(
6632 void* self,
6633 wuffs_base__io_buffer* a_dst,
6634 wuffs_base__more_information* a_minfo,
6635 wuffs_base__io_buffer* a_src);
6636 wuffs_base__range_ii_u64 (*workbuf_len)(
6637 const void* self);
6638 } wuffs_base__image_decoder__func_ptrs;
6640 typedef struct wuffs_base__image_decoder__struct wuffs_base__image_decoder;
6642 WUFFS_BASE__GENERATED_C_CODE
6643 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6644 wuffs_base__image_decoder__decode_frame(
6645 wuffs_base__image_decoder* self,
6646 wuffs_base__pixel_buffer* a_dst,
6647 wuffs_base__io_buffer* a_src,
6648 wuffs_base__pixel_blend a_blend,
6649 wuffs_base__slice_u8 a_workbuf,
6650 wuffs_base__decode_frame_options* a_opts);
6652 WUFFS_BASE__GENERATED_C_CODE
6653 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6654 wuffs_base__image_decoder__decode_frame_config(
6655 wuffs_base__image_decoder* self,
6656 wuffs_base__frame_config* a_dst,
6657 wuffs_base__io_buffer* a_src);
6659 WUFFS_BASE__GENERATED_C_CODE
6660 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6661 wuffs_base__image_decoder__decode_image_config(
6662 wuffs_base__image_decoder* self,
6663 wuffs_base__image_config* a_dst,
6664 wuffs_base__io_buffer* a_src);
6666 WUFFS_BASE__GENERATED_C_CODE
6667 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
6668 wuffs_base__image_decoder__frame_dirty_rect(
6669 const wuffs_base__image_decoder* self);
6671 WUFFS_BASE__GENERATED_C_CODE
6672 WUFFS_BASE__MAYBE_STATIC uint64_t
6673 wuffs_base__image_decoder__get_quirk(
6674 const wuffs_base__image_decoder* self,
6675 uint32_t a_key);
6677 WUFFS_BASE__GENERATED_C_CODE
6678 WUFFS_BASE__MAYBE_STATIC uint32_t
6679 wuffs_base__image_decoder__num_animation_loops(
6680 const wuffs_base__image_decoder* self);
6682 WUFFS_BASE__GENERATED_C_CODE
6683 WUFFS_BASE__MAYBE_STATIC uint64_t
6684 wuffs_base__image_decoder__num_decoded_frame_configs(
6685 const wuffs_base__image_decoder* self);
6687 WUFFS_BASE__GENERATED_C_CODE
6688 WUFFS_BASE__MAYBE_STATIC uint64_t
6689 wuffs_base__image_decoder__num_decoded_frames(
6690 const wuffs_base__image_decoder* self);
6692 WUFFS_BASE__GENERATED_C_CODE
6693 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6694 wuffs_base__image_decoder__restart_frame(
6695 wuffs_base__image_decoder* self,
6696 uint64_t a_index,
6697 uint64_t a_io_position);
6699 WUFFS_BASE__GENERATED_C_CODE
6700 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6701 wuffs_base__image_decoder__set_quirk(
6702 wuffs_base__image_decoder* self,
6703 uint32_t a_key,
6704 uint64_t a_value);
6706 WUFFS_BASE__GENERATED_C_CODE
6707 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
6708 wuffs_base__image_decoder__set_report_metadata(
6709 wuffs_base__image_decoder* self,
6710 uint32_t a_fourcc,
6711 bool a_report);
6713 WUFFS_BASE__GENERATED_C_CODE
6714 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6715 wuffs_base__image_decoder__tell_me_more(
6716 wuffs_base__image_decoder* self,
6717 wuffs_base__io_buffer* a_dst,
6718 wuffs_base__more_information* a_minfo,
6719 wuffs_base__io_buffer* a_src);
6721 WUFFS_BASE__GENERATED_C_CODE
6722 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
6723 wuffs_base__image_decoder__workbuf_len(
6724 const wuffs_base__image_decoder* self);
6726 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6728 struct wuffs_base__image_decoder__struct {
6729 struct {
6730 uint32_t magic;
6731 uint32_t active_coroutine;
6732 wuffs_base__vtable first_vtable;
6733 } private_impl;
6735 #ifdef __cplusplus
6736 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6737 using unique_ptr = std::unique_ptr<wuffs_base__image_decoder, wuffs_unique_ptr_deleter>;
6738 #endif
6740 inline wuffs_base__status
6741 decode_frame(
6742 wuffs_base__pixel_buffer* a_dst,
6743 wuffs_base__io_buffer* a_src,
6744 wuffs_base__pixel_blend a_blend,
6745 wuffs_base__slice_u8 a_workbuf,
6746 wuffs_base__decode_frame_options* a_opts) {
6747 return wuffs_base__image_decoder__decode_frame(
6748 this, a_dst, a_src, a_blend, a_workbuf, a_opts);
6751 inline wuffs_base__status
6752 decode_frame_config(
6753 wuffs_base__frame_config* a_dst,
6754 wuffs_base__io_buffer* a_src) {
6755 return wuffs_base__image_decoder__decode_frame_config(
6756 this, a_dst, a_src);
6759 inline wuffs_base__status
6760 decode_image_config(
6761 wuffs_base__image_config* a_dst,
6762 wuffs_base__io_buffer* a_src) {
6763 return wuffs_base__image_decoder__decode_image_config(
6764 this, a_dst, a_src);
6767 inline wuffs_base__rect_ie_u32
6768 frame_dirty_rect() const {
6769 return wuffs_base__image_decoder__frame_dirty_rect(this);
6772 inline uint64_t
6773 get_quirk(
6774 uint32_t a_key) const {
6775 return wuffs_base__image_decoder__get_quirk(
6776 this, a_key);
6779 inline uint32_t
6780 num_animation_loops() const {
6781 return wuffs_base__image_decoder__num_animation_loops(this);
6784 inline uint64_t
6785 num_decoded_frame_configs() const {
6786 return wuffs_base__image_decoder__num_decoded_frame_configs(this);
6789 inline uint64_t
6790 num_decoded_frames() const {
6791 return wuffs_base__image_decoder__num_decoded_frames(this);
6794 inline wuffs_base__status
6795 restart_frame(
6796 uint64_t a_index,
6797 uint64_t a_io_position) {
6798 return wuffs_base__image_decoder__restart_frame(
6799 this, a_index, a_io_position);
6802 inline wuffs_base__status
6803 set_quirk(
6804 uint32_t a_key,
6805 uint64_t a_value) {
6806 return wuffs_base__image_decoder__set_quirk(
6807 this, a_key, a_value);
6810 inline wuffs_base__empty_struct
6811 set_report_metadata(
6812 uint32_t a_fourcc,
6813 bool a_report) {
6814 return wuffs_base__image_decoder__set_report_metadata(
6815 this, a_fourcc, a_report);
6818 inline wuffs_base__status
6819 tell_me_more(
6820 wuffs_base__io_buffer* a_dst,
6821 wuffs_base__more_information* a_minfo,
6822 wuffs_base__io_buffer* a_src) {
6823 return wuffs_base__image_decoder__tell_me_more(
6824 this, a_dst, a_minfo, a_src);
6827 inline wuffs_base__range_ii_u64
6828 workbuf_len() const {
6829 return wuffs_base__image_decoder__workbuf_len(this);
6832 #endif // __cplusplus
6833 }; // struct wuffs_base__image_decoder__struct
6835 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6837 // --------
6839 extern const char wuffs_base__io_transformer__vtable_name[];
6841 typedef struct wuffs_base__io_transformer__func_ptrs__struct {
6842 wuffs_base__optional_u63 (*dst_history_retain_length)(
6843 const void* self);
6844 uint64_t (*get_quirk)(
6845 const void* self,
6846 uint32_t a_key);
6847 wuffs_base__status (*set_quirk)(
6848 void* self,
6849 uint32_t a_key,
6850 uint64_t a_value);
6851 wuffs_base__status (*transform_io)(
6852 void* self,
6853 wuffs_base__io_buffer* a_dst,
6854 wuffs_base__io_buffer* a_src,
6855 wuffs_base__slice_u8 a_workbuf);
6856 wuffs_base__range_ii_u64 (*workbuf_len)(
6857 const void* self);
6858 } wuffs_base__io_transformer__func_ptrs;
6860 typedef struct wuffs_base__io_transformer__struct wuffs_base__io_transformer;
6862 WUFFS_BASE__GENERATED_C_CODE
6863 WUFFS_BASE__MAYBE_STATIC wuffs_base__optional_u63
6864 wuffs_base__io_transformer__dst_history_retain_length(
6865 const wuffs_base__io_transformer* self);
6867 WUFFS_BASE__GENERATED_C_CODE
6868 WUFFS_BASE__MAYBE_STATIC uint64_t
6869 wuffs_base__io_transformer__get_quirk(
6870 const wuffs_base__io_transformer* self,
6871 uint32_t a_key);
6873 WUFFS_BASE__GENERATED_C_CODE
6874 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6875 wuffs_base__io_transformer__set_quirk(
6876 wuffs_base__io_transformer* self,
6877 uint32_t a_key,
6878 uint64_t a_value);
6880 WUFFS_BASE__GENERATED_C_CODE
6881 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6882 wuffs_base__io_transformer__transform_io(
6883 wuffs_base__io_transformer* self,
6884 wuffs_base__io_buffer* a_dst,
6885 wuffs_base__io_buffer* a_src,
6886 wuffs_base__slice_u8 a_workbuf);
6888 WUFFS_BASE__GENERATED_C_CODE
6889 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
6890 wuffs_base__io_transformer__workbuf_len(
6891 const wuffs_base__io_transformer* self);
6893 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6895 struct wuffs_base__io_transformer__struct {
6896 struct {
6897 uint32_t magic;
6898 uint32_t active_coroutine;
6899 wuffs_base__vtable first_vtable;
6900 } private_impl;
6902 #ifdef __cplusplus
6903 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6904 using unique_ptr = std::unique_ptr<wuffs_base__io_transformer, wuffs_unique_ptr_deleter>;
6905 #endif
6907 inline wuffs_base__optional_u63
6908 dst_history_retain_length() const {
6909 return wuffs_base__io_transformer__dst_history_retain_length(this);
6912 inline uint64_t
6913 get_quirk(
6914 uint32_t a_key) const {
6915 return wuffs_base__io_transformer__get_quirk(
6916 this, a_key);
6919 inline wuffs_base__status
6920 set_quirk(
6921 uint32_t a_key,
6922 uint64_t a_value) {
6923 return wuffs_base__io_transformer__set_quirk(
6924 this, a_key, a_value);
6927 inline wuffs_base__status
6928 transform_io(
6929 wuffs_base__io_buffer* a_dst,
6930 wuffs_base__io_buffer* a_src,
6931 wuffs_base__slice_u8 a_workbuf) {
6932 return wuffs_base__io_transformer__transform_io(
6933 this, a_dst, a_src, a_workbuf);
6936 inline wuffs_base__range_ii_u64
6937 workbuf_len() const {
6938 return wuffs_base__io_transformer__workbuf_len(this);
6941 #endif // __cplusplus
6942 }; // struct wuffs_base__io_transformer__struct
6944 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6946 // --------
6948 extern const char wuffs_base__token_decoder__vtable_name[];
6950 typedef struct wuffs_base__token_decoder__func_ptrs__struct {
6951 wuffs_base__status (*decode_tokens)(
6952 void* self,
6953 wuffs_base__token_buffer* a_dst,
6954 wuffs_base__io_buffer* a_src,
6955 wuffs_base__slice_u8 a_workbuf);
6956 uint64_t (*get_quirk)(
6957 const void* self,
6958 uint32_t a_key);
6959 wuffs_base__status (*set_quirk)(
6960 void* self,
6961 uint32_t a_key,
6962 uint64_t a_value);
6963 wuffs_base__range_ii_u64 (*workbuf_len)(
6964 const void* self);
6965 } wuffs_base__token_decoder__func_ptrs;
6967 typedef struct wuffs_base__token_decoder__struct wuffs_base__token_decoder;
6969 WUFFS_BASE__GENERATED_C_CODE
6970 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6971 wuffs_base__token_decoder__decode_tokens(
6972 wuffs_base__token_decoder* self,
6973 wuffs_base__token_buffer* a_dst,
6974 wuffs_base__io_buffer* a_src,
6975 wuffs_base__slice_u8 a_workbuf);
6977 WUFFS_BASE__GENERATED_C_CODE
6978 WUFFS_BASE__MAYBE_STATIC uint64_t
6979 wuffs_base__token_decoder__get_quirk(
6980 const wuffs_base__token_decoder* self,
6981 uint32_t a_key);
6983 WUFFS_BASE__GENERATED_C_CODE
6984 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6985 wuffs_base__token_decoder__set_quirk(
6986 wuffs_base__token_decoder* self,
6987 uint32_t a_key,
6988 uint64_t a_value);
6990 WUFFS_BASE__GENERATED_C_CODE
6991 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
6992 wuffs_base__token_decoder__workbuf_len(
6993 const wuffs_base__token_decoder* self);
6995 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6997 struct wuffs_base__token_decoder__struct {
6998 struct {
6999 uint32_t magic;
7000 uint32_t active_coroutine;
7001 wuffs_base__vtable first_vtable;
7002 } private_impl;
7004 #ifdef __cplusplus
7005 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
7006 using unique_ptr = std::unique_ptr<wuffs_base__token_decoder, wuffs_unique_ptr_deleter>;
7007 #endif
7009 inline wuffs_base__status
7010 decode_tokens(
7011 wuffs_base__token_buffer* a_dst,
7012 wuffs_base__io_buffer* a_src,
7013 wuffs_base__slice_u8 a_workbuf) {
7014 return wuffs_base__token_decoder__decode_tokens(
7015 this, a_dst, a_src, a_workbuf);
7018 inline uint64_t
7019 get_quirk(
7020 uint32_t a_key) const {
7021 return wuffs_base__token_decoder__get_quirk(
7022 this, a_key);
7025 inline wuffs_base__status
7026 set_quirk(
7027 uint32_t a_key,
7028 uint64_t a_value) {
7029 return wuffs_base__token_decoder__set_quirk(
7030 this, a_key, a_value);
7033 inline wuffs_base__range_ii_u64
7034 workbuf_len() const {
7035 return wuffs_base__token_decoder__workbuf_len(this);
7038 #endif // __cplusplus
7039 }; // struct wuffs_base__token_decoder__struct
7041 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7043 // ----------------
7045 #ifdef __cplusplus
7046 } // extern "C"
7047 #endif
7049 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ADLER32) || defined(WUFFS_NONMONOLITHIC)
7051 // ---------------- Status Codes
7053 // ---------------- Public Consts
7055 // ---------------- Struct Declarations
7057 typedef struct wuffs_adler32__hasher__struct wuffs_adler32__hasher;
7059 #ifdef __cplusplus
7060 extern "C" {
7061 #endif
7063 // ---------------- Public Initializer Prototypes
7065 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
7066 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
7068 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
7069 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
7071 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
7072 wuffs_adler32__hasher__initialize(
7073 wuffs_adler32__hasher* self,
7074 size_t sizeof_star_self,
7075 uint64_t wuffs_version,
7076 uint32_t options);
7078 size_t
7079 sizeof__wuffs_adler32__hasher(void);
7081 // ---------------- Allocs
7083 // These functions allocate and initialize Wuffs structs. They return NULL if
7084 // memory allocation fails. If they return non-NULL, there is no need to call
7085 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
7086 // calling free on the returned pointer. That pointer is effectively a C++
7087 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
7089 wuffs_adler32__hasher*
7090 wuffs_adler32__hasher__alloc(void);
7092 static inline wuffs_base__hasher_u32*
7093 wuffs_adler32__hasher__alloc_as__wuffs_base__hasher_u32(void) {
7094 return (wuffs_base__hasher_u32*)(wuffs_adler32__hasher__alloc());
7097 // ---------------- Upcasts
7099 static inline wuffs_base__hasher_u32*
7100 wuffs_adler32__hasher__upcast_as__wuffs_base__hasher_u32(
7101 wuffs_adler32__hasher* p) {
7102 return (wuffs_base__hasher_u32*)p;
7105 // ---------------- Public Function Prototypes
7107 WUFFS_BASE__GENERATED_C_CODE
7108 WUFFS_BASE__MAYBE_STATIC uint64_t
7109 wuffs_adler32__hasher__get_quirk(
7110 const wuffs_adler32__hasher* self,
7111 uint32_t a_key);
7113 WUFFS_BASE__GENERATED_C_CODE
7114 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7115 wuffs_adler32__hasher__set_quirk(
7116 wuffs_adler32__hasher* self,
7117 uint32_t a_key,
7118 uint64_t a_value);
7120 WUFFS_BASE__GENERATED_C_CODE
7121 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
7122 wuffs_adler32__hasher__update(
7123 wuffs_adler32__hasher* self,
7124 wuffs_base__slice_u8 a_x);
7126 WUFFS_BASE__GENERATED_C_CODE
7127 WUFFS_BASE__MAYBE_STATIC uint32_t
7128 wuffs_adler32__hasher__update_u32(
7129 wuffs_adler32__hasher* self,
7130 wuffs_base__slice_u8 a_x);
7132 WUFFS_BASE__GENERATED_C_CODE
7133 WUFFS_BASE__MAYBE_STATIC uint32_t
7134 wuffs_adler32__hasher__checksum_u32(
7135 const wuffs_adler32__hasher* self);
7137 #ifdef __cplusplus
7138 } // extern "C"
7139 #endif
7141 // ---------------- Struct Definitions
7143 // These structs' fields, and the sizeof them, are private implementation
7144 // details that aren't guaranteed to be stable across Wuffs versions.
7146 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
7148 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7150 struct wuffs_adler32__hasher__struct {
7151 // Do not access the private_impl's or private_data's fields directly. There
7152 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
7153 // the wuffs_foo__bar__baz functions.
7155 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
7156 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
7158 struct {
7159 uint32_t magic;
7160 uint32_t active_coroutine;
7161 wuffs_base__vtable vtable_for__wuffs_base__hasher_u32;
7162 wuffs_base__vtable null_vtable;
7164 uint32_t f_state;
7165 bool f_started;
7167 wuffs_base__empty_struct (*choosy_up)(
7168 wuffs_adler32__hasher* self,
7169 wuffs_base__slice_u8 a_x);
7170 } private_impl;
7172 #ifdef __cplusplus
7173 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
7174 using unique_ptr = std::unique_ptr<wuffs_adler32__hasher, wuffs_unique_ptr_deleter>;
7176 // On failure, the alloc_etc functions return nullptr. They don't throw.
7178 static inline unique_ptr
7179 alloc() {
7180 return unique_ptr(wuffs_adler32__hasher__alloc());
7183 static inline wuffs_base__hasher_u32::unique_ptr
7184 alloc_as__wuffs_base__hasher_u32() {
7185 return wuffs_base__hasher_u32::unique_ptr(
7186 wuffs_adler32__hasher__alloc_as__wuffs_base__hasher_u32());
7188 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
7190 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
7191 // Disallow constructing or copying an object via standard C++ mechanisms,
7192 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
7193 // size and field layout is not part of the public, stable, memory-safe API.
7194 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
7195 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
7196 // their first argument) rather than tweaking bar.private_impl.qux fields.
7198 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
7199 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
7200 // order to provide convenience methods. These forward on "this", so that you
7201 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
7202 wuffs_adler32__hasher__struct() = delete;
7203 wuffs_adler32__hasher__struct(const wuffs_adler32__hasher__struct&) = delete;
7204 wuffs_adler32__hasher__struct& operator=(
7205 const wuffs_adler32__hasher__struct&) = delete;
7206 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
7208 #if !defined(WUFFS_IMPLEMENTATION)
7209 // As above, the size of the struct is not part of the public API, and unless
7210 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
7211 // allocated, not stack allocated. Its size is not intended to be known at
7212 // compile time, but it is unfortunately divulged as a side effect of
7213 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
7214 // instead of "sizeof T", invoking the operator. To make the two values
7215 // different, so that passing the latter will be rejected by the initialize
7216 // function, we add an arbitrary amount of dead weight.
7217 uint8_t dead_weight[123000000]; // 123 MB.
7218 #endif // !defined(WUFFS_IMPLEMENTATION)
7220 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
7221 initialize(
7222 size_t sizeof_star_self,
7223 uint64_t wuffs_version,
7224 uint32_t options) {
7225 return wuffs_adler32__hasher__initialize(
7226 this, sizeof_star_self, wuffs_version, options);
7229 inline wuffs_base__hasher_u32*
7230 upcast_as__wuffs_base__hasher_u32() {
7231 return (wuffs_base__hasher_u32*)this;
7234 inline uint64_t
7235 get_quirk(
7236 uint32_t a_key) const {
7237 return wuffs_adler32__hasher__get_quirk(this, a_key);
7240 inline wuffs_base__status
7241 set_quirk(
7242 uint32_t a_key,
7243 uint64_t a_value) {
7244 return wuffs_adler32__hasher__set_quirk(this, a_key, a_value);
7247 inline wuffs_base__empty_struct
7248 update(
7249 wuffs_base__slice_u8 a_x) {
7250 return wuffs_adler32__hasher__update(this, a_x);
7253 inline uint32_t
7254 update_u32(
7255 wuffs_base__slice_u8 a_x) {
7256 return wuffs_adler32__hasher__update_u32(this, a_x);
7259 inline uint32_t
7260 checksum_u32() const {
7261 return wuffs_adler32__hasher__checksum_u32(this);
7264 #endif // __cplusplus
7265 }; // struct wuffs_adler32__hasher__struct
7267 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7269 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ADLER32) || defined(WUFFS_NONMONOLITHIC)
7271 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BMP) || defined(WUFFS_NONMONOLITHIC)
7273 // ---------------- Status Codes
7275 extern const char wuffs_bmp__error__bad_header[];
7276 extern const char wuffs_bmp__error__bad_rle_compression[];
7277 extern const char wuffs_bmp__error__truncated_input[];
7278 extern const char wuffs_bmp__error__unsupported_bmp_file[];
7280 // ---------------- Public Consts
7282 #define WUFFS_BMP__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0u
7284 // ---------------- Struct Declarations
7286 typedef struct wuffs_bmp__decoder__struct wuffs_bmp__decoder;
7288 #ifdef __cplusplus
7289 extern "C" {
7290 #endif
7292 // ---------------- Public Initializer Prototypes
7294 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
7295 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
7297 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
7298 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
7300 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
7301 wuffs_bmp__decoder__initialize(
7302 wuffs_bmp__decoder* self,
7303 size_t sizeof_star_self,
7304 uint64_t wuffs_version,
7305 uint32_t options);
7307 size_t
7308 sizeof__wuffs_bmp__decoder(void);
7310 // ---------------- Allocs
7312 // These functions allocate and initialize Wuffs structs. They return NULL if
7313 // memory allocation fails. If they return non-NULL, there is no need to call
7314 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
7315 // calling free on the returned pointer. That pointer is effectively a C++
7316 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
7318 wuffs_bmp__decoder*
7319 wuffs_bmp__decoder__alloc(void);
7321 static inline wuffs_base__image_decoder*
7322 wuffs_bmp__decoder__alloc_as__wuffs_base__image_decoder(void) {
7323 return (wuffs_base__image_decoder*)(wuffs_bmp__decoder__alloc());
7326 // ---------------- Upcasts
7328 static inline wuffs_base__image_decoder*
7329 wuffs_bmp__decoder__upcast_as__wuffs_base__image_decoder(
7330 wuffs_bmp__decoder* p) {
7331 return (wuffs_base__image_decoder*)p;
7334 // ---------------- Public Function Prototypes
7336 WUFFS_BASE__GENERATED_C_CODE
7337 WUFFS_BASE__MAYBE_STATIC uint64_t
7338 wuffs_bmp__decoder__get_quirk(
7339 const wuffs_bmp__decoder* self,
7340 uint32_t a_key);
7342 WUFFS_BASE__GENERATED_C_CODE
7343 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7344 wuffs_bmp__decoder__set_quirk(
7345 wuffs_bmp__decoder* self,
7346 uint32_t a_key,
7347 uint64_t a_value);
7349 WUFFS_BASE__GENERATED_C_CODE
7350 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7351 wuffs_bmp__decoder__decode_image_config(
7352 wuffs_bmp__decoder* self,
7353 wuffs_base__image_config* a_dst,
7354 wuffs_base__io_buffer* a_src);
7356 WUFFS_BASE__GENERATED_C_CODE
7357 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7358 wuffs_bmp__decoder__decode_frame_config(
7359 wuffs_bmp__decoder* self,
7360 wuffs_base__frame_config* a_dst,
7361 wuffs_base__io_buffer* a_src);
7363 WUFFS_BASE__GENERATED_C_CODE
7364 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7365 wuffs_bmp__decoder__decode_frame(
7366 wuffs_bmp__decoder* self,
7367 wuffs_base__pixel_buffer* a_dst,
7368 wuffs_base__io_buffer* a_src,
7369 wuffs_base__pixel_blend a_blend,
7370 wuffs_base__slice_u8 a_workbuf,
7371 wuffs_base__decode_frame_options* a_opts);
7373 WUFFS_BASE__GENERATED_C_CODE
7374 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
7375 wuffs_bmp__decoder__frame_dirty_rect(
7376 const wuffs_bmp__decoder* self);
7378 WUFFS_BASE__GENERATED_C_CODE
7379 WUFFS_BASE__MAYBE_STATIC uint32_t
7380 wuffs_bmp__decoder__num_animation_loops(
7381 const wuffs_bmp__decoder* self);
7383 WUFFS_BASE__GENERATED_C_CODE
7384 WUFFS_BASE__MAYBE_STATIC uint64_t
7385 wuffs_bmp__decoder__num_decoded_frame_configs(
7386 const wuffs_bmp__decoder* self);
7388 WUFFS_BASE__GENERATED_C_CODE
7389 WUFFS_BASE__MAYBE_STATIC uint64_t
7390 wuffs_bmp__decoder__num_decoded_frames(
7391 const wuffs_bmp__decoder* self);
7393 WUFFS_BASE__GENERATED_C_CODE
7394 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7395 wuffs_bmp__decoder__restart_frame(
7396 wuffs_bmp__decoder* self,
7397 uint64_t a_index,
7398 uint64_t a_io_position);
7400 WUFFS_BASE__GENERATED_C_CODE
7401 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
7402 wuffs_bmp__decoder__set_report_metadata(
7403 wuffs_bmp__decoder* self,
7404 uint32_t a_fourcc,
7405 bool a_report);
7407 WUFFS_BASE__GENERATED_C_CODE
7408 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7409 wuffs_bmp__decoder__tell_me_more(
7410 wuffs_bmp__decoder* self,
7411 wuffs_base__io_buffer* a_dst,
7412 wuffs_base__more_information* a_minfo,
7413 wuffs_base__io_buffer* a_src);
7415 WUFFS_BASE__GENERATED_C_CODE
7416 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
7417 wuffs_bmp__decoder__workbuf_len(
7418 const wuffs_bmp__decoder* self);
7420 #ifdef __cplusplus
7421 } // extern "C"
7422 #endif
7424 // ---------------- Struct Definitions
7426 // These structs' fields, and the sizeof them, are private implementation
7427 // details that aren't guaranteed to be stable across Wuffs versions.
7429 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
7431 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7433 struct wuffs_bmp__decoder__struct {
7434 // Do not access the private_impl's or private_data's fields directly. There
7435 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
7436 // the wuffs_foo__bar__baz functions.
7438 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
7439 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
7441 struct {
7442 uint32_t magic;
7443 uint32_t active_coroutine;
7444 wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
7445 wuffs_base__vtable null_vtable;
7447 uint32_t f_width;
7448 uint32_t f_height;
7449 uint8_t f_call_sequence;
7450 bool f_top_down;
7451 uint32_t f_pad_per_row;
7452 uint32_t f_src_pixfmt;
7453 uint32_t f_io_redirect_fourcc;
7454 uint64_t f_io_redirect_pos;
7455 uint64_t f_frame_config_io_position;
7456 uint32_t f_bitmap_info_len;
7457 uint32_t f_padding;
7458 uint32_t f_bits_per_pixel;
7459 uint32_t f_compression;
7460 uint32_t f_channel_masks[4];
7461 uint8_t f_channel_shifts[4];
7462 uint8_t f_channel_num_bits[4];
7463 uint32_t f_dst_x;
7464 uint32_t f_dst_y;
7465 uint32_t f_dst_y_inc;
7466 uint32_t f_pending_pad;
7467 uint32_t f_rle_state;
7468 uint32_t f_rle_length;
7469 uint8_t f_rle_delta_x;
7470 bool f_rle_padded;
7471 wuffs_base__pixel_swizzler f_swizzler;
7473 uint32_t p_decode_image_config;
7474 uint32_t p_do_decode_image_config;
7475 uint32_t p_decode_frame_config;
7476 uint32_t p_do_decode_frame_config;
7477 uint32_t p_decode_frame;
7478 uint32_t p_do_decode_frame;
7479 uint32_t p_tell_me_more;
7480 uint32_t p_read_palette;
7481 } private_impl;
7483 struct {
7484 uint8_t f_scratch[2048];
7485 uint8_t f_src_palette[1024];
7487 struct {
7488 uint64_t scratch;
7489 } s_do_decode_image_config;
7490 struct {
7491 uint64_t scratch;
7492 } s_do_decode_frame;
7493 struct {
7494 uint32_t v_i;
7495 uint64_t scratch;
7496 } s_read_palette;
7497 } private_data;
7499 #ifdef __cplusplus
7500 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
7501 using unique_ptr = std::unique_ptr<wuffs_bmp__decoder, wuffs_unique_ptr_deleter>;
7503 // On failure, the alloc_etc functions return nullptr. They don't throw.
7505 static inline unique_ptr
7506 alloc() {
7507 return unique_ptr(wuffs_bmp__decoder__alloc());
7510 static inline wuffs_base__image_decoder::unique_ptr
7511 alloc_as__wuffs_base__image_decoder() {
7512 return wuffs_base__image_decoder::unique_ptr(
7513 wuffs_bmp__decoder__alloc_as__wuffs_base__image_decoder());
7515 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
7517 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
7518 // Disallow constructing or copying an object via standard C++ mechanisms,
7519 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
7520 // size and field layout is not part of the public, stable, memory-safe API.
7521 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
7522 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
7523 // their first argument) rather than tweaking bar.private_impl.qux fields.
7525 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
7526 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
7527 // order to provide convenience methods. These forward on "this", so that you
7528 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
7529 wuffs_bmp__decoder__struct() = delete;
7530 wuffs_bmp__decoder__struct(const wuffs_bmp__decoder__struct&) = delete;
7531 wuffs_bmp__decoder__struct& operator=(
7532 const wuffs_bmp__decoder__struct&) = delete;
7533 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
7535 #if !defined(WUFFS_IMPLEMENTATION)
7536 // As above, the size of the struct is not part of the public API, and unless
7537 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
7538 // allocated, not stack allocated. Its size is not intended to be known at
7539 // compile time, but it is unfortunately divulged as a side effect of
7540 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
7541 // instead of "sizeof T", invoking the operator. To make the two values
7542 // different, so that passing the latter will be rejected by the initialize
7543 // function, we add an arbitrary amount of dead weight.
7544 uint8_t dead_weight[123000000]; // 123 MB.
7545 #endif // !defined(WUFFS_IMPLEMENTATION)
7547 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
7548 initialize(
7549 size_t sizeof_star_self,
7550 uint64_t wuffs_version,
7551 uint32_t options) {
7552 return wuffs_bmp__decoder__initialize(
7553 this, sizeof_star_self, wuffs_version, options);
7556 inline wuffs_base__image_decoder*
7557 upcast_as__wuffs_base__image_decoder() {
7558 return (wuffs_base__image_decoder*)this;
7561 inline uint64_t
7562 get_quirk(
7563 uint32_t a_key) const {
7564 return wuffs_bmp__decoder__get_quirk(this, a_key);
7567 inline wuffs_base__status
7568 set_quirk(
7569 uint32_t a_key,
7570 uint64_t a_value) {
7571 return wuffs_bmp__decoder__set_quirk(this, a_key, a_value);
7574 inline wuffs_base__status
7575 decode_image_config(
7576 wuffs_base__image_config* a_dst,
7577 wuffs_base__io_buffer* a_src) {
7578 return wuffs_bmp__decoder__decode_image_config(this, a_dst, a_src);
7581 inline wuffs_base__status
7582 decode_frame_config(
7583 wuffs_base__frame_config* a_dst,
7584 wuffs_base__io_buffer* a_src) {
7585 return wuffs_bmp__decoder__decode_frame_config(this, a_dst, a_src);
7588 inline wuffs_base__status
7589 decode_frame(
7590 wuffs_base__pixel_buffer* a_dst,
7591 wuffs_base__io_buffer* a_src,
7592 wuffs_base__pixel_blend a_blend,
7593 wuffs_base__slice_u8 a_workbuf,
7594 wuffs_base__decode_frame_options* a_opts) {
7595 return wuffs_bmp__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
7598 inline wuffs_base__rect_ie_u32
7599 frame_dirty_rect() const {
7600 return wuffs_bmp__decoder__frame_dirty_rect(this);
7603 inline uint32_t
7604 num_animation_loops() const {
7605 return wuffs_bmp__decoder__num_animation_loops(this);
7608 inline uint64_t
7609 num_decoded_frame_configs() const {
7610 return wuffs_bmp__decoder__num_decoded_frame_configs(this);
7613 inline uint64_t
7614 num_decoded_frames() const {
7615 return wuffs_bmp__decoder__num_decoded_frames(this);
7618 inline wuffs_base__status
7619 restart_frame(
7620 uint64_t a_index,
7621 uint64_t a_io_position) {
7622 return wuffs_bmp__decoder__restart_frame(this, a_index, a_io_position);
7625 inline wuffs_base__empty_struct
7626 set_report_metadata(
7627 uint32_t a_fourcc,
7628 bool a_report) {
7629 return wuffs_bmp__decoder__set_report_metadata(this, a_fourcc, a_report);
7632 inline wuffs_base__status
7633 tell_me_more(
7634 wuffs_base__io_buffer* a_dst,
7635 wuffs_base__more_information* a_minfo,
7636 wuffs_base__io_buffer* a_src) {
7637 return wuffs_bmp__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
7640 inline wuffs_base__range_ii_u64
7641 workbuf_len() const {
7642 return wuffs_bmp__decoder__workbuf_len(this);
7645 #endif // __cplusplus
7646 }; // struct wuffs_bmp__decoder__struct
7648 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7650 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BMP) || defined(WUFFS_NONMONOLITHIC)
7652 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BZIP2) || defined(WUFFS_NONMONOLITHIC)
7654 // ---------------- Status Codes
7656 extern const char wuffs_bzip2__error__bad_huffman_code_over_subscribed[];
7657 extern const char wuffs_bzip2__error__bad_huffman_code_under_subscribed[];
7658 extern const char wuffs_bzip2__error__bad_block_header[];
7659 extern const char wuffs_bzip2__error__bad_block_length[];
7660 extern const char wuffs_bzip2__error__bad_checksum[];
7661 extern const char wuffs_bzip2__error__bad_header[];
7662 extern const char wuffs_bzip2__error__bad_number_of_sections[];
7663 extern const char wuffs_bzip2__error__truncated_input[];
7664 extern const char wuffs_bzip2__error__unsupported_block_randomization[];
7666 // ---------------- Public Consts
7668 #define WUFFS_BZIP2__DECODER_DST_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0u
7670 #define WUFFS_BZIP2__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0u
7672 // ---------------- Struct Declarations
7674 typedef struct wuffs_bzip2__decoder__struct wuffs_bzip2__decoder;
7676 #ifdef __cplusplus
7677 extern "C" {
7678 #endif
7680 // ---------------- Public Initializer Prototypes
7682 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
7683 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
7685 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
7686 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
7688 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
7689 wuffs_bzip2__decoder__initialize(
7690 wuffs_bzip2__decoder* self,
7691 size_t sizeof_star_self,
7692 uint64_t wuffs_version,
7693 uint32_t options);
7695 size_t
7696 sizeof__wuffs_bzip2__decoder(void);
7698 // ---------------- Allocs
7700 // These functions allocate and initialize Wuffs structs. They return NULL if
7701 // memory allocation fails. If they return non-NULL, there is no need to call
7702 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
7703 // calling free on the returned pointer. That pointer is effectively a C++
7704 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
7706 wuffs_bzip2__decoder*
7707 wuffs_bzip2__decoder__alloc(void);
7709 static inline wuffs_base__io_transformer*
7710 wuffs_bzip2__decoder__alloc_as__wuffs_base__io_transformer(void) {
7711 return (wuffs_base__io_transformer*)(wuffs_bzip2__decoder__alloc());
7714 // ---------------- Upcasts
7716 static inline wuffs_base__io_transformer*
7717 wuffs_bzip2__decoder__upcast_as__wuffs_base__io_transformer(
7718 wuffs_bzip2__decoder* p) {
7719 return (wuffs_base__io_transformer*)p;
7722 // ---------------- Public Function Prototypes
7724 WUFFS_BASE__GENERATED_C_CODE
7725 WUFFS_BASE__MAYBE_STATIC uint64_t
7726 wuffs_bzip2__decoder__get_quirk(
7727 const wuffs_bzip2__decoder* self,
7728 uint32_t a_key);
7730 WUFFS_BASE__GENERATED_C_CODE
7731 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7732 wuffs_bzip2__decoder__set_quirk(
7733 wuffs_bzip2__decoder* self,
7734 uint32_t a_key,
7735 uint64_t a_value);
7737 WUFFS_BASE__GENERATED_C_CODE
7738 WUFFS_BASE__MAYBE_STATIC wuffs_base__optional_u63
7739 wuffs_bzip2__decoder__dst_history_retain_length(
7740 const wuffs_bzip2__decoder* self);
7742 WUFFS_BASE__GENERATED_C_CODE
7743 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
7744 wuffs_bzip2__decoder__workbuf_len(
7745 const wuffs_bzip2__decoder* self);
7747 WUFFS_BASE__GENERATED_C_CODE
7748 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7749 wuffs_bzip2__decoder__transform_io(
7750 wuffs_bzip2__decoder* self,
7751 wuffs_base__io_buffer* a_dst,
7752 wuffs_base__io_buffer* a_src,
7753 wuffs_base__slice_u8 a_workbuf);
7755 #ifdef __cplusplus
7756 } // extern "C"
7757 #endif
7759 // ---------------- Struct Definitions
7761 // These structs' fields, and the sizeof them, are private implementation
7762 // details that aren't guaranteed to be stable across Wuffs versions.
7764 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
7766 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7768 struct wuffs_bzip2__decoder__struct {
7769 // Do not access the private_impl's or private_data's fields directly. There
7770 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
7771 // the wuffs_foo__bar__baz functions.
7773 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
7774 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
7776 struct {
7777 uint32_t magic;
7778 uint32_t active_coroutine;
7779 wuffs_base__vtable vtable_for__wuffs_base__io_transformer;
7780 wuffs_base__vtable null_vtable;
7782 uint32_t f_bits;
7783 uint32_t f_n_bits;
7784 uint32_t f_max_incl_block_size;
7785 uint32_t f_block_size;
7786 bool f_decode_huffman_finished;
7787 uint8_t f_decode_huffman_which;
7788 uint32_t f_decode_huffman_ticks;
7789 uint32_t f_decode_huffman_section;
7790 uint32_t f_decode_huffman_run_shift;
7791 uint32_t f_flush_pointer;
7792 uint32_t f_flush_repeat_count;
7793 uint8_t f_flush_prev;
7794 bool f_ignore_checksum;
7795 uint32_t f_final_checksum_have;
7796 uint32_t f_block_checksum_have;
7797 uint32_t f_block_checksum_want;
7798 uint32_t f_original_pointer;
7799 uint32_t f_num_symbols;
7800 uint32_t f_num_huffman_codes;
7801 uint32_t f_num_sections;
7802 uint32_t f_code_lengths_bitmask;
7804 uint32_t p_transform_io;
7805 uint32_t p_do_transform_io;
7806 uint32_t p_prepare_block;
7807 uint32_t p_read_code_lengths;
7808 uint32_t p_flush_slow;
7809 uint32_t p_decode_huffman_slow;
7810 } private_impl;
7812 struct {
7813 uint32_t f_scratch;
7814 uint32_t f_letter_counts[256];
7815 uint8_t f_presence[256];
7816 uint8_t f_mtft[256];
7817 uint8_t f_huffman_selectors[32768];
7818 uint16_t f_huffman_trees[6][257][2];
7819 uint16_t f_huffman_tables[6][256];
7820 uint32_t f_bwt[1048576];
7822 struct {
7823 uint32_t v_i;
7824 uint64_t v_tag;
7825 uint32_t v_final_checksum_want;
7826 } s_do_transform_io;
7827 struct {
7828 uint32_t v_i;
7829 uint32_t v_selector;
7830 } s_prepare_block;
7831 struct {
7832 uint32_t v_i;
7833 uint32_t v_code_length;
7834 } s_read_code_lengths;
7835 struct {
7836 uint32_t v_flush_pointer;
7837 uint32_t v_flush_repeat_count;
7838 uint8_t v_flush_prev;
7839 uint32_t v_block_checksum_have;
7840 uint32_t v_block_size;
7841 uint8_t v_curr;
7842 uint64_t scratch;
7843 } s_flush_slow;
7844 struct {
7845 uint32_t v_node_index;
7846 } s_decode_huffman_slow;
7847 } private_data;
7849 #ifdef __cplusplus
7850 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
7851 using unique_ptr = std::unique_ptr<wuffs_bzip2__decoder, wuffs_unique_ptr_deleter>;
7853 // On failure, the alloc_etc functions return nullptr. They don't throw.
7855 static inline unique_ptr
7856 alloc() {
7857 return unique_ptr(wuffs_bzip2__decoder__alloc());
7860 static inline wuffs_base__io_transformer::unique_ptr
7861 alloc_as__wuffs_base__io_transformer() {
7862 return wuffs_base__io_transformer::unique_ptr(
7863 wuffs_bzip2__decoder__alloc_as__wuffs_base__io_transformer());
7865 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
7867 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
7868 // Disallow constructing or copying an object via standard C++ mechanisms,
7869 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
7870 // size and field layout is not part of the public, stable, memory-safe API.
7871 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
7872 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
7873 // their first argument) rather than tweaking bar.private_impl.qux fields.
7875 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
7876 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
7877 // order to provide convenience methods. These forward on "this", so that you
7878 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
7879 wuffs_bzip2__decoder__struct() = delete;
7880 wuffs_bzip2__decoder__struct(const wuffs_bzip2__decoder__struct&) = delete;
7881 wuffs_bzip2__decoder__struct& operator=(
7882 const wuffs_bzip2__decoder__struct&) = delete;
7883 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
7885 #if !defined(WUFFS_IMPLEMENTATION)
7886 // As above, the size of the struct is not part of the public API, and unless
7887 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
7888 // allocated, not stack allocated. Its size is not intended to be known at
7889 // compile time, but it is unfortunately divulged as a side effect of
7890 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
7891 // instead of "sizeof T", invoking the operator. To make the two values
7892 // different, so that passing the latter will be rejected by the initialize
7893 // function, we add an arbitrary amount of dead weight.
7894 uint8_t dead_weight[123000000]; // 123 MB.
7895 #endif // !defined(WUFFS_IMPLEMENTATION)
7897 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
7898 initialize(
7899 size_t sizeof_star_self,
7900 uint64_t wuffs_version,
7901 uint32_t options) {
7902 return wuffs_bzip2__decoder__initialize(
7903 this, sizeof_star_self, wuffs_version, options);
7906 inline wuffs_base__io_transformer*
7907 upcast_as__wuffs_base__io_transformer() {
7908 return (wuffs_base__io_transformer*)this;
7911 inline uint64_t
7912 get_quirk(
7913 uint32_t a_key) const {
7914 return wuffs_bzip2__decoder__get_quirk(this, a_key);
7917 inline wuffs_base__status
7918 set_quirk(
7919 uint32_t a_key,
7920 uint64_t a_value) {
7921 return wuffs_bzip2__decoder__set_quirk(this, a_key, a_value);
7924 inline wuffs_base__optional_u63
7925 dst_history_retain_length() const {
7926 return wuffs_bzip2__decoder__dst_history_retain_length(this);
7929 inline wuffs_base__range_ii_u64
7930 workbuf_len() const {
7931 return wuffs_bzip2__decoder__workbuf_len(this);
7934 inline wuffs_base__status
7935 transform_io(
7936 wuffs_base__io_buffer* a_dst,
7937 wuffs_base__io_buffer* a_src,
7938 wuffs_base__slice_u8 a_workbuf) {
7939 return wuffs_bzip2__decoder__transform_io(this, a_dst, a_src, a_workbuf);
7942 #endif // __cplusplus
7943 }; // struct wuffs_bzip2__decoder__struct
7945 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7947 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BZIP2) || defined(WUFFS_NONMONOLITHIC)
7949 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CBOR) || defined(WUFFS_NONMONOLITHIC)
7951 // ---------------- Status Codes
7953 extern const char wuffs_cbor__error__bad_input[];
7954 extern const char wuffs_cbor__error__unsupported_recursion_depth[];
7956 // ---------------- Public Consts
7958 #define WUFFS_CBOR__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0u
7960 #define WUFFS_CBOR__DECODER_DEPTH_MAX_INCL 1024u
7962 #define WUFFS_CBOR__DECODER_DST_TOKEN_BUFFER_LENGTH_MIN_INCL 2u
7964 #define WUFFS_CBOR__DECODER_SRC_IO_BUFFER_LENGTH_MIN_INCL 9u
7966 #define WUFFS_CBOR__TOKEN_VALUE_MAJOR 787997u
7968 #define WUFFS_CBOR__TOKEN_VALUE_MINOR__DETAIL_MASK 262143u
7970 #define WUFFS_CBOR__TOKEN_VALUE_MINOR__MINUS_1_MINUS_X 16777216u
7972 #define WUFFS_CBOR__TOKEN_VALUE_MINOR__SIMPLE_VALUE 8388608u
7974 #define WUFFS_CBOR__TOKEN_VALUE_MINOR__TAG 4194304u
7976 // ---------------- Struct Declarations
7978 typedef struct wuffs_cbor__decoder__struct wuffs_cbor__decoder;
7980 #ifdef __cplusplus
7981 extern "C" {
7982 #endif
7984 // ---------------- Public Initializer Prototypes
7986 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
7987 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
7989 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
7990 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
7992 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
7993 wuffs_cbor__decoder__initialize(
7994 wuffs_cbor__decoder* self,
7995 size_t sizeof_star_self,
7996 uint64_t wuffs_version,
7997 uint32_t options);
7999 size_t
8000 sizeof__wuffs_cbor__decoder(void);
8002 // ---------------- Allocs
8004 // These functions allocate and initialize Wuffs structs. They return NULL if
8005 // memory allocation fails. If they return non-NULL, there is no need to call
8006 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
8007 // calling free on the returned pointer. That pointer is effectively a C++
8008 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
8010 wuffs_cbor__decoder*
8011 wuffs_cbor__decoder__alloc(void);
8013 static inline wuffs_base__token_decoder*
8014 wuffs_cbor__decoder__alloc_as__wuffs_base__token_decoder(void) {
8015 return (wuffs_base__token_decoder*)(wuffs_cbor__decoder__alloc());
8018 // ---------------- Upcasts
8020 static inline wuffs_base__token_decoder*
8021 wuffs_cbor__decoder__upcast_as__wuffs_base__token_decoder(
8022 wuffs_cbor__decoder* p) {
8023 return (wuffs_base__token_decoder*)p;
8026 // ---------------- Public Function Prototypes
8028 WUFFS_BASE__GENERATED_C_CODE
8029 WUFFS_BASE__MAYBE_STATIC uint64_t
8030 wuffs_cbor__decoder__get_quirk(
8031 const wuffs_cbor__decoder* self,
8032 uint32_t a_key);
8034 WUFFS_BASE__GENERATED_C_CODE
8035 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8036 wuffs_cbor__decoder__set_quirk(
8037 wuffs_cbor__decoder* self,
8038 uint32_t a_key,
8039 uint64_t a_value);
8041 WUFFS_BASE__GENERATED_C_CODE
8042 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
8043 wuffs_cbor__decoder__workbuf_len(
8044 const wuffs_cbor__decoder* self);
8046 WUFFS_BASE__GENERATED_C_CODE
8047 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8048 wuffs_cbor__decoder__decode_tokens(
8049 wuffs_cbor__decoder* self,
8050 wuffs_base__token_buffer* a_dst,
8051 wuffs_base__io_buffer* a_src,
8052 wuffs_base__slice_u8 a_workbuf);
8054 #ifdef __cplusplus
8055 } // extern "C"
8056 #endif
8058 // ---------------- Struct Definitions
8060 // These structs' fields, and the sizeof them, are private implementation
8061 // details that aren't guaranteed to be stable across Wuffs versions.
8063 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
8065 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
8067 struct wuffs_cbor__decoder__struct {
8068 // Do not access the private_impl's or private_data's fields directly. There
8069 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
8070 // the wuffs_foo__bar__baz functions.
8072 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
8073 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
8075 struct {
8076 uint32_t magic;
8077 uint32_t active_coroutine;
8078 wuffs_base__vtable vtable_for__wuffs_base__token_decoder;
8079 wuffs_base__vtable null_vtable;
8081 bool f_end_of_data;
8083 uint32_t p_decode_tokens;
8084 } private_impl;
8086 struct {
8087 uint32_t f_stack[64];
8088 uint64_t f_container_num_remaining[1024];
8090 struct {
8091 uint64_t v_string_length;
8092 uint32_t v_depth;
8093 bool v_tagged;
8094 uint8_t v_indefinite_string_major_type;
8095 } s_decode_tokens;
8096 } private_data;
8098 #ifdef __cplusplus
8099 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
8100 using unique_ptr = std::unique_ptr<wuffs_cbor__decoder, wuffs_unique_ptr_deleter>;
8102 // On failure, the alloc_etc functions return nullptr. They don't throw.
8104 static inline unique_ptr
8105 alloc() {
8106 return unique_ptr(wuffs_cbor__decoder__alloc());
8109 static inline wuffs_base__token_decoder::unique_ptr
8110 alloc_as__wuffs_base__token_decoder() {
8111 return wuffs_base__token_decoder::unique_ptr(
8112 wuffs_cbor__decoder__alloc_as__wuffs_base__token_decoder());
8114 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
8116 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
8117 // Disallow constructing or copying an object via standard C++ mechanisms,
8118 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
8119 // size and field layout is not part of the public, stable, memory-safe API.
8120 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
8121 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
8122 // their first argument) rather than tweaking bar.private_impl.qux fields.
8124 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
8125 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
8126 // order to provide convenience methods. These forward on "this", so that you
8127 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
8128 wuffs_cbor__decoder__struct() = delete;
8129 wuffs_cbor__decoder__struct(const wuffs_cbor__decoder__struct&) = delete;
8130 wuffs_cbor__decoder__struct& operator=(
8131 const wuffs_cbor__decoder__struct&) = delete;
8132 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
8134 #if !defined(WUFFS_IMPLEMENTATION)
8135 // As above, the size of the struct is not part of the public API, and unless
8136 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
8137 // allocated, not stack allocated. Its size is not intended to be known at
8138 // compile time, but it is unfortunately divulged as a side effect of
8139 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
8140 // instead of "sizeof T", invoking the operator. To make the two values
8141 // different, so that passing the latter will be rejected by the initialize
8142 // function, we add an arbitrary amount of dead weight.
8143 uint8_t dead_weight[123000000]; // 123 MB.
8144 #endif // !defined(WUFFS_IMPLEMENTATION)
8146 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
8147 initialize(
8148 size_t sizeof_star_self,
8149 uint64_t wuffs_version,
8150 uint32_t options) {
8151 return wuffs_cbor__decoder__initialize(
8152 this, sizeof_star_self, wuffs_version, options);
8155 inline wuffs_base__token_decoder*
8156 upcast_as__wuffs_base__token_decoder() {
8157 return (wuffs_base__token_decoder*)this;
8160 inline uint64_t
8161 get_quirk(
8162 uint32_t a_key) const {
8163 return wuffs_cbor__decoder__get_quirk(this, a_key);
8166 inline wuffs_base__status
8167 set_quirk(
8168 uint32_t a_key,
8169 uint64_t a_value) {
8170 return wuffs_cbor__decoder__set_quirk(this, a_key, a_value);
8173 inline wuffs_base__range_ii_u64
8174 workbuf_len() const {
8175 return wuffs_cbor__decoder__workbuf_len(this);
8178 inline wuffs_base__status
8179 decode_tokens(
8180 wuffs_base__token_buffer* a_dst,
8181 wuffs_base__io_buffer* a_src,
8182 wuffs_base__slice_u8 a_workbuf) {
8183 return wuffs_cbor__decoder__decode_tokens(this, a_dst, a_src, a_workbuf);
8186 #endif // __cplusplus
8187 }; // struct wuffs_cbor__decoder__struct
8189 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
8191 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CBOR) || defined(WUFFS_NONMONOLITHIC)
8193 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CRC32) || defined(WUFFS_NONMONOLITHIC)
8195 // ---------------- Status Codes
8197 // ---------------- Public Consts
8199 // ---------------- Struct Declarations
8201 typedef struct wuffs_crc32__ieee_hasher__struct wuffs_crc32__ieee_hasher;
8203 #ifdef __cplusplus
8204 extern "C" {
8205 #endif
8207 // ---------------- Public Initializer Prototypes
8209 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
8210 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
8212 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
8213 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
8215 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
8216 wuffs_crc32__ieee_hasher__initialize(
8217 wuffs_crc32__ieee_hasher* self,
8218 size_t sizeof_star_self,
8219 uint64_t wuffs_version,
8220 uint32_t options);
8222 size_t
8223 sizeof__wuffs_crc32__ieee_hasher(void);
8225 // ---------------- Allocs
8227 // These functions allocate and initialize Wuffs structs. They return NULL if
8228 // memory allocation fails. If they return non-NULL, there is no need to call
8229 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
8230 // calling free on the returned pointer. That pointer is effectively a C++
8231 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
8233 wuffs_crc32__ieee_hasher*
8234 wuffs_crc32__ieee_hasher__alloc(void);
8236 static inline wuffs_base__hasher_u32*
8237 wuffs_crc32__ieee_hasher__alloc_as__wuffs_base__hasher_u32(void) {
8238 return (wuffs_base__hasher_u32*)(wuffs_crc32__ieee_hasher__alloc());
8241 // ---------------- Upcasts
8243 static inline wuffs_base__hasher_u32*
8244 wuffs_crc32__ieee_hasher__upcast_as__wuffs_base__hasher_u32(
8245 wuffs_crc32__ieee_hasher* p) {
8246 return (wuffs_base__hasher_u32*)p;
8249 // ---------------- Public Function Prototypes
8251 WUFFS_BASE__GENERATED_C_CODE
8252 WUFFS_BASE__MAYBE_STATIC uint64_t
8253 wuffs_crc32__ieee_hasher__get_quirk(
8254 const wuffs_crc32__ieee_hasher* self,
8255 uint32_t a_key);
8257 WUFFS_BASE__GENERATED_C_CODE
8258 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8259 wuffs_crc32__ieee_hasher__set_quirk(
8260 wuffs_crc32__ieee_hasher* self,
8261 uint32_t a_key,
8262 uint64_t a_value);
8264 WUFFS_BASE__GENERATED_C_CODE
8265 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
8266 wuffs_crc32__ieee_hasher__update(
8267 wuffs_crc32__ieee_hasher* self,
8268 wuffs_base__slice_u8 a_x);
8270 WUFFS_BASE__GENERATED_C_CODE
8271 WUFFS_BASE__MAYBE_STATIC uint32_t
8272 wuffs_crc32__ieee_hasher__update_u32(
8273 wuffs_crc32__ieee_hasher* self,
8274 wuffs_base__slice_u8 a_x);
8276 WUFFS_BASE__GENERATED_C_CODE
8277 WUFFS_BASE__MAYBE_STATIC uint32_t
8278 wuffs_crc32__ieee_hasher__checksum_u32(
8279 const wuffs_crc32__ieee_hasher* self);
8281 #ifdef __cplusplus
8282 } // extern "C"
8283 #endif
8285 // ---------------- Struct Definitions
8287 // These structs' fields, and the sizeof them, are private implementation
8288 // details that aren't guaranteed to be stable across Wuffs versions.
8290 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
8292 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
8294 struct wuffs_crc32__ieee_hasher__struct {
8295 // Do not access the private_impl's or private_data's fields directly. There
8296 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
8297 // the wuffs_foo__bar__baz functions.
8299 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
8300 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
8302 struct {
8303 uint32_t magic;
8304 uint32_t active_coroutine;
8305 wuffs_base__vtable vtable_for__wuffs_base__hasher_u32;
8306 wuffs_base__vtable null_vtable;
8308 uint32_t f_state;
8310 wuffs_base__empty_struct (*choosy_up)(
8311 wuffs_crc32__ieee_hasher* self,
8312 wuffs_base__slice_u8 a_x);
8313 } private_impl;
8315 #ifdef __cplusplus
8316 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
8317 using unique_ptr = std::unique_ptr<wuffs_crc32__ieee_hasher, wuffs_unique_ptr_deleter>;
8319 // On failure, the alloc_etc functions return nullptr. They don't throw.
8321 static inline unique_ptr
8322 alloc() {
8323 return unique_ptr(wuffs_crc32__ieee_hasher__alloc());
8326 static inline wuffs_base__hasher_u32::unique_ptr
8327 alloc_as__wuffs_base__hasher_u32() {
8328 return wuffs_base__hasher_u32::unique_ptr(
8329 wuffs_crc32__ieee_hasher__alloc_as__wuffs_base__hasher_u32());
8331 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
8333 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
8334 // Disallow constructing or copying an object via standard C++ mechanisms,
8335 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
8336 // size and field layout is not part of the public, stable, memory-safe API.
8337 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
8338 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
8339 // their first argument) rather than tweaking bar.private_impl.qux fields.
8341 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
8342 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
8343 // order to provide convenience methods. These forward on "this", so that you
8344 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
8345 wuffs_crc32__ieee_hasher__struct() = delete;
8346 wuffs_crc32__ieee_hasher__struct(const wuffs_crc32__ieee_hasher__struct&) = delete;
8347 wuffs_crc32__ieee_hasher__struct& operator=(
8348 const wuffs_crc32__ieee_hasher__struct&) = delete;
8349 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
8351 #if !defined(WUFFS_IMPLEMENTATION)
8352 // As above, the size of the struct is not part of the public API, and unless
8353 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
8354 // allocated, not stack allocated. Its size is not intended to be known at
8355 // compile time, but it is unfortunately divulged as a side effect of
8356 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
8357 // instead of "sizeof T", invoking the operator. To make the two values
8358 // different, so that passing the latter will be rejected by the initialize
8359 // function, we add an arbitrary amount of dead weight.
8360 uint8_t dead_weight[123000000]; // 123 MB.
8361 #endif // !defined(WUFFS_IMPLEMENTATION)
8363 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
8364 initialize(
8365 size_t sizeof_star_self,
8366 uint64_t wuffs_version,
8367 uint32_t options) {
8368 return wuffs_crc32__ieee_hasher__initialize(
8369 this, sizeof_star_self, wuffs_version, options);
8372 inline wuffs_base__hasher_u32*
8373 upcast_as__wuffs_base__hasher_u32() {
8374 return (wuffs_base__hasher_u32*)this;
8377 inline uint64_t
8378 get_quirk(
8379 uint32_t a_key) const {
8380 return wuffs_crc32__ieee_hasher__get_quirk(this, a_key);
8383 inline wuffs_base__status
8384 set_quirk(
8385 uint32_t a_key,
8386 uint64_t a_value) {
8387 return wuffs_crc32__ieee_hasher__set_quirk(this, a_key, a_value);
8390 inline wuffs_base__empty_struct
8391 update(
8392 wuffs_base__slice_u8 a_x) {
8393 return wuffs_crc32__ieee_hasher__update(this, a_x);
8396 inline uint32_t
8397 update_u32(
8398 wuffs_base__slice_u8 a_x) {
8399 return wuffs_crc32__ieee_hasher__update_u32(this, a_x);
8402 inline uint32_t
8403 checksum_u32() const {
8404 return wuffs_crc32__ieee_hasher__checksum_u32(this);
8407 #endif // __cplusplus
8408 }; // struct wuffs_crc32__ieee_hasher__struct
8410 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
8412 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CRC32) || defined(WUFFS_NONMONOLITHIC)
8414 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CRC64) || defined(WUFFS_NONMONOLITHIC)
8416 // ---------------- Status Codes
8418 // ---------------- Public Consts
8420 // ---------------- Struct Declarations
8422 typedef struct wuffs_crc64__ecma_hasher__struct wuffs_crc64__ecma_hasher;
8424 #ifdef __cplusplus
8425 extern "C" {
8426 #endif
8428 // ---------------- Public Initializer Prototypes
8430 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
8431 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
8433 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
8434 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
8436 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
8437 wuffs_crc64__ecma_hasher__initialize(
8438 wuffs_crc64__ecma_hasher* self,
8439 size_t sizeof_star_self,
8440 uint64_t wuffs_version,
8441 uint32_t options);
8443 size_t
8444 sizeof__wuffs_crc64__ecma_hasher(void);
8446 // ---------------- Allocs
8448 // These functions allocate and initialize Wuffs structs. They return NULL if
8449 // memory allocation fails. If they return non-NULL, there is no need to call
8450 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
8451 // calling free on the returned pointer. That pointer is effectively a C++
8452 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
8454 wuffs_crc64__ecma_hasher*
8455 wuffs_crc64__ecma_hasher__alloc(void);
8457 static inline wuffs_base__hasher_u64*
8458 wuffs_crc64__ecma_hasher__alloc_as__wuffs_base__hasher_u64(void) {
8459 return (wuffs_base__hasher_u64*)(wuffs_crc64__ecma_hasher__alloc());
8462 // ---------------- Upcasts
8464 static inline wuffs_base__hasher_u64*
8465 wuffs_crc64__ecma_hasher__upcast_as__wuffs_base__hasher_u64(
8466 wuffs_crc64__ecma_hasher* p) {
8467 return (wuffs_base__hasher_u64*)p;
8470 // ---------------- Public Function Prototypes
8472 WUFFS_BASE__GENERATED_C_CODE
8473 WUFFS_BASE__MAYBE_STATIC uint64_t
8474 wuffs_crc64__ecma_hasher__get_quirk(
8475 const wuffs_crc64__ecma_hasher* self,
8476 uint32_t a_key);
8478 WUFFS_BASE__GENERATED_C_CODE
8479 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8480 wuffs_crc64__ecma_hasher__set_quirk(
8481 wuffs_crc64__ecma_hasher* self,
8482 uint32_t a_key,
8483 uint64_t a_value);
8485 WUFFS_BASE__GENERATED_C_CODE
8486 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
8487 wuffs_crc64__ecma_hasher__update(
8488 wuffs_crc64__ecma_hasher* self,
8489 wuffs_base__slice_u8 a_x);
8491 WUFFS_BASE__GENERATED_C_CODE
8492 WUFFS_BASE__MAYBE_STATIC uint64_t
8493 wuffs_crc64__ecma_hasher__update_u64(
8494 wuffs_crc64__ecma_hasher* self,
8495 wuffs_base__slice_u8 a_x);
8497 WUFFS_BASE__GENERATED_C_CODE
8498 WUFFS_BASE__MAYBE_STATIC uint64_t
8499 wuffs_crc64__ecma_hasher__checksum_u64(
8500 const wuffs_crc64__ecma_hasher* self);
8502 #ifdef __cplusplus
8503 } // extern "C"
8504 #endif
8506 // ---------------- Struct Definitions
8508 // These structs' fields, and the sizeof them, are private implementation
8509 // details that aren't guaranteed to be stable across Wuffs versions.
8511 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
8513 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
8515 struct wuffs_crc64__ecma_hasher__struct {
8516 // Do not access the private_impl's or private_data's fields directly. There
8517 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
8518 // the wuffs_foo__bar__baz functions.
8520 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
8521 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
8523 struct {
8524 uint32_t magic;
8525 uint32_t active_coroutine;
8526 wuffs_base__vtable vtable_for__wuffs_base__hasher_u64;
8527 wuffs_base__vtable null_vtable;
8529 uint64_t f_state;
8531 wuffs_base__empty_struct (*choosy_up)(
8532 wuffs_crc64__ecma_hasher* self,
8533 wuffs_base__slice_u8 a_x);
8534 } private_impl;
8536 #ifdef __cplusplus
8537 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
8538 using unique_ptr = std::unique_ptr<wuffs_crc64__ecma_hasher, wuffs_unique_ptr_deleter>;
8540 // On failure, the alloc_etc functions return nullptr. They don't throw.
8542 static inline unique_ptr
8543 alloc() {
8544 return unique_ptr(wuffs_crc64__ecma_hasher__alloc());
8547 static inline wuffs_base__hasher_u64::unique_ptr
8548 alloc_as__wuffs_base__hasher_u64() {
8549 return wuffs_base__hasher_u64::unique_ptr(
8550 wuffs_crc64__ecma_hasher__alloc_as__wuffs_base__hasher_u64());
8552 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
8554 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
8555 // Disallow constructing or copying an object via standard C++ mechanisms,
8556 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
8557 // size and field layout is not part of the public, stable, memory-safe API.
8558 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
8559 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
8560 // their first argument) rather than tweaking bar.private_impl.qux fields.
8562 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
8563 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
8564 // order to provide convenience methods. These forward on "this", so that you
8565 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
8566 wuffs_crc64__ecma_hasher__struct() = delete;
8567 wuffs_crc64__ecma_hasher__struct(const wuffs_crc64__ecma_hasher__struct&) = delete;
8568 wuffs_crc64__ecma_hasher__struct& operator=(
8569 const wuffs_crc64__ecma_hasher__struct&) = delete;
8570 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
8572 #if !defined(WUFFS_IMPLEMENTATION)
8573 // As above, the size of the struct is not part of the public API, and unless
8574 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
8575 // allocated, not stack allocated. Its size is not intended to be known at
8576 // compile time, but it is unfortunately divulged as a side effect of
8577 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
8578 // instead of "sizeof T", invoking the operator. To make the two values
8579 // different, so that passing the latter will be rejected by the initialize
8580 // function, we add an arbitrary amount of dead weight.
8581 uint8_t dead_weight[123000000]; // 123 MB.
8582 #endif // !defined(WUFFS_IMPLEMENTATION)
8584 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
8585 initialize(
8586 size_t sizeof_star_self,
8587 uint64_t wuffs_version,
8588 uint32_t options) {
8589 return wuffs_crc64__ecma_hasher__initialize(
8590 this, sizeof_star_self, wuffs_version, options);
8593 inline wuffs_base__hasher_u64*
8594 upcast_as__wuffs_base__hasher_u64() {
8595 return (wuffs_base__hasher_u64*)this;
8598 inline uint64_t
8599 get_quirk(
8600 uint32_t a_key) const {
8601 return wuffs_crc64__ecma_hasher__get_quirk(this, a_key);
8604 inline wuffs_base__status
8605 set_quirk(
8606 uint32_t a_key,
8607 uint64_t a_value) {
8608 return wuffs_crc64__ecma_hasher__set_quirk(this, a_key, a_value);
8611 inline wuffs_base__empty_struct
8612 update(
8613 wuffs_base__slice_u8 a_x) {
8614 return wuffs_crc64__ecma_hasher__update(this, a_x);
8617 inline uint64_t
8618 update_u64(
8619 wuffs_base__slice_u8 a_x) {
8620 return wuffs_crc64__ecma_hasher__update_u64(this, a_x);
8623 inline uint64_t
8624 checksum_u64() const {
8625 return wuffs_crc64__ecma_hasher__checksum_u64(this);
8628 #endif // __cplusplus
8629 }; // struct wuffs_crc64__ecma_hasher__struct
8631 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
8633 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CRC64) || defined(WUFFS_NONMONOLITHIC)
8635 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__DEFLATE) || defined(WUFFS_NONMONOLITHIC)
8637 // ---------------- Status Codes
8639 extern const char wuffs_deflate__error__bad_huffman_code_over_subscribed[];
8640 extern const char wuffs_deflate__error__bad_huffman_code_under_subscribed[];
8641 extern const char wuffs_deflate__error__bad_huffman_code_length_count[];
8642 extern const char wuffs_deflate__error__bad_huffman_code_length_repetition[];
8643 extern const char wuffs_deflate__error__bad_huffman_code[];
8644 extern const char wuffs_deflate__error__bad_huffman_minimum_code_length[];
8645 extern const char wuffs_deflate__error__bad_block[];
8646 extern const char wuffs_deflate__error__bad_distance[];
8647 extern const char wuffs_deflate__error__bad_distance_code_count[];
8648 extern const char wuffs_deflate__error__bad_literal_length_code_count[];
8649 extern const char wuffs_deflate__error__inconsistent_stored_block_length[];
8650 extern const char wuffs_deflate__error__missing_end_of_block_code[];
8651 extern const char wuffs_deflate__error__no_huffman_codes[];
8652 extern const char wuffs_deflate__error__truncated_input[];
8654 // ---------------- Public Consts
8656 #define WUFFS_DEFLATE__DECODER_DST_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0u
8658 #define WUFFS_DEFLATE__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 1u
8660 // ---------------- Struct Declarations
8662 typedef struct wuffs_deflate__decoder__struct wuffs_deflate__decoder;
8664 #ifdef __cplusplus
8665 extern "C" {
8666 #endif
8668 // ---------------- Public Initializer Prototypes
8670 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
8671 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
8673 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
8674 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
8676 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
8677 wuffs_deflate__decoder__initialize(
8678 wuffs_deflate__decoder* self,
8679 size_t sizeof_star_self,
8680 uint64_t wuffs_version,
8681 uint32_t options);
8683 size_t
8684 sizeof__wuffs_deflate__decoder(void);
8686 // ---------------- Allocs
8688 // These functions allocate and initialize Wuffs structs. They return NULL if
8689 // memory allocation fails. If they return non-NULL, there is no need to call
8690 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
8691 // calling free on the returned pointer. That pointer is effectively a C++
8692 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
8694 wuffs_deflate__decoder*
8695 wuffs_deflate__decoder__alloc(void);
8697 static inline wuffs_base__io_transformer*
8698 wuffs_deflate__decoder__alloc_as__wuffs_base__io_transformer(void) {
8699 return (wuffs_base__io_transformer*)(wuffs_deflate__decoder__alloc());
8702 // ---------------- Upcasts
8704 static inline wuffs_base__io_transformer*
8705 wuffs_deflate__decoder__upcast_as__wuffs_base__io_transformer(
8706 wuffs_deflate__decoder* p) {
8707 return (wuffs_base__io_transformer*)p;
8710 // ---------------- Public Function Prototypes
8712 WUFFS_BASE__GENERATED_C_CODE
8713 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
8714 wuffs_deflate__decoder__add_history(
8715 wuffs_deflate__decoder* self,
8716 wuffs_base__slice_u8 a_hist);
8718 WUFFS_BASE__GENERATED_C_CODE
8719 WUFFS_BASE__MAYBE_STATIC uint64_t
8720 wuffs_deflate__decoder__get_quirk(
8721 const wuffs_deflate__decoder* self,
8722 uint32_t a_key);
8724 WUFFS_BASE__GENERATED_C_CODE
8725 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8726 wuffs_deflate__decoder__set_quirk(
8727 wuffs_deflate__decoder* self,
8728 uint32_t a_key,
8729 uint64_t a_value);
8731 WUFFS_BASE__GENERATED_C_CODE
8732 WUFFS_BASE__MAYBE_STATIC wuffs_base__optional_u63
8733 wuffs_deflate__decoder__dst_history_retain_length(
8734 const wuffs_deflate__decoder* self);
8736 WUFFS_BASE__GENERATED_C_CODE
8737 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
8738 wuffs_deflate__decoder__workbuf_len(
8739 const wuffs_deflate__decoder* self);
8741 WUFFS_BASE__GENERATED_C_CODE
8742 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8743 wuffs_deflate__decoder__transform_io(
8744 wuffs_deflate__decoder* self,
8745 wuffs_base__io_buffer* a_dst,
8746 wuffs_base__io_buffer* a_src,
8747 wuffs_base__slice_u8 a_workbuf);
8749 #ifdef __cplusplus
8750 } // extern "C"
8751 #endif
8753 // ---------------- Struct Definitions
8755 // These structs' fields, and the sizeof them, are private implementation
8756 // details that aren't guaranteed to be stable across Wuffs versions.
8758 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
8760 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
8762 struct wuffs_deflate__decoder__struct {
8763 // Do not access the private_impl's or private_data's fields directly. There
8764 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
8765 // the wuffs_foo__bar__baz functions.
8767 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
8768 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
8770 struct {
8771 uint32_t magic;
8772 uint32_t active_coroutine;
8773 wuffs_base__vtable vtable_for__wuffs_base__io_transformer;
8774 wuffs_base__vtable null_vtable;
8776 uint32_t f_bits;
8777 uint32_t f_n_bits;
8778 uint64_t f_transformed_history_count;
8779 uint32_t f_history_index;
8780 uint32_t f_n_huffs_bits[2];
8781 bool f_end_of_block;
8783 uint32_t p_transform_io;
8784 uint32_t p_do_transform_io;
8785 uint32_t p_decode_blocks;
8786 uint32_t p_decode_uncompressed;
8787 uint32_t p_init_dynamic_huffman;
8788 wuffs_base__status (*choosy_decode_huffman_fast64)(
8789 wuffs_deflate__decoder* self,
8790 wuffs_base__io_buffer* a_dst,
8791 wuffs_base__io_buffer* a_src);
8792 uint32_t p_decode_huffman_slow;
8793 } private_impl;
8795 struct {
8796 uint32_t f_huffs[2][1024];
8797 uint8_t f_history[33025];
8798 uint8_t f_code_lengths[320];
8800 struct {
8801 uint32_t v_final;
8802 } s_decode_blocks;
8803 struct {
8804 uint32_t v_length;
8805 uint64_t scratch;
8806 } s_decode_uncompressed;
8807 struct {
8808 uint32_t v_bits;
8809 uint32_t v_n_bits;
8810 uint32_t v_n_lit;
8811 uint32_t v_n_dist;
8812 uint32_t v_n_clen;
8813 uint32_t v_i;
8814 uint32_t v_mask;
8815 uint32_t v_n_extra_bits;
8816 uint8_t v_rep_symbol;
8817 uint32_t v_rep_count;
8818 } s_init_dynamic_huffman;
8819 struct {
8820 uint32_t v_bits;
8821 uint32_t v_n_bits;
8822 uint32_t v_table_entry_n_bits;
8823 uint32_t v_lmask;
8824 uint32_t v_dmask;
8825 uint32_t v_redir_top;
8826 uint32_t v_redir_mask;
8827 uint32_t v_length;
8828 uint32_t v_dist_minus_1;
8829 uint64_t scratch;
8830 } s_decode_huffman_slow;
8831 } private_data;
8833 #ifdef __cplusplus
8834 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
8835 using unique_ptr = std::unique_ptr<wuffs_deflate__decoder, wuffs_unique_ptr_deleter>;
8837 // On failure, the alloc_etc functions return nullptr. They don't throw.
8839 static inline unique_ptr
8840 alloc() {
8841 return unique_ptr(wuffs_deflate__decoder__alloc());
8844 static inline wuffs_base__io_transformer::unique_ptr
8845 alloc_as__wuffs_base__io_transformer() {
8846 return wuffs_base__io_transformer::unique_ptr(
8847 wuffs_deflate__decoder__alloc_as__wuffs_base__io_transformer());
8849 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
8851 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
8852 // Disallow constructing or copying an object via standard C++ mechanisms,
8853 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
8854 // size and field layout is not part of the public, stable, memory-safe API.
8855 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
8856 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
8857 // their first argument) rather than tweaking bar.private_impl.qux fields.
8859 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
8860 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
8861 // order to provide convenience methods. These forward on "this", so that you
8862 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
8863 wuffs_deflate__decoder__struct() = delete;
8864 wuffs_deflate__decoder__struct(const wuffs_deflate__decoder__struct&) = delete;
8865 wuffs_deflate__decoder__struct& operator=(
8866 const wuffs_deflate__decoder__struct&) = delete;
8867 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
8869 #if !defined(WUFFS_IMPLEMENTATION)
8870 // As above, the size of the struct is not part of the public API, and unless
8871 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
8872 // allocated, not stack allocated. Its size is not intended to be known at
8873 // compile time, but it is unfortunately divulged as a side effect of
8874 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
8875 // instead of "sizeof T", invoking the operator. To make the two values
8876 // different, so that passing the latter will be rejected by the initialize
8877 // function, we add an arbitrary amount of dead weight.
8878 uint8_t dead_weight[123000000]; // 123 MB.
8879 #endif // !defined(WUFFS_IMPLEMENTATION)
8881 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
8882 initialize(
8883 size_t sizeof_star_self,
8884 uint64_t wuffs_version,
8885 uint32_t options) {
8886 return wuffs_deflate__decoder__initialize(
8887 this, sizeof_star_self, wuffs_version, options);
8890 inline wuffs_base__io_transformer*
8891 upcast_as__wuffs_base__io_transformer() {
8892 return (wuffs_base__io_transformer*)this;
8895 inline wuffs_base__empty_struct
8896 add_history(
8897 wuffs_base__slice_u8 a_hist) {
8898 return wuffs_deflate__decoder__add_history(this, a_hist);
8901 inline uint64_t
8902 get_quirk(
8903 uint32_t a_key) const {
8904 return wuffs_deflate__decoder__get_quirk(this, a_key);
8907 inline wuffs_base__status
8908 set_quirk(
8909 uint32_t a_key,
8910 uint64_t a_value) {
8911 return wuffs_deflate__decoder__set_quirk(this, a_key, a_value);
8914 inline wuffs_base__optional_u63
8915 dst_history_retain_length() const {
8916 return wuffs_deflate__decoder__dst_history_retain_length(this);
8919 inline wuffs_base__range_ii_u64
8920 workbuf_len() const {
8921 return wuffs_deflate__decoder__workbuf_len(this);
8924 inline wuffs_base__status
8925 transform_io(
8926 wuffs_base__io_buffer* a_dst,
8927 wuffs_base__io_buffer* a_src,
8928 wuffs_base__slice_u8 a_workbuf) {
8929 return wuffs_deflate__decoder__transform_io(this, a_dst, a_src, a_workbuf);
8932 #endif // __cplusplus
8933 }; // struct wuffs_deflate__decoder__struct
8935 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
8937 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__DEFLATE) || defined(WUFFS_NONMONOLITHIC)
8939 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GIF) || defined(WUFFS_NONMONOLITHIC)
8941 // ---------------- Status Codes
8943 extern const char wuffs_gif__error__bad_lzw_code[];
8944 extern const char wuffs_gif__error__bad_extension_label[];
8945 extern const char wuffs_gif__error__bad_frame_size[];
8946 extern const char wuffs_gif__error__bad_graphic_control[];
8947 extern const char wuffs_gif__error__bad_header[];
8948 extern const char wuffs_gif__error__bad_literal_width[];
8949 extern const char wuffs_gif__error__bad_palette[];
8950 extern const char wuffs_gif__error__truncated_input[];
8952 // ---------------- Public Consts
8954 #define WUFFS_GIF__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0u
8956 #define WUFFS_GIF__QUIRK_DELAY_NUM_DECODED_FRAMES 1041635328u
8958 #define WUFFS_GIF__QUIRK_FIRST_FRAME_LOCAL_PALETTE_MEANS_BLACK_BACKGROUND 1041635329u
8960 #define WUFFS_GIF__QUIRK_HONOR_BACKGROUND_COLOR 1041635330u
8962 #define WUFFS_GIF__QUIRK_IGNORE_TOO_MUCH_PIXEL_DATA 1041635331u
8964 #define WUFFS_GIF__QUIRK_IMAGE_BOUNDS_ARE_STRICT 1041635332u
8966 #define WUFFS_GIF__QUIRK_REJECT_EMPTY_FRAME 1041635333u
8968 #define WUFFS_GIF__QUIRK_REJECT_EMPTY_PALETTE 1041635334u
8970 // ---------------- Struct Declarations
8972 typedef struct wuffs_gif__decoder__struct wuffs_gif__decoder;
8974 #ifdef __cplusplus
8975 extern "C" {
8976 #endif
8978 // ---------------- Public Initializer Prototypes
8980 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
8981 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
8983 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
8984 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
8986 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
8987 wuffs_gif__decoder__initialize(
8988 wuffs_gif__decoder* self,
8989 size_t sizeof_star_self,
8990 uint64_t wuffs_version,
8991 uint32_t options);
8993 size_t
8994 sizeof__wuffs_gif__decoder(void);
8996 // ---------------- Allocs
8998 // These functions allocate and initialize Wuffs structs. They return NULL if
8999 // memory allocation fails. If they return non-NULL, there is no need to call
9000 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
9001 // calling free on the returned pointer. That pointer is effectively a C++
9002 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
9004 wuffs_gif__decoder*
9005 wuffs_gif__decoder__alloc(void);
9007 static inline wuffs_base__image_decoder*
9008 wuffs_gif__decoder__alloc_as__wuffs_base__image_decoder(void) {
9009 return (wuffs_base__image_decoder*)(wuffs_gif__decoder__alloc());
9012 // ---------------- Upcasts
9014 static inline wuffs_base__image_decoder*
9015 wuffs_gif__decoder__upcast_as__wuffs_base__image_decoder(
9016 wuffs_gif__decoder* p) {
9017 return (wuffs_base__image_decoder*)p;
9020 // ---------------- Public Function Prototypes
9022 WUFFS_BASE__GENERATED_C_CODE
9023 WUFFS_BASE__MAYBE_STATIC uint64_t
9024 wuffs_gif__decoder__get_quirk(
9025 const wuffs_gif__decoder* self,
9026 uint32_t a_key);
9028 WUFFS_BASE__GENERATED_C_CODE
9029 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9030 wuffs_gif__decoder__set_quirk(
9031 wuffs_gif__decoder* self,
9032 uint32_t a_key,
9033 uint64_t a_value);
9035 WUFFS_BASE__GENERATED_C_CODE
9036 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9037 wuffs_gif__decoder__decode_image_config(
9038 wuffs_gif__decoder* self,
9039 wuffs_base__image_config* a_dst,
9040 wuffs_base__io_buffer* a_src);
9042 WUFFS_BASE__GENERATED_C_CODE
9043 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
9044 wuffs_gif__decoder__set_report_metadata(
9045 wuffs_gif__decoder* self,
9046 uint32_t a_fourcc,
9047 bool a_report);
9049 WUFFS_BASE__GENERATED_C_CODE
9050 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9051 wuffs_gif__decoder__tell_me_more(
9052 wuffs_gif__decoder* self,
9053 wuffs_base__io_buffer* a_dst,
9054 wuffs_base__more_information* a_minfo,
9055 wuffs_base__io_buffer* a_src);
9057 WUFFS_BASE__GENERATED_C_CODE
9058 WUFFS_BASE__MAYBE_STATIC uint32_t
9059 wuffs_gif__decoder__num_animation_loops(
9060 const wuffs_gif__decoder* self);
9062 WUFFS_BASE__GENERATED_C_CODE
9063 WUFFS_BASE__MAYBE_STATIC uint64_t
9064 wuffs_gif__decoder__num_decoded_frame_configs(
9065 const wuffs_gif__decoder* self);
9067 WUFFS_BASE__GENERATED_C_CODE
9068 WUFFS_BASE__MAYBE_STATIC uint64_t
9069 wuffs_gif__decoder__num_decoded_frames(
9070 const wuffs_gif__decoder* self);
9072 WUFFS_BASE__GENERATED_C_CODE
9073 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
9074 wuffs_gif__decoder__frame_dirty_rect(
9075 const wuffs_gif__decoder* self);
9077 WUFFS_BASE__GENERATED_C_CODE
9078 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
9079 wuffs_gif__decoder__workbuf_len(
9080 const wuffs_gif__decoder* self);
9082 WUFFS_BASE__GENERATED_C_CODE
9083 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9084 wuffs_gif__decoder__restart_frame(
9085 wuffs_gif__decoder* self,
9086 uint64_t a_index,
9087 uint64_t a_io_position);
9089 WUFFS_BASE__GENERATED_C_CODE
9090 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9091 wuffs_gif__decoder__decode_frame_config(
9092 wuffs_gif__decoder* self,
9093 wuffs_base__frame_config* a_dst,
9094 wuffs_base__io_buffer* a_src);
9096 WUFFS_BASE__GENERATED_C_CODE
9097 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9098 wuffs_gif__decoder__decode_frame(
9099 wuffs_gif__decoder* self,
9100 wuffs_base__pixel_buffer* a_dst,
9101 wuffs_base__io_buffer* a_src,
9102 wuffs_base__pixel_blend a_blend,
9103 wuffs_base__slice_u8 a_workbuf,
9104 wuffs_base__decode_frame_options* a_opts);
9106 #ifdef __cplusplus
9107 } // extern "C"
9108 #endif
9110 // ---------------- Struct Definitions
9112 // These structs' fields, and the sizeof them, are private implementation
9113 // details that aren't guaranteed to be stable across Wuffs versions.
9115 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
9117 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
9119 struct wuffs_gif__decoder__struct {
9120 // Do not access the private_impl's or private_data's fields directly. There
9121 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
9122 // the wuffs_foo__bar__baz functions.
9124 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
9125 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
9127 struct {
9128 uint32_t magic;
9129 uint32_t active_coroutine;
9130 wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
9131 wuffs_base__vtable null_vtable;
9133 uint32_t f_width;
9134 uint32_t f_height;
9135 uint8_t f_call_sequence;
9136 bool f_report_metadata_iccp;
9137 bool f_report_metadata_xmp;
9138 uint32_t f_metadata_fourcc;
9139 uint64_t f_metadata_io_position;
9140 bool f_quirks[7];
9141 bool f_delayed_num_decoded_frames;
9142 bool f_seen_header;
9143 bool f_ignored_but_affects_benchmarks;
9144 bool f_has_global_palette;
9145 uint8_t f_interlace;
9146 bool f_seen_num_animation_loops_value;
9147 uint32_t f_num_animation_loops_value;
9148 uint32_t f_background_color_u32_argb_premul;
9149 uint32_t f_black_color_u32_argb_premul;
9150 bool f_gc_has_transparent_index;
9151 uint8_t f_gc_transparent_index;
9152 uint8_t f_gc_disposal;
9153 uint64_t f_gc_duration;
9154 uint64_t f_frame_config_io_position;
9155 uint64_t f_num_decoded_frame_configs_value;
9156 uint64_t f_num_decoded_frames_value;
9157 uint32_t f_frame_rect_x0;
9158 uint32_t f_frame_rect_y0;
9159 uint32_t f_frame_rect_x1;
9160 uint32_t f_frame_rect_y1;
9161 uint32_t f_dst_x;
9162 uint32_t f_dst_y;
9163 uint32_t f_dirty_max_excl_y;
9164 uint64_t f_compressed_ri;
9165 uint64_t f_compressed_wi;
9166 wuffs_base__pixel_swizzler f_swizzler;
9167 uint32_t f_lzw_pending_literal_width_plus_one;
9168 uint32_t f_lzw_literal_width;
9169 uint32_t f_lzw_clear_code;
9170 uint32_t f_lzw_end_code;
9171 uint32_t f_lzw_save_code;
9172 uint32_t f_lzw_prev_code;
9173 uint32_t f_lzw_width;
9174 uint32_t f_lzw_bits;
9175 uint32_t f_lzw_n_bits;
9176 uint32_t f_lzw_output_ri;
9177 uint32_t f_lzw_output_wi;
9178 uint32_t f_lzw_read_from_return_value;
9179 uint16_t f_lzw_prefixes[4096];
9181 uint32_t p_decode_image_config;
9182 uint32_t p_do_decode_image_config;
9183 uint32_t p_tell_me_more;
9184 uint32_t p_do_tell_me_more;
9185 uint32_t p_decode_frame_config;
9186 uint32_t p_do_decode_frame_config;
9187 uint32_t p_skip_frame;
9188 uint32_t p_decode_frame;
9189 uint32_t p_do_decode_frame;
9190 uint32_t p_decode_up_to_id_part1;
9191 uint32_t p_decode_header;
9192 uint32_t p_decode_lsd;
9193 uint32_t p_decode_extension;
9194 uint32_t p_skip_blocks;
9195 uint32_t p_decode_ae;
9196 uint32_t p_decode_gc;
9197 uint32_t p_decode_id_part0;
9198 uint32_t p_decode_id_part1;
9199 uint32_t p_decode_id_part2;
9200 } private_impl;
9202 struct {
9203 uint8_t f_compressed[4096];
9204 uint8_t f_palettes[2][1024];
9205 uint8_t f_dst_palette[1024];
9206 uint8_t f_lzw_suffixes[4096][8];
9207 uint16_t f_lzw_lm1s[4096];
9208 uint8_t f_lzw_output[8199];
9210 struct {
9211 uint32_t v_background_color;
9212 } s_do_decode_frame_config;
9213 struct {
9214 uint64_t scratch;
9215 } s_skip_frame;
9216 struct {
9217 uint64_t scratch;
9218 } s_decode_header;
9219 struct {
9220 uint8_t v_flags;
9221 uint8_t v_background_color_index;
9222 uint32_t v_num_palette_entries;
9223 uint32_t v_i;
9224 uint64_t scratch;
9225 } s_decode_lsd;
9226 struct {
9227 uint64_t scratch;
9228 } s_skip_blocks;
9229 struct {
9230 uint8_t v_block_size;
9231 bool v_is_animexts;
9232 bool v_is_netscape;
9233 bool v_is_iccp;
9234 bool v_is_xmp;
9235 uint64_t scratch;
9236 } s_decode_ae;
9237 struct {
9238 uint64_t scratch;
9239 } s_decode_gc;
9240 struct {
9241 uint64_t scratch;
9242 } s_decode_id_part0;
9243 struct {
9244 uint8_t v_which_palette;
9245 uint32_t v_num_palette_entries;
9246 uint32_t v_i;
9247 uint64_t scratch;
9248 } s_decode_id_part1;
9249 struct {
9250 uint64_t v_block_size;
9251 bool v_need_block_size;
9252 uint64_t scratch;
9253 } s_decode_id_part2;
9254 } private_data;
9256 #ifdef __cplusplus
9257 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
9258 using unique_ptr = std::unique_ptr<wuffs_gif__decoder, wuffs_unique_ptr_deleter>;
9260 // On failure, the alloc_etc functions return nullptr. They don't throw.
9262 static inline unique_ptr
9263 alloc() {
9264 return unique_ptr(wuffs_gif__decoder__alloc());
9267 static inline wuffs_base__image_decoder::unique_ptr
9268 alloc_as__wuffs_base__image_decoder() {
9269 return wuffs_base__image_decoder::unique_ptr(
9270 wuffs_gif__decoder__alloc_as__wuffs_base__image_decoder());
9272 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
9274 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
9275 // Disallow constructing or copying an object via standard C++ mechanisms,
9276 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
9277 // size and field layout is not part of the public, stable, memory-safe API.
9278 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
9279 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
9280 // their first argument) rather than tweaking bar.private_impl.qux fields.
9282 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
9283 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
9284 // order to provide convenience methods. These forward on "this", so that you
9285 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
9286 wuffs_gif__decoder__struct() = delete;
9287 wuffs_gif__decoder__struct(const wuffs_gif__decoder__struct&) = delete;
9288 wuffs_gif__decoder__struct& operator=(
9289 const wuffs_gif__decoder__struct&) = delete;
9290 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
9292 #if !defined(WUFFS_IMPLEMENTATION)
9293 // As above, the size of the struct is not part of the public API, and unless
9294 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
9295 // allocated, not stack allocated. Its size is not intended to be known at
9296 // compile time, but it is unfortunately divulged as a side effect of
9297 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
9298 // instead of "sizeof T", invoking the operator. To make the two values
9299 // different, so that passing the latter will be rejected by the initialize
9300 // function, we add an arbitrary amount of dead weight.
9301 uint8_t dead_weight[123000000]; // 123 MB.
9302 #endif // !defined(WUFFS_IMPLEMENTATION)
9304 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
9305 initialize(
9306 size_t sizeof_star_self,
9307 uint64_t wuffs_version,
9308 uint32_t options) {
9309 return wuffs_gif__decoder__initialize(
9310 this, sizeof_star_self, wuffs_version, options);
9313 inline wuffs_base__image_decoder*
9314 upcast_as__wuffs_base__image_decoder() {
9315 return (wuffs_base__image_decoder*)this;
9318 inline uint64_t
9319 get_quirk(
9320 uint32_t a_key) const {
9321 return wuffs_gif__decoder__get_quirk(this, a_key);
9324 inline wuffs_base__status
9325 set_quirk(
9326 uint32_t a_key,
9327 uint64_t a_value) {
9328 return wuffs_gif__decoder__set_quirk(this, a_key, a_value);
9331 inline wuffs_base__status
9332 decode_image_config(
9333 wuffs_base__image_config* a_dst,
9334 wuffs_base__io_buffer* a_src) {
9335 return wuffs_gif__decoder__decode_image_config(this, a_dst, a_src);
9338 inline wuffs_base__empty_struct
9339 set_report_metadata(
9340 uint32_t a_fourcc,
9341 bool a_report) {
9342 return wuffs_gif__decoder__set_report_metadata(this, a_fourcc, a_report);
9345 inline wuffs_base__status
9346 tell_me_more(
9347 wuffs_base__io_buffer* a_dst,
9348 wuffs_base__more_information* a_minfo,
9349 wuffs_base__io_buffer* a_src) {
9350 return wuffs_gif__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
9353 inline uint32_t
9354 num_animation_loops() const {
9355 return wuffs_gif__decoder__num_animation_loops(this);
9358 inline uint64_t
9359 num_decoded_frame_configs() const {
9360 return wuffs_gif__decoder__num_decoded_frame_configs(this);
9363 inline uint64_t
9364 num_decoded_frames() const {
9365 return wuffs_gif__decoder__num_decoded_frames(this);
9368 inline wuffs_base__rect_ie_u32
9369 frame_dirty_rect() const {
9370 return wuffs_gif__decoder__frame_dirty_rect(this);
9373 inline wuffs_base__range_ii_u64
9374 workbuf_len() const {
9375 return wuffs_gif__decoder__workbuf_len(this);
9378 inline wuffs_base__status
9379 restart_frame(
9380 uint64_t a_index,
9381 uint64_t a_io_position) {
9382 return wuffs_gif__decoder__restart_frame(this, a_index, a_io_position);
9385 inline wuffs_base__status
9386 decode_frame_config(
9387 wuffs_base__frame_config* a_dst,
9388 wuffs_base__io_buffer* a_src) {
9389 return wuffs_gif__decoder__decode_frame_config(this, a_dst, a_src);
9392 inline wuffs_base__status
9393 decode_frame(
9394 wuffs_base__pixel_buffer* a_dst,
9395 wuffs_base__io_buffer* a_src,
9396 wuffs_base__pixel_blend a_blend,
9397 wuffs_base__slice_u8 a_workbuf,
9398 wuffs_base__decode_frame_options* a_opts) {
9399 return wuffs_gif__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
9402 #endif // __cplusplus
9403 }; // struct wuffs_gif__decoder__struct
9405 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
9407 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GIF) || defined(WUFFS_NONMONOLITHIC)
9409 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GZIP) || defined(WUFFS_NONMONOLITHIC)
9411 // ---------------- Status Codes
9413 extern const char wuffs_gzip__error__bad_checksum[];
9414 extern const char wuffs_gzip__error__bad_compression_method[];
9415 extern const char wuffs_gzip__error__bad_encoding_flags[];
9416 extern const char wuffs_gzip__error__bad_header[];
9417 extern const char wuffs_gzip__error__truncated_input[];
9419 // ---------------- Public Consts
9421 #define WUFFS_GZIP__DECODER_DST_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0u
9423 #define WUFFS_GZIP__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 1u
9425 // ---------------- Struct Declarations
9427 typedef struct wuffs_gzip__decoder__struct wuffs_gzip__decoder;
9429 #ifdef __cplusplus
9430 extern "C" {
9431 #endif
9433 // ---------------- Public Initializer Prototypes
9435 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
9436 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
9438 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
9439 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
9441 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
9442 wuffs_gzip__decoder__initialize(
9443 wuffs_gzip__decoder* self,
9444 size_t sizeof_star_self,
9445 uint64_t wuffs_version,
9446 uint32_t options);
9448 size_t
9449 sizeof__wuffs_gzip__decoder(void);
9451 // ---------------- Allocs
9453 // These functions allocate and initialize Wuffs structs. They return NULL if
9454 // memory allocation fails. If they return non-NULL, there is no need to call
9455 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
9456 // calling free on the returned pointer. That pointer is effectively a C++
9457 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
9459 wuffs_gzip__decoder*
9460 wuffs_gzip__decoder__alloc(void);
9462 static inline wuffs_base__io_transformer*
9463 wuffs_gzip__decoder__alloc_as__wuffs_base__io_transformer(void) {
9464 return (wuffs_base__io_transformer*)(wuffs_gzip__decoder__alloc());
9467 // ---------------- Upcasts
9469 static inline wuffs_base__io_transformer*
9470 wuffs_gzip__decoder__upcast_as__wuffs_base__io_transformer(
9471 wuffs_gzip__decoder* p) {
9472 return (wuffs_base__io_transformer*)p;
9475 // ---------------- Public Function Prototypes
9477 WUFFS_BASE__GENERATED_C_CODE
9478 WUFFS_BASE__MAYBE_STATIC uint64_t
9479 wuffs_gzip__decoder__get_quirk(
9480 const wuffs_gzip__decoder* self,
9481 uint32_t a_key);
9483 WUFFS_BASE__GENERATED_C_CODE
9484 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9485 wuffs_gzip__decoder__set_quirk(
9486 wuffs_gzip__decoder* self,
9487 uint32_t a_key,
9488 uint64_t a_value);
9490 WUFFS_BASE__GENERATED_C_CODE
9491 WUFFS_BASE__MAYBE_STATIC wuffs_base__optional_u63
9492 wuffs_gzip__decoder__dst_history_retain_length(
9493 const wuffs_gzip__decoder* self);
9495 WUFFS_BASE__GENERATED_C_CODE
9496 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
9497 wuffs_gzip__decoder__workbuf_len(
9498 const wuffs_gzip__decoder* self);
9500 WUFFS_BASE__GENERATED_C_CODE
9501 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9502 wuffs_gzip__decoder__transform_io(
9503 wuffs_gzip__decoder* self,
9504 wuffs_base__io_buffer* a_dst,
9505 wuffs_base__io_buffer* a_src,
9506 wuffs_base__slice_u8 a_workbuf);
9508 #ifdef __cplusplus
9509 } // extern "C"
9510 #endif
9512 // ---------------- Struct Definitions
9514 // These structs' fields, and the sizeof them, are private implementation
9515 // details that aren't guaranteed to be stable across Wuffs versions.
9517 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
9519 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
9521 struct wuffs_gzip__decoder__struct {
9522 // Do not access the private_impl's or private_data's fields directly. There
9523 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
9524 // the wuffs_foo__bar__baz functions.
9526 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
9527 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
9529 struct {
9530 uint32_t magic;
9531 uint32_t active_coroutine;
9532 wuffs_base__vtable vtable_for__wuffs_base__io_transformer;
9533 wuffs_base__vtable null_vtable;
9535 bool f_ignore_checksum;
9537 uint32_t p_transform_io;
9538 uint32_t p_do_transform_io;
9539 } private_impl;
9541 struct {
9542 wuffs_crc32__ieee_hasher f_checksum;
9543 wuffs_deflate__decoder f_flate;
9545 struct {
9546 uint8_t v_flags;
9547 uint32_t v_checksum_have;
9548 uint32_t v_decoded_length_have;
9549 uint32_t v_checksum_want;
9550 uint64_t scratch;
9551 } s_do_transform_io;
9552 } private_data;
9554 #ifdef __cplusplus
9555 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
9556 using unique_ptr = std::unique_ptr<wuffs_gzip__decoder, wuffs_unique_ptr_deleter>;
9558 // On failure, the alloc_etc functions return nullptr. They don't throw.
9560 static inline unique_ptr
9561 alloc() {
9562 return unique_ptr(wuffs_gzip__decoder__alloc());
9565 static inline wuffs_base__io_transformer::unique_ptr
9566 alloc_as__wuffs_base__io_transformer() {
9567 return wuffs_base__io_transformer::unique_ptr(
9568 wuffs_gzip__decoder__alloc_as__wuffs_base__io_transformer());
9570 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
9572 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
9573 // Disallow constructing or copying an object via standard C++ mechanisms,
9574 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
9575 // size and field layout is not part of the public, stable, memory-safe API.
9576 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
9577 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
9578 // their first argument) rather than tweaking bar.private_impl.qux fields.
9580 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
9581 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
9582 // order to provide convenience methods. These forward on "this", so that you
9583 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
9584 wuffs_gzip__decoder__struct() = delete;
9585 wuffs_gzip__decoder__struct(const wuffs_gzip__decoder__struct&) = delete;
9586 wuffs_gzip__decoder__struct& operator=(
9587 const wuffs_gzip__decoder__struct&) = delete;
9588 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
9590 #if !defined(WUFFS_IMPLEMENTATION)
9591 // As above, the size of the struct is not part of the public API, and unless
9592 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
9593 // allocated, not stack allocated. Its size is not intended to be known at
9594 // compile time, but it is unfortunately divulged as a side effect of
9595 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
9596 // instead of "sizeof T", invoking the operator. To make the two values
9597 // different, so that passing the latter will be rejected by the initialize
9598 // function, we add an arbitrary amount of dead weight.
9599 uint8_t dead_weight[123000000]; // 123 MB.
9600 #endif // !defined(WUFFS_IMPLEMENTATION)
9602 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
9603 initialize(
9604 size_t sizeof_star_self,
9605 uint64_t wuffs_version,
9606 uint32_t options) {
9607 return wuffs_gzip__decoder__initialize(
9608 this, sizeof_star_self, wuffs_version, options);
9611 inline wuffs_base__io_transformer*
9612 upcast_as__wuffs_base__io_transformer() {
9613 return (wuffs_base__io_transformer*)this;
9616 inline uint64_t
9617 get_quirk(
9618 uint32_t a_key) const {
9619 return wuffs_gzip__decoder__get_quirk(this, a_key);
9622 inline wuffs_base__status
9623 set_quirk(
9624 uint32_t a_key,
9625 uint64_t a_value) {
9626 return wuffs_gzip__decoder__set_quirk(this, a_key, a_value);
9629 inline wuffs_base__optional_u63
9630 dst_history_retain_length() const {
9631 return wuffs_gzip__decoder__dst_history_retain_length(this);
9634 inline wuffs_base__range_ii_u64
9635 workbuf_len() const {
9636 return wuffs_gzip__decoder__workbuf_len(this);
9639 inline wuffs_base__status
9640 transform_io(
9641 wuffs_base__io_buffer* a_dst,
9642 wuffs_base__io_buffer* a_src,
9643 wuffs_base__slice_u8 a_workbuf) {
9644 return wuffs_gzip__decoder__transform_io(this, a_dst, a_src, a_workbuf);
9647 #endif // __cplusplus
9648 }; // struct wuffs_gzip__decoder__struct
9650 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
9652 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GZIP) || defined(WUFFS_NONMONOLITHIC)
9654 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JPEG) || defined(WUFFS_NONMONOLITHIC)
9656 // ---------------- Status Codes
9658 extern const char wuffs_jpeg__error__bad_dht_marker[];
9659 extern const char wuffs_jpeg__error__bad_dqt_marker[];
9660 extern const char wuffs_jpeg__error__bad_dri_marker[];
9661 extern const char wuffs_jpeg__error__bad_sof_marker[];
9662 extern const char wuffs_jpeg__error__bad_sos_marker[];
9663 extern const char wuffs_jpeg__error__bad_header[];
9664 extern const char wuffs_jpeg__error__bad_marker[];
9665 extern const char wuffs_jpeg__error__bad_scan_count[];
9666 extern const char wuffs_jpeg__error__missing_huffman_table[];
9667 extern const char wuffs_jpeg__error__missing_quantization_table[];
9668 extern const char wuffs_jpeg__error__rejected_progressive_jpeg[];
9669 extern const char wuffs_jpeg__error__truncated_input[];
9670 extern const char wuffs_jpeg__error__unsupported_arithmetic_coding[];
9671 extern const char wuffs_jpeg__error__unsupported_color_model[];
9672 extern const char wuffs_jpeg__error__unsupported_fractional_sampling[];
9673 extern const char wuffs_jpeg__error__unsupported_hierarchical_coding[];
9674 extern const char wuffs_jpeg__error__unsupported_implicit_height[];
9675 extern const char wuffs_jpeg__error__unsupported_lossless_coding[];
9676 extern const char wuffs_jpeg__error__unsupported_marker[];
9677 extern const char wuffs_jpeg__error__unsupported_precision_12_bits[];
9678 extern const char wuffs_jpeg__error__unsupported_precision_16_bits[];
9679 extern const char wuffs_jpeg__error__unsupported_precision[];
9680 extern const char wuffs_jpeg__error__unsupported_scan_count[];
9682 // ---------------- Public Consts
9684 #define WUFFS_JPEG__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 51552191232u
9686 #define WUFFS_JPEG__QUIRK_REJECT_PROGRESSIVE_JPEGS 1220532224u
9688 // ---------------- Struct Declarations
9690 typedef struct wuffs_jpeg__decoder__struct wuffs_jpeg__decoder;
9692 #ifdef __cplusplus
9693 extern "C" {
9694 #endif
9696 // ---------------- Public Initializer Prototypes
9698 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
9699 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
9701 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
9702 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
9704 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
9705 wuffs_jpeg__decoder__initialize(
9706 wuffs_jpeg__decoder* self,
9707 size_t sizeof_star_self,
9708 uint64_t wuffs_version,
9709 uint32_t options);
9711 size_t
9712 sizeof__wuffs_jpeg__decoder(void);
9714 // ---------------- Allocs
9716 // These functions allocate and initialize Wuffs structs. They return NULL if
9717 // memory allocation fails. If they return non-NULL, there is no need to call
9718 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
9719 // calling free on the returned pointer. That pointer is effectively a C++
9720 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
9722 wuffs_jpeg__decoder*
9723 wuffs_jpeg__decoder__alloc(void);
9725 static inline wuffs_base__image_decoder*
9726 wuffs_jpeg__decoder__alloc_as__wuffs_base__image_decoder(void) {
9727 return (wuffs_base__image_decoder*)(wuffs_jpeg__decoder__alloc());
9730 // ---------------- Upcasts
9732 static inline wuffs_base__image_decoder*
9733 wuffs_jpeg__decoder__upcast_as__wuffs_base__image_decoder(
9734 wuffs_jpeg__decoder* p) {
9735 return (wuffs_base__image_decoder*)p;
9738 // ---------------- Public Function Prototypes
9740 WUFFS_BASE__GENERATED_C_CODE
9741 WUFFS_BASE__MAYBE_STATIC uint64_t
9742 wuffs_jpeg__decoder__get_quirk(
9743 const wuffs_jpeg__decoder* self,
9744 uint32_t a_key);
9746 WUFFS_BASE__GENERATED_C_CODE
9747 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9748 wuffs_jpeg__decoder__set_quirk(
9749 wuffs_jpeg__decoder* self,
9750 uint32_t a_key,
9751 uint64_t a_value);
9753 WUFFS_BASE__GENERATED_C_CODE
9754 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9755 wuffs_jpeg__decoder__decode_image_config(
9756 wuffs_jpeg__decoder* self,
9757 wuffs_base__image_config* a_dst,
9758 wuffs_base__io_buffer* a_src);
9760 WUFFS_BASE__GENERATED_C_CODE
9761 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9762 wuffs_jpeg__decoder__decode_frame_config(
9763 wuffs_jpeg__decoder* self,
9764 wuffs_base__frame_config* a_dst,
9765 wuffs_base__io_buffer* a_src);
9767 WUFFS_BASE__GENERATED_C_CODE
9768 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9769 wuffs_jpeg__decoder__decode_frame(
9770 wuffs_jpeg__decoder* self,
9771 wuffs_base__pixel_buffer* a_dst,
9772 wuffs_base__io_buffer* a_src,
9773 wuffs_base__pixel_blend a_blend,
9774 wuffs_base__slice_u8 a_workbuf,
9775 wuffs_base__decode_frame_options* a_opts);
9777 WUFFS_BASE__GENERATED_C_CODE
9778 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
9779 wuffs_jpeg__decoder__frame_dirty_rect(
9780 const wuffs_jpeg__decoder* self);
9782 WUFFS_BASE__GENERATED_C_CODE
9783 WUFFS_BASE__MAYBE_STATIC uint32_t
9784 wuffs_jpeg__decoder__num_animation_loops(
9785 const wuffs_jpeg__decoder* self);
9787 WUFFS_BASE__GENERATED_C_CODE
9788 WUFFS_BASE__MAYBE_STATIC uint64_t
9789 wuffs_jpeg__decoder__num_decoded_frame_configs(
9790 const wuffs_jpeg__decoder* self);
9792 WUFFS_BASE__GENERATED_C_CODE
9793 WUFFS_BASE__MAYBE_STATIC uint64_t
9794 wuffs_jpeg__decoder__num_decoded_frames(
9795 const wuffs_jpeg__decoder* self);
9797 WUFFS_BASE__GENERATED_C_CODE
9798 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9799 wuffs_jpeg__decoder__restart_frame(
9800 wuffs_jpeg__decoder* self,
9801 uint64_t a_index,
9802 uint64_t a_io_position);
9804 WUFFS_BASE__GENERATED_C_CODE
9805 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
9806 wuffs_jpeg__decoder__set_report_metadata(
9807 wuffs_jpeg__decoder* self,
9808 uint32_t a_fourcc,
9809 bool a_report);
9811 WUFFS_BASE__GENERATED_C_CODE
9812 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9813 wuffs_jpeg__decoder__tell_me_more(
9814 wuffs_jpeg__decoder* self,
9815 wuffs_base__io_buffer* a_dst,
9816 wuffs_base__more_information* a_minfo,
9817 wuffs_base__io_buffer* a_src);
9819 WUFFS_BASE__GENERATED_C_CODE
9820 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
9821 wuffs_jpeg__decoder__workbuf_len(
9822 const wuffs_jpeg__decoder* self);
9824 #ifdef __cplusplus
9825 } // extern "C"
9826 #endif
9828 // ---------------- Struct Definitions
9830 // These structs' fields, and the sizeof them, are private implementation
9831 // details that aren't guaranteed to be stable across Wuffs versions.
9833 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
9835 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
9837 struct wuffs_jpeg__decoder__struct {
9838 // Do not access the private_impl's or private_data's fields directly. There
9839 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
9840 // the wuffs_foo__bar__baz functions.
9842 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
9843 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
9845 struct {
9846 uint32_t magic;
9847 uint32_t active_coroutine;
9848 wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
9849 wuffs_base__vtable null_vtable;
9851 uint32_t f_width;
9852 uint32_t f_height;
9853 uint32_t f_width_in_mcus;
9854 uint32_t f_height_in_mcus;
9855 uint8_t f_call_sequence;
9856 bool f_test_only_interrupt_decode_mcu;
9857 bool f_is_jfif;
9858 uint8_t f_is_adobe;
9859 bool f_is_rgb_or_cmyk;
9860 uint8_t f_sof_marker;
9861 uint8_t f_next_restart_marker;
9862 uint8_t f_max_incl_components_h;
9863 uint8_t f_max_incl_components_v;
9864 uint32_t f_num_components;
9865 uint8_t f_components_c[4];
9866 uint8_t f_components_h[4];
9867 uint8_t f_components_v[4];
9868 uint8_t f_components_tq[4];
9869 uint32_t f_components_workbuf_widths[4];
9870 uint32_t f_components_workbuf_heights[4];
9871 uint64_t f_components_workbuf_offsets[9];
9872 uint32_t f_scan_count;
9873 uint32_t f_scan_num_components;
9874 uint8_t f_scan_comps_cselector[4];
9875 uint8_t f_scan_comps_td[4];
9876 uint8_t f_scan_comps_ta[4];
9877 uint8_t f_scan_ss;
9878 uint8_t f_scan_se;
9879 uint8_t f_scan_ah;
9880 uint8_t f_scan_al;
9881 uint32_t f_scan_width_in_mcus;
9882 uint32_t f_scan_height_in_mcus;
9883 uint8_t f_scan_comps_bx_offset[16];
9884 uint8_t f_scan_comps_by_offset[16];
9885 uint32_t f_mcu_num_blocks;
9886 uint32_t f_mcu_current_block;
9887 uint32_t f_mcu_zig_index;
9888 uint8_t f_mcu_blocks_sselector[16];
9889 uint64_t f_mcu_blocks_offset[10];
9890 uint32_t f_mcu_blocks_mx_mul[10];
9891 uint32_t f_mcu_blocks_my_mul[10];
9892 uint8_t f_mcu_blocks_dc_hselector[10];
9893 uint8_t f_mcu_blocks_ac_hselector[10];
9894 uint16_t f_mcu_previous_dc_values[4];
9895 uint8_t f_block_smoothing_lowest_scan_al[4][10];
9896 uint16_t f_block_smoothing_dc_values[5][5];
9897 uint32_t f_block_smoothing_mx_max_incl;
9898 uint32_t f_block_smoothing_my_max_incl;
9899 uint16_t f_restart_interval;
9900 uint16_t f_saved_restart_interval;
9901 uint16_t f_restarts_remaining;
9902 uint16_t f_eob_run;
9903 uint64_t f_frame_config_io_position;
9904 uint32_t f_payload_length;
9905 bool f_seen_dqt[4];
9906 bool f_saved_seen_dqt[4];
9907 bool f_seen_dht[8];
9908 uint64_t f_bitstream_bits;
9909 uint32_t f_bitstream_n_bits;
9910 uint32_t f_bitstream_ri;
9911 uint32_t f_bitstream_wi;
9912 bool f_bitstream_is_closed;
9913 bool f_expect_multiple_scans;
9914 bool f_use_lower_quality;
9915 bool f_reject_progressive_jpegs;
9916 bool f_swizzle_immediately;
9917 wuffs_base__status f_swizzle_immediately_status;
9918 uint32_t f_swizzle_immediately_b_offsets[10];
9919 uint32_t f_swizzle_immediately_c_offsets[5];
9920 uint32_t f_bitstream_padding;
9921 uint16_t f_quant_tables[4][64];
9922 uint16_t f_saved_quant_tables[4][64];
9923 uint8_t f_huff_tables_symbols[8][256];
9924 uint32_t f_huff_tables_slow[8][16];
9925 uint16_t f_huff_tables_fast[8][256];
9926 wuffs_base__pixel_swizzler f_swizzler;
9928 wuffs_base__empty_struct (*choosy_decode_idct)(
9929 wuffs_jpeg__decoder* self,
9930 wuffs_base__slice_u8 a_dst_buffer,
9931 uint64_t a_dst_stride,
9932 uint32_t a_q);
9933 uint32_t p_decode_image_config;
9934 uint32_t p_do_decode_image_config;
9935 uint32_t p_decode_dqt;
9936 uint32_t p_decode_dri;
9937 uint32_t p_decode_appn;
9938 uint32_t p_decode_sof;
9939 uint32_t p_decode_frame_config;
9940 uint32_t p_do_decode_frame_config;
9941 uint32_t p_decode_frame;
9942 uint32_t p_do_decode_frame;
9943 uint32_t p_decode_dht;
9944 uint32_t p_decode_sos;
9945 uint32_t p_prepare_scan;
9946 wuffs_base__empty_struct (*choosy_load_mcu_blocks_for_single_component)(
9947 wuffs_jpeg__decoder* self,
9948 uint32_t a_mx,
9949 uint32_t a_my,
9950 wuffs_base__slice_u8 a_workbuf,
9951 uint32_t a_csel);
9952 uint32_t p_skip_past_the_next_restart_marker;
9953 uint32_t (*choosy_decode_mcu)(
9954 wuffs_jpeg__decoder* self,
9955 wuffs_base__pixel_buffer* a_dst,
9956 wuffs_base__slice_u8 a_workbuf,
9957 uint32_t a_mx,
9958 uint32_t a_my);
9959 } private_impl;
9961 struct {
9962 uint8_t f_bitstream_buffer[2048];
9963 uint16_t f_mcu_blocks[10][64];
9964 uint8_t f_swizzle_immediately_buffer[640];
9965 uint8_t f_swizzle_ycck_scratch_buffer_2k[2048];
9966 uint8_t f_dht_temp_counts[16];
9967 uint8_t f_dht_temp_bit_lengths[256];
9968 uint16_t f_dht_temp_bit_strings[256];
9969 uint8_t f_dst_palette[1024];
9971 struct {
9972 uint8_t v_marker;
9973 uint64_t scratch;
9974 } s_do_decode_image_config;
9975 struct {
9976 uint8_t v_q;
9977 uint32_t v_i;
9978 } s_decode_dqt;
9979 struct {
9980 uint64_t scratch;
9981 } s_decode_dri;
9982 struct {
9983 uint64_t scratch;
9984 } s_decode_appn;
9985 struct {
9986 uint32_t v_i;
9987 uint64_t scratch;
9988 } s_decode_sof;
9989 struct {
9990 uint8_t v_marker;
9991 uint64_t scratch;
9992 } s_do_decode_frame;
9993 struct {
9994 uint8_t v_tc4_th;
9995 uint32_t v_total_count;
9996 uint32_t v_i;
9997 } s_decode_dht;
9998 struct {
9999 uint32_t v_my;
10000 uint32_t v_mx;
10001 } s_decode_sos;
10002 struct {
10003 uint32_t v_i;
10004 uint64_t scratch;
10005 } s_prepare_scan;
10006 } private_data;
10008 #ifdef __cplusplus
10009 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
10010 using unique_ptr = std::unique_ptr<wuffs_jpeg__decoder, wuffs_unique_ptr_deleter>;
10012 // On failure, the alloc_etc functions return nullptr. They don't throw.
10014 static inline unique_ptr
10015 alloc() {
10016 return unique_ptr(wuffs_jpeg__decoder__alloc());
10019 static inline wuffs_base__image_decoder::unique_ptr
10020 alloc_as__wuffs_base__image_decoder() {
10021 return wuffs_base__image_decoder::unique_ptr(
10022 wuffs_jpeg__decoder__alloc_as__wuffs_base__image_decoder());
10024 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
10026 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
10027 // Disallow constructing or copying an object via standard C++ mechanisms,
10028 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
10029 // size and field layout is not part of the public, stable, memory-safe API.
10030 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
10031 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
10032 // their first argument) rather than tweaking bar.private_impl.qux fields.
10034 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
10035 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
10036 // order to provide convenience methods. These forward on "this", so that you
10037 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
10038 wuffs_jpeg__decoder__struct() = delete;
10039 wuffs_jpeg__decoder__struct(const wuffs_jpeg__decoder__struct&) = delete;
10040 wuffs_jpeg__decoder__struct& operator=(
10041 const wuffs_jpeg__decoder__struct&) = delete;
10042 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
10044 #if !defined(WUFFS_IMPLEMENTATION)
10045 // As above, the size of the struct is not part of the public API, and unless
10046 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
10047 // allocated, not stack allocated. Its size is not intended to be known at
10048 // compile time, but it is unfortunately divulged as a side effect of
10049 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
10050 // instead of "sizeof T", invoking the operator. To make the two values
10051 // different, so that passing the latter will be rejected by the initialize
10052 // function, we add an arbitrary amount of dead weight.
10053 uint8_t dead_weight[123000000]; // 123 MB.
10054 #endif // !defined(WUFFS_IMPLEMENTATION)
10056 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
10057 initialize(
10058 size_t sizeof_star_self,
10059 uint64_t wuffs_version,
10060 uint32_t options) {
10061 return wuffs_jpeg__decoder__initialize(
10062 this, sizeof_star_self, wuffs_version, options);
10065 inline wuffs_base__image_decoder*
10066 upcast_as__wuffs_base__image_decoder() {
10067 return (wuffs_base__image_decoder*)this;
10070 inline uint64_t
10071 get_quirk(
10072 uint32_t a_key) const {
10073 return wuffs_jpeg__decoder__get_quirk(this, a_key);
10076 inline wuffs_base__status
10077 set_quirk(
10078 uint32_t a_key,
10079 uint64_t a_value) {
10080 return wuffs_jpeg__decoder__set_quirk(this, a_key, a_value);
10083 inline wuffs_base__status
10084 decode_image_config(
10085 wuffs_base__image_config* a_dst,
10086 wuffs_base__io_buffer* a_src) {
10087 return wuffs_jpeg__decoder__decode_image_config(this, a_dst, a_src);
10090 inline wuffs_base__status
10091 decode_frame_config(
10092 wuffs_base__frame_config* a_dst,
10093 wuffs_base__io_buffer* a_src) {
10094 return wuffs_jpeg__decoder__decode_frame_config(this, a_dst, a_src);
10097 inline wuffs_base__status
10098 decode_frame(
10099 wuffs_base__pixel_buffer* a_dst,
10100 wuffs_base__io_buffer* a_src,
10101 wuffs_base__pixel_blend a_blend,
10102 wuffs_base__slice_u8 a_workbuf,
10103 wuffs_base__decode_frame_options* a_opts) {
10104 return wuffs_jpeg__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
10107 inline wuffs_base__rect_ie_u32
10108 frame_dirty_rect() const {
10109 return wuffs_jpeg__decoder__frame_dirty_rect(this);
10112 inline uint32_t
10113 num_animation_loops() const {
10114 return wuffs_jpeg__decoder__num_animation_loops(this);
10117 inline uint64_t
10118 num_decoded_frame_configs() const {
10119 return wuffs_jpeg__decoder__num_decoded_frame_configs(this);
10122 inline uint64_t
10123 num_decoded_frames() const {
10124 return wuffs_jpeg__decoder__num_decoded_frames(this);
10127 inline wuffs_base__status
10128 restart_frame(
10129 uint64_t a_index,
10130 uint64_t a_io_position) {
10131 return wuffs_jpeg__decoder__restart_frame(this, a_index, a_io_position);
10134 inline wuffs_base__empty_struct
10135 set_report_metadata(
10136 uint32_t a_fourcc,
10137 bool a_report) {
10138 return wuffs_jpeg__decoder__set_report_metadata(this, a_fourcc, a_report);
10141 inline wuffs_base__status
10142 tell_me_more(
10143 wuffs_base__io_buffer* a_dst,
10144 wuffs_base__more_information* a_minfo,
10145 wuffs_base__io_buffer* a_src) {
10146 return wuffs_jpeg__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
10149 inline wuffs_base__range_ii_u64
10150 workbuf_len() const {
10151 return wuffs_jpeg__decoder__workbuf_len(this);
10154 #endif // __cplusplus
10155 }; // struct wuffs_jpeg__decoder__struct
10157 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
10159 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JPEG) || defined(WUFFS_NONMONOLITHIC)
10161 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JSON) || defined(WUFFS_NONMONOLITHIC)
10163 // ---------------- Status Codes
10165 extern const char wuffs_json__error__bad_c0_control_code[];
10166 extern const char wuffs_json__error__bad_utf_8[];
10167 extern const char wuffs_json__error__bad_backslash_escape[];
10168 extern const char wuffs_json__error__bad_input[];
10169 extern const char wuffs_json__error__bad_new_line_in_a_string[];
10170 extern const char wuffs_json__error__bad_quirk_combination[];
10171 extern const char wuffs_json__error__unsupported_number_length[];
10172 extern const char wuffs_json__error__unsupported_recursion_depth[];
10174 // ---------------- Public Consts
10176 #define WUFFS_JSON__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0u
10178 #define WUFFS_JSON__DECODER_DEPTH_MAX_INCL 1024u
10180 #define WUFFS_JSON__DECODER_DST_TOKEN_BUFFER_LENGTH_MIN_INCL 1u
10182 #define WUFFS_JSON__DECODER_SRC_IO_BUFFER_LENGTH_MIN_INCL 100u
10184 #define WUFFS_JSON__QUIRK_ALLOW_ASCII_CONTROL_CODES 1225364480u
10186 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_A 1225364481u
10188 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_CAPITAL_U 1225364482u
10190 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_E 1225364483u
10192 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_NEW_LINE 1225364484u
10194 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_QUESTION_MARK 1225364485u
10196 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_SINGLE_QUOTE 1225364486u
10198 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_V 1225364487u
10200 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_X_AS_CODE_POINTS 1225364489u
10202 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_ZERO 1225364490u
10204 #define WUFFS_JSON__QUIRK_ALLOW_COMMENT_BLOCK 1225364491u
10206 #define WUFFS_JSON__QUIRK_ALLOW_COMMENT_LINE 1225364492u
10208 #define WUFFS_JSON__QUIRK_ALLOW_EXTRA_COMMA 1225364493u
10210 #define WUFFS_JSON__QUIRK_ALLOW_INF_NAN_NUMBERS 1225364494u
10212 #define WUFFS_JSON__QUIRK_ALLOW_LEADING_ASCII_RECORD_SEPARATOR 1225364495u
10214 #define WUFFS_JSON__QUIRK_ALLOW_LEADING_UNICODE_BYTE_ORDER_MARK 1225364496u
10216 #define WUFFS_JSON__QUIRK_ALLOW_TRAILING_FILLER 1225364497u
10218 #define WUFFS_JSON__QUIRK_EXPECT_TRAILING_NEW_LINE_OR_EOF 1225364498u
10220 #define WUFFS_JSON__QUIRK_JSON_POINTER_ALLOW_TILDE_N_TILDE_R_TILDE_T 1225364499u
10222 #define WUFFS_JSON__QUIRK_REPLACE_INVALID_UNICODE 1225364500u
10224 // ---------------- Struct Declarations
10226 typedef struct wuffs_json__decoder__struct wuffs_json__decoder;
10228 #ifdef __cplusplus
10229 extern "C" {
10230 #endif
10232 // ---------------- Public Initializer Prototypes
10234 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
10235 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
10237 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
10238 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
10240 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
10241 wuffs_json__decoder__initialize(
10242 wuffs_json__decoder* self,
10243 size_t sizeof_star_self,
10244 uint64_t wuffs_version,
10245 uint32_t options);
10247 size_t
10248 sizeof__wuffs_json__decoder(void);
10250 // ---------------- Allocs
10252 // These functions allocate and initialize Wuffs structs. They return NULL if
10253 // memory allocation fails. If they return non-NULL, there is no need to call
10254 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
10255 // calling free on the returned pointer. That pointer is effectively a C++
10256 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
10258 wuffs_json__decoder*
10259 wuffs_json__decoder__alloc(void);
10261 static inline wuffs_base__token_decoder*
10262 wuffs_json__decoder__alloc_as__wuffs_base__token_decoder(void) {
10263 return (wuffs_base__token_decoder*)(wuffs_json__decoder__alloc());
10266 // ---------------- Upcasts
10268 static inline wuffs_base__token_decoder*
10269 wuffs_json__decoder__upcast_as__wuffs_base__token_decoder(
10270 wuffs_json__decoder* p) {
10271 return (wuffs_base__token_decoder*)p;
10274 // ---------------- Public Function Prototypes
10276 WUFFS_BASE__GENERATED_C_CODE
10277 WUFFS_BASE__MAYBE_STATIC uint64_t
10278 wuffs_json__decoder__get_quirk(
10279 const wuffs_json__decoder* self,
10280 uint32_t a_key);
10282 WUFFS_BASE__GENERATED_C_CODE
10283 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
10284 wuffs_json__decoder__set_quirk(
10285 wuffs_json__decoder* self,
10286 uint32_t a_key,
10287 uint64_t a_value);
10289 WUFFS_BASE__GENERATED_C_CODE
10290 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
10291 wuffs_json__decoder__workbuf_len(
10292 const wuffs_json__decoder* self);
10294 WUFFS_BASE__GENERATED_C_CODE
10295 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
10296 wuffs_json__decoder__decode_tokens(
10297 wuffs_json__decoder* self,
10298 wuffs_base__token_buffer* a_dst,
10299 wuffs_base__io_buffer* a_src,
10300 wuffs_base__slice_u8 a_workbuf);
10302 #ifdef __cplusplus
10303 } // extern "C"
10304 #endif
10306 // ---------------- Struct Definitions
10308 // These structs' fields, and the sizeof them, are private implementation
10309 // details that aren't guaranteed to be stable across Wuffs versions.
10311 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
10313 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
10315 struct wuffs_json__decoder__struct {
10316 // Do not access the private_impl's or private_data's fields directly. There
10317 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
10318 // the wuffs_foo__bar__baz functions.
10320 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
10321 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
10323 struct {
10324 uint32_t magic;
10325 uint32_t active_coroutine;
10326 wuffs_base__vtable vtable_for__wuffs_base__token_decoder;
10327 wuffs_base__vtable null_vtable;
10329 bool f_quirks[21];
10330 bool f_allow_leading_ars;
10331 bool f_allow_leading_ubom;
10332 bool f_end_of_data;
10333 uint8_t f_trailer_stop;
10334 uint8_t f_comment_type;
10336 uint32_t p_decode_tokens;
10337 uint32_t p_decode_leading;
10338 uint32_t p_decode_comment;
10339 uint32_t p_decode_inf_nan;
10340 uint32_t p_decode_trailer;
10341 } private_impl;
10343 struct {
10344 uint32_t f_stack[32];
10346 struct {
10347 uint32_t v_depth;
10348 uint32_t v_expect;
10349 uint32_t v_expect_after_value;
10350 } s_decode_tokens;
10351 } private_data;
10353 #ifdef __cplusplus
10354 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
10355 using unique_ptr = std::unique_ptr<wuffs_json__decoder, wuffs_unique_ptr_deleter>;
10357 // On failure, the alloc_etc functions return nullptr. They don't throw.
10359 static inline unique_ptr
10360 alloc() {
10361 return unique_ptr(wuffs_json__decoder__alloc());
10364 static inline wuffs_base__token_decoder::unique_ptr
10365 alloc_as__wuffs_base__token_decoder() {
10366 return wuffs_base__token_decoder::unique_ptr(
10367 wuffs_json__decoder__alloc_as__wuffs_base__token_decoder());
10369 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
10371 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
10372 // Disallow constructing or copying an object via standard C++ mechanisms,
10373 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
10374 // size and field layout is not part of the public, stable, memory-safe API.
10375 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
10376 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
10377 // their first argument) rather than tweaking bar.private_impl.qux fields.
10379 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
10380 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
10381 // order to provide convenience methods. These forward on "this", so that you
10382 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
10383 wuffs_json__decoder__struct() = delete;
10384 wuffs_json__decoder__struct(const wuffs_json__decoder__struct&) = delete;
10385 wuffs_json__decoder__struct& operator=(
10386 const wuffs_json__decoder__struct&) = delete;
10387 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
10389 #if !defined(WUFFS_IMPLEMENTATION)
10390 // As above, the size of the struct is not part of the public API, and unless
10391 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
10392 // allocated, not stack allocated. Its size is not intended to be known at
10393 // compile time, but it is unfortunately divulged as a side effect of
10394 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
10395 // instead of "sizeof T", invoking the operator. To make the two values
10396 // different, so that passing the latter will be rejected by the initialize
10397 // function, we add an arbitrary amount of dead weight.
10398 uint8_t dead_weight[123000000]; // 123 MB.
10399 #endif // !defined(WUFFS_IMPLEMENTATION)
10401 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
10402 initialize(
10403 size_t sizeof_star_self,
10404 uint64_t wuffs_version,
10405 uint32_t options) {
10406 return wuffs_json__decoder__initialize(
10407 this, sizeof_star_self, wuffs_version, options);
10410 inline wuffs_base__token_decoder*
10411 upcast_as__wuffs_base__token_decoder() {
10412 return (wuffs_base__token_decoder*)this;
10415 inline uint64_t
10416 get_quirk(
10417 uint32_t a_key) const {
10418 return wuffs_json__decoder__get_quirk(this, a_key);
10421 inline wuffs_base__status
10422 set_quirk(
10423 uint32_t a_key,
10424 uint64_t a_value) {
10425 return wuffs_json__decoder__set_quirk(this, a_key, a_value);
10428 inline wuffs_base__range_ii_u64
10429 workbuf_len() const {
10430 return wuffs_json__decoder__workbuf_len(this);
10433 inline wuffs_base__status
10434 decode_tokens(
10435 wuffs_base__token_buffer* a_dst,
10436 wuffs_base__io_buffer* a_src,
10437 wuffs_base__slice_u8 a_workbuf) {
10438 return wuffs_json__decoder__decode_tokens(this, a_dst, a_src, a_workbuf);
10441 #endif // __cplusplus
10442 }; // struct wuffs_json__decoder__struct
10444 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
10446 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JSON) || defined(WUFFS_NONMONOLITHIC)
10448 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZMA) || defined(WUFFS_NONMONOLITHIC)
10450 // ---------------- Status Codes
10452 extern const char wuffs_lzma__error__bad_lzma2_header[];
10453 extern const char wuffs_lzma__error__bad_bitstream_trailer[];
10454 extern const char wuffs_lzma__error__bad_code[];
10455 extern const char wuffs_lzma__error__bad_decoded_length[];
10456 extern const char wuffs_lzma__error__bad_distance[];
10457 extern const char wuffs_lzma__error__bad_header[];
10458 extern const char wuffs_lzma__error__truncated_input[];
10459 extern const char wuffs_lzma__error__unsupported_decoded_length[];
10460 extern const char wuffs_lzma__error__unsupported_properties[];
10462 // ---------------- Public Consts
10464 #define WUFFS_LZMA__DECODER_DST_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0u
10466 #define WUFFS_LZMA__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 4294967568u
10468 #define WUFFS_LZMA__QUIRK_ALLOW_NON_ZERO_INITIAL_BYTE 1348001792u
10470 #define WUFFS_LZMA__QUIRK_FORMAT_EXTENSION 1348001793u
10472 // ---------------- Struct Declarations
10474 typedef struct wuffs_lzma__decoder__struct wuffs_lzma__decoder;
10476 #ifdef __cplusplus
10477 extern "C" {
10478 #endif
10480 // ---------------- Public Initializer Prototypes
10482 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
10483 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
10485 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
10486 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
10488 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
10489 wuffs_lzma__decoder__initialize(
10490 wuffs_lzma__decoder* self,
10491 size_t sizeof_star_self,
10492 uint64_t wuffs_version,
10493 uint32_t options);
10495 size_t
10496 sizeof__wuffs_lzma__decoder(void);
10498 // ---------------- Allocs
10500 // These functions allocate and initialize Wuffs structs. They return NULL if
10501 // memory allocation fails. If they return non-NULL, there is no need to call
10502 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
10503 // calling free on the returned pointer. That pointer is effectively a C++
10504 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
10506 wuffs_lzma__decoder*
10507 wuffs_lzma__decoder__alloc(void);
10509 static inline wuffs_base__io_transformer*
10510 wuffs_lzma__decoder__alloc_as__wuffs_base__io_transformer(void) {
10511 return (wuffs_base__io_transformer*)(wuffs_lzma__decoder__alloc());
10514 // ---------------- Upcasts
10516 static inline wuffs_base__io_transformer*
10517 wuffs_lzma__decoder__upcast_as__wuffs_base__io_transformer(
10518 wuffs_lzma__decoder* p) {
10519 return (wuffs_base__io_transformer*)p;
10522 // ---------------- Public Function Prototypes
10524 WUFFS_BASE__GENERATED_C_CODE
10525 WUFFS_BASE__MAYBE_STATIC uint64_t
10526 wuffs_lzma__decoder__get_quirk(
10527 const wuffs_lzma__decoder* self,
10528 uint32_t a_key);
10530 WUFFS_BASE__GENERATED_C_CODE
10531 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
10532 wuffs_lzma__decoder__set_quirk(
10533 wuffs_lzma__decoder* self,
10534 uint32_t a_key,
10535 uint64_t a_value);
10537 WUFFS_BASE__GENERATED_C_CODE
10538 WUFFS_BASE__MAYBE_STATIC wuffs_base__optional_u63
10539 wuffs_lzma__decoder__dst_history_retain_length(
10540 const wuffs_lzma__decoder* self);
10542 WUFFS_BASE__GENERATED_C_CODE
10543 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
10544 wuffs_lzma__decoder__workbuf_len(
10545 const wuffs_lzma__decoder* self);
10547 WUFFS_BASE__GENERATED_C_CODE
10548 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
10549 wuffs_lzma__decoder__transform_io(
10550 wuffs_lzma__decoder* self,
10551 wuffs_base__io_buffer* a_dst,
10552 wuffs_base__io_buffer* a_src,
10553 wuffs_base__slice_u8 a_workbuf);
10555 #ifdef __cplusplus
10556 } // extern "C"
10557 #endif
10559 // ---------------- Struct Definitions
10561 // These structs' fields, and the sizeof them, are private implementation
10562 // details that aren't guaranteed to be stable across Wuffs versions.
10564 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
10566 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
10568 struct wuffs_lzma__decoder__struct {
10569 // Do not access the private_impl's or private_data's fields directly. There
10570 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
10571 // the wuffs_foo__bar__baz functions.
10573 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
10574 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
10576 struct {
10577 uint32_t magic;
10578 uint32_t active_coroutine;
10579 wuffs_base__vtable vtable_for__wuffs_base__io_transformer;
10580 wuffs_base__vtable null_vtable;
10582 uint32_t f_lc;
10583 uint32_t f_lp;
10584 uint32_t f_pb;
10585 uint32_t f_format_extension;
10586 uint32_t f_dict_size;
10587 uint32_t f_dict_workbuf_index;
10588 uint32_t f_dict_seen;
10589 uint64_t f_decoded_length;
10590 uint64_t f_lzma2_encoded_length_have;
10591 uint64_t f_lzma2_encoded_length_want;
10592 bool f_lzma2_need_prob_reset;
10593 bool f_lzma2_need_properties;
10594 bool f_lzma2_need_dict_reset;
10595 bool f_prev_lzma2_chunk_was_uncompressed;
10596 bool f_allow_non_zero_initial_byte;
10597 bool f_end_of_chunk;
10598 uint8_t f_stashed_bytes[2];
10599 uint32_t f_stashed_bits;
10600 uint32_t f_stashed_range;
10601 uint32_t f_stashed_state;
10602 uint32_t f_stashed_rep0;
10603 uint32_t f_stashed_rep1;
10604 uint32_t f_stashed_rep2;
10605 uint32_t f_stashed_rep3;
10606 uint64_t f_stashed_pos;
10607 uint64_t f_stashed_pos_end;
10609 uint32_t p_decode_bitstream_slow;
10610 uint32_t p_transform_io;
10611 uint32_t p_do_transform_io;
10612 uint32_t p_decode_bitstream;
10613 uint32_t p_update_stashed_bytes;
10614 uint32_t p_decode_optional_end_of_stream;
10615 } private_impl;
10617 struct {
10618 uint16_t f_probs_ao00[192];
10619 uint16_t f_probs_ao20[12];
10620 uint16_t f_probs_ao40[12];
10621 uint16_t f_probs_ao41[192];
10622 uint16_t f_probs_ao60[12];
10623 uint16_t f_probs_ao63[12];
10624 uint16_t f_probs_match_len_low[16][8];
10625 uint16_t f_probs_match_len_mid[16][8];
10626 uint16_t f_probs_match_len_high[1][256];
10627 uint16_t f_probs_longrep_len_low[16][8];
10628 uint16_t f_probs_longrep_len_mid[16][8];
10629 uint16_t f_probs_longrep_len_high[1][256];
10630 uint16_t f_probs_slot[4][64];
10631 uint16_t f_probs_small_dist[128];
10632 uint16_t f_probs_large_dist[16];
10633 uint16_t f_probs_lit[16][768];
10635 struct {
10636 uint32_t v_bits;
10637 uint32_t v_range;
10638 uint32_t v_state;
10639 uint32_t v_rep0;
10640 uint32_t v_rep1;
10641 uint32_t v_rep2;
10642 uint32_t v_rep3;
10643 uint32_t v_rep;
10644 uint64_t v_pos;
10645 uint64_t v_pos_end;
10646 uint32_t v_lc;
10647 uint64_t v_lp_mask;
10648 uint64_t v_pb_mask;
10649 uint32_t v_tree_node;
10650 uint8_t v_prev_byte;
10651 uint32_t v_match_byte;
10652 uint32_t v_len_state;
10653 uint32_t v_slot;
10654 uint32_t v_len;
10655 uint32_t v_lanl_offset;
10656 uint32_t v_num_extra_bits;
10657 uint32_t v_dist_extra_bits;
10658 uint32_t v_i;
10659 uint32_t v_index_lit;
10660 uint32_t v_index_len;
10661 uint32_t v_index_small_dist_base;
10662 uint32_t v_index_small_dist_extra;
10663 uint32_t v_index_large_dist;
10664 uint32_t v_dist;
10665 uint64_t scratch;
10666 } s_decode_bitstream_slow;
10667 struct {
10668 uint8_t v_header_byte;
10669 uint32_t v_length;
10670 uint64_t scratch;
10671 } s_do_transform_io;
10672 } private_data;
10674 #ifdef __cplusplus
10675 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
10676 using unique_ptr = std::unique_ptr<wuffs_lzma__decoder, wuffs_unique_ptr_deleter>;
10678 // On failure, the alloc_etc functions return nullptr. They don't throw.
10680 static inline unique_ptr
10681 alloc() {
10682 return unique_ptr(wuffs_lzma__decoder__alloc());
10685 static inline wuffs_base__io_transformer::unique_ptr
10686 alloc_as__wuffs_base__io_transformer() {
10687 return wuffs_base__io_transformer::unique_ptr(
10688 wuffs_lzma__decoder__alloc_as__wuffs_base__io_transformer());
10690 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
10692 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
10693 // Disallow constructing or copying an object via standard C++ mechanisms,
10694 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
10695 // size and field layout is not part of the public, stable, memory-safe API.
10696 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
10697 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
10698 // their first argument) rather than tweaking bar.private_impl.qux fields.
10700 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
10701 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
10702 // order to provide convenience methods. These forward on "this", so that you
10703 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
10704 wuffs_lzma__decoder__struct() = delete;
10705 wuffs_lzma__decoder__struct(const wuffs_lzma__decoder__struct&) = delete;
10706 wuffs_lzma__decoder__struct& operator=(
10707 const wuffs_lzma__decoder__struct&) = delete;
10708 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
10710 #if !defined(WUFFS_IMPLEMENTATION)
10711 // As above, the size of the struct is not part of the public API, and unless
10712 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
10713 // allocated, not stack allocated. Its size is not intended to be known at
10714 // compile time, but it is unfortunately divulged as a side effect of
10715 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
10716 // instead of "sizeof T", invoking the operator. To make the two values
10717 // different, so that passing the latter will be rejected by the initialize
10718 // function, we add an arbitrary amount of dead weight.
10719 uint8_t dead_weight[123000000]; // 123 MB.
10720 #endif // !defined(WUFFS_IMPLEMENTATION)
10722 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
10723 initialize(
10724 size_t sizeof_star_self,
10725 uint64_t wuffs_version,
10726 uint32_t options) {
10727 return wuffs_lzma__decoder__initialize(
10728 this, sizeof_star_self, wuffs_version, options);
10731 inline wuffs_base__io_transformer*
10732 upcast_as__wuffs_base__io_transformer() {
10733 return (wuffs_base__io_transformer*)this;
10736 inline uint64_t
10737 get_quirk(
10738 uint32_t a_key) const {
10739 return wuffs_lzma__decoder__get_quirk(this, a_key);
10742 inline wuffs_base__status
10743 set_quirk(
10744 uint32_t a_key,
10745 uint64_t a_value) {
10746 return wuffs_lzma__decoder__set_quirk(this, a_key, a_value);
10749 inline wuffs_base__optional_u63
10750 dst_history_retain_length() const {
10751 return wuffs_lzma__decoder__dst_history_retain_length(this);
10754 inline wuffs_base__range_ii_u64
10755 workbuf_len() const {
10756 return wuffs_lzma__decoder__workbuf_len(this);
10759 inline wuffs_base__status
10760 transform_io(
10761 wuffs_base__io_buffer* a_dst,
10762 wuffs_base__io_buffer* a_src,
10763 wuffs_base__slice_u8 a_workbuf) {
10764 return wuffs_lzma__decoder__transform_io(this, a_dst, a_src, a_workbuf);
10767 #endif // __cplusplus
10768 }; // struct wuffs_lzma__decoder__struct
10770 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
10772 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZMA) || defined(WUFFS_NONMONOLITHIC)
10774 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZIP) || defined(WUFFS_NONMONOLITHIC)
10776 // ---------------- Status Codes
10778 extern const char wuffs_lzip__error__bad_checksum[];
10779 extern const char wuffs_lzip__error__bad_footer[];
10780 extern const char wuffs_lzip__error__bad_header[];
10781 extern const char wuffs_lzip__error__truncated_input[];
10783 // ---------------- Public Consts
10785 #define WUFFS_LZIP__DECODER_DST_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0u
10787 #define WUFFS_LZIP__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 4294967568u
10789 // ---------------- Struct Declarations
10791 typedef struct wuffs_lzip__decoder__struct wuffs_lzip__decoder;
10793 #ifdef __cplusplus
10794 extern "C" {
10795 #endif
10797 // ---------------- Public Initializer Prototypes
10799 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
10800 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
10802 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
10803 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
10805 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
10806 wuffs_lzip__decoder__initialize(
10807 wuffs_lzip__decoder* self,
10808 size_t sizeof_star_self,
10809 uint64_t wuffs_version,
10810 uint32_t options);
10812 size_t
10813 sizeof__wuffs_lzip__decoder(void);
10815 // ---------------- Allocs
10817 // These functions allocate and initialize Wuffs structs. They return NULL if
10818 // memory allocation fails. If they return non-NULL, there is no need to call
10819 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
10820 // calling free on the returned pointer. That pointer is effectively a C++
10821 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
10823 wuffs_lzip__decoder*
10824 wuffs_lzip__decoder__alloc(void);
10826 static inline wuffs_base__io_transformer*
10827 wuffs_lzip__decoder__alloc_as__wuffs_base__io_transformer(void) {
10828 return (wuffs_base__io_transformer*)(wuffs_lzip__decoder__alloc());
10831 // ---------------- Upcasts
10833 static inline wuffs_base__io_transformer*
10834 wuffs_lzip__decoder__upcast_as__wuffs_base__io_transformer(
10835 wuffs_lzip__decoder* p) {
10836 return (wuffs_base__io_transformer*)p;
10839 // ---------------- Public Function Prototypes
10841 WUFFS_BASE__GENERATED_C_CODE
10842 WUFFS_BASE__MAYBE_STATIC uint64_t
10843 wuffs_lzip__decoder__get_quirk(
10844 const wuffs_lzip__decoder* self,
10845 uint32_t a_key);
10847 WUFFS_BASE__GENERATED_C_CODE
10848 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
10849 wuffs_lzip__decoder__set_quirk(
10850 wuffs_lzip__decoder* self,
10851 uint32_t a_key,
10852 uint64_t a_value);
10854 WUFFS_BASE__GENERATED_C_CODE
10855 WUFFS_BASE__MAYBE_STATIC wuffs_base__optional_u63
10856 wuffs_lzip__decoder__dst_history_retain_length(
10857 const wuffs_lzip__decoder* self);
10859 WUFFS_BASE__GENERATED_C_CODE
10860 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
10861 wuffs_lzip__decoder__workbuf_len(
10862 const wuffs_lzip__decoder* self);
10864 WUFFS_BASE__GENERATED_C_CODE
10865 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
10866 wuffs_lzip__decoder__transform_io(
10867 wuffs_lzip__decoder* self,
10868 wuffs_base__io_buffer* a_dst,
10869 wuffs_base__io_buffer* a_src,
10870 wuffs_base__slice_u8 a_workbuf);
10872 #ifdef __cplusplus
10873 } // extern "C"
10874 #endif
10876 // ---------------- Struct Definitions
10878 // These structs' fields, and the sizeof them, are private implementation
10879 // details that aren't guaranteed to be stable across Wuffs versions.
10881 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
10883 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
10885 struct wuffs_lzip__decoder__struct {
10886 // Do not access the private_impl's or private_data's fields directly. There
10887 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
10888 // the wuffs_foo__bar__baz functions.
10890 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
10891 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
10893 struct {
10894 uint32_t magic;
10895 uint32_t active_coroutine;
10896 wuffs_base__vtable vtable_for__wuffs_base__io_transformer;
10897 wuffs_base__vtable null_vtable;
10899 bool f_ignore_checksum;
10900 uint64_t f_dsize_have;
10901 uint64_t f_ssize_have;
10903 uint32_t p_transform_io;
10904 uint32_t p_do_transform_io;
10905 } private_impl;
10907 struct {
10908 wuffs_crc32__ieee_hasher f_crc32;
10909 wuffs_lzma__decoder f_lzma;
10911 struct {
10912 uint64_t scratch;
10913 } s_do_transform_io;
10914 } private_data;
10916 #ifdef __cplusplus
10917 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
10918 using unique_ptr = std::unique_ptr<wuffs_lzip__decoder, wuffs_unique_ptr_deleter>;
10920 // On failure, the alloc_etc functions return nullptr. They don't throw.
10922 static inline unique_ptr
10923 alloc() {
10924 return unique_ptr(wuffs_lzip__decoder__alloc());
10927 static inline wuffs_base__io_transformer::unique_ptr
10928 alloc_as__wuffs_base__io_transformer() {
10929 return wuffs_base__io_transformer::unique_ptr(
10930 wuffs_lzip__decoder__alloc_as__wuffs_base__io_transformer());
10932 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
10934 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
10935 // Disallow constructing or copying an object via standard C++ mechanisms,
10936 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
10937 // size and field layout is not part of the public, stable, memory-safe API.
10938 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
10939 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
10940 // their first argument) rather than tweaking bar.private_impl.qux fields.
10942 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
10943 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
10944 // order to provide convenience methods. These forward on "this", so that you
10945 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
10946 wuffs_lzip__decoder__struct() = delete;
10947 wuffs_lzip__decoder__struct(const wuffs_lzip__decoder__struct&) = delete;
10948 wuffs_lzip__decoder__struct& operator=(
10949 const wuffs_lzip__decoder__struct&) = delete;
10950 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
10952 #if !defined(WUFFS_IMPLEMENTATION)
10953 // As above, the size of the struct is not part of the public API, and unless
10954 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
10955 // allocated, not stack allocated. Its size is not intended to be known at
10956 // compile time, but it is unfortunately divulged as a side effect of
10957 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
10958 // instead of "sizeof T", invoking the operator. To make the two values
10959 // different, so that passing the latter will be rejected by the initialize
10960 // function, we add an arbitrary amount of dead weight.
10961 uint8_t dead_weight[123000000]; // 123 MB.
10962 #endif // !defined(WUFFS_IMPLEMENTATION)
10964 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
10965 initialize(
10966 size_t sizeof_star_self,
10967 uint64_t wuffs_version,
10968 uint32_t options) {
10969 return wuffs_lzip__decoder__initialize(
10970 this, sizeof_star_self, wuffs_version, options);
10973 inline wuffs_base__io_transformer*
10974 upcast_as__wuffs_base__io_transformer() {
10975 return (wuffs_base__io_transformer*)this;
10978 inline uint64_t
10979 get_quirk(
10980 uint32_t a_key) const {
10981 return wuffs_lzip__decoder__get_quirk(this, a_key);
10984 inline wuffs_base__status
10985 set_quirk(
10986 uint32_t a_key,
10987 uint64_t a_value) {
10988 return wuffs_lzip__decoder__set_quirk(this, a_key, a_value);
10991 inline wuffs_base__optional_u63
10992 dst_history_retain_length() const {
10993 return wuffs_lzip__decoder__dst_history_retain_length(this);
10996 inline wuffs_base__range_ii_u64
10997 workbuf_len() const {
10998 return wuffs_lzip__decoder__workbuf_len(this);
11001 inline wuffs_base__status
11002 transform_io(
11003 wuffs_base__io_buffer* a_dst,
11004 wuffs_base__io_buffer* a_src,
11005 wuffs_base__slice_u8 a_workbuf) {
11006 return wuffs_lzip__decoder__transform_io(this, a_dst, a_src, a_workbuf);
11009 #endif // __cplusplus
11010 }; // struct wuffs_lzip__decoder__struct
11012 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
11014 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZIP) || defined(WUFFS_NONMONOLITHIC)
11016 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZW) || defined(WUFFS_NONMONOLITHIC)
11018 // ---------------- Status Codes
11020 extern const char wuffs_lzw__error__bad_code[];
11021 extern const char wuffs_lzw__error__truncated_input[];
11023 // ---------------- Public Consts
11025 #define WUFFS_LZW__DECODER_DST_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0u
11027 #define WUFFS_LZW__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0u
11029 #define WUFFS_LZW__QUIRK_LITERAL_WIDTH_PLUS_ONE 1348378624u
11031 // ---------------- Struct Declarations
11033 typedef struct wuffs_lzw__decoder__struct wuffs_lzw__decoder;
11035 #ifdef __cplusplus
11036 extern "C" {
11037 #endif
11039 // ---------------- Public Initializer Prototypes
11041 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
11042 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
11044 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
11045 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
11047 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
11048 wuffs_lzw__decoder__initialize(
11049 wuffs_lzw__decoder* self,
11050 size_t sizeof_star_self,
11051 uint64_t wuffs_version,
11052 uint32_t options);
11054 size_t
11055 sizeof__wuffs_lzw__decoder(void);
11057 // ---------------- Allocs
11059 // These functions allocate and initialize Wuffs structs. They return NULL if
11060 // memory allocation fails. If they return non-NULL, there is no need to call
11061 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
11062 // calling free on the returned pointer. That pointer is effectively a C++
11063 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
11065 wuffs_lzw__decoder*
11066 wuffs_lzw__decoder__alloc(void);
11068 static inline wuffs_base__io_transformer*
11069 wuffs_lzw__decoder__alloc_as__wuffs_base__io_transformer(void) {
11070 return (wuffs_base__io_transformer*)(wuffs_lzw__decoder__alloc());
11073 // ---------------- Upcasts
11075 static inline wuffs_base__io_transformer*
11076 wuffs_lzw__decoder__upcast_as__wuffs_base__io_transformer(
11077 wuffs_lzw__decoder* p) {
11078 return (wuffs_base__io_transformer*)p;
11081 // ---------------- Public Function Prototypes
11083 WUFFS_BASE__GENERATED_C_CODE
11084 WUFFS_BASE__MAYBE_STATIC uint64_t
11085 wuffs_lzw__decoder__get_quirk(
11086 const wuffs_lzw__decoder* self,
11087 uint32_t a_key);
11089 WUFFS_BASE__GENERATED_C_CODE
11090 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
11091 wuffs_lzw__decoder__set_quirk(
11092 wuffs_lzw__decoder* self,
11093 uint32_t a_key,
11094 uint64_t a_value);
11096 WUFFS_BASE__GENERATED_C_CODE
11097 WUFFS_BASE__MAYBE_STATIC wuffs_base__optional_u63
11098 wuffs_lzw__decoder__dst_history_retain_length(
11099 const wuffs_lzw__decoder* self);
11101 WUFFS_BASE__GENERATED_C_CODE
11102 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
11103 wuffs_lzw__decoder__workbuf_len(
11104 const wuffs_lzw__decoder* self);
11106 WUFFS_BASE__GENERATED_C_CODE
11107 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
11108 wuffs_lzw__decoder__transform_io(
11109 wuffs_lzw__decoder* self,
11110 wuffs_base__io_buffer* a_dst,
11111 wuffs_base__io_buffer* a_src,
11112 wuffs_base__slice_u8 a_workbuf);
11114 WUFFS_BASE__GENERATED_C_CODE
11115 WUFFS_BASE__MAYBE_STATIC wuffs_base__slice_u8
11116 wuffs_lzw__decoder__flush(
11117 wuffs_lzw__decoder* self);
11119 #ifdef __cplusplus
11120 } // extern "C"
11121 #endif
11123 // ---------------- Struct Definitions
11125 // These structs' fields, and the sizeof them, are private implementation
11126 // details that aren't guaranteed to be stable across Wuffs versions.
11128 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
11130 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
11132 struct wuffs_lzw__decoder__struct {
11133 // Do not access the private_impl's or private_data's fields directly. There
11134 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
11135 // the wuffs_foo__bar__baz functions.
11137 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
11138 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
11140 struct {
11141 uint32_t magic;
11142 uint32_t active_coroutine;
11143 wuffs_base__vtable vtable_for__wuffs_base__io_transformer;
11144 wuffs_base__vtable null_vtable;
11146 uint32_t f_pending_literal_width_plus_one;
11147 uint32_t f_literal_width;
11148 uint32_t f_clear_code;
11149 uint32_t f_end_code;
11150 uint32_t f_save_code;
11151 uint32_t f_prev_code;
11152 uint32_t f_width;
11153 uint32_t f_bits;
11154 uint32_t f_n_bits;
11155 uint32_t f_output_ri;
11156 uint32_t f_output_wi;
11157 uint32_t f_read_from_return_value;
11158 uint16_t f_prefixes[4096];
11160 uint32_t p_transform_io;
11161 uint32_t p_write_to;
11162 } private_impl;
11164 struct {
11165 uint8_t f_suffixes[4096][8];
11166 uint16_t f_lm1s[4096];
11167 uint8_t f_output[8199];
11168 } private_data;
11170 #ifdef __cplusplus
11171 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
11172 using unique_ptr = std::unique_ptr<wuffs_lzw__decoder, wuffs_unique_ptr_deleter>;
11174 // On failure, the alloc_etc functions return nullptr. They don't throw.
11176 static inline unique_ptr
11177 alloc() {
11178 return unique_ptr(wuffs_lzw__decoder__alloc());
11181 static inline wuffs_base__io_transformer::unique_ptr
11182 alloc_as__wuffs_base__io_transformer() {
11183 return wuffs_base__io_transformer::unique_ptr(
11184 wuffs_lzw__decoder__alloc_as__wuffs_base__io_transformer());
11186 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
11188 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
11189 // Disallow constructing or copying an object via standard C++ mechanisms,
11190 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
11191 // size and field layout is not part of the public, stable, memory-safe API.
11192 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
11193 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
11194 // their first argument) rather than tweaking bar.private_impl.qux fields.
11196 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
11197 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
11198 // order to provide convenience methods. These forward on "this", so that you
11199 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
11200 wuffs_lzw__decoder__struct() = delete;
11201 wuffs_lzw__decoder__struct(const wuffs_lzw__decoder__struct&) = delete;
11202 wuffs_lzw__decoder__struct& operator=(
11203 const wuffs_lzw__decoder__struct&) = delete;
11204 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
11206 #if !defined(WUFFS_IMPLEMENTATION)
11207 // As above, the size of the struct is not part of the public API, and unless
11208 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
11209 // allocated, not stack allocated. Its size is not intended to be known at
11210 // compile time, but it is unfortunately divulged as a side effect of
11211 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
11212 // instead of "sizeof T", invoking the operator. To make the two values
11213 // different, so that passing the latter will be rejected by the initialize
11214 // function, we add an arbitrary amount of dead weight.
11215 uint8_t dead_weight[123000000]; // 123 MB.
11216 #endif // !defined(WUFFS_IMPLEMENTATION)
11218 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
11219 initialize(
11220 size_t sizeof_star_self,
11221 uint64_t wuffs_version,
11222 uint32_t options) {
11223 return wuffs_lzw__decoder__initialize(
11224 this, sizeof_star_self, wuffs_version, options);
11227 inline wuffs_base__io_transformer*
11228 upcast_as__wuffs_base__io_transformer() {
11229 return (wuffs_base__io_transformer*)this;
11232 inline uint64_t
11233 get_quirk(
11234 uint32_t a_key) const {
11235 return wuffs_lzw__decoder__get_quirk(this, a_key);
11238 inline wuffs_base__status
11239 set_quirk(
11240 uint32_t a_key,
11241 uint64_t a_value) {
11242 return wuffs_lzw__decoder__set_quirk(this, a_key, a_value);
11245 inline wuffs_base__optional_u63
11246 dst_history_retain_length() const {
11247 return wuffs_lzw__decoder__dst_history_retain_length(this);
11250 inline wuffs_base__range_ii_u64
11251 workbuf_len() const {
11252 return wuffs_lzw__decoder__workbuf_len(this);
11255 inline wuffs_base__status
11256 transform_io(
11257 wuffs_base__io_buffer* a_dst,
11258 wuffs_base__io_buffer* a_src,
11259 wuffs_base__slice_u8 a_workbuf) {
11260 return wuffs_lzw__decoder__transform_io(this, a_dst, a_src, a_workbuf);
11263 inline wuffs_base__slice_u8
11264 flush() {
11265 return wuffs_lzw__decoder__flush(this);
11268 #endif // __cplusplus
11269 }; // struct wuffs_lzw__decoder__struct
11271 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
11273 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZW) || defined(WUFFS_NONMONOLITHIC)
11275 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NETPBM) || defined(WUFFS_NONMONOLITHIC)
11277 // ---------------- Status Codes
11279 extern const char wuffs_netpbm__error__bad_header[];
11280 extern const char wuffs_netpbm__error__truncated_input[];
11281 extern const char wuffs_netpbm__error__unsupported_netpbm_file[];
11283 // ---------------- Public Consts
11285 #define WUFFS_NETPBM__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0u
11287 // ---------------- Struct Declarations
11289 typedef struct wuffs_netpbm__decoder__struct wuffs_netpbm__decoder;
11291 #ifdef __cplusplus
11292 extern "C" {
11293 #endif
11295 // ---------------- Public Initializer Prototypes
11297 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
11298 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
11300 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
11301 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
11303 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
11304 wuffs_netpbm__decoder__initialize(
11305 wuffs_netpbm__decoder* self,
11306 size_t sizeof_star_self,
11307 uint64_t wuffs_version,
11308 uint32_t options);
11310 size_t
11311 sizeof__wuffs_netpbm__decoder(void);
11313 // ---------------- Allocs
11315 // These functions allocate and initialize Wuffs structs. They return NULL if
11316 // memory allocation fails. If they return non-NULL, there is no need to call
11317 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
11318 // calling free on the returned pointer. That pointer is effectively a C++
11319 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
11321 wuffs_netpbm__decoder*
11322 wuffs_netpbm__decoder__alloc(void);
11324 static inline wuffs_base__image_decoder*
11325 wuffs_netpbm__decoder__alloc_as__wuffs_base__image_decoder(void) {
11326 return (wuffs_base__image_decoder*)(wuffs_netpbm__decoder__alloc());
11329 // ---------------- Upcasts
11331 static inline wuffs_base__image_decoder*
11332 wuffs_netpbm__decoder__upcast_as__wuffs_base__image_decoder(
11333 wuffs_netpbm__decoder* p) {
11334 return (wuffs_base__image_decoder*)p;
11337 // ---------------- Public Function Prototypes
11339 WUFFS_BASE__GENERATED_C_CODE
11340 WUFFS_BASE__MAYBE_STATIC uint64_t
11341 wuffs_netpbm__decoder__get_quirk(
11342 const wuffs_netpbm__decoder* self,
11343 uint32_t a_key);
11345 WUFFS_BASE__GENERATED_C_CODE
11346 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
11347 wuffs_netpbm__decoder__set_quirk(
11348 wuffs_netpbm__decoder* self,
11349 uint32_t a_key,
11350 uint64_t a_value);
11352 WUFFS_BASE__GENERATED_C_CODE
11353 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
11354 wuffs_netpbm__decoder__decode_image_config(
11355 wuffs_netpbm__decoder* self,
11356 wuffs_base__image_config* a_dst,
11357 wuffs_base__io_buffer* a_src);
11359 WUFFS_BASE__GENERATED_C_CODE
11360 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
11361 wuffs_netpbm__decoder__decode_frame_config(
11362 wuffs_netpbm__decoder* self,
11363 wuffs_base__frame_config* a_dst,
11364 wuffs_base__io_buffer* a_src);
11366 WUFFS_BASE__GENERATED_C_CODE
11367 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
11368 wuffs_netpbm__decoder__decode_frame(
11369 wuffs_netpbm__decoder* self,
11370 wuffs_base__pixel_buffer* a_dst,
11371 wuffs_base__io_buffer* a_src,
11372 wuffs_base__pixel_blend a_blend,
11373 wuffs_base__slice_u8 a_workbuf,
11374 wuffs_base__decode_frame_options* a_opts);
11376 WUFFS_BASE__GENERATED_C_CODE
11377 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
11378 wuffs_netpbm__decoder__frame_dirty_rect(
11379 const wuffs_netpbm__decoder* self);
11381 WUFFS_BASE__GENERATED_C_CODE
11382 WUFFS_BASE__MAYBE_STATIC uint32_t
11383 wuffs_netpbm__decoder__num_animation_loops(
11384 const wuffs_netpbm__decoder* self);
11386 WUFFS_BASE__GENERATED_C_CODE
11387 WUFFS_BASE__MAYBE_STATIC uint64_t
11388 wuffs_netpbm__decoder__num_decoded_frame_configs(
11389 const wuffs_netpbm__decoder* self);
11391 WUFFS_BASE__GENERATED_C_CODE
11392 WUFFS_BASE__MAYBE_STATIC uint64_t
11393 wuffs_netpbm__decoder__num_decoded_frames(
11394 const wuffs_netpbm__decoder* self);
11396 WUFFS_BASE__GENERATED_C_CODE
11397 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
11398 wuffs_netpbm__decoder__restart_frame(
11399 wuffs_netpbm__decoder* self,
11400 uint64_t a_index,
11401 uint64_t a_io_position);
11403 WUFFS_BASE__GENERATED_C_CODE
11404 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
11405 wuffs_netpbm__decoder__set_report_metadata(
11406 wuffs_netpbm__decoder* self,
11407 uint32_t a_fourcc,
11408 bool a_report);
11410 WUFFS_BASE__GENERATED_C_CODE
11411 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
11412 wuffs_netpbm__decoder__tell_me_more(
11413 wuffs_netpbm__decoder* self,
11414 wuffs_base__io_buffer* a_dst,
11415 wuffs_base__more_information* a_minfo,
11416 wuffs_base__io_buffer* a_src);
11418 WUFFS_BASE__GENERATED_C_CODE
11419 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
11420 wuffs_netpbm__decoder__workbuf_len(
11421 const wuffs_netpbm__decoder* self);
11423 #ifdef __cplusplus
11424 } // extern "C"
11425 #endif
11427 // ---------------- Struct Definitions
11429 // These structs' fields, and the sizeof them, are private implementation
11430 // details that aren't guaranteed to be stable across Wuffs versions.
11432 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
11434 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
11436 struct wuffs_netpbm__decoder__struct {
11437 // Do not access the private_impl's or private_data's fields directly. There
11438 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
11439 // the wuffs_foo__bar__baz functions.
11441 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
11442 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
11444 struct {
11445 uint32_t magic;
11446 uint32_t active_coroutine;
11447 wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
11448 wuffs_base__vtable null_vtable;
11450 uint32_t f_pixfmt;
11451 uint32_t f_width;
11452 uint32_t f_height;
11453 uint32_t f_max_value;
11454 uint8_t f_call_sequence;
11455 uint64_t f_frame_config_io_position;
11456 uint32_t f_dst_x;
11457 uint32_t f_dst_y;
11458 wuffs_base__pixel_swizzler f_swizzler;
11460 uint32_t p_decode_image_config;
11461 uint32_t p_do_decode_image_config;
11462 uint32_t p_decode_frame_config;
11463 uint32_t p_do_decode_frame_config;
11464 uint32_t p_decode_frame;
11465 uint32_t p_do_decode_frame;
11466 } private_impl;
11468 #ifdef __cplusplus
11469 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
11470 using unique_ptr = std::unique_ptr<wuffs_netpbm__decoder, wuffs_unique_ptr_deleter>;
11472 // On failure, the alloc_etc functions return nullptr. They don't throw.
11474 static inline unique_ptr
11475 alloc() {
11476 return unique_ptr(wuffs_netpbm__decoder__alloc());
11479 static inline wuffs_base__image_decoder::unique_ptr
11480 alloc_as__wuffs_base__image_decoder() {
11481 return wuffs_base__image_decoder::unique_ptr(
11482 wuffs_netpbm__decoder__alloc_as__wuffs_base__image_decoder());
11484 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
11486 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
11487 // Disallow constructing or copying an object via standard C++ mechanisms,
11488 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
11489 // size and field layout is not part of the public, stable, memory-safe API.
11490 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
11491 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
11492 // their first argument) rather than tweaking bar.private_impl.qux fields.
11494 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
11495 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
11496 // order to provide convenience methods. These forward on "this", so that you
11497 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
11498 wuffs_netpbm__decoder__struct() = delete;
11499 wuffs_netpbm__decoder__struct(const wuffs_netpbm__decoder__struct&) = delete;
11500 wuffs_netpbm__decoder__struct& operator=(
11501 const wuffs_netpbm__decoder__struct&) = delete;
11502 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
11504 #if !defined(WUFFS_IMPLEMENTATION)
11505 // As above, the size of the struct is not part of the public API, and unless
11506 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
11507 // allocated, not stack allocated. Its size is not intended to be known at
11508 // compile time, but it is unfortunately divulged as a side effect of
11509 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
11510 // instead of "sizeof T", invoking the operator. To make the two values
11511 // different, so that passing the latter will be rejected by the initialize
11512 // function, we add an arbitrary amount of dead weight.
11513 uint8_t dead_weight[123000000]; // 123 MB.
11514 #endif // !defined(WUFFS_IMPLEMENTATION)
11516 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
11517 initialize(
11518 size_t sizeof_star_self,
11519 uint64_t wuffs_version,
11520 uint32_t options) {
11521 return wuffs_netpbm__decoder__initialize(
11522 this, sizeof_star_self, wuffs_version, options);
11525 inline wuffs_base__image_decoder*
11526 upcast_as__wuffs_base__image_decoder() {
11527 return (wuffs_base__image_decoder*)this;
11530 inline uint64_t
11531 get_quirk(
11532 uint32_t a_key) const {
11533 return wuffs_netpbm__decoder__get_quirk(this, a_key);
11536 inline wuffs_base__status
11537 set_quirk(
11538 uint32_t a_key,
11539 uint64_t a_value) {
11540 return wuffs_netpbm__decoder__set_quirk(this, a_key, a_value);
11543 inline wuffs_base__status
11544 decode_image_config(
11545 wuffs_base__image_config* a_dst,
11546 wuffs_base__io_buffer* a_src) {
11547 return wuffs_netpbm__decoder__decode_image_config(this, a_dst, a_src);
11550 inline wuffs_base__status
11551 decode_frame_config(
11552 wuffs_base__frame_config* a_dst,
11553 wuffs_base__io_buffer* a_src) {
11554 return wuffs_netpbm__decoder__decode_frame_config(this, a_dst, a_src);
11557 inline wuffs_base__status
11558 decode_frame(
11559 wuffs_base__pixel_buffer* a_dst,
11560 wuffs_base__io_buffer* a_src,
11561 wuffs_base__pixel_blend a_blend,
11562 wuffs_base__slice_u8 a_workbuf,
11563 wuffs_base__decode_frame_options* a_opts) {
11564 return wuffs_netpbm__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
11567 inline wuffs_base__rect_ie_u32
11568 frame_dirty_rect() const {
11569 return wuffs_netpbm__decoder__frame_dirty_rect(this);
11572 inline uint32_t
11573 num_animation_loops() const {
11574 return wuffs_netpbm__decoder__num_animation_loops(this);
11577 inline uint64_t
11578 num_decoded_frame_configs() const {
11579 return wuffs_netpbm__decoder__num_decoded_frame_configs(this);
11582 inline uint64_t
11583 num_decoded_frames() const {
11584 return wuffs_netpbm__decoder__num_decoded_frames(this);
11587 inline wuffs_base__status
11588 restart_frame(
11589 uint64_t a_index,
11590 uint64_t a_io_position) {
11591 return wuffs_netpbm__decoder__restart_frame(this, a_index, a_io_position);
11594 inline wuffs_base__empty_struct
11595 set_report_metadata(
11596 uint32_t a_fourcc,
11597 bool a_report) {
11598 return wuffs_netpbm__decoder__set_report_metadata(this, a_fourcc, a_report);
11601 inline wuffs_base__status
11602 tell_me_more(
11603 wuffs_base__io_buffer* a_dst,
11604 wuffs_base__more_information* a_minfo,
11605 wuffs_base__io_buffer* a_src) {
11606 return wuffs_netpbm__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
11609 inline wuffs_base__range_ii_u64
11610 workbuf_len() const {
11611 return wuffs_netpbm__decoder__workbuf_len(this);
11614 #endif // __cplusplus
11615 }; // struct wuffs_netpbm__decoder__struct
11617 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
11619 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NETPBM) || defined(WUFFS_NONMONOLITHIC)
11621 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NIE) || defined(WUFFS_NONMONOLITHIC)
11623 // ---------------- Status Codes
11625 extern const char wuffs_nie__error__bad_header[];
11626 extern const char wuffs_nie__error__truncated_input[];
11627 extern const char wuffs_nie__error__unsupported_nie_file[];
11629 // ---------------- Public Consts
11631 #define WUFFS_NIE__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0u
11633 // ---------------- Struct Declarations
11635 typedef struct wuffs_nie__decoder__struct wuffs_nie__decoder;
11637 #ifdef __cplusplus
11638 extern "C" {
11639 #endif
11641 // ---------------- Public Initializer Prototypes
11643 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
11644 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
11646 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
11647 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
11649 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
11650 wuffs_nie__decoder__initialize(
11651 wuffs_nie__decoder* self,
11652 size_t sizeof_star_self,
11653 uint64_t wuffs_version,
11654 uint32_t options);
11656 size_t
11657 sizeof__wuffs_nie__decoder(void);
11659 // ---------------- Allocs
11661 // These functions allocate and initialize Wuffs structs. They return NULL if
11662 // memory allocation fails. If they return non-NULL, there is no need to call
11663 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
11664 // calling free on the returned pointer. That pointer is effectively a C++
11665 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
11667 wuffs_nie__decoder*
11668 wuffs_nie__decoder__alloc(void);
11670 static inline wuffs_base__image_decoder*
11671 wuffs_nie__decoder__alloc_as__wuffs_base__image_decoder(void) {
11672 return (wuffs_base__image_decoder*)(wuffs_nie__decoder__alloc());
11675 // ---------------- Upcasts
11677 static inline wuffs_base__image_decoder*
11678 wuffs_nie__decoder__upcast_as__wuffs_base__image_decoder(
11679 wuffs_nie__decoder* p) {
11680 return (wuffs_base__image_decoder*)p;
11683 // ---------------- Public Function Prototypes
11685 WUFFS_BASE__GENERATED_C_CODE
11686 WUFFS_BASE__MAYBE_STATIC uint64_t
11687 wuffs_nie__decoder__get_quirk(
11688 const wuffs_nie__decoder* self,
11689 uint32_t a_key);
11691 WUFFS_BASE__GENERATED_C_CODE
11692 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
11693 wuffs_nie__decoder__set_quirk(
11694 wuffs_nie__decoder* self,
11695 uint32_t a_key,
11696 uint64_t a_value);
11698 WUFFS_BASE__GENERATED_C_CODE
11699 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
11700 wuffs_nie__decoder__decode_image_config(
11701 wuffs_nie__decoder* self,
11702 wuffs_base__image_config* a_dst,
11703 wuffs_base__io_buffer* a_src);
11705 WUFFS_BASE__GENERATED_C_CODE
11706 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
11707 wuffs_nie__decoder__decode_frame_config(
11708 wuffs_nie__decoder* self,
11709 wuffs_base__frame_config* a_dst,
11710 wuffs_base__io_buffer* a_src);
11712 WUFFS_BASE__GENERATED_C_CODE
11713 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
11714 wuffs_nie__decoder__decode_frame(
11715 wuffs_nie__decoder* self,
11716 wuffs_base__pixel_buffer* a_dst,
11717 wuffs_base__io_buffer* a_src,
11718 wuffs_base__pixel_blend a_blend,
11719 wuffs_base__slice_u8 a_workbuf,
11720 wuffs_base__decode_frame_options* a_opts);
11722 WUFFS_BASE__GENERATED_C_CODE
11723 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
11724 wuffs_nie__decoder__frame_dirty_rect(
11725 const wuffs_nie__decoder* self);
11727 WUFFS_BASE__GENERATED_C_CODE
11728 WUFFS_BASE__MAYBE_STATIC uint32_t
11729 wuffs_nie__decoder__num_animation_loops(
11730 const wuffs_nie__decoder* self);
11732 WUFFS_BASE__GENERATED_C_CODE
11733 WUFFS_BASE__MAYBE_STATIC uint64_t
11734 wuffs_nie__decoder__num_decoded_frame_configs(
11735 const wuffs_nie__decoder* self);
11737 WUFFS_BASE__GENERATED_C_CODE
11738 WUFFS_BASE__MAYBE_STATIC uint64_t
11739 wuffs_nie__decoder__num_decoded_frames(
11740 const wuffs_nie__decoder* self);
11742 WUFFS_BASE__GENERATED_C_CODE
11743 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
11744 wuffs_nie__decoder__restart_frame(
11745 wuffs_nie__decoder* self,
11746 uint64_t a_index,
11747 uint64_t a_io_position);
11749 WUFFS_BASE__GENERATED_C_CODE
11750 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
11751 wuffs_nie__decoder__set_report_metadata(
11752 wuffs_nie__decoder* self,
11753 uint32_t a_fourcc,
11754 bool a_report);
11756 WUFFS_BASE__GENERATED_C_CODE
11757 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
11758 wuffs_nie__decoder__tell_me_more(
11759 wuffs_nie__decoder* self,
11760 wuffs_base__io_buffer* a_dst,
11761 wuffs_base__more_information* a_minfo,
11762 wuffs_base__io_buffer* a_src);
11764 WUFFS_BASE__GENERATED_C_CODE
11765 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
11766 wuffs_nie__decoder__workbuf_len(
11767 const wuffs_nie__decoder* self);
11769 #ifdef __cplusplus
11770 } // extern "C"
11771 #endif
11773 // ---------------- Struct Definitions
11775 // These structs' fields, and the sizeof them, are private implementation
11776 // details that aren't guaranteed to be stable across Wuffs versions.
11778 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
11780 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
11782 struct wuffs_nie__decoder__struct {
11783 // Do not access the private_impl's or private_data's fields directly. There
11784 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
11785 // the wuffs_foo__bar__baz functions.
11787 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
11788 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
11790 struct {
11791 uint32_t magic;
11792 uint32_t active_coroutine;
11793 wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
11794 wuffs_base__vtable null_vtable;
11796 uint32_t f_pixfmt;
11797 uint32_t f_width;
11798 uint32_t f_height;
11799 uint8_t f_call_sequence;
11800 uint32_t f_dst_x;
11801 uint32_t f_dst_y;
11802 wuffs_base__pixel_swizzler f_swizzler;
11804 uint32_t p_decode_image_config;
11805 uint32_t p_do_decode_image_config;
11806 uint32_t p_decode_frame_config;
11807 uint32_t p_do_decode_frame_config;
11808 uint32_t p_decode_frame;
11809 uint32_t p_do_decode_frame;
11810 } private_impl;
11812 struct {
11813 struct {
11814 uint64_t scratch;
11815 } s_do_decode_image_config;
11816 } private_data;
11818 #ifdef __cplusplus
11819 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
11820 using unique_ptr = std::unique_ptr<wuffs_nie__decoder, wuffs_unique_ptr_deleter>;
11822 // On failure, the alloc_etc functions return nullptr. They don't throw.
11824 static inline unique_ptr
11825 alloc() {
11826 return unique_ptr(wuffs_nie__decoder__alloc());
11829 static inline wuffs_base__image_decoder::unique_ptr
11830 alloc_as__wuffs_base__image_decoder() {
11831 return wuffs_base__image_decoder::unique_ptr(
11832 wuffs_nie__decoder__alloc_as__wuffs_base__image_decoder());
11834 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
11836 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
11837 // Disallow constructing or copying an object via standard C++ mechanisms,
11838 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
11839 // size and field layout is not part of the public, stable, memory-safe API.
11840 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
11841 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
11842 // their first argument) rather than tweaking bar.private_impl.qux fields.
11844 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
11845 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
11846 // order to provide convenience methods. These forward on "this", so that you
11847 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
11848 wuffs_nie__decoder__struct() = delete;
11849 wuffs_nie__decoder__struct(const wuffs_nie__decoder__struct&) = delete;
11850 wuffs_nie__decoder__struct& operator=(
11851 const wuffs_nie__decoder__struct&) = delete;
11852 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
11854 #if !defined(WUFFS_IMPLEMENTATION)
11855 // As above, the size of the struct is not part of the public API, and unless
11856 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
11857 // allocated, not stack allocated. Its size is not intended to be known at
11858 // compile time, but it is unfortunately divulged as a side effect of
11859 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
11860 // instead of "sizeof T", invoking the operator. To make the two values
11861 // different, so that passing the latter will be rejected by the initialize
11862 // function, we add an arbitrary amount of dead weight.
11863 uint8_t dead_weight[123000000]; // 123 MB.
11864 #endif // !defined(WUFFS_IMPLEMENTATION)
11866 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
11867 initialize(
11868 size_t sizeof_star_self,
11869 uint64_t wuffs_version,
11870 uint32_t options) {
11871 return wuffs_nie__decoder__initialize(
11872 this, sizeof_star_self, wuffs_version, options);
11875 inline wuffs_base__image_decoder*
11876 upcast_as__wuffs_base__image_decoder() {
11877 return (wuffs_base__image_decoder*)this;
11880 inline uint64_t
11881 get_quirk(
11882 uint32_t a_key) const {
11883 return wuffs_nie__decoder__get_quirk(this, a_key);
11886 inline wuffs_base__status
11887 set_quirk(
11888 uint32_t a_key,
11889 uint64_t a_value) {
11890 return wuffs_nie__decoder__set_quirk(this, a_key, a_value);
11893 inline wuffs_base__status
11894 decode_image_config(
11895 wuffs_base__image_config* a_dst,
11896 wuffs_base__io_buffer* a_src) {
11897 return wuffs_nie__decoder__decode_image_config(this, a_dst, a_src);
11900 inline wuffs_base__status
11901 decode_frame_config(
11902 wuffs_base__frame_config* a_dst,
11903 wuffs_base__io_buffer* a_src) {
11904 return wuffs_nie__decoder__decode_frame_config(this, a_dst, a_src);
11907 inline wuffs_base__status
11908 decode_frame(
11909 wuffs_base__pixel_buffer* a_dst,
11910 wuffs_base__io_buffer* a_src,
11911 wuffs_base__pixel_blend a_blend,
11912 wuffs_base__slice_u8 a_workbuf,
11913 wuffs_base__decode_frame_options* a_opts) {
11914 return wuffs_nie__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
11917 inline wuffs_base__rect_ie_u32
11918 frame_dirty_rect() const {
11919 return wuffs_nie__decoder__frame_dirty_rect(this);
11922 inline uint32_t
11923 num_animation_loops() const {
11924 return wuffs_nie__decoder__num_animation_loops(this);
11927 inline uint64_t
11928 num_decoded_frame_configs() const {
11929 return wuffs_nie__decoder__num_decoded_frame_configs(this);
11932 inline uint64_t
11933 num_decoded_frames() const {
11934 return wuffs_nie__decoder__num_decoded_frames(this);
11937 inline wuffs_base__status
11938 restart_frame(
11939 uint64_t a_index,
11940 uint64_t a_io_position) {
11941 return wuffs_nie__decoder__restart_frame(this, a_index, a_io_position);
11944 inline wuffs_base__empty_struct
11945 set_report_metadata(
11946 uint32_t a_fourcc,
11947 bool a_report) {
11948 return wuffs_nie__decoder__set_report_metadata(this, a_fourcc, a_report);
11951 inline wuffs_base__status
11952 tell_me_more(
11953 wuffs_base__io_buffer* a_dst,
11954 wuffs_base__more_information* a_minfo,
11955 wuffs_base__io_buffer* a_src) {
11956 return wuffs_nie__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
11959 inline wuffs_base__range_ii_u64
11960 workbuf_len() const {
11961 return wuffs_nie__decoder__workbuf_len(this);
11964 #endif // __cplusplus
11965 }; // struct wuffs_nie__decoder__struct
11967 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
11969 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NIE) || defined(WUFFS_NONMONOLITHIC)
11971 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ZLIB) || defined(WUFFS_NONMONOLITHIC)
11973 // ---------------- Status Codes
11975 extern const char wuffs_zlib__note__dictionary_required[];
11976 extern const char wuffs_zlib__error__bad_checksum[];
11977 extern const char wuffs_zlib__error__bad_compression_method[];
11978 extern const char wuffs_zlib__error__bad_compression_window_size[];
11979 extern const char wuffs_zlib__error__bad_parity_check[];
11980 extern const char wuffs_zlib__error__incorrect_dictionary[];
11981 extern const char wuffs_zlib__error__truncated_input[];
11983 // ---------------- Public Consts
11985 #define WUFFS_ZLIB__QUIRK_JUST_RAW_DEFLATE 2113790976u
11987 #define WUFFS_ZLIB__DECODER_DST_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0u
11989 #define WUFFS_ZLIB__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 1u
11991 // ---------------- Struct Declarations
11993 typedef struct wuffs_zlib__decoder__struct wuffs_zlib__decoder;
11995 #ifdef __cplusplus
11996 extern "C" {
11997 #endif
11999 // ---------------- Public Initializer Prototypes
12001 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
12002 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
12004 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
12005 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
12007 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
12008 wuffs_zlib__decoder__initialize(
12009 wuffs_zlib__decoder* self,
12010 size_t sizeof_star_self,
12011 uint64_t wuffs_version,
12012 uint32_t options);
12014 size_t
12015 sizeof__wuffs_zlib__decoder(void);
12017 // ---------------- Allocs
12019 // These functions allocate and initialize Wuffs structs. They return NULL if
12020 // memory allocation fails. If they return non-NULL, there is no need to call
12021 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
12022 // calling free on the returned pointer. That pointer is effectively a C++
12023 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
12025 wuffs_zlib__decoder*
12026 wuffs_zlib__decoder__alloc(void);
12028 static inline wuffs_base__io_transformer*
12029 wuffs_zlib__decoder__alloc_as__wuffs_base__io_transformer(void) {
12030 return (wuffs_base__io_transformer*)(wuffs_zlib__decoder__alloc());
12033 // ---------------- Upcasts
12035 static inline wuffs_base__io_transformer*
12036 wuffs_zlib__decoder__upcast_as__wuffs_base__io_transformer(
12037 wuffs_zlib__decoder* p) {
12038 return (wuffs_base__io_transformer*)p;
12041 // ---------------- Public Function Prototypes
12043 WUFFS_BASE__GENERATED_C_CODE
12044 WUFFS_BASE__MAYBE_STATIC uint32_t
12045 wuffs_zlib__decoder__dictionary_id(
12046 const wuffs_zlib__decoder* self);
12048 WUFFS_BASE__GENERATED_C_CODE
12049 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
12050 wuffs_zlib__decoder__add_dictionary(
12051 wuffs_zlib__decoder* self,
12052 wuffs_base__slice_u8 a_dict);
12054 WUFFS_BASE__GENERATED_C_CODE
12055 WUFFS_BASE__MAYBE_STATIC uint64_t
12056 wuffs_zlib__decoder__get_quirk(
12057 const wuffs_zlib__decoder* self,
12058 uint32_t a_key);
12060 WUFFS_BASE__GENERATED_C_CODE
12061 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
12062 wuffs_zlib__decoder__set_quirk(
12063 wuffs_zlib__decoder* self,
12064 uint32_t a_key,
12065 uint64_t a_value);
12067 WUFFS_BASE__GENERATED_C_CODE
12068 WUFFS_BASE__MAYBE_STATIC wuffs_base__optional_u63
12069 wuffs_zlib__decoder__dst_history_retain_length(
12070 const wuffs_zlib__decoder* self);
12072 WUFFS_BASE__GENERATED_C_CODE
12073 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
12074 wuffs_zlib__decoder__workbuf_len(
12075 const wuffs_zlib__decoder* self);
12077 WUFFS_BASE__GENERATED_C_CODE
12078 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
12079 wuffs_zlib__decoder__transform_io(
12080 wuffs_zlib__decoder* self,
12081 wuffs_base__io_buffer* a_dst,
12082 wuffs_base__io_buffer* a_src,
12083 wuffs_base__slice_u8 a_workbuf);
12085 #ifdef __cplusplus
12086 } // extern "C"
12087 #endif
12089 // ---------------- Struct Definitions
12091 // These structs' fields, and the sizeof them, are private implementation
12092 // details that aren't guaranteed to be stable across Wuffs versions.
12094 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
12096 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
12098 struct wuffs_zlib__decoder__struct {
12099 // Do not access the private_impl's or private_data's fields directly. There
12100 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
12101 // the wuffs_foo__bar__baz functions.
12103 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
12104 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
12106 struct {
12107 uint32_t magic;
12108 uint32_t active_coroutine;
12109 wuffs_base__vtable vtable_for__wuffs_base__io_transformer;
12110 wuffs_base__vtable null_vtable;
12112 bool f_bad_call_sequence;
12113 bool f_header_complete;
12114 bool f_got_dictionary;
12115 bool f_want_dictionary;
12116 bool f_quirks[1];
12117 bool f_ignore_checksum;
12118 uint32_t f_dict_id_have;
12119 uint32_t f_dict_id_want;
12121 uint32_t p_transform_io;
12122 uint32_t p_do_transform_io;
12123 } private_impl;
12125 struct {
12126 wuffs_adler32__hasher f_checksum;
12127 wuffs_adler32__hasher f_dict_id_hasher;
12128 wuffs_deflate__decoder f_flate;
12130 struct {
12131 uint32_t v_checksum_have;
12132 uint64_t scratch;
12133 } s_do_transform_io;
12134 } private_data;
12136 #ifdef __cplusplus
12137 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
12138 using unique_ptr = std::unique_ptr<wuffs_zlib__decoder, wuffs_unique_ptr_deleter>;
12140 // On failure, the alloc_etc functions return nullptr. They don't throw.
12142 static inline unique_ptr
12143 alloc() {
12144 return unique_ptr(wuffs_zlib__decoder__alloc());
12147 static inline wuffs_base__io_transformer::unique_ptr
12148 alloc_as__wuffs_base__io_transformer() {
12149 return wuffs_base__io_transformer::unique_ptr(
12150 wuffs_zlib__decoder__alloc_as__wuffs_base__io_transformer());
12152 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
12154 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
12155 // Disallow constructing or copying an object via standard C++ mechanisms,
12156 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
12157 // size and field layout is not part of the public, stable, memory-safe API.
12158 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
12159 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
12160 // their first argument) rather than tweaking bar.private_impl.qux fields.
12162 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
12163 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
12164 // order to provide convenience methods. These forward on "this", so that you
12165 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
12166 wuffs_zlib__decoder__struct() = delete;
12167 wuffs_zlib__decoder__struct(const wuffs_zlib__decoder__struct&) = delete;
12168 wuffs_zlib__decoder__struct& operator=(
12169 const wuffs_zlib__decoder__struct&) = delete;
12170 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
12172 #if !defined(WUFFS_IMPLEMENTATION)
12173 // As above, the size of the struct is not part of the public API, and unless
12174 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
12175 // allocated, not stack allocated. Its size is not intended to be known at
12176 // compile time, but it is unfortunately divulged as a side effect of
12177 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
12178 // instead of "sizeof T", invoking the operator. To make the two values
12179 // different, so that passing the latter will be rejected by the initialize
12180 // function, we add an arbitrary amount of dead weight.
12181 uint8_t dead_weight[123000000]; // 123 MB.
12182 #endif // !defined(WUFFS_IMPLEMENTATION)
12184 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
12185 initialize(
12186 size_t sizeof_star_self,
12187 uint64_t wuffs_version,
12188 uint32_t options) {
12189 return wuffs_zlib__decoder__initialize(
12190 this, sizeof_star_self, wuffs_version, options);
12193 inline wuffs_base__io_transformer*
12194 upcast_as__wuffs_base__io_transformer() {
12195 return (wuffs_base__io_transformer*)this;
12198 inline uint32_t
12199 dictionary_id() const {
12200 return wuffs_zlib__decoder__dictionary_id(this);
12203 inline wuffs_base__empty_struct
12204 add_dictionary(
12205 wuffs_base__slice_u8 a_dict) {
12206 return wuffs_zlib__decoder__add_dictionary(this, a_dict);
12209 inline uint64_t
12210 get_quirk(
12211 uint32_t a_key) const {
12212 return wuffs_zlib__decoder__get_quirk(this, a_key);
12215 inline wuffs_base__status
12216 set_quirk(
12217 uint32_t a_key,
12218 uint64_t a_value) {
12219 return wuffs_zlib__decoder__set_quirk(this, a_key, a_value);
12222 inline wuffs_base__optional_u63
12223 dst_history_retain_length() const {
12224 return wuffs_zlib__decoder__dst_history_retain_length(this);
12227 inline wuffs_base__range_ii_u64
12228 workbuf_len() const {
12229 return wuffs_zlib__decoder__workbuf_len(this);
12232 inline wuffs_base__status
12233 transform_io(
12234 wuffs_base__io_buffer* a_dst,
12235 wuffs_base__io_buffer* a_src,
12236 wuffs_base__slice_u8 a_workbuf) {
12237 return wuffs_zlib__decoder__transform_io(this, a_dst, a_src, a_workbuf);
12240 #endif // __cplusplus
12241 }; // struct wuffs_zlib__decoder__struct
12243 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
12245 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ZLIB) || defined(WUFFS_NONMONOLITHIC)
12247 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__PNG) || defined(WUFFS_NONMONOLITHIC)
12249 // ---------------- Status Codes
12251 extern const char wuffs_png__error__bad_animation_sequence_number[];
12252 extern const char wuffs_png__error__bad_checksum[];
12253 extern const char wuffs_png__error__bad_chunk[];
12254 extern const char wuffs_png__error__bad_filter[];
12255 extern const char wuffs_png__error__bad_header[];
12256 extern const char wuffs_png__error__bad_text_chunk_not_latin_1[];
12257 extern const char wuffs_png__error__missing_palette[];
12258 extern const char wuffs_png__error__truncated_input[];
12259 extern const char wuffs_png__error__unsupported_cgbi_extension[];
12260 extern const char wuffs_png__error__unsupported_png_compression_method[];
12261 extern const char wuffs_png__error__unsupported_png_file[];
12263 // ---------------- Public Consts
12265 #define WUFFS_PNG__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 2251799562027015u
12267 #define WUFFS_PNG__DECODER_SRC_IO_BUFFER_LENGTH_MIN_INCL 8u
12269 // ---------------- Struct Declarations
12271 typedef struct wuffs_png__decoder__struct wuffs_png__decoder;
12273 #ifdef __cplusplus
12274 extern "C" {
12275 #endif
12277 // ---------------- Public Initializer Prototypes
12279 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
12280 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
12282 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
12283 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
12285 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
12286 wuffs_png__decoder__initialize(
12287 wuffs_png__decoder* self,
12288 size_t sizeof_star_self,
12289 uint64_t wuffs_version,
12290 uint32_t options);
12292 size_t
12293 sizeof__wuffs_png__decoder(void);
12295 // ---------------- Allocs
12297 // These functions allocate and initialize Wuffs structs. They return NULL if
12298 // memory allocation fails. If they return non-NULL, there is no need to call
12299 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
12300 // calling free on the returned pointer. That pointer is effectively a C++
12301 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
12303 wuffs_png__decoder*
12304 wuffs_png__decoder__alloc(void);
12306 static inline wuffs_base__image_decoder*
12307 wuffs_png__decoder__alloc_as__wuffs_base__image_decoder(void) {
12308 return (wuffs_base__image_decoder*)(wuffs_png__decoder__alloc());
12311 // ---------------- Upcasts
12313 static inline wuffs_base__image_decoder*
12314 wuffs_png__decoder__upcast_as__wuffs_base__image_decoder(
12315 wuffs_png__decoder* p) {
12316 return (wuffs_base__image_decoder*)p;
12319 // ---------------- Public Function Prototypes
12321 WUFFS_BASE__GENERATED_C_CODE
12322 WUFFS_BASE__MAYBE_STATIC uint64_t
12323 wuffs_png__decoder__get_quirk(
12324 const wuffs_png__decoder* self,
12325 uint32_t a_key);
12327 WUFFS_BASE__GENERATED_C_CODE
12328 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
12329 wuffs_png__decoder__set_quirk(
12330 wuffs_png__decoder* self,
12331 uint32_t a_key,
12332 uint64_t a_value);
12334 WUFFS_BASE__GENERATED_C_CODE
12335 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
12336 wuffs_png__decoder__decode_image_config(
12337 wuffs_png__decoder* self,
12338 wuffs_base__image_config* a_dst,
12339 wuffs_base__io_buffer* a_src);
12341 WUFFS_BASE__GENERATED_C_CODE
12342 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
12343 wuffs_png__decoder__decode_frame_config(
12344 wuffs_png__decoder* self,
12345 wuffs_base__frame_config* a_dst,
12346 wuffs_base__io_buffer* a_src);
12348 WUFFS_BASE__GENERATED_C_CODE
12349 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
12350 wuffs_png__decoder__decode_frame(
12351 wuffs_png__decoder* self,
12352 wuffs_base__pixel_buffer* a_dst,
12353 wuffs_base__io_buffer* a_src,
12354 wuffs_base__pixel_blend a_blend,
12355 wuffs_base__slice_u8 a_workbuf,
12356 wuffs_base__decode_frame_options* a_opts);
12358 WUFFS_BASE__GENERATED_C_CODE
12359 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
12360 wuffs_png__decoder__frame_dirty_rect(
12361 const wuffs_png__decoder* self);
12363 WUFFS_BASE__GENERATED_C_CODE
12364 WUFFS_BASE__MAYBE_STATIC uint32_t
12365 wuffs_png__decoder__num_animation_loops(
12366 const wuffs_png__decoder* self);
12368 WUFFS_BASE__GENERATED_C_CODE
12369 WUFFS_BASE__MAYBE_STATIC uint64_t
12370 wuffs_png__decoder__num_decoded_frame_configs(
12371 const wuffs_png__decoder* self);
12373 WUFFS_BASE__GENERATED_C_CODE
12374 WUFFS_BASE__MAYBE_STATIC uint64_t
12375 wuffs_png__decoder__num_decoded_frames(
12376 const wuffs_png__decoder* self);
12378 WUFFS_BASE__GENERATED_C_CODE
12379 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
12380 wuffs_png__decoder__restart_frame(
12381 wuffs_png__decoder* self,
12382 uint64_t a_index,
12383 uint64_t a_io_position);
12385 WUFFS_BASE__GENERATED_C_CODE
12386 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
12387 wuffs_png__decoder__set_report_metadata(
12388 wuffs_png__decoder* self,
12389 uint32_t a_fourcc,
12390 bool a_report);
12392 WUFFS_BASE__GENERATED_C_CODE
12393 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
12394 wuffs_png__decoder__tell_me_more(
12395 wuffs_png__decoder* self,
12396 wuffs_base__io_buffer* a_dst,
12397 wuffs_base__more_information* a_minfo,
12398 wuffs_base__io_buffer* a_src);
12400 WUFFS_BASE__GENERATED_C_CODE
12401 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
12402 wuffs_png__decoder__workbuf_len(
12403 const wuffs_png__decoder* self);
12405 #ifdef __cplusplus
12406 } // extern "C"
12407 #endif
12409 // ---------------- Struct Definitions
12411 // These structs' fields, and the sizeof them, are private implementation
12412 // details that aren't guaranteed to be stable across Wuffs versions.
12414 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
12416 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
12418 struct wuffs_png__decoder__struct {
12419 // Do not access the private_impl's or private_data's fields directly. There
12420 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
12421 // the wuffs_foo__bar__baz functions.
12423 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
12424 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
12426 struct {
12427 uint32_t magic;
12428 uint32_t active_coroutine;
12429 wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
12430 wuffs_base__vtable null_vtable;
12432 uint32_t f_width;
12433 uint32_t f_height;
12434 uint64_t f_pass_bytes_per_row;
12435 uint64_t f_workbuf_wi;
12436 uint64_t f_workbuf_hist_pos_base;
12437 uint64_t f_overall_workbuf_length;
12438 uint64_t f_pass_workbuf_length;
12439 uint8_t f_call_sequence;
12440 bool f_report_metadata_chrm;
12441 bool f_report_metadata_exif;
12442 bool f_report_metadata_gama;
12443 bool f_report_metadata_iccp;
12444 bool f_report_metadata_kvp;
12445 bool f_report_metadata_srgb;
12446 bool f_ignore_checksum;
12447 uint8_t f_depth;
12448 uint8_t f_color_type;
12449 uint8_t f_filter_distance;
12450 uint8_t f_interlace_pass;
12451 bool f_seen_actl;
12452 bool f_seen_chrm;
12453 bool f_seen_fctl;
12454 bool f_seen_exif;
12455 bool f_seen_gama;
12456 bool f_seen_iccp;
12457 bool f_seen_idat;
12458 bool f_seen_ihdr;
12459 bool f_seen_plte;
12460 bool f_seen_srgb;
12461 bool f_seen_trns;
12462 bool f_metadata_is_zlib_compressed;
12463 bool f_zlib_is_dirty;
12464 uint32_t f_chunk_type;
12465 uint8_t f_chunk_type_array[4];
12466 uint32_t f_chunk_length;
12467 uint64_t f_remap_transparency;
12468 uint32_t f_dst_pixfmt;
12469 uint32_t f_src_pixfmt;
12470 uint32_t f_num_animation_frames_value;
12471 uint32_t f_num_animation_loops_value;
12472 uint32_t f_num_decoded_frame_configs_value;
12473 uint32_t f_num_decoded_frames_value;
12474 uint32_t f_frame_rect_x0;
12475 uint32_t f_frame_rect_y0;
12476 uint32_t f_frame_rect_x1;
12477 uint32_t f_frame_rect_y1;
12478 uint32_t f_first_rect_x0;
12479 uint32_t f_first_rect_y0;
12480 uint32_t f_first_rect_x1;
12481 uint32_t f_first_rect_y1;
12482 uint64_t f_frame_config_io_position;
12483 uint64_t f_first_config_io_position;
12484 uint64_t f_frame_duration;
12485 uint64_t f_first_duration;
12486 uint8_t f_frame_disposal;
12487 uint8_t f_first_disposal;
12488 bool f_frame_overwrite_instead_of_blend;
12489 bool f_first_overwrite_instead_of_blend;
12490 uint32_t f_next_animation_seq_num;
12491 uint32_t f_metadata_flavor;
12492 uint32_t f_metadata_fourcc;
12493 uint64_t f_metadata_x;
12494 uint64_t f_metadata_y;
12495 uint64_t f_metadata_z;
12496 uint32_t f_ztxt_ri;
12497 uint32_t f_ztxt_wi;
12498 uint64_t f_ztxt_hist_pos;
12499 wuffs_base__pixel_swizzler f_swizzler;
12501 wuffs_base__empty_struct (*choosy_filter_1)(
12502 wuffs_png__decoder* self,
12503 wuffs_base__slice_u8 a_curr);
12504 wuffs_base__empty_struct (*choosy_filter_3)(
12505 wuffs_png__decoder* self,
12506 wuffs_base__slice_u8 a_curr,
12507 wuffs_base__slice_u8 a_prev);
12508 wuffs_base__empty_struct (*choosy_filter_4)(
12509 wuffs_png__decoder* self,
12510 wuffs_base__slice_u8 a_curr,
12511 wuffs_base__slice_u8 a_prev);
12512 uint32_t p_decode_image_config;
12513 uint32_t p_do_decode_image_config;
12514 uint32_t p_decode_ihdr;
12515 uint32_t p_decode_other_chunk;
12516 uint32_t p_decode_actl;
12517 uint32_t p_decode_chrm;
12518 uint32_t p_decode_fctl;
12519 uint32_t p_decode_gama;
12520 uint32_t p_decode_iccp;
12521 uint32_t p_decode_plte;
12522 uint32_t p_decode_srgb;
12523 uint32_t p_decode_trns;
12524 uint32_t p_decode_frame_config;
12525 uint32_t p_do_decode_frame_config;
12526 uint32_t p_skip_frame;
12527 uint32_t p_decode_frame;
12528 uint32_t p_do_decode_frame;
12529 uint32_t p_decode_pass;
12530 uint32_t p_tell_me_more;
12531 uint32_t p_do_tell_me_more;
12532 wuffs_base__status (*choosy_filter_and_swizzle)(
12533 wuffs_png__decoder* self,
12534 wuffs_base__pixel_buffer* a_dst,
12535 wuffs_base__slice_u8 a_workbuf);
12536 } private_impl;
12538 struct {
12539 wuffs_crc32__ieee_hasher f_crc32;
12540 wuffs_zlib__decoder f_zlib;
12541 uint8_t f_dst_palette[1024];
12542 uint8_t f_src_palette[1024];
12544 struct {
12545 uint32_t v_checksum_have;
12546 uint64_t scratch;
12547 } s_do_decode_image_config;
12548 struct {
12549 uint64_t scratch;
12550 } s_decode_ihdr;
12551 struct {
12552 uint64_t scratch;
12553 } s_decode_other_chunk;
12554 struct {
12555 uint64_t scratch;
12556 } s_decode_actl;
12557 struct {
12558 uint64_t scratch;
12559 } s_decode_chrm;
12560 struct {
12561 uint32_t v_x0;
12562 uint32_t v_x1;
12563 uint32_t v_y1;
12564 uint64_t scratch;
12565 } s_decode_fctl;
12566 struct {
12567 uint64_t scratch;
12568 } s_decode_gama;
12569 struct {
12570 uint32_t v_num_entries;
12571 uint32_t v_i;
12572 uint64_t scratch;
12573 } s_decode_plte;
12574 struct {
12575 uint32_t v_i;
12576 uint32_t v_n;
12577 uint64_t scratch;
12578 } s_decode_trns;
12579 struct {
12580 uint64_t scratch;
12581 } s_do_decode_frame_config;
12582 struct {
12583 uint64_t scratch;
12584 } s_skip_frame;
12585 struct {
12586 uint64_t scratch;
12587 } s_do_decode_frame;
12588 struct {
12589 uint64_t scratch;
12590 } s_decode_pass;
12591 struct {
12592 wuffs_base__status v_zlib_status;
12593 uint64_t scratch;
12594 } s_do_tell_me_more;
12595 } private_data;
12597 #ifdef __cplusplus
12598 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
12599 using unique_ptr = std::unique_ptr<wuffs_png__decoder, wuffs_unique_ptr_deleter>;
12601 // On failure, the alloc_etc functions return nullptr. They don't throw.
12603 static inline unique_ptr
12604 alloc() {
12605 return unique_ptr(wuffs_png__decoder__alloc());
12608 static inline wuffs_base__image_decoder::unique_ptr
12609 alloc_as__wuffs_base__image_decoder() {
12610 return wuffs_base__image_decoder::unique_ptr(
12611 wuffs_png__decoder__alloc_as__wuffs_base__image_decoder());
12613 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
12615 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
12616 // Disallow constructing or copying an object via standard C++ mechanisms,
12617 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
12618 // size and field layout is not part of the public, stable, memory-safe API.
12619 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
12620 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
12621 // their first argument) rather than tweaking bar.private_impl.qux fields.
12623 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
12624 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
12625 // order to provide convenience methods. These forward on "this", so that you
12626 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
12627 wuffs_png__decoder__struct() = delete;
12628 wuffs_png__decoder__struct(const wuffs_png__decoder__struct&) = delete;
12629 wuffs_png__decoder__struct& operator=(
12630 const wuffs_png__decoder__struct&) = delete;
12631 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
12633 #if !defined(WUFFS_IMPLEMENTATION)
12634 // As above, the size of the struct is not part of the public API, and unless
12635 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
12636 // allocated, not stack allocated. Its size is not intended to be known at
12637 // compile time, but it is unfortunately divulged as a side effect of
12638 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
12639 // instead of "sizeof T", invoking the operator. To make the two values
12640 // different, so that passing the latter will be rejected by the initialize
12641 // function, we add an arbitrary amount of dead weight.
12642 uint8_t dead_weight[123000000]; // 123 MB.
12643 #endif // !defined(WUFFS_IMPLEMENTATION)
12645 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
12646 initialize(
12647 size_t sizeof_star_self,
12648 uint64_t wuffs_version,
12649 uint32_t options) {
12650 return wuffs_png__decoder__initialize(
12651 this, sizeof_star_self, wuffs_version, options);
12654 inline wuffs_base__image_decoder*
12655 upcast_as__wuffs_base__image_decoder() {
12656 return (wuffs_base__image_decoder*)this;
12659 inline uint64_t
12660 get_quirk(
12661 uint32_t a_key) const {
12662 return wuffs_png__decoder__get_quirk(this, a_key);
12665 inline wuffs_base__status
12666 set_quirk(
12667 uint32_t a_key,
12668 uint64_t a_value) {
12669 return wuffs_png__decoder__set_quirk(this, a_key, a_value);
12672 inline wuffs_base__status
12673 decode_image_config(
12674 wuffs_base__image_config* a_dst,
12675 wuffs_base__io_buffer* a_src) {
12676 return wuffs_png__decoder__decode_image_config(this, a_dst, a_src);
12679 inline wuffs_base__status
12680 decode_frame_config(
12681 wuffs_base__frame_config* a_dst,
12682 wuffs_base__io_buffer* a_src) {
12683 return wuffs_png__decoder__decode_frame_config(this, a_dst, a_src);
12686 inline wuffs_base__status
12687 decode_frame(
12688 wuffs_base__pixel_buffer* a_dst,
12689 wuffs_base__io_buffer* a_src,
12690 wuffs_base__pixel_blend a_blend,
12691 wuffs_base__slice_u8 a_workbuf,
12692 wuffs_base__decode_frame_options* a_opts) {
12693 return wuffs_png__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
12696 inline wuffs_base__rect_ie_u32
12697 frame_dirty_rect() const {
12698 return wuffs_png__decoder__frame_dirty_rect(this);
12701 inline uint32_t
12702 num_animation_loops() const {
12703 return wuffs_png__decoder__num_animation_loops(this);
12706 inline uint64_t
12707 num_decoded_frame_configs() const {
12708 return wuffs_png__decoder__num_decoded_frame_configs(this);
12711 inline uint64_t
12712 num_decoded_frames() const {
12713 return wuffs_png__decoder__num_decoded_frames(this);
12716 inline wuffs_base__status
12717 restart_frame(
12718 uint64_t a_index,
12719 uint64_t a_io_position) {
12720 return wuffs_png__decoder__restart_frame(this, a_index, a_io_position);
12723 inline wuffs_base__empty_struct
12724 set_report_metadata(
12725 uint32_t a_fourcc,
12726 bool a_report) {
12727 return wuffs_png__decoder__set_report_metadata(this, a_fourcc, a_report);
12730 inline wuffs_base__status
12731 tell_me_more(
12732 wuffs_base__io_buffer* a_dst,
12733 wuffs_base__more_information* a_minfo,
12734 wuffs_base__io_buffer* a_src) {
12735 return wuffs_png__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
12738 inline wuffs_base__range_ii_u64
12739 workbuf_len() const {
12740 return wuffs_png__decoder__workbuf_len(this);
12743 #endif // __cplusplus
12744 }; // struct wuffs_png__decoder__struct
12746 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
12748 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__PNG) || defined(WUFFS_NONMONOLITHIC)
12750 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__QOI) || defined(WUFFS_NONMONOLITHIC)
12752 // ---------------- Status Codes
12754 extern const char wuffs_qoi__error__bad_footer[];
12755 extern const char wuffs_qoi__error__bad_header[];
12756 extern const char wuffs_qoi__error__truncated_input[];
12758 // ---------------- Public Consts
12760 #define WUFFS_QOI__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0u
12762 // ---------------- Struct Declarations
12764 typedef struct wuffs_qoi__decoder__struct wuffs_qoi__decoder;
12766 #ifdef __cplusplus
12767 extern "C" {
12768 #endif
12770 // ---------------- Public Initializer Prototypes
12772 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
12773 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
12775 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
12776 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
12778 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
12779 wuffs_qoi__decoder__initialize(
12780 wuffs_qoi__decoder* self,
12781 size_t sizeof_star_self,
12782 uint64_t wuffs_version,
12783 uint32_t options);
12785 size_t
12786 sizeof__wuffs_qoi__decoder(void);
12788 // ---------------- Allocs
12790 // These functions allocate and initialize Wuffs structs. They return NULL if
12791 // memory allocation fails. If they return non-NULL, there is no need to call
12792 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
12793 // calling free on the returned pointer. That pointer is effectively a C++
12794 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
12796 wuffs_qoi__decoder*
12797 wuffs_qoi__decoder__alloc(void);
12799 static inline wuffs_base__image_decoder*
12800 wuffs_qoi__decoder__alloc_as__wuffs_base__image_decoder(void) {
12801 return (wuffs_base__image_decoder*)(wuffs_qoi__decoder__alloc());
12804 // ---------------- Upcasts
12806 static inline wuffs_base__image_decoder*
12807 wuffs_qoi__decoder__upcast_as__wuffs_base__image_decoder(
12808 wuffs_qoi__decoder* p) {
12809 return (wuffs_base__image_decoder*)p;
12812 // ---------------- Public Function Prototypes
12814 WUFFS_BASE__GENERATED_C_CODE
12815 WUFFS_BASE__MAYBE_STATIC uint64_t
12816 wuffs_qoi__decoder__get_quirk(
12817 const wuffs_qoi__decoder* self,
12818 uint32_t a_key);
12820 WUFFS_BASE__GENERATED_C_CODE
12821 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
12822 wuffs_qoi__decoder__set_quirk(
12823 wuffs_qoi__decoder* self,
12824 uint32_t a_key,
12825 uint64_t a_value);
12827 WUFFS_BASE__GENERATED_C_CODE
12828 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
12829 wuffs_qoi__decoder__decode_image_config(
12830 wuffs_qoi__decoder* self,
12831 wuffs_base__image_config* a_dst,
12832 wuffs_base__io_buffer* a_src);
12834 WUFFS_BASE__GENERATED_C_CODE
12835 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
12836 wuffs_qoi__decoder__decode_frame_config(
12837 wuffs_qoi__decoder* self,
12838 wuffs_base__frame_config* a_dst,
12839 wuffs_base__io_buffer* a_src);
12841 WUFFS_BASE__GENERATED_C_CODE
12842 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
12843 wuffs_qoi__decoder__decode_frame(
12844 wuffs_qoi__decoder* self,
12845 wuffs_base__pixel_buffer* a_dst,
12846 wuffs_base__io_buffer* a_src,
12847 wuffs_base__pixel_blend a_blend,
12848 wuffs_base__slice_u8 a_workbuf,
12849 wuffs_base__decode_frame_options* a_opts);
12851 WUFFS_BASE__GENERATED_C_CODE
12852 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
12853 wuffs_qoi__decoder__frame_dirty_rect(
12854 const wuffs_qoi__decoder* self);
12856 WUFFS_BASE__GENERATED_C_CODE
12857 WUFFS_BASE__MAYBE_STATIC uint32_t
12858 wuffs_qoi__decoder__num_animation_loops(
12859 const wuffs_qoi__decoder* self);
12861 WUFFS_BASE__GENERATED_C_CODE
12862 WUFFS_BASE__MAYBE_STATIC uint64_t
12863 wuffs_qoi__decoder__num_decoded_frame_configs(
12864 const wuffs_qoi__decoder* self);
12866 WUFFS_BASE__GENERATED_C_CODE
12867 WUFFS_BASE__MAYBE_STATIC uint64_t
12868 wuffs_qoi__decoder__num_decoded_frames(
12869 const wuffs_qoi__decoder* self);
12871 WUFFS_BASE__GENERATED_C_CODE
12872 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
12873 wuffs_qoi__decoder__restart_frame(
12874 wuffs_qoi__decoder* self,
12875 uint64_t a_index,
12876 uint64_t a_io_position);
12878 WUFFS_BASE__GENERATED_C_CODE
12879 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
12880 wuffs_qoi__decoder__set_report_metadata(
12881 wuffs_qoi__decoder* self,
12882 uint32_t a_fourcc,
12883 bool a_report);
12885 WUFFS_BASE__GENERATED_C_CODE
12886 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
12887 wuffs_qoi__decoder__tell_me_more(
12888 wuffs_qoi__decoder* self,
12889 wuffs_base__io_buffer* a_dst,
12890 wuffs_base__more_information* a_minfo,
12891 wuffs_base__io_buffer* a_src);
12893 WUFFS_BASE__GENERATED_C_CODE
12894 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
12895 wuffs_qoi__decoder__workbuf_len(
12896 const wuffs_qoi__decoder* self);
12898 #ifdef __cplusplus
12899 } // extern "C"
12900 #endif
12902 // ---------------- Struct Definitions
12904 // These structs' fields, and the sizeof them, are private implementation
12905 // details that aren't guaranteed to be stable across Wuffs versions.
12907 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
12909 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
12911 struct wuffs_qoi__decoder__struct {
12912 // Do not access the private_impl's or private_data's fields directly. There
12913 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
12914 // the wuffs_foo__bar__baz functions.
12916 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
12917 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
12919 struct {
12920 uint32_t magic;
12921 uint32_t active_coroutine;
12922 wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
12923 wuffs_base__vtable null_vtable;
12925 uint32_t f_pixfmt;
12926 uint32_t f_width;
12927 uint32_t f_height;
12928 uint64_t f_remaining_pixels_times_4;
12929 uint8_t f_call_sequence;
12930 uint32_t f_buffer_index;
12931 uint32_t f_dst_x;
12932 uint32_t f_dst_y;
12933 wuffs_base__pixel_swizzler f_swizzler;
12935 uint32_t p_decode_image_config;
12936 uint32_t p_do_decode_image_config;
12937 uint32_t p_decode_frame_config;
12938 uint32_t p_do_decode_frame_config;
12939 uint32_t p_decode_frame;
12940 uint32_t p_do_decode_frame;
12941 uint32_t p_from_src_to_buffer;
12942 } private_impl;
12944 struct {
12945 uint8_t f_pixel[4];
12946 uint8_t f_cache[256];
12947 uint8_t f_buffer[8196];
12949 struct {
12950 uint64_t scratch;
12951 } s_do_decode_image_config;
12952 struct {
12953 uint64_t scratch;
12954 } s_do_decode_frame;
12955 struct {
12956 uint8_t v_dg;
12957 uint32_t v_bi;
12958 uint32_t v_bk;
12959 } s_from_src_to_buffer;
12960 } private_data;
12962 #ifdef __cplusplus
12963 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
12964 using unique_ptr = std::unique_ptr<wuffs_qoi__decoder, wuffs_unique_ptr_deleter>;
12966 // On failure, the alloc_etc functions return nullptr. They don't throw.
12968 static inline unique_ptr
12969 alloc() {
12970 return unique_ptr(wuffs_qoi__decoder__alloc());
12973 static inline wuffs_base__image_decoder::unique_ptr
12974 alloc_as__wuffs_base__image_decoder() {
12975 return wuffs_base__image_decoder::unique_ptr(
12976 wuffs_qoi__decoder__alloc_as__wuffs_base__image_decoder());
12978 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
12980 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
12981 // Disallow constructing or copying an object via standard C++ mechanisms,
12982 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
12983 // size and field layout is not part of the public, stable, memory-safe API.
12984 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
12985 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
12986 // their first argument) rather than tweaking bar.private_impl.qux fields.
12988 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
12989 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
12990 // order to provide convenience methods. These forward on "this", so that you
12991 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
12992 wuffs_qoi__decoder__struct() = delete;
12993 wuffs_qoi__decoder__struct(const wuffs_qoi__decoder__struct&) = delete;
12994 wuffs_qoi__decoder__struct& operator=(
12995 const wuffs_qoi__decoder__struct&) = delete;
12996 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
12998 #if !defined(WUFFS_IMPLEMENTATION)
12999 // As above, the size of the struct is not part of the public API, and unless
13000 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
13001 // allocated, not stack allocated. Its size is not intended to be known at
13002 // compile time, but it is unfortunately divulged as a side effect of
13003 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
13004 // instead of "sizeof T", invoking the operator. To make the two values
13005 // different, so that passing the latter will be rejected by the initialize
13006 // function, we add an arbitrary amount of dead weight.
13007 uint8_t dead_weight[123000000]; // 123 MB.
13008 #endif // !defined(WUFFS_IMPLEMENTATION)
13010 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
13011 initialize(
13012 size_t sizeof_star_self,
13013 uint64_t wuffs_version,
13014 uint32_t options) {
13015 return wuffs_qoi__decoder__initialize(
13016 this, sizeof_star_self, wuffs_version, options);
13019 inline wuffs_base__image_decoder*
13020 upcast_as__wuffs_base__image_decoder() {
13021 return (wuffs_base__image_decoder*)this;
13024 inline uint64_t
13025 get_quirk(
13026 uint32_t a_key) const {
13027 return wuffs_qoi__decoder__get_quirk(this, a_key);
13030 inline wuffs_base__status
13031 set_quirk(
13032 uint32_t a_key,
13033 uint64_t a_value) {
13034 return wuffs_qoi__decoder__set_quirk(this, a_key, a_value);
13037 inline wuffs_base__status
13038 decode_image_config(
13039 wuffs_base__image_config* a_dst,
13040 wuffs_base__io_buffer* a_src) {
13041 return wuffs_qoi__decoder__decode_image_config(this, a_dst, a_src);
13044 inline wuffs_base__status
13045 decode_frame_config(
13046 wuffs_base__frame_config* a_dst,
13047 wuffs_base__io_buffer* a_src) {
13048 return wuffs_qoi__decoder__decode_frame_config(this, a_dst, a_src);
13051 inline wuffs_base__status
13052 decode_frame(
13053 wuffs_base__pixel_buffer* a_dst,
13054 wuffs_base__io_buffer* a_src,
13055 wuffs_base__pixel_blend a_blend,
13056 wuffs_base__slice_u8 a_workbuf,
13057 wuffs_base__decode_frame_options* a_opts) {
13058 return wuffs_qoi__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
13061 inline wuffs_base__rect_ie_u32
13062 frame_dirty_rect() const {
13063 return wuffs_qoi__decoder__frame_dirty_rect(this);
13066 inline uint32_t
13067 num_animation_loops() const {
13068 return wuffs_qoi__decoder__num_animation_loops(this);
13071 inline uint64_t
13072 num_decoded_frame_configs() const {
13073 return wuffs_qoi__decoder__num_decoded_frame_configs(this);
13076 inline uint64_t
13077 num_decoded_frames() const {
13078 return wuffs_qoi__decoder__num_decoded_frames(this);
13081 inline wuffs_base__status
13082 restart_frame(
13083 uint64_t a_index,
13084 uint64_t a_io_position) {
13085 return wuffs_qoi__decoder__restart_frame(this, a_index, a_io_position);
13088 inline wuffs_base__empty_struct
13089 set_report_metadata(
13090 uint32_t a_fourcc,
13091 bool a_report) {
13092 return wuffs_qoi__decoder__set_report_metadata(this, a_fourcc, a_report);
13095 inline wuffs_base__status
13096 tell_me_more(
13097 wuffs_base__io_buffer* a_dst,
13098 wuffs_base__more_information* a_minfo,
13099 wuffs_base__io_buffer* a_src) {
13100 return wuffs_qoi__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
13103 inline wuffs_base__range_ii_u64
13104 workbuf_len() const {
13105 return wuffs_qoi__decoder__workbuf_len(this);
13108 #endif // __cplusplus
13109 }; // struct wuffs_qoi__decoder__struct
13111 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
13113 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__QOI) || defined(WUFFS_NONMONOLITHIC)
13115 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__SHA256) || defined(WUFFS_NONMONOLITHIC)
13117 // ---------------- Status Codes
13119 // ---------------- Public Consts
13121 // ---------------- Struct Declarations
13123 typedef struct wuffs_sha256__hasher__struct wuffs_sha256__hasher;
13125 #ifdef __cplusplus
13126 extern "C" {
13127 #endif
13129 // ---------------- Public Initializer Prototypes
13131 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
13132 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
13134 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
13135 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
13137 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
13138 wuffs_sha256__hasher__initialize(
13139 wuffs_sha256__hasher* self,
13140 size_t sizeof_star_self,
13141 uint64_t wuffs_version,
13142 uint32_t options);
13144 size_t
13145 sizeof__wuffs_sha256__hasher(void);
13147 // ---------------- Allocs
13149 // These functions allocate and initialize Wuffs structs. They return NULL if
13150 // memory allocation fails. If they return non-NULL, there is no need to call
13151 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
13152 // calling free on the returned pointer. That pointer is effectively a C++
13153 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
13155 wuffs_sha256__hasher*
13156 wuffs_sha256__hasher__alloc(void);
13158 static inline wuffs_base__hasher_bitvec256*
13159 wuffs_sha256__hasher__alloc_as__wuffs_base__hasher_bitvec256(void) {
13160 return (wuffs_base__hasher_bitvec256*)(wuffs_sha256__hasher__alloc());
13163 // ---------------- Upcasts
13165 static inline wuffs_base__hasher_bitvec256*
13166 wuffs_sha256__hasher__upcast_as__wuffs_base__hasher_bitvec256(
13167 wuffs_sha256__hasher* p) {
13168 return (wuffs_base__hasher_bitvec256*)p;
13171 // ---------------- Public Function Prototypes
13173 WUFFS_BASE__GENERATED_C_CODE
13174 WUFFS_BASE__MAYBE_STATIC uint64_t
13175 wuffs_sha256__hasher__get_quirk(
13176 const wuffs_sha256__hasher* self,
13177 uint32_t a_key);
13179 WUFFS_BASE__GENERATED_C_CODE
13180 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
13181 wuffs_sha256__hasher__set_quirk(
13182 wuffs_sha256__hasher* self,
13183 uint32_t a_key,
13184 uint64_t a_value);
13186 WUFFS_BASE__GENERATED_C_CODE
13187 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
13188 wuffs_sha256__hasher__update(
13189 wuffs_sha256__hasher* self,
13190 wuffs_base__slice_u8 a_x);
13192 WUFFS_BASE__GENERATED_C_CODE
13193 WUFFS_BASE__MAYBE_STATIC wuffs_base__bitvec256
13194 wuffs_sha256__hasher__update_bitvec256(
13195 wuffs_sha256__hasher* self,
13196 wuffs_base__slice_u8 a_x);
13198 WUFFS_BASE__GENERATED_C_CODE
13199 WUFFS_BASE__MAYBE_STATIC wuffs_base__bitvec256
13200 wuffs_sha256__hasher__checksum_bitvec256(
13201 const wuffs_sha256__hasher* self);
13203 #ifdef __cplusplus
13204 } // extern "C"
13205 #endif
13207 // ---------------- Struct Definitions
13209 // These structs' fields, and the sizeof them, are private implementation
13210 // details that aren't guaranteed to be stable across Wuffs versions.
13212 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
13214 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
13216 struct wuffs_sha256__hasher__struct {
13217 // Do not access the private_impl's or private_data's fields directly. There
13218 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
13219 // the wuffs_foo__bar__baz functions.
13221 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
13222 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
13224 struct {
13225 uint32_t magic;
13226 uint32_t active_coroutine;
13227 wuffs_base__vtable vtable_for__wuffs_base__hasher_bitvec256;
13228 wuffs_base__vtable null_vtable;
13230 uint64_t f_length_modulo_u64;
13231 bool f_length_overflows_u64;
13232 uint8_t f_padding0;
13233 uint8_t f_padding1;
13234 uint8_t f_padding2;
13235 uint32_t f_buf_len;
13236 uint8_t f_buf_data[64];
13237 uint32_t f_h0;
13238 uint32_t f_h1;
13239 uint32_t f_h2;
13240 uint32_t f_h3;
13241 uint32_t f_h4;
13242 uint32_t f_h5;
13243 uint32_t f_h6;
13244 uint32_t f_h7;
13245 } private_impl;
13247 #ifdef __cplusplus
13248 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
13249 using unique_ptr = std::unique_ptr<wuffs_sha256__hasher, wuffs_unique_ptr_deleter>;
13251 // On failure, the alloc_etc functions return nullptr. They don't throw.
13253 static inline unique_ptr
13254 alloc() {
13255 return unique_ptr(wuffs_sha256__hasher__alloc());
13258 static inline wuffs_base__hasher_bitvec256::unique_ptr
13259 alloc_as__wuffs_base__hasher_bitvec256() {
13260 return wuffs_base__hasher_bitvec256::unique_ptr(
13261 wuffs_sha256__hasher__alloc_as__wuffs_base__hasher_bitvec256());
13263 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
13265 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
13266 // Disallow constructing or copying an object via standard C++ mechanisms,
13267 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
13268 // size and field layout is not part of the public, stable, memory-safe API.
13269 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
13270 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
13271 // their first argument) rather than tweaking bar.private_impl.qux fields.
13273 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
13274 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
13275 // order to provide convenience methods. These forward on "this", so that you
13276 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
13277 wuffs_sha256__hasher__struct() = delete;
13278 wuffs_sha256__hasher__struct(const wuffs_sha256__hasher__struct&) = delete;
13279 wuffs_sha256__hasher__struct& operator=(
13280 const wuffs_sha256__hasher__struct&) = delete;
13281 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
13283 #if !defined(WUFFS_IMPLEMENTATION)
13284 // As above, the size of the struct is not part of the public API, and unless
13285 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
13286 // allocated, not stack allocated. Its size is not intended to be known at
13287 // compile time, but it is unfortunately divulged as a side effect of
13288 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
13289 // instead of "sizeof T", invoking the operator. To make the two values
13290 // different, so that passing the latter will be rejected by the initialize
13291 // function, we add an arbitrary amount of dead weight.
13292 uint8_t dead_weight[123000000]; // 123 MB.
13293 #endif // !defined(WUFFS_IMPLEMENTATION)
13295 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
13296 initialize(
13297 size_t sizeof_star_self,
13298 uint64_t wuffs_version,
13299 uint32_t options) {
13300 return wuffs_sha256__hasher__initialize(
13301 this, sizeof_star_self, wuffs_version, options);
13304 inline wuffs_base__hasher_bitvec256*
13305 upcast_as__wuffs_base__hasher_bitvec256() {
13306 return (wuffs_base__hasher_bitvec256*)this;
13309 inline uint64_t
13310 get_quirk(
13311 uint32_t a_key) const {
13312 return wuffs_sha256__hasher__get_quirk(this, a_key);
13315 inline wuffs_base__status
13316 set_quirk(
13317 uint32_t a_key,
13318 uint64_t a_value) {
13319 return wuffs_sha256__hasher__set_quirk(this, a_key, a_value);
13322 inline wuffs_base__empty_struct
13323 update(
13324 wuffs_base__slice_u8 a_x) {
13325 return wuffs_sha256__hasher__update(this, a_x);
13328 inline wuffs_base__bitvec256
13329 update_bitvec256(
13330 wuffs_base__slice_u8 a_x) {
13331 return wuffs_sha256__hasher__update_bitvec256(this, a_x);
13334 inline wuffs_base__bitvec256
13335 checksum_bitvec256() const {
13336 return wuffs_sha256__hasher__checksum_bitvec256(this);
13339 #endif // __cplusplus
13340 }; // struct wuffs_sha256__hasher__struct
13342 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
13344 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__SHA256) || defined(WUFFS_NONMONOLITHIC)
13346 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__TGA) || defined(WUFFS_NONMONOLITHIC)
13348 // ---------------- Status Codes
13350 extern const char wuffs_tga__error__bad_header[];
13351 extern const char wuffs_tga__error__bad_run_length_encoding[];
13352 extern const char wuffs_tga__error__truncated_input[];
13353 extern const char wuffs_tga__error__unsupported_tga_file[];
13355 // ---------------- Public Consts
13357 #define WUFFS_TGA__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0u
13359 // ---------------- Struct Declarations
13361 typedef struct wuffs_tga__decoder__struct wuffs_tga__decoder;
13363 #ifdef __cplusplus
13364 extern "C" {
13365 #endif
13367 // ---------------- Public Initializer Prototypes
13369 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
13370 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
13372 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
13373 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
13375 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
13376 wuffs_tga__decoder__initialize(
13377 wuffs_tga__decoder* self,
13378 size_t sizeof_star_self,
13379 uint64_t wuffs_version,
13380 uint32_t options);
13382 size_t
13383 sizeof__wuffs_tga__decoder(void);
13385 // ---------------- Allocs
13387 // These functions allocate and initialize Wuffs structs. They return NULL if
13388 // memory allocation fails. If they return non-NULL, there is no need to call
13389 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
13390 // calling free on the returned pointer. That pointer is effectively a C++
13391 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
13393 wuffs_tga__decoder*
13394 wuffs_tga__decoder__alloc(void);
13396 static inline wuffs_base__image_decoder*
13397 wuffs_tga__decoder__alloc_as__wuffs_base__image_decoder(void) {
13398 return (wuffs_base__image_decoder*)(wuffs_tga__decoder__alloc());
13401 // ---------------- Upcasts
13403 static inline wuffs_base__image_decoder*
13404 wuffs_tga__decoder__upcast_as__wuffs_base__image_decoder(
13405 wuffs_tga__decoder* p) {
13406 return (wuffs_base__image_decoder*)p;
13409 // ---------------- Public Function Prototypes
13411 WUFFS_BASE__GENERATED_C_CODE
13412 WUFFS_BASE__MAYBE_STATIC uint64_t
13413 wuffs_tga__decoder__get_quirk(
13414 const wuffs_tga__decoder* self,
13415 uint32_t a_key);
13417 WUFFS_BASE__GENERATED_C_CODE
13418 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
13419 wuffs_tga__decoder__set_quirk(
13420 wuffs_tga__decoder* self,
13421 uint32_t a_key,
13422 uint64_t a_value);
13424 WUFFS_BASE__GENERATED_C_CODE
13425 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
13426 wuffs_tga__decoder__decode_image_config(
13427 wuffs_tga__decoder* self,
13428 wuffs_base__image_config* a_dst,
13429 wuffs_base__io_buffer* a_src);
13431 WUFFS_BASE__GENERATED_C_CODE
13432 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
13433 wuffs_tga__decoder__decode_frame_config(
13434 wuffs_tga__decoder* self,
13435 wuffs_base__frame_config* a_dst,
13436 wuffs_base__io_buffer* a_src);
13438 WUFFS_BASE__GENERATED_C_CODE
13439 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
13440 wuffs_tga__decoder__decode_frame(
13441 wuffs_tga__decoder* self,
13442 wuffs_base__pixel_buffer* a_dst,
13443 wuffs_base__io_buffer* a_src,
13444 wuffs_base__pixel_blend a_blend,
13445 wuffs_base__slice_u8 a_workbuf,
13446 wuffs_base__decode_frame_options* a_opts);
13448 WUFFS_BASE__GENERATED_C_CODE
13449 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
13450 wuffs_tga__decoder__frame_dirty_rect(
13451 const wuffs_tga__decoder* self);
13453 WUFFS_BASE__GENERATED_C_CODE
13454 WUFFS_BASE__MAYBE_STATIC uint32_t
13455 wuffs_tga__decoder__num_animation_loops(
13456 const wuffs_tga__decoder* self);
13458 WUFFS_BASE__GENERATED_C_CODE
13459 WUFFS_BASE__MAYBE_STATIC uint64_t
13460 wuffs_tga__decoder__num_decoded_frame_configs(
13461 const wuffs_tga__decoder* self);
13463 WUFFS_BASE__GENERATED_C_CODE
13464 WUFFS_BASE__MAYBE_STATIC uint64_t
13465 wuffs_tga__decoder__num_decoded_frames(
13466 const wuffs_tga__decoder* self);
13468 WUFFS_BASE__GENERATED_C_CODE
13469 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
13470 wuffs_tga__decoder__restart_frame(
13471 wuffs_tga__decoder* self,
13472 uint64_t a_index,
13473 uint64_t a_io_position);
13475 WUFFS_BASE__GENERATED_C_CODE
13476 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
13477 wuffs_tga__decoder__set_report_metadata(
13478 wuffs_tga__decoder* self,
13479 uint32_t a_fourcc,
13480 bool a_report);
13482 WUFFS_BASE__GENERATED_C_CODE
13483 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
13484 wuffs_tga__decoder__tell_me_more(
13485 wuffs_tga__decoder* self,
13486 wuffs_base__io_buffer* a_dst,
13487 wuffs_base__more_information* a_minfo,
13488 wuffs_base__io_buffer* a_src);
13490 WUFFS_BASE__GENERATED_C_CODE
13491 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
13492 wuffs_tga__decoder__workbuf_len(
13493 const wuffs_tga__decoder* self);
13495 #ifdef __cplusplus
13496 } // extern "C"
13497 #endif
13499 // ---------------- Struct Definitions
13501 // These structs' fields, and the sizeof them, are private implementation
13502 // details that aren't guaranteed to be stable across Wuffs versions.
13504 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
13506 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
13508 struct wuffs_tga__decoder__struct {
13509 // Do not access the private_impl's or private_data's fields directly. There
13510 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
13511 // the wuffs_foo__bar__baz functions.
13513 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
13514 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
13516 struct {
13517 uint32_t magic;
13518 uint32_t active_coroutine;
13519 wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
13520 wuffs_base__vtable null_vtable;
13522 uint32_t f_width;
13523 uint32_t f_height;
13524 uint8_t f_call_sequence;
13525 uint8_t f_header_id_length;
13526 uint8_t f_header_color_map_type;
13527 uint8_t f_header_image_type;
13528 uint16_t f_header_color_map_first_entry_index;
13529 uint16_t f_header_color_map_length;
13530 uint8_t f_header_color_map_entry_size;
13531 uint8_t f_header_pixel_depth;
13532 uint8_t f_header_image_descriptor;
13533 bool f_opaque;
13534 uint32_t f_scratch_bytes_per_pixel;
13535 uint32_t f_src_bytes_per_pixel;
13536 uint32_t f_src_pixfmt;
13537 uint64_t f_frame_config_io_position;
13538 wuffs_base__pixel_swizzler f_swizzler;
13540 uint32_t p_decode_image_config;
13541 uint32_t p_do_decode_image_config;
13542 uint32_t p_decode_frame_config;
13543 uint32_t p_do_decode_frame_config;
13544 uint32_t p_decode_frame;
13545 uint32_t p_do_decode_frame;
13546 } private_impl;
13548 struct {
13549 uint8_t f_dst_palette[1024];
13550 uint8_t f_src_palette[1024];
13551 uint8_t f_scratch[4];
13553 struct {
13554 uint32_t v_i;
13555 uint64_t scratch;
13556 } s_do_decode_image_config;
13557 struct {
13558 uint64_t v_dst_bytes_per_pixel;
13559 uint32_t v_dst_x;
13560 uint32_t v_dst_y;
13561 uint64_t v_mark;
13562 uint32_t v_num_pixels32;
13563 uint32_t v_lit_length;
13564 uint32_t v_run_length;
13565 uint64_t v_num_dst_bytes;
13566 uint64_t scratch;
13567 } s_do_decode_frame;
13568 } private_data;
13570 #ifdef __cplusplus
13571 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
13572 using unique_ptr = std::unique_ptr<wuffs_tga__decoder, wuffs_unique_ptr_deleter>;
13574 // On failure, the alloc_etc functions return nullptr. They don't throw.
13576 static inline unique_ptr
13577 alloc() {
13578 return unique_ptr(wuffs_tga__decoder__alloc());
13581 static inline wuffs_base__image_decoder::unique_ptr
13582 alloc_as__wuffs_base__image_decoder() {
13583 return wuffs_base__image_decoder::unique_ptr(
13584 wuffs_tga__decoder__alloc_as__wuffs_base__image_decoder());
13586 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
13588 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
13589 // Disallow constructing or copying an object via standard C++ mechanisms,
13590 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
13591 // size and field layout is not part of the public, stable, memory-safe API.
13592 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
13593 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
13594 // their first argument) rather than tweaking bar.private_impl.qux fields.
13596 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
13597 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
13598 // order to provide convenience methods. These forward on "this", so that you
13599 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
13600 wuffs_tga__decoder__struct() = delete;
13601 wuffs_tga__decoder__struct(const wuffs_tga__decoder__struct&) = delete;
13602 wuffs_tga__decoder__struct& operator=(
13603 const wuffs_tga__decoder__struct&) = delete;
13604 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
13606 #if !defined(WUFFS_IMPLEMENTATION)
13607 // As above, the size of the struct is not part of the public API, and unless
13608 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
13609 // allocated, not stack allocated. Its size is not intended to be known at
13610 // compile time, but it is unfortunately divulged as a side effect of
13611 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
13612 // instead of "sizeof T", invoking the operator. To make the two values
13613 // different, so that passing the latter will be rejected by the initialize
13614 // function, we add an arbitrary amount of dead weight.
13615 uint8_t dead_weight[123000000]; // 123 MB.
13616 #endif // !defined(WUFFS_IMPLEMENTATION)
13618 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
13619 initialize(
13620 size_t sizeof_star_self,
13621 uint64_t wuffs_version,
13622 uint32_t options) {
13623 return wuffs_tga__decoder__initialize(
13624 this, sizeof_star_self, wuffs_version, options);
13627 inline wuffs_base__image_decoder*
13628 upcast_as__wuffs_base__image_decoder() {
13629 return (wuffs_base__image_decoder*)this;
13632 inline uint64_t
13633 get_quirk(
13634 uint32_t a_key) const {
13635 return wuffs_tga__decoder__get_quirk(this, a_key);
13638 inline wuffs_base__status
13639 set_quirk(
13640 uint32_t a_key,
13641 uint64_t a_value) {
13642 return wuffs_tga__decoder__set_quirk(this, a_key, a_value);
13645 inline wuffs_base__status
13646 decode_image_config(
13647 wuffs_base__image_config* a_dst,
13648 wuffs_base__io_buffer* a_src) {
13649 return wuffs_tga__decoder__decode_image_config(this, a_dst, a_src);
13652 inline wuffs_base__status
13653 decode_frame_config(
13654 wuffs_base__frame_config* a_dst,
13655 wuffs_base__io_buffer* a_src) {
13656 return wuffs_tga__decoder__decode_frame_config(this, a_dst, a_src);
13659 inline wuffs_base__status
13660 decode_frame(
13661 wuffs_base__pixel_buffer* a_dst,
13662 wuffs_base__io_buffer* a_src,
13663 wuffs_base__pixel_blend a_blend,
13664 wuffs_base__slice_u8 a_workbuf,
13665 wuffs_base__decode_frame_options* a_opts) {
13666 return wuffs_tga__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
13669 inline wuffs_base__rect_ie_u32
13670 frame_dirty_rect() const {
13671 return wuffs_tga__decoder__frame_dirty_rect(this);
13674 inline uint32_t
13675 num_animation_loops() const {
13676 return wuffs_tga__decoder__num_animation_loops(this);
13679 inline uint64_t
13680 num_decoded_frame_configs() const {
13681 return wuffs_tga__decoder__num_decoded_frame_configs(this);
13684 inline uint64_t
13685 num_decoded_frames() const {
13686 return wuffs_tga__decoder__num_decoded_frames(this);
13689 inline wuffs_base__status
13690 restart_frame(
13691 uint64_t a_index,
13692 uint64_t a_io_position) {
13693 return wuffs_tga__decoder__restart_frame(this, a_index, a_io_position);
13696 inline wuffs_base__empty_struct
13697 set_report_metadata(
13698 uint32_t a_fourcc,
13699 bool a_report) {
13700 return wuffs_tga__decoder__set_report_metadata(this, a_fourcc, a_report);
13703 inline wuffs_base__status
13704 tell_me_more(
13705 wuffs_base__io_buffer* a_dst,
13706 wuffs_base__more_information* a_minfo,
13707 wuffs_base__io_buffer* a_src) {
13708 return wuffs_tga__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
13711 inline wuffs_base__range_ii_u64
13712 workbuf_len() const {
13713 return wuffs_tga__decoder__workbuf_len(this);
13716 #endif // __cplusplus
13717 }; // struct wuffs_tga__decoder__struct
13719 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
13721 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__TGA) || defined(WUFFS_NONMONOLITHIC)
13723 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__VP8) || defined(WUFFS_NONMONOLITHIC)
13725 // ---------------- Status Codes
13727 // ---------------- Public Consts
13729 // ---------------- Struct Declarations
13731 typedef struct wuffs_vp8__placeholder__struct wuffs_vp8__placeholder;
13733 #ifdef __cplusplus
13734 extern "C" {
13735 #endif
13737 // ---------------- Public Initializer Prototypes
13739 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
13740 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
13742 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
13743 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
13745 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
13746 wuffs_vp8__placeholder__initialize(
13747 wuffs_vp8__placeholder* self,
13748 size_t sizeof_star_self,
13749 uint64_t wuffs_version,
13750 uint32_t options);
13752 size_t
13753 sizeof__wuffs_vp8__placeholder(void);
13755 // ---------------- Allocs
13757 // These functions allocate and initialize Wuffs structs. They return NULL if
13758 // memory allocation fails. If they return non-NULL, there is no need to call
13759 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
13760 // calling free on the returned pointer. That pointer is effectively a C++
13761 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
13763 wuffs_vp8__placeholder*
13764 wuffs_vp8__placeholder__alloc(void);
13766 // ---------------- Upcasts
13768 // ---------------- Public Function Prototypes
13770 #ifdef __cplusplus
13771 } // extern "C"
13772 #endif
13774 // ---------------- Struct Definitions
13776 // These structs' fields, and the sizeof them, are private implementation
13777 // details that aren't guaranteed to be stable across Wuffs versions.
13779 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
13781 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
13783 struct wuffs_vp8__placeholder__struct {
13784 // Do not access the private_impl's or private_data's fields directly. There
13785 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
13786 // the wuffs_foo__bar__baz functions.
13788 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
13789 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
13791 struct {
13792 uint32_t magic;
13793 uint32_t active_coroutine;
13794 wuffs_base__vtable null_vtable;
13796 uint32_t f_placeholder;
13797 } private_impl;
13799 #ifdef __cplusplus
13800 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
13801 using unique_ptr = std::unique_ptr<wuffs_vp8__placeholder, wuffs_unique_ptr_deleter>;
13803 // On failure, the alloc_etc functions return nullptr. They don't throw.
13805 static inline unique_ptr
13806 alloc() {
13807 return unique_ptr(wuffs_vp8__placeholder__alloc());
13809 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
13811 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
13812 // Disallow constructing or copying an object via standard C++ mechanisms,
13813 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
13814 // size and field layout is not part of the public, stable, memory-safe API.
13815 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
13816 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
13817 // their first argument) rather than tweaking bar.private_impl.qux fields.
13819 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
13820 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
13821 // order to provide convenience methods. These forward on "this", so that you
13822 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
13823 wuffs_vp8__placeholder__struct() = delete;
13824 wuffs_vp8__placeholder__struct(const wuffs_vp8__placeholder__struct&) = delete;
13825 wuffs_vp8__placeholder__struct& operator=(
13826 const wuffs_vp8__placeholder__struct&) = delete;
13827 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
13829 #if !defined(WUFFS_IMPLEMENTATION)
13830 // As above, the size of the struct is not part of the public API, and unless
13831 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
13832 // allocated, not stack allocated. Its size is not intended to be known at
13833 // compile time, but it is unfortunately divulged as a side effect of
13834 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
13835 // instead of "sizeof T", invoking the operator. To make the two values
13836 // different, so that passing the latter will be rejected by the initialize
13837 // function, we add an arbitrary amount of dead weight.
13838 uint8_t dead_weight[123000000]; // 123 MB.
13839 #endif // !defined(WUFFS_IMPLEMENTATION)
13841 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
13842 initialize(
13843 size_t sizeof_star_self,
13844 uint64_t wuffs_version,
13845 uint32_t options) {
13846 return wuffs_vp8__placeholder__initialize(
13847 this, sizeof_star_self, wuffs_version, options);
13850 #endif // __cplusplus
13851 }; // struct wuffs_vp8__placeholder__struct
13853 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
13855 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__VP8) || defined(WUFFS_NONMONOLITHIC)
13857 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP) || defined(WUFFS_NONMONOLITHIC)
13859 // ---------------- Status Codes
13861 extern const char wuffs_wbmp__error__bad_header[];
13862 extern const char wuffs_wbmp__error__truncated_input[];
13864 // ---------------- Public Consts
13866 #define WUFFS_WBMP__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0u
13868 // ---------------- Struct Declarations
13870 typedef struct wuffs_wbmp__decoder__struct wuffs_wbmp__decoder;
13872 #ifdef __cplusplus
13873 extern "C" {
13874 #endif
13876 // ---------------- Public Initializer Prototypes
13878 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
13879 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
13881 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
13882 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
13884 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
13885 wuffs_wbmp__decoder__initialize(
13886 wuffs_wbmp__decoder* self,
13887 size_t sizeof_star_self,
13888 uint64_t wuffs_version,
13889 uint32_t options);
13891 size_t
13892 sizeof__wuffs_wbmp__decoder(void);
13894 // ---------------- Allocs
13896 // These functions allocate and initialize Wuffs structs. They return NULL if
13897 // memory allocation fails. If they return non-NULL, there is no need to call
13898 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
13899 // calling free on the returned pointer. That pointer is effectively a C++
13900 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
13902 wuffs_wbmp__decoder*
13903 wuffs_wbmp__decoder__alloc(void);
13905 static inline wuffs_base__image_decoder*
13906 wuffs_wbmp__decoder__alloc_as__wuffs_base__image_decoder(void) {
13907 return (wuffs_base__image_decoder*)(wuffs_wbmp__decoder__alloc());
13910 // ---------------- Upcasts
13912 static inline wuffs_base__image_decoder*
13913 wuffs_wbmp__decoder__upcast_as__wuffs_base__image_decoder(
13914 wuffs_wbmp__decoder* p) {
13915 return (wuffs_base__image_decoder*)p;
13918 // ---------------- Public Function Prototypes
13920 WUFFS_BASE__GENERATED_C_CODE
13921 WUFFS_BASE__MAYBE_STATIC uint64_t
13922 wuffs_wbmp__decoder__get_quirk(
13923 const wuffs_wbmp__decoder* self,
13924 uint32_t a_key);
13926 WUFFS_BASE__GENERATED_C_CODE
13927 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
13928 wuffs_wbmp__decoder__set_quirk(
13929 wuffs_wbmp__decoder* self,
13930 uint32_t a_key,
13931 uint64_t a_value);
13933 WUFFS_BASE__GENERATED_C_CODE
13934 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
13935 wuffs_wbmp__decoder__decode_image_config(
13936 wuffs_wbmp__decoder* self,
13937 wuffs_base__image_config* a_dst,
13938 wuffs_base__io_buffer* a_src);
13940 WUFFS_BASE__GENERATED_C_CODE
13941 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
13942 wuffs_wbmp__decoder__decode_frame_config(
13943 wuffs_wbmp__decoder* self,
13944 wuffs_base__frame_config* a_dst,
13945 wuffs_base__io_buffer* a_src);
13947 WUFFS_BASE__GENERATED_C_CODE
13948 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
13949 wuffs_wbmp__decoder__decode_frame(
13950 wuffs_wbmp__decoder* self,
13951 wuffs_base__pixel_buffer* a_dst,
13952 wuffs_base__io_buffer* a_src,
13953 wuffs_base__pixel_blend a_blend,
13954 wuffs_base__slice_u8 a_workbuf,
13955 wuffs_base__decode_frame_options* a_opts);
13957 WUFFS_BASE__GENERATED_C_CODE
13958 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
13959 wuffs_wbmp__decoder__frame_dirty_rect(
13960 const wuffs_wbmp__decoder* self);
13962 WUFFS_BASE__GENERATED_C_CODE
13963 WUFFS_BASE__MAYBE_STATIC uint32_t
13964 wuffs_wbmp__decoder__num_animation_loops(
13965 const wuffs_wbmp__decoder* self);
13967 WUFFS_BASE__GENERATED_C_CODE
13968 WUFFS_BASE__MAYBE_STATIC uint64_t
13969 wuffs_wbmp__decoder__num_decoded_frame_configs(
13970 const wuffs_wbmp__decoder* self);
13972 WUFFS_BASE__GENERATED_C_CODE
13973 WUFFS_BASE__MAYBE_STATIC uint64_t
13974 wuffs_wbmp__decoder__num_decoded_frames(
13975 const wuffs_wbmp__decoder* self);
13977 WUFFS_BASE__GENERATED_C_CODE
13978 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
13979 wuffs_wbmp__decoder__restart_frame(
13980 wuffs_wbmp__decoder* self,
13981 uint64_t a_index,
13982 uint64_t a_io_position);
13984 WUFFS_BASE__GENERATED_C_CODE
13985 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
13986 wuffs_wbmp__decoder__set_report_metadata(
13987 wuffs_wbmp__decoder* self,
13988 uint32_t a_fourcc,
13989 bool a_report);
13991 WUFFS_BASE__GENERATED_C_CODE
13992 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
13993 wuffs_wbmp__decoder__tell_me_more(
13994 wuffs_wbmp__decoder* self,
13995 wuffs_base__io_buffer* a_dst,
13996 wuffs_base__more_information* a_minfo,
13997 wuffs_base__io_buffer* a_src);
13999 WUFFS_BASE__GENERATED_C_CODE
14000 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
14001 wuffs_wbmp__decoder__workbuf_len(
14002 const wuffs_wbmp__decoder* self);
14004 #ifdef __cplusplus
14005 } // extern "C"
14006 #endif
14008 // ---------------- Struct Definitions
14010 // These structs' fields, and the sizeof them, are private implementation
14011 // details that aren't guaranteed to be stable across Wuffs versions.
14013 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
14015 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
14017 struct wuffs_wbmp__decoder__struct {
14018 // Do not access the private_impl's or private_data's fields directly. There
14019 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
14020 // the wuffs_foo__bar__baz functions.
14022 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
14023 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
14025 struct {
14026 uint32_t magic;
14027 uint32_t active_coroutine;
14028 wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
14029 wuffs_base__vtable null_vtable;
14031 uint32_t f_width;
14032 uint32_t f_height;
14033 uint8_t f_call_sequence;
14034 uint64_t f_frame_config_io_position;
14035 wuffs_base__pixel_swizzler f_swizzler;
14037 uint32_t p_decode_image_config;
14038 uint32_t p_do_decode_image_config;
14039 uint32_t p_decode_frame_config;
14040 uint32_t p_do_decode_frame_config;
14041 uint32_t p_decode_frame;
14042 uint32_t p_do_decode_frame;
14043 } private_impl;
14045 struct {
14046 struct {
14047 uint32_t v_i;
14048 uint32_t v_p;
14049 } s_do_decode_image_config;
14050 struct {
14051 uint64_t v_dst_bytes_per_pixel;
14052 uint32_t v_dst_x;
14053 uint32_t v_dst_y;
14054 uint8_t v_src[1];
14055 uint8_t v_c8;
14056 } s_do_decode_frame;
14057 } private_data;
14059 #ifdef __cplusplus
14060 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
14061 using unique_ptr = std::unique_ptr<wuffs_wbmp__decoder, wuffs_unique_ptr_deleter>;
14063 // On failure, the alloc_etc functions return nullptr. They don't throw.
14065 static inline unique_ptr
14066 alloc() {
14067 return unique_ptr(wuffs_wbmp__decoder__alloc());
14070 static inline wuffs_base__image_decoder::unique_ptr
14071 alloc_as__wuffs_base__image_decoder() {
14072 return wuffs_base__image_decoder::unique_ptr(
14073 wuffs_wbmp__decoder__alloc_as__wuffs_base__image_decoder());
14075 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
14077 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
14078 // Disallow constructing or copying an object via standard C++ mechanisms,
14079 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
14080 // size and field layout is not part of the public, stable, memory-safe API.
14081 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
14082 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
14083 // their first argument) rather than tweaking bar.private_impl.qux fields.
14085 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
14086 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
14087 // order to provide convenience methods. These forward on "this", so that you
14088 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
14089 wuffs_wbmp__decoder__struct() = delete;
14090 wuffs_wbmp__decoder__struct(const wuffs_wbmp__decoder__struct&) = delete;
14091 wuffs_wbmp__decoder__struct& operator=(
14092 const wuffs_wbmp__decoder__struct&) = delete;
14093 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
14095 #if !defined(WUFFS_IMPLEMENTATION)
14096 // As above, the size of the struct is not part of the public API, and unless
14097 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
14098 // allocated, not stack allocated. Its size is not intended to be known at
14099 // compile time, but it is unfortunately divulged as a side effect of
14100 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
14101 // instead of "sizeof T", invoking the operator. To make the two values
14102 // different, so that passing the latter will be rejected by the initialize
14103 // function, we add an arbitrary amount of dead weight.
14104 uint8_t dead_weight[123000000]; // 123 MB.
14105 #endif // !defined(WUFFS_IMPLEMENTATION)
14107 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
14108 initialize(
14109 size_t sizeof_star_self,
14110 uint64_t wuffs_version,
14111 uint32_t options) {
14112 return wuffs_wbmp__decoder__initialize(
14113 this, sizeof_star_self, wuffs_version, options);
14116 inline wuffs_base__image_decoder*
14117 upcast_as__wuffs_base__image_decoder() {
14118 return (wuffs_base__image_decoder*)this;
14121 inline uint64_t
14122 get_quirk(
14123 uint32_t a_key) const {
14124 return wuffs_wbmp__decoder__get_quirk(this, a_key);
14127 inline wuffs_base__status
14128 set_quirk(
14129 uint32_t a_key,
14130 uint64_t a_value) {
14131 return wuffs_wbmp__decoder__set_quirk(this, a_key, a_value);
14134 inline wuffs_base__status
14135 decode_image_config(
14136 wuffs_base__image_config* a_dst,
14137 wuffs_base__io_buffer* a_src) {
14138 return wuffs_wbmp__decoder__decode_image_config(this, a_dst, a_src);
14141 inline wuffs_base__status
14142 decode_frame_config(
14143 wuffs_base__frame_config* a_dst,
14144 wuffs_base__io_buffer* a_src) {
14145 return wuffs_wbmp__decoder__decode_frame_config(this, a_dst, a_src);
14148 inline wuffs_base__status
14149 decode_frame(
14150 wuffs_base__pixel_buffer* a_dst,
14151 wuffs_base__io_buffer* a_src,
14152 wuffs_base__pixel_blend a_blend,
14153 wuffs_base__slice_u8 a_workbuf,
14154 wuffs_base__decode_frame_options* a_opts) {
14155 return wuffs_wbmp__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
14158 inline wuffs_base__rect_ie_u32
14159 frame_dirty_rect() const {
14160 return wuffs_wbmp__decoder__frame_dirty_rect(this);
14163 inline uint32_t
14164 num_animation_loops() const {
14165 return wuffs_wbmp__decoder__num_animation_loops(this);
14168 inline uint64_t
14169 num_decoded_frame_configs() const {
14170 return wuffs_wbmp__decoder__num_decoded_frame_configs(this);
14173 inline uint64_t
14174 num_decoded_frames() const {
14175 return wuffs_wbmp__decoder__num_decoded_frames(this);
14178 inline wuffs_base__status
14179 restart_frame(
14180 uint64_t a_index,
14181 uint64_t a_io_position) {
14182 return wuffs_wbmp__decoder__restart_frame(this, a_index, a_io_position);
14185 inline wuffs_base__empty_struct
14186 set_report_metadata(
14187 uint32_t a_fourcc,
14188 bool a_report) {
14189 return wuffs_wbmp__decoder__set_report_metadata(this, a_fourcc, a_report);
14192 inline wuffs_base__status
14193 tell_me_more(
14194 wuffs_base__io_buffer* a_dst,
14195 wuffs_base__more_information* a_minfo,
14196 wuffs_base__io_buffer* a_src) {
14197 return wuffs_wbmp__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
14200 inline wuffs_base__range_ii_u64
14201 workbuf_len() const {
14202 return wuffs_wbmp__decoder__workbuf_len(this);
14205 #endif // __cplusplus
14206 }; // struct wuffs_wbmp__decoder__struct
14208 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
14210 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP) || defined(WUFFS_NONMONOLITHIC)
14212 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WEBP) || defined(WUFFS_NONMONOLITHIC)
14214 // ---------------- Status Codes
14216 extern const char wuffs_webp__error__bad_huffman_code_over_subscribed[];
14217 extern const char wuffs_webp__error__bad_huffman_code_under_subscribed[];
14218 extern const char wuffs_webp__error__bad_huffman_code[];
14219 extern const char wuffs_webp__error__bad_back_reference[];
14220 extern const char wuffs_webp__error__bad_color_cache[];
14221 extern const char wuffs_webp__error__bad_header[];
14222 extern const char wuffs_webp__error__bad_transform[];
14223 extern const char wuffs_webp__error__short_chunk[];
14224 extern const char wuffs_webp__error__truncated_input[];
14225 extern const char wuffs_webp__error__unsupported_number_of_huffman_groups[];
14226 extern const char wuffs_webp__error__unsupported_transform_after_color_indexing_transform[];
14227 extern const char wuffs_webp__error__unsupported_webp_file[];
14229 // ---------------- Public Consts
14231 #define WUFFS_WEBP__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0u
14233 // ---------------- Struct Declarations
14235 typedef struct wuffs_webp__decoder__struct wuffs_webp__decoder;
14237 #ifdef __cplusplus
14238 extern "C" {
14239 #endif
14241 // ---------------- Public Initializer Prototypes
14243 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
14244 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
14246 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
14247 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
14249 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
14250 wuffs_webp__decoder__initialize(
14251 wuffs_webp__decoder* self,
14252 size_t sizeof_star_self,
14253 uint64_t wuffs_version,
14254 uint32_t options);
14256 size_t
14257 sizeof__wuffs_webp__decoder(void);
14259 // ---------------- Allocs
14261 // These functions allocate and initialize Wuffs structs. They return NULL if
14262 // memory allocation fails. If they return non-NULL, there is no need to call
14263 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
14264 // calling free on the returned pointer. That pointer is effectively a C++
14265 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
14267 wuffs_webp__decoder*
14268 wuffs_webp__decoder__alloc(void);
14270 static inline wuffs_base__image_decoder*
14271 wuffs_webp__decoder__alloc_as__wuffs_base__image_decoder(void) {
14272 return (wuffs_base__image_decoder*)(wuffs_webp__decoder__alloc());
14275 // ---------------- Upcasts
14277 static inline wuffs_base__image_decoder*
14278 wuffs_webp__decoder__upcast_as__wuffs_base__image_decoder(
14279 wuffs_webp__decoder* p) {
14280 return (wuffs_base__image_decoder*)p;
14283 // ---------------- Public Function Prototypes
14285 WUFFS_BASE__GENERATED_C_CODE
14286 WUFFS_BASE__MAYBE_STATIC uint64_t
14287 wuffs_webp__decoder__get_quirk(
14288 const wuffs_webp__decoder* self,
14289 uint32_t a_key);
14291 WUFFS_BASE__GENERATED_C_CODE
14292 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
14293 wuffs_webp__decoder__set_quirk(
14294 wuffs_webp__decoder* self,
14295 uint32_t a_key,
14296 uint64_t a_value);
14298 WUFFS_BASE__GENERATED_C_CODE
14299 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
14300 wuffs_webp__decoder__decode_image_config(
14301 wuffs_webp__decoder* self,
14302 wuffs_base__image_config* a_dst,
14303 wuffs_base__io_buffer* a_src);
14305 WUFFS_BASE__GENERATED_C_CODE
14306 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
14307 wuffs_webp__decoder__decode_frame_config(
14308 wuffs_webp__decoder* self,
14309 wuffs_base__frame_config* a_dst,
14310 wuffs_base__io_buffer* a_src);
14312 WUFFS_BASE__GENERATED_C_CODE
14313 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
14314 wuffs_webp__decoder__decode_frame(
14315 wuffs_webp__decoder* self,
14316 wuffs_base__pixel_buffer* a_dst,
14317 wuffs_base__io_buffer* a_src,
14318 wuffs_base__pixel_blend a_blend,
14319 wuffs_base__slice_u8 a_workbuf,
14320 wuffs_base__decode_frame_options* a_opts);
14322 WUFFS_BASE__GENERATED_C_CODE
14323 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
14324 wuffs_webp__decoder__frame_dirty_rect(
14325 const wuffs_webp__decoder* self);
14327 WUFFS_BASE__GENERATED_C_CODE
14328 WUFFS_BASE__MAYBE_STATIC uint32_t
14329 wuffs_webp__decoder__num_animation_loops(
14330 const wuffs_webp__decoder* self);
14332 WUFFS_BASE__GENERATED_C_CODE
14333 WUFFS_BASE__MAYBE_STATIC uint64_t
14334 wuffs_webp__decoder__num_decoded_frame_configs(
14335 const wuffs_webp__decoder* self);
14337 WUFFS_BASE__GENERATED_C_CODE
14338 WUFFS_BASE__MAYBE_STATIC uint64_t
14339 wuffs_webp__decoder__num_decoded_frames(
14340 const wuffs_webp__decoder* self);
14342 WUFFS_BASE__GENERATED_C_CODE
14343 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
14344 wuffs_webp__decoder__restart_frame(
14345 wuffs_webp__decoder* self,
14346 uint64_t a_index,
14347 uint64_t a_io_position);
14349 WUFFS_BASE__GENERATED_C_CODE
14350 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
14351 wuffs_webp__decoder__set_report_metadata(
14352 wuffs_webp__decoder* self,
14353 uint32_t a_fourcc,
14354 bool a_report);
14356 WUFFS_BASE__GENERATED_C_CODE
14357 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
14358 wuffs_webp__decoder__tell_me_more(
14359 wuffs_webp__decoder* self,
14360 wuffs_base__io_buffer* a_dst,
14361 wuffs_base__more_information* a_minfo,
14362 wuffs_base__io_buffer* a_src);
14364 WUFFS_BASE__GENERATED_C_CODE
14365 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
14366 wuffs_webp__decoder__workbuf_len(
14367 const wuffs_webp__decoder* self);
14369 #ifdef __cplusplus
14370 } // extern "C"
14371 #endif
14373 // ---------------- Struct Definitions
14375 // These structs' fields, and the sizeof them, are private implementation
14376 // details that aren't guaranteed to be stable across Wuffs versions.
14378 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
14380 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
14382 struct wuffs_webp__decoder__struct {
14383 // Do not access the private_impl's or private_data's fields directly. There
14384 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
14385 // the wuffs_foo__bar__baz functions.
14387 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
14388 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
14390 struct {
14391 uint32_t magic;
14392 uint32_t active_coroutine;
14393 wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
14394 wuffs_base__vtable null_vtable;
14396 uint32_t f_pixfmt;
14397 uint32_t f_width;
14398 uint32_t f_height;
14399 uint8_t f_call_sequence;
14400 uint8_t f_code_length_code_lengths[19];
14401 bool f_sub_chunk_has_padding;
14402 uint64_t f_frame_config_io_position;
14403 uint32_t f_riff_chunk_length;
14404 uint32_t f_sub_chunk_length;
14405 uint32_t f_bits;
14406 uint32_t f_n_bits;
14407 bool f_seen_transform[4];
14408 uint8_t f_transform_type[4];
14409 uint8_t f_transform_tile_size_log2[4];
14410 uint32_t f_n_transforms;
14411 uint32_t f_color_cache_bits;
14412 uint32_t f_overall_color_cache_bits;
14413 uint32_t f_overall_tile_size_log2;
14414 uint32_t f_overall_n_huffman_groups;
14415 uint32_t f_ht_n_symbols;
14416 uint32_t f_ht_code_lengths_remaining;
14417 uint32_t f_color_indexing_palette_size;
14418 uint32_t f_color_indexing_width;
14419 uint32_t f_workbuf_offset_for_transform[4];
14420 uint32_t f_workbuf_offset_for_color_indexing;
14421 wuffs_base__pixel_swizzler f_swizzler;
14423 uint32_t p_decode_huffman_groups;
14424 uint32_t p_decode_huffman_tree;
14425 uint32_t p_decode_huffman_tree_simple;
14426 uint32_t p_decode_code_length_code_lengths;
14427 uint32_t p_build_code_lengths;
14428 uint32_t p_decode_pixels_slow;
14429 uint32_t p_decode_image_config;
14430 uint32_t p_do_decode_image_config;
14431 uint32_t p_do_decode_image_config_limited;
14432 uint32_t p_do_decode_image_config_limited_vp8l;
14433 uint32_t p_decode_frame_config;
14434 uint32_t p_do_decode_frame_config;
14435 uint32_t p_decode_frame;
14436 uint32_t p_do_decode_frame;
14437 uint32_t p_decode_transform;
14438 uint32_t p_decode_color_cache_parameters;
14439 uint32_t p_decode_hg_table;
14440 uint32_t p_decode_pixels;
14441 } private_impl;
14443 struct {
14444 uint8_t f_palette[1024];
14445 uint32_t f_color_cache[2048];
14446 uint16_t f_codes[2328];
14447 uint16_t f_code_lengths[2328];
14448 uint16_t f_code_lengths_huffman_nodes[37];
14449 uint16_t f_huffman_nodes[256][6267];
14451 struct {
14452 uint32_t v_hg;
14453 uint32_t v_ht;
14454 } s_decode_huffman_groups;
14455 struct {
14456 uint32_t v_use_second_symbol;
14457 uint32_t v_first_symbol_n_bits;
14458 uint32_t v_symbol0;
14459 uint32_t v_base_offset;
14460 } s_decode_huffman_tree_simple;
14461 struct {
14462 uint32_t v_n_codes;
14463 uint32_t v_i;
14464 } s_decode_code_length_code_lengths;
14465 struct {
14466 uint32_t v_length_n_bits;
14467 uint16_t v_prev_code_length;
14468 uint32_t v_s;
14469 uint32_t v_s_max;
14470 uint16_t v_node;
14471 uint16_t v_repeat_value;
14472 uint32_t v_repeat_n_bits;
14473 } s_build_code_lengths;
14474 struct {
14475 uint64_t v_p;
14476 uint64_t v_p_max;
14477 uint32_t v_tile_size_log2;
14478 uint32_t v_width_in_tiles;
14479 uint32_t v_x;
14480 uint32_t v_y;
14481 uint32_t v_hg;
14482 uint16_t v_node;
14483 uint32_t v_color;
14484 uint32_t v_back_ref_len_n_bits;
14485 uint32_t v_back_ref_len_minus_1;
14486 uint32_t v_back_ref_dist_n_bits;
14487 uint32_t v_back_ref_dist_premap_minus_1;
14488 uint64_t v_color_cache_p;
14489 } s_decode_pixels_slow;
14490 struct {
14491 uint64_t scratch;
14492 } s_do_decode_image_config;
14493 struct {
14494 uint64_t scratch;
14495 } s_do_decode_image_config_limited;
14496 struct {
14497 uint64_t scratch;
14498 } s_do_decode_image_config_limited_vp8l;
14499 struct {
14500 uint32_t v_width;
14501 } s_do_decode_frame;
14502 struct {
14503 uint32_t v_transform_type;
14504 uint32_t v_tile_size_log2;
14505 } s_decode_transform;
14506 struct {
14507 uint32_t v_tile_size_log2;
14508 } s_decode_hg_table;
14509 } private_data;
14511 #ifdef __cplusplus
14512 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
14513 using unique_ptr = std::unique_ptr<wuffs_webp__decoder, wuffs_unique_ptr_deleter>;
14515 // On failure, the alloc_etc functions return nullptr. They don't throw.
14517 static inline unique_ptr
14518 alloc() {
14519 return unique_ptr(wuffs_webp__decoder__alloc());
14522 static inline wuffs_base__image_decoder::unique_ptr
14523 alloc_as__wuffs_base__image_decoder() {
14524 return wuffs_base__image_decoder::unique_ptr(
14525 wuffs_webp__decoder__alloc_as__wuffs_base__image_decoder());
14527 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
14529 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
14530 // Disallow constructing or copying an object via standard C++ mechanisms,
14531 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
14532 // size and field layout is not part of the public, stable, memory-safe API.
14533 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
14534 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
14535 // their first argument) rather than tweaking bar.private_impl.qux fields.
14537 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
14538 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
14539 // order to provide convenience methods. These forward on "this", so that you
14540 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
14541 wuffs_webp__decoder__struct() = delete;
14542 wuffs_webp__decoder__struct(const wuffs_webp__decoder__struct&) = delete;
14543 wuffs_webp__decoder__struct& operator=(
14544 const wuffs_webp__decoder__struct&) = delete;
14545 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
14547 #if !defined(WUFFS_IMPLEMENTATION)
14548 // As above, the size of the struct is not part of the public API, and unless
14549 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
14550 // allocated, not stack allocated. Its size is not intended to be known at
14551 // compile time, but it is unfortunately divulged as a side effect of
14552 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
14553 // instead of "sizeof T", invoking the operator. To make the two values
14554 // different, so that passing the latter will be rejected by the initialize
14555 // function, we add an arbitrary amount of dead weight.
14556 uint8_t dead_weight[123000000]; // 123 MB.
14557 #endif // !defined(WUFFS_IMPLEMENTATION)
14559 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
14560 initialize(
14561 size_t sizeof_star_self,
14562 uint64_t wuffs_version,
14563 uint32_t options) {
14564 return wuffs_webp__decoder__initialize(
14565 this, sizeof_star_self, wuffs_version, options);
14568 inline wuffs_base__image_decoder*
14569 upcast_as__wuffs_base__image_decoder() {
14570 return (wuffs_base__image_decoder*)this;
14573 inline uint64_t
14574 get_quirk(
14575 uint32_t a_key) const {
14576 return wuffs_webp__decoder__get_quirk(this, a_key);
14579 inline wuffs_base__status
14580 set_quirk(
14581 uint32_t a_key,
14582 uint64_t a_value) {
14583 return wuffs_webp__decoder__set_quirk(this, a_key, a_value);
14586 inline wuffs_base__status
14587 decode_image_config(
14588 wuffs_base__image_config* a_dst,
14589 wuffs_base__io_buffer* a_src) {
14590 return wuffs_webp__decoder__decode_image_config(this, a_dst, a_src);
14593 inline wuffs_base__status
14594 decode_frame_config(
14595 wuffs_base__frame_config* a_dst,
14596 wuffs_base__io_buffer* a_src) {
14597 return wuffs_webp__decoder__decode_frame_config(this, a_dst, a_src);
14600 inline wuffs_base__status
14601 decode_frame(
14602 wuffs_base__pixel_buffer* a_dst,
14603 wuffs_base__io_buffer* a_src,
14604 wuffs_base__pixel_blend a_blend,
14605 wuffs_base__slice_u8 a_workbuf,
14606 wuffs_base__decode_frame_options* a_opts) {
14607 return wuffs_webp__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
14610 inline wuffs_base__rect_ie_u32
14611 frame_dirty_rect() const {
14612 return wuffs_webp__decoder__frame_dirty_rect(this);
14615 inline uint32_t
14616 num_animation_loops() const {
14617 return wuffs_webp__decoder__num_animation_loops(this);
14620 inline uint64_t
14621 num_decoded_frame_configs() const {
14622 return wuffs_webp__decoder__num_decoded_frame_configs(this);
14625 inline uint64_t
14626 num_decoded_frames() const {
14627 return wuffs_webp__decoder__num_decoded_frames(this);
14630 inline wuffs_base__status
14631 restart_frame(
14632 uint64_t a_index,
14633 uint64_t a_io_position) {
14634 return wuffs_webp__decoder__restart_frame(this, a_index, a_io_position);
14637 inline wuffs_base__empty_struct
14638 set_report_metadata(
14639 uint32_t a_fourcc,
14640 bool a_report) {
14641 return wuffs_webp__decoder__set_report_metadata(this, a_fourcc, a_report);
14644 inline wuffs_base__status
14645 tell_me_more(
14646 wuffs_base__io_buffer* a_dst,
14647 wuffs_base__more_information* a_minfo,
14648 wuffs_base__io_buffer* a_src) {
14649 return wuffs_webp__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
14652 inline wuffs_base__range_ii_u64
14653 workbuf_len() const {
14654 return wuffs_webp__decoder__workbuf_len(this);
14657 #endif // __cplusplus
14658 }; // struct wuffs_webp__decoder__struct
14660 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
14662 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WEBP) || defined(WUFFS_NONMONOLITHIC)
14664 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH32) || defined(WUFFS_NONMONOLITHIC)
14666 // ---------------- Status Codes
14668 // ---------------- Public Consts
14670 // ---------------- Struct Declarations
14672 typedef struct wuffs_xxhash32__hasher__struct wuffs_xxhash32__hasher;
14674 #ifdef __cplusplus
14675 extern "C" {
14676 #endif
14678 // ---------------- Public Initializer Prototypes
14680 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
14681 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
14683 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
14684 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
14686 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
14687 wuffs_xxhash32__hasher__initialize(
14688 wuffs_xxhash32__hasher* self,
14689 size_t sizeof_star_self,
14690 uint64_t wuffs_version,
14691 uint32_t options);
14693 size_t
14694 sizeof__wuffs_xxhash32__hasher(void);
14696 // ---------------- Allocs
14698 // These functions allocate and initialize Wuffs structs. They return NULL if
14699 // memory allocation fails. If they return non-NULL, there is no need to call
14700 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
14701 // calling free on the returned pointer. That pointer is effectively a C++
14702 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
14704 wuffs_xxhash32__hasher*
14705 wuffs_xxhash32__hasher__alloc(void);
14707 static inline wuffs_base__hasher_u32*
14708 wuffs_xxhash32__hasher__alloc_as__wuffs_base__hasher_u32(void) {
14709 return (wuffs_base__hasher_u32*)(wuffs_xxhash32__hasher__alloc());
14712 // ---------------- Upcasts
14714 static inline wuffs_base__hasher_u32*
14715 wuffs_xxhash32__hasher__upcast_as__wuffs_base__hasher_u32(
14716 wuffs_xxhash32__hasher* p) {
14717 return (wuffs_base__hasher_u32*)p;
14720 // ---------------- Public Function Prototypes
14722 WUFFS_BASE__GENERATED_C_CODE
14723 WUFFS_BASE__MAYBE_STATIC uint64_t
14724 wuffs_xxhash32__hasher__get_quirk(
14725 const wuffs_xxhash32__hasher* self,
14726 uint32_t a_key);
14728 WUFFS_BASE__GENERATED_C_CODE
14729 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
14730 wuffs_xxhash32__hasher__set_quirk(
14731 wuffs_xxhash32__hasher* self,
14732 uint32_t a_key,
14733 uint64_t a_value);
14735 WUFFS_BASE__GENERATED_C_CODE
14736 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
14737 wuffs_xxhash32__hasher__update(
14738 wuffs_xxhash32__hasher* self,
14739 wuffs_base__slice_u8 a_x);
14741 WUFFS_BASE__GENERATED_C_CODE
14742 WUFFS_BASE__MAYBE_STATIC uint32_t
14743 wuffs_xxhash32__hasher__update_u32(
14744 wuffs_xxhash32__hasher* self,
14745 wuffs_base__slice_u8 a_x);
14747 WUFFS_BASE__GENERATED_C_CODE
14748 WUFFS_BASE__MAYBE_STATIC uint32_t
14749 wuffs_xxhash32__hasher__checksum_u32(
14750 const wuffs_xxhash32__hasher* self);
14752 #ifdef __cplusplus
14753 } // extern "C"
14754 #endif
14756 // ---------------- Struct Definitions
14758 // These structs' fields, and the sizeof them, are private implementation
14759 // details that aren't guaranteed to be stable across Wuffs versions.
14761 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
14763 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
14765 struct wuffs_xxhash32__hasher__struct {
14766 // Do not access the private_impl's or private_data's fields directly. There
14767 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
14768 // the wuffs_foo__bar__baz functions.
14770 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
14771 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
14773 struct {
14774 uint32_t magic;
14775 uint32_t active_coroutine;
14776 wuffs_base__vtable vtable_for__wuffs_base__hasher_u32;
14777 wuffs_base__vtable null_vtable;
14779 uint32_t f_length_modulo_u32;
14780 bool f_length_overflows_u32;
14781 uint8_t f_padding0;
14782 uint8_t f_padding1;
14783 uint8_t f_buf_len;
14784 uint8_t f_buf_data[16];
14785 uint32_t f_v0;
14786 uint32_t f_v1;
14787 uint32_t f_v2;
14788 uint32_t f_v3;
14789 } private_impl;
14791 #ifdef __cplusplus
14792 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
14793 using unique_ptr = std::unique_ptr<wuffs_xxhash32__hasher, wuffs_unique_ptr_deleter>;
14795 // On failure, the alloc_etc functions return nullptr. They don't throw.
14797 static inline unique_ptr
14798 alloc() {
14799 return unique_ptr(wuffs_xxhash32__hasher__alloc());
14802 static inline wuffs_base__hasher_u32::unique_ptr
14803 alloc_as__wuffs_base__hasher_u32() {
14804 return wuffs_base__hasher_u32::unique_ptr(
14805 wuffs_xxhash32__hasher__alloc_as__wuffs_base__hasher_u32());
14807 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
14809 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
14810 // Disallow constructing or copying an object via standard C++ mechanisms,
14811 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
14812 // size and field layout is not part of the public, stable, memory-safe API.
14813 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
14814 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
14815 // their first argument) rather than tweaking bar.private_impl.qux fields.
14817 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
14818 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
14819 // order to provide convenience methods. These forward on "this", so that you
14820 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
14821 wuffs_xxhash32__hasher__struct() = delete;
14822 wuffs_xxhash32__hasher__struct(const wuffs_xxhash32__hasher__struct&) = delete;
14823 wuffs_xxhash32__hasher__struct& operator=(
14824 const wuffs_xxhash32__hasher__struct&) = delete;
14825 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
14827 #if !defined(WUFFS_IMPLEMENTATION)
14828 // As above, the size of the struct is not part of the public API, and unless
14829 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
14830 // allocated, not stack allocated. Its size is not intended to be known at
14831 // compile time, but it is unfortunately divulged as a side effect of
14832 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
14833 // instead of "sizeof T", invoking the operator. To make the two values
14834 // different, so that passing the latter will be rejected by the initialize
14835 // function, we add an arbitrary amount of dead weight.
14836 uint8_t dead_weight[123000000]; // 123 MB.
14837 #endif // !defined(WUFFS_IMPLEMENTATION)
14839 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
14840 initialize(
14841 size_t sizeof_star_self,
14842 uint64_t wuffs_version,
14843 uint32_t options) {
14844 return wuffs_xxhash32__hasher__initialize(
14845 this, sizeof_star_self, wuffs_version, options);
14848 inline wuffs_base__hasher_u32*
14849 upcast_as__wuffs_base__hasher_u32() {
14850 return (wuffs_base__hasher_u32*)this;
14853 inline uint64_t
14854 get_quirk(
14855 uint32_t a_key) const {
14856 return wuffs_xxhash32__hasher__get_quirk(this, a_key);
14859 inline wuffs_base__status
14860 set_quirk(
14861 uint32_t a_key,
14862 uint64_t a_value) {
14863 return wuffs_xxhash32__hasher__set_quirk(this, a_key, a_value);
14866 inline wuffs_base__empty_struct
14867 update(
14868 wuffs_base__slice_u8 a_x) {
14869 return wuffs_xxhash32__hasher__update(this, a_x);
14872 inline uint32_t
14873 update_u32(
14874 wuffs_base__slice_u8 a_x) {
14875 return wuffs_xxhash32__hasher__update_u32(this, a_x);
14878 inline uint32_t
14879 checksum_u32() const {
14880 return wuffs_xxhash32__hasher__checksum_u32(this);
14883 #endif // __cplusplus
14884 }; // struct wuffs_xxhash32__hasher__struct
14886 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
14888 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH32) || defined(WUFFS_NONMONOLITHIC)
14890 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH64) || defined(WUFFS_NONMONOLITHIC)
14892 // ---------------- Status Codes
14894 // ---------------- Public Consts
14896 // ---------------- Struct Declarations
14898 typedef struct wuffs_xxhash64__hasher__struct wuffs_xxhash64__hasher;
14900 #ifdef __cplusplus
14901 extern "C" {
14902 #endif
14904 // ---------------- Public Initializer Prototypes
14906 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
14907 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
14909 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
14910 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
14912 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
14913 wuffs_xxhash64__hasher__initialize(
14914 wuffs_xxhash64__hasher* self,
14915 size_t sizeof_star_self,
14916 uint64_t wuffs_version,
14917 uint32_t options);
14919 size_t
14920 sizeof__wuffs_xxhash64__hasher(void);
14922 // ---------------- Allocs
14924 // These functions allocate and initialize Wuffs structs. They return NULL if
14925 // memory allocation fails. If they return non-NULL, there is no need to call
14926 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
14927 // calling free on the returned pointer. That pointer is effectively a C++
14928 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
14930 wuffs_xxhash64__hasher*
14931 wuffs_xxhash64__hasher__alloc(void);
14933 static inline wuffs_base__hasher_u64*
14934 wuffs_xxhash64__hasher__alloc_as__wuffs_base__hasher_u64(void) {
14935 return (wuffs_base__hasher_u64*)(wuffs_xxhash64__hasher__alloc());
14938 // ---------------- Upcasts
14940 static inline wuffs_base__hasher_u64*
14941 wuffs_xxhash64__hasher__upcast_as__wuffs_base__hasher_u64(
14942 wuffs_xxhash64__hasher* p) {
14943 return (wuffs_base__hasher_u64*)p;
14946 // ---------------- Public Function Prototypes
14948 WUFFS_BASE__GENERATED_C_CODE
14949 WUFFS_BASE__MAYBE_STATIC uint64_t
14950 wuffs_xxhash64__hasher__get_quirk(
14951 const wuffs_xxhash64__hasher* self,
14952 uint32_t a_key);
14954 WUFFS_BASE__GENERATED_C_CODE
14955 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
14956 wuffs_xxhash64__hasher__set_quirk(
14957 wuffs_xxhash64__hasher* self,
14958 uint32_t a_key,
14959 uint64_t a_value);
14961 WUFFS_BASE__GENERATED_C_CODE
14962 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
14963 wuffs_xxhash64__hasher__update(
14964 wuffs_xxhash64__hasher* self,
14965 wuffs_base__slice_u8 a_x);
14967 WUFFS_BASE__GENERATED_C_CODE
14968 WUFFS_BASE__MAYBE_STATIC uint64_t
14969 wuffs_xxhash64__hasher__update_u64(
14970 wuffs_xxhash64__hasher* self,
14971 wuffs_base__slice_u8 a_x);
14973 WUFFS_BASE__GENERATED_C_CODE
14974 WUFFS_BASE__MAYBE_STATIC uint64_t
14975 wuffs_xxhash64__hasher__checksum_u64(
14976 const wuffs_xxhash64__hasher* self);
14978 #ifdef __cplusplus
14979 } // extern "C"
14980 #endif
14982 // ---------------- Struct Definitions
14984 // These structs' fields, and the sizeof them, are private implementation
14985 // details that aren't guaranteed to be stable across Wuffs versions.
14987 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
14989 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
14991 struct wuffs_xxhash64__hasher__struct {
14992 // Do not access the private_impl's or private_data's fields directly. There
14993 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
14994 // the wuffs_foo__bar__baz functions.
14996 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
14997 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
14999 struct {
15000 uint32_t magic;
15001 uint32_t active_coroutine;
15002 wuffs_base__vtable vtable_for__wuffs_base__hasher_u64;
15003 wuffs_base__vtable null_vtable;
15005 uint64_t f_length_modulo_u64;
15006 bool f_length_overflows_u64;
15007 uint8_t f_padding0;
15008 uint8_t f_padding1;
15009 uint8_t f_padding2;
15010 uint32_t f_buf_len;
15011 uint8_t f_buf_data[32];
15012 uint64_t f_v0;
15013 uint64_t f_v1;
15014 uint64_t f_v2;
15015 uint64_t f_v3;
15016 } private_impl;
15018 #ifdef __cplusplus
15019 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
15020 using unique_ptr = std::unique_ptr<wuffs_xxhash64__hasher, wuffs_unique_ptr_deleter>;
15022 // On failure, the alloc_etc functions return nullptr. They don't throw.
15024 static inline unique_ptr
15025 alloc() {
15026 return unique_ptr(wuffs_xxhash64__hasher__alloc());
15029 static inline wuffs_base__hasher_u64::unique_ptr
15030 alloc_as__wuffs_base__hasher_u64() {
15031 return wuffs_base__hasher_u64::unique_ptr(
15032 wuffs_xxhash64__hasher__alloc_as__wuffs_base__hasher_u64());
15034 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
15036 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
15037 // Disallow constructing or copying an object via standard C++ mechanisms,
15038 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
15039 // size and field layout is not part of the public, stable, memory-safe API.
15040 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
15041 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
15042 // their first argument) rather than tweaking bar.private_impl.qux fields.
15044 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
15045 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
15046 // order to provide convenience methods. These forward on "this", so that you
15047 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
15048 wuffs_xxhash64__hasher__struct() = delete;
15049 wuffs_xxhash64__hasher__struct(const wuffs_xxhash64__hasher__struct&) = delete;
15050 wuffs_xxhash64__hasher__struct& operator=(
15051 const wuffs_xxhash64__hasher__struct&) = delete;
15052 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
15054 #if !defined(WUFFS_IMPLEMENTATION)
15055 // As above, the size of the struct is not part of the public API, and unless
15056 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
15057 // allocated, not stack allocated. Its size is not intended to be known at
15058 // compile time, but it is unfortunately divulged as a side effect of
15059 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
15060 // instead of "sizeof T", invoking the operator. To make the two values
15061 // different, so that passing the latter will be rejected by the initialize
15062 // function, we add an arbitrary amount of dead weight.
15063 uint8_t dead_weight[123000000]; // 123 MB.
15064 #endif // !defined(WUFFS_IMPLEMENTATION)
15066 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
15067 initialize(
15068 size_t sizeof_star_self,
15069 uint64_t wuffs_version,
15070 uint32_t options) {
15071 return wuffs_xxhash64__hasher__initialize(
15072 this, sizeof_star_self, wuffs_version, options);
15075 inline wuffs_base__hasher_u64*
15076 upcast_as__wuffs_base__hasher_u64() {
15077 return (wuffs_base__hasher_u64*)this;
15080 inline uint64_t
15081 get_quirk(
15082 uint32_t a_key) const {
15083 return wuffs_xxhash64__hasher__get_quirk(this, a_key);
15086 inline wuffs_base__status
15087 set_quirk(
15088 uint32_t a_key,
15089 uint64_t a_value) {
15090 return wuffs_xxhash64__hasher__set_quirk(this, a_key, a_value);
15093 inline wuffs_base__empty_struct
15094 update(
15095 wuffs_base__slice_u8 a_x) {
15096 return wuffs_xxhash64__hasher__update(this, a_x);
15099 inline uint64_t
15100 update_u64(
15101 wuffs_base__slice_u8 a_x) {
15102 return wuffs_xxhash64__hasher__update_u64(this, a_x);
15105 inline uint64_t
15106 checksum_u64() const {
15107 return wuffs_xxhash64__hasher__checksum_u64(this);
15110 #endif // __cplusplus
15111 }; // struct wuffs_xxhash64__hasher__struct
15113 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
15115 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH64) || defined(WUFFS_NONMONOLITHIC)
15117 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XZ) || defined(WUFFS_NONMONOLITHIC)
15119 // ---------------- Status Codes
15121 extern const char wuffs_xz__error__bad_bcj_offset[];
15122 extern const char wuffs_xz__error__bad_block_header[];
15123 extern const char wuffs_xz__error__bad_checksum[];
15124 extern const char wuffs_xz__error__bad_filter[];
15125 extern const char wuffs_xz__error__bad_footer[];
15126 extern const char wuffs_xz__error__bad_header[];
15127 extern const char wuffs_xz__error__bad_header_concatenated_stream[];
15128 extern const char wuffs_xz__error__bad_index[];
15129 extern const char wuffs_xz__error__bad_padding[];
15130 extern const char wuffs_xz__error__truncated_input[];
15131 extern const char wuffs_xz__error__unsupported_checksum_algorithm[];
15132 extern const char wuffs_xz__error__unsupported_filter[];
15133 extern const char wuffs_xz__error__unsupported_filter_combination[];
15135 // ---------------- Public Consts
15137 #define WUFFS_XZ__QUIRK_DECODE_STANDALONE_CONCATENATED_STREAMS 2021322752u
15139 #define WUFFS_XZ__DECODER_DST_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0u
15141 #define WUFFS_XZ__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 4294967568u
15143 // ---------------- Struct Declarations
15145 typedef struct wuffs_xz__decoder__struct wuffs_xz__decoder;
15147 #ifdef __cplusplus
15148 extern "C" {
15149 #endif
15151 // ---------------- Public Initializer Prototypes
15153 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
15154 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
15156 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
15157 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
15159 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
15160 wuffs_xz__decoder__initialize(
15161 wuffs_xz__decoder* self,
15162 size_t sizeof_star_self,
15163 uint64_t wuffs_version,
15164 uint32_t options);
15166 size_t
15167 sizeof__wuffs_xz__decoder(void);
15169 // ---------------- Allocs
15171 // These functions allocate and initialize Wuffs structs. They return NULL if
15172 // memory allocation fails. If they return non-NULL, there is no need to call
15173 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
15174 // calling free on the returned pointer. That pointer is effectively a C++
15175 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
15177 wuffs_xz__decoder*
15178 wuffs_xz__decoder__alloc(void);
15180 static inline wuffs_base__io_transformer*
15181 wuffs_xz__decoder__alloc_as__wuffs_base__io_transformer(void) {
15182 return (wuffs_base__io_transformer*)(wuffs_xz__decoder__alloc());
15185 // ---------------- Upcasts
15187 static inline wuffs_base__io_transformer*
15188 wuffs_xz__decoder__upcast_as__wuffs_base__io_transformer(
15189 wuffs_xz__decoder* p) {
15190 return (wuffs_base__io_transformer*)p;
15193 // ---------------- Public Function Prototypes
15195 WUFFS_BASE__GENERATED_C_CODE
15196 WUFFS_BASE__MAYBE_STATIC uint64_t
15197 wuffs_xz__decoder__get_quirk(
15198 const wuffs_xz__decoder* self,
15199 uint32_t a_key);
15201 WUFFS_BASE__GENERATED_C_CODE
15202 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
15203 wuffs_xz__decoder__set_quirk(
15204 wuffs_xz__decoder* self,
15205 uint32_t a_key,
15206 uint64_t a_value);
15208 WUFFS_BASE__GENERATED_C_CODE
15209 WUFFS_BASE__MAYBE_STATIC wuffs_base__optional_u63
15210 wuffs_xz__decoder__dst_history_retain_length(
15211 const wuffs_xz__decoder* self);
15213 WUFFS_BASE__GENERATED_C_CODE
15214 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
15215 wuffs_xz__decoder__workbuf_len(
15216 const wuffs_xz__decoder* self);
15218 WUFFS_BASE__GENERATED_C_CODE
15219 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
15220 wuffs_xz__decoder__transform_io(
15221 wuffs_xz__decoder* self,
15222 wuffs_base__io_buffer* a_dst,
15223 wuffs_base__io_buffer* a_src,
15224 wuffs_base__slice_u8 a_workbuf);
15226 #ifdef __cplusplus
15227 } // extern "C"
15228 #endif
15230 // ---------------- Struct Definitions
15232 // These structs' fields, and the sizeof them, are private implementation
15233 // details that aren't guaranteed to be stable across Wuffs versions.
15235 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
15237 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
15239 struct wuffs_xz__decoder__struct {
15240 // Do not access the private_impl's or private_data's fields directly. There
15241 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
15242 // the wuffs_foo__bar__baz functions.
15244 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
15245 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
15247 struct {
15248 uint32_t magic;
15249 uint32_t active_coroutine;
15250 wuffs_base__vtable vtable_for__wuffs_base__io_transformer;
15251 wuffs_base__vtable null_vtable;
15253 uint32_t f_filters[3];
15254 uint32_t f_num_non_final_filters;
15255 uint8_t f_checksummer;
15256 bool f_ignore_checksum;
15257 bool f_standalone_format;
15258 bool f_lzma_needs_reset;
15259 bool f_block_has_compressed_size;
15260 bool f_block_has_uncompressed_size;
15261 uint8_t f_bcj_undo_index;
15262 uint32_t f_bcj_pos;
15263 uint32_t f_bcj_x86_prev_mask;
15264 uint64_t f_block_compressed_size;
15265 uint64_t f_block_uncompressed_size;
15266 uint64_t f_compressed_size_for_index;
15267 uint32_t f_verification_have_hashed_sizes[2];
15268 uint32_t f_verification_want_hashed_sizes[2];
15269 uint64_t f_verification_have_total_sizes[2];
15270 uint64_t f_verification_want_total_sizes[2];
15271 uint64_t f_num_actual_blocks;
15272 uint64_t f_num_index_blocks;
15273 uint64_t f_index_block_compressed_size;
15274 uint64_t f_index_block_uncompressed_size;
15275 uint64_t f_backwards_size;
15276 bool f_started_verify_index;
15277 uint16_t f_flags;
15279 uint8_t (*choosy_apply_non_final_filters)(
15280 wuffs_xz__decoder* self,
15281 wuffs_base__slice_u8 a_dst_slice);
15282 uint32_t p_transform_io;
15283 uint32_t p_do_transform_io;
15284 uint32_t p_decode_block_header_with_padding;
15285 uint32_t p_decode_block_header_sans_padding;
15286 uint32_t p_verify_index;
15287 uint32_t p_verify_footer;
15288 } private_impl;
15290 struct {
15291 uint8_t f_filter_data[3][256];
15292 wuffs_crc32__ieee_hasher f_crc32;
15293 wuffs_crc64__ecma_hasher f_crc64;
15294 wuffs_sha256__hasher f_sha256;
15295 wuffs_lzma__decoder f_lzma;
15297 struct {
15298 uint32_t v_checksum32_have;
15299 uint32_t v_checksum32_want;
15300 wuffs_base__bitvec256 v_checksum256_have;
15301 uint64_t v_compressed_size;
15302 uint64_t v_uncompressed_size;
15303 uint64_t scratch;
15304 } s_do_transform_io;
15305 struct {
15306 uint64_t v_padded_size_have;
15307 uint64_t v_padded_size_want;
15308 } s_decode_block_header_with_padding;
15309 struct {
15310 uint8_t v_flags;
15311 uint8_t v_filter_id;
15312 uint32_t v_shift;
15313 uint32_t v_f;
15314 uint64_t scratch;
15315 } s_decode_block_header_sans_padding;
15316 struct {
15317 uint32_t v_shift;
15318 } s_verify_index;
15319 struct {
15320 uint64_t scratch;
15321 } s_verify_footer;
15322 } private_data;
15324 #ifdef __cplusplus
15325 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
15326 using unique_ptr = std::unique_ptr<wuffs_xz__decoder, wuffs_unique_ptr_deleter>;
15328 // On failure, the alloc_etc functions return nullptr. They don't throw.
15330 static inline unique_ptr
15331 alloc() {
15332 return unique_ptr(wuffs_xz__decoder__alloc());
15335 static inline wuffs_base__io_transformer::unique_ptr
15336 alloc_as__wuffs_base__io_transformer() {
15337 return wuffs_base__io_transformer::unique_ptr(
15338 wuffs_xz__decoder__alloc_as__wuffs_base__io_transformer());
15340 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
15342 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
15343 // Disallow constructing or copying an object via standard C++ mechanisms,
15344 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
15345 // size and field layout is not part of the public, stable, memory-safe API.
15346 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
15347 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
15348 // their first argument) rather than tweaking bar.private_impl.qux fields.
15350 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
15351 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
15352 // order to provide convenience methods. These forward on "this", so that you
15353 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
15354 wuffs_xz__decoder__struct() = delete;
15355 wuffs_xz__decoder__struct(const wuffs_xz__decoder__struct&) = delete;
15356 wuffs_xz__decoder__struct& operator=(
15357 const wuffs_xz__decoder__struct&) = delete;
15358 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
15360 #if !defined(WUFFS_IMPLEMENTATION)
15361 // As above, the size of the struct is not part of the public API, and unless
15362 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
15363 // allocated, not stack allocated. Its size is not intended to be known at
15364 // compile time, but it is unfortunately divulged as a side effect of
15365 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
15366 // instead of "sizeof T", invoking the operator. To make the two values
15367 // different, so that passing the latter will be rejected by the initialize
15368 // function, we add an arbitrary amount of dead weight.
15369 uint8_t dead_weight[123000000]; // 123 MB.
15370 #endif // !defined(WUFFS_IMPLEMENTATION)
15372 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
15373 initialize(
15374 size_t sizeof_star_self,
15375 uint64_t wuffs_version,
15376 uint32_t options) {
15377 return wuffs_xz__decoder__initialize(
15378 this, sizeof_star_self, wuffs_version, options);
15381 inline wuffs_base__io_transformer*
15382 upcast_as__wuffs_base__io_transformer() {
15383 return (wuffs_base__io_transformer*)this;
15386 inline uint64_t
15387 get_quirk(
15388 uint32_t a_key) const {
15389 return wuffs_xz__decoder__get_quirk(this, a_key);
15392 inline wuffs_base__status
15393 set_quirk(
15394 uint32_t a_key,
15395 uint64_t a_value) {
15396 return wuffs_xz__decoder__set_quirk(this, a_key, a_value);
15399 inline wuffs_base__optional_u63
15400 dst_history_retain_length() const {
15401 return wuffs_xz__decoder__dst_history_retain_length(this);
15404 inline wuffs_base__range_ii_u64
15405 workbuf_len() const {
15406 return wuffs_xz__decoder__workbuf_len(this);
15409 inline wuffs_base__status
15410 transform_io(
15411 wuffs_base__io_buffer* a_dst,
15412 wuffs_base__io_buffer* a_src,
15413 wuffs_base__slice_u8 a_workbuf) {
15414 return wuffs_xz__decoder__transform_io(this, a_dst, a_src, a_workbuf);
15417 #endif // __cplusplus
15418 }; // struct wuffs_xz__decoder__struct
15420 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
15422 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XZ) || defined(WUFFS_NONMONOLITHIC)
15424 #if defined(__cplusplus) && defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
15426 // ---------------- Auxiliary - Base
15428 // Auxiliary code is discussed at
15429 // https://github.com/google/wuffs/blob/main/doc/note/auxiliary-code.md
15431 #include <stdio.h>
15433 #include <string>
15434 #include <utility>
15436 namespace wuffs_aux {
15438 using IOBuffer = wuffs_base__io_buffer;
15440 // MemOwner represents ownership of some memory. Dynamically allocated memory
15441 // (e.g. from malloc or new) is typically paired with free or delete, invoked
15442 // when the std::unique_ptr is destroyed. Statically allocated memory might use
15443 // MemOwner(nullptr, &free), even if that statically allocated memory is not
15444 // nullptr, since calling free(nullptr) is a no-op.
15445 using MemOwner = std::unique_ptr<void, decltype(&free)>;
15447 using QuirkKeyValuePair = std::pair<uint32_t, uint64_t>;
15449 namespace sync_io {
15451 // --------
15453 // DynIOBuffer is an IOBuffer that is backed by a dynamically sized byte array.
15454 // It owns that backing array and will free it in its destructor.
15456 // The array size can be explicitly extended (by calling the grow method) but,
15457 // unlike a C++ std::vector, there is no implicit extension (e.g. by calling
15458 // std::vector::insert) and its maximum size is capped by the max_incl
15459 // constructor argument.
15461 // It contains an IOBuffer-typed field whose reader side provides access to
15462 // previously written bytes and whose writer side provides access to the
15463 // allocated but not-yet-written-to slack space. For Go programmers, this slack
15464 // space is roughly analogous to the s[len(s):cap(s)] space of a slice s.
15465 class DynIOBuffer {
15466 public:
15467 enum GrowResult {
15468 OK = 0,
15469 FailedMaxInclExceeded = 1,
15470 FailedOutOfMemory = 2,
15473 // m_buf holds the dynamically sized byte array and its read/write indexes:
15474 // - m_buf.meta.wi is roughly analogous to a Go slice's length.
15475 // - m_buf.data.len is roughly analogous to a Go slice's capacity. It is
15476 // also equal to the m_buf.data.ptr malloc/realloc size.
15478 // Users should not modify the m_buf.data.ptr or m_buf.data.len fields (as
15479 // they are conceptually private to this class), but they can modify the
15480 // bytes referenced by that pointer-length pair (e.g. compactions).
15481 IOBuffer m_buf;
15483 // m_max_incl is an inclusive upper bound on the backing array size.
15484 const uint64_t m_max_incl;
15486 // Constructor and destructor.
15487 explicit DynIOBuffer(uint64_t max_incl);
15488 ~DynIOBuffer();
15490 // Drop frees the byte array and resets m_buf. The DynIOBuffer can still be
15491 // used after a drop call. It just restarts from zero.
15492 void drop();
15494 // grow ensures that the byte array size is at least min_incl and at most
15495 // max_incl. It returns FailedMaxInclExceeded if that would require
15496 // allocating more than max_incl bytes, including the case where (min_incl >
15497 // max_incl). It returns FailedOutOfMemory if memory allocation failed.
15498 GrowResult grow(uint64_t min_incl);
15500 private:
15501 // Delete the copy and assign constructors.
15502 DynIOBuffer(const DynIOBuffer&) = delete;
15503 DynIOBuffer& operator=(const DynIOBuffer&) = delete;
15505 static uint64_t round_up(uint64_t min_incl, uint64_t max_incl);
15508 // --------
15510 class Input {
15511 public:
15512 virtual ~Input();
15514 virtual IOBuffer* BringsItsOwnIOBuffer();
15515 virtual std::string CopyIn(IOBuffer* dst) = 0;
15518 // --------
15520 // FileInput is an Input that reads from a file source.
15522 // It does not take responsibility for closing the file when done.
15523 class FileInput : public Input {
15524 public:
15525 FileInput(FILE* f);
15527 virtual std::string CopyIn(IOBuffer* dst);
15529 private:
15530 FILE* m_f;
15532 // Delete the copy and assign constructors.
15533 FileInput(const FileInput&) = delete;
15534 FileInput& operator=(const FileInput&) = delete;
15537 // --------
15539 // MemoryInput is an Input that reads from an in-memory source.
15541 // It does not take responsibility for freeing the memory when done.
15542 class MemoryInput : public Input {
15543 public:
15544 MemoryInput(const char* ptr, size_t len);
15545 MemoryInput(const uint8_t* ptr, size_t len);
15547 virtual IOBuffer* BringsItsOwnIOBuffer();
15548 virtual std::string CopyIn(IOBuffer* dst);
15550 private:
15551 IOBuffer m_io;
15553 // Delete the copy and assign constructors.
15554 MemoryInput(const MemoryInput&) = delete;
15555 MemoryInput& operator=(const MemoryInput&) = delete;
15558 // --------
15560 } // namespace sync_io
15562 } // namespace wuffs_aux
15564 // ---------------- Auxiliary - CBOR
15566 namespace wuffs_aux {
15568 struct DecodeCborResult {
15569 DecodeCborResult(std::string&& error_message0, uint64_t cursor_position0);
15571 std::string error_message;
15572 uint64_t cursor_position;
15575 class DecodeCborCallbacks {
15576 public:
15577 virtual ~DecodeCborCallbacks();
15579 // AppendXxx are called for leaf nodes: literals, numbers, strings, etc.
15581 virtual std::string AppendNull() = 0;
15582 virtual std::string AppendUndefined() = 0;
15583 virtual std::string AppendBool(bool val) = 0;
15584 virtual std::string AppendF64(double val) = 0;
15585 virtual std::string AppendI64(int64_t val) = 0;
15586 virtual std::string AppendU64(uint64_t val) = 0;
15587 virtual std::string AppendByteString(std::string&& val) = 0;
15588 virtual std::string AppendTextString(std::string&& val) = 0;
15589 virtual std::string AppendMinus1MinusX(uint64_t val) = 0;
15590 virtual std::string AppendCborSimpleValue(uint8_t val) = 0;
15591 virtual std::string AppendCborTag(uint64_t val) = 0;
15593 // Push and Pop are called for container nodes: CBOR arrays (lists) and CBOR
15594 // maps (dictionaries).
15596 // The flags bits combine exactly one of:
15597 // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_NONE
15598 // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_LIST
15599 // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_DICT
15600 // and exactly one of:
15601 // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_NONE
15602 // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_LIST
15603 // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_DICT
15605 virtual std::string Push(uint32_t flags) = 0;
15606 virtual std::string Pop(uint32_t flags) = 0;
15608 // Done is always the last Callback method called by DecodeCbor, whether or
15609 // not parsing the input as CBOR encountered an error. Even when successful,
15610 // trailing data may remain in input and buffer.
15612 // Do not keep a reference to buffer or buffer.data.ptr after Done returns,
15613 // as DecodeCbor may then de-allocate the backing array.
15615 // The default Done implementation is a no-op.
15616 virtual void //
15617 Done(DecodeCborResult& result, sync_io::Input& input, IOBuffer& buffer);
15620 // The FooArgBar types add structure to Foo's optional arguments. They wrap
15621 // inner representations for several reasons:
15622 // - It provides a home for the DefaultValue static method, for Foo callers
15623 // that want to override some but not all optional arguments.
15624 // - It provides the "Bar" name at Foo call sites, which can help self-
15625 // document Foo calls with many arguemnts.
15626 // - It provides some type safety against accidentally transposing or omitting
15627 // adjacent fundamentally-numeric-typed optional arguments.
15629 // DecodeCborArgQuirks wraps an optional argument to DecodeCbor.
15630 struct DecodeCborArgQuirks {
15631 explicit DecodeCborArgQuirks(const QuirkKeyValuePair* ptr0,
15632 const size_t len0);
15634 // DefaultValue returns an empty slice.
15635 static DecodeCborArgQuirks DefaultValue();
15637 const QuirkKeyValuePair* ptr;
15638 const size_t len;
15641 // DecodeCbor calls callbacks based on the CBOR-formatted data in input.
15643 // On success, the returned error_message is empty and cursor_position counts
15644 // the number of bytes consumed. On failure, error_message is non-empty and
15645 // cursor_position is the location of the error. That error may be a content
15646 // error (invalid CBOR) or an input error (e.g. network failure).
15647 DecodeCborResult //
15648 DecodeCbor(DecodeCborCallbacks& callbacks,
15649 sync_io::Input& input,
15650 DecodeCborArgQuirks quirks = DecodeCborArgQuirks::DefaultValue());
15652 } // namespace wuffs_aux
15654 // ---------------- Auxiliary - Image
15656 namespace wuffs_aux {
15658 struct DecodeImageResult {
15659 DecodeImageResult(MemOwner&& pixbuf_mem_owner0,
15660 wuffs_base__pixel_buffer pixbuf0,
15661 std::string&& error_message0);
15662 DecodeImageResult(std::string&& error_message0);
15664 MemOwner pixbuf_mem_owner;
15665 wuffs_base__pixel_buffer pixbuf;
15666 std::string error_message;
15669 // DecodeImageCallbacks are the callbacks given to DecodeImage. They are always
15670 // called in this order:
15671 // 1. SelectDecoder
15672 // 2. HandleMetadata
15673 // 3. SelectPixfmt
15674 // 4. AllocPixbuf
15675 // 5. AllocWorkbuf
15676 // 6. Done
15678 // It may return early - the third callback might not be invoked if the second
15679 // one fails - but the final callback (Done) is always invoked.
15680 class DecodeImageCallbacks {
15681 public:
15682 // AllocPixbufResult holds a memory allocation (the result of malloc or new,
15683 // a statically allocated pointer, etc), or an error message. The memory is
15684 // de-allocated when mem_owner goes out of scope and is destroyed.
15685 struct AllocPixbufResult {
15686 AllocPixbufResult(MemOwner&& mem_owner0, wuffs_base__pixel_buffer pixbuf0);
15687 AllocPixbufResult(std::string&& error_message0);
15689 MemOwner mem_owner;
15690 wuffs_base__pixel_buffer pixbuf;
15691 std::string error_message;
15694 // AllocWorkbufResult holds a memory allocation (the result of malloc or new,
15695 // a statically allocated pointer, etc), or an error message. The memory is
15696 // de-allocated when mem_owner goes out of scope and is destroyed.
15697 struct AllocWorkbufResult {
15698 AllocWorkbufResult(MemOwner&& mem_owner0, wuffs_base__slice_u8 workbuf0);
15699 AllocWorkbufResult(std::string&& error_message0);
15701 MemOwner mem_owner;
15702 wuffs_base__slice_u8 workbuf;
15703 std::string error_message;
15706 virtual ~DecodeImageCallbacks();
15708 // SelectDecoder returns the image decoder for the input data's file format.
15709 // Returning a nullptr means failure (DecodeImage_UnsupportedImageFormat).
15711 // Common formats will have a FourCC value in the range [1 ..= 0x7FFF_FFFF],
15712 // such as WUFFS_BASE__FOURCC__JPEG. A zero FourCC value means that Wuffs'
15713 // standard library did not recognize the image format but if SelectDecoder
15714 // was overridden, it may examine the input data's starting bytes and still
15715 // provide its own image decoder, e.g. for an exotic image file format that's
15716 // not in Wuffs' standard library. The prefix_etc fields have the same
15717 // meaning as wuffs_base__magic_number_guess_fourcc arguments. SelectDecoder
15718 // implementations should not modify prefix_data's contents.
15720 // SelectDecoder might be called more than once, since some image file
15721 // formats can wrap others. For example, a nominal BMP file can actually
15722 // contain a JPEG or a PNG.
15724 // The default SelectDecoder accepts the FOURCC codes listed below. For
15725 // modular builds (i.e. when #define'ing WUFFS_CONFIG__MODULES), acceptance
15726 // of the ETC file format is optional (for each value of ETC) and depends on
15727 // the corresponding module to be enabled at compile time (i.e. #define'ing
15728 // WUFFS_CONFIG__MODULE__ETC).
15729 // - WUFFS_BASE__FOURCC__BMP
15730 // - WUFFS_BASE__FOURCC__GIF
15731 // - WUFFS_BASE__FOURCC__JPEG
15732 // - WUFFS_BASE__FOURCC__NIE
15733 // - WUFFS_BASE__FOURCC__NPBM
15734 // - WUFFS_BASE__FOURCC__PNG
15735 // - WUFFS_BASE__FOURCC__QOI
15736 // - WUFFS_BASE__FOURCC__TGA
15737 // - WUFFS_BASE__FOURCC__WBMP
15738 // - WUFFS_BASE__FOURCC__WEBP
15739 virtual wuffs_base__image_decoder::unique_ptr //
15740 SelectDecoder(uint32_t fourcc,
15741 wuffs_base__slice_u8 prefix_data,
15742 bool prefix_closed);
15744 // HandleMetadata acknowledges image metadata. minfo.flavor will be one of:
15745 // - WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_RAW_PASSTHROUGH
15746 // - WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_PARSED
15747 // If it is ETC__METADATA_RAW_ETC then raw contains the metadata bytes. Those
15748 // bytes should not be retained beyond the the HandleMetadata call.
15750 // minfo.metadata__fourcc() will typically match one of the
15751 // DecodeImageArgFlags bits. For example, if (REPORT_METADATA_CHRM |
15752 // REPORT_METADATA_GAMA) was passed to DecodeImage then the metadata FourCC
15753 // will be either WUFFS_BASE__FOURCC__CHRM or WUFFS_BASE__FOURCC__GAMA.
15755 // It returns an error message, or an empty string on success.
15756 virtual std::string //
15757 HandleMetadata(const wuffs_base__more_information& minfo,
15758 wuffs_base__slice_u8 raw);
15760 // SelectPixfmt returns the destination pixel format for AllocPixbuf. It
15761 // should return wuffs_base__make_pixel_format(etc) called with one of:
15762 // - WUFFS_BASE__PIXEL_FORMAT__BGR_565
15763 // - WUFFS_BASE__PIXEL_FORMAT__BGR
15764 // - WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL
15765 // - WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE
15766 // - WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL
15767 // - WUFFS_BASE__PIXEL_FORMAT__RGB
15768 // - WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL
15769 // - WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL
15770 // or return image_config.pixcfg.pixel_format(). The latter means to use the
15771 // image file's natural pixel format. For example, GIF images' natural pixel
15772 // format is an indexed one.
15774 // Returning otherwise means failure (DecodeImage_UnsupportedPixelFormat).
15776 // The default SelectPixfmt implementation returns
15777 // wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL) which
15778 // is 4 bytes per pixel (8 bits per channel × 4 channels).
15779 virtual wuffs_base__pixel_format //
15780 SelectPixfmt(const wuffs_base__image_config& image_config);
15782 // AllocPixbuf allocates the pixel buffer.
15784 // allow_uninitialized_memory will be true if a valid background_color was
15785 // passed to DecodeImage, since the pixel buffer's contents will be
15786 // overwritten with that color after AllocPixbuf returns.
15788 // The default AllocPixbuf implementation allocates either uninitialized or
15789 // zeroed memory. Zeroed memory typically corresponds to filling with opaque
15790 // black or transparent black, depending on the pixel format.
15791 virtual AllocPixbufResult //
15792 AllocPixbuf(const wuffs_base__image_config& image_config,
15793 bool allow_uninitialized_memory);
15795 // AllocWorkbuf allocates the work buffer. The allocated buffer's length
15796 // should be at least len_range.min_incl, but larger allocations (up to
15797 // len_range.max_incl) may have better performance (by using more memory).
15799 // The default AllocWorkbuf implementation allocates len_range.max_incl bytes
15800 // of either uninitialized or zeroed memory.
15801 virtual AllocWorkbufResult //
15802 AllocWorkbuf(wuffs_base__range_ii_u64 len_range,
15803 bool allow_uninitialized_memory);
15805 // Done is always the last Callback method called by DecodeImage, whether or
15806 // not parsing the input encountered an error. Even when successful, trailing
15807 // data may remain in input and buffer.
15809 // The image_decoder is the one returned by SelectDecoder (if SelectDecoder
15810 // was successful), or a no-op unique_ptr otherwise. Like any unique_ptr,
15811 // ownership moves to the Done implementation.
15813 // Do not keep a reference to buffer or buffer.data.ptr after Done returns,
15814 // as DecodeImage may then de-allocate the backing array.
15816 // The default Done implementation is a no-op, other than running the
15817 // image_decoder unique_ptr destructor.
15818 virtual void //
15819 Done(DecodeImageResult& result,
15820 sync_io::Input& input,
15821 IOBuffer& buffer,
15822 wuffs_base__image_decoder::unique_ptr image_decoder);
15825 extern const char DecodeImage_BufferIsTooShort[];
15826 extern const char DecodeImage_MaxInclDimensionExceeded[];
15827 extern const char DecodeImage_MaxInclMetadataLengthExceeded[];
15828 extern const char DecodeImage_OutOfMemory[];
15829 extern const char DecodeImage_UnexpectedEndOfFile[];
15830 extern const char DecodeImage_UnsupportedImageFormat[];
15831 extern const char DecodeImage_UnsupportedMetadata[];
15832 extern const char DecodeImage_UnsupportedPixelBlend[];
15833 extern const char DecodeImage_UnsupportedPixelConfiguration[];
15834 extern const char DecodeImage_UnsupportedPixelFormat[];
15836 // The FooArgBar types add structure to Foo's optional arguments. They wrap
15837 // inner representations for several reasons:
15838 // - It provides a home for the DefaultValue static method, for Foo callers
15839 // that want to override some but not all optional arguments.
15840 // - It provides the "Bar" name at Foo call sites, which can help self-
15841 // document Foo calls with many arguemnts.
15842 // - It provides some type safety against accidentally transposing or omitting
15843 // adjacent fundamentally-numeric-typed optional arguments.
15845 // DecodeImageArgQuirks wraps an optional argument to DecodeImage.
15846 struct DecodeImageArgQuirks {
15847 explicit DecodeImageArgQuirks(const QuirkKeyValuePair* ptr0,
15848 const size_t len0);
15850 // DefaultValue returns an empty slice.
15851 static DecodeImageArgQuirks DefaultValue();
15853 const QuirkKeyValuePair* ptr;
15854 const size_t len;
15857 // DecodeImageArgFlags wraps an optional argument to DecodeImage.
15858 struct DecodeImageArgFlags {
15859 explicit DecodeImageArgFlags(uint64_t repr0);
15861 // DefaultValue returns 0.
15862 static DecodeImageArgFlags DefaultValue();
15864 // TODO: support all of the REPORT_METADATA_ETC flags, not just CHRM, EXIF,
15865 // GAMA, ICCP, KVP, SRGB and XMP.
15867 // Background Color.
15868 static constexpr uint64_t REPORT_METADATA_BGCL = 0x0001;
15869 // Primary Chromaticities and White Point.
15870 static constexpr uint64_t REPORT_METADATA_CHRM = 0x0002;
15871 // Exchangeable Image File Format.
15872 static constexpr uint64_t REPORT_METADATA_EXIF = 0x0004;
15873 // Gamma Correction.
15874 static constexpr uint64_t REPORT_METADATA_GAMA = 0x0008;
15875 // International Color Consortium Profile.
15876 static constexpr uint64_t REPORT_METADATA_ICCP = 0x0010;
15877 // Key-Value Pair.
15879 // For PNG files, this includes iTXt, tEXt and zTXt chunks. In the
15880 // HandleMetadata callback, the raw argument contains UTF-8 strings.
15881 static constexpr uint64_t REPORT_METADATA_KVP = 0x0020;
15882 // Modification Time.
15883 static constexpr uint64_t REPORT_METADATA_MTIM = 0x0040;
15884 // Offset (2-Dimensional).
15885 static constexpr uint64_t REPORT_METADATA_OFS2 = 0x0080;
15886 // Physical Dimensions.
15887 static constexpr uint64_t REPORT_METADATA_PHYD = 0x0100;
15888 // Standard Red Green Blue (Rendering Intent).
15889 static constexpr uint64_t REPORT_METADATA_SRGB = 0x0200;
15890 // Extensible Metadata Platform.
15891 static constexpr uint64_t REPORT_METADATA_XMP = 0x0400;
15893 uint64_t repr;
15896 // DecodeImageArgPixelBlend wraps an optional argument to DecodeImage.
15897 struct DecodeImageArgPixelBlend {
15898 explicit DecodeImageArgPixelBlend(wuffs_base__pixel_blend repr0);
15900 // DefaultValue returns WUFFS_BASE__PIXEL_BLEND__SRC.
15901 static DecodeImageArgPixelBlend DefaultValue();
15903 wuffs_base__pixel_blend repr;
15906 // DecodeImageArgBackgroundColor wraps an optional argument to DecodeImage.
15907 struct DecodeImageArgBackgroundColor {
15908 explicit DecodeImageArgBackgroundColor(
15909 wuffs_base__color_u32_argb_premul repr0);
15911 // DefaultValue returns 1, an invalid wuffs_base__color_u32_argb_premul.
15912 static DecodeImageArgBackgroundColor DefaultValue();
15914 wuffs_base__color_u32_argb_premul repr;
15917 // DecodeImageArgMaxInclDimension wraps an optional argument to DecodeImage.
15918 struct DecodeImageArgMaxInclDimension {
15919 explicit DecodeImageArgMaxInclDimension(uint32_t repr0);
15921 // DefaultValue returns 1048575 = 0x000F_FFFF, more than 1 million pixels.
15922 static DecodeImageArgMaxInclDimension DefaultValue();
15924 uint32_t repr;
15927 // DecodeImageArgMaxInclMetadataLength wraps an optional argument to
15928 // DecodeImage.
15929 struct DecodeImageArgMaxInclMetadataLength {
15930 explicit DecodeImageArgMaxInclMetadataLength(uint64_t repr0);
15932 // DefaultValue returns 16777215 = 0x00FF_FFFF, one less than 16 MiB.
15933 static DecodeImageArgMaxInclMetadataLength DefaultValue();
15935 uint64_t repr;
15938 // DecodeImage decodes the image data in input. A variety of image file formats
15939 // can be decoded, depending on what callbacks.SelectDecoder returns.
15941 // For animated formats, only the first frame is returned, since the API is
15942 // simpler for synchronous I/O and having DecodeImage only return when
15943 // completely done, but rendering animation often involves handling other
15944 // events in between animation frames. To decode multiple frames of animated
15945 // images, or for asynchronous I/O (e.g. when decoding an image streamed over
15946 // the network), use Wuffs' lower level C API instead of its higher level,
15947 // simplified C++ API (the wuffs_aux API).
15949 // The DecodeImageResult's fields depend on whether decoding succeeded:
15950 // - On total success, the error_message is empty and pixbuf.pixcfg.is_valid()
15951 // is true.
15952 // - On partial success (e.g. the input file was truncated but we are still
15953 // able to decode some of the pixels), error_message is non-empty but
15954 // pixbuf.pixcfg.is_valid() is still true. It is up to the caller whether to
15955 // accept or reject partial success.
15956 // - On failure, the error_message is non_empty and pixbuf.pixcfg.is_valid()
15957 // is false.
15959 // The callbacks allocate the pixel buffer memory and work buffer memory. On
15960 // success, pixel buffer memory ownership is passed to the DecodeImage caller
15961 // as the returned pixbuf_mem_owner. Regardless of success or failure, the work
15962 // buffer memory is deleted.
15964 // The pixel_blend (one of the constants listed below) determines how to
15965 // composite the decoded image over the pixel buffer's original pixels (as
15966 // returned by callbacks.AllocPixbuf):
15967 // - WUFFS_BASE__PIXEL_BLEND__SRC
15968 // - WUFFS_BASE__PIXEL_BLEND__SRC_OVER
15970 // The background_color is used to fill the pixel buffer after
15971 // callbacks.AllocPixbuf returns, if it is valid in the
15972 // wuffs_base__color_u32_argb_premul__is_valid sense. The default value,
15973 // 0x0000_0001, is not valid since its Blue channel value (0x01) is greater
15974 // than its Alpha channel value (0x00). A valid background_color will typically
15975 // be overwritten when pixel_blend is WUFFS_BASE__PIXEL_BLEND__SRC, but might
15976 // still be visible on partial (not total) success or when pixel_blend is
15977 // WUFFS_BASE__PIXEL_BLEND__SRC_OVER and the decoded image is not fully opaque.
15979 // Decoding fails (with DecodeImage_MaxInclDimensionExceeded) if the image's
15980 // width or height is greater than max_incl_dimension or if any opted-in (via
15981 // flags bits) metadata is longer than max_incl_metadata_length.
15982 DecodeImageResult //
15983 DecodeImage(DecodeImageCallbacks& callbacks,
15984 sync_io::Input& input,
15985 DecodeImageArgQuirks quirks = DecodeImageArgQuirks::DefaultValue(),
15986 DecodeImageArgFlags flags = DecodeImageArgFlags::DefaultValue(),
15987 DecodeImageArgPixelBlend pixel_blend =
15988 DecodeImageArgPixelBlend::DefaultValue(),
15989 DecodeImageArgBackgroundColor background_color =
15990 DecodeImageArgBackgroundColor::DefaultValue(),
15991 DecodeImageArgMaxInclDimension max_incl_dimension =
15992 DecodeImageArgMaxInclDimension::DefaultValue(),
15993 DecodeImageArgMaxInclMetadataLength max_incl_metadata_length =
15994 DecodeImageArgMaxInclMetadataLength::DefaultValue());
15996 } // namespace wuffs_aux
15998 // ---------------- Auxiliary - JSON
16000 namespace wuffs_aux {
16002 struct DecodeJsonResult {
16003 DecodeJsonResult(std::string&& error_message0, uint64_t cursor_position0);
16005 std::string error_message;
16006 uint64_t cursor_position;
16009 class DecodeJsonCallbacks {
16010 public:
16011 virtual ~DecodeJsonCallbacks();
16013 // AppendXxx are called for leaf nodes: literals, numbers and strings. For
16014 // strings, the Callbacks implementation is responsible for tracking map keys
16015 // versus other values.
16017 virtual std::string AppendNull() = 0;
16018 virtual std::string AppendBool(bool val) = 0;
16019 virtual std::string AppendF64(double val) = 0;
16020 virtual std::string AppendI64(int64_t val) = 0;
16021 virtual std::string AppendTextString(std::string&& val) = 0;
16023 // Push and Pop are called for container nodes: JSON arrays (lists) and JSON
16024 // objects (dictionaries).
16026 // The flags bits combine exactly one of:
16027 // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_NONE
16028 // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_LIST
16029 // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_DICT
16030 // and exactly one of:
16031 // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_NONE
16032 // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_LIST
16033 // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_DICT
16035 virtual std::string Push(uint32_t flags) = 0;
16036 virtual std::string Pop(uint32_t flags) = 0;
16038 // Done is always the last Callback method called by DecodeJson, whether or
16039 // not parsing the input as JSON encountered an error. Even when successful,
16040 // trailing data may remain in input and buffer. See "Unintuitive JSON
16041 // Parsing" (https://nullprogram.com/blog/2019/12/28/) which discusses JSON
16042 // parsing and when it stops.
16044 // Do not keep a reference to buffer or buffer.data.ptr after Done returns,
16045 // as DecodeJson may then de-allocate the backing array.
16047 // The default Done implementation is a no-op.
16048 virtual void //
16049 Done(DecodeJsonResult& result, sync_io::Input& input, IOBuffer& buffer);
16052 extern const char DecodeJson_BadJsonPointer[];
16053 extern const char DecodeJson_NoMatch[];
16055 // The FooArgBar types add structure to Foo's optional arguments. They wrap
16056 // inner representations for several reasons:
16057 // - It provides a home for the DefaultValue static method, for Foo callers
16058 // that want to override some but not all optional arguments.
16059 // - It provides the "Bar" name at Foo call sites, which can help self-
16060 // document Foo calls with many arguemnts.
16061 // - It provides some type safety against accidentally transposing or omitting
16062 // adjacent fundamentally-numeric-typed optional arguments.
16064 // DecodeJsonArgQuirks wraps an optional argument to DecodeJson.
16065 struct DecodeJsonArgQuirks {
16066 explicit DecodeJsonArgQuirks(const QuirkKeyValuePair* ptr0,
16067 const size_t len0);
16069 // DefaultValue returns an empty slice.
16070 static DecodeJsonArgQuirks DefaultValue();
16072 const QuirkKeyValuePair* ptr;
16073 const size_t len;
16076 // DecodeJsonArgJsonPointer wraps an optional argument to DecodeJson.
16077 struct DecodeJsonArgJsonPointer {
16078 explicit DecodeJsonArgJsonPointer(std::string repr0);
16080 // DefaultValue returns an empty string.
16081 static DecodeJsonArgJsonPointer DefaultValue();
16083 std::string repr;
16086 // DecodeJson calls callbacks based on the JSON-formatted data in input.
16088 // On success, the returned error_message is empty and cursor_position counts
16089 // the number of bytes consumed. On failure, error_message is non-empty and
16090 // cursor_position is the location of the error. That error may be a content
16091 // error (invalid JSON) or an input error (e.g. network failure).
16093 // json_pointer is a query in the JSON Pointer (RFC 6901) syntax. The callbacks
16094 // run for the input's sub-node that matches the query. DecodeJson_NoMatch is
16095 // returned if no matching sub-node was found. The empty query matches the
16096 // input's root node, consistent with JSON Pointer semantics.
16098 // The JSON Pointer implementation is greedy: duplicate keys are not rejected
16099 // but only the first match for each '/'-separated fragment is followed.
16100 DecodeJsonResult //
16101 DecodeJson(DecodeJsonCallbacks& callbacks,
16102 sync_io::Input& input,
16103 DecodeJsonArgQuirks quirks = DecodeJsonArgQuirks::DefaultValue(),
16104 DecodeJsonArgJsonPointer json_pointer =
16105 DecodeJsonArgJsonPointer::DefaultValue());
16107 } // namespace wuffs_aux
16109 #endif // defined(__cplusplus) && defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
16111 // ‼ WUFFS C HEADER ENDS HERE.
16112 #ifdef WUFFS_IMPLEMENTATION
16114 #ifdef __cplusplus
16115 extern "C" {
16116 #endif
16118 // ---------------- Fundamentals
16120 // WUFFS_BASE__MAGIC is a magic number to check that initializers are called.
16121 // It's not foolproof, given C doesn't automatically zero memory before use,
16122 // but it should catch 99.99% of cases.
16124 // Its (non-zero) value is arbitrary, based on md5sum("wuffs").
16125 #define WUFFS_BASE__MAGIC ((uint32_t)0x3CCB6C71)
16127 // WUFFS_BASE__DISABLED is a magic number to indicate that a non-recoverable
16128 // error was previously encountered.
16130 // Its (non-zero) value is arbitrary, based on md5sum("disabled").
16131 #define WUFFS_BASE__DISABLED ((uint32_t)0x075AE3D2)
16133 // Use switch cases for coroutine suspension points, similar to the technique
16134 // in https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
16136 // The implicit fallthrough is intentional.
16138 // We use trivial macros instead of an explicit assignment and case statement
16139 // so that clang-format doesn't get confused by the unusual "case"s.
16140 #define WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0 case 0:;
16141 #define WUFFS_BASE__COROUTINE_SUSPENSION_POINT(n) \
16142 coro_susp_point = n; \
16143 case n:;
16145 #define WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(n) \
16146 if (!status.repr) { \
16147 goto ok; \
16148 } else if (*status.repr != '$') { \
16149 goto exit; \
16151 coro_susp_point = n; \
16152 goto suspend; \
16153 case n:;
16155 // The "defined(__clang__)" isn't redundant. While vanilla clang defines
16156 // __GNUC__, clang-cl (which mimics MSVC's cl.exe) does not.
16157 #if defined(__GNUC__) || defined(__clang__)
16158 #define WUFFS_BASE__LIKELY(expr) (__builtin_expect(!!(expr), 1))
16159 #define WUFFS_BASE__UNLIKELY(expr) (__builtin_expect(!!(expr), 0))
16160 #else
16161 #define WUFFS_BASE__LIKELY(expr) (expr)
16162 #define WUFFS_BASE__UNLIKELY(expr) (expr)
16163 #endif
16165 // --------
16167 static inline wuffs_base__empty_struct //
16168 wuffs_private_impl__ignore_status(wuffs_base__status z) {
16169 return wuffs_base__make_empty_struct();
16172 static inline wuffs_base__status //
16173 wuffs_private_impl__status__ensure_not_a_suspension(wuffs_base__status z) {
16174 if (z.repr && (*z.repr == '$')) {
16175 z.repr = wuffs_base__error__cannot_return_a_suspension;
16177 return z;
16180 // --------
16182 // wuffs_private_impl__iterate_total_advance returns the exclusive
16183 // pointer-offset at which iteration should stop. The overall slice has length
16184 // total_len, each iteration's sub-slice has length iter_len and are placed
16185 // iter_advance apart.
16187 // The iter_advance may not be larger than iter_len. The iter_advance may be
16188 // smaller than iter_len, in which case the sub-slices will overlap.
16190 // The return value r satisfies ((0 <= r) && (r <= total_len)).
16192 // For example, if total_len = 15, iter_len = 5 and iter_advance = 3, there are
16193 // four iterations at offsets 0, 3, 6 and 9. This function returns 12.
16195 // 0123456789012345
16196 // [....]
16197 // [....]
16198 // [....]
16199 // [....]
16200 // $
16201 // 0123456789012345
16203 // For example, if total_len = 15, iter_len = 5 and iter_advance = 5, there are
16204 // three iterations at offsets 0, 5 and 10. This function returns 15.
16206 // 0123456789012345
16207 // [....]
16208 // [....]
16209 // [....]
16210 // $
16211 // 0123456789012345
16212 static inline size_t //
16213 wuffs_private_impl__iterate_total_advance(size_t total_len,
16214 size_t iter_len,
16215 size_t iter_advance) {
16216 if (total_len >= iter_len) {
16217 size_t n = total_len - iter_len;
16218 return ((n / iter_advance) * iter_advance) + iter_advance;
16220 return 0;
16223 // ---------------- Numeric Types
16225 extern const uint8_t wuffs_private_impl__low_bits_mask__u8[8];
16226 extern const uint16_t wuffs_private_impl__low_bits_mask__u16[16];
16227 extern const uint32_t wuffs_private_impl__low_bits_mask__u32[32];
16228 extern const uint64_t wuffs_private_impl__low_bits_mask__u64[64];
16230 #define WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U8(n) \
16231 (wuffs_private_impl__low_bits_mask__u8[n])
16232 #define WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U16(n) \
16233 (wuffs_private_impl__low_bits_mask__u16[n])
16234 #define WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U32(n) \
16235 (wuffs_private_impl__low_bits_mask__u32[n])
16236 #define WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U64(n) \
16237 (wuffs_private_impl__low_bits_mask__u64[n])
16239 // --------
16241 static inline void //
16242 wuffs_private_impl__u8__sat_add_indirect(uint8_t* x, uint8_t y) {
16243 *x = wuffs_base__u8__sat_add(*x, y);
16246 static inline void //
16247 wuffs_private_impl__u8__sat_sub_indirect(uint8_t* x, uint8_t y) {
16248 *x = wuffs_base__u8__sat_sub(*x, y);
16251 static inline void //
16252 wuffs_private_impl__u16__sat_add_indirect(uint16_t* x, uint16_t y) {
16253 *x = wuffs_base__u16__sat_add(*x, y);
16256 static inline void //
16257 wuffs_private_impl__u16__sat_sub_indirect(uint16_t* x, uint16_t y) {
16258 *x = wuffs_base__u16__sat_sub(*x, y);
16261 static inline void //
16262 wuffs_private_impl__u32__sat_add_indirect(uint32_t* x, uint32_t y) {
16263 *x = wuffs_base__u32__sat_add(*x, y);
16266 static inline void //
16267 wuffs_private_impl__u32__sat_sub_indirect(uint32_t* x, uint32_t y) {
16268 *x = wuffs_base__u32__sat_sub(*x, y);
16271 static inline void //
16272 wuffs_private_impl__u64__sat_add_indirect(uint64_t* x, uint64_t y) {
16273 *x = wuffs_base__u64__sat_add(*x, y);
16276 static inline void //
16277 wuffs_private_impl__u64__sat_sub_indirect(uint64_t* x, uint64_t y) {
16278 *x = wuffs_base__u64__sat_sub(*x, y);
16281 // ---------------- Numeric Types (Utility)
16283 #define wuffs_base__utility__sign_extend_convert_u8_u32(a) \
16284 ((uint32_t)(int32_t)(int8_t)(a))
16286 #define wuffs_base__utility__sign_extend_convert_u16_u32(a) \
16287 ((uint32_t)(int32_t)(int16_t)(a))
16289 #define wuffs_base__utility__sign_extend_rshift_u32(a, n) \
16290 ((uint32_t)(((int32_t)(a)) >> (n)))
16292 #define wuffs_base__utility__sign_extend_rshift_u64(a, n) \
16293 ((uint64_t)(((int64_t)(a)) >> (n)))
16295 #define wuffs_base__utility__make_bitvec256(e00, e01, e02, e03) \
16296 wuffs_base__make_bitvec256(e00, e01, e02, e03)
16298 #define wuffs_base__utility__make_optional_u63(h, v) \
16299 wuffs_base__make_optional_u63(h, v)
16301 // ---------------- Slices and Tables
16303 // This function basically returns (ptr + len), except that that expression is
16304 // Undefined Behavior in C (but not C++) when ptr is NULL, even if len is zero.
16306 // Precondition: (ptr != NULL) || (len == 0).
16307 static inline const uint8_t* //
16308 wuffs_private_impl__ptr_u8_plus_len(const uint8_t* ptr, size_t len) {
16309 return ptr ? (ptr + len) : NULL;
16312 // --------
16314 // wuffs_private_impl__slice_u8__prefix returns up to the first up_to bytes of
16315 // s.
16316 static inline wuffs_base__slice_u8 //
16317 wuffs_private_impl__slice_u8__prefix(wuffs_base__slice_u8 s, uint64_t up_to) {
16318 if (((uint64_t)(s.len)) > up_to) {
16319 s.len = ((size_t)up_to);
16321 return s;
16324 // wuffs_private_impl__slice_u8__suffix returns up to the last up_to bytes of
16325 // s.
16326 static inline wuffs_base__slice_u8 //
16327 wuffs_private_impl__slice_u8__suffix(wuffs_base__slice_u8 s, uint64_t up_to) {
16328 if (((uint64_t)(s.len)) > up_to) {
16329 s.ptr += ((uint64_t)(s.len)) - up_to;
16330 s.len = ((size_t)up_to);
16332 return s;
16335 // wuffs_private_impl__slice_u8__copy_from_slice calls memmove(dst.ptr,
16336 // src.ptr, len) where len is the minimum of dst.len and src.len.
16338 // Passing a wuffs_base__slice_u8 with all fields NULL or zero (a valid, empty
16339 // slice) is valid and results in a no-op.
16340 static inline uint64_t //
16341 wuffs_private_impl__slice_u8__copy_from_slice(wuffs_base__slice_u8 dst,
16342 wuffs_base__slice_u8 src) {
16343 size_t len = dst.len < src.len ? dst.len : src.len;
16344 if (len > 0) {
16345 memmove(dst.ptr, src.ptr, len);
16347 return len;
16350 static inline wuffs_base__empty_struct //
16351 wuffs_private_impl__bulk_load_host_endian(void* ptr,
16352 size_t len,
16353 wuffs_base__slice_u8 src) {
16354 if (len && (len <= src.len)) {
16355 memmove(ptr, src.ptr, len);
16357 return wuffs_base__make_empty_struct();
16360 static inline wuffs_base__empty_struct //
16361 wuffs_private_impl__bulk_memset(void* ptr, size_t len, uint8_t byte_value) {
16362 if (len) {
16363 memset(ptr, byte_value, len);
16365 return wuffs_base__make_empty_struct();
16368 static inline wuffs_base__empty_struct //
16369 wuffs_private_impl__bulk_save_host_endian(void* ptr,
16370 size_t len,
16371 wuffs_base__slice_u8 dst) {
16372 if (len && (len <= dst.len)) {
16373 memmove(dst.ptr, ptr, len);
16375 return wuffs_base__make_empty_struct();
16378 // --------
16380 static inline wuffs_base__slice_u8 //
16381 wuffs_private_impl__table_u8__row_u32(wuffs_base__table_u8 t, uint32_t y) {
16382 if (t.ptr && (y < t.height)) {
16383 return wuffs_base__make_slice_u8(t.ptr + (t.stride * y), t.width);
16385 return wuffs_base__empty_slice_u8();
16388 // ---------------- Slices and Tables (Utility)
16390 #define wuffs_base__utility__empty_slice_u8 wuffs_base__empty_slice_u8
16392 // ---------------- Ranges and Rects
16394 static inline uint32_t //
16395 wuffs_private_impl__range_ii_u32__get_min_incl(
16396 const wuffs_base__range_ii_u32* r) {
16397 return r->min_incl;
16400 static inline uint32_t //
16401 wuffs_private_impl__range_ii_u32__get_max_incl(
16402 const wuffs_base__range_ii_u32* r) {
16403 return r->max_incl;
16406 static inline uint32_t //
16407 wuffs_private_impl__range_ie_u32__get_min_incl(
16408 const wuffs_base__range_ie_u32* r) {
16409 return r->min_incl;
16412 static inline uint32_t //
16413 wuffs_private_impl__range_ie_u32__get_max_excl(
16414 const wuffs_base__range_ie_u32* r) {
16415 return r->max_excl;
16418 static inline uint64_t //
16419 wuffs_private_impl__range_ii_u64__get_min_incl(
16420 const wuffs_base__range_ii_u64* r) {
16421 return r->min_incl;
16424 static inline uint64_t //
16425 wuffs_private_impl__range_ii_u64__get_max_incl(
16426 const wuffs_base__range_ii_u64* r) {
16427 return r->max_incl;
16430 static inline uint64_t //
16431 wuffs_private_impl__range_ie_u64__get_min_incl(
16432 const wuffs_base__range_ie_u64* r) {
16433 return r->min_incl;
16436 static inline uint64_t //
16437 wuffs_private_impl__range_ie_u64__get_max_excl(
16438 const wuffs_base__range_ie_u64* r) {
16439 return r->max_excl;
16442 // ---------------- Ranges and Rects (Utility)
16444 #define wuffs_base__utility__empty_range_ii_u32 wuffs_base__empty_range_ii_u32
16445 #define wuffs_base__utility__empty_range_ie_u32 wuffs_base__empty_range_ie_u32
16446 #define wuffs_base__utility__empty_range_ii_u64 wuffs_base__empty_range_ii_u64
16447 #define wuffs_base__utility__empty_range_ie_u64 wuffs_base__empty_range_ie_u64
16448 #define wuffs_base__utility__empty_rect_ii_u32 wuffs_base__empty_rect_ii_u32
16449 #define wuffs_base__utility__empty_rect_ie_u32 wuffs_base__empty_rect_ie_u32
16450 #define wuffs_base__utility__make_range_ii_u32 wuffs_base__make_range_ii_u32
16451 #define wuffs_base__utility__make_range_ie_u32 wuffs_base__make_range_ie_u32
16452 #define wuffs_base__utility__make_range_ii_u64 wuffs_base__make_range_ii_u64
16453 #define wuffs_base__utility__make_range_ie_u64 wuffs_base__make_range_ie_u64
16454 #define wuffs_base__utility__make_rect_ii_u32 wuffs_base__make_rect_ii_u32
16455 #define wuffs_base__utility__make_rect_ie_u32 wuffs_base__make_rect_ie_u32
16457 // ---------------- I/O
16459 static inline uint64_t //
16460 wuffs_private_impl__io__count_since(uint64_t mark, uint64_t index) {
16461 if (index >= mark) {
16462 return index - mark;
16464 return 0;
16467 // TODO: drop the "const" in "const uint8_t* ptr". Some though required about
16468 // the base.io_reader.since method returning a mutable "slice base.u8".
16469 #if defined(__GNUC__)
16470 #pragma GCC diagnostic push
16471 #pragma GCC diagnostic ignored "-Wcast-qual"
16472 #endif
16473 static inline wuffs_base__slice_u8 //
16474 wuffs_private_impl__io__since(uint64_t mark,
16475 uint64_t index,
16476 const uint8_t* ptr) {
16477 if (index >= mark) {
16478 return wuffs_base__make_slice_u8(((uint8_t*)ptr) + mark,
16479 ((size_t)(index - mark)));
16481 return wuffs_base__empty_slice_u8();
16483 #if defined(__GNUC__)
16484 #pragma GCC diagnostic pop
16485 #endif
16487 // --------
16489 static inline void //
16490 wuffs_private_impl__io_reader__limit(const uint8_t** ptr_io2_r,
16491 const uint8_t* iop_r,
16492 uint64_t limit) {
16493 if (((uint64_t)(*ptr_io2_r - iop_r)) > limit) {
16494 *ptr_io2_r = iop_r + limit;
16498 static inline uint32_t //
16499 wuffs_private_impl__io_reader__limited_copy_u32_to_slice(
16500 const uint8_t** ptr_iop_r,
16501 const uint8_t* io2_r,
16502 uint32_t length,
16503 wuffs_base__slice_u8 dst) {
16504 const uint8_t* iop_r = *ptr_iop_r;
16505 size_t n = dst.len;
16506 if (n > length) {
16507 n = length;
16509 if (n > ((size_t)(io2_r - iop_r))) {
16510 n = (size_t)(io2_r - iop_r);
16512 if (n > 0) {
16513 memmove(dst.ptr, iop_r, n);
16514 *ptr_iop_r += n;
16516 return (uint32_t)(n);
16519 // wuffs_private_impl__io_reader__match7 returns whether the io_reader's
16520 // upcoming bytes start with the given prefix (up to 7 bytes long). It is
16521 // peek-like, not read-like, in that there are no side-effects.
16523 // The low 3 bits of a hold the prefix length, n.
16525 // The high 56 bits of a hold the prefix itself, in little-endian order. The
16526 // first prefix byte is in bits 8..=15, the second prefix byte is in bits
16527 // 16..=23, etc. The high (8 * (7 - n)) bits are ignored.
16529 // There are three possible return values:
16530 // - 0 means success.
16531 // - 1 means inconclusive, equivalent to "$short read".
16532 // - 2 means failure.
16533 static inline uint32_t //
16534 wuffs_private_impl__io_reader__match7(const uint8_t* iop_r,
16535 const uint8_t* io2_r,
16536 wuffs_base__io_buffer* r,
16537 uint64_t a) {
16538 uint32_t n = a & 7;
16539 a >>= 8;
16540 if ((io2_r - iop_r) >= 8) {
16541 uint64_t x = wuffs_base__peek_u64le__no_bounds_check(iop_r);
16542 uint32_t shift = 8 * (8 - n);
16543 return ((a << shift) == (x << shift)) ? 0 : 2;
16545 for (; n > 0; n--) {
16546 if (iop_r >= io2_r) {
16547 return (r && r->meta.closed) ? 2 : 1;
16548 } else if (*iop_r != ((uint8_t)(a))) {
16549 return 2;
16551 iop_r++;
16552 a >>= 8;
16554 return 0;
16557 static inline wuffs_base__io_buffer* //
16558 wuffs_private_impl__io_reader__set(wuffs_base__io_buffer* b,
16559 const uint8_t** ptr_iop_r,
16560 const uint8_t** ptr_io0_r,
16561 const uint8_t** ptr_io1_r,
16562 const uint8_t** ptr_io2_r,
16563 wuffs_base__slice_u8 data,
16564 uint64_t history_position) {
16565 b->data = data;
16566 b->meta.wi = data.len;
16567 b->meta.ri = 0;
16568 b->meta.pos = history_position;
16569 b->meta.closed = false;
16571 *ptr_iop_r = data.ptr;
16572 *ptr_io0_r = data.ptr;
16573 *ptr_io1_r = data.ptr;
16574 *ptr_io2_r = data.ptr + data.len;
16576 return b;
16579 // --------
16581 static inline uint64_t //
16582 wuffs_private_impl__io_writer__copy_from_slice(uint8_t** ptr_iop_w,
16583 uint8_t* io2_w,
16584 wuffs_base__slice_u8 src) {
16585 uint8_t* iop_w = *ptr_iop_w;
16586 size_t n = src.len;
16587 if (n > ((size_t)(io2_w - iop_w))) {
16588 n = (size_t)(io2_w - iop_w);
16590 if (n > 0) {
16591 memmove(iop_w, src.ptr, n);
16592 *ptr_iop_w += n;
16594 return (uint64_t)(n);
16597 static inline void //
16598 wuffs_private_impl__io_writer__limit(uint8_t** ptr_io2_w,
16599 uint8_t* iop_w,
16600 uint64_t limit) {
16601 if (((uint64_t)(*ptr_io2_w - iop_w)) > limit) {
16602 *ptr_io2_w = iop_w + limit;
16606 static inline uint32_t //
16607 wuffs_private_impl__io_writer__limited_copy_u32_from_history(
16608 uint8_t** ptr_iop_w,
16609 uint8_t* io0_w,
16610 uint8_t* io2_w,
16611 uint32_t length,
16612 uint32_t distance) {
16613 if (!distance) {
16614 return 0;
16616 uint8_t* p = *ptr_iop_w;
16617 if ((size_t)(p - io0_w) < (size_t)(distance)) {
16618 return 0;
16620 uint8_t* q = p - distance;
16621 size_t n = (size_t)(io2_w - p);
16622 if ((size_t)(length) > n) {
16623 length = (uint32_t)(n);
16624 } else {
16625 n = (size_t)(length);
16627 // TODO: unrolling by 3 seems best for the std/deflate benchmarks, but that
16628 // is mostly because 3 is the minimum length for the deflate format. This
16629 // function implementation shouldn't overfit to that one format. Perhaps the
16630 // limited_copy_u32_from_history Wuffs method should also take an unroll hint
16631 // argument, and the cgen can look if that argument is the constant
16632 // expression '3'.
16634 // See also wuffs_private_impl__io_writer__limited_copy_u32_from_history_fast
16635 // below.
16636 for (; n >= 3; n -= 3) {
16637 *p++ = *q++;
16638 *p++ = *q++;
16639 *p++ = *q++;
16641 for (; n; n--) {
16642 *p++ = *q++;
16644 *ptr_iop_w = p;
16645 return length;
16648 // wuffs_private_impl__io_writer__limited_copy_u32_from_history_fast is like
16649 // the wuffs_private_impl__io_writer__limited_copy_u32_from_history function
16650 // above, but has stronger pre-conditions.
16652 // The caller needs to prove that:
16653 // - length >= 1
16654 // - length <= (io2_w - *ptr_iop_w)
16655 // - distance >= 1
16656 // - distance <= (*ptr_iop_w - io0_w)
16657 static inline uint32_t //
16658 wuffs_private_impl__io_writer__limited_copy_u32_from_history_fast(
16659 uint8_t** ptr_iop_w,
16660 uint8_t* io0_w,
16661 uint8_t* io2_w,
16662 uint32_t length,
16663 uint32_t distance) {
16664 uint8_t* p = *ptr_iop_w;
16665 uint8_t* q = p - distance;
16666 uint32_t n = length;
16667 for (; n >= 3; n -= 3) {
16668 *p++ = *q++;
16669 *p++ = *q++;
16670 *p++ = *q++;
16672 for (; n; n--) {
16673 *p++ = *q++;
16675 *ptr_iop_w = p;
16676 return length;
16679 // wuffs_private_impl__io_writer__limited_copy_u32_from_history_fast_return_cusp
16680 // is like the
16681 // wuffs_private_impl__io_writer__limited_copy_u32_from_history_fast function,
16682 // but also returns the cusp: a byte pair (as a u16le) being the last byte of
16683 // and next byte after the copied history.
16685 // For example, if history was [10, 11, 12, 13, 14, 15, 16, 17, 18] then:
16686 // - copying l=3, d=8 produces [11, 12, 13] and the cusp is (13, 14).
16687 // - copying l=3, d=2 produces [17, 18, 17] and the cusp is (17, 18).
16689 // The caller needs to prove that:
16690 // - length >= 1
16691 // - length <= (io2_w - *ptr_iop_w)
16692 // - distance >= 1
16693 // - distance <= (*ptr_iop_w - io0_w)
16694 static inline uint32_t //
16695 wuffs_private_impl__io_writer__limited_copy_u32_from_history_fast_return_cusp(
16696 uint8_t** ptr_iop_w,
16697 uint8_t* io0_w,
16698 uint8_t* io2_w,
16699 uint32_t length,
16700 uint32_t distance) {
16701 uint8_t* p = *ptr_iop_w;
16702 uint8_t* q = p - distance;
16703 uint32_t n = length;
16704 for (; n >= 3; n -= 3) {
16705 *p++ = *q++;
16706 *p++ = *q++;
16707 *p++ = *q++;
16709 for (; n; n--) {
16710 *p++ = *q++;
16712 *ptr_iop_w = p;
16713 return (uint32_t)wuffs_base__peek_u16le__no_bounds_check(q - 1);
16716 // wuffs_private_impl__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast
16717 // copies the previous byte (the one immediately before *ptr_iop_w), copying 8
16718 // byte chunks at a time. Each chunk contains 8 repetitions of the same byte.
16720 // In terms of number of bytes copied, length is rounded up to a multiple of 8.
16721 // As a special case, a zero length rounds up to 8 (even though 0 is already a
16722 // multiple of 8), since there is always at least one 8 byte chunk copied.
16724 // In terms of advancing *ptr_iop_w, length is not rounded up.
16726 // The caller needs to prove that:
16727 // - length >= 1
16728 // - (length + 8) <= (io2_w - *ptr_iop_w)
16729 // - distance == 1
16730 // - distance <= (*ptr_iop_w - io0_w)
16731 static inline uint32_t //
16732 wuffs_private_impl__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast(
16733 uint8_t** ptr_iop_w,
16734 uint8_t* io0_w,
16735 uint8_t* io2_w,
16736 uint32_t length,
16737 uint32_t distance) {
16738 uint8_t* p = *ptr_iop_w;
16739 uint64_t x = p[-1];
16740 x |= x << 8;
16741 x |= x << 16;
16742 x |= x << 32;
16743 uint32_t n = length;
16744 while (1) {
16745 wuffs_base__poke_u64le__no_bounds_check(p, x);
16746 if (n <= 8) {
16747 p += n;
16748 break;
16750 p += 8;
16751 n -= 8;
16753 *ptr_iop_w = p;
16754 return length;
16757 // wuffs_private_impl__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast_return_cusp
16758 // copies the previous byte (the one immediately before *ptr_iop_w), copying 8
16759 // byte chunks at a time. Each chunk contains 8 repetitions of the same byte.
16760 // It also returns the cusp: a byte pair (as a u16le) being the last byte of
16761 // and next byte after the copied history.
16763 // In terms of number of bytes copied, length is rounded up to a multiple of 8.
16764 // As a special case, a zero length rounds up to 8 (even though 0 is already a
16765 // multiple of 8), since there is always at least one 8 byte chunk copied.
16767 // In terms of advancing *ptr_iop_w, length is not rounded up.
16769 // The caller needs to prove that:
16770 // - length >= 1
16771 // - (length + 8) <= (io2_w - *ptr_iop_w)
16772 // - distance == 1
16773 // - distance <= (*ptr_iop_w - io0_w)
16774 static inline uint32_t //
16775 wuffs_private_impl__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast_return_cusp(
16776 uint8_t** ptr_iop_w,
16777 uint8_t* io0_w,
16778 uint8_t* io2_w,
16779 uint32_t length,
16780 uint32_t distance) {
16781 uint8_t* p = *ptr_iop_w;
16782 uint8_t* q = p - distance;
16783 uint64_t x = p[-1];
16784 x |= x << 8;
16785 x |= x << 16;
16786 x |= x << 32;
16787 uint32_t n = length;
16788 while (1) {
16789 wuffs_base__poke_u64le__no_bounds_check(p, x);
16790 if (n <= 8) {
16791 p += n;
16792 q += n;
16793 break;
16795 p += 8;
16796 q += 8;
16797 n -= 8;
16799 *ptr_iop_w = p;
16800 return (uint32_t)wuffs_base__peek_u16le__no_bounds_check(q - 1);
16803 // wuffs_private_impl__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast
16804 // is like the
16805 // wuffs_private_impl__io_writer__limited_copy_u32_from_history_fast function
16806 // above, but copies 8 byte chunks at a time.
16808 // In terms of number of bytes copied, length is rounded up to a multiple of 8.
16809 // As a special case, a zero length rounds up to 8 (even though 0 is already a
16810 // multiple of 8), since there is always at least one 8 byte chunk copied.
16812 // In terms of advancing *ptr_iop_w, length is not rounded up.
16814 // The caller needs to prove that:
16815 // - length >= 1
16816 // - (length + 8) <= (io2_w - *ptr_iop_w)
16817 // - distance >= 8
16818 // - distance <= (*ptr_iop_w - io0_w)
16819 static inline uint32_t //
16820 wuffs_private_impl__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast(
16821 uint8_t** ptr_iop_w,
16822 uint8_t* io0_w,
16823 uint8_t* io2_w,
16824 uint32_t length,
16825 uint32_t distance) {
16826 uint8_t* p = *ptr_iop_w;
16827 uint8_t* q = p - distance;
16828 uint32_t n = length;
16829 while (1) {
16830 memcpy(p, q, 8);
16831 if (n <= 8) {
16832 p += n;
16833 break;
16835 p += 8;
16836 q += 8;
16837 n -= 8;
16839 *ptr_iop_w = p;
16840 return length;
16843 // wuffs_private_impl__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast_return_cusp
16844 // is like the
16845 // wuffs_private_impl__io_writer__limited_copy_u32_from_history_fast function
16846 // above, but copies 8 byte chunks at a time. It also returns the cusp: a byte
16847 // pair (as a u16le) being the last byte of and next byte after the copied
16848 // history.
16850 // In terms of number of bytes copied, length is rounded up to a multiple of 8.
16851 // As a special case, a zero length rounds up to 8 (even though 0 is already a
16852 // multiple of 8), since there is always at least one 8 byte chunk copied.
16854 // In terms of advancing *ptr_iop_w, length is not rounded up.
16856 // The caller needs to prove that:
16857 // - length >= 1
16858 // - (length + 8) <= (io2_w - *ptr_iop_w)
16859 // - distance >= 8
16860 // - distance <= (*ptr_iop_w - io0_w)
16861 static inline uint32_t //
16862 wuffs_private_impl__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast_return_cusp(
16863 uint8_t** ptr_iop_w,
16864 uint8_t* io0_w,
16865 uint8_t* io2_w,
16866 uint32_t length,
16867 uint32_t distance) {
16868 uint8_t* p = *ptr_iop_w;
16869 uint8_t* q = p - distance;
16870 uint32_t n = length;
16871 while (1) {
16872 memcpy(p, q, 8);
16873 if (n <= 8) {
16874 p += n;
16875 q += n;
16876 break;
16878 p += 8;
16879 q += 8;
16880 n -= 8;
16882 *ptr_iop_w = p;
16883 return (uint32_t)wuffs_base__peek_u16le__no_bounds_check(q - 1);
16886 static inline uint32_t //
16887 wuffs_private_impl__io_writer__limited_copy_u32_from_reader(
16888 uint8_t** ptr_iop_w,
16889 uint8_t* io2_w,
16890 uint32_t length,
16891 const uint8_t** ptr_iop_r,
16892 const uint8_t* io2_r) {
16893 uint8_t* iop_w = *ptr_iop_w;
16894 size_t n = length;
16895 if (n > ((size_t)(io2_w - iop_w))) {
16896 n = (size_t)(io2_w - iop_w);
16898 const uint8_t* iop_r = *ptr_iop_r;
16899 if (n > ((size_t)(io2_r - iop_r))) {
16900 n = (size_t)(io2_r - iop_r);
16902 if (n > 0) {
16903 memmove(iop_w, iop_r, n);
16904 *ptr_iop_w += n;
16905 *ptr_iop_r += n;
16907 return (uint32_t)(n);
16910 static inline uint32_t //
16911 wuffs_private_impl__io_writer__limited_copy_u32_from_slice(
16912 uint8_t** ptr_iop_w,
16913 uint8_t* io2_w,
16914 uint32_t length,
16915 wuffs_base__slice_u8 src) {
16916 uint8_t* iop_w = *ptr_iop_w;
16917 size_t n = src.len;
16918 if (n > length) {
16919 n = length;
16921 if (n > ((size_t)(io2_w - iop_w))) {
16922 n = (size_t)(io2_w - iop_w);
16924 if (n > 0) {
16925 memmove(iop_w, src.ptr, n);
16926 *ptr_iop_w += n;
16928 return (uint32_t)(n);
16931 static inline wuffs_base__io_buffer* //
16932 wuffs_private_impl__io_writer__set(wuffs_base__io_buffer* b,
16933 uint8_t** ptr_iop_w,
16934 uint8_t** ptr_io0_w,
16935 uint8_t** ptr_io1_w,
16936 uint8_t** ptr_io2_w,
16937 wuffs_base__slice_u8 data,
16938 uint64_t history_position) {
16939 b->data = data;
16940 b->meta.wi = 0;
16941 b->meta.ri = 0;
16942 b->meta.pos = history_position;
16943 b->meta.closed = false;
16945 *ptr_iop_w = data.ptr;
16946 *ptr_io0_w = data.ptr;
16947 *ptr_io1_w = data.ptr;
16948 *ptr_io2_w = data.ptr + data.len;
16950 return b;
16953 // ---------------- I/O (Utility)
16955 #define wuffs_base__utility__empty_io_reader wuffs_base__empty_io_reader
16956 #define wuffs_base__utility__empty_io_writer wuffs_base__empty_io_writer
16958 // ---------------- Tokens
16960 // ---------------- Tokens (Utility)
16962 // ---------------- Memory Allocation
16964 // ---------------- Images
16966 WUFFS_BASE__MAYBE_STATIC uint64_t //
16967 wuffs_base__pixel_swizzler__limited_swizzle_u32_interleaved_from_reader(
16968 const wuffs_base__pixel_swizzler* p,
16969 uint32_t up_to_num_pixels,
16970 wuffs_base__slice_u8 dst,
16971 wuffs_base__slice_u8 dst_palette,
16972 const uint8_t** ptr_iop_r,
16973 const uint8_t* io2_r);
16975 WUFFS_BASE__MAYBE_STATIC uint64_t //
16976 wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(
16977 const wuffs_base__pixel_swizzler* p,
16978 wuffs_base__slice_u8 dst,
16979 wuffs_base__slice_u8 dst_palette,
16980 const uint8_t** ptr_iop_r,
16981 const uint8_t* io2_r);
16983 WUFFS_BASE__MAYBE_STATIC uint64_t //
16984 wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(
16985 const wuffs_base__pixel_swizzler* p,
16986 wuffs_base__slice_u8 dst,
16987 wuffs_base__slice_u8 dst_palette,
16988 uint64_t num_pixels);
16990 WUFFS_BASE__MAYBE_STATIC wuffs_base__status //
16991 wuffs_base__pixel_swizzler__swizzle_ycck(
16992 const wuffs_base__pixel_swizzler* p,
16993 wuffs_base__pixel_buffer* dst,
16994 wuffs_base__slice_u8 dst_palette,
16995 uint32_t x_min_incl,
16996 uint32_t x_max_excl,
16997 uint32_t y_min_incl,
16998 uint32_t y_max_excl,
16999 wuffs_base__slice_u8 src0,
17000 wuffs_base__slice_u8 src1,
17001 wuffs_base__slice_u8 src2,
17002 wuffs_base__slice_u8 src3,
17003 uint32_t width0,
17004 uint32_t width1,
17005 uint32_t width2,
17006 uint32_t width3,
17007 uint32_t height0,
17008 uint32_t height1,
17009 uint32_t height2,
17010 uint32_t height3,
17011 uint32_t stride0,
17012 uint32_t stride1,
17013 uint32_t stride2,
17014 uint32_t stride3,
17015 uint8_t h0,
17016 uint8_t h1,
17017 uint8_t h2,
17018 uint8_t h3,
17019 uint8_t v0,
17020 uint8_t v1,
17021 uint8_t v2,
17022 uint8_t v3,
17023 bool is_rgb_or_cmyk,
17024 bool triangle_filter_for_2to1,
17025 wuffs_base__slice_u8 scratch_buffer_2k);
17027 // ---------------- Images (Utility)
17029 #define wuffs_base__utility__make_pixel_format wuffs_base__make_pixel_format
17031 // ---------------- String Conversions
17033 // ---------------- Unicode and UTF-8
17035 // ----------------
17037 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
17038 defined(WUFFS_CONFIG__MODULE__BASE__CORE)
17040 const uint8_t wuffs_private_impl__low_bits_mask__u8[8] = {
17041 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F,
17044 const uint16_t wuffs_private_impl__low_bits_mask__u16[16] = {
17045 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F,
17046 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF,
17049 const uint32_t wuffs_private_impl__low_bits_mask__u32[32] = {
17050 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000F, 0x0000001F,
17051 0x0000003F, 0x0000007F, 0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF,
17052 0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF, 0x0001FFFF,
17053 0x0003FFFF, 0x0007FFFF, 0x000FFFFF, 0x001FFFFF, 0x003FFFFF, 0x007FFFFF,
17054 0x00FFFFFF, 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF, 0x1FFFFFFF,
17055 0x3FFFFFFF, 0x7FFFFFFF,
17058 const uint64_t wuffs_private_impl__low_bits_mask__u64[64] = {
17059 0x0000000000000000, 0x0000000000000001, 0x0000000000000003,
17060 0x0000000000000007, 0x000000000000000F, 0x000000000000001F,
17061 0x000000000000003F, 0x000000000000007F, 0x00000000000000FF,
17062 0x00000000000001FF, 0x00000000000003FF, 0x00000000000007FF,
17063 0x0000000000000FFF, 0x0000000000001FFF, 0x0000000000003FFF,
17064 0x0000000000007FFF, 0x000000000000FFFF, 0x000000000001FFFF,
17065 0x000000000003FFFF, 0x000000000007FFFF, 0x00000000000FFFFF,
17066 0x00000000001FFFFF, 0x00000000003FFFFF, 0x00000000007FFFFF,
17067 0x0000000000FFFFFF, 0x0000000001FFFFFF, 0x0000000003FFFFFF,
17068 0x0000000007FFFFFF, 0x000000000FFFFFFF, 0x000000001FFFFFFF,
17069 0x000000003FFFFFFF, 0x000000007FFFFFFF, 0x00000000FFFFFFFF,
17070 0x00000001FFFFFFFF, 0x00000003FFFFFFFF, 0x00000007FFFFFFFF,
17071 0x0000000FFFFFFFFF, 0x0000001FFFFFFFFF, 0x0000003FFFFFFFFF,
17072 0x0000007FFFFFFFFF, 0x000000FFFFFFFFFF, 0x000001FFFFFFFFFF,
17073 0x000003FFFFFFFFFF, 0x000007FFFFFFFFFF, 0x00000FFFFFFFFFFF,
17074 0x00001FFFFFFFFFFF, 0x00003FFFFFFFFFFF, 0x00007FFFFFFFFFFF,
17075 0x0000FFFFFFFFFFFF, 0x0001FFFFFFFFFFFF, 0x0003FFFFFFFFFFFF,
17076 0x0007FFFFFFFFFFFF, 0x000FFFFFFFFFFFFF, 0x001FFFFFFFFFFFFF,
17077 0x003FFFFFFFFFFFFF, 0x007FFFFFFFFFFFFF, 0x00FFFFFFFFFFFFFF,
17078 0x01FFFFFFFFFFFFFF, 0x03FFFFFFFFFFFFFF, 0x07FFFFFFFFFFFFFF,
17079 0x0FFFFFFFFFFFFFFF, 0x1FFFFFFFFFFFFFFF, 0x3FFFFFFFFFFFFFFF,
17080 0x7FFFFFFFFFFFFFFF,
17083 const uint32_t wuffs_private_impl__pixel_format__bits_per_channel[16] = {
17084 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
17085 0x08, 0x0A, 0x0C, 0x10, 0x18, 0x20, 0x30, 0x40,
17088 const char wuffs_base__note__i_o_redirect[] = "@base: I/O redirect";
17089 const char wuffs_base__note__end_of_data[] = "@base: end of data";
17090 const char wuffs_base__note__metadata_reported[] = "@base: metadata reported";
17091 const char wuffs_base__suspension__even_more_information[] = "$base: even more information";
17092 const char wuffs_base__suspension__mispositioned_read[] = "$base: mispositioned read";
17093 const char wuffs_base__suspension__mispositioned_write[] = "$base: mispositioned write";
17094 const char wuffs_base__suspension__short_read[] = "$base: short read";
17095 const char wuffs_base__suspension__short_workbuf[] = "$base: short workbuf";
17096 const char wuffs_base__suspension__short_write[] = "$base: short write";
17097 const char wuffs_base__error__bad_i_o_position[] = "#base: bad I/O position";
17098 const char wuffs_base__error__bad_argument_length_too_short[] = "#base: bad argument (length too short)";
17099 const char wuffs_base__error__bad_argument[] = "#base: bad argument";
17100 const char wuffs_base__error__bad_call_sequence[] = "#base: bad call sequence";
17101 const char wuffs_base__error__bad_data[] = "#base: bad data";
17102 const char wuffs_base__error__bad_receiver[] = "#base: bad receiver";
17103 const char wuffs_base__error__bad_restart[] = "#base: bad restart";
17104 const char wuffs_base__error__bad_sizeof_receiver[] = "#base: bad sizeof receiver";
17105 const char wuffs_base__error__bad_vtable[] = "#base: bad vtable";
17106 const char wuffs_base__error__bad_workbuf_length[] = "#base: bad workbuf length";
17107 const char wuffs_base__error__bad_wuffs_version[] = "#base: bad wuffs version";
17108 const char wuffs_base__error__cannot_return_a_suspension[] = "#base: cannot return a suspension";
17109 const char wuffs_base__error__disabled_by_wuffs_config_dst_pixel_format_enable_allowlist[] = "#base: disabled by WUFFS_CONFIG__DST_PIXEL_FORMAT__ENABLE_ALLOWLIST";
17110 const char wuffs_base__error__disabled_by_previous_error[] = "#base: disabled by previous error";
17111 const char wuffs_base__error__initialize_falsely_claimed_already_zeroed[] = "#base: initialize falsely claimed already zeroed";
17112 const char wuffs_base__error__initialize_not_called[] = "#base: initialize not called";
17113 const char wuffs_base__error__insufficient_history[] = "#base: insufficient history";
17114 const char wuffs_base__error__interleaved_coroutine_calls[] = "#base: interleaved coroutine calls";
17115 const char wuffs_base__error__no_more_information[] = "#base: no more information";
17116 const char wuffs_base__error__not_enough_data[] = "#base: not enough data";
17117 const char wuffs_base__error__out_of_bounds[] = "#base: out of bounds";
17118 const char wuffs_base__error__unsupported_image_dimension[] = "#base: unsupported image dimension";
17119 const char wuffs_base__error__unsupported_method[] = "#base: unsupported method";
17120 const char wuffs_base__error__unsupported_option[] = "#base: unsupported option";
17121 const char wuffs_base__error__unsupported_pixel_swizzler_option[] = "#base: unsupported pixel swizzler option";
17122 const char wuffs_base__error__too_much_data[] = "#base: too much data";
17124 const char wuffs_base__hasher_u32__vtable_name[] = "{vtable}wuffs_base__hasher_u32";
17125 const char wuffs_base__hasher_u64__vtable_name[] = "{vtable}wuffs_base__hasher_u64";
17126 const char wuffs_base__hasher_bitvec256__vtable_name[] = "{vtable}wuffs_base__hasher_bitvec256";
17127 const char wuffs_base__image_decoder__vtable_name[] = "{vtable}wuffs_base__image_decoder";
17128 const char wuffs_base__io_transformer__vtable_name[] = "{vtable}wuffs_base__io_transformer";
17129 const char wuffs_base__token_decoder__vtable_name[] = "{vtable}wuffs_base__token_decoder";
17131 #endif // !defined(WUFFS_CONFIG__MODULES) ||
17132 // defined(WUFFS_CONFIG__MODULE__BASE) ||
17133 // defined(WUFFS_CONFIG__MODULE__BASE__CORE)
17135 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
17136 defined(WUFFS_CONFIG__MODULE__BASE__INTERFACES)
17138 // ---------------- Interface Definitions.
17140 WUFFS_BASE__GENERATED_C_CODE
17141 WUFFS_BASE__MAYBE_STATIC uint32_t
17142 wuffs_base__hasher_u32__checksum_u32(
17143 const wuffs_base__hasher_u32* self) {
17144 if (!self) {
17145 return 0;
17147 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
17148 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
17149 return 0;
17152 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
17153 int i;
17154 for (i = 0; i < 63; i++) {
17155 if (v->vtable_name == wuffs_base__hasher_u32__vtable_name) {
17156 const wuffs_base__hasher_u32__func_ptrs* func_ptrs =
17157 (const wuffs_base__hasher_u32__func_ptrs*)(v->function_pointers);
17158 return (*func_ptrs->checksum_u32)(self);
17159 } else if (v->vtable_name == NULL) {
17160 break;
17162 v++;
17165 return 0;
17168 WUFFS_BASE__GENERATED_C_CODE
17169 WUFFS_BASE__MAYBE_STATIC uint64_t
17170 wuffs_base__hasher_u32__get_quirk(
17171 const wuffs_base__hasher_u32* self,
17172 uint32_t a_key) {
17173 if (!self) {
17174 return 0;
17176 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
17177 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
17178 return 0;
17181 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
17182 int i;
17183 for (i = 0; i < 63; i++) {
17184 if (v->vtable_name == wuffs_base__hasher_u32__vtable_name) {
17185 const wuffs_base__hasher_u32__func_ptrs* func_ptrs =
17186 (const wuffs_base__hasher_u32__func_ptrs*)(v->function_pointers);
17187 return (*func_ptrs->get_quirk)(self, a_key);
17188 } else if (v->vtable_name == NULL) {
17189 break;
17191 v++;
17194 return 0;
17197 WUFFS_BASE__GENERATED_C_CODE
17198 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
17199 wuffs_base__hasher_u32__set_quirk(
17200 wuffs_base__hasher_u32* self,
17201 uint32_t a_key,
17202 uint64_t a_value) {
17203 if (!self) {
17204 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
17206 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
17207 return wuffs_base__make_status(
17208 (self->private_impl.magic == WUFFS_BASE__DISABLED)
17209 ? wuffs_base__error__disabled_by_previous_error
17210 : wuffs_base__error__initialize_not_called);
17213 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
17214 int i;
17215 for (i = 0; i < 63; i++) {
17216 if (v->vtable_name == wuffs_base__hasher_u32__vtable_name) {
17217 const wuffs_base__hasher_u32__func_ptrs* func_ptrs =
17218 (const wuffs_base__hasher_u32__func_ptrs*)(v->function_pointers);
17219 return (*func_ptrs->set_quirk)(self, a_key, a_value);
17220 } else if (v->vtable_name == NULL) {
17221 break;
17223 v++;
17226 return wuffs_base__make_status(wuffs_base__error__bad_vtable);
17229 WUFFS_BASE__GENERATED_C_CODE
17230 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
17231 wuffs_base__hasher_u32__update(
17232 wuffs_base__hasher_u32* self,
17233 wuffs_base__slice_u8 a_x) {
17234 if (!self) {
17235 return wuffs_base__make_empty_struct();
17237 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
17238 return wuffs_base__make_empty_struct();
17241 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
17242 int i;
17243 for (i = 0; i < 63; i++) {
17244 if (v->vtable_name == wuffs_base__hasher_u32__vtable_name) {
17245 const wuffs_base__hasher_u32__func_ptrs* func_ptrs =
17246 (const wuffs_base__hasher_u32__func_ptrs*)(v->function_pointers);
17247 return (*func_ptrs->update)(self, a_x);
17248 } else if (v->vtable_name == NULL) {
17249 break;
17251 v++;
17254 return wuffs_base__make_empty_struct();
17257 WUFFS_BASE__GENERATED_C_CODE
17258 WUFFS_BASE__MAYBE_STATIC uint32_t
17259 wuffs_base__hasher_u32__update_u32(
17260 wuffs_base__hasher_u32* self,
17261 wuffs_base__slice_u8 a_x) {
17262 if (!self) {
17263 return 0;
17265 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
17266 return 0;
17269 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
17270 int i;
17271 for (i = 0; i < 63; i++) {
17272 if (v->vtable_name == wuffs_base__hasher_u32__vtable_name) {
17273 const wuffs_base__hasher_u32__func_ptrs* func_ptrs =
17274 (const wuffs_base__hasher_u32__func_ptrs*)(v->function_pointers);
17275 return (*func_ptrs->update_u32)(self, a_x);
17276 } else if (v->vtable_name == NULL) {
17277 break;
17279 v++;
17282 return 0;
17285 // --------
17287 WUFFS_BASE__GENERATED_C_CODE
17288 WUFFS_BASE__MAYBE_STATIC uint64_t
17289 wuffs_base__hasher_u64__checksum_u64(
17290 const wuffs_base__hasher_u64* self) {
17291 if (!self) {
17292 return 0;
17294 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
17295 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
17296 return 0;
17299 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
17300 int i;
17301 for (i = 0; i < 63; i++) {
17302 if (v->vtable_name == wuffs_base__hasher_u64__vtable_name) {
17303 const wuffs_base__hasher_u64__func_ptrs* func_ptrs =
17304 (const wuffs_base__hasher_u64__func_ptrs*)(v->function_pointers);
17305 return (*func_ptrs->checksum_u64)(self);
17306 } else if (v->vtable_name == NULL) {
17307 break;
17309 v++;
17312 return 0;
17315 WUFFS_BASE__GENERATED_C_CODE
17316 WUFFS_BASE__MAYBE_STATIC uint64_t
17317 wuffs_base__hasher_u64__get_quirk(
17318 const wuffs_base__hasher_u64* self,
17319 uint32_t a_key) {
17320 if (!self) {
17321 return 0;
17323 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
17324 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
17325 return 0;
17328 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
17329 int i;
17330 for (i = 0; i < 63; i++) {
17331 if (v->vtable_name == wuffs_base__hasher_u64__vtable_name) {
17332 const wuffs_base__hasher_u64__func_ptrs* func_ptrs =
17333 (const wuffs_base__hasher_u64__func_ptrs*)(v->function_pointers);
17334 return (*func_ptrs->get_quirk)(self, a_key);
17335 } else if (v->vtable_name == NULL) {
17336 break;
17338 v++;
17341 return 0;
17344 WUFFS_BASE__GENERATED_C_CODE
17345 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
17346 wuffs_base__hasher_u64__set_quirk(
17347 wuffs_base__hasher_u64* self,
17348 uint32_t a_key,
17349 uint64_t a_value) {
17350 if (!self) {
17351 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
17353 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
17354 return wuffs_base__make_status(
17355 (self->private_impl.magic == WUFFS_BASE__DISABLED)
17356 ? wuffs_base__error__disabled_by_previous_error
17357 : wuffs_base__error__initialize_not_called);
17360 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
17361 int i;
17362 for (i = 0; i < 63; i++) {
17363 if (v->vtable_name == wuffs_base__hasher_u64__vtable_name) {
17364 const wuffs_base__hasher_u64__func_ptrs* func_ptrs =
17365 (const wuffs_base__hasher_u64__func_ptrs*)(v->function_pointers);
17366 return (*func_ptrs->set_quirk)(self, a_key, a_value);
17367 } else if (v->vtable_name == NULL) {
17368 break;
17370 v++;
17373 return wuffs_base__make_status(wuffs_base__error__bad_vtable);
17376 WUFFS_BASE__GENERATED_C_CODE
17377 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
17378 wuffs_base__hasher_u64__update(
17379 wuffs_base__hasher_u64* self,
17380 wuffs_base__slice_u8 a_x) {
17381 if (!self) {
17382 return wuffs_base__make_empty_struct();
17384 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
17385 return wuffs_base__make_empty_struct();
17388 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
17389 int i;
17390 for (i = 0; i < 63; i++) {
17391 if (v->vtable_name == wuffs_base__hasher_u64__vtable_name) {
17392 const wuffs_base__hasher_u64__func_ptrs* func_ptrs =
17393 (const wuffs_base__hasher_u64__func_ptrs*)(v->function_pointers);
17394 return (*func_ptrs->update)(self, a_x);
17395 } else if (v->vtable_name == NULL) {
17396 break;
17398 v++;
17401 return wuffs_base__make_empty_struct();
17404 WUFFS_BASE__GENERATED_C_CODE
17405 WUFFS_BASE__MAYBE_STATIC uint64_t
17406 wuffs_base__hasher_u64__update_u64(
17407 wuffs_base__hasher_u64* self,
17408 wuffs_base__slice_u8 a_x) {
17409 if (!self) {
17410 return 0;
17412 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
17413 return 0;
17416 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
17417 int i;
17418 for (i = 0; i < 63; i++) {
17419 if (v->vtable_name == wuffs_base__hasher_u64__vtable_name) {
17420 const wuffs_base__hasher_u64__func_ptrs* func_ptrs =
17421 (const wuffs_base__hasher_u64__func_ptrs*)(v->function_pointers);
17422 return (*func_ptrs->update_u64)(self, a_x);
17423 } else if (v->vtable_name == NULL) {
17424 break;
17426 v++;
17429 return 0;
17432 // --------
17434 WUFFS_BASE__GENERATED_C_CODE
17435 WUFFS_BASE__MAYBE_STATIC wuffs_base__bitvec256
17436 wuffs_base__hasher_bitvec256__checksum_bitvec256(
17437 const wuffs_base__hasher_bitvec256* self) {
17438 if (!self) {
17439 return wuffs_base__utility__make_bitvec256(0u, 0u, 0u, 0u);
17441 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
17442 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
17443 return wuffs_base__utility__make_bitvec256(0u, 0u, 0u, 0u);
17446 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
17447 int i;
17448 for (i = 0; i < 63; i++) {
17449 if (v->vtable_name == wuffs_base__hasher_bitvec256__vtable_name) {
17450 const wuffs_base__hasher_bitvec256__func_ptrs* func_ptrs =
17451 (const wuffs_base__hasher_bitvec256__func_ptrs*)(v->function_pointers);
17452 return (*func_ptrs->checksum_bitvec256)(self);
17453 } else if (v->vtable_name == NULL) {
17454 break;
17456 v++;
17459 return wuffs_base__utility__make_bitvec256(0u, 0u, 0u, 0u);
17462 WUFFS_BASE__GENERATED_C_CODE
17463 WUFFS_BASE__MAYBE_STATIC uint64_t
17464 wuffs_base__hasher_bitvec256__get_quirk(
17465 const wuffs_base__hasher_bitvec256* self,
17466 uint32_t a_key) {
17467 if (!self) {
17468 return 0;
17470 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
17471 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
17472 return 0;
17475 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
17476 int i;
17477 for (i = 0; i < 63; i++) {
17478 if (v->vtable_name == wuffs_base__hasher_bitvec256__vtable_name) {
17479 const wuffs_base__hasher_bitvec256__func_ptrs* func_ptrs =
17480 (const wuffs_base__hasher_bitvec256__func_ptrs*)(v->function_pointers);
17481 return (*func_ptrs->get_quirk)(self, a_key);
17482 } else if (v->vtable_name == NULL) {
17483 break;
17485 v++;
17488 return 0;
17491 WUFFS_BASE__GENERATED_C_CODE
17492 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
17493 wuffs_base__hasher_bitvec256__set_quirk(
17494 wuffs_base__hasher_bitvec256* self,
17495 uint32_t a_key,
17496 uint64_t a_value) {
17497 if (!self) {
17498 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
17500 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
17501 return wuffs_base__make_status(
17502 (self->private_impl.magic == WUFFS_BASE__DISABLED)
17503 ? wuffs_base__error__disabled_by_previous_error
17504 : wuffs_base__error__initialize_not_called);
17507 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
17508 int i;
17509 for (i = 0; i < 63; i++) {
17510 if (v->vtable_name == wuffs_base__hasher_bitvec256__vtable_name) {
17511 const wuffs_base__hasher_bitvec256__func_ptrs* func_ptrs =
17512 (const wuffs_base__hasher_bitvec256__func_ptrs*)(v->function_pointers);
17513 return (*func_ptrs->set_quirk)(self, a_key, a_value);
17514 } else if (v->vtable_name == NULL) {
17515 break;
17517 v++;
17520 return wuffs_base__make_status(wuffs_base__error__bad_vtable);
17523 WUFFS_BASE__GENERATED_C_CODE
17524 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
17525 wuffs_base__hasher_bitvec256__update(
17526 wuffs_base__hasher_bitvec256* self,
17527 wuffs_base__slice_u8 a_x) {
17528 if (!self) {
17529 return wuffs_base__make_empty_struct();
17531 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
17532 return wuffs_base__make_empty_struct();
17535 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
17536 int i;
17537 for (i = 0; i < 63; i++) {
17538 if (v->vtable_name == wuffs_base__hasher_bitvec256__vtable_name) {
17539 const wuffs_base__hasher_bitvec256__func_ptrs* func_ptrs =
17540 (const wuffs_base__hasher_bitvec256__func_ptrs*)(v->function_pointers);
17541 return (*func_ptrs->update)(self, a_x);
17542 } else if (v->vtable_name == NULL) {
17543 break;
17545 v++;
17548 return wuffs_base__make_empty_struct();
17551 WUFFS_BASE__GENERATED_C_CODE
17552 WUFFS_BASE__MAYBE_STATIC wuffs_base__bitvec256
17553 wuffs_base__hasher_bitvec256__update_bitvec256(
17554 wuffs_base__hasher_bitvec256* self,
17555 wuffs_base__slice_u8 a_x) {
17556 if (!self) {
17557 return wuffs_base__utility__make_bitvec256(0u, 0u, 0u, 0u);
17559 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
17560 return wuffs_base__utility__make_bitvec256(0u, 0u, 0u, 0u);
17563 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
17564 int i;
17565 for (i = 0; i < 63; i++) {
17566 if (v->vtable_name == wuffs_base__hasher_bitvec256__vtable_name) {
17567 const wuffs_base__hasher_bitvec256__func_ptrs* func_ptrs =
17568 (const wuffs_base__hasher_bitvec256__func_ptrs*)(v->function_pointers);
17569 return (*func_ptrs->update_bitvec256)(self, a_x);
17570 } else if (v->vtable_name == NULL) {
17571 break;
17573 v++;
17576 return wuffs_base__utility__make_bitvec256(0u, 0u, 0u, 0u);
17579 // --------
17581 WUFFS_BASE__GENERATED_C_CODE
17582 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
17583 wuffs_base__image_decoder__decode_frame(
17584 wuffs_base__image_decoder* self,
17585 wuffs_base__pixel_buffer* a_dst,
17586 wuffs_base__io_buffer* a_src,
17587 wuffs_base__pixel_blend a_blend,
17588 wuffs_base__slice_u8 a_workbuf,
17589 wuffs_base__decode_frame_options* a_opts) {
17590 if (!self) {
17591 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
17593 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
17594 return wuffs_base__make_status(
17595 (self->private_impl.magic == WUFFS_BASE__DISABLED)
17596 ? wuffs_base__error__disabled_by_previous_error
17597 : wuffs_base__error__initialize_not_called);
17600 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
17601 int i;
17602 for (i = 0; i < 63; i++) {
17603 if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
17604 const wuffs_base__image_decoder__func_ptrs* func_ptrs =
17605 (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
17606 return (*func_ptrs->decode_frame)(self, a_dst, a_src, a_blend, a_workbuf, a_opts);
17607 } else if (v->vtable_name == NULL) {
17608 break;
17610 v++;
17613 return wuffs_base__make_status(wuffs_base__error__bad_vtable);
17616 WUFFS_BASE__GENERATED_C_CODE
17617 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
17618 wuffs_base__image_decoder__decode_frame_config(
17619 wuffs_base__image_decoder* self,
17620 wuffs_base__frame_config* a_dst,
17621 wuffs_base__io_buffer* a_src) {
17622 if (!self) {
17623 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
17625 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
17626 return wuffs_base__make_status(
17627 (self->private_impl.magic == WUFFS_BASE__DISABLED)
17628 ? wuffs_base__error__disabled_by_previous_error
17629 : wuffs_base__error__initialize_not_called);
17632 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
17633 int i;
17634 for (i = 0; i < 63; i++) {
17635 if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
17636 const wuffs_base__image_decoder__func_ptrs* func_ptrs =
17637 (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
17638 return (*func_ptrs->decode_frame_config)(self, a_dst, a_src);
17639 } else if (v->vtable_name == NULL) {
17640 break;
17642 v++;
17645 return wuffs_base__make_status(wuffs_base__error__bad_vtable);
17648 WUFFS_BASE__GENERATED_C_CODE
17649 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
17650 wuffs_base__image_decoder__decode_image_config(
17651 wuffs_base__image_decoder* self,
17652 wuffs_base__image_config* a_dst,
17653 wuffs_base__io_buffer* a_src) {
17654 if (!self) {
17655 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
17657 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
17658 return wuffs_base__make_status(
17659 (self->private_impl.magic == WUFFS_BASE__DISABLED)
17660 ? wuffs_base__error__disabled_by_previous_error
17661 : wuffs_base__error__initialize_not_called);
17664 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
17665 int i;
17666 for (i = 0; i < 63; i++) {
17667 if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
17668 const wuffs_base__image_decoder__func_ptrs* func_ptrs =
17669 (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
17670 return (*func_ptrs->decode_image_config)(self, a_dst, a_src);
17671 } else if (v->vtable_name == NULL) {
17672 break;
17674 v++;
17677 return wuffs_base__make_status(wuffs_base__error__bad_vtable);
17680 WUFFS_BASE__GENERATED_C_CODE
17681 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
17682 wuffs_base__image_decoder__frame_dirty_rect(
17683 const wuffs_base__image_decoder* self) {
17684 if (!self) {
17685 return wuffs_base__utility__empty_rect_ie_u32();
17687 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
17688 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
17689 return wuffs_base__utility__empty_rect_ie_u32();
17692 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
17693 int i;
17694 for (i = 0; i < 63; i++) {
17695 if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
17696 const wuffs_base__image_decoder__func_ptrs* func_ptrs =
17697 (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
17698 return (*func_ptrs->frame_dirty_rect)(self);
17699 } else if (v->vtable_name == NULL) {
17700 break;
17702 v++;
17705 return wuffs_base__utility__empty_rect_ie_u32();
17708 WUFFS_BASE__GENERATED_C_CODE
17709 WUFFS_BASE__MAYBE_STATIC uint64_t
17710 wuffs_base__image_decoder__get_quirk(
17711 const wuffs_base__image_decoder* self,
17712 uint32_t a_key) {
17713 if (!self) {
17714 return 0;
17716 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
17717 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
17718 return 0;
17721 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
17722 int i;
17723 for (i = 0; i < 63; i++) {
17724 if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
17725 const wuffs_base__image_decoder__func_ptrs* func_ptrs =
17726 (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
17727 return (*func_ptrs->get_quirk)(self, a_key);
17728 } else if (v->vtable_name == NULL) {
17729 break;
17731 v++;
17734 return 0;
17737 WUFFS_BASE__GENERATED_C_CODE
17738 WUFFS_BASE__MAYBE_STATIC uint32_t
17739 wuffs_base__image_decoder__num_animation_loops(
17740 const wuffs_base__image_decoder* self) {
17741 if (!self) {
17742 return 0;
17744 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
17745 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
17746 return 0;
17749 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
17750 int i;
17751 for (i = 0; i < 63; i++) {
17752 if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
17753 const wuffs_base__image_decoder__func_ptrs* func_ptrs =
17754 (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
17755 return (*func_ptrs->num_animation_loops)(self);
17756 } else if (v->vtable_name == NULL) {
17757 break;
17759 v++;
17762 return 0;
17765 WUFFS_BASE__GENERATED_C_CODE
17766 WUFFS_BASE__MAYBE_STATIC uint64_t
17767 wuffs_base__image_decoder__num_decoded_frame_configs(
17768 const wuffs_base__image_decoder* self) {
17769 if (!self) {
17770 return 0;
17772 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
17773 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
17774 return 0;
17777 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
17778 int i;
17779 for (i = 0; i < 63; i++) {
17780 if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
17781 const wuffs_base__image_decoder__func_ptrs* func_ptrs =
17782 (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
17783 return (*func_ptrs->num_decoded_frame_configs)(self);
17784 } else if (v->vtable_name == NULL) {
17785 break;
17787 v++;
17790 return 0;
17793 WUFFS_BASE__GENERATED_C_CODE
17794 WUFFS_BASE__MAYBE_STATIC uint64_t
17795 wuffs_base__image_decoder__num_decoded_frames(
17796 const wuffs_base__image_decoder* self) {
17797 if (!self) {
17798 return 0;
17800 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
17801 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
17802 return 0;
17805 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
17806 int i;
17807 for (i = 0; i < 63; i++) {
17808 if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
17809 const wuffs_base__image_decoder__func_ptrs* func_ptrs =
17810 (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
17811 return (*func_ptrs->num_decoded_frames)(self);
17812 } else if (v->vtable_name == NULL) {
17813 break;
17815 v++;
17818 return 0;
17821 WUFFS_BASE__GENERATED_C_CODE
17822 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
17823 wuffs_base__image_decoder__restart_frame(
17824 wuffs_base__image_decoder* self,
17825 uint64_t a_index,
17826 uint64_t a_io_position) {
17827 if (!self) {
17828 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
17830 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
17831 return wuffs_base__make_status(
17832 (self->private_impl.magic == WUFFS_BASE__DISABLED)
17833 ? wuffs_base__error__disabled_by_previous_error
17834 : wuffs_base__error__initialize_not_called);
17837 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
17838 int i;
17839 for (i = 0; i < 63; i++) {
17840 if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
17841 const wuffs_base__image_decoder__func_ptrs* func_ptrs =
17842 (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
17843 return (*func_ptrs->restart_frame)(self, a_index, a_io_position);
17844 } else if (v->vtable_name == NULL) {
17845 break;
17847 v++;
17850 return wuffs_base__make_status(wuffs_base__error__bad_vtable);
17853 WUFFS_BASE__GENERATED_C_CODE
17854 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
17855 wuffs_base__image_decoder__set_quirk(
17856 wuffs_base__image_decoder* self,
17857 uint32_t a_key,
17858 uint64_t a_value) {
17859 if (!self) {
17860 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
17862 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
17863 return wuffs_base__make_status(
17864 (self->private_impl.magic == WUFFS_BASE__DISABLED)
17865 ? wuffs_base__error__disabled_by_previous_error
17866 : wuffs_base__error__initialize_not_called);
17869 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
17870 int i;
17871 for (i = 0; i < 63; i++) {
17872 if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
17873 const wuffs_base__image_decoder__func_ptrs* func_ptrs =
17874 (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
17875 return (*func_ptrs->set_quirk)(self, a_key, a_value);
17876 } else if (v->vtable_name == NULL) {
17877 break;
17879 v++;
17882 return wuffs_base__make_status(wuffs_base__error__bad_vtable);
17885 WUFFS_BASE__GENERATED_C_CODE
17886 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
17887 wuffs_base__image_decoder__set_report_metadata(
17888 wuffs_base__image_decoder* self,
17889 uint32_t a_fourcc,
17890 bool a_report) {
17891 if (!self) {
17892 return wuffs_base__make_empty_struct();
17894 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
17895 return wuffs_base__make_empty_struct();
17898 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
17899 int i;
17900 for (i = 0; i < 63; i++) {
17901 if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
17902 const wuffs_base__image_decoder__func_ptrs* func_ptrs =
17903 (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
17904 return (*func_ptrs->set_report_metadata)(self, a_fourcc, a_report);
17905 } else if (v->vtable_name == NULL) {
17906 break;
17908 v++;
17911 return wuffs_base__make_empty_struct();
17914 WUFFS_BASE__GENERATED_C_CODE
17915 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
17916 wuffs_base__image_decoder__tell_me_more(
17917 wuffs_base__image_decoder* self,
17918 wuffs_base__io_buffer* a_dst,
17919 wuffs_base__more_information* a_minfo,
17920 wuffs_base__io_buffer* a_src) {
17921 if (!self) {
17922 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
17924 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
17925 return wuffs_base__make_status(
17926 (self->private_impl.magic == WUFFS_BASE__DISABLED)
17927 ? wuffs_base__error__disabled_by_previous_error
17928 : wuffs_base__error__initialize_not_called);
17931 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
17932 int i;
17933 for (i = 0; i < 63; i++) {
17934 if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
17935 const wuffs_base__image_decoder__func_ptrs* func_ptrs =
17936 (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
17937 return (*func_ptrs->tell_me_more)(self, a_dst, a_minfo, a_src);
17938 } else if (v->vtable_name == NULL) {
17939 break;
17941 v++;
17944 return wuffs_base__make_status(wuffs_base__error__bad_vtable);
17947 WUFFS_BASE__GENERATED_C_CODE
17948 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
17949 wuffs_base__image_decoder__workbuf_len(
17950 const wuffs_base__image_decoder* self) {
17951 if (!self) {
17952 return wuffs_base__utility__empty_range_ii_u64();
17954 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
17955 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
17956 return wuffs_base__utility__empty_range_ii_u64();
17959 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
17960 int i;
17961 for (i = 0; i < 63; i++) {
17962 if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
17963 const wuffs_base__image_decoder__func_ptrs* func_ptrs =
17964 (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
17965 return (*func_ptrs->workbuf_len)(self);
17966 } else if (v->vtable_name == NULL) {
17967 break;
17969 v++;
17972 return wuffs_base__utility__empty_range_ii_u64();
17975 // --------
17977 WUFFS_BASE__GENERATED_C_CODE
17978 WUFFS_BASE__MAYBE_STATIC wuffs_base__optional_u63
17979 wuffs_base__io_transformer__dst_history_retain_length(
17980 const wuffs_base__io_transformer* self) {
17981 if (!self) {
17982 return wuffs_base__utility__make_optional_u63(false, 0u);
17984 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
17985 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
17986 return wuffs_base__utility__make_optional_u63(false, 0u);
17989 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
17990 int i;
17991 for (i = 0; i < 63; i++) {
17992 if (v->vtable_name == wuffs_base__io_transformer__vtable_name) {
17993 const wuffs_base__io_transformer__func_ptrs* func_ptrs =
17994 (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers);
17995 return (*func_ptrs->dst_history_retain_length)(self);
17996 } else if (v->vtable_name == NULL) {
17997 break;
17999 v++;
18002 return wuffs_base__utility__make_optional_u63(false, 0u);
18005 WUFFS_BASE__GENERATED_C_CODE
18006 WUFFS_BASE__MAYBE_STATIC uint64_t
18007 wuffs_base__io_transformer__get_quirk(
18008 const wuffs_base__io_transformer* self,
18009 uint32_t a_key) {
18010 if (!self) {
18011 return 0;
18013 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
18014 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
18015 return 0;
18018 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
18019 int i;
18020 for (i = 0; i < 63; i++) {
18021 if (v->vtable_name == wuffs_base__io_transformer__vtable_name) {
18022 const wuffs_base__io_transformer__func_ptrs* func_ptrs =
18023 (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers);
18024 return (*func_ptrs->get_quirk)(self, a_key);
18025 } else if (v->vtable_name == NULL) {
18026 break;
18028 v++;
18031 return 0;
18034 WUFFS_BASE__GENERATED_C_CODE
18035 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
18036 wuffs_base__io_transformer__set_quirk(
18037 wuffs_base__io_transformer* self,
18038 uint32_t a_key,
18039 uint64_t a_value) {
18040 if (!self) {
18041 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
18043 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
18044 return wuffs_base__make_status(
18045 (self->private_impl.magic == WUFFS_BASE__DISABLED)
18046 ? wuffs_base__error__disabled_by_previous_error
18047 : wuffs_base__error__initialize_not_called);
18050 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
18051 int i;
18052 for (i = 0; i < 63; i++) {
18053 if (v->vtable_name == wuffs_base__io_transformer__vtable_name) {
18054 const wuffs_base__io_transformer__func_ptrs* func_ptrs =
18055 (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers);
18056 return (*func_ptrs->set_quirk)(self, a_key, a_value);
18057 } else if (v->vtable_name == NULL) {
18058 break;
18060 v++;
18063 return wuffs_base__make_status(wuffs_base__error__bad_vtable);
18066 WUFFS_BASE__GENERATED_C_CODE
18067 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
18068 wuffs_base__io_transformer__transform_io(
18069 wuffs_base__io_transformer* self,
18070 wuffs_base__io_buffer* a_dst,
18071 wuffs_base__io_buffer* a_src,
18072 wuffs_base__slice_u8 a_workbuf) {
18073 if (!self) {
18074 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
18076 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
18077 return wuffs_base__make_status(
18078 (self->private_impl.magic == WUFFS_BASE__DISABLED)
18079 ? wuffs_base__error__disabled_by_previous_error
18080 : wuffs_base__error__initialize_not_called);
18083 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
18084 int i;
18085 for (i = 0; i < 63; i++) {
18086 if (v->vtable_name == wuffs_base__io_transformer__vtable_name) {
18087 const wuffs_base__io_transformer__func_ptrs* func_ptrs =
18088 (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers);
18089 return (*func_ptrs->transform_io)(self, a_dst, a_src, a_workbuf);
18090 } else if (v->vtable_name == NULL) {
18091 break;
18093 v++;
18096 return wuffs_base__make_status(wuffs_base__error__bad_vtable);
18099 WUFFS_BASE__GENERATED_C_CODE
18100 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
18101 wuffs_base__io_transformer__workbuf_len(
18102 const wuffs_base__io_transformer* self) {
18103 if (!self) {
18104 return wuffs_base__utility__empty_range_ii_u64();
18106 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
18107 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
18108 return wuffs_base__utility__empty_range_ii_u64();
18111 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
18112 int i;
18113 for (i = 0; i < 63; i++) {
18114 if (v->vtable_name == wuffs_base__io_transformer__vtable_name) {
18115 const wuffs_base__io_transformer__func_ptrs* func_ptrs =
18116 (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers);
18117 return (*func_ptrs->workbuf_len)(self);
18118 } else if (v->vtable_name == NULL) {
18119 break;
18121 v++;
18124 return wuffs_base__utility__empty_range_ii_u64();
18127 // --------
18129 WUFFS_BASE__GENERATED_C_CODE
18130 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
18131 wuffs_base__token_decoder__decode_tokens(
18132 wuffs_base__token_decoder* self,
18133 wuffs_base__token_buffer* a_dst,
18134 wuffs_base__io_buffer* a_src,
18135 wuffs_base__slice_u8 a_workbuf) {
18136 if (!self) {
18137 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
18139 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
18140 return wuffs_base__make_status(
18141 (self->private_impl.magic == WUFFS_BASE__DISABLED)
18142 ? wuffs_base__error__disabled_by_previous_error
18143 : wuffs_base__error__initialize_not_called);
18146 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
18147 int i;
18148 for (i = 0; i < 63; i++) {
18149 if (v->vtable_name == wuffs_base__token_decoder__vtable_name) {
18150 const wuffs_base__token_decoder__func_ptrs* func_ptrs =
18151 (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers);
18152 return (*func_ptrs->decode_tokens)(self, a_dst, a_src, a_workbuf);
18153 } else if (v->vtable_name == NULL) {
18154 break;
18156 v++;
18159 return wuffs_base__make_status(wuffs_base__error__bad_vtable);
18162 WUFFS_BASE__GENERATED_C_CODE
18163 WUFFS_BASE__MAYBE_STATIC uint64_t
18164 wuffs_base__token_decoder__get_quirk(
18165 const wuffs_base__token_decoder* self,
18166 uint32_t a_key) {
18167 if (!self) {
18168 return 0;
18170 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
18171 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
18172 return 0;
18175 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
18176 int i;
18177 for (i = 0; i < 63; i++) {
18178 if (v->vtable_name == wuffs_base__token_decoder__vtable_name) {
18179 const wuffs_base__token_decoder__func_ptrs* func_ptrs =
18180 (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers);
18181 return (*func_ptrs->get_quirk)(self, a_key);
18182 } else if (v->vtable_name == NULL) {
18183 break;
18185 v++;
18188 return 0;
18191 WUFFS_BASE__GENERATED_C_CODE
18192 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
18193 wuffs_base__token_decoder__set_quirk(
18194 wuffs_base__token_decoder* self,
18195 uint32_t a_key,
18196 uint64_t a_value) {
18197 if (!self) {
18198 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
18200 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
18201 return wuffs_base__make_status(
18202 (self->private_impl.magic == WUFFS_BASE__DISABLED)
18203 ? wuffs_base__error__disabled_by_previous_error
18204 : wuffs_base__error__initialize_not_called);
18207 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
18208 int i;
18209 for (i = 0; i < 63; i++) {
18210 if (v->vtable_name == wuffs_base__token_decoder__vtable_name) {
18211 const wuffs_base__token_decoder__func_ptrs* func_ptrs =
18212 (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers);
18213 return (*func_ptrs->set_quirk)(self, a_key, a_value);
18214 } else if (v->vtable_name == NULL) {
18215 break;
18217 v++;
18220 return wuffs_base__make_status(wuffs_base__error__bad_vtable);
18223 WUFFS_BASE__GENERATED_C_CODE
18224 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
18225 wuffs_base__token_decoder__workbuf_len(
18226 const wuffs_base__token_decoder* self) {
18227 if (!self) {
18228 return wuffs_base__utility__empty_range_ii_u64();
18230 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
18231 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
18232 return wuffs_base__utility__empty_range_ii_u64();
18235 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
18236 int i;
18237 for (i = 0; i < 63; i++) {
18238 if (v->vtable_name == wuffs_base__token_decoder__vtable_name) {
18239 const wuffs_base__token_decoder__func_ptrs* func_ptrs =
18240 (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers);
18241 return (*func_ptrs->workbuf_len)(self);
18242 } else if (v->vtable_name == NULL) {
18243 break;
18245 v++;
18248 return wuffs_base__utility__empty_range_ii_u64();
18251 #endif // !defined(WUFFS_CONFIG__MODULES) ||
18252 // defined(WUFFS_CONFIG__MODULE__BASE) ||
18253 // defined(WUFFS_CONFIG__MODULE__BASE__INTERFACES)
18255 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
18256 defined(WUFFS_CONFIG__MODULE__BASE__FLOATCONV)
18258 // ---------------- IEEE 754 Floating Point
18260 // The etc__hpd_left_shift and etc__powers_of_5 tables were printed by
18261 // script/print-hpd-left-shift.go. That script has an optional -comments flag,
18262 // whose output is not copied here, which prints further detail.
18264 // These tables are used in
18265 // wuffs_private_impl__high_prec_dec__lshift_num_new_digits.
18267 // wuffs_private_impl__hpd_left_shift[i] encodes the number of new digits
18268 // created after multiplying a positive integer by (1 << i): the additional
18269 // length in the decimal representation. For example, shifting "234" by 3
18270 // (equivalent to multiplying by 8) will produce "1872". Going from a 3-length
18271 // string to a 4-length string means that 1 new digit was added (and existing
18272 // digits may have changed).
18274 // Shifting by i can add either N or N-1 new digits, depending on whether the
18275 // original positive integer compares >= or < to the i'th power of 5 (as 10
18276 // equals 2 * 5). Comparison is lexicographic, not numerical.
18278 // For example, shifting by 4 (i.e. multiplying by 16) can add 1 or 2 new
18279 // digits, depending on a lexicographic comparison to (5 ** 4), i.e. "625":
18280 // - ("1" << 4) is "16", which adds 1 new digit.
18281 // - ("5678" << 4) is "90848", which adds 1 new digit.
18282 // - ("624" << 4) is "9984", which adds 1 new digit.
18283 // - ("62498" << 4) is "999968", which adds 1 new digit.
18284 // - ("625" << 4) is "10000", which adds 2 new digits.
18285 // - ("625001" << 4) is "10000016", which adds 2 new digits.
18286 // - ("7008" << 4) is "112128", which adds 2 new digits.
18287 // - ("99" << 4) is "1584", which adds 2 new digits.
18289 // Thus, when i is 4, N is 2 and (5 ** i) is "625". This etc__hpd_left_shift
18290 // array encodes this as:
18291 // - etc__hpd_left_shift[4] is 0x1006 = (2 << 11) | 0x0006.
18292 // - etc__hpd_left_shift[5] is 0x1009 = (? << 11) | 0x0009.
18293 // where the ? isn't relevant for i == 4.
18295 // The high 5 bits of etc__hpd_left_shift[i] is N, the higher of the two
18296 // possible number of new digits. The low 11 bits are an offset into the
18297 // etc__powers_of_5 array (of length 0x051C, so offsets fit in 11 bits). When i
18298 // is 4, its offset and the next one is 6 and 9, and etc__powers_of_5[6 .. 9]
18299 // is the string "\x06\x02\x05", so the relevant power of 5 is "625".
18301 // Thanks to Ken Thompson for the original idea.
18302 static const uint16_t wuffs_private_impl__hpd_left_shift[65] = {
18303 0x0000, 0x0800, 0x0801, 0x0803, 0x1006, 0x1009, 0x100D, 0x1812, 0x1817,
18304 0x181D, 0x2024, 0x202B, 0x2033, 0x203C, 0x2846, 0x2850, 0x285B, 0x3067,
18305 0x3073, 0x3080, 0x388E, 0x389C, 0x38AB, 0x38BB, 0x40CC, 0x40DD, 0x40EF,
18306 0x4902, 0x4915, 0x4929, 0x513E, 0x5153, 0x5169, 0x5180, 0x5998, 0x59B0,
18307 0x59C9, 0x61E3, 0x61FD, 0x6218, 0x6A34, 0x6A50, 0x6A6D, 0x6A8B, 0x72AA,
18308 0x72C9, 0x72E9, 0x7B0A, 0x7B2B, 0x7B4D, 0x8370, 0x8393, 0x83B7, 0x83DC,
18309 0x8C02, 0x8C28, 0x8C4F, 0x9477, 0x949F, 0x94C8, 0x9CF2, 0x051C, 0x051C,
18310 0x051C, 0x051C,
18313 // wuffs_private_impl__powers_of_5 contains the powers of 5, concatenated
18314 // together: "5", "25", "125", "625", "3125", etc.
18315 static const uint8_t wuffs_private_impl__powers_of_5[0x051C] = {
18316 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,
18317 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,
18318 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,
18319 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,
18320 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,
18321 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,
18322 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,
18323 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,
18324 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,
18325 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,
18326 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,
18327 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,
18328 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,
18329 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,
18330 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,
18331 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,
18332 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,
18333 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,
18334 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,
18335 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,
18336 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,
18337 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,
18338 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,
18339 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,
18340 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,
18341 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,
18342 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,
18343 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,
18344 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,
18345 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,
18346 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,
18347 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,
18348 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,
18349 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,
18350 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,
18351 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,
18352 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,
18353 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,
18354 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,
18355 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,
18356 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,
18357 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,
18358 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,
18359 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,
18360 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,
18361 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,
18362 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,
18363 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,
18364 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,
18365 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,
18366 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,
18367 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,
18368 6, 9, 1, 4, 0, 6, 2, 5,
18371 // --------
18373 // wuffs_private_impl__powers_of_10 contains truncated approximations to the
18374 // powers of 10, ranging from 1e-307 to 1e+288 inclusive, as 596 pairs of
18375 // uint64_t values (a 128-bit mantissa).
18377 // There's also an implicit third column (implied by a linear formula involving
18378 // the base-10 exponent) that is the base-2 exponent, biased by a magic
18379 // constant. That constant (1214 or 0x04BE) equals 1023 + 191. 1023 is the bias
18380 // for IEEE 754 double-precision floating point. 191 is ((3 * 64) - 1) and
18381 // wuffs_private_impl__parse_number_f64_eisel_lemire works with
18382 // multiples-of-64-bit mantissas.
18384 // For example, the third row holds the approximation to 1e-305:
18385 // 0xE0B62E29_29ABA83C_331ACDAB_FE94DE87 * (2 ** (0x0049 - 0x04BE))
18387 // Similarly, 1e+4 is approximated by:
18388 // 0x9C400000_00000000_00000000_00000000 * (2 ** (0x044C - 0x04BE))
18390 // Similarly, 1e+68 is approximated by:
18391 // 0xED63A231_D4C4FB27_4CA7AAA8_63EE4BDD * (2 ** (0x0520 - 0x04BE))
18393 // This table was generated by by script/print-mpb-powers-of-10.go
18394 static const uint64_t wuffs_private_impl__powers_of_10[596][2] = {
18395 {0xA5D3B6D479F8E056, 0x8FD0C16206306BAB}, // 1e-307
18396 {0x8F48A4899877186C, 0xB3C4F1BA87BC8696}, // 1e-306
18397 {0x331ACDABFE94DE87, 0xE0B62E2929ABA83C}, // 1e-305
18398 {0x9FF0C08B7F1D0B14, 0x8C71DCD9BA0B4925}, // 1e-304
18399 {0x07ECF0AE5EE44DD9, 0xAF8E5410288E1B6F}, // 1e-303
18400 {0xC9E82CD9F69D6150, 0xDB71E91432B1A24A}, // 1e-302
18401 {0xBE311C083A225CD2, 0x892731AC9FAF056E}, // 1e-301
18402 {0x6DBD630A48AAF406, 0xAB70FE17C79AC6CA}, // 1e-300
18403 {0x092CBBCCDAD5B108, 0xD64D3D9DB981787D}, // 1e-299
18404 {0x25BBF56008C58EA5, 0x85F0468293F0EB4E}, // 1e-298
18405 {0xAF2AF2B80AF6F24E, 0xA76C582338ED2621}, // 1e-297
18406 {0x1AF5AF660DB4AEE1, 0xD1476E2C07286FAA}, // 1e-296
18407 {0x50D98D9FC890ED4D, 0x82CCA4DB847945CA}, // 1e-295
18408 {0xE50FF107BAB528A0, 0xA37FCE126597973C}, // 1e-294
18409 {0x1E53ED49A96272C8, 0xCC5FC196FEFD7D0C}, // 1e-293
18410 {0x25E8E89C13BB0F7A, 0xFF77B1FCBEBCDC4F}, // 1e-292
18411 {0x77B191618C54E9AC, 0x9FAACF3DF73609B1}, // 1e-291
18412 {0xD59DF5B9EF6A2417, 0xC795830D75038C1D}, // 1e-290
18413 {0x4B0573286B44AD1D, 0xF97AE3D0D2446F25}, // 1e-289
18414 {0x4EE367F9430AEC32, 0x9BECCE62836AC577}, // 1e-288
18415 {0x229C41F793CDA73F, 0xC2E801FB244576D5}, // 1e-287
18416 {0x6B43527578C1110F, 0xF3A20279ED56D48A}, // 1e-286
18417 {0x830A13896B78AAA9, 0x9845418C345644D6}, // 1e-285
18418 {0x23CC986BC656D553, 0xBE5691EF416BD60C}, // 1e-284
18419 {0x2CBFBE86B7EC8AA8, 0xEDEC366B11C6CB8F}, // 1e-283
18420 {0x7BF7D71432F3D6A9, 0x94B3A202EB1C3F39}, // 1e-282
18421 {0xDAF5CCD93FB0CC53, 0xB9E08A83A5E34F07}, // 1e-281
18422 {0xD1B3400F8F9CFF68, 0xE858AD248F5C22C9}, // 1e-280
18423 {0x23100809B9C21FA1, 0x91376C36D99995BE}, // 1e-279
18424 {0xABD40A0C2832A78A, 0xB58547448FFFFB2D}, // 1e-278
18425 {0x16C90C8F323F516C, 0xE2E69915B3FFF9F9}, // 1e-277
18426 {0xAE3DA7D97F6792E3, 0x8DD01FAD907FFC3B}, // 1e-276
18427 {0x99CD11CFDF41779C, 0xB1442798F49FFB4A}, // 1e-275
18428 {0x40405643D711D583, 0xDD95317F31C7FA1D}, // 1e-274
18429 {0x482835EA666B2572, 0x8A7D3EEF7F1CFC52}, // 1e-273
18430 {0xDA3243650005EECF, 0xAD1C8EAB5EE43B66}, // 1e-272
18431 {0x90BED43E40076A82, 0xD863B256369D4A40}, // 1e-271
18432 {0x5A7744A6E804A291, 0x873E4F75E2224E68}, // 1e-270
18433 {0x711515D0A205CB36, 0xA90DE3535AAAE202}, // 1e-269
18434 {0x0D5A5B44CA873E03, 0xD3515C2831559A83}, // 1e-268
18435 {0xE858790AFE9486C2, 0x8412D9991ED58091}, // 1e-267
18436 {0x626E974DBE39A872, 0xA5178FFF668AE0B6}, // 1e-266
18437 {0xFB0A3D212DC8128F, 0xCE5D73FF402D98E3}, // 1e-265
18438 {0x7CE66634BC9D0B99, 0x80FA687F881C7F8E}, // 1e-264
18439 {0x1C1FFFC1EBC44E80, 0xA139029F6A239F72}, // 1e-263
18440 {0xA327FFB266B56220, 0xC987434744AC874E}, // 1e-262
18441 {0x4BF1FF9F0062BAA8, 0xFBE9141915D7A922}, // 1e-261
18442 {0x6F773FC3603DB4A9, 0x9D71AC8FADA6C9B5}, // 1e-260
18443 {0xCB550FB4384D21D3, 0xC4CE17B399107C22}, // 1e-259
18444 {0x7E2A53A146606A48, 0xF6019DA07F549B2B}, // 1e-258
18445 {0x2EDA7444CBFC426D, 0x99C102844F94E0FB}, // 1e-257
18446 {0xFA911155FEFB5308, 0xC0314325637A1939}, // 1e-256
18447 {0x793555AB7EBA27CA, 0xF03D93EEBC589F88}, // 1e-255
18448 {0x4BC1558B2F3458DE, 0x96267C7535B763B5}, // 1e-254
18449 {0x9EB1AAEDFB016F16, 0xBBB01B9283253CA2}, // 1e-253
18450 {0x465E15A979C1CADC, 0xEA9C227723EE8BCB}, // 1e-252
18451 {0x0BFACD89EC191EC9, 0x92A1958A7675175F}, // 1e-251
18452 {0xCEF980EC671F667B, 0xB749FAED14125D36}, // 1e-250
18453 {0x82B7E12780E7401A, 0xE51C79A85916F484}, // 1e-249
18454 {0xD1B2ECB8B0908810, 0x8F31CC0937AE58D2}, // 1e-248
18455 {0x861FA7E6DCB4AA15, 0xB2FE3F0B8599EF07}, // 1e-247
18456 {0x67A791E093E1D49A, 0xDFBDCECE67006AC9}, // 1e-246
18457 {0xE0C8BB2C5C6D24E0, 0x8BD6A141006042BD}, // 1e-245
18458 {0x58FAE9F773886E18, 0xAECC49914078536D}, // 1e-244
18459 {0xAF39A475506A899E, 0xDA7F5BF590966848}, // 1e-243
18460 {0x6D8406C952429603, 0x888F99797A5E012D}, // 1e-242
18461 {0xC8E5087BA6D33B83, 0xAAB37FD7D8F58178}, // 1e-241
18462 {0xFB1E4A9A90880A64, 0xD5605FCDCF32E1D6}, // 1e-240
18463 {0x5CF2EEA09A55067F, 0x855C3BE0A17FCD26}, // 1e-239
18464 {0xF42FAA48C0EA481E, 0xA6B34AD8C9DFC06F}, // 1e-238
18465 {0xF13B94DAF124DA26, 0xD0601D8EFC57B08B}, // 1e-237
18466 {0x76C53D08D6B70858, 0x823C12795DB6CE57}, // 1e-236
18467 {0x54768C4B0C64CA6E, 0xA2CB1717B52481ED}, // 1e-235
18468 {0xA9942F5DCF7DFD09, 0xCB7DDCDDA26DA268}, // 1e-234
18469 {0xD3F93B35435D7C4C, 0xFE5D54150B090B02}, // 1e-233
18470 {0xC47BC5014A1A6DAF, 0x9EFA548D26E5A6E1}, // 1e-232
18471 {0x359AB6419CA1091B, 0xC6B8E9B0709F109A}, // 1e-231
18472 {0xC30163D203C94B62, 0xF867241C8CC6D4C0}, // 1e-230
18473 {0x79E0DE63425DCF1D, 0x9B407691D7FC44F8}, // 1e-229
18474 {0x985915FC12F542E4, 0xC21094364DFB5636}, // 1e-228
18475 {0x3E6F5B7B17B2939D, 0xF294B943E17A2BC4}, // 1e-227
18476 {0xA705992CEECF9C42, 0x979CF3CA6CEC5B5A}, // 1e-226
18477 {0x50C6FF782A838353, 0xBD8430BD08277231}, // 1e-225
18478 {0xA4F8BF5635246428, 0xECE53CEC4A314EBD}, // 1e-224
18479 {0x871B7795E136BE99, 0x940F4613AE5ED136}, // 1e-223
18480 {0x28E2557B59846E3F, 0xB913179899F68584}, // 1e-222
18481 {0x331AEADA2FE589CF, 0xE757DD7EC07426E5}, // 1e-221
18482 {0x3FF0D2C85DEF7621, 0x9096EA6F3848984F}, // 1e-220
18483 {0x0FED077A756B53A9, 0xB4BCA50B065ABE63}, // 1e-219
18484 {0xD3E8495912C62894, 0xE1EBCE4DC7F16DFB}, // 1e-218
18485 {0x64712DD7ABBBD95C, 0x8D3360F09CF6E4BD}, // 1e-217
18486 {0xBD8D794D96AACFB3, 0xB080392CC4349DEC}, // 1e-216
18487 {0xECF0D7A0FC5583A0, 0xDCA04777F541C567}, // 1e-215
18488 {0xF41686C49DB57244, 0x89E42CAAF9491B60}, // 1e-214
18489 {0x311C2875C522CED5, 0xAC5D37D5B79B6239}, // 1e-213
18490 {0x7D633293366B828B, 0xD77485CB25823AC7}, // 1e-212
18491 {0xAE5DFF9C02033197, 0x86A8D39EF77164BC}, // 1e-211
18492 {0xD9F57F830283FDFC, 0xA8530886B54DBDEB}, // 1e-210
18493 {0xD072DF63C324FD7B, 0xD267CAA862A12D66}, // 1e-209
18494 {0x4247CB9E59F71E6D, 0x8380DEA93DA4BC60}, // 1e-208
18495 {0x52D9BE85F074E608, 0xA46116538D0DEB78}, // 1e-207
18496 {0x67902E276C921F8B, 0xCD795BE870516656}, // 1e-206
18497 {0x00BA1CD8A3DB53B6, 0x806BD9714632DFF6}, // 1e-205
18498 {0x80E8A40ECCD228A4, 0xA086CFCD97BF97F3}, // 1e-204
18499 {0x6122CD128006B2CD, 0xC8A883C0FDAF7DF0}, // 1e-203
18500 {0x796B805720085F81, 0xFAD2A4B13D1B5D6C}, // 1e-202
18501 {0xCBE3303674053BB0, 0x9CC3A6EEC6311A63}, // 1e-201
18502 {0xBEDBFC4411068A9C, 0xC3F490AA77BD60FC}, // 1e-200
18503 {0xEE92FB5515482D44, 0xF4F1B4D515ACB93B}, // 1e-199
18504 {0x751BDD152D4D1C4A, 0x991711052D8BF3C5}, // 1e-198
18505 {0xD262D45A78A0635D, 0xBF5CD54678EEF0B6}, // 1e-197
18506 {0x86FB897116C87C34, 0xEF340A98172AACE4}, // 1e-196
18507 {0xD45D35E6AE3D4DA0, 0x9580869F0E7AAC0E}, // 1e-195
18508 {0x8974836059CCA109, 0xBAE0A846D2195712}, // 1e-194
18509 {0x2BD1A438703FC94B, 0xE998D258869FACD7}, // 1e-193
18510 {0x7B6306A34627DDCF, 0x91FF83775423CC06}, // 1e-192
18511 {0x1A3BC84C17B1D542, 0xB67F6455292CBF08}, // 1e-191
18512 {0x20CABA5F1D9E4A93, 0xE41F3D6A7377EECA}, // 1e-190
18513 {0x547EB47B7282EE9C, 0x8E938662882AF53E}, // 1e-189
18514 {0xE99E619A4F23AA43, 0xB23867FB2A35B28D}, // 1e-188
18515 {0x6405FA00E2EC94D4, 0xDEC681F9F4C31F31}, // 1e-187
18516 {0xDE83BC408DD3DD04, 0x8B3C113C38F9F37E}, // 1e-186
18517 {0x9624AB50B148D445, 0xAE0B158B4738705E}, // 1e-185
18518 {0x3BADD624DD9B0957, 0xD98DDAEE19068C76}, // 1e-184
18519 {0xE54CA5D70A80E5D6, 0x87F8A8D4CFA417C9}, // 1e-183
18520 {0x5E9FCF4CCD211F4C, 0xA9F6D30A038D1DBC}, // 1e-182
18521 {0x7647C3200069671F, 0xD47487CC8470652B}, // 1e-181
18522 {0x29ECD9F40041E073, 0x84C8D4DFD2C63F3B}, // 1e-180
18523 {0xF468107100525890, 0xA5FB0A17C777CF09}, // 1e-179
18524 {0x7182148D4066EEB4, 0xCF79CC9DB955C2CC}, // 1e-178
18525 {0xC6F14CD848405530, 0x81AC1FE293D599BF}, // 1e-177
18526 {0xB8ADA00E5A506A7C, 0xA21727DB38CB002F}, // 1e-176
18527 {0xA6D90811F0E4851C, 0xCA9CF1D206FDC03B}, // 1e-175
18528 {0x908F4A166D1DA663, 0xFD442E4688BD304A}, // 1e-174
18529 {0x9A598E4E043287FE, 0x9E4A9CEC15763E2E}, // 1e-173
18530 {0x40EFF1E1853F29FD, 0xC5DD44271AD3CDBA}, // 1e-172
18531 {0xD12BEE59E68EF47C, 0xF7549530E188C128}, // 1e-171
18532 {0x82BB74F8301958CE, 0x9A94DD3E8CF578B9}, // 1e-170
18533 {0xE36A52363C1FAF01, 0xC13A148E3032D6E7}, // 1e-169
18534 {0xDC44E6C3CB279AC1, 0xF18899B1BC3F8CA1}, // 1e-168
18535 {0x29AB103A5EF8C0B9, 0x96F5600F15A7B7E5}, // 1e-167
18536 {0x7415D448F6B6F0E7, 0xBCB2B812DB11A5DE}, // 1e-166
18537 {0x111B495B3464AD21, 0xEBDF661791D60F56}, // 1e-165
18538 {0xCAB10DD900BEEC34, 0x936B9FCEBB25C995}, // 1e-164
18539 {0x3D5D514F40EEA742, 0xB84687C269EF3BFB}, // 1e-163
18540 {0x0CB4A5A3112A5112, 0xE65829B3046B0AFA}, // 1e-162
18541 {0x47F0E785EABA72AB, 0x8FF71A0FE2C2E6DC}, // 1e-161
18542 {0x59ED216765690F56, 0xB3F4E093DB73A093}, // 1e-160
18543 {0x306869C13EC3532C, 0xE0F218B8D25088B8}, // 1e-159
18544 {0x1E414218C73A13FB, 0x8C974F7383725573}, // 1e-158
18545 {0xE5D1929EF90898FA, 0xAFBD2350644EEACF}, // 1e-157
18546 {0xDF45F746B74ABF39, 0xDBAC6C247D62A583}, // 1e-156
18547 {0x6B8BBA8C328EB783, 0x894BC396CE5DA772}, // 1e-155
18548 {0x066EA92F3F326564, 0xAB9EB47C81F5114F}, // 1e-154
18549 {0xC80A537B0EFEFEBD, 0xD686619BA27255A2}, // 1e-153
18550 {0xBD06742CE95F5F36, 0x8613FD0145877585}, // 1e-152
18551 {0x2C48113823B73704, 0xA798FC4196E952E7}, // 1e-151
18552 {0xF75A15862CA504C5, 0xD17F3B51FCA3A7A0}, // 1e-150
18553 {0x9A984D73DBE722FB, 0x82EF85133DE648C4}, // 1e-149
18554 {0xC13E60D0D2E0EBBA, 0xA3AB66580D5FDAF5}, // 1e-148
18555 {0x318DF905079926A8, 0xCC963FEE10B7D1B3}, // 1e-147
18556 {0xFDF17746497F7052, 0xFFBBCFE994E5C61F}, // 1e-146
18557 {0xFEB6EA8BEDEFA633, 0x9FD561F1FD0F9BD3}, // 1e-145
18558 {0xFE64A52EE96B8FC0, 0xC7CABA6E7C5382C8}, // 1e-144
18559 {0x3DFDCE7AA3C673B0, 0xF9BD690A1B68637B}, // 1e-143
18560 {0x06BEA10CA65C084E, 0x9C1661A651213E2D}, // 1e-142
18561 {0x486E494FCFF30A62, 0xC31BFA0FE5698DB8}, // 1e-141
18562 {0x5A89DBA3C3EFCCFA, 0xF3E2F893DEC3F126}, // 1e-140
18563 {0xF89629465A75E01C, 0x986DDB5C6B3A76B7}, // 1e-139
18564 {0xF6BBB397F1135823, 0xBE89523386091465}, // 1e-138
18565 {0x746AA07DED582E2C, 0xEE2BA6C0678B597F}, // 1e-137
18566 {0xA8C2A44EB4571CDC, 0x94DB483840B717EF}, // 1e-136
18567 {0x92F34D62616CE413, 0xBA121A4650E4DDEB}, // 1e-135
18568 {0x77B020BAF9C81D17, 0xE896A0D7E51E1566}, // 1e-134
18569 {0x0ACE1474DC1D122E, 0x915E2486EF32CD60}, // 1e-133
18570 {0x0D819992132456BA, 0xB5B5ADA8AAFF80B8}, // 1e-132
18571 {0x10E1FFF697ED6C69, 0xE3231912D5BF60E6}, // 1e-131
18572 {0xCA8D3FFA1EF463C1, 0x8DF5EFABC5979C8F}, // 1e-130
18573 {0xBD308FF8A6B17CB2, 0xB1736B96B6FD83B3}, // 1e-129
18574 {0xAC7CB3F6D05DDBDE, 0xDDD0467C64BCE4A0}, // 1e-128
18575 {0x6BCDF07A423AA96B, 0x8AA22C0DBEF60EE4}, // 1e-127
18576 {0x86C16C98D2C953C6, 0xAD4AB7112EB3929D}, // 1e-126
18577 {0xE871C7BF077BA8B7, 0xD89D64D57A607744}, // 1e-125
18578 {0x11471CD764AD4972, 0x87625F056C7C4A8B}, // 1e-124
18579 {0xD598E40D3DD89BCF, 0xA93AF6C6C79B5D2D}, // 1e-123
18580 {0x4AFF1D108D4EC2C3, 0xD389B47879823479}, // 1e-122
18581 {0xCEDF722A585139BA, 0x843610CB4BF160CB}, // 1e-121
18582 {0xC2974EB4EE658828, 0xA54394FE1EEDB8FE}, // 1e-120
18583 {0x733D226229FEEA32, 0xCE947A3DA6A9273E}, // 1e-119
18584 {0x0806357D5A3F525F, 0x811CCC668829B887}, // 1e-118
18585 {0xCA07C2DCB0CF26F7, 0xA163FF802A3426A8}, // 1e-117
18586 {0xFC89B393DD02F0B5, 0xC9BCFF6034C13052}, // 1e-116
18587 {0xBBAC2078D443ACE2, 0xFC2C3F3841F17C67}, // 1e-115
18588 {0xD54B944B84AA4C0D, 0x9D9BA7832936EDC0}, // 1e-114
18589 {0x0A9E795E65D4DF11, 0xC5029163F384A931}, // 1e-113
18590 {0x4D4617B5FF4A16D5, 0xF64335BCF065D37D}, // 1e-112
18591 {0x504BCED1BF8E4E45, 0x99EA0196163FA42E}, // 1e-111
18592 {0xE45EC2862F71E1D6, 0xC06481FB9BCF8D39}, // 1e-110
18593 {0x5D767327BB4E5A4C, 0xF07DA27A82C37088}, // 1e-109
18594 {0x3A6A07F8D510F86F, 0x964E858C91BA2655}, // 1e-108
18595 {0x890489F70A55368B, 0xBBE226EFB628AFEA}, // 1e-107
18596 {0x2B45AC74CCEA842E, 0xEADAB0ABA3B2DBE5}, // 1e-106
18597 {0x3B0B8BC90012929D, 0x92C8AE6B464FC96F}, // 1e-105
18598 {0x09CE6EBB40173744, 0xB77ADA0617E3BBCB}, // 1e-104
18599 {0xCC420A6A101D0515, 0xE55990879DDCAABD}, // 1e-103
18600 {0x9FA946824A12232D, 0x8F57FA54C2A9EAB6}, // 1e-102
18601 {0x47939822DC96ABF9, 0xB32DF8E9F3546564}, // 1e-101
18602 {0x59787E2B93BC56F7, 0xDFF9772470297EBD}, // 1e-100
18603 {0x57EB4EDB3C55B65A, 0x8BFBEA76C619EF36}, // 1e-99
18604 {0xEDE622920B6B23F1, 0xAEFAE51477A06B03}, // 1e-98
18605 {0xE95FAB368E45ECED, 0xDAB99E59958885C4}, // 1e-97
18606 {0x11DBCB0218EBB414, 0x88B402F7FD75539B}, // 1e-96
18607 {0xD652BDC29F26A119, 0xAAE103B5FCD2A881}, // 1e-95
18608 {0x4BE76D3346F0495F, 0xD59944A37C0752A2}, // 1e-94
18609 {0x6F70A4400C562DDB, 0x857FCAE62D8493A5}, // 1e-93
18610 {0xCB4CCD500F6BB952, 0xA6DFBD9FB8E5B88E}, // 1e-92
18611 {0x7E2000A41346A7A7, 0xD097AD07A71F26B2}, // 1e-91
18612 {0x8ED400668C0C28C8, 0x825ECC24C873782F}, // 1e-90
18613 {0x728900802F0F32FA, 0xA2F67F2DFA90563B}, // 1e-89
18614 {0x4F2B40A03AD2FFB9, 0xCBB41EF979346BCA}, // 1e-88
18615 {0xE2F610C84987BFA8, 0xFEA126B7D78186BC}, // 1e-87
18616 {0x0DD9CA7D2DF4D7C9, 0x9F24B832E6B0F436}, // 1e-86
18617 {0x91503D1C79720DBB, 0xC6EDE63FA05D3143}, // 1e-85
18618 {0x75A44C6397CE912A, 0xF8A95FCF88747D94}, // 1e-84
18619 {0xC986AFBE3EE11ABA, 0x9B69DBE1B548CE7C}, // 1e-83
18620 {0xFBE85BADCE996168, 0xC24452DA229B021B}, // 1e-82
18621 {0xFAE27299423FB9C3, 0xF2D56790AB41C2A2}, // 1e-81
18622 {0xDCCD879FC967D41A, 0x97C560BA6B0919A5}, // 1e-80
18623 {0x5400E987BBC1C920, 0xBDB6B8E905CB600F}, // 1e-79
18624 {0x290123E9AAB23B68, 0xED246723473E3813}, // 1e-78
18625 {0xF9A0B6720AAF6521, 0x9436C0760C86E30B}, // 1e-77
18626 {0xF808E40E8D5B3E69, 0xB94470938FA89BCE}, // 1e-76
18627 {0xB60B1D1230B20E04, 0xE7958CB87392C2C2}, // 1e-75
18628 {0xB1C6F22B5E6F48C2, 0x90BD77F3483BB9B9}, // 1e-74
18629 {0x1E38AEB6360B1AF3, 0xB4ECD5F01A4AA828}, // 1e-73
18630 {0x25C6DA63C38DE1B0, 0xE2280B6C20DD5232}, // 1e-72
18631 {0x579C487E5A38AD0E, 0x8D590723948A535F}, // 1e-71
18632 {0x2D835A9DF0C6D851, 0xB0AF48EC79ACE837}, // 1e-70
18633 {0xF8E431456CF88E65, 0xDCDB1B2798182244}, // 1e-69
18634 {0x1B8E9ECB641B58FF, 0x8A08F0F8BF0F156B}, // 1e-68
18635 {0xE272467E3D222F3F, 0xAC8B2D36EED2DAC5}, // 1e-67
18636 {0x5B0ED81DCC6ABB0F, 0xD7ADF884AA879177}, // 1e-66
18637 {0x98E947129FC2B4E9, 0x86CCBB52EA94BAEA}, // 1e-65
18638 {0x3F2398D747B36224, 0xA87FEA27A539E9A5}, // 1e-64
18639 {0x8EEC7F0D19A03AAD, 0xD29FE4B18E88640E}, // 1e-63
18640 {0x1953CF68300424AC, 0x83A3EEEEF9153E89}, // 1e-62
18641 {0x5FA8C3423C052DD7, 0xA48CEAAAB75A8E2B}, // 1e-61
18642 {0x3792F412CB06794D, 0xCDB02555653131B6}, // 1e-60
18643 {0xE2BBD88BBEE40BD0, 0x808E17555F3EBF11}, // 1e-59
18644 {0x5B6ACEAEAE9D0EC4, 0xA0B19D2AB70E6ED6}, // 1e-58
18645 {0xF245825A5A445275, 0xC8DE047564D20A8B}, // 1e-57
18646 {0xEED6E2F0F0D56712, 0xFB158592BE068D2E}, // 1e-56
18647 {0x55464DD69685606B, 0x9CED737BB6C4183D}, // 1e-55
18648 {0xAA97E14C3C26B886, 0xC428D05AA4751E4C}, // 1e-54
18649 {0xD53DD99F4B3066A8, 0xF53304714D9265DF}, // 1e-53
18650 {0xE546A8038EFE4029, 0x993FE2C6D07B7FAB}, // 1e-52
18651 {0xDE98520472BDD033, 0xBF8FDB78849A5F96}, // 1e-51
18652 {0x963E66858F6D4440, 0xEF73D256A5C0F77C}, // 1e-50
18653 {0xDDE7001379A44AA8, 0x95A8637627989AAD}, // 1e-49
18654 {0x5560C018580D5D52, 0xBB127C53B17EC159}, // 1e-48
18655 {0xAAB8F01E6E10B4A6, 0xE9D71B689DDE71AF}, // 1e-47
18656 {0xCAB3961304CA70E8, 0x9226712162AB070D}, // 1e-46
18657 {0x3D607B97C5FD0D22, 0xB6B00D69BB55C8D1}, // 1e-45
18658 {0x8CB89A7DB77C506A, 0xE45C10C42A2B3B05}, // 1e-44
18659 {0x77F3608E92ADB242, 0x8EB98A7A9A5B04E3}, // 1e-43
18660 {0x55F038B237591ED3, 0xB267ED1940F1C61C}, // 1e-42
18661 {0x6B6C46DEC52F6688, 0xDF01E85F912E37A3}, // 1e-41
18662 {0x2323AC4B3B3DA015, 0x8B61313BBABCE2C6}, // 1e-40
18663 {0xABEC975E0A0D081A, 0xAE397D8AA96C1B77}, // 1e-39
18664 {0x96E7BD358C904A21, 0xD9C7DCED53C72255}, // 1e-38
18665 {0x7E50D64177DA2E54, 0x881CEA14545C7575}, // 1e-37
18666 {0xDDE50BD1D5D0B9E9, 0xAA242499697392D2}, // 1e-36
18667 {0x955E4EC64B44E864, 0xD4AD2DBFC3D07787}, // 1e-35
18668 {0xBD5AF13BEF0B113E, 0x84EC3C97DA624AB4}, // 1e-34
18669 {0xECB1AD8AEACDD58E, 0xA6274BBDD0FADD61}, // 1e-33
18670 {0x67DE18EDA5814AF2, 0xCFB11EAD453994BA}, // 1e-32
18671 {0x80EACF948770CED7, 0x81CEB32C4B43FCF4}, // 1e-31
18672 {0xA1258379A94D028D, 0xA2425FF75E14FC31}, // 1e-30
18673 {0x096EE45813A04330, 0xCAD2F7F5359A3B3E}, // 1e-29
18674 {0x8BCA9D6E188853FC, 0xFD87B5F28300CA0D}, // 1e-28
18675 {0x775EA264CF55347D, 0x9E74D1B791E07E48}, // 1e-27
18676 {0x95364AFE032A819D, 0xC612062576589DDA}, // 1e-26
18677 {0x3A83DDBD83F52204, 0xF79687AED3EEC551}, // 1e-25
18678 {0xC4926A9672793542, 0x9ABE14CD44753B52}, // 1e-24
18679 {0x75B7053C0F178293, 0xC16D9A0095928A27}, // 1e-23
18680 {0x5324C68B12DD6338, 0xF1C90080BAF72CB1}, // 1e-22
18681 {0xD3F6FC16EBCA5E03, 0x971DA05074DA7BEE}, // 1e-21
18682 {0x88F4BB1CA6BCF584, 0xBCE5086492111AEA}, // 1e-20
18683 {0x2B31E9E3D06C32E5, 0xEC1E4A7DB69561A5}, // 1e-19
18684 {0x3AFF322E62439FCF, 0x9392EE8E921D5D07}, // 1e-18
18685 {0x09BEFEB9FAD487C2, 0xB877AA3236A4B449}, // 1e-17
18686 {0x4C2EBE687989A9B3, 0xE69594BEC44DE15B}, // 1e-16
18687 {0x0F9D37014BF60A10, 0x901D7CF73AB0ACD9}, // 1e-15
18688 {0x538484C19EF38C94, 0xB424DC35095CD80F}, // 1e-14
18689 {0x2865A5F206B06FB9, 0xE12E13424BB40E13}, // 1e-13
18690 {0xF93F87B7442E45D3, 0x8CBCCC096F5088CB}, // 1e-12
18691 {0xF78F69A51539D748, 0xAFEBFF0BCB24AAFE}, // 1e-11
18692 {0xB573440E5A884D1B, 0xDBE6FECEBDEDD5BE}, // 1e-10
18693 {0x31680A88F8953030, 0x89705F4136B4A597}, // 1e-9
18694 {0xFDC20D2B36BA7C3D, 0xABCC77118461CEFC}, // 1e-8
18695 {0x3D32907604691B4C, 0xD6BF94D5E57A42BC}, // 1e-7
18696 {0xA63F9A49C2C1B10F, 0x8637BD05AF6C69B5}, // 1e-6
18697 {0x0FCF80DC33721D53, 0xA7C5AC471B478423}, // 1e-5
18698 {0xD3C36113404EA4A8, 0xD1B71758E219652B}, // 1e-4
18699 {0x645A1CAC083126E9, 0x83126E978D4FDF3B}, // 1e-3
18700 {0x3D70A3D70A3D70A3, 0xA3D70A3D70A3D70A}, // 1e-2
18701 {0xCCCCCCCCCCCCCCCC, 0xCCCCCCCCCCCCCCCC}, // 1e-1
18702 {0x0000000000000000, 0x8000000000000000}, // 1e0
18703 {0x0000000000000000, 0xA000000000000000}, // 1e1
18704 {0x0000000000000000, 0xC800000000000000}, // 1e2
18705 {0x0000000000000000, 0xFA00000000000000}, // 1e3
18706 {0x0000000000000000, 0x9C40000000000000}, // 1e4
18707 {0x0000000000000000, 0xC350000000000000}, // 1e5
18708 {0x0000000000000000, 0xF424000000000000}, // 1e6
18709 {0x0000000000000000, 0x9896800000000000}, // 1e7
18710 {0x0000000000000000, 0xBEBC200000000000}, // 1e8
18711 {0x0000000000000000, 0xEE6B280000000000}, // 1e9
18712 {0x0000000000000000, 0x9502F90000000000}, // 1e10
18713 {0x0000000000000000, 0xBA43B74000000000}, // 1e11
18714 {0x0000000000000000, 0xE8D4A51000000000}, // 1e12
18715 {0x0000000000000000, 0x9184E72A00000000}, // 1e13
18716 {0x0000000000000000, 0xB5E620F480000000}, // 1e14
18717 {0x0000000000000000, 0xE35FA931A0000000}, // 1e15
18718 {0x0000000000000000, 0x8E1BC9BF04000000}, // 1e16
18719 {0x0000000000000000, 0xB1A2BC2EC5000000}, // 1e17
18720 {0x0000000000000000, 0xDE0B6B3A76400000}, // 1e18
18721 {0x0000000000000000, 0x8AC7230489E80000}, // 1e19
18722 {0x0000000000000000, 0xAD78EBC5AC620000}, // 1e20
18723 {0x0000000000000000, 0xD8D726B7177A8000}, // 1e21
18724 {0x0000000000000000, 0x878678326EAC9000}, // 1e22
18725 {0x0000000000000000, 0xA968163F0A57B400}, // 1e23
18726 {0x0000000000000000, 0xD3C21BCECCEDA100}, // 1e24
18727 {0x0000000000000000, 0x84595161401484A0}, // 1e25
18728 {0x0000000000000000, 0xA56FA5B99019A5C8}, // 1e26
18729 {0x0000000000000000, 0xCECB8F27F4200F3A}, // 1e27
18730 {0x4000000000000000, 0x813F3978F8940984}, // 1e28
18731 {0x5000000000000000, 0xA18F07D736B90BE5}, // 1e29
18732 {0xA400000000000000, 0xC9F2C9CD04674EDE}, // 1e30
18733 {0x4D00000000000000, 0xFC6F7C4045812296}, // 1e31
18734 {0xF020000000000000, 0x9DC5ADA82B70B59D}, // 1e32
18735 {0x6C28000000000000, 0xC5371912364CE305}, // 1e33
18736 {0xC732000000000000, 0xF684DF56C3E01BC6}, // 1e34
18737 {0x3C7F400000000000, 0x9A130B963A6C115C}, // 1e35
18738 {0x4B9F100000000000, 0xC097CE7BC90715B3}, // 1e36
18739 {0x1E86D40000000000, 0xF0BDC21ABB48DB20}, // 1e37
18740 {0x1314448000000000, 0x96769950B50D88F4}, // 1e38
18741 {0x17D955A000000000, 0xBC143FA4E250EB31}, // 1e39
18742 {0x5DCFAB0800000000, 0xEB194F8E1AE525FD}, // 1e40
18743 {0x5AA1CAE500000000, 0x92EFD1B8D0CF37BE}, // 1e41
18744 {0xF14A3D9E40000000, 0xB7ABC627050305AD}, // 1e42
18745 {0x6D9CCD05D0000000, 0xE596B7B0C643C719}, // 1e43
18746 {0xE4820023A2000000, 0x8F7E32CE7BEA5C6F}, // 1e44
18747 {0xDDA2802C8A800000, 0xB35DBF821AE4F38B}, // 1e45
18748 {0xD50B2037AD200000, 0xE0352F62A19E306E}, // 1e46
18749 {0x4526F422CC340000, 0x8C213D9DA502DE45}, // 1e47
18750 {0x9670B12B7F410000, 0xAF298D050E4395D6}, // 1e48
18751 {0x3C0CDD765F114000, 0xDAF3F04651D47B4C}, // 1e49
18752 {0xA5880A69FB6AC800, 0x88D8762BF324CD0F}, // 1e50
18753 {0x8EEA0D047A457A00, 0xAB0E93B6EFEE0053}, // 1e51
18754 {0x72A4904598D6D880, 0xD5D238A4ABE98068}, // 1e52
18755 {0x47A6DA2B7F864750, 0x85A36366EB71F041}, // 1e53
18756 {0x999090B65F67D924, 0xA70C3C40A64E6C51}, // 1e54
18757 {0xFFF4B4E3F741CF6D, 0xD0CF4B50CFE20765}, // 1e55
18758 {0xBFF8F10E7A8921A4, 0x82818F1281ED449F}, // 1e56
18759 {0xAFF72D52192B6A0D, 0xA321F2D7226895C7}, // 1e57
18760 {0x9BF4F8A69F764490, 0xCBEA6F8CEB02BB39}, // 1e58
18761 {0x02F236D04753D5B4, 0xFEE50B7025C36A08}, // 1e59
18762 {0x01D762422C946590, 0x9F4F2726179A2245}, // 1e60
18763 {0x424D3AD2B7B97EF5, 0xC722F0EF9D80AAD6}, // 1e61
18764 {0xD2E0898765A7DEB2, 0xF8EBAD2B84E0D58B}, // 1e62
18765 {0x63CC55F49F88EB2F, 0x9B934C3B330C8577}, // 1e63
18766 {0x3CBF6B71C76B25FB, 0xC2781F49FFCFA6D5}, // 1e64
18767 {0x8BEF464E3945EF7A, 0xF316271C7FC3908A}, // 1e65
18768 {0x97758BF0E3CBB5AC, 0x97EDD871CFDA3A56}, // 1e66
18769 {0x3D52EEED1CBEA317, 0xBDE94E8E43D0C8EC}, // 1e67
18770 {0x4CA7AAA863EE4BDD, 0xED63A231D4C4FB27}, // 1e68
18771 {0x8FE8CAA93E74EF6A, 0x945E455F24FB1CF8}, // 1e69
18772 {0xB3E2FD538E122B44, 0xB975D6B6EE39E436}, // 1e70
18773 {0x60DBBCA87196B616, 0xE7D34C64A9C85D44}, // 1e71
18774 {0xBC8955E946FE31CD, 0x90E40FBEEA1D3A4A}, // 1e72
18775 {0x6BABAB6398BDBE41, 0xB51D13AEA4A488DD}, // 1e73
18776 {0xC696963C7EED2DD1, 0xE264589A4DCDAB14}, // 1e74
18777 {0xFC1E1DE5CF543CA2, 0x8D7EB76070A08AEC}, // 1e75
18778 {0x3B25A55F43294BCB, 0xB0DE65388CC8ADA8}, // 1e76
18779 {0x49EF0EB713F39EBE, 0xDD15FE86AFFAD912}, // 1e77
18780 {0x6E3569326C784337, 0x8A2DBF142DFCC7AB}, // 1e78
18781 {0x49C2C37F07965404, 0xACB92ED9397BF996}, // 1e79
18782 {0xDC33745EC97BE906, 0xD7E77A8F87DAF7FB}, // 1e80
18783 {0x69A028BB3DED71A3, 0x86F0AC99B4E8DAFD}, // 1e81
18784 {0xC40832EA0D68CE0C, 0xA8ACD7C0222311BC}, // 1e82
18785 {0xF50A3FA490C30190, 0xD2D80DB02AABD62B}, // 1e83
18786 {0x792667C6DA79E0FA, 0x83C7088E1AAB65DB}, // 1e84
18787 {0x577001B891185938, 0xA4B8CAB1A1563F52}, // 1e85
18788 {0xED4C0226B55E6F86, 0xCDE6FD5E09ABCF26}, // 1e86
18789 {0x544F8158315B05B4, 0x80B05E5AC60B6178}, // 1e87
18790 {0x696361AE3DB1C721, 0xA0DC75F1778E39D6}, // 1e88
18791 {0x03BC3A19CD1E38E9, 0xC913936DD571C84C}, // 1e89
18792 {0x04AB48A04065C723, 0xFB5878494ACE3A5F}, // 1e90
18793 {0x62EB0D64283F9C76, 0x9D174B2DCEC0E47B}, // 1e91
18794 {0x3BA5D0BD324F8394, 0xC45D1DF942711D9A}, // 1e92
18795 {0xCA8F44EC7EE36479, 0xF5746577930D6500}, // 1e93
18796 {0x7E998B13CF4E1ECB, 0x9968BF6ABBE85F20}, // 1e94
18797 {0x9E3FEDD8C321A67E, 0xBFC2EF456AE276E8}, // 1e95
18798 {0xC5CFE94EF3EA101E, 0xEFB3AB16C59B14A2}, // 1e96
18799 {0xBBA1F1D158724A12, 0x95D04AEE3B80ECE5}, // 1e97
18800 {0x2A8A6E45AE8EDC97, 0xBB445DA9CA61281F}, // 1e98
18801 {0xF52D09D71A3293BD, 0xEA1575143CF97226}, // 1e99
18802 {0x593C2626705F9C56, 0x924D692CA61BE758}, // 1e100
18803 {0x6F8B2FB00C77836C, 0xB6E0C377CFA2E12E}, // 1e101
18804 {0x0B6DFB9C0F956447, 0xE498F455C38B997A}, // 1e102
18805 {0x4724BD4189BD5EAC, 0x8EDF98B59A373FEC}, // 1e103
18806 {0x58EDEC91EC2CB657, 0xB2977EE300C50FE7}, // 1e104
18807 {0x2F2967B66737E3ED, 0xDF3D5E9BC0F653E1}, // 1e105
18808 {0xBD79E0D20082EE74, 0x8B865B215899F46C}, // 1e106
18809 {0xECD8590680A3AA11, 0xAE67F1E9AEC07187}, // 1e107
18810 {0xE80E6F4820CC9495, 0xDA01EE641A708DE9}, // 1e108
18811 {0x3109058D147FDCDD, 0x884134FE908658B2}, // 1e109
18812 {0xBD4B46F0599FD415, 0xAA51823E34A7EEDE}, // 1e110
18813 {0x6C9E18AC7007C91A, 0xD4E5E2CDC1D1EA96}, // 1e111
18814 {0x03E2CF6BC604DDB0, 0x850FADC09923329E}, // 1e112
18815 {0x84DB8346B786151C, 0xA6539930BF6BFF45}, // 1e113
18816 {0xE612641865679A63, 0xCFE87F7CEF46FF16}, // 1e114
18817 {0x4FCB7E8F3F60C07E, 0x81F14FAE158C5F6E}, // 1e115
18818 {0xE3BE5E330F38F09D, 0xA26DA3999AEF7749}, // 1e116
18819 {0x5CADF5BFD3072CC5, 0xCB090C8001AB551C}, // 1e117
18820 {0x73D9732FC7C8F7F6, 0xFDCB4FA002162A63}, // 1e118
18821 {0x2867E7FDDCDD9AFA, 0x9E9F11C4014DDA7E}, // 1e119
18822 {0xB281E1FD541501B8, 0xC646D63501A1511D}, // 1e120
18823 {0x1F225A7CA91A4226, 0xF7D88BC24209A565}, // 1e121
18824 {0x3375788DE9B06958, 0x9AE757596946075F}, // 1e122
18825 {0x0052D6B1641C83AE, 0xC1A12D2FC3978937}, // 1e123
18826 {0xC0678C5DBD23A49A, 0xF209787BB47D6B84}, // 1e124
18827 {0xF840B7BA963646E0, 0x9745EB4D50CE6332}, // 1e125
18828 {0xB650E5A93BC3D898, 0xBD176620A501FBFF}, // 1e126
18829 {0xA3E51F138AB4CEBE, 0xEC5D3FA8CE427AFF}, // 1e127
18830 {0xC66F336C36B10137, 0x93BA47C980E98CDF}, // 1e128
18831 {0xB80B0047445D4184, 0xB8A8D9BBE123F017}, // 1e129
18832 {0xA60DC059157491E5, 0xE6D3102AD96CEC1D}, // 1e130
18833 {0x87C89837AD68DB2F, 0x9043EA1AC7E41392}, // 1e131
18834 {0x29BABE4598C311FB, 0xB454E4A179DD1877}, // 1e132
18835 {0xF4296DD6FEF3D67A, 0xE16A1DC9D8545E94}, // 1e133
18836 {0x1899E4A65F58660C, 0x8CE2529E2734BB1D}, // 1e134
18837 {0x5EC05DCFF72E7F8F, 0xB01AE745B101E9E4}, // 1e135
18838 {0x76707543F4FA1F73, 0xDC21A1171D42645D}, // 1e136
18839 {0x6A06494A791C53A8, 0x899504AE72497EBA}, // 1e137
18840 {0x0487DB9D17636892, 0xABFA45DA0EDBDE69}, // 1e138
18841 {0x45A9D2845D3C42B6, 0xD6F8D7509292D603}, // 1e139
18842 {0x0B8A2392BA45A9B2, 0x865B86925B9BC5C2}, // 1e140
18843 {0x8E6CAC7768D7141E, 0xA7F26836F282B732}, // 1e141
18844 {0x3207D795430CD926, 0xD1EF0244AF2364FF}, // 1e142
18845 {0x7F44E6BD49E807B8, 0x8335616AED761F1F}, // 1e143
18846 {0x5F16206C9C6209A6, 0xA402B9C5A8D3A6E7}, // 1e144
18847 {0x36DBA887C37A8C0F, 0xCD036837130890A1}, // 1e145
18848 {0xC2494954DA2C9789, 0x802221226BE55A64}, // 1e146
18849 {0xF2DB9BAA10B7BD6C, 0xA02AA96B06DEB0FD}, // 1e147
18850 {0x6F92829494E5ACC7, 0xC83553C5C8965D3D}, // 1e148
18851 {0xCB772339BA1F17F9, 0xFA42A8B73ABBF48C}, // 1e149
18852 {0xFF2A760414536EFB, 0x9C69A97284B578D7}, // 1e150
18853 {0xFEF5138519684ABA, 0xC38413CF25E2D70D}, // 1e151
18854 {0x7EB258665FC25D69, 0xF46518C2EF5B8CD1}, // 1e152
18855 {0xEF2F773FFBD97A61, 0x98BF2F79D5993802}, // 1e153
18856 {0xAAFB550FFACFD8FA, 0xBEEEFB584AFF8603}, // 1e154
18857 {0x95BA2A53F983CF38, 0xEEAABA2E5DBF6784}, // 1e155
18858 {0xDD945A747BF26183, 0x952AB45CFA97A0B2}, // 1e156
18859 {0x94F971119AEEF9E4, 0xBA756174393D88DF}, // 1e157
18860 {0x7A37CD5601AAB85D, 0xE912B9D1478CEB17}, // 1e158
18861 {0xAC62E055C10AB33A, 0x91ABB422CCB812EE}, // 1e159
18862 {0x577B986B314D6009, 0xB616A12B7FE617AA}, // 1e160
18863 {0xED5A7E85FDA0B80B, 0xE39C49765FDF9D94}, // 1e161
18864 {0x14588F13BE847307, 0x8E41ADE9FBEBC27D}, // 1e162
18865 {0x596EB2D8AE258FC8, 0xB1D219647AE6B31C}, // 1e163
18866 {0x6FCA5F8ED9AEF3BB, 0xDE469FBD99A05FE3}, // 1e164
18867 {0x25DE7BB9480D5854, 0x8AEC23D680043BEE}, // 1e165
18868 {0xAF561AA79A10AE6A, 0xADA72CCC20054AE9}, // 1e166
18869 {0x1B2BA1518094DA04, 0xD910F7FF28069DA4}, // 1e167
18870 {0x90FB44D2F05D0842, 0x87AA9AFF79042286}, // 1e168
18871 {0x353A1607AC744A53, 0xA99541BF57452B28}, // 1e169
18872 {0x42889B8997915CE8, 0xD3FA922F2D1675F2}, // 1e170
18873 {0x69956135FEBADA11, 0x847C9B5D7C2E09B7}, // 1e171
18874 {0x43FAB9837E699095, 0xA59BC234DB398C25}, // 1e172
18875 {0x94F967E45E03F4BB, 0xCF02B2C21207EF2E}, // 1e173
18876 {0x1D1BE0EEBAC278F5, 0x8161AFB94B44F57D}, // 1e174
18877 {0x6462D92A69731732, 0xA1BA1BA79E1632DC}, // 1e175
18878 {0x7D7B8F7503CFDCFE, 0xCA28A291859BBF93}, // 1e176
18879 {0x5CDA735244C3D43E, 0xFCB2CB35E702AF78}, // 1e177
18880 {0x3A0888136AFA64A7, 0x9DEFBF01B061ADAB}, // 1e178
18881 {0x088AAA1845B8FDD0, 0xC56BAEC21C7A1916}, // 1e179
18882 {0x8AAD549E57273D45, 0xF6C69A72A3989F5B}, // 1e180
18883 {0x36AC54E2F678864B, 0x9A3C2087A63F6399}, // 1e181
18884 {0x84576A1BB416A7DD, 0xC0CB28A98FCF3C7F}, // 1e182
18885 {0x656D44A2A11C51D5, 0xF0FDF2D3F3C30B9F}, // 1e183
18886 {0x9F644AE5A4B1B325, 0x969EB7C47859E743}, // 1e184
18887 {0x873D5D9F0DDE1FEE, 0xBC4665B596706114}, // 1e185
18888 {0xA90CB506D155A7EA, 0xEB57FF22FC0C7959}, // 1e186
18889 {0x09A7F12442D588F2, 0x9316FF75DD87CBD8}, // 1e187
18890 {0x0C11ED6D538AEB2F, 0xB7DCBF5354E9BECE}, // 1e188
18891 {0x8F1668C8A86DA5FA, 0xE5D3EF282A242E81}, // 1e189
18892 {0xF96E017D694487BC, 0x8FA475791A569D10}, // 1e190
18893 {0x37C981DCC395A9AC, 0xB38D92D760EC4455}, // 1e191
18894 {0x85BBE253F47B1417, 0xE070F78D3927556A}, // 1e192
18895 {0x93956D7478CCEC8E, 0x8C469AB843B89562}, // 1e193
18896 {0x387AC8D1970027B2, 0xAF58416654A6BABB}, // 1e194
18897 {0x06997B05FCC0319E, 0xDB2E51BFE9D0696A}, // 1e195
18898 {0x441FECE3BDF81F03, 0x88FCF317F22241E2}, // 1e196
18899 {0xD527E81CAD7626C3, 0xAB3C2FDDEEAAD25A}, // 1e197
18900 {0x8A71E223D8D3B074, 0xD60B3BD56A5586F1}, // 1e198
18901 {0xF6872D5667844E49, 0x85C7056562757456}, // 1e199
18902 {0xB428F8AC016561DB, 0xA738C6BEBB12D16C}, // 1e200
18903 {0xE13336D701BEBA52, 0xD106F86E69D785C7}, // 1e201
18904 {0xECC0024661173473, 0x82A45B450226B39C}, // 1e202
18905 {0x27F002D7F95D0190, 0xA34D721642B06084}, // 1e203
18906 {0x31EC038DF7B441F4, 0xCC20CE9BD35C78A5}, // 1e204
18907 {0x7E67047175A15271, 0xFF290242C83396CE}, // 1e205
18908 {0x0F0062C6E984D386, 0x9F79A169BD203E41}, // 1e206
18909 {0x52C07B78A3E60868, 0xC75809C42C684DD1}, // 1e207
18910 {0xA7709A56CCDF8A82, 0xF92E0C3537826145}, // 1e208
18911 {0x88A66076400BB691, 0x9BBCC7A142B17CCB}, // 1e209
18912 {0x6ACFF893D00EA435, 0xC2ABF989935DDBFE}, // 1e210
18913 {0x0583F6B8C4124D43, 0xF356F7EBF83552FE}, // 1e211
18914 {0xC3727A337A8B704A, 0x98165AF37B2153DE}, // 1e212
18915 {0x744F18C0592E4C5C, 0xBE1BF1B059E9A8D6}, // 1e213
18916 {0x1162DEF06F79DF73, 0xEDA2EE1C7064130C}, // 1e214
18917 {0x8ADDCB5645AC2BA8, 0x9485D4D1C63E8BE7}, // 1e215
18918 {0x6D953E2BD7173692, 0xB9A74A0637CE2EE1}, // 1e216
18919 {0xC8FA8DB6CCDD0437, 0xE8111C87C5C1BA99}, // 1e217
18920 {0x1D9C9892400A22A2, 0x910AB1D4DB9914A0}, // 1e218
18921 {0x2503BEB6D00CAB4B, 0xB54D5E4A127F59C8}, // 1e219
18922 {0x2E44AE64840FD61D, 0xE2A0B5DC971F303A}, // 1e220
18923 {0x5CEAECFED289E5D2, 0x8DA471A9DE737E24}, // 1e221
18924 {0x7425A83E872C5F47, 0xB10D8E1456105DAD}, // 1e222
18925 {0xD12F124E28F77719, 0xDD50F1996B947518}, // 1e223
18926 {0x82BD6B70D99AAA6F, 0x8A5296FFE33CC92F}, // 1e224
18927 {0x636CC64D1001550B, 0xACE73CBFDC0BFB7B}, // 1e225
18928 {0x3C47F7E05401AA4E, 0xD8210BEFD30EFA5A}, // 1e226
18929 {0x65ACFAEC34810A71, 0x8714A775E3E95C78}, // 1e227
18930 {0x7F1839A741A14D0D, 0xA8D9D1535CE3B396}, // 1e228
18931 {0x1EDE48111209A050, 0xD31045A8341CA07C}, // 1e229
18932 {0x934AED0AAB460432, 0x83EA2B892091E44D}, // 1e230
18933 {0xF81DA84D5617853F, 0xA4E4B66B68B65D60}, // 1e231
18934 {0x36251260AB9D668E, 0xCE1DE40642E3F4B9}, // 1e232
18935 {0xC1D72B7C6B426019, 0x80D2AE83E9CE78F3}, // 1e233
18936 {0xB24CF65B8612F81F, 0xA1075A24E4421730}, // 1e234
18937 {0xDEE033F26797B627, 0xC94930AE1D529CFC}, // 1e235
18938 {0x169840EF017DA3B1, 0xFB9B7CD9A4A7443C}, // 1e236
18939 {0x8E1F289560EE864E, 0x9D412E0806E88AA5}, // 1e237
18940 {0xF1A6F2BAB92A27E2, 0xC491798A08A2AD4E}, // 1e238
18941 {0xAE10AF696774B1DB, 0xF5B5D7EC8ACB58A2}, // 1e239
18942 {0xACCA6DA1E0A8EF29, 0x9991A6F3D6BF1765}, // 1e240
18943 {0x17FD090A58D32AF3, 0xBFF610B0CC6EDD3F}, // 1e241
18944 {0xDDFC4B4CEF07F5B0, 0xEFF394DCFF8A948E}, // 1e242
18945 {0x4ABDAF101564F98E, 0x95F83D0A1FB69CD9}, // 1e243
18946 {0x9D6D1AD41ABE37F1, 0xBB764C4CA7A4440F}, // 1e244
18947 {0x84C86189216DC5ED, 0xEA53DF5FD18D5513}, // 1e245
18948 {0x32FD3CF5B4E49BB4, 0x92746B9BE2F8552C}, // 1e246
18949 {0x3FBC8C33221DC2A1, 0xB7118682DBB66A77}, // 1e247
18950 {0x0FABAF3FEAA5334A, 0xE4D5E82392A40515}, // 1e248
18951 {0x29CB4D87F2A7400E, 0x8F05B1163BA6832D}, // 1e249
18952 {0x743E20E9EF511012, 0xB2C71D5BCA9023F8}, // 1e250
18953 {0x914DA9246B255416, 0xDF78E4B2BD342CF6}, // 1e251
18954 {0x1AD089B6C2F7548E, 0x8BAB8EEFB6409C1A}, // 1e252
18955 {0xA184AC2473B529B1, 0xAE9672ABA3D0C320}, // 1e253
18956 {0xC9E5D72D90A2741E, 0xDA3C0F568CC4F3E8}, // 1e254
18957 {0x7E2FA67C7A658892, 0x8865899617FB1871}, // 1e255
18958 {0xDDBB901B98FEEAB7, 0xAA7EEBFB9DF9DE8D}, // 1e256
18959 {0x552A74227F3EA565, 0xD51EA6FA85785631}, // 1e257
18960 {0xD53A88958F87275F, 0x8533285C936B35DE}, // 1e258
18961 {0x8A892ABAF368F137, 0xA67FF273B8460356}, // 1e259
18962 {0x2D2B7569B0432D85, 0xD01FEF10A657842C}, // 1e260
18963 {0x9C3B29620E29FC73, 0x8213F56A67F6B29B}, // 1e261
18964 {0x8349F3BA91B47B8F, 0xA298F2C501F45F42}, // 1e262
18965 {0x241C70A936219A73, 0xCB3F2F7642717713}, // 1e263
18966 {0xED238CD383AA0110, 0xFE0EFB53D30DD4D7}, // 1e264
18967 {0xF4363804324A40AA, 0x9EC95D1463E8A506}, // 1e265
18968 {0xB143C6053EDCD0D5, 0xC67BB4597CE2CE48}, // 1e266
18969 {0xDD94B7868E94050A, 0xF81AA16FDC1B81DA}, // 1e267
18970 {0xCA7CF2B4191C8326, 0x9B10A4E5E9913128}, // 1e268
18971 {0xFD1C2F611F63A3F0, 0xC1D4CE1F63F57D72}, // 1e269
18972 {0xBC633B39673C8CEC, 0xF24A01A73CF2DCCF}, // 1e270
18973 {0xD5BE0503E085D813, 0x976E41088617CA01}, // 1e271
18974 {0x4B2D8644D8A74E18, 0xBD49D14AA79DBC82}, // 1e272
18975 {0xDDF8E7D60ED1219E, 0xEC9C459D51852BA2}, // 1e273
18976 {0xCABB90E5C942B503, 0x93E1AB8252F33B45}, // 1e274
18977 {0x3D6A751F3B936243, 0xB8DA1662E7B00A17}, // 1e275
18978 {0x0CC512670A783AD4, 0xE7109BFBA19C0C9D}, // 1e276
18979 {0x27FB2B80668B24C5, 0x906A617D450187E2}, // 1e277
18980 {0xB1F9F660802DEDF6, 0xB484F9DC9641E9DA}, // 1e278
18981 {0x5E7873F8A0396973, 0xE1A63853BBD26451}, // 1e279
18982 {0xDB0B487B6423E1E8, 0x8D07E33455637EB2}, // 1e280
18983 {0x91CE1A9A3D2CDA62, 0xB049DC016ABC5E5F}, // 1e281
18984 {0x7641A140CC7810FB, 0xDC5C5301C56B75F7}, // 1e282
18985 {0xA9E904C87FCB0A9D, 0x89B9B3E11B6329BA}, // 1e283
18986 {0x546345FA9FBDCD44, 0xAC2820D9623BF429}, // 1e284
18987 {0xA97C177947AD4095, 0xD732290FBACAF133}, // 1e285
18988 {0x49ED8EABCCCC485D, 0x867F59A9D4BED6C0}, // 1e286
18989 {0x5C68F256BFFF5A74, 0xA81F301449EE8C70}, // 1e287
18990 {0x73832EEC6FFF3111, 0xD226FC195C6A2F8C}, // 1e288
18993 // wuffs_private_impl__f64_powers_of_10 holds powers of 10 that can be exactly
18994 // represented by a float64 (what C calls a double).
18995 static const double wuffs_private_impl__f64_powers_of_10[23] = {
18996 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11,
18997 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22,
19000 // ---------------- IEEE 754 Floating Point
19002 WUFFS_BASE__MAYBE_STATIC wuffs_base__lossy_value_u16 //
19003 wuffs_base__ieee_754_bit_representation__from_f64_to_u16_truncate(double f) {
19004 uint64_t u = 0;
19005 if (sizeof(uint64_t) == sizeof(double)) {
19006 memcpy(&u, &f, sizeof(uint64_t));
19008 uint16_t neg = ((uint16_t)((u >> 63) << 15));
19009 u &= 0x7FFFFFFFFFFFFFFF;
19010 uint64_t exp = u >> 52;
19011 uint64_t man = u & 0x000FFFFFFFFFFFFF;
19013 if (exp == 0x7FF) {
19014 if (man == 0) { // Infinity.
19015 wuffs_base__lossy_value_u16 ret;
19016 ret.value = neg | 0x7C00;
19017 ret.lossy = false;
19018 return ret;
19020 // NaN. Shift the 52 mantissa bits to 10 mantissa bits, keeping the most
19021 // significant mantissa bit (quiet vs signaling NaNs). Also set the low 9
19022 // bits of ret.value so that the 10-bit mantissa is non-zero.
19023 wuffs_base__lossy_value_u16 ret;
19024 ret.value = neg | 0x7DFF | ((uint16_t)(man >> 42));
19025 ret.lossy = false;
19026 return ret;
19028 } else if (exp > 0x40E) { // Truncate to the largest finite f16.
19029 wuffs_base__lossy_value_u16 ret;
19030 ret.value = neg | 0x7BFF;
19031 ret.lossy = true;
19032 return ret;
19034 } else if (exp <= 0x3E6) { // Truncate to zero.
19035 wuffs_base__lossy_value_u16 ret;
19036 ret.value = neg;
19037 ret.lossy = (u != 0);
19038 return ret;
19040 } else if (exp <= 0x3F0) { // Normal f64, subnormal f16.
19041 // Convert from a 53-bit mantissa (after realizing the implicit bit) to a
19042 // 10-bit mantissa and then adjust for the exponent.
19043 man |= 0x0010000000000000;
19044 uint32_t shift = ((uint32_t)(1051 - exp)); // 1051 = 0x3F0 + 53 - 10.
19045 uint64_t shifted_man = man >> shift;
19046 wuffs_base__lossy_value_u16 ret;
19047 ret.value = neg | ((uint16_t)shifted_man);
19048 ret.lossy = (shifted_man << shift) != man;
19049 return ret;
19052 // Normal f64, normal f16.
19054 // Re-bias from 1023 to 15 and shift above f16's 10 mantissa bits.
19055 exp = (exp - 1008) << 10; // 1008 = 1023 - 15 = 0x3FF - 0xF.
19057 // Convert from a 52-bit mantissa (excluding the implicit bit) to a 10-bit
19058 // mantissa (again excluding the implicit bit). We lose some information if
19059 // any of the bottom 42 bits are non-zero.
19060 wuffs_base__lossy_value_u16 ret;
19061 ret.value = neg | ((uint16_t)exp) | ((uint16_t)(man >> 42));
19062 ret.lossy = (man << 22) != 0;
19063 return ret;
19066 WUFFS_BASE__MAYBE_STATIC wuffs_base__lossy_value_u32 //
19067 wuffs_base__ieee_754_bit_representation__from_f64_to_u32_truncate(double f) {
19068 uint64_t u = 0;
19069 if (sizeof(uint64_t) == sizeof(double)) {
19070 memcpy(&u, &f, sizeof(uint64_t));
19072 uint32_t neg = ((uint32_t)(u >> 63)) << 31;
19073 u &= 0x7FFFFFFFFFFFFFFF;
19074 uint64_t exp = u >> 52;
19075 uint64_t man = u & 0x000FFFFFFFFFFFFF;
19077 if (exp == 0x7FF) {
19078 if (man == 0) { // Infinity.
19079 wuffs_base__lossy_value_u32 ret;
19080 ret.value = neg | 0x7F800000;
19081 ret.lossy = false;
19082 return ret;
19084 // NaN. Shift the 52 mantissa bits to 23 mantissa bits, keeping the most
19085 // significant mantissa bit (quiet vs signaling NaNs). Also set the low 22
19086 // bits of ret.value so that the 23-bit mantissa is non-zero.
19087 wuffs_base__lossy_value_u32 ret;
19088 ret.value = neg | 0x7FBFFFFF | ((uint32_t)(man >> 29));
19089 ret.lossy = false;
19090 return ret;
19092 } else if (exp > 0x47E) { // Truncate to the largest finite f32.
19093 wuffs_base__lossy_value_u32 ret;
19094 ret.value = neg | 0x7F7FFFFF;
19095 ret.lossy = true;
19096 return ret;
19098 } else if (exp <= 0x369) { // Truncate to zero.
19099 wuffs_base__lossy_value_u32 ret;
19100 ret.value = neg;
19101 ret.lossy = (u != 0);
19102 return ret;
19104 } else if (exp <= 0x380) { // Normal f64, subnormal f32.
19105 // Convert from a 53-bit mantissa (after realizing the implicit bit) to a
19106 // 23-bit mantissa and then adjust for the exponent.
19107 man |= 0x0010000000000000;
19108 uint32_t shift = ((uint32_t)(926 - exp)); // 926 = 0x380 + 53 - 23.
19109 uint64_t shifted_man = man >> shift;
19110 wuffs_base__lossy_value_u32 ret;
19111 ret.value = neg | ((uint32_t)shifted_man);
19112 ret.lossy = (shifted_man << shift) != man;
19113 return ret;
19116 // Normal f64, normal f32.
19118 // Re-bias from 1023 to 127 and shift above f32's 23 mantissa bits.
19119 exp = (exp - 896) << 23; // 896 = 1023 - 127 = 0x3FF - 0x7F.
19121 // Convert from a 52-bit mantissa (excluding the implicit bit) to a 23-bit
19122 // mantissa (again excluding the implicit bit). We lose some information if
19123 // any of the bottom 29 bits are non-zero.
19124 wuffs_base__lossy_value_u32 ret;
19125 ret.value = neg | ((uint32_t)exp) | ((uint32_t)(man >> 29));
19126 ret.lossy = (man << 35) != 0;
19127 return ret;
19130 // --------
19132 #define WUFFS_PRIVATE_IMPL__HPD__DECIMAL_POINT__RANGE 2047
19133 #define WUFFS_PRIVATE_IMPL__HPD__DIGITS_PRECISION 800
19135 // WUFFS_PRIVATE_IMPL__HPD__SHIFT__MAX_INCL is the largest N such that
19136 // ((10 << N) < (1 << 64)).
19137 #define WUFFS_PRIVATE_IMPL__HPD__SHIFT__MAX_INCL 60
19139 // wuffs_private_impl__high_prec_dec (abbreviated as HPD) is a fixed precision
19140 // floating point decimal number, augmented with ±infinity values, but it
19141 // cannot represent NaN (Not a Number).
19143 // "High precision" means that the mantissa holds 800 decimal digits. 800 is
19144 // WUFFS_PRIVATE_IMPL__HPD__DIGITS_PRECISION.
19146 // An HPD isn't for general purpose arithmetic, only for conversions to and
19147 // from IEEE 754 double-precision floating point, where the largest and
19148 // smallest positive, finite values are approximately 1.8e+308 and 4.9e-324.
19149 // HPD exponents above +2047 mean infinity, below -2047 mean zero. The ±2047
19150 // bounds are further away from zero than ±(324 + 800), where 800 and 2047 is
19151 // WUFFS_PRIVATE_IMPL__HPD__DIGITS_PRECISION and
19152 // WUFFS_PRIVATE_IMPL__HPD__DECIMAL_POINT__RANGE.
19154 // digits[.. num_digits] are the number's digits in big-endian order. The
19155 // uint8_t values are in the range [0 ..= 9], not ['0' ..= '9'], where e.g. '7'
19156 // is the ASCII value 0x37.
19158 // decimal_point is the index (within digits) of the decimal point. It may be
19159 // negative or be larger than num_digits, in which case the explicit digits are
19160 // padded with implicit zeroes.
19162 // For example, if num_digits is 3 and digits is "\x07\x08\x09":
19163 // - A decimal_point of -2 means ".00789"
19164 // - A decimal_point of -1 means ".0789"
19165 // - A decimal_point of +0 means ".789"
19166 // - A decimal_point of +1 means "7.89"
19167 // - A decimal_point of +2 means "78.9"
19168 // - A decimal_point of +3 means "789."
19169 // - A decimal_point of +4 means "7890."
19170 // - A decimal_point of +5 means "78900."
19172 // As above, a decimal_point higher than +2047 means that the overall value is
19173 // infinity, lower than -2047 means zero.
19175 // negative is a sign bit. An HPD can distinguish positive and negative zero.
19177 // truncated is whether there are more than
19178 // WUFFS_PRIVATE_IMPL__HPD__DIGITS_PRECISION digits, and at least one of those
19179 // extra digits are non-zero. The existence of long-tail digits can affect
19180 // rounding.
19182 // The "all fields are zero" value is valid, and represents the number +0.
19183 typedef struct wuffs_private_impl__high_prec_dec__struct {
19184 uint32_t num_digits;
19185 int32_t decimal_point;
19186 bool negative;
19187 bool truncated;
19188 uint8_t digits[WUFFS_PRIVATE_IMPL__HPD__DIGITS_PRECISION];
19189 } wuffs_private_impl__high_prec_dec;
19191 // wuffs_private_impl__high_prec_dec__trim trims trailing zeroes from the
19192 // h->digits[.. h->num_digits] slice. They have no benefit, since we explicitly
19193 // track h->decimal_point.
19195 // Preconditions:
19196 // - h is non-NULL.
19197 static inline void //
19198 wuffs_private_impl__high_prec_dec__trim(wuffs_private_impl__high_prec_dec* h) {
19199 while ((h->num_digits > 0) && (h->digits[h->num_digits - 1] == 0)) {
19200 h->num_digits--;
19204 // wuffs_private_impl__high_prec_dec__assign sets h to represent the number x.
19206 // Preconditions:
19207 // - h is non-NULL.
19208 static void //
19209 wuffs_private_impl__high_prec_dec__assign(wuffs_private_impl__high_prec_dec* h,
19210 uint64_t x,
19211 bool negative) {
19212 uint32_t n = 0;
19214 // Set h->digits.
19215 if (x > 0) {
19216 // Calculate the digits, working right-to-left. After we determine n (how
19217 // many digits there are), copy from buf to h->digits.
19219 // UINT64_MAX, 18446744073709551615, is 20 digits long. It can be faster to
19220 // copy a constant number of bytes than a variable number (20 instead of
19221 // n). Make buf large enough (and start writing to it from the middle) so
19222 // that can we always copy 20 bytes: the slice buf[(20-n) .. (40-n)].
19223 uint8_t buf[40] = {0};
19224 uint8_t* ptr = &buf[20];
19225 do {
19226 uint64_t remaining = x / 10;
19227 x -= remaining * 10;
19228 ptr--;
19229 *ptr = (uint8_t)x;
19230 n++;
19231 x = remaining;
19232 } while (x > 0);
19233 memcpy(h->digits, ptr, 20);
19236 // Set h's other fields.
19237 h->num_digits = n;
19238 h->decimal_point = (int32_t)n;
19239 h->negative = negative;
19240 h->truncated = false;
19241 wuffs_private_impl__high_prec_dec__trim(h);
19244 static wuffs_base__status //
19245 wuffs_private_impl__high_prec_dec__parse(wuffs_private_impl__high_prec_dec* h,
19246 wuffs_base__slice_u8 s,
19247 uint32_t options) {
19248 if (!h) {
19249 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
19251 h->num_digits = 0;
19252 h->decimal_point = 0;
19253 h->negative = false;
19254 h->truncated = false;
19256 uint8_t* p = s.ptr;
19257 uint8_t* q = s.ptr + s.len;
19259 if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
19260 for (;; p++) {
19261 if (p >= q) {
19262 return wuffs_base__make_status(wuffs_base__error__bad_argument);
19263 } else if (*p != '_') {
19264 break;
19269 // Parse sign.
19270 do {
19271 if (*p == '+') {
19272 p++;
19273 } else if (*p == '-') {
19274 h->negative = true;
19275 p++;
19276 } else {
19277 break;
19279 if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
19280 for (;; p++) {
19281 if (p >= q) {
19282 return wuffs_base__make_status(wuffs_base__error__bad_argument);
19283 } else if (*p != '_') {
19284 break;
19288 } while (0);
19290 // Parse digits, up to (and including) a '.', 'E' or 'e'. Examples for each
19291 // limb in this if-else chain:
19292 // - "0.789"
19293 // - "1002.789"
19294 // - ".789"
19295 // - Other (invalid input).
19296 uint32_t nd = 0;
19297 int32_t dp = 0;
19298 bool no_digits_before_separator = false;
19299 if (('0' == *p) &&
19300 !(options &
19301 WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_MULTIPLE_LEADING_ZEROES)) {
19302 p++;
19303 for (;; p++) {
19304 if (p >= q) {
19305 goto after_all;
19306 } else if (*p ==
19307 ((options &
19308 WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)
19309 ? ','
19310 : '.')) {
19311 p++;
19312 goto after_sep;
19313 } else if ((*p == 'E') || (*p == 'e')) {
19314 p++;
19315 goto after_exp;
19316 } else if ((*p != '_') ||
19317 !(options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) {
19318 return wuffs_base__make_status(wuffs_base__error__bad_argument);
19322 } else if (('0' <= *p) && (*p <= '9')) {
19323 if (*p == '0') {
19324 for (; (p < q) && (*p == '0'); p++) {
19326 } else {
19327 h->digits[nd++] = (uint8_t)(*p - '0');
19328 dp = (int32_t)nd;
19329 p++;
19332 for (;; p++) {
19333 if (p >= q) {
19334 goto after_all;
19335 } else if (('0' <= *p) && (*p <= '9')) {
19336 if (nd < WUFFS_PRIVATE_IMPL__HPD__DIGITS_PRECISION) {
19337 h->digits[nd++] = (uint8_t)(*p - '0');
19338 dp = (int32_t)nd;
19339 } else if ('0' != *p) {
19340 // Long-tail non-zeroes set the truncated bit.
19341 h->truncated = true;
19343 } else if (*p ==
19344 ((options &
19345 WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)
19346 ? ','
19347 : '.')) {
19348 p++;
19349 goto after_sep;
19350 } else if ((*p == 'E') || (*p == 'e')) {
19351 p++;
19352 goto after_exp;
19353 } else if ((*p != '_') ||
19354 !(options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) {
19355 return wuffs_base__make_status(wuffs_base__error__bad_argument);
19359 } else if (*p == ((options &
19360 WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)
19361 ? ','
19362 : '.')) {
19363 p++;
19364 no_digits_before_separator = true;
19366 } else {
19367 return wuffs_base__make_status(wuffs_base__error__bad_argument);
19370 after_sep:
19371 for (;; p++) {
19372 if (p >= q) {
19373 goto after_all;
19374 } else if ('0' == *p) {
19375 if (nd == 0) {
19376 // Track leading zeroes implicitly.
19377 dp--;
19378 } else if (nd < WUFFS_PRIVATE_IMPL__HPD__DIGITS_PRECISION) {
19379 h->digits[nd++] = (uint8_t)(*p - '0');
19381 } else if (('0' < *p) && (*p <= '9')) {
19382 if (nd < WUFFS_PRIVATE_IMPL__HPD__DIGITS_PRECISION) {
19383 h->digits[nd++] = (uint8_t)(*p - '0');
19384 } else {
19385 // Long-tail non-zeroes set the truncated bit.
19386 h->truncated = true;
19388 } else if ((*p == 'E') || (*p == 'e')) {
19389 p++;
19390 goto after_exp;
19391 } else if ((*p != '_') ||
19392 !(options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) {
19393 return wuffs_base__make_status(wuffs_base__error__bad_argument);
19397 after_exp:
19398 do {
19399 if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
19400 for (;; p++) {
19401 if (p >= q) {
19402 return wuffs_base__make_status(wuffs_base__error__bad_argument);
19403 } else if (*p != '_') {
19404 break;
19409 int32_t exp_sign = +1;
19410 if (*p == '+') {
19411 p++;
19412 } else if (*p == '-') {
19413 exp_sign = -1;
19414 p++;
19417 int32_t exp = 0;
19418 const int32_t exp_large = WUFFS_PRIVATE_IMPL__HPD__DECIMAL_POINT__RANGE +
19419 WUFFS_PRIVATE_IMPL__HPD__DIGITS_PRECISION;
19420 bool saw_exp_digits = false;
19421 for (; p < q; p++) {
19422 if ((*p == '_') &&
19423 (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) {
19424 // No-op.
19425 } else if (('0' <= *p) && (*p <= '9')) {
19426 saw_exp_digits = true;
19427 if (exp < exp_large) {
19428 exp = (10 * exp) + ((int32_t)(*p - '0'));
19430 } else {
19431 break;
19434 if (!saw_exp_digits) {
19435 return wuffs_base__make_status(wuffs_base__error__bad_argument);
19437 dp += exp_sign * exp;
19438 } while (0);
19440 after_all:
19441 if (p != q) {
19442 return wuffs_base__make_status(wuffs_base__error__bad_argument);
19444 h->num_digits = nd;
19445 if (nd == 0) {
19446 if (no_digits_before_separator) {
19447 return wuffs_base__make_status(wuffs_base__error__bad_argument);
19449 h->decimal_point = 0;
19450 } else if (dp < -WUFFS_PRIVATE_IMPL__HPD__DECIMAL_POINT__RANGE) {
19451 h->decimal_point = -WUFFS_PRIVATE_IMPL__HPD__DECIMAL_POINT__RANGE - 1;
19452 } else if (dp > +WUFFS_PRIVATE_IMPL__HPD__DECIMAL_POINT__RANGE) {
19453 h->decimal_point = +WUFFS_PRIVATE_IMPL__HPD__DECIMAL_POINT__RANGE + 1;
19454 } else {
19455 h->decimal_point = dp;
19457 wuffs_private_impl__high_prec_dec__trim(h);
19458 return wuffs_base__make_status(NULL);
19461 // --------
19463 // wuffs_private_impl__high_prec_dec__lshift_num_new_digits returns the number
19464 // of additional decimal digits when left-shifting by shift.
19466 // See below for preconditions.
19467 static uint32_t //
19468 wuffs_private_impl__high_prec_dec__lshift_num_new_digits(
19469 wuffs_private_impl__high_prec_dec* h,
19470 uint32_t shift) {
19471 // Masking with 0x3F should be unnecessary (assuming the preconditions) but
19472 // it's cheap and ensures that we don't overflow the
19473 // wuffs_private_impl__hpd_left_shift array.
19474 shift &= 63;
19476 uint32_t x_a = wuffs_private_impl__hpd_left_shift[shift];
19477 uint32_t x_b = wuffs_private_impl__hpd_left_shift[shift + 1];
19478 uint32_t num_new_digits = x_a >> 11;
19479 uint32_t pow5_a = 0x7FF & x_a;
19480 uint32_t pow5_b = 0x7FF & x_b;
19482 const uint8_t* pow5 = &wuffs_private_impl__powers_of_5[pow5_a];
19483 uint32_t i = 0;
19484 uint32_t n = pow5_b - pow5_a;
19485 for (; i < n; i++) {
19486 if (i >= h->num_digits) {
19487 return num_new_digits - 1;
19488 } else if (h->digits[i] == pow5[i]) {
19489 continue;
19490 } else if (h->digits[i] < pow5[i]) {
19491 return num_new_digits - 1;
19492 } else {
19493 return num_new_digits;
19496 return num_new_digits;
19499 // --------
19501 // wuffs_private_impl__high_prec_dec__rounded_integer returns the integral
19502 // (non-fractional) part of h, provided that it is 18 or fewer decimal digits.
19503 // For 19 or more digits, it returns UINT64_MAX. Note that:
19504 // - (1 << 53) is 9007199254740992, which has 16 decimal digits.
19505 // - (1 << 56) is 72057594037927936, which has 17 decimal digits.
19506 // - (1 << 59) is 576460752303423488, which has 18 decimal digits.
19507 // - (1 << 63) is 9223372036854775808, which has 19 decimal digits.
19508 // and that IEEE 754 double precision has 52 mantissa bits.
19510 // That integral part is rounded-to-even: rounding 7.5 or 8.5 both give 8.
19512 // h's negative bit is ignored: rounding -8.6 returns 9.
19514 // See below for preconditions.
19515 static uint64_t //
19516 wuffs_private_impl__high_prec_dec__rounded_integer(
19517 wuffs_private_impl__high_prec_dec* h) {
19518 if ((h->num_digits == 0) || (h->decimal_point < 0)) {
19519 return 0;
19520 } else if (h->decimal_point > 18) {
19521 return UINT64_MAX;
19524 uint32_t dp = (uint32_t)(h->decimal_point);
19525 uint64_t n = 0;
19526 uint32_t i = 0;
19527 for (; i < dp; i++) {
19528 n = (10 * n) + ((i < h->num_digits) ? h->digits[i] : 0);
19531 bool round_up = false;
19532 if (dp < h->num_digits) {
19533 round_up = h->digits[dp] >= 5;
19534 if ((h->digits[dp] == 5) && (dp + 1 == h->num_digits)) {
19535 // We are exactly halfway. If we're truncated, round up, otherwise round
19536 // to even.
19537 round_up = h->truncated || //
19538 ((dp > 0) && (1 & h->digits[dp - 1]));
19541 if (round_up) {
19542 n++;
19545 return n;
19548 // wuffs_private_impl__high_prec_dec__small_xshift shifts h's number (where 'x'
19549 // is 'l' or 'r' for left or right) by a small shift value.
19551 // Preconditions:
19552 // - h is non-NULL.
19553 // - h->decimal_point is "not extreme".
19554 // - shift is non-zero.
19555 // - shift is "a small shift".
19557 // "Not extreme" means within ±WUFFS_PRIVATE_IMPL__HPD__DECIMAL_POINT__RANGE.
19559 // "A small shift" means not more than
19560 // WUFFS_PRIVATE_IMPL__HPD__SHIFT__MAX_INCL.
19562 // wuffs_private_impl__high_prec_dec__rounded_integer and
19563 // wuffs_private_impl__high_prec_dec__lshift_num_new_digits have the same
19564 // preconditions.
19566 // wuffs_private_impl__high_prec_dec__lshift keeps the first two preconditions
19567 // but not the last two. Its shift argument is signed and does not need to be
19568 // "small": zero is a no-op, positive means left shift and negative means right
19569 // shift.
19571 static void //
19572 wuffs_private_impl__high_prec_dec__small_lshift(
19573 wuffs_private_impl__high_prec_dec* h,
19574 uint32_t shift) {
19575 if (h->num_digits == 0) {
19576 return;
19578 uint32_t num_new_digits =
19579 wuffs_private_impl__high_prec_dec__lshift_num_new_digits(h, shift);
19580 uint32_t rx = h->num_digits - 1; // Read index.
19581 uint32_t wx = h->num_digits - 1 + num_new_digits; // Write index.
19582 uint64_t n = 0;
19584 // Repeat: pick up a digit, put down a digit, right to left.
19585 while (((int32_t)rx) >= 0) {
19586 n += ((uint64_t)(h->digits[rx])) << shift;
19587 uint64_t quo = n / 10;
19588 uint64_t rem = n - (10 * quo);
19589 if (wx < WUFFS_PRIVATE_IMPL__HPD__DIGITS_PRECISION) {
19590 h->digits[wx] = (uint8_t)rem;
19591 } else if (rem > 0) {
19592 h->truncated = true;
19594 n = quo;
19595 wx--;
19596 rx--;
19599 // Put down leading digits, right to left.
19600 while (n > 0) {
19601 uint64_t quo = n / 10;
19602 uint64_t rem = n - (10 * quo);
19603 if (wx < WUFFS_PRIVATE_IMPL__HPD__DIGITS_PRECISION) {
19604 h->digits[wx] = (uint8_t)rem;
19605 } else if (rem > 0) {
19606 h->truncated = true;
19608 n = quo;
19609 wx--;
19612 // Finish.
19613 h->num_digits += num_new_digits;
19614 if (h->num_digits > WUFFS_PRIVATE_IMPL__HPD__DIGITS_PRECISION) {
19615 h->num_digits = WUFFS_PRIVATE_IMPL__HPD__DIGITS_PRECISION;
19617 h->decimal_point += (int32_t)num_new_digits;
19618 wuffs_private_impl__high_prec_dec__trim(h);
19621 static void //
19622 wuffs_private_impl__high_prec_dec__small_rshift(
19623 wuffs_private_impl__high_prec_dec* h,
19624 uint32_t shift) {
19625 uint32_t rx = 0; // Read index.
19626 uint32_t wx = 0; // Write index.
19627 uint64_t n = 0;
19629 // Pick up enough leading digits to cover the first shift.
19630 while ((n >> shift) == 0) {
19631 if (rx < h->num_digits) {
19632 // Read a digit.
19633 n = (10 * n) + h->digits[rx++];
19634 } else if (n == 0) {
19635 // h's number used to be zero and remains zero.
19636 return;
19637 } else {
19638 // Read sufficient implicit trailing zeroes.
19639 while ((n >> shift) == 0) {
19640 n = 10 * n;
19641 rx++;
19643 break;
19646 h->decimal_point -= ((int32_t)(rx - 1));
19647 if (h->decimal_point < -WUFFS_PRIVATE_IMPL__HPD__DECIMAL_POINT__RANGE) {
19648 // After the shift, h's number is effectively zero.
19649 h->num_digits = 0;
19650 h->decimal_point = 0;
19651 h->truncated = false;
19652 return;
19655 // Repeat: pick up a digit, put down a digit, left to right.
19656 uint64_t mask = (((uint64_t)(1)) << shift) - 1;
19657 while (rx < h->num_digits) {
19658 uint8_t new_digit = ((uint8_t)(n >> shift));
19659 n = (10 * (n & mask)) + h->digits[rx++];
19660 h->digits[wx++] = new_digit;
19663 // Put down trailing digits, left to right.
19664 while (n > 0) {
19665 uint8_t new_digit = ((uint8_t)(n >> shift));
19666 n = 10 * (n & mask);
19667 if (wx < WUFFS_PRIVATE_IMPL__HPD__DIGITS_PRECISION) {
19668 h->digits[wx++] = new_digit;
19669 } else if (new_digit > 0) {
19670 h->truncated = true;
19674 // Finish.
19675 h->num_digits = wx;
19676 wuffs_private_impl__high_prec_dec__trim(h);
19679 static void //
19680 wuffs_private_impl__high_prec_dec__lshift(wuffs_private_impl__high_prec_dec* h,
19681 int32_t shift) {
19682 if (shift > 0) {
19683 while (shift > +WUFFS_PRIVATE_IMPL__HPD__SHIFT__MAX_INCL) {
19684 wuffs_private_impl__high_prec_dec__small_lshift(
19685 h, WUFFS_PRIVATE_IMPL__HPD__SHIFT__MAX_INCL);
19686 shift -= WUFFS_PRIVATE_IMPL__HPD__SHIFT__MAX_INCL;
19688 wuffs_private_impl__high_prec_dec__small_lshift(h, ((uint32_t)(+shift)));
19689 } else if (shift < 0) {
19690 while (shift < -WUFFS_PRIVATE_IMPL__HPD__SHIFT__MAX_INCL) {
19691 wuffs_private_impl__high_prec_dec__small_rshift(
19692 h, WUFFS_PRIVATE_IMPL__HPD__SHIFT__MAX_INCL);
19693 shift += WUFFS_PRIVATE_IMPL__HPD__SHIFT__MAX_INCL;
19695 wuffs_private_impl__high_prec_dec__small_rshift(h, ((uint32_t)(-shift)));
19699 // --------
19701 // wuffs_private_impl__high_prec_dec__round_etc rounds h's number. For those
19702 // functions that take an n argument, rounding produces at most n digits (which
19703 // is not necessarily at most n decimal places). Negative n values are ignored,
19704 // as well as any n greater than or equal to h's number of digits. The
19705 // etc__round_just_enough function implicitly chooses an n to implement
19706 // WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION.
19708 // Preconditions:
19709 // - h is non-NULL.
19710 // - h->decimal_point is "not extreme".
19712 // "Not extreme" means within ±WUFFS_PRIVATE_IMPL__HPD__DECIMAL_POINT__RANGE.
19714 static void //
19715 wuffs_private_impl__high_prec_dec__round_down(
19716 wuffs_private_impl__high_prec_dec* h,
19717 int32_t n) {
19718 if ((n < 0) || (h->num_digits <= (uint32_t)n)) {
19719 return;
19721 h->num_digits = (uint32_t)(n);
19722 wuffs_private_impl__high_prec_dec__trim(h);
19725 static void //
19726 wuffs_private_impl__high_prec_dec__round_up(
19727 wuffs_private_impl__high_prec_dec* h,
19728 int32_t n) {
19729 if ((n < 0) || (h->num_digits <= (uint32_t)n)) {
19730 return;
19733 for (n--; n >= 0; n--) {
19734 if (h->digits[n] < 9) {
19735 h->digits[n]++;
19736 h->num_digits = (uint32_t)(n + 1);
19737 return;
19741 // The number is all 9s. Change to a single 1 and adjust the decimal point.
19742 h->digits[0] = 1;
19743 h->num_digits = 1;
19744 h->decimal_point++;
19747 static void //
19748 wuffs_private_impl__high_prec_dec__round_nearest(
19749 wuffs_private_impl__high_prec_dec* h,
19750 int32_t n) {
19751 if ((n < 0) || (h->num_digits <= (uint32_t)n)) {
19752 return;
19754 bool up = h->digits[n] >= 5;
19755 if ((h->digits[n] == 5) && ((n + 1) == ((int32_t)(h->num_digits)))) {
19756 up = h->truncated || //
19757 ((n > 0) && ((h->digits[n - 1] & 1) != 0));
19760 if (up) {
19761 wuffs_private_impl__high_prec_dec__round_up(h, n);
19762 } else {
19763 wuffs_private_impl__high_prec_dec__round_down(h, n);
19767 static void //
19768 wuffs_private_impl__high_prec_dec__round_just_enough(
19769 wuffs_private_impl__high_prec_dec* h,
19770 int32_t exp2,
19771 uint64_t mantissa) {
19772 // The magic numbers 52 and 53 in this function are because IEEE 754 double
19773 // precision has 52 mantissa bits.
19775 // Let f be the floating point number represented by exp2 and mantissa (and
19776 // also the number in h): the number (mantissa * (2 ** (exp2 - 52))).
19778 // If f is zero or a small integer, we can return early.
19779 if ((mantissa == 0) ||
19780 ((exp2 < 53) && (h->decimal_point >= ((int32_t)(h->num_digits))))) {
19781 return;
19784 // The smallest normal f has an exp2 of -1022 and a mantissa of (1 << 52).
19785 // Subnormal numbers have the same exp2 but a smaller mantissa.
19786 static const int32_t min_incl_normal_exp2 = -1022;
19787 static const uint64_t min_incl_normal_mantissa = 0x0010000000000000ul;
19789 // Compute lower and upper bounds such that any number between them (possibly
19790 // inclusive) will round to f. First, the lower bound. Our number f is:
19791 // ((mantissa + 0) * (2 ** ( exp2 - 52)))
19793 // The next lowest floating point number is:
19794 // ((mantissa - 1) * (2 ** ( exp2 - 52)))
19795 // unless (mantissa - 1) drops the (1 << 52) bit and exp2 is not the
19796 // min_incl_normal_exp2. Either way, call it:
19797 // ((l_mantissa) * (2 ** (l_exp2 - 52)))
19799 // The lower bound is halfway between them (noting that 52 became 53):
19800 // (((2 * l_mantissa) + 1) * (2 ** (l_exp2 - 53)))
19801 int32_t l_exp2 = exp2;
19802 uint64_t l_mantissa = mantissa - 1;
19803 if ((exp2 > min_incl_normal_exp2) && (mantissa <= min_incl_normal_mantissa)) {
19804 l_exp2 = exp2 - 1;
19805 l_mantissa = (2 * mantissa) - 1;
19807 wuffs_private_impl__high_prec_dec lower;
19808 wuffs_private_impl__high_prec_dec__assign(&lower, (2 * l_mantissa) + 1,
19809 false);
19810 wuffs_private_impl__high_prec_dec__lshift(&lower, l_exp2 - 53);
19812 // Next, the upper bound. Our number f is:
19813 // ((mantissa + 0) * (2 ** (exp2 - 52)))
19815 // The next highest floating point number is:
19816 // ((mantissa + 1) * (2 ** (exp2 - 52)))
19818 // The upper bound is halfway between them (noting that 52 became 53):
19819 // (((2 * mantissa) + 1) * (2 ** (exp2 - 53)))
19820 wuffs_private_impl__high_prec_dec upper;
19821 wuffs_private_impl__high_prec_dec__assign(&upper, (2 * mantissa) + 1, false);
19822 wuffs_private_impl__high_prec_dec__lshift(&upper, exp2 - 53);
19824 // The lower and upper bounds are possible outputs only if the original
19825 // mantissa is even, so that IEEE round-to-even would round to the original
19826 // mantissa and not its neighbors.
19827 bool inclusive = (mantissa & 1) == 0;
19829 // As we walk the digits, we want to know whether rounding up would fall
19830 // within the upper bound. This is tracked by upper_delta:
19831 // - When -1, the digits of h and upper are the same so far.
19832 // - When +0, we saw a difference of 1 between h and upper on a previous
19833 // digit and subsequently only 9s for h and 0s for upper. Thus, rounding
19834 // up may fall outside of the bound if !inclusive.
19835 // - When +1, the difference is greater than 1 and we know that rounding up
19836 // falls within the bound.
19838 // This is a state machine with three states. The numerical value for each
19839 // state (-1, +0 or +1) isn't important, other than their order.
19840 int upper_delta = -1;
19842 // We can now figure out the shortest number of digits required. Walk the
19843 // digits until h has distinguished itself from lower or upper.
19845 // The zi and zd variables are indexes and digits, for z in l (lower), h (the
19846 // number) and u (upper).
19848 // The lower, h and upper numbers may have their decimal points at different
19849 // places. In this case, upper is the longest, so we iterate ui starting from
19850 // 0 and iterate li and hi starting from either 0 or -1.
19851 int32_t ui = 0;
19852 for (;; ui++) {
19853 // Calculate hd, the middle number's digit.
19854 int32_t hi = ui - upper.decimal_point + h->decimal_point;
19855 if (hi >= ((int32_t)(h->num_digits))) {
19856 break;
19858 uint8_t hd = (((uint32_t)hi) < h->num_digits) ? h->digits[hi] : 0;
19860 // Calculate ld, the lower bound's digit.
19861 int32_t li = ui - upper.decimal_point + lower.decimal_point;
19862 uint8_t ld = (((uint32_t)li) < lower.num_digits) ? lower.digits[li] : 0;
19864 // We can round down (truncate) if lower has a different digit than h or if
19865 // lower is inclusive and is exactly the result of rounding down (i.e. we
19866 // have reached the final digit of lower).
19867 bool can_round_down =
19868 (ld != hd) || //
19869 (inclusive && ((li + 1) == ((int32_t)(lower.num_digits))));
19871 // Calculate ud, the upper bound's digit, and update upper_delta.
19872 uint8_t ud = (((uint32_t)ui) < upper.num_digits) ? upper.digits[ui] : 0;
19873 if (upper_delta < 0) {
19874 if ((hd + 1) < ud) {
19875 // For example:
19876 // h = 12345???
19877 // upper = 12347???
19878 upper_delta = +1;
19879 } else if (hd != ud) {
19880 // For example:
19881 // h = 12345???
19882 // upper = 12346???
19883 upper_delta = +0;
19885 } else if (upper_delta == 0) {
19886 if ((hd != 9) || (ud != 0)) {
19887 // For example:
19888 // h = 1234598?
19889 // upper = 1234600?
19890 upper_delta = +1;
19894 // We can round up if upper has a different digit than h and either upper
19895 // is inclusive or upper is bigger than the result of rounding up.
19896 bool can_round_up =
19897 (upper_delta > 0) || //
19898 ((upper_delta == 0) && //
19899 (inclusive || ((ui + 1) < ((int32_t)(upper.num_digits)))));
19901 // If we can round either way, round to nearest. If we can round only one
19902 // way, do it. If we can't round, continue the loop.
19903 if (can_round_down) {
19904 if (can_round_up) {
19905 wuffs_private_impl__high_prec_dec__round_nearest(h, hi + 1);
19906 return;
19907 } else {
19908 wuffs_private_impl__high_prec_dec__round_down(h, hi + 1);
19909 return;
19911 } else {
19912 if (can_round_up) {
19913 wuffs_private_impl__high_prec_dec__round_up(h, hi + 1);
19914 return;
19920 // --------
19922 // wuffs_private_impl__parse_number_f64_eisel_lemire produces the IEEE 754
19923 // double-precision value for an exact mantissa and base-10 exponent. For
19924 // example:
19925 // - when parsing "12345.678e+02", man is 12345678 and exp10 is -1.
19926 // - when parsing "-12", man is 12 and exp10 is 0. Processing the leading
19927 // minus sign is the responsibility of the caller, not this function.
19929 // On success, it returns a non-negative int64_t such that the low 63 bits hold
19930 // the 11-bit exponent and 52-bit mantissa.
19932 // On failure, it returns a negative value.
19934 // The algorithm is based on an original idea by Michael Eisel that was refined
19935 // by Daniel Lemire. See
19936 // https://lemire.me/blog/2020/03/10/fast-float-parsing-in-practice/
19937 // and
19938 // https://nigeltao.github.io/blog/2020/eisel-lemire.html
19940 // Preconditions:
19941 // - man is non-zero.
19942 // - exp10 is in the range [-307 ..= 288], the same range of the
19943 // wuffs_private_impl__powers_of_10 array.
19945 // The exp10 range (and the fact that man is in the range [1 ..= UINT64_MAX],
19946 // approximately [1 ..= 1.85e+19]) means that (man * (10 ** exp10)) is in the
19947 // range [1e-307 ..= 1.85e+307]. This is entirely within the range of normal
19948 // (neither subnormal nor non-finite) f64 values: DBL_MIN and DBL_MAX are
19949 // approximately 2.23e–308 and 1.80e+308.
19950 static int64_t //
19951 wuffs_private_impl__parse_number_f64_eisel_lemire(uint64_t man, int32_t exp10) {
19952 // Look up the (possibly truncated) base-2 representation of (10 ** exp10).
19953 // The look-up table was constructed so that it is already normalized: the
19954 // table entry's mantissa's MSB (most significant bit) is on.
19955 const uint64_t* po10 = &wuffs_private_impl__powers_of_10[exp10 + 307][0];
19957 // Normalize the man argument. The (man != 0) precondition means that a
19958 // non-zero bit exists.
19959 uint32_t clz = wuffs_base__count_leading_zeroes_u64(man);
19960 man <<= clz;
19962 // Calculate the return value's base-2 exponent. We might tweak it by ±1
19963 // later, but its initial value comes from a linear scaling of exp10,
19964 // converting from power-of-10 to power-of-2, and adjusting by clz.
19966 // The magic constants are:
19967 // - 1087 = 1023 + 64. The 1023 is the f64 exponent bias. The 64 is because
19968 // the look-up table uses 64-bit mantissas.
19969 // - 217706 is such that the ratio 217706 / 65536 ≈ 3.321930 is close enough
19970 // (over the practical range of exp10) to log(10) / log(2) ≈ 3.321928.
19971 // - 65536 = 1<<16 is arbitrary but a power of 2, so division is a shift.
19973 // Equality of the linearly-scaled value and the actual power-of-2, over the
19974 // range of exp10 arguments that this function accepts, is confirmed by
19975 // script/print-mpb-powers-of-10.go
19976 uint64_t ret_exp2 =
19977 ((uint64_t)(((217706 * exp10) >> 16) + 1087)) - ((uint64_t)clz);
19979 // Multiply the two mantissas. Normalization means that both mantissas are at
19980 // least (1<<63), so the 128-bit product must be at least (1<<126). The high
19981 // 64 bits of the product, x_hi, must therefore be at least (1<<62).
19983 // As a consequence, x_hi has either 0 or 1 leading zeroes. Shifting x_hi
19984 // right by either 9 or 10 bits (depending on x_hi's MSB) will therefore
19985 // leave the top 10 MSBs (bits 54 ..= 63) off and the 11th MSB (bit 53) on.
19986 wuffs_base__multiply_u64__output x = wuffs_base__multiply_u64(man, po10[1]);
19987 uint64_t x_hi = x.hi;
19988 uint64_t x_lo = x.lo;
19990 // Before we shift right by at least 9 bits, recall that the look-up table
19991 // entry was possibly truncated. We have so far only calculated a lower bound
19992 // for the product (man * e), where e is (10 ** exp10). The upper bound would
19993 // add a further (man * 1) to the 128-bit product, which overflows the lower
19994 // 64-bit limb if ((x_lo + man) < man).
19996 // If overflow occurs, that adds 1 to x_hi. Since we're about to shift right
19997 // by at least 9 bits, that carried 1 can be ignored unless the higher 64-bit
19998 // limb's low 9 bits are all on.
20000 // For example, parsing "9999999999999999999" will take the if-true branch
20001 // here, since:
20002 // - x_hi = 0x4563918244F3FFFF
20003 // - x_lo = 0x8000000000000000
20004 // - man = 0x8AC7230489E7FFFF
20005 if (((x_hi & 0x1FF) == 0x1FF) && ((x_lo + man) < man)) {
20006 // Refine our calculation of (man * e). Before, our approximation of e used
20007 // a "low resolution" 64-bit mantissa. Now use a "high resolution" 128-bit
20008 // mantissa. We've already calculated x = (man * bits_0_to_63_incl_of_e).
20009 // Now calculate y = (man * bits_64_to_127_incl_of_e).
20010 wuffs_base__multiply_u64__output y = wuffs_base__multiply_u64(man, po10[0]);
20011 uint64_t y_hi = y.hi;
20012 uint64_t y_lo = y.lo;
20014 // Merge the 128-bit x and 128-bit y, which overlap by 64 bits, to
20015 // calculate the 192-bit product of the 64-bit man by the 128-bit e.
20016 // As we exit this if-block, we only care about the high 128 bits
20017 // (merged_hi and merged_lo) of that 192-bit product.
20019 // For example, parsing "1.234e-45" will take the if-true branch here,
20020 // since:
20021 // - x_hi = 0x70B7E3696DB29FFF
20022 // - x_lo = 0xE040000000000000
20023 // - y_hi = 0x33718BBEAB0E0D7A
20024 // - y_lo = 0xA880000000000000
20025 uint64_t merged_hi = x_hi;
20026 uint64_t merged_lo = x_lo + y_hi;
20027 if (merged_lo < x_lo) {
20028 merged_hi++; // Carry the overflow bit.
20031 // The "high resolution" approximation of e is still a lower bound. Once
20032 // again, see if the upper bound is large enough to produce a different
20033 // result. This time, if it does, give up instead of reaching for an even
20034 // more precise approximation to e.
20036 // This three-part check is similar to the two-part check that guarded the
20037 // if block that we're now in, but it has an extra term for the middle 64
20038 // bits (checking that adding 1 to merged_lo would overflow).
20040 // For example, parsing "5.9604644775390625e-8" will take the if-true
20041 // branch here, since:
20042 // - merged_hi = 0x7FFFFFFFFFFFFFFF
20043 // - merged_lo = 0xFFFFFFFFFFFFFFFF
20044 // - y_lo = 0x4DB3FFC120988200
20045 // - man = 0xD3C21BCECCEDA100
20046 if (((merged_hi & 0x1FF) == 0x1FF) && ((merged_lo + 1) == 0) &&
20047 (y_lo + man < man)) {
20048 return -1;
20051 // Replace the 128-bit x with merged.
20052 x_hi = merged_hi;
20053 x_lo = merged_lo;
20056 // As mentioned above, shifting x_hi right by either 9 or 10 bits will leave
20057 // the top 10 MSBs (bits 54 ..= 63) off and the 11th MSB (bit 53) on. If the
20058 // MSB (before shifting) was on, adjust ret_exp2 for the larger shift.
20060 // Having bit 53 on (and higher bits off) means that ret_mantissa is a 54-bit
20061 // number.
20062 uint64_t msb = x_hi >> 63;
20063 uint64_t ret_mantissa = x_hi >> (msb + 9);
20064 ret_exp2 -= 1 ^ msb;
20066 // IEEE 754 rounds to-nearest with ties rounded to-even. Rounding to-even can
20067 // be tricky. If we're half-way between two exactly representable numbers
20068 // (x's low 73 bits are zero and the next 2 bits that matter are "01"), give
20069 // up instead of trying to pick the winner.
20071 // Technically, we could tighten the condition by changing "73" to "73 or 74,
20072 // depending on msb", but a flat "73" is simpler.
20074 // For example, parsing "1e+23" will take the if-true branch here, since:
20075 // - x_hi = 0x54B40B1F852BDA00
20076 // - ret_mantissa = 0x002A5A058FC295ED
20077 if ((x_lo == 0) && ((x_hi & 0x1FF) == 0) && ((ret_mantissa & 3) == 1)) {
20078 return -1;
20081 // If we're not halfway then it's rounding to-nearest. Starting with a 54-bit
20082 // number, carry the lowest bit (bit 0) up if it's on. Regardless of whether
20083 // it was on or off, shifting right by one then produces a 53-bit number. If
20084 // carrying up overflowed, shift again.
20085 ret_mantissa += ret_mantissa & 1;
20086 ret_mantissa >>= 1;
20087 // This if block is equivalent to (but benchmarks slightly faster than) the
20088 // following branchless form:
20089 // uint64_t overflow_adjustment = ret_mantissa >> 53;
20090 // ret_mantissa >>= overflow_adjustment;
20091 // ret_exp2 += overflow_adjustment;
20093 // For example, parsing "7.2057594037927933e+16" will take the if-true
20094 // branch here, since:
20095 // - x_hi = 0x7FFFFFFFFFFFFE80
20096 // - ret_mantissa = 0x0020000000000000
20097 if ((ret_mantissa >> 53) > 0) {
20098 ret_mantissa >>= 1;
20099 ret_exp2++;
20102 // Starting with a 53-bit number, IEEE 754 double-precision normal numbers
20103 // have an implicit mantissa bit. Mask that away and keep the low 52 bits.
20104 ret_mantissa &= 0x000FFFFFFFFFFFFF;
20106 // Pack the bits and return.
20107 return ((int64_t)(ret_mantissa | (ret_exp2 << 52)));
20110 // --------
20112 static wuffs_base__result_f64 //
20113 wuffs_private_impl__parse_number_f64_special(wuffs_base__slice_u8 s,
20114 uint32_t options) {
20115 do {
20116 if (options & WUFFS_BASE__PARSE_NUMBER_FXX__REJECT_INF_AND_NAN) {
20117 goto fail;
20120 uint8_t* p = s.ptr;
20121 uint8_t* q = s.ptr + s.len;
20123 for (; (p < q) && (*p == '_'); p++) {
20125 if (p >= q) {
20126 goto fail;
20129 // Parse sign.
20130 bool negative = false;
20131 do {
20132 if (*p == '+') {
20133 p++;
20134 } else if (*p == '-') {
20135 negative = true;
20136 p++;
20137 } else {
20138 break;
20140 for (; (p < q) && (*p == '_'); p++) {
20142 } while (0);
20143 if (p >= q) {
20144 goto fail;
20147 bool nan = false;
20148 switch (p[0]) {
20149 case 'I':
20150 case 'i':
20151 if (((q - p) < 3) || //
20152 ((p[1] != 'N') && (p[1] != 'n')) || //
20153 ((p[2] != 'F') && (p[2] != 'f'))) {
20154 goto fail;
20156 p += 3;
20158 if ((p >= q) || (*p == '_')) {
20159 break;
20160 } else if (((q - p) < 5) || //
20161 ((p[0] != 'I') && (p[0] != 'i')) || //
20162 ((p[1] != 'N') && (p[1] != 'n')) || //
20163 ((p[2] != 'I') && (p[2] != 'i')) || //
20164 ((p[3] != 'T') && (p[3] != 't')) || //
20165 ((p[4] != 'Y') && (p[4] != 'y'))) {
20166 goto fail;
20168 p += 5;
20170 if ((p >= q) || (*p == '_')) {
20171 break;
20173 goto fail;
20175 case 'N':
20176 case 'n':
20177 if (((q - p) < 3) || //
20178 ((p[1] != 'A') && (p[1] != 'a')) || //
20179 ((p[2] != 'N') && (p[2] != 'n'))) {
20180 goto fail;
20182 p += 3;
20184 if ((p >= q) || (*p == '_')) {
20185 nan = true;
20186 break;
20188 goto fail;
20190 default:
20191 goto fail;
20194 // Finish.
20195 for (; (p < q) && (*p == '_'); p++) {
20197 if (p != q) {
20198 goto fail;
20200 wuffs_base__result_f64 ret;
20201 ret.status.repr = NULL;
20202 ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
20203 (nan ? 0x7FFFFFFFFFFFFFFF : 0x7FF0000000000000) |
20204 (negative ? 0x8000000000000000 : 0));
20205 return ret;
20206 } while (0);
20208 fail:
20209 do {
20210 wuffs_base__result_f64 ret;
20211 ret.status.repr = wuffs_base__error__bad_argument;
20212 ret.value = 0;
20213 return ret;
20214 } while (0);
20217 WUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64 //
20218 wuffs_private_impl__high_prec_dec__to_f64(wuffs_private_impl__high_prec_dec* h,
20219 uint32_t options) {
20220 do {
20221 // powers converts decimal powers of 10 to binary powers of 2. For example,
20222 // (10000 >> 13) is 1. It stops before the elements exceed 60, also known
20223 // as WUFFS_PRIVATE_IMPL__HPD__SHIFT__MAX_INCL.
20225 // This rounds down (1<<13 is a lower bound for 1e4). Adding 1 to the array
20226 // element value rounds up (1<<14 is an upper bound for 1e4) while staying
20227 // at or below WUFFS_PRIVATE_IMPL__HPD__SHIFT__MAX_INCL.
20229 // When starting in the range [1e+1 .. 1e+2] (i.e. h->decimal_point == +2),
20230 // powers[2] == 6 and so:
20231 // - Right shifting by 6+0 produces the range [10/64 .. 100/64] =
20232 // [0.156250 .. 1.56250]. The resultant h->decimal_point is +0 or +1.
20233 // - Right shifting by 6+1 produces the range [10/128 .. 100/128] =
20234 // [0.078125 .. 0.78125]. The resultant h->decimal_point is -1 or -0.
20236 // When starting in the range [1e-3 .. 1e-2] (i.e. h->decimal_point == -2),
20237 // powers[2] == 6 and so:
20238 // - Left shifting by 6+0 produces the range [0.001*64 .. 0.01*64] =
20239 // [0.064 .. 0.64]. The resultant h->decimal_point is -1 or -0.
20240 // - Left shifting by 6+1 produces the range [0.001*128 .. 0.01*128] =
20241 // [0.128 .. 1.28]. The resultant h->decimal_point is +0 or +1.
20243 // Thus, when targeting h->decimal_point being +0 or +1, use (powers[n]+0)
20244 // when right shifting but (powers[n]+1) when left shifting.
20245 static const uint32_t num_powers = 19;
20246 static const uint8_t powers[19] = {
20247 0, 3, 6, 9, 13, 16, 19, 23, 26, 29, //
20248 33, 36, 39, 43, 46, 49, 53, 56, 59, //
20251 // Handle zero and obvious extremes. The largest and smallest positive
20252 // finite f64 values are approximately 1.8e+308 and 4.9e-324.
20253 if ((h->num_digits == 0) || (h->decimal_point < -326)) {
20254 goto zero;
20255 } else if (h->decimal_point > 310) {
20256 goto infinity;
20259 // Try the fast Eisel-Lemire algorithm again. Calculating the (man, exp10)
20260 // pair from the high_prec_dec h is more correct but slower than the
20261 // approach taken in wuffs_base__parse_number_f64. The latter is optimized
20262 // for the common cases (e.g. assuming no underscores or a leading '+'
20263 // sign) rather than the full set of cases allowed by the Wuffs API.
20265 // When we have 19 or fewer mantissa digits, run Eisel-Lemire once (trying
20266 // for an exact result). When we have more than 19 mantissa digits, run it
20267 // twice to get a lower and upper bound. We still have an exact result
20268 // (within f64's rounding margin) if both bounds are equal (and valid).
20269 uint32_t i_max = h->num_digits;
20270 if (i_max > 19) {
20271 i_max = 19;
20273 int32_t exp10 = h->decimal_point - ((int32_t)i_max);
20274 if ((-307 <= exp10) && (exp10 <= 288)) {
20275 uint64_t man = 0;
20276 uint32_t i;
20277 for (i = 0; i < i_max; i++) {
20278 man = (10 * man) + h->digits[i];
20280 while (man != 0) { // The 'while' is just an 'if' that we can 'break'.
20281 int64_t r0 =
20282 wuffs_private_impl__parse_number_f64_eisel_lemire(man + 0, exp10);
20283 if (r0 < 0) {
20284 break;
20285 } else if (h->num_digits > 19) {
20286 int64_t r1 =
20287 wuffs_private_impl__parse_number_f64_eisel_lemire(man + 1, exp10);
20288 if (r1 != r0) {
20289 break;
20292 wuffs_base__result_f64 ret;
20293 ret.status.repr = NULL;
20294 ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
20295 ((uint64_t)r0) | (((uint64_t)(h->negative)) << 63));
20296 return ret;
20300 // When Eisel-Lemire fails, fall back to Simple Decimal Conversion. See
20301 // https://nigeltao.github.io/blog/2020/parse-number-f64-simple.html
20303 // Scale by powers of 2 until we're in the range [0.1 .. 10]. Equivalently,
20304 // that h->decimal_point is +0 or +1.
20306 // First we shift right while at or above 10...
20307 const int32_t f64_bias = -1023;
20308 int32_t exp2 = 0;
20309 while (h->decimal_point > 1) {
20310 uint32_t n = (uint32_t)(+h->decimal_point);
20311 uint32_t shift = (n < num_powers)
20312 ? powers[n]
20313 : WUFFS_PRIVATE_IMPL__HPD__SHIFT__MAX_INCL;
20315 wuffs_private_impl__high_prec_dec__small_rshift(h, shift);
20316 if (h->decimal_point < -WUFFS_PRIVATE_IMPL__HPD__DECIMAL_POINT__RANGE) {
20317 goto zero;
20319 exp2 += (int32_t)shift;
20321 // ...then we shift left while below 0.1.
20322 while (h->decimal_point < 0) {
20323 uint32_t shift;
20324 uint32_t n = (uint32_t)(-h->decimal_point);
20325 shift = (n < num_powers)
20326 // The +1 is per "when targeting h->decimal_point being +0 or
20327 // +1... when left shifting" in the powers comment above.
20328 ? (powers[n] + 1u)
20329 : WUFFS_PRIVATE_IMPL__HPD__SHIFT__MAX_INCL;
20331 wuffs_private_impl__high_prec_dec__small_lshift(h, shift);
20332 if (h->decimal_point > +WUFFS_PRIVATE_IMPL__HPD__DECIMAL_POINT__RANGE) {
20333 goto infinity;
20335 exp2 -= (int32_t)shift;
20338 // To get from "in the range [0.1 .. 10]" to "in the range [1 .. 2]" (which
20339 // will give us our exponent in base-2), the mantissa's first 3 digits will
20340 // determine the final left shift, equal to 52 (the number of explicit f64
20341 // bits) plus an additional adjustment.
20342 int man3 = (100 * h->digits[0]) +
20343 ((h->num_digits > 1) ? (10 * h->digits[1]) : 0) +
20344 ((h->num_digits > 2) ? h->digits[2] : 0);
20345 int32_t additional_lshift = 0;
20346 if (h->decimal_point == 0) { // The value is in [0.1 .. 1].
20347 if (man3 < 125) {
20348 additional_lshift = +4;
20349 } else if (man3 < 250) {
20350 additional_lshift = +3;
20351 } else if (man3 < 500) {
20352 additional_lshift = +2;
20353 } else {
20354 additional_lshift = +1;
20356 } else { // The value is in [1 .. 10].
20357 if (man3 < 200) {
20358 additional_lshift = -0;
20359 } else if (man3 < 400) {
20360 additional_lshift = -1;
20361 } else if (man3 < 800) {
20362 additional_lshift = -2;
20363 } else {
20364 additional_lshift = -3;
20367 exp2 -= additional_lshift;
20368 uint32_t final_lshift = (uint32_t)(52 + additional_lshift);
20370 // The minimum normal exponent is (f64_bias + 1).
20371 while ((f64_bias + 1) > exp2) {
20372 uint32_t n = (uint32_t)((f64_bias + 1) - exp2);
20373 if (n > WUFFS_PRIVATE_IMPL__HPD__SHIFT__MAX_INCL) {
20374 n = WUFFS_PRIVATE_IMPL__HPD__SHIFT__MAX_INCL;
20376 wuffs_private_impl__high_prec_dec__small_rshift(h, n);
20377 exp2 += (int32_t)n;
20380 // Check for overflow.
20381 if ((exp2 - f64_bias) >= 0x07FF) { // (1 << 11) - 1.
20382 goto infinity;
20385 // Extract 53 bits for the mantissa (in base-2).
20386 wuffs_private_impl__high_prec_dec__small_lshift(h, final_lshift);
20387 uint64_t man2 = wuffs_private_impl__high_prec_dec__rounded_integer(h);
20389 // Rounding might have added one bit. If so, shift and re-check overflow.
20390 if ((man2 >> 53) != 0) {
20391 man2 >>= 1;
20392 exp2++;
20393 if ((exp2 - f64_bias) >= 0x07FF) { // (1 << 11) - 1.
20394 goto infinity;
20398 // Handle subnormal numbers.
20399 if ((man2 >> 52) == 0) {
20400 exp2 = f64_bias;
20403 // Pack the bits and return.
20404 uint64_t exp2_bits =
20405 (uint64_t)((exp2 - f64_bias) & 0x07FF); // (1 << 11) - 1.
20406 uint64_t bits = (man2 & 0x000FFFFFFFFFFFFF) | // (1 << 52) - 1.
20407 (exp2_bits << 52) | //
20408 (h->negative ? 0x8000000000000000 : 0); // (1 << 63).
20410 wuffs_base__result_f64 ret;
20411 ret.status.repr = NULL;
20412 ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(bits);
20413 return ret;
20414 } while (0);
20416 zero:
20417 do {
20418 uint64_t bits = h->negative ? 0x8000000000000000 : 0;
20420 wuffs_base__result_f64 ret;
20421 ret.status.repr = NULL;
20422 ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(bits);
20423 return ret;
20424 } while (0);
20426 infinity:
20427 do {
20428 if (options & WUFFS_BASE__PARSE_NUMBER_FXX__REJECT_INF_AND_NAN) {
20429 wuffs_base__result_f64 ret;
20430 ret.status.repr = wuffs_base__error__bad_argument;
20431 ret.value = 0;
20432 return ret;
20435 uint64_t bits = h->negative ? 0xFFF0000000000000 : 0x7FF0000000000000;
20437 wuffs_base__result_f64 ret;
20438 ret.status.repr = NULL;
20439 ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(bits);
20440 return ret;
20441 } while (0);
20444 static inline bool //
20445 wuffs_private_impl__is_decimal_digit(uint8_t c) {
20446 return ('0' <= c) && (c <= '9');
20449 WUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64 //
20450 wuffs_base__parse_number_f64(wuffs_base__slice_u8 s, uint32_t options) {
20451 // In practice, almost all "dd.ddddE±xxx" numbers can be represented
20452 // losslessly by a uint64_t mantissa "dddddd" and an int32_t base-10
20453 // exponent, adjusting "xxx" for the position (if present) of the decimal
20454 // separator '.' or ','.
20456 // This (u64 man, i32 exp10) data structure is superficially similar to the
20457 // "Do It Yourself Floating Point" type from Loitsch (†), but the exponent
20458 // here is base-10, not base-2.
20460 // If s's number fits in a (man, exp10), parse that pair with the
20461 // Eisel-Lemire algorithm. If not, or if Eisel-Lemire fails, parsing s with
20462 // the fallback algorithm is slower but comprehensive.
20464 // † "Printing Floating-Point Numbers Quickly and Accurately with Integers"
20465 // (https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf).
20466 // Florian Loitsch is also the primary contributor to
20467 // https://github.com/google/double-conversion
20468 do {
20469 // Calculating that (man, exp10) pair needs to stay within s's bounds.
20470 // Provided that s isn't extremely long, work on a NUL-terminated copy of
20471 // s's contents. The NUL byte isn't a valid part of "±dd.ddddE±xxx".
20473 // As the pointer p walks the contents, it's faster to repeatedly check "is
20474 // *p a valid digit" than "is p within bounds and *p a valid digit".
20475 if (s.len >= 256) {
20476 goto fallback;
20478 uint8_t z[256];
20479 memcpy(&z[0], s.ptr, s.len);
20480 z[s.len] = 0;
20481 const uint8_t* p = &z[0];
20483 // Look for a leading minus sign. Technically, we could also look for an
20484 // optional plus sign, but the "script/process-json-numbers.c with -p"
20485 // benchmark is noticably slower if we do. It's optional and, in practice,
20486 // usually absent. Let the fallback catch it.
20487 bool negative = (*p == '-');
20488 if (negative) {
20489 p++;
20492 // After walking "dd.dddd", comparing p later with p now will produce the
20493 // number of "d"s and "."s.
20494 const uint8_t* const start_of_digits_ptr = p;
20496 // Walk the "d"s before a '.', 'E', NUL byte, etc. If it starts with '0',
20497 // it must be a single '0'. If it starts with a non-zero decimal digit, it
20498 // can be a sequence of decimal digits.
20500 // Update the man variable during the walk. It's OK if man overflows now.
20501 // We'll detect that later.
20502 uint64_t man;
20503 if (*p == '0') {
20504 man = 0;
20505 p++;
20506 if (wuffs_private_impl__is_decimal_digit(*p)) {
20507 goto fallback;
20509 } else if (wuffs_private_impl__is_decimal_digit(*p)) {
20510 man = ((uint8_t)(*p - '0'));
20511 p++;
20512 for (; wuffs_private_impl__is_decimal_digit(*p); p++) {
20513 man = (10 * man) + ((uint8_t)(*p - '0'));
20515 } else {
20516 goto fallback;
20519 // Walk the "d"s after the optional decimal separator ('.' or ','),
20520 // updating the man and exp10 variables.
20521 int32_t exp10 = 0;
20522 if (*p ==
20523 ((options & WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)
20524 ? ','
20525 : '.')) {
20526 p++;
20527 const uint8_t* first_after_separator_ptr = p;
20528 if (!wuffs_private_impl__is_decimal_digit(*p)) {
20529 goto fallback;
20531 man = (10 * man) + ((uint8_t)(*p - '0'));
20532 p++;
20533 for (; wuffs_private_impl__is_decimal_digit(*p); p++) {
20534 man = (10 * man) + ((uint8_t)(*p - '0'));
20536 exp10 = ((int32_t)(first_after_separator_ptr - p));
20539 // Count the number of digits:
20540 // - for an input of "314159", digit_count is 6.
20541 // - for an input of "3.14159", digit_count is 7.
20543 // This is off-by-one if there is a decimal separator. That's OK for now.
20544 // We'll correct for that later. The "script/process-json-numbers.c with
20545 // -p" benchmark is noticably slower if we try to correct for that now.
20546 uint32_t digit_count = (uint32_t)(p - start_of_digits_ptr);
20548 // Update exp10 for the optional exponent, starting with 'E' or 'e'.
20549 if ((*p | 0x20) == 'e') {
20550 p++;
20551 int32_t exp_sign = +1;
20552 if (*p == '-') {
20553 p++;
20554 exp_sign = -1;
20555 } else if (*p == '+') {
20556 p++;
20558 if (!wuffs_private_impl__is_decimal_digit(*p)) {
20559 goto fallback;
20561 int32_t exp_num = ((uint8_t)(*p - '0'));
20562 p++;
20563 // The rest of the exp_num walking has a peculiar control flow but, once
20564 // again, the "script/process-json-numbers.c with -p" benchmark is
20565 // sensitive to alternative formulations.
20566 if (wuffs_private_impl__is_decimal_digit(*p)) {
20567 exp_num = (10 * exp_num) + ((uint8_t)(*p - '0'));
20568 p++;
20570 if (wuffs_private_impl__is_decimal_digit(*p)) {
20571 exp_num = (10 * exp_num) + ((uint8_t)(*p - '0'));
20572 p++;
20574 while (wuffs_private_impl__is_decimal_digit(*p)) {
20575 if (exp_num > 0x1000000) {
20576 goto fallback;
20578 exp_num = (10 * exp_num) + ((uint8_t)(*p - '0'));
20579 p++;
20581 exp10 += exp_sign * exp_num;
20584 // The Wuffs API is that the original slice has no trailing data. It also
20585 // allows underscores, which we don't catch here but the fallback should.
20586 if (p != &z[s.len]) {
20587 goto fallback;
20590 // Check that the uint64_t typed man variable has not overflowed, based on
20591 // digit_count.
20593 // For reference:
20594 // - (1 << 63) is 9223372036854775808, which has 19 decimal digits.
20595 // - (1 << 64) is 18446744073709551616, which has 20 decimal digits.
20596 // - 19 nines, 9999999999999999999, is 0x8AC7230489E7FFFF, which has 64
20597 // bits and 16 hexadecimal digits.
20598 // - 20 nines, 99999999999999999999, is 0x56BC75E2D630FFFFF, which has 67
20599 // bits and 17 hexadecimal digits.
20600 if (digit_count > 19) {
20601 // Even if we have more than 19 pseudo-digits, it's not yet definitely an
20602 // overflow. Recall that digit_count might be off-by-one (too large) if
20603 // there's a decimal separator. It will also over-report the number of
20604 // meaningful digits if the input looks something like "0.000dddExxx".
20606 // We adjust by the number of leading '0's and '.'s and re-compare to 19.
20607 // Once again, technically, we could skip ','s too, but that perturbs the
20608 // "script/process-json-numbers.c with -p" benchmark.
20609 const uint8_t* q = start_of_digits_ptr;
20610 for (; (*q == '0') || (*q == '.'); q++) {
20612 digit_count -= (uint32_t)(q - start_of_digits_ptr);
20613 if (digit_count > 19) {
20614 goto fallback;
20618 // The wuffs_private_impl__parse_number_f64_eisel_lemire preconditions
20619 // include that exp10 is in the range [-307 ..= 288].
20620 if ((exp10 < -307) || (288 < exp10)) {
20621 goto fallback;
20624 // If both man and (10 ** exp10) are exactly representable by a double, we
20625 // don't need to run the Eisel-Lemire algorithm.
20626 if ((-22 <= exp10) && (exp10 <= 22) && ((man >> 53) == 0)) {
20627 double d = (double)man;
20628 if (exp10 >= 0) {
20629 d *= wuffs_private_impl__f64_powers_of_10[+exp10];
20630 } else {
20631 d /= wuffs_private_impl__f64_powers_of_10[-exp10];
20633 wuffs_base__result_f64 ret;
20634 ret.status.repr = NULL;
20635 ret.value = negative ? -d : +d;
20636 return ret;
20639 // The wuffs_private_impl__parse_number_f64_eisel_lemire preconditions
20640 // include that man is non-zero. Parsing "0" should be caught by the "If
20641 // both man and (10 ** exp10)" above, but "0e99" might not.
20642 if (man == 0) {
20643 goto fallback;
20646 // Our man and exp10 are in range. Run the Eisel-Lemire algorithm.
20647 int64_t r = wuffs_private_impl__parse_number_f64_eisel_lemire(man, exp10);
20648 if (r < 0) {
20649 goto fallback;
20651 wuffs_base__result_f64 ret;
20652 ret.status.repr = NULL;
20653 ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
20654 ((uint64_t)r) | (((uint64_t)negative) << 63));
20655 return ret;
20656 } while (0);
20658 fallback:
20659 do {
20660 wuffs_private_impl__high_prec_dec h;
20661 wuffs_base__status status =
20662 wuffs_private_impl__high_prec_dec__parse(&h, s, options);
20663 if (status.repr) {
20664 return wuffs_private_impl__parse_number_f64_special(s, options);
20666 return wuffs_private_impl__high_prec_dec__to_f64(&h, options);
20667 } while (0);
20670 // --------
20672 static inline size_t //
20673 wuffs_private_impl__render_inf(wuffs_base__slice_u8 dst,
20674 bool neg,
20675 uint32_t options) {
20676 if (neg) {
20677 if (dst.len < 4) {
20678 return 0;
20680 wuffs_base__poke_u32le__no_bounds_check(dst.ptr, 0x666E492D); // '-Inf'le.
20681 return 4;
20684 if (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN) {
20685 if (dst.len < 4) {
20686 return 0;
20688 wuffs_base__poke_u32le__no_bounds_check(dst.ptr, 0x666E492B); // '+Inf'le.
20689 return 4;
20692 if (dst.len < 3) {
20693 return 0;
20695 wuffs_base__poke_u24le__no_bounds_check(dst.ptr, 0x666E49); // 'Inf'le.
20696 return 3;
20699 static inline size_t //
20700 wuffs_private_impl__render_nan(wuffs_base__slice_u8 dst) {
20701 if (dst.len < 3) {
20702 return 0;
20704 wuffs_base__poke_u24le__no_bounds_check(dst.ptr, 0x4E614E); // 'NaN'le.
20705 return 3;
20708 static size_t //
20709 wuffs_private_impl__high_prec_dec__render_exponent_absent(
20710 wuffs_base__slice_u8 dst,
20711 wuffs_private_impl__high_prec_dec* h,
20712 uint32_t precision,
20713 uint32_t options) {
20714 size_t n = (h->negative ||
20715 (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN))
20717 : 0;
20718 if (h->decimal_point <= 0) {
20719 n += 1;
20720 } else {
20721 n += (size_t)(h->decimal_point);
20723 if (precision > 0) {
20724 n += precision + 1; // +1 for the '.'.
20727 // Don't modify dst if the formatted number won't fit.
20728 if (n > dst.len) {
20729 return 0;
20732 // Align-left or align-right.
20733 uint8_t* ptr = (options & WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT)
20734 ? &dst.ptr[dst.len - n]
20735 : &dst.ptr[0];
20737 // Leading "±".
20738 if (h->negative) {
20739 *ptr++ = '-';
20740 } else if (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN) {
20741 *ptr++ = '+';
20744 // Integral digits.
20745 if (h->decimal_point <= 0) {
20746 *ptr++ = '0';
20747 } else {
20748 uint32_t m =
20749 wuffs_base__u32__min(h->num_digits, (uint32_t)(h->decimal_point));
20750 uint32_t i = 0;
20751 for (; i < m; i++) {
20752 *ptr++ = (uint8_t)('0' | h->digits[i]);
20754 for (; i < (uint32_t)(h->decimal_point); i++) {
20755 *ptr++ = '0';
20759 // Separator and then fractional digits.
20760 if (precision > 0) {
20761 *ptr++ =
20762 (options & WUFFS_BASE__RENDER_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)
20763 ? ','
20764 : '.';
20765 uint32_t i = 0;
20766 for (; i < precision; i++) {
20767 uint32_t j = ((uint32_t)(h->decimal_point)) + i;
20768 *ptr++ = (uint8_t)('0' | ((j < h->num_digits) ? h->digits[j] : 0));
20772 return n;
20775 static size_t //
20776 wuffs_private_impl__high_prec_dec__render_exponent_present(
20777 wuffs_base__slice_u8 dst,
20778 wuffs_private_impl__high_prec_dec* h,
20779 uint32_t precision,
20780 uint32_t options) {
20781 int32_t exp = 0;
20782 if (h->num_digits > 0) {
20783 exp = h->decimal_point - 1;
20785 bool negative_exp = exp < 0;
20786 if (negative_exp) {
20787 exp = -exp;
20790 size_t n = (h->negative ||
20791 (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN))
20793 : 3; // Mininum 3 bytes: first digit and then "e±".
20794 if (precision > 0) {
20795 n += precision + 1; // +1 for the '.'.
20797 n += (exp < 100) ? 2 : 3;
20799 // Don't modify dst if the formatted number won't fit.
20800 if (n > dst.len) {
20801 return 0;
20804 // Align-left or align-right.
20805 uint8_t* ptr = (options & WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT)
20806 ? &dst.ptr[dst.len - n]
20807 : &dst.ptr[0];
20809 // Leading "±".
20810 if (h->negative) {
20811 *ptr++ = '-';
20812 } else if (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN) {
20813 *ptr++ = '+';
20816 // Integral digit.
20817 if (h->num_digits > 0) {
20818 *ptr++ = (uint8_t)('0' | h->digits[0]);
20819 } else {
20820 *ptr++ = '0';
20823 // Separator and then fractional digits.
20824 if (precision > 0) {
20825 *ptr++ =
20826 (options & WUFFS_BASE__RENDER_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)
20827 ? ','
20828 : '.';
20829 uint32_t i = 1;
20830 uint32_t j = wuffs_base__u32__min(h->num_digits, precision + 1);
20831 for (; i < j; i++) {
20832 *ptr++ = (uint8_t)('0' | h->digits[i]);
20834 for (; i <= precision; i++) {
20835 *ptr++ = '0';
20839 // Exponent: "e±" and then 2 or 3 digits.
20840 *ptr++ = 'e';
20841 *ptr++ = negative_exp ? '-' : '+';
20842 if (exp < 10) {
20843 *ptr++ = '0';
20844 *ptr++ = (uint8_t)('0' | exp);
20845 } else if (exp < 100) {
20846 *ptr++ = (uint8_t)('0' | (exp / 10));
20847 *ptr++ = (uint8_t)('0' | (exp % 10));
20848 } else {
20849 int32_t e = exp / 100;
20850 exp -= e * 100;
20851 *ptr++ = (uint8_t)('0' | e);
20852 *ptr++ = (uint8_t)('0' | (exp / 10));
20853 *ptr++ = (uint8_t)('0' | (exp % 10));
20856 return n;
20859 WUFFS_BASE__MAYBE_STATIC size_t //
20860 wuffs_base__render_number_f64(wuffs_base__slice_u8 dst,
20861 double x,
20862 uint32_t precision,
20863 uint32_t options) {
20864 // Decompose x (64 bits) into negativity (1 bit), base-2 exponent (11 bits
20865 // with a -1023 bias) and mantissa (52 bits).
20866 uint64_t bits = wuffs_base__ieee_754_bit_representation__from_f64_to_u64(x);
20867 bool neg = (bits >> 63) != 0;
20868 int32_t exp2 = ((int32_t)(bits >> 52)) & 0x7FF;
20869 uint64_t man = bits & 0x000FFFFFFFFFFFFFul;
20871 // Apply the exponent bias and set the implicit top bit of the mantissa,
20872 // unless x is subnormal. Also take care of Inf and NaN.
20873 if (exp2 == 0x7FF) {
20874 if (man != 0) {
20875 return wuffs_private_impl__render_nan(dst);
20877 return wuffs_private_impl__render_inf(dst, neg, options);
20878 } else if (exp2 == 0) {
20879 exp2 = -1022;
20880 } else {
20881 exp2 -= 1023;
20882 man |= 0x0010000000000000ul;
20885 // Ensure that precision isn't too large.
20886 if (precision > 4095) {
20887 precision = 4095;
20890 // Convert from the (neg, exp2, man) tuple to an HPD.
20891 wuffs_private_impl__high_prec_dec h;
20892 wuffs_private_impl__high_prec_dec__assign(&h, man, neg);
20893 if (h.num_digits > 0) {
20894 wuffs_private_impl__high_prec_dec__lshift(&h,
20895 exp2 - 52); // 52 mantissa bits.
20898 // Handle the "%e" and "%f" formats.
20899 switch (options & (WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_ABSENT |
20900 WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_PRESENT)) {
20901 case WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_ABSENT: // The "%"f" format.
20902 if (options & WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION) {
20903 wuffs_private_impl__high_prec_dec__round_just_enough(&h, exp2, man);
20904 int32_t p = ((int32_t)(h.num_digits)) - h.decimal_point;
20905 precision = ((uint32_t)(wuffs_base__i32__max(0, p)));
20906 } else {
20907 wuffs_private_impl__high_prec_dec__round_nearest(
20908 &h, ((int32_t)precision) + h.decimal_point);
20910 return wuffs_private_impl__high_prec_dec__render_exponent_absent(
20911 dst, &h, precision, options);
20913 case WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_PRESENT: // The "%e" format.
20914 if (options & WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION) {
20915 wuffs_private_impl__high_prec_dec__round_just_enough(&h, exp2, man);
20916 precision = (h.num_digits > 0) ? (h.num_digits - 1) : 0;
20917 } else {
20918 wuffs_private_impl__high_prec_dec__round_nearest(
20919 &h, ((int32_t)precision) + 1);
20921 return wuffs_private_impl__high_prec_dec__render_exponent_present(
20922 dst, &h, precision, options);
20925 // We have the "%g" format and so precision means the number of significant
20926 // digits, not the number of digits after the decimal separator. Perform
20927 // rounding and determine whether to use "%e" or "%f".
20928 int32_t e_threshold = 0;
20929 if (options & WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION) {
20930 wuffs_private_impl__high_prec_dec__round_just_enough(&h, exp2, man);
20931 precision = h.num_digits;
20932 e_threshold = 6;
20933 } else {
20934 if (precision == 0) {
20935 precision = 1;
20937 wuffs_private_impl__high_prec_dec__round_nearest(&h, ((int32_t)precision));
20938 e_threshold = ((int32_t)precision);
20939 int32_t nd = ((int32_t)(h.num_digits));
20940 if ((e_threshold > nd) && (nd >= h.decimal_point)) {
20941 e_threshold = nd;
20945 // Use the "%e" format if the exponent is large.
20946 int32_t e = h.decimal_point - 1;
20947 if ((e < -4) || (e_threshold <= e)) {
20948 uint32_t p = wuffs_base__u32__min(precision, h.num_digits);
20949 return wuffs_private_impl__high_prec_dec__render_exponent_present(
20950 dst, &h, (p > 0) ? (p - 1) : 0, options);
20953 // Use the "%f" format otherwise.
20954 int32_t p = ((int32_t)precision);
20955 if (p > h.decimal_point) {
20956 p = ((int32_t)(h.num_digits));
20958 precision = ((uint32_t)(wuffs_base__i32__max(0, p - h.decimal_point)));
20959 return wuffs_private_impl__high_prec_dec__render_exponent_absent(
20960 dst, &h, precision, options);
20963 #endif // !defined(WUFFS_CONFIG__MODULES) ||
20964 // defined(WUFFS_CONFIG__MODULE__BASE) ||
20965 // defined(WUFFS_CONFIG__MODULE__BASE__FLOATCONV)
20967 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
20968 defined(WUFFS_CONFIG__MODULE__BASE__INTCONV)
20970 // ---------------- Integer
20972 // wuffs_base__parse_number__foo_digits entries are 0x00 for invalid digits,
20973 // and (0x80 | v) for valid digits, where v is the 4 bit value.
20975 static const uint8_t wuffs_base__parse_number__decimal_digits[256] = {
20976 // 0 1 2 3 4 5 6 7
20977 // 8 9 A B C D E F
20978 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00 ..= 0x07.
20979 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x08 ..= 0x0F.
20980 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x10 ..= 0x17.
20981 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x18 ..= 0x1F.
20982 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x20 ..= 0x27.
20983 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x28 ..= 0x2F.
20984 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, // 0x30 ..= 0x37. '0'-'7'.
20985 0x88, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x38 ..= 0x3F. '8'-'9'.
20987 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x40 ..= 0x47.
20988 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x48 ..= 0x4F.
20989 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50 ..= 0x57.
20990 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x58 ..= 0x5F.
20991 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x60 ..= 0x67.
20992 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x68 ..= 0x6F.
20993 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x70 ..= 0x77.
20994 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x78 ..= 0x7F.
20996 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x80 ..= 0x87.
20997 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x88 ..= 0x8F.
20998 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x90 ..= 0x97.
20999 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x98 ..= 0x9F.
21000 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xA0 ..= 0xA7.
21001 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xA8 ..= 0xAF.
21002 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xB0 ..= 0xB7.
21003 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xB8 ..= 0xBF.
21005 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xC0 ..= 0xC7.
21006 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xC8 ..= 0xCF.
21007 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xD0 ..= 0xD7.
21008 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xD8 ..= 0xDF.
21009 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xE0 ..= 0xE7.
21010 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xE8 ..= 0xEF.
21011 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xF0 ..= 0xF7.
21012 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xF8 ..= 0xFF.
21013 // 0 1 2 3 4 5 6 7
21014 // 8 9 A B C D E F
21017 static const uint8_t wuffs_base__parse_number__hexadecimal_digits[256] = {
21018 // 0 1 2 3 4 5 6 7
21019 // 8 9 A B C D E F
21020 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00 ..= 0x07.
21021 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x08 ..= 0x0F.
21022 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x10 ..= 0x17.
21023 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x18 ..= 0x1F.
21024 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x20 ..= 0x27.
21025 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x28 ..= 0x2F.
21026 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, // 0x30 ..= 0x37. '0'-'7'.
21027 0x88, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x38 ..= 0x3F. '8'-'9'.
21029 0x00, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x00, // 0x40 ..= 0x47. 'A'-'F'.
21030 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x48 ..= 0x4F.
21031 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50 ..= 0x57.
21032 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x58 ..= 0x5F.
21033 0x00, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x00, // 0x60 ..= 0x67. 'a'-'f'.
21034 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x68 ..= 0x6F.
21035 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x70 ..= 0x77.
21036 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x78 ..= 0x7F.
21038 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x80 ..= 0x87.
21039 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x88 ..= 0x8F.
21040 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x90 ..= 0x97.
21041 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x98 ..= 0x9F.
21042 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xA0 ..= 0xA7.
21043 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xA8 ..= 0xAF.
21044 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xB0 ..= 0xB7.
21045 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xB8 ..= 0xBF.
21047 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xC0 ..= 0xC7.
21048 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xC8 ..= 0xCF.
21049 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xD0 ..= 0xD7.
21050 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xD8 ..= 0xDF.
21051 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xE0 ..= 0xE7.
21052 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xE8 ..= 0xEF.
21053 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xF0 ..= 0xF7.
21054 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xF8 ..= 0xFF.
21055 // 0 1 2 3 4 5 6 7
21056 // 8 9 A B C D E F
21059 static const uint8_t wuffs_private_impl__encode_base16[16] = {
21060 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, // 0x00 ..= 0x07.
21061 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, // 0x08 ..= 0x0F.
21064 // --------
21066 WUFFS_BASE__MAYBE_STATIC wuffs_base__result_i64 //
21067 wuffs_base__parse_number_i64(wuffs_base__slice_u8 s, uint32_t options) {
21068 uint8_t* p = s.ptr;
21069 uint8_t* q = s.ptr + s.len;
21071 if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
21072 for (; (p < q) && (*p == '_'); p++) {
21076 bool negative = false;
21077 if (p >= q) {
21078 goto fail_bad_argument;
21079 } else if (*p == '-') {
21080 p++;
21081 negative = true;
21082 } else if (*p == '+') {
21083 p++;
21086 do {
21087 wuffs_base__result_u64 r = wuffs_base__parse_number_u64(
21088 wuffs_base__make_slice_u8(p, (size_t)(q - p)), options);
21089 if (r.status.repr != NULL) {
21090 wuffs_base__result_i64 ret;
21091 ret.status.repr = r.status.repr;
21092 ret.value = 0;
21093 return ret;
21094 } else if (negative) {
21095 if (r.value < 0x8000000000000000) {
21096 wuffs_base__result_i64 ret;
21097 ret.status.repr = NULL;
21098 ret.value = -(int64_t)(r.value);
21099 return ret;
21100 } else if (r.value == 0x8000000000000000) {
21101 wuffs_base__result_i64 ret;
21102 ret.status.repr = NULL;
21103 ret.value = INT64_MIN;
21104 return ret;
21106 goto fail_out_of_bounds;
21107 } else if (r.value > 0x7FFFFFFFFFFFFFFF) {
21108 goto fail_out_of_bounds;
21109 } else {
21110 wuffs_base__result_i64 ret;
21111 ret.status.repr = NULL;
21112 ret.value = +(int64_t)(r.value);
21113 return ret;
21115 } while (0);
21117 fail_bad_argument:
21118 do {
21119 wuffs_base__result_i64 ret;
21120 ret.status.repr = wuffs_base__error__bad_argument;
21121 ret.value = 0;
21122 return ret;
21123 } while (0);
21125 fail_out_of_bounds:
21126 do {
21127 wuffs_base__result_i64 ret;
21128 ret.status.repr = wuffs_base__error__out_of_bounds;
21129 ret.value = 0;
21130 return ret;
21131 } while (0);
21134 WUFFS_BASE__MAYBE_STATIC wuffs_base__result_u64 //
21135 wuffs_base__parse_number_u64(wuffs_base__slice_u8 s, uint32_t options) {
21136 uint8_t* p = s.ptr;
21137 uint8_t* q = s.ptr + s.len;
21139 if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
21140 for (; (p < q) && (*p == '_'); p++) {
21144 if (p >= q) {
21145 goto fail_bad_argument;
21147 } else if (*p == '0') {
21148 p++;
21149 if (p >= q) {
21150 goto ok_zero;
21152 if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
21153 if (*p == '_') {
21154 p++;
21155 for (; p < q; p++) {
21156 if (*p != '_') {
21157 if (options &
21158 WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_MULTIPLE_LEADING_ZEROES) {
21159 goto decimal;
21161 goto fail_bad_argument;
21164 goto ok_zero;
21168 if ((*p == 'x') || (*p == 'X')) {
21169 p++;
21170 if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
21171 for (; (p < q) && (*p == '_'); p++) {
21174 if (p < q) {
21175 goto hexadecimal;
21178 } else if ((*p == 'd') || (*p == 'D')) {
21179 p++;
21180 if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
21181 for (; (p < q) && (*p == '_'); p++) {
21184 if (p < q) {
21185 goto decimal;
21189 if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_MULTIPLE_LEADING_ZEROES) {
21190 goto decimal;
21192 goto fail_bad_argument;
21195 decimal:
21196 do {
21197 uint64_t v = wuffs_base__parse_number__decimal_digits[*p++];
21198 if (v == 0) {
21199 goto fail_bad_argument;
21201 v &= 0x0F;
21203 // UINT64_MAX is 18446744073709551615, which is ((10 * max10) + max1).
21204 const uint64_t max10 = 1844674407370955161u;
21205 const uint8_t max1 = 5;
21207 for (; p < q; p++) {
21208 if ((*p == '_') &&
21209 (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) {
21210 continue;
21212 uint8_t digit = wuffs_base__parse_number__decimal_digits[*p];
21213 if (digit == 0) {
21214 goto fail_bad_argument;
21216 digit &= 0x0F;
21217 if ((v > max10) || ((v == max10) && (digit > max1))) {
21218 goto fail_out_of_bounds;
21220 v = (10 * v) + ((uint64_t)(digit));
21223 wuffs_base__result_u64 ret;
21224 ret.status.repr = NULL;
21225 ret.value = v;
21226 return ret;
21227 } while (0);
21229 hexadecimal:
21230 do {
21231 uint64_t v = wuffs_base__parse_number__hexadecimal_digits[*p++];
21232 if (v == 0) {
21233 goto fail_bad_argument;
21235 v &= 0x0F;
21237 for (; p < q; p++) {
21238 if ((*p == '_') &&
21239 (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) {
21240 continue;
21242 uint8_t digit = wuffs_base__parse_number__hexadecimal_digits[*p];
21243 if (digit == 0) {
21244 goto fail_bad_argument;
21246 digit &= 0x0F;
21247 if ((v >> 60) != 0) {
21248 goto fail_out_of_bounds;
21250 v = (v << 4) | ((uint64_t)(digit));
21253 wuffs_base__result_u64 ret;
21254 ret.status.repr = NULL;
21255 ret.value = v;
21256 return ret;
21257 } while (0);
21259 ok_zero:
21260 do {
21261 wuffs_base__result_u64 ret;
21262 ret.status.repr = NULL;
21263 ret.value = 0;
21264 return ret;
21265 } while (0);
21267 fail_bad_argument:
21268 do {
21269 wuffs_base__result_u64 ret;
21270 ret.status.repr = wuffs_base__error__bad_argument;
21271 ret.value = 0;
21272 return ret;
21273 } while (0);
21275 fail_out_of_bounds:
21276 do {
21277 wuffs_base__result_u64 ret;
21278 ret.status.repr = wuffs_base__error__out_of_bounds;
21279 ret.value = 0;
21280 return ret;
21281 } while (0);
21284 // --------
21286 // wuffs_base__render_number__first_hundred contains the decimal encodings of
21287 // the first one hundred numbers [0 ..= 99].
21288 static const uint8_t wuffs_base__render_number__first_hundred[200] = {
21289 '0', '0', '0', '1', '0', '2', '0', '3', '0', '4', //
21290 '0', '5', '0', '6', '0', '7', '0', '8', '0', '9', //
21291 '1', '0', '1', '1', '1', '2', '1', '3', '1', '4', //
21292 '1', '5', '1', '6', '1', '7', '1', '8', '1', '9', //
21293 '2', '0', '2', '1', '2', '2', '2', '3', '2', '4', //
21294 '2', '5', '2', '6', '2', '7', '2', '8', '2', '9', //
21295 '3', '0', '3', '1', '3', '2', '3', '3', '3', '4', //
21296 '3', '5', '3', '6', '3', '7', '3', '8', '3', '9', //
21297 '4', '0', '4', '1', '4', '2', '4', '3', '4', '4', //
21298 '4', '5', '4', '6', '4', '7', '4', '8', '4', '9', //
21299 '5', '0', '5', '1', '5', '2', '5', '3', '5', '4', //
21300 '5', '5', '5', '6', '5', '7', '5', '8', '5', '9', //
21301 '6', '0', '6', '1', '6', '2', '6', '3', '6', '4', //
21302 '6', '5', '6', '6', '6', '7', '6', '8', '6', '9', //
21303 '7', '0', '7', '1', '7', '2', '7', '3', '7', '4', //
21304 '7', '5', '7', '6', '7', '7', '7', '8', '7', '9', //
21305 '8', '0', '8', '1', '8', '2', '8', '3', '8', '4', //
21306 '8', '5', '8', '6', '8', '7', '8', '8', '8', '9', //
21307 '9', '0', '9', '1', '9', '2', '9', '3', '9', '4', //
21308 '9', '5', '9', '6', '9', '7', '9', '8', '9', '9', //
21311 static size_t //
21312 wuffs_private_impl__render_number_u64(wuffs_base__slice_u8 dst,
21313 uint64_t x,
21314 uint32_t options,
21315 bool neg) {
21316 uint8_t buf[WUFFS_BASE__U64__BYTE_LENGTH__MAX_INCL];
21317 uint8_t* ptr = &buf[0] + sizeof(buf);
21319 while (x >= 100) {
21320 size_t index = ((size_t)((x % 100) * 2));
21321 x /= 100;
21322 uint8_t s0 = wuffs_base__render_number__first_hundred[index + 0];
21323 uint8_t s1 = wuffs_base__render_number__first_hundred[index + 1];
21324 ptr -= 2;
21325 ptr[0] = s0;
21326 ptr[1] = s1;
21329 if (x < 10) {
21330 ptr -= 1;
21331 ptr[0] = (uint8_t)('0' + x);
21332 } else {
21333 size_t index = ((size_t)(x * 2));
21334 uint8_t s0 = wuffs_base__render_number__first_hundred[index + 0];
21335 uint8_t s1 = wuffs_base__render_number__first_hundred[index + 1];
21336 ptr -= 2;
21337 ptr[0] = s0;
21338 ptr[1] = s1;
21341 if (neg) {
21342 ptr -= 1;
21343 ptr[0] = '-';
21344 } else if (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN) {
21345 ptr -= 1;
21346 ptr[0] = '+';
21349 size_t n = sizeof(buf) - ((size_t)(ptr - &buf[0]));
21350 if (n > dst.len) {
21351 return 0;
21353 memcpy(dst.ptr + ((options & WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT)
21354 ? (dst.len - n)
21355 : 0),
21356 ptr, n);
21357 return n;
21360 WUFFS_BASE__MAYBE_STATIC size_t //
21361 wuffs_base__render_number_i64(wuffs_base__slice_u8 dst,
21362 int64_t x,
21363 uint32_t options) {
21364 uint64_t u = (uint64_t)x;
21365 bool neg = x < 0;
21366 if (neg) {
21367 u = 1 + ~u;
21369 return wuffs_private_impl__render_number_u64(dst, u, options, neg);
21372 WUFFS_BASE__MAYBE_STATIC size_t //
21373 wuffs_base__render_number_u64(wuffs_base__slice_u8 dst,
21374 uint64_t x,
21375 uint32_t options) {
21376 return wuffs_private_impl__render_number_u64(dst, x, options, false);
21379 // ---------------- Base-16
21381 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output //
21382 wuffs_base__base_16__decode2(wuffs_base__slice_u8 dst,
21383 wuffs_base__slice_u8 src,
21384 bool src_closed,
21385 uint32_t options) {
21386 wuffs_base__transform__output o;
21387 size_t src_len2 = src.len / 2;
21388 size_t len;
21389 if (dst.len < src_len2) {
21390 len = dst.len;
21391 o.status.repr = wuffs_base__suspension__short_write;
21392 } else {
21393 len = src_len2;
21394 if (!src_closed) {
21395 o.status.repr = wuffs_base__suspension__short_read;
21396 } else if (src.len & 1) {
21397 o.status.repr = wuffs_base__error__bad_data;
21398 } else {
21399 o.status.repr = NULL;
21403 uint8_t* d = dst.ptr;
21404 uint8_t* s = src.ptr;
21405 size_t n = len;
21407 while (n--) {
21408 *d = (uint8_t)((wuffs_base__parse_number__hexadecimal_digits[s[0]] << 4) |
21409 (wuffs_base__parse_number__hexadecimal_digits[s[1]] & 0x0F));
21410 d += 1;
21411 s += 2;
21414 o.num_dst = len;
21415 o.num_src = len * 2;
21416 return o;
21419 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output //
21420 wuffs_base__base_16__decode4(wuffs_base__slice_u8 dst,
21421 wuffs_base__slice_u8 src,
21422 bool src_closed,
21423 uint32_t options) {
21424 wuffs_base__transform__output o;
21425 size_t src_len4 = src.len / 4;
21426 size_t len = dst.len < src_len4 ? dst.len : src_len4;
21427 if (dst.len < src_len4) {
21428 len = dst.len;
21429 o.status.repr = wuffs_base__suspension__short_write;
21430 } else {
21431 len = src_len4;
21432 if (!src_closed) {
21433 o.status.repr = wuffs_base__suspension__short_read;
21434 } else if (src.len & 1) {
21435 o.status.repr = wuffs_base__error__bad_data;
21436 } else {
21437 o.status.repr = NULL;
21441 uint8_t* d = dst.ptr;
21442 uint8_t* s = src.ptr;
21443 size_t n = len;
21445 while (n--) {
21446 *d = (uint8_t)((wuffs_base__parse_number__hexadecimal_digits[s[2]] << 4) |
21447 (wuffs_base__parse_number__hexadecimal_digits[s[3]] & 0x0F));
21448 d += 1;
21449 s += 4;
21452 o.num_dst = len;
21453 o.num_src = len * 4;
21454 return o;
21457 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output //
21458 wuffs_base__base_16__encode2(wuffs_base__slice_u8 dst,
21459 wuffs_base__slice_u8 src,
21460 bool src_closed,
21461 uint32_t options) {
21462 wuffs_base__transform__output o;
21463 size_t dst_len2 = dst.len / 2;
21464 size_t len;
21465 if (dst_len2 < src.len) {
21466 len = dst_len2;
21467 o.status.repr = wuffs_base__suspension__short_write;
21468 } else {
21469 len = src.len;
21470 if (!src_closed) {
21471 o.status.repr = wuffs_base__suspension__short_read;
21472 } else {
21473 o.status.repr = NULL;
21477 uint8_t* d = dst.ptr;
21478 uint8_t* s = src.ptr;
21479 size_t n = len;
21481 while (n--) {
21482 uint8_t c = *s;
21483 d[0] = wuffs_private_impl__encode_base16[c >> 4];
21484 d[1] = wuffs_private_impl__encode_base16[c & 0x0F];
21485 d += 2;
21486 s += 1;
21489 o.num_dst = len * 2;
21490 o.num_src = len;
21491 return o;
21494 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output //
21495 wuffs_base__base_16__encode4(wuffs_base__slice_u8 dst,
21496 wuffs_base__slice_u8 src,
21497 bool src_closed,
21498 uint32_t options) {
21499 wuffs_base__transform__output o;
21500 size_t dst_len4 = dst.len / 4;
21501 size_t len;
21502 if (dst_len4 < src.len) {
21503 len = dst_len4;
21504 o.status.repr = wuffs_base__suspension__short_write;
21505 } else {
21506 len = src.len;
21507 if (!src_closed) {
21508 o.status.repr = wuffs_base__suspension__short_read;
21509 } else {
21510 o.status.repr = NULL;
21514 uint8_t* d = dst.ptr;
21515 uint8_t* s = src.ptr;
21516 size_t n = len;
21518 while (n--) {
21519 uint8_t c = *s;
21520 d[0] = '\\';
21521 d[1] = 'x';
21522 d[2] = wuffs_private_impl__encode_base16[c >> 4];
21523 d[3] = wuffs_private_impl__encode_base16[c & 0x0F];
21524 d += 4;
21525 s += 1;
21528 o.num_dst = len * 4;
21529 o.num_src = len;
21530 return o;
21533 // ---------------- Base-64
21535 // The two base-64 alphabets, std and url, differ only in the last two codes.
21536 // - std: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
21537 // - url: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
21539 static const uint8_t wuffs_base__base_64__decode_std[256] = {
21540 // 0 1 2 3 4 5 6 7
21541 // 8 9 A B C D E F
21542 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x00 ..= 0x07.
21543 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x08 ..= 0x0F.
21544 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x10 ..= 0x17.
21545 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x18 ..= 0x1F.
21546 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x20 ..= 0x27.
21547 0x80, 0x80, 0x80, 0x3E, 0x80, 0x80, 0x80, 0x3F, // 0x28 ..= 0x2F.
21548 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, // 0x30 ..= 0x37.
21549 0x3C, 0x3D, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x38 ..= 0x3F.
21551 0x80, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // 0x40 ..= 0x47.
21552 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, // 0x48 ..= 0x4F.
21553 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, // 0x50 ..= 0x57.
21554 0x17, 0x18, 0x19, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x58 ..= 0x5F.
21555 0x80, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, // 0x60 ..= 0x67.
21556 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, // 0x68 ..= 0x6F.
21557 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, // 0x70 ..= 0x77.
21558 0x31, 0x32, 0x33, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x78 ..= 0x7F.
21560 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x80 ..= 0x87.
21561 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x88 ..= 0x8F.
21562 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x90 ..= 0x97.
21563 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x98 ..= 0x9F.
21564 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xA0 ..= 0xA7.
21565 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xA8 ..= 0xAF.
21566 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xB0 ..= 0xB7.
21567 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xB8 ..= 0xBF.
21569 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xC0 ..= 0xC7.
21570 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xC8 ..= 0xCF.
21571 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xD0 ..= 0xD7.
21572 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xD8 ..= 0xDF.
21573 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xE0 ..= 0xE7.
21574 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xE8 ..= 0xEF.
21575 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xF0 ..= 0xF7.
21576 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xF8 ..= 0xFF.
21577 // 0 1 2 3 4 5 6 7
21578 // 8 9 A B C D E F
21581 static const uint8_t wuffs_base__base_64__decode_url[256] = {
21582 // 0 1 2 3 4 5 6 7
21583 // 8 9 A B C D E F
21584 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x00 ..= 0x07.
21585 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x08 ..= 0x0F.
21586 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x10 ..= 0x17.
21587 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x18 ..= 0x1F.
21588 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x20 ..= 0x27.
21589 0x80, 0x80, 0x80, 0x80, 0x80, 0x3E, 0x80, 0x80, // 0x28 ..= 0x2F.
21590 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, // 0x30 ..= 0x37.
21591 0x3C, 0x3D, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x38 ..= 0x3F.
21593 0x80, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // 0x40 ..= 0x47.
21594 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, // 0x48 ..= 0x4F.
21595 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, // 0x50 ..= 0x57.
21596 0x17, 0x18, 0x19, 0x80, 0x80, 0x80, 0x80, 0x3F, // 0x58 ..= 0x5F.
21597 0x80, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, // 0x60 ..= 0x67.
21598 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, // 0x68 ..= 0x6F.
21599 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, // 0x70 ..= 0x77.
21600 0x31, 0x32, 0x33, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x78 ..= 0x7F.
21602 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x80 ..= 0x87.
21603 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x88 ..= 0x8F.
21604 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x90 ..= 0x97.
21605 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x98 ..= 0x9F.
21606 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xA0 ..= 0xA7.
21607 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xA8 ..= 0xAF.
21608 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xB0 ..= 0xB7.
21609 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xB8 ..= 0xBF.
21611 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xC0 ..= 0xC7.
21612 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xC8 ..= 0xCF.
21613 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xD0 ..= 0xD7.
21614 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xD8 ..= 0xDF.
21615 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xE0 ..= 0xE7.
21616 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xE8 ..= 0xEF.
21617 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xF0 ..= 0xF7.
21618 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xF8 ..= 0xFF.
21619 // 0 1 2 3 4 5 6 7
21620 // 8 9 A B C D E F
21623 static const uint8_t wuffs_base__base_64__encode_std[64] = {
21624 // 0 1 2 3 4 5 6 7
21625 // 8 9 A B C D E F
21626 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, // 0x00 ..= 0x07.
21627 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, // 0x08 ..= 0x0F.
21628 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, // 0x10 ..= 0x17.
21629 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, // 0x18 ..= 0x1F.
21630 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, // 0x20 ..= 0x27.
21631 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, // 0x28 ..= 0x2F.
21632 0x77, 0x78, 0x79, 0x7A, 0x30, 0x31, 0x32, 0x33, // 0x30 ..= 0x37.
21633 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2B, 0x2F, // 0x38 ..= 0x3F.
21636 static const uint8_t wuffs_base__base_64__encode_url[64] = {
21637 // 0 1 2 3 4 5 6 7
21638 // 8 9 A B C D E F
21639 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, // 0x00 ..= 0x07.
21640 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, // 0x08 ..= 0x0F.
21641 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, // 0x10 ..= 0x17.
21642 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, // 0x18 ..= 0x1F.
21643 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, // 0x20 ..= 0x27.
21644 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, // 0x28 ..= 0x2F.
21645 0x77, 0x78, 0x79, 0x7A, 0x30, 0x31, 0x32, 0x33, // 0x30 ..= 0x37.
21646 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2D, 0x5F, // 0x38 ..= 0x3F.
21649 // --------
21651 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output //
21652 wuffs_base__base_64__decode(wuffs_base__slice_u8 dst,
21653 wuffs_base__slice_u8 src,
21654 bool src_closed,
21655 uint32_t options) {
21656 const uint8_t* alphabet = (options & WUFFS_BASE__BASE_64__URL_ALPHABET)
21657 ? wuffs_base__base_64__decode_url
21658 : wuffs_base__base_64__decode_std;
21659 wuffs_base__transform__output o;
21660 uint8_t* d_ptr = dst.ptr;
21661 size_t d_len = dst.len;
21662 const uint8_t* s_ptr = src.ptr;
21663 size_t s_len = src.len;
21664 bool pad = false;
21666 while (s_len >= 4) {
21667 uint32_t s = wuffs_base__peek_u32le__no_bounds_check(s_ptr);
21668 uint32_t s0 = alphabet[0xFF & (s >> 0)];
21669 uint32_t s1 = alphabet[0xFF & (s >> 8)];
21670 uint32_t s2 = alphabet[0xFF & (s >> 16)];
21671 uint32_t s3 = alphabet[0xFF & (s >> 24)];
21673 if (((s0 | s1 | s2 | s3) & 0xC0) != 0) {
21674 if (s_len > 4) {
21675 o.status.repr = wuffs_base__error__bad_data;
21676 goto done;
21677 } else if (!src_closed) {
21678 o.status.repr = wuffs_base__suspension__short_read;
21679 goto done;
21680 } else if ((options & WUFFS_BASE__BASE_64__DECODE_ALLOW_PADDING) &&
21681 (s_ptr[3] == '=')) {
21682 pad = true;
21683 if (s_ptr[2] == '=') {
21684 goto src2;
21686 goto src3;
21688 o.status.repr = wuffs_base__error__bad_data;
21689 goto done;
21692 if (d_len < 3) {
21693 o.status.repr = wuffs_base__suspension__short_write;
21694 goto done;
21697 s_ptr += 4;
21698 s_len -= 4;
21699 s = (s0 << 18) | (s1 << 12) | (s2 << 6) | (s3 << 0);
21700 *d_ptr++ = (uint8_t)(s >> 16);
21701 *d_ptr++ = (uint8_t)(s >> 8);
21702 *d_ptr++ = (uint8_t)(s >> 0);
21703 d_len -= 3;
21706 if (!src_closed) {
21707 o.status.repr = wuffs_base__suspension__short_read;
21708 goto done;
21711 if (s_len == 0) {
21712 o.status.repr = NULL;
21713 goto done;
21714 } else if (s_len == 1) {
21715 o.status.repr = wuffs_base__error__bad_data;
21716 goto done;
21717 } else if (s_len == 2) {
21718 goto src2;
21721 src3:
21722 do {
21723 uint32_t s = wuffs_base__peek_u24le__no_bounds_check(s_ptr);
21724 uint32_t s0 = alphabet[0xFF & (s >> 0)];
21725 uint32_t s1 = alphabet[0xFF & (s >> 8)];
21726 uint32_t s2 = alphabet[0xFF & (s >> 16)];
21727 if ((s0 & 0xC0) || (s1 & 0xC0) || (s2 & 0xC3)) {
21728 o.status.repr = wuffs_base__error__bad_data;
21729 goto done;
21731 if (d_len < 2) {
21732 o.status.repr = wuffs_base__suspension__short_write;
21733 goto done;
21735 s_ptr += pad ? 4 : 3;
21736 s = (s0 << 18) | (s1 << 12) | (s2 << 6);
21737 *d_ptr++ = (uint8_t)(s >> 16);
21738 *d_ptr++ = (uint8_t)(s >> 8);
21739 o.status.repr = NULL;
21740 goto done;
21741 } while (0);
21743 src2:
21744 do {
21745 uint32_t s = wuffs_base__peek_u16le__no_bounds_check(s_ptr);
21746 uint32_t s0 = alphabet[0xFF & (s >> 0)];
21747 uint32_t s1 = alphabet[0xFF & (s >> 8)];
21748 if ((s0 & 0xC0) || (s1 & 0xCF)) {
21749 o.status.repr = wuffs_base__error__bad_data;
21750 goto done;
21752 if (d_len < 1) {
21753 o.status.repr = wuffs_base__suspension__short_write;
21754 goto done;
21756 s_ptr += pad ? 4 : 2;
21757 s = (s0 << 18) | (s1 << 12);
21758 *d_ptr++ = (uint8_t)(s >> 16);
21759 o.status.repr = NULL;
21760 goto done;
21761 } while (0);
21763 done:
21764 o.num_dst = (size_t)(d_ptr - dst.ptr);
21765 o.num_src = (size_t)(s_ptr - src.ptr);
21766 return o;
21769 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output //
21770 wuffs_base__base_64__encode(wuffs_base__slice_u8 dst,
21771 wuffs_base__slice_u8 src,
21772 bool src_closed,
21773 uint32_t options) {
21774 const uint8_t* alphabet = (options & WUFFS_BASE__BASE_64__URL_ALPHABET)
21775 ? wuffs_base__base_64__encode_url
21776 : wuffs_base__base_64__encode_std;
21777 wuffs_base__transform__output o;
21778 uint8_t* d_ptr = dst.ptr;
21779 size_t d_len = dst.len;
21780 const uint8_t* s_ptr = src.ptr;
21781 size_t s_len = src.len;
21783 do {
21784 while (s_len >= 3) {
21785 if (d_len < 4) {
21786 o.status.repr = wuffs_base__suspension__short_write;
21787 goto done;
21789 uint32_t s = wuffs_base__peek_u24be__no_bounds_check(s_ptr);
21790 s_ptr += 3;
21791 s_len -= 3;
21792 *d_ptr++ = alphabet[0x3F & (s >> 18)];
21793 *d_ptr++ = alphabet[0x3F & (s >> 12)];
21794 *d_ptr++ = alphabet[0x3F & (s >> 6)];
21795 *d_ptr++ = alphabet[0x3F & (s >> 0)];
21796 d_len -= 4;
21799 if (!src_closed) {
21800 o.status.repr = wuffs_base__suspension__short_read;
21801 goto done;
21804 if (s_len == 2) {
21805 if (d_len <
21806 ((options & WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING) ? 4 : 3)) {
21807 o.status.repr = wuffs_base__suspension__short_write;
21808 goto done;
21810 uint32_t s = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(s_ptr)))
21811 << 8;
21812 s_ptr += 2;
21813 *d_ptr++ = alphabet[0x3F & (s >> 18)];
21814 *d_ptr++ = alphabet[0x3F & (s >> 12)];
21815 *d_ptr++ = alphabet[0x3F & (s >> 6)];
21816 if (options & WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING) {
21817 *d_ptr++ = '=';
21819 o.status.repr = NULL;
21820 goto done;
21822 } else if (s_len == 1) {
21823 if (d_len <
21824 ((options & WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING) ? 4 : 2)) {
21825 o.status.repr = wuffs_base__suspension__short_write;
21826 goto done;
21828 uint32_t s = ((uint32_t)(wuffs_base__peek_u8__no_bounds_check(s_ptr)))
21829 << 16;
21830 s_ptr += 1;
21831 *d_ptr++ = alphabet[0x3F & (s >> 18)];
21832 *d_ptr++ = alphabet[0x3F & (s >> 12)];
21833 if (options & WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING) {
21834 *d_ptr++ = '=';
21835 *d_ptr++ = '=';
21837 o.status.repr = NULL;
21838 goto done;
21840 } else {
21841 o.status.repr = NULL;
21842 goto done;
21844 } while (0);
21846 done:
21847 o.num_dst = (size_t)(d_ptr - dst.ptr);
21848 o.num_src = (size_t)(s_ptr - src.ptr);
21849 return o;
21852 #endif // !defined(WUFFS_CONFIG__MODULES) ||
21853 // defined(WUFFS_CONFIG__MODULE__BASE) ||
21854 // defined(WUFFS_CONFIG__MODULE__BASE__INTCONV)
21856 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
21857 defined(WUFFS_CONFIG__MODULE__BASE__MAGIC)
21859 // ---------------- Magic Numbers
21861 // ICO doesn't start with a magic identifier. Instead, see if the opening bytes
21862 // are plausibly ICO.
21864 // Callers should have already verified that (prefix_data.len >= 2) and the
21865 // first two bytes are 0x00.
21867 // See:
21868 // - https://docs.fileformat.com/image/ico/
21869 static int32_t //
21870 wuffs_base__magic_number_guess_fourcc__maybe_ico(
21871 wuffs_base__slice_u8 prefix_data,
21872 bool prefix_closed) {
21873 // Allow-list for the Image Type field.
21874 if (prefix_data.len < 4) {
21875 return prefix_closed ? 0 : -1;
21876 } else if (prefix_data.ptr[3] != 0) {
21877 return 0;
21879 switch (prefix_data.ptr[2]) {
21880 case 0x01: // ICO
21881 case 0x02: // CUR
21882 break;
21883 default:
21884 return 0;
21887 // The Number Of Images should be positive.
21888 if (prefix_data.len < 6) {
21889 return prefix_closed ? 0 : -1;
21890 } else if ((prefix_data.ptr[4] == 0) && (prefix_data.ptr[5] == 0)) {
21891 return 0;
21894 // The first ICONDIRENTRY's fourth byte should be zero.
21895 if (prefix_data.len < 10) {
21896 return prefix_closed ? 0 : -1;
21897 } else if (prefix_data.ptr[9] != 0) {
21898 return 0;
21901 // TODO: have a separate FourCC for CUR?
21902 return 0x49434F20; // 'ICO 'be
21905 // TGA doesn't start with a magic identifier. Instead, see if the opening bytes
21906 // are plausibly TGA.
21908 // Callers should have already verified that (prefix_data.len >= 2) and the
21909 // second byte (prefix_data.ptr[1], the Color Map Type byte), is either 0x00 or
21910 // 0x01.
21912 // See:
21913 // - https://docs.fileformat.com/image/tga/
21914 // - https://www.dca.fee.unicamp.br/~martino/disciplinas/ea978/tgaffs.pdf
21915 static int32_t //
21916 wuffs_base__magic_number_guess_fourcc__maybe_tga(
21917 wuffs_base__slice_u8 prefix_data,
21918 bool prefix_closed) {
21919 // Allow-list for the Image Type field.
21920 if (prefix_data.len < 3) {
21921 return prefix_closed ? 0 : -1;
21923 switch (prefix_data.ptr[2]) {
21924 case 0x01:
21925 case 0x02:
21926 case 0x03:
21927 case 0x09:
21928 case 0x0A:
21929 case 0x0B:
21930 break;
21931 default:
21932 // TODO: 0x20 and 0x21 are invalid, according to the spec, but are
21933 // apparently unofficial extensions.
21934 return 0;
21937 // Allow-list for the Color Map Entry Size field (if the Color Map Type field
21938 // is non-zero) or else all the Color Map fields should be zero.
21939 if (prefix_data.len < 8) {
21940 return prefix_closed ? 0 : -1;
21941 } else if (prefix_data.ptr[1] != 0x00) {
21942 switch (prefix_data.ptr[7]) {
21943 case 0x0F:
21944 case 0x10:
21945 case 0x18:
21946 case 0x20:
21947 break;
21948 default:
21949 return 0;
21951 } else if ((prefix_data.ptr[3] | prefix_data.ptr[4] | prefix_data.ptr[5] |
21952 prefix_data.ptr[6] | prefix_data.ptr[7]) != 0x00) {
21953 return 0;
21956 // Allow-list for the Pixel Depth field.
21957 if (prefix_data.len < 17) {
21958 return prefix_closed ? 0 : -1;
21960 switch (prefix_data.ptr[16]) {
21961 case 0x01:
21962 case 0x08:
21963 case 0x0F:
21964 case 0x10:
21965 case 0x18:
21966 case 0x20:
21967 break;
21968 default:
21969 return 0;
21972 return 0x54474120; // 'TGA 'be
21975 WUFFS_BASE__MAYBE_STATIC int32_t //
21976 wuffs_base__magic_number_guess_fourcc(wuffs_base__slice_u8 prefix_data,
21977 bool prefix_closed) {
21978 // This is similar to (but different from):
21979 // - the magic/Magdir tables under https://github.com/file/file
21980 // - the MIME Sniffing algorithm at https://mimesniff.spec.whatwg.org/
21982 // table holds the 'magic numbers' (which are actually variable length
21983 // strings). The strings may contain NUL bytes, so the "const char* magic"
21984 // value starts with the length-minus-1 of the 'magic number'.
21986 // Keep it sorted by magic[1], then magic[0] descending (prioritizing longer
21987 // matches) and finally by magic[2:]. When multiple entries match, the
21988 // longest one wins.
21990 // The fourcc field might be negated, in which case there's further
21991 // specialization (see § below).
21992 static struct {
21993 int32_t fourcc;
21994 const char* magic;
21995 } table[] = {
21996 {-0x30302020, "\x01\x00\x00"}, // '00 'be
21997 {+0x475A2020, "\x02\x1F\x8B\x08"}, // GZ
21998 {+0x5A535444, "\x03\x28\xB5\x2F\xFD"}, // ZSTD
21999 {+0x425A3220, "\x02\x42\x5A\x68"}, // BZ2
22000 {+0x424D5020, "\x01\x42\x4D"}, // BMP
22001 {+0x47494620, "\x03\x47\x49\x46\x38"}, // GIF
22002 {+0x54494646, "\x03\x49\x49\x2A\x00"}, // TIFF (little-endian)
22003 {+0x4C5A4950, "\x04\x4C\x5A\x49\x50\x01"}, // LZIP
22004 {+0x54494646, "\x03\x4D\x4D\x00\x2A"}, // TIFF (big-endian)
22005 {+0x4E50424D, "\x02\x50\x35\x0A"}, // NPBM (P5; *.pgm)
22006 {+0x4E50424D, "\x02\x50\x36\x0A"}, // NPBM (P6; *.ppm)
22007 {-0x52494646, "\x03\x52\x49\x46\x46"}, // RIFF
22008 {+0x4C5A4D41, "\x04\x5D\x00\x10\x00\x00"}, // LZMA
22009 {+0x4C5A4D41, "\x02\x5D\x00\x00"}, // LZMA
22010 {+0x4E494520, "\x02\x6E\xC3\xAF"}, // NIE
22011 {+0x514F4920, "\x03\x71\x6F\x69\x66"}, // QOI
22012 {+0x5A4C4942, "\x01\x78\x9C"}, // ZLIB
22013 {+0x504E4720, "\x03\x89\x50\x4E\x47"}, // PNG
22014 {+0x585A2020, "\x04\xFD\x37\x7A\x58\x5A"}, // XZ
22015 {+0x4A504547, "\x01\xFF\xD8"}, // JPEG
22017 static const size_t table_len = sizeof(table) / sizeof(table[0]);
22019 if (prefix_data.len == 0) {
22020 return prefix_closed ? 0 : -1;
22022 uint8_t pre_first_byte = prefix_data.ptr[0];
22024 int32_t fourcc = 0;
22025 size_t i;
22026 for (i = 0; i < table_len; i++) {
22027 uint8_t mag_first_byte = ((uint8_t)(table[i].magic[1]));
22028 if (pre_first_byte < mag_first_byte) {
22029 break;
22030 } else if (pre_first_byte > mag_first_byte) {
22031 continue;
22033 fourcc = table[i].fourcc;
22035 uint8_t mag_remaining_len = ((uint8_t)(table[i].magic[0]));
22036 if (mag_remaining_len == 0) {
22037 goto match;
22040 const char* mag_remaining_ptr = table[i].magic + 2;
22041 uint8_t* pre_remaining_ptr = prefix_data.ptr + 1;
22042 size_t pre_remaining_len = prefix_data.len - 1;
22043 if (pre_remaining_len < mag_remaining_len) {
22044 if (!memcmp(pre_remaining_ptr, mag_remaining_ptr, pre_remaining_len)) {
22045 return prefix_closed ? 0 : -1;
22047 } else {
22048 if (!memcmp(pre_remaining_ptr, mag_remaining_ptr, mag_remaining_len)) {
22049 goto match;
22054 if (prefix_data.len < 2) {
22055 return prefix_closed ? 0 : -1;
22056 } else if ((prefix_data.ptr[1] == 0x00) || (prefix_data.ptr[1] == 0x01)) {
22057 return wuffs_base__magic_number_guess_fourcc__maybe_tga(prefix_data,
22058 prefix_closed);
22061 return 0;
22063 match:
22064 // Negative FourCC values (see § above) are further specialized.
22065 if (fourcc < 0) {
22066 fourcc = -fourcc;
22068 if (fourcc == 0x52494646) { // 'RIFF'be
22069 if (prefix_data.len < 12) {
22070 return prefix_closed ? 0 : -1;
22072 uint32_t x = wuffs_base__peek_u32be__no_bounds_check(prefix_data.ptr + 8);
22073 if (x == 0x57454250) { // 'WEBP'be
22074 return 0x57454250; // 'WEBP'be
22077 } else if (fourcc == 0x30302020) { // '00 'be
22078 // Binary data starting with multiple 0x00 NUL bytes is quite common.
22079 // Unfortunately, some file formats also don't start with a magic
22080 // identifier, so we have to use heuristics (where the order matters, the
22081 // same as /usr/bin/file's magic/Magdir tables) as best we can. Maybe
22082 // it's TGA, ICO/CUR, etc. Maybe it's something else.
22083 int32_t tga = wuffs_base__magic_number_guess_fourcc__maybe_tga(
22084 prefix_data, prefix_closed);
22085 if (tga != 0) {
22086 return tga;
22088 int32_t ico = wuffs_base__magic_number_guess_fourcc__maybe_ico(
22089 prefix_data, prefix_closed);
22090 if (ico != 0) {
22091 return ico;
22093 if (prefix_data.len < 4) {
22094 return prefix_closed ? 0 : -1;
22095 } else if ((prefix_data.ptr[2] != 0x00) &&
22096 ((prefix_data.ptr[2] >= 0x80) ||
22097 (prefix_data.ptr[3] != 0x00))) {
22098 // Roughly speaking, this could be a non-degenerate (non-0-width and
22099 // non-0-height) WBMP image.
22100 return 0x57424D50; // 'WBMP'be
22102 return 0;
22105 return fourcc;
22108 #endif // !defined(WUFFS_CONFIG__MODULES) ||
22109 // defined(WUFFS_CONFIG__MODULE__BASE) ||
22110 // defined(WUFFS_CONFIG__MODULE__BASE__MAGIC)
22112 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
22113 defined(WUFFS_CONFIG__MODULE__BASE__PIXCONV)
22115 // ---------------- Pixel Swizzler
22117 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
22118 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
22119 static uint64_t //
22120 wuffs_private_impl__swizzle_bgrw__bgr__x86_sse42(uint8_t* dst_ptr,
22121 size_t dst_len,
22122 uint8_t* dst_palette_ptr,
22123 size_t dst_palette_len,
22124 const uint8_t* src_ptr,
22125 size_t src_len);
22127 static uint64_t //
22128 wuffs_private_impl__swizzle_bgrw__rgb__x86_sse42(uint8_t* dst_ptr,
22129 size_t dst_len,
22130 uint8_t* dst_palette_ptr,
22131 size_t dst_palette_len,
22132 const uint8_t* src_ptr,
22133 size_t src_len);
22135 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
22136 static uint64_t //
22137 wuffs_private_impl__swizzle_swap_rgbx_bgrx__x86_sse42(uint8_t* dst_ptr,
22138 size_t dst_len,
22139 uint8_t* dst_palette_ptr,
22140 size_t dst_palette_len,
22141 const uint8_t* src_ptr,
22142 size_t src_len);
22144 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
22145 static uint64_t //
22146 wuffs_private_impl__swizzle_xxxx__y__x86_sse42(uint8_t* dst_ptr,
22147 size_t dst_len,
22148 uint8_t* dst_palette_ptr,
22149 size_t dst_palette_len,
22150 const uint8_t* src_ptr,
22151 size_t src_len);
22152 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
22154 // --------
22156 static inline uint32_t //
22157 wuffs_private_impl__swap_u32_argb_abgr(uint32_t u) {
22158 uint32_t o = u & 0xFF00FF00ul;
22159 uint32_t r = u & 0x00FF0000ul;
22160 uint32_t b = u & 0x000000FFul;
22161 return o | (r >> 16) | (b << 16);
22164 static inline uint64_t //
22165 wuffs_private_impl__swap_u64_argb_abgr(uint64_t u) {
22166 uint64_t o = u & 0xFFFF0000FFFF0000ull;
22167 uint64_t r = u & 0x0000FFFF00000000ull;
22168 uint64_t b = u & 0x000000000000FFFFull;
22169 return o | (r >> 32) | (b << 32);
22172 static inline uint32_t //
22173 wuffs_private_impl__color_u64__as__color_u32__swap_u32_argb_abgr(uint64_t c) {
22174 uint32_t a = ((uint32_t)(0xFF & (c >> 56)));
22175 uint32_t r = ((uint32_t)(0xFF & (c >> 40)));
22176 uint32_t g = ((uint32_t)(0xFF & (c >> 24)));
22177 uint32_t b = ((uint32_t)(0xFF & (c >> 8)));
22178 return (a << 24) | (b << 16) | (g << 8) | (r << 0);
22181 // --------
22183 WUFFS_BASE__MAYBE_STATIC wuffs_base__color_u32_argb_premul //
22184 wuffs_base__pixel_buffer__color_u32_at(const wuffs_base__pixel_buffer* pb,
22185 uint32_t x,
22186 uint32_t y) {
22187 if (!pb || (x >= pb->pixcfg.private_impl.width) ||
22188 (y >= pb->pixcfg.private_impl.height)) {
22189 return 0;
22192 if (wuffs_base__pixel_format__is_planar(&pb->pixcfg.private_impl.pixfmt)) {
22193 // TODO: support planar formats.
22194 return 0;
22197 size_t stride = pb->private_impl.planes[0].stride;
22198 const uint8_t* row = pb->private_impl.planes[0].ptr + (stride * ((size_t)y));
22200 switch (pb->pixcfg.private_impl.pixfmt.repr) {
22201 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
22202 case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
22203 return wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x)));
22205 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL:
22206 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY: {
22207 uint8_t* palette = pb->private_impl.planes[3].ptr;
22208 return wuffs_base__peek_u32le__no_bounds_check(palette +
22209 (4 * ((size_t)row[x])));
22212 // Common formats above. Rarer formats below.
22214 case WUFFS_BASE__PIXEL_FORMAT__Y:
22215 return 0xFF000000 | (0x00010101 * ((uint32_t)(row[x])));
22216 case WUFFS_BASE__PIXEL_FORMAT__Y_16LE:
22217 return 0xFF000000 | (0x00010101 * ((uint32_t)(row[(2 * x) + 1])));
22218 case WUFFS_BASE__PIXEL_FORMAT__Y_16BE:
22219 return 0xFF000000 | (0x00010101 * ((uint32_t)(row[(2 * x) + 0])));
22220 case WUFFS_BASE__PIXEL_FORMAT__YA_NONPREMUL:
22221 return wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
22222 (((uint32_t)(row[(2 * x) + 1])) << 24) |
22223 (((uint32_t)(row[(2 * x) + 0])) * 0x00010101));
22225 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL: {
22226 uint8_t* palette = pb->private_impl.planes[3].ptr;
22227 return wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
22228 wuffs_base__peek_u32le__no_bounds_check(palette +
22229 (4 * ((size_t)row[x]))));
22232 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
22233 return wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
22234 wuffs_base__peek_u16le__no_bounds_check(row + (2 * ((size_t)x))));
22235 case WUFFS_BASE__PIXEL_FORMAT__BGR:
22236 return 0xFF000000 |
22237 wuffs_base__peek_u24le__no_bounds_check(row + (3 * ((size_t)x)));
22238 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
22239 return wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
22240 wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x))));
22241 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
22242 return wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(
22243 wuffs_base__peek_u64le__no_bounds_check(row + (8 * ((size_t)x))));
22244 case WUFFS_BASE__PIXEL_FORMAT__BGRX:
22245 return 0xFF000000 |
22246 wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x)));
22248 case WUFFS_BASE__PIXEL_FORMAT__RGB:
22249 return wuffs_private_impl__swap_u32_argb_abgr(
22250 0xFF000000 |
22251 wuffs_base__peek_u24le__no_bounds_check(row + (3 * ((size_t)x))));
22252 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
22253 return wuffs_private_impl__swap_u32_argb_abgr(
22254 wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
22255 wuffs_base__peek_u32le__no_bounds_check(row +
22256 (4 * ((size_t)x)))));
22257 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
22258 case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
22259 return wuffs_private_impl__swap_u32_argb_abgr(
22260 wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x))));
22261 case WUFFS_BASE__PIXEL_FORMAT__RGBX:
22262 return wuffs_private_impl__swap_u32_argb_abgr(
22263 0xFF000000 |
22264 wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x))));
22266 default:
22267 // TODO: support more formats.
22268 break;
22271 return 0;
22274 // --------
22276 WUFFS_BASE__MAYBE_STATIC wuffs_base__status //
22277 wuffs_base__pixel_buffer__set_color_u32_at(
22278 wuffs_base__pixel_buffer* pb,
22279 uint32_t x,
22280 uint32_t y,
22281 wuffs_base__color_u32_argb_premul color) {
22282 if (!pb) {
22283 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
22285 if ((x >= pb->pixcfg.private_impl.width) ||
22286 (y >= pb->pixcfg.private_impl.height)) {
22287 return wuffs_base__make_status(wuffs_base__error__bad_argument);
22290 if (wuffs_base__pixel_format__is_planar(&pb->pixcfg.private_impl.pixfmt)) {
22291 // TODO: support planar formats.
22292 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
22295 size_t stride = pb->private_impl.planes[0].stride;
22296 uint8_t* row = pb->private_impl.planes[0].ptr + (stride * ((size_t)y));
22298 switch (pb->pixcfg.private_impl.pixfmt.repr) {
22299 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
22300 case WUFFS_BASE__PIXEL_FORMAT__BGRX:
22301 wuffs_base__poke_u32le__no_bounds_check(row + (4 * ((size_t)x)), color);
22302 break;
22304 // Common formats above. Rarer formats below.
22306 case WUFFS_BASE__PIXEL_FORMAT__Y:
22307 wuffs_base__poke_u8__no_bounds_check(
22308 row + ((size_t)x),
22309 wuffs_base__color_u32_argb_premul__as__color_u8_gray(color));
22310 break;
22311 case WUFFS_BASE__PIXEL_FORMAT__Y_16LE:
22312 wuffs_base__poke_u16le__no_bounds_check(
22313 row + (2 * ((size_t)x)),
22314 wuffs_base__color_u32_argb_premul__as__color_u16_gray(color));
22315 break;
22316 case WUFFS_BASE__PIXEL_FORMAT__Y_16BE:
22317 wuffs_base__poke_u16be__no_bounds_check(
22318 row + (2 * ((size_t)x)),
22319 wuffs_base__color_u32_argb_premul__as__color_u16_gray(color));
22320 break;
22321 case WUFFS_BASE__PIXEL_FORMAT__YA_NONPREMUL:
22322 wuffs_base__poke_u16le__no_bounds_check(
22323 row + (2 * ((size_t)x)),
22324 wuffs_base__color_u32_argb_premul__as__color_u16_alpha_gray_nonpremul(
22325 color));
22326 break;
22328 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:
22329 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL:
22330 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY:
22331 wuffs_base__poke_u8__no_bounds_check(
22332 row + ((size_t)x), wuffs_base__pixel_palette__closest_element(
22333 wuffs_base__pixel_buffer__palette(pb),
22334 pb->pixcfg.private_impl.pixfmt, color));
22335 break;
22337 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
22338 wuffs_base__poke_u16le__no_bounds_check(
22339 row + (2 * ((size_t)x)),
22340 wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(color));
22341 break;
22342 case WUFFS_BASE__PIXEL_FORMAT__BGR:
22343 wuffs_base__poke_u24le__no_bounds_check(row + (3 * ((size_t)x)), color);
22344 break;
22345 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
22346 wuffs_base__poke_u32le__no_bounds_check(
22347 row + (4 * ((size_t)x)),
22348 wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
22349 color));
22350 break;
22351 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
22352 wuffs_base__poke_u64le__no_bounds_check(
22353 row + (8 * ((size_t)x)),
22354 wuffs_base__color_u32_argb_premul__as__color_u64_argb_nonpremul(
22355 color));
22356 break;
22358 case WUFFS_BASE__PIXEL_FORMAT__RGB:
22359 wuffs_base__poke_u24le__no_bounds_check(
22360 row + (3 * ((size_t)x)),
22361 wuffs_private_impl__swap_u32_argb_abgr(color));
22362 break;
22363 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
22364 wuffs_base__poke_u32le__no_bounds_check(
22365 row + (4 * ((size_t)x)),
22366 wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
22367 wuffs_private_impl__swap_u32_argb_abgr(color)));
22368 break;
22369 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
22370 case WUFFS_BASE__PIXEL_FORMAT__RGBX:
22371 wuffs_base__poke_u32le__no_bounds_check(
22372 row + (4 * ((size_t)x)),
22373 wuffs_private_impl__swap_u32_argb_abgr(color));
22374 break;
22376 default:
22377 // TODO: support more formats.
22378 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
22381 return wuffs_base__make_status(NULL);
22384 // --------
22386 static inline void //
22387 wuffs_private_impl__pixel_buffer__set_color_u32_fill_rect__xx(
22388 wuffs_base__pixel_buffer* pb,
22389 wuffs_base__rect_ie_u32 rect,
22390 uint16_t color) {
22391 size_t stride = pb->private_impl.planes[0].stride;
22392 uint32_t width = wuffs_base__rect_ie_u32__width(&rect);
22393 if ((stride == (2 * ((uint64_t)width))) && (rect.min_incl_x == 0)) {
22394 uint8_t* ptr =
22395 pb->private_impl.planes[0].ptr + (stride * ((size_t)rect.min_incl_y));
22396 uint32_t height = wuffs_base__rect_ie_u32__height(&rect);
22397 size_t n;
22398 for (n = ((size_t)width) * ((size_t)height); n > 0; n--) {
22399 wuffs_base__poke_u16le__no_bounds_check(ptr, color);
22400 ptr += 2;
22402 return;
22405 uint32_t y;
22406 for (y = rect.min_incl_y; y < rect.max_excl_y; y++) {
22407 uint8_t* ptr = pb->private_impl.planes[0].ptr + (stride * ((size_t)y)) +
22408 (2 * ((size_t)rect.min_incl_x));
22409 uint32_t n;
22410 for (n = width; n > 0; n--) {
22411 wuffs_base__poke_u16le__no_bounds_check(ptr, color);
22412 ptr += 2;
22417 static inline void //
22418 wuffs_private_impl__pixel_buffer__set_color_u32_fill_rect__xxx(
22419 wuffs_base__pixel_buffer* pb,
22420 wuffs_base__rect_ie_u32 rect,
22421 uint32_t color) {
22422 size_t stride = pb->private_impl.planes[0].stride;
22423 uint32_t width = wuffs_base__rect_ie_u32__width(&rect);
22424 if ((stride == (3 * ((uint64_t)width))) && (rect.min_incl_x == 0)) {
22425 uint8_t* ptr =
22426 pb->private_impl.planes[0].ptr + (stride * ((size_t)rect.min_incl_y));
22427 uint32_t height = wuffs_base__rect_ie_u32__height(&rect);
22428 size_t n;
22429 for (n = ((size_t)width) * ((size_t)height); n > 0; n--) {
22430 wuffs_base__poke_u24le__no_bounds_check(ptr, color);
22431 ptr += 3;
22433 return;
22436 uint32_t y;
22437 for (y = rect.min_incl_y; y < rect.max_excl_y; y++) {
22438 uint8_t* ptr = pb->private_impl.planes[0].ptr + (stride * ((size_t)y)) +
22439 (3 * ((size_t)rect.min_incl_x));
22440 uint32_t n;
22441 for (n = width; n > 0; n--) {
22442 wuffs_base__poke_u24le__no_bounds_check(ptr, color);
22443 ptr += 3;
22448 static inline void //
22449 wuffs_private_impl__pixel_buffer__set_color_u32_fill_rect__xxxx(
22450 wuffs_base__pixel_buffer* pb,
22451 wuffs_base__rect_ie_u32 rect,
22452 uint32_t color) {
22453 size_t stride = pb->private_impl.planes[0].stride;
22454 uint32_t width = wuffs_base__rect_ie_u32__width(&rect);
22455 if ((stride == (4 * ((uint64_t)width))) && (rect.min_incl_x == 0)) {
22456 uint8_t* ptr =
22457 pb->private_impl.planes[0].ptr + (stride * ((size_t)rect.min_incl_y));
22458 uint32_t height = wuffs_base__rect_ie_u32__height(&rect);
22459 size_t n;
22460 for (n = ((size_t)width) * ((size_t)height); n > 0; n--) {
22461 wuffs_base__poke_u32le__no_bounds_check(ptr, color);
22462 ptr += 4;
22464 return;
22467 uint32_t y;
22468 for (y = rect.min_incl_y; y < rect.max_excl_y; y++) {
22469 uint8_t* ptr = pb->private_impl.planes[0].ptr + (stride * ((size_t)y)) +
22470 (4 * ((size_t)rect.min_incl_x));
22471 uint32_t n;
22472 for (n = width; n > 0; n--) {
22473 wuffs_base__poke_u32le__no_bounds_check(ptr, color);
22474 ptr += 4;
22479 static inline void //
22480 wuffs_private_impl__pixel_buffer__set_color_u32_fill_rect__xxxxxxxx(
22481 wuffs_base__pixel_buffer* pb,
22482 wuffs_base__rect_ie_u32 rect,
22483 uint64_t color) {
22484 size_t stride = pb->private_impl.planes[0].stride;
22485 uint32_t width = wuffs_base__rect_ie_u32__width(&rect);
22486 if ((stride == (8 * ((uint64_t)width))) && (rect.min_incl_x == 0)) {
22487 uint8_t* ptr =
22488 pb->private_impl.planes[0].ptr + (stride * ((size_t)rect.min_incl_y));
22489 uint32_t height = wuffs_base__rect_ie_u32__height(&rect);
22490 size_t n;
22491 for (n = ((size_t)width) * ((size_t)height); n > 0; n--) {
22492 wuffs_base__poke_u64le__no_bounds_check(ptr, color);
22493 ptr += 8;
22495 return;
22498 uint32_t y;
22499 for (y = rect.min_incl_y; y < rect.max_excl_y; y++) {
22500 uint8_t* ptr = pb->private_impl.planes[0].ptr + (stride * ((size_t)y)) +
22501 (8 * ((size_t)rect.min_incl_x));
22502 uint32_t n;
22503 for (n = width; n > 0; n--) {
22504 wuffs_base__poke_u64le__no_bounds_check(ptr, color);
22505 ptr += 8;
22510 WUFFS_BASE__MAYBE_STATIC wuffs_base__status //
22511 wuffs_base__pixel_buffer__set_color_u32_fill_rect(
22512 wuffs_base__pixel_buffer* pb,
22513 wuffs_base__rect_ie_u32 rect,
22514 wuffs_base__color_u32_argb_premul color) {
22515 if (!pb) {
22516 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
22517 } else if (wuffs_base__rect_ie_u32__is_empty(&rect)) {
22518 return wuffs_base__make_status(NULL);
22520 wuffs_base__rect_ie_u32 bounds =
22521 wuffs_base__pixel_config__bounds(&pb->pixcfg);
22522 if (!wuffs_base__rect_ie_u32__contains_rect(&bounds, rect)) {
22523 return wuffs_base__make_status(wuffs_base__error__bad_argument);
22526 if (wuffs_base__pixel_format__is_planar(&pb->pixcfg.private_impl.pixfmt)) {
22527 // TODO: support planar formats.
22528 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
22531 switch (pb->pixcfg.private_impl.pixfmt.repr) {
22532 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
22533 case WUFFS_BASE__PIXEL_FORMAT__BGRX:
22534 wuffs_private_impl__pixel_buffer__set_color_u32_fill_rect__xxxx(pb, rect,
22535 color);
22536 return wuffs_base__make_status(NULL);
22538 // Common formats above. Rarer formats below.
22540 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
22541 wuffs_private_impl__pixel_buffer__set_color_u32_fill_rect__xx(
22542 pb, rect,
22543 wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(color));
22544 return wuffs_base__make_status(NULL);
22546 case WUFFS_BASE__PIXEL_FORMAT__BGR:
22547 wuffs_private_impl__pixel_buffer__set_color_u32_fill_rect__xxx(pb, rect,
22548 color);
22549 return wuffs_base__make_status(NULL);
22551 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
22552 wuffs_private_impl__pixel_buffer__set_color_u32_fill_rect__xxxx(
22553 pb, rect,
22554 wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
22555 color));
22556 return wuffs_base__make_status(NULL);
22558 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
22559 wuffs_private_impl__pixel_buffer__set_color_u32_fill_rect__xxxxxxxx(
22560 pb, rect,
22561 wuffs_base__color_u32_argb_premul__as__color_u64_argb_nonpremul(
22562 color));
22563 return wuffs_base__make_status(NULL);
22565 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
22566 wuffs_private_impl__pixel_buffer__set_color_u32_fill_rect__xxxx(
22567 pb, rect,
22568 wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
22569 wuffs_private_impl__swap_u32_argb_abgr(color)));
22570 return wuffs_base__make_status(NULL);
22572 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
22573 case WUFFS_BASE__PIXEL_FORMAT__RGBX:
22574 wuffs_private_impl__pixel_buffer__set_color_u32_fill_rect__xxxx(
22575 pb, rect, wuffs_private_impl__swap_u32_argb_abgr(color));
22576 return wuffs_base__make_status(NULL);
22579 uint32_t y;
22580 for (y = rect.min_incl_y; y < rect.max_excl_y; y++) {
22581 uint32_t x;
22582 for (x = rect.min_incl_x; x < rect.max_excl_x; x++) {
22583 wuffs_base__pixel_buffer__set_color_u32_at(pb, x, y, color);
22586 return wuffs_base__make_status(NULL);
22589 // --------
22591 WUFFS_BASE__MAYBE_STATIC uint8_t //
22592 wuffs_base__pixel_palette__closest_element(
22593 wuffs_base__slice_u8 palette_slice,
22594 wuffs_base__pixel_format palette_format,
22595 wuffs_base__color_u32_argb_premul c) {
22596 size_t n = palette_slice.len / 4;
22597 if (n > (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
22598 n = (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4);
22600 size_t best_index = 0;
22601 uint64_t best_score = 0xFFFFFFFFFFFFFFFF;
22603 // Work in 16-bit color.
22604 uint32_t ca = 0x101 * (0xFF & (c >> 24));
22605 uint32_t cr = 0x101 * (0xFF & (c >> 16));
22606 uint32_t cg = 0x101 * (0xFF & (c >> 8));
22607 uint32_t cb = 0x101 * (0xFF & (c >> 0));
22609 switch (palette_format.repr) {
22610 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:
22611 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL:
22612 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY: {
22613 bool nonpremul = palette_format.repr ==
22614 WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL;
22616 size_t i;
22617 for (i = 0; i < n; i++) {
22618 // Work in 16-bit color.
22619 uint32_t pb = 0x101 * ((uint32_t)(palette_slice.ptr[(4 * i) + 0]));
22620 uint32_t pg = 0x101 * ((uint32_t)(palette_slice.ptr[(4 * i) + 1]));
22621 uint32_t pr = 0x101 * ((uint32_t)(palette_slice.ptr[(4 * i) + 2]));
22622 uint32_t pa = 0x101 * ((uint32_t)(palette_slice.ptr[(4 * i) + 3]));
22624 // Convert to premultiplied alpha.
22625 if (nonpremul && (pa != 0xFFFF)) {
22626 pb = (pb * pa) / 0xFFFF;
22627 pg = (pg * pa) / 0xFFFF;
22628 pr = (pr * pa) / 0xFFFF;
22631 // These deltas are conceptually int32_t (signed) but after squaring,
22632 // it's equivalent to work in uint32_t (unsigned).
22633 pb -= cb;
22634 pg -= cg;
22635 pr -= cr;
22636 pa -= ca;
22637 uint64_t score = ((uint64_t)(pb * pb)) + ((uint64_t)(pg * pg)) +
22638 ((uint64_t)(pr * pr)) + ((uint64_t)(pa * pa));
22639 if (best_score > score) {
22640 best_score = score;
22641 best_index = i;
22644 break;
22648 return (uint8_t)best_index;
22651 // --------
22653 static inline uint32_t //
22654 wuffs_private_impl__composite_nonpremul_nonpremul_u32_axxx(
22655 uint32_t dst_nonpremul,
22656 uint32_t src_nonpremul) {
22657 // Extract 16-bit color components.
22659 // If the destination is transparent then SRC_OVER is equivalent to SRC: just
22660 // return src_nonpremul. This isn't just an optimization (skipping the rest
22661 // of the function's computation). It also preserves the nonpremul
22662 // distinction between e.g. transparent red and transparent blue that would
22663 // otherwise be lost by converting from nonpremul to premul and back.
22664 uint32_t da = 0x101 * (0xFF & (dst_nonpremul >> 24));
22665 if (da == 0) {
22666 return src_nonpremul;
22668 uint32_t dr = 0x101 * (0xFF & (dst_nonpremul >> 16));
22669 uint32_t dg = 0x101 * (0xFF & (dst_nonpremul >> 8));
22670 uint32_t db = 0x101 * (0xFF & (dst_nonpremul >> 0));
22671 uint32_t sa = 0x101 * (0xFF & (src_nonpremul >> 24));
22672 uint32_t sr = 0x101 * (0xFF & (src_nonpremul >> 16));
22673 uint32_t sg = 0x101 * (0xFF & (src_nonpremul >> 8));
22674 uint32_t sb = 0x101 * (0xFF & (src_nonpremul >> 0));
22676 // Convert dst from nonpremul to premul.
22677 dr = (dr * da) / 0xFFFF;
22678 dg = (dg * da) / 0xFFFF;
22679 db = (db * da) / 0xFFFF;
22681 // Calculate the inverse of the src-alpha: how much of the dst to keep.
22682 uint32_t ia = 0xFFFF - sa;
22684 // Composite src (nonpremul) over dst (premul).
22685 da = sa + ((da * ia) / 0xFFFF);
22686 dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
22687 dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
22688 db = ((sb * sa) + (db * ia)) / 0xFFFF;
22690 // Convert dst from premul to nonpremul.
22691 if (da != 0) {
22692 dr = (dr * 0xFFFF) / da;
22693 dg = (dg * 0xFFFF) / da;
22694 db = (db * 0xFFFF) / da;
22697 // Convert from 16-bit color to 8-bit color.
22698 da >>= 8;
22699 dr >>= 8;
22700 dg >>= 8;
22701 db >>= 8;
22703 // Combine components.
22704 return (db << 0) | (dg << 8) | (dr << 16) | (da << 24);
22707 static inline uint64_t //
22708 wuffs_private_impl__composite_nonpremul_nonpremul_u64_axxx(
22709 uint64_t dst_nonpremul,
22710 uint64_t src_nonpremul) {
22711 // Extract components.
22713 // If the destination is transparent then SRC_OVER is equivalent to SRC: just
22714 // return src_nonpremul. This isn't just an optimization (skipping the rest
22715 // of the function's computation). It also preserves the nonpremul
22716 // distinction between e.g. transparent red and transparent blue that would
22717 // otherwise be lost by converting from nonpremul to premul and back.
22718 uint64_t da = 0xFFFF & (dst_nonpremul >> 48);
22719 if (da == 0) {
22720 return src_nonpremul;
22722 uint64_t dr = 0xFFFF & (dst_nonpremul >> 32);
22723 uint64_t dg = 0xFFFF & (dst_nonpremul >> 16);
22724 uint64_t db = 0xFFFF & (dst_nonpremul >> 0);
22725 uint64_t sa = 0xFFFF & (src_nonpremul >> 48);
22726 uint64_t sr = 0xFFFF & (src_nonpremul >> 32);
22727 uint64_t sg = 0xFFFF & (src_nonpremul >> 16);
22728 uint64_t sb = 0xFFFF & (src_nonpremul >> 0);
22730 // Convert dst from nonpremul to premul.
22731 dr = (dr * da) / 0xFFFF;
22732 dg = (dg * da) / 0xFFFF;
22733 db = (db * da) / 0xFFFF;
22735 // Calculate the inverse of the src-alpha: how much of the dst to keep.
22736 uint64_t ia = 0xFFFF - sa;
22738 // Composite src (nonpremul) over dst (premul).
22739 da = sa + ((da * ia) / 0xFFFF);
22740 dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
22741 dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
22742 db = ((sb * sa) + (db * ia)) / 0xFFFF;
22744 // Convert dst from premul to nonpremul.
22745 if (da != 0) {
22746 dr = (dr * 0xFFFF) / da;
22747 dg = (dg * 0xFFFF) / da;
22748 db = (db * 0xFFFF) / da;
22751 // Combine components.
22752 return (db << 0) | (dg << 16) | (dr << 32) | (da << 48);
22755 static inline uint32_t //
22756 wuffs_private_impl__composite_nonpremul_premul_u32_axxx(uint32_t dst_nonpremul,
22757 uint32_t src_premul) {
22758 // Extract 16-bit color components.
22759 uint32_t da = 0x101 * (0xFF & (dst_nonpremul >> 24));
22760 uint32_t dr = 0x101 * (0xFF & (dst_nonpremul >> 16));
22761 uint32_t dg = 0x101 * (0xFF & (dst_nonpremul >> 8));
22762 uint32_t db = 0x101 * (0xFF & (dst_nonpremul >> 0));
22763 uint32_t sa = 0x101 * (0xFF & (src_premul >> 24));
22764 uint32_t sr = 0x101 * (0xFF & (src_premul >> 16));
22765 uint32_t sg = 0x101 * (0xFF & (src_premul >> 8));
22766 uint32_t sb = 0x101 * (0xFF & (src_premul >> 0));
22768 // Convert dst from nonpremul to premul.
22769 dr = (dr * da) / 0xFFFF;
22770 dg = (dg * da) / 0xFFFF;
22771 db = (db * da) / 0xFFFF;
22773 // Calculate the inverse of the src-alpha: how much of the dst to keep.
22774 uint32_t ia = 0xFFFF - sa;
22776 // Composite src (premul) over dst (premul).
22777 da = sa + ((da * ia) / 0xFFFF);
22778 dr = sr + ((dr * ia) / 0xFFFF);
22779 dg = sg + ((dg * ia) / 0xFFFF);
22780 db = sb + ((db * ia) / 0xFFFF);
22782 // Convert dst from premul to nonpremul.
22783 if (da != 0) {
22784 dr = (dr * 0xFFFF) / da;
22785 dg = (dg * 0xFFFF) / da;
22786 db = (db * 0xFFFF) / da;
22789 // Convert from 16-bit color to 8-bit color.
22790 da >>= 8;
22791 dr >>= 8;
22792 dg >>= 8;
22793 db >>= 8;
22795 // Combine components.
22796 return (db << 0) | (dg << 8) | (dr << 16) | (da << 24);
22799 static inline uint64_t //
22800 wuffs_private_impl__composite_nonpremul_premul_u64_axxx(uint64_t dst_nonpremul,
22801 uint64_t src_premul) {
22802 // Extract components.
22803 uint64_t da = 0xFFFF & (dst_nonpremul >> 48);
22804 uint64_t dr = 0xFFFF & (dst_nonpremul >> 32);
22805 uint64_t dg = 0xFFFF & (dst_nonpremul >> 16);
22806 uint64_t db = 0xFFFF & (dst_nonpremul >> 0);
22807 uint64_t sa = 0xFFFF & (src_premul >> 48);
22808 uint64_t sr = 0xFFFF & (src_premul >> 32);
22809 uint64_t sg = 0xFFFF & (src_premul >> 16);
22810 uint64_t sb = 0xFFFF & (src_premul >> 0);
22812 // Convert dst from nonpremul to premul.
22813 dr = (dr * da) / 0xFFFF;
22814 dg = (dg * da) / 0xFFFF;
22815 db = (db * da) / 0xFFFF;
22817 // Calculate the inverse of the src-alpha: how much of the dst to keep.
22818 uint64_t ia = 0xFFFF - sa;
22820 // Composite src (premul) over dst (premul).
22821 da = sa + ((da * ia) / 0xFFFF);
22822 dr = sr + ((dr * ia) / 0xFFFF);
22823 dg = sg + ((dg * ia) / 0xFFFF);
22824 db = sb + ((db * ia) / 0xFFFF);
22826 // Convert dst from premul to nonpremul.
22827 if (da != 0) {
22828 dr = (dr * 0xFFFF) / da;
22829 dg = (dg * 0xFFFF) / da;
22830 db = (db * 0xFFFF) / da;
22833 // Combine components.
22834 return (db << 0) | (dg << 16) | (dr << 32) | (da << 48);
22837 static inline uint32_t //
22838 wuffs_private_impl__composite_premul_nonpremul_u32_axxx(
22839 uint32_t dst_premul,
22840 uint32_t src_nonpremul) {
22841 // Extract 16-bit color components.
22842 uint32_t da = 0x101 * (0xFF & (dst_premul >> 24));
22843 uint32_t dr = 0x101 * (0xFF & (dst_premul >> 16));
22844 uint32_t dg = 0x101 * (0xFF & (dst_premul >> 8));
22845 uint32_t db = 0x101 * (0xFF & (dst_premul >> 0));
22846 uint32_t sa = 0x101 * (0xFF & (src_nonpremul >> 24));
22847 uint32_t sr = 0x101 * (0xFF & (src_nonpremul >> 16));
22848 uint32_t sg = 0x101 * (0xFF & (src_nonpremul >> 8));
22849 uint32_t sb = 0x101 * (0xFF & (src_nonpremul >> 0));
22851 // Calculate the inverse of the src-alpha: how much of the dst to keep.
22852 uint32_t ia = 0xFFFF - sa;
22854 // Composite src (nonpremul) over dst (premul).
22855 da = sa + ((da * ia) / 0xFFFF);
22856 dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
22857 dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
22858 db = ((sb * sa) + (db * ia)) / 0xFFFF;
22860 // Convert from 16-bit color to 8-bit color.
22861 da >>= 8;
22862 dr >>= 8;
22863 dg >>= 8;
22864 db >>= 8;
22866 // Combine components.
22867 return (db << 0) | (dg << 8) | (dr << 16) | (da << 24);
22870 static inline uint64_t //
22871 wuffs_private_impl__composite_premul_nonpremul_u64_axxx(
22872 uint64_t dst_premul,
22873 uint64_t src_nonpremul) {
22874 // Extract components.
22875 uint64_t da = 0xFFFF & (dst_premul >> 48);
22876 uint64_t dr = 0xFFFF & (dst_premul >> 32);
22877 uint64_t dg = 0xFFFF & (dst_premul >> 16);
22878 uint64_t db = 0xFFFF & (dst_premul >> 0);
22879 uint64_t sa = 0xFFFF & (src_nonpremul >> 48);
22880 uint64_t sr = 0xFFFF & (src_nonpremul >> 32);
22881 uint64_t sg = 0xFFFF & (src_nonpremul >> 16);
22882 uint64_t sb = 0xFFFF & (src_nonpremul >> 0);
22884 // Calculate the inverse of the src-alpha: how much of the dst to keep.
22885 uint64_t ia = 0xFFFF - sa;
22887 // Composite src (nonpremul) over dst (premul).
22888 da = sa + ((da * ia) / 0xFFFF);
22889 dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
22890 dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
22891 db = ((sb * sa) + (db * ia)) / 0xFFFF;
22893 // Combine components.
22894 return (db << 0) | (dg << 16) | (dr << 32) | (da << 48);
22897 static inline uint32_t //
22898 wuffs_private_impl__composite_premul_premul_u32_axxx(uint32_t dst_premul,
22899 uint32_t src_premul) {
22900 // Extract 16-bit color components.
22901 uint32_t da = 0x101 * (0xFF & (dst_premul >> 24));
22902 uint32_t dr = 0x101 * (0xFF & (dst_premul >> 16));
22903 uint32_t dg = 0x101 * (0xFF & (dst_premul >> 8));
22904 uint32_t db = 0x101 * (0xFF & (dst_premul >> 0));
22905 uint32_t sa = 0x101 * (0xFF & (src_premul >> 24));
22906 uint32_t sr = 0x101 * (0xFF & (src_premul >> 16));
22907 uint32_t sg = 0x101 * (0xFF & (src_premul >> 8));
22908 uint32_t sb = 0x101 * (0xFF & (src_premul >> 0));
22910 // Calculate the inverse of the src-alpha: how much of the dst to keep.
22911 uint32_t ia = 0xFFFF - sa;
22913 // Composite src (premul) over dst (premul).
22914 da = sa + ((da * ia) / 0xFFFF);
22915 dr = sr + ((dr * ia) / 0xFFFF);
22916 dg = sg + ((dg * ia) / 0xFFFF);
22917 db = sb + ((db * ia) / 0xFFFF);
22919 // Convert from 16-bit color to 8-bit color.
22920 da >>= 8;
22921 dr >>= 8;
22922 dg >>= 8;
22923 db >>= 8;
22925 // Combine components.
22926 return (db << 0) | (dg << 8) | (dr << 16) | (da << 24);
22929 // --------
22931 static uint64_t //
22932 wuffs_private_impl__swizzle_squash_align4_bgr_565_8888(uint8_t* dst_ptr,
22933 size_t dst_len,
22934 const uint8_t* src_ptr,
22935 size_t src_len,
22936 bool nonpremul) {
22937 size_t len = (dst_len < src_len ? dst_len : src_len) / 4;
22938 uint8_t* d = dst_ptr;
22939 const uint8_t* s = src_ptr;
22941 size_t n = len;
22942 while (n--) {
22943 uint32_t argb = wuffs_base__peek_u32le__no_bounds_check(s);
22944 if (nonpremul) {
22945 argb =
22946 wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(argb);
22948 uint32_t b5 = 0x1F & (argb >> (8 - 5));
22949 uint32_t g6 = 0x3F & (argb >> (16 - 6));
22950 uint32_t r5 = 0x1F & (argb >> (24 - 5));
22951 uint32_t alpha = argb & 0xFF000000;
22952 wuffs_base__poke_u32le__no_bounds_check(
22953 d, alpha | (r5 << 11) | (g6 << 5) | (b5 << 0));
22954 s += 4;
22955 d += 4;
22957 return len;
22960 // --------
22962 static uint64_t //
22963 wuffs_private_impl__swizzle_swap_rgb_bgr(uint8_t* dst_ptr,
22964 size_t dst_len,
22965 uint8_t* dst_palette_ptr,
22966 size_t dst_palette_len,
22967 const uint8_t* src_ptr,
22968 size_t src_len) {
22969 size_t len = (dst_len < src_len ? dst_len : src_len) / 3;
22970 uint8_t* d = dst_ptr;
22971 const uint8_t* s = src_ptr;
22973 size_t n = len;
22974 while (n--) {
22975 uint8_t s0 = s[0];
22976 uint8_t s1 = s[1];
22977 uint8_t s2 = s[2];
22978 d[0] = s2;
22979 d[1] = s1;
22980 d[2] = s0;
22981 s += 3;
22982 d += 3;
22984 return len;
22987 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
22988 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
22989 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
22990 static uint64_t //
22991 wuffs_private_impl__swizzle_swap_rgbx_bgrx__x86_sse42(uint8_t* dst_ptr,
22992 size_t dst_len,
22993 uint8_t* dst_palette_ptr,
22994 size_t dst_palette_len,
22995 const uint8_t* src_ptr,
22996 size_t src_len) {
22997 size_t len = (dst_len < src_len ? dst_len : src_len) / 4;
22998 uint8_t* d = dst_ptr;
22999 const uint8_t* s = src_ptr;
23000 size_t n = len;
23002 __m128i shuffle = _mm_set_epi8(+0x0F, +0x0C, +0x0D, +0x0E, //
23003 +0x0B, +0x08, +0x09, +0x0A, //
23004 +0x07, +0x04, +0x05, +0x06, //
23005 +0x03, +0x00, +0x01, +0x02);
23007 while (n >= 4) {
23008 __m128i x;
23009 x = _mm_lddqu_si128((const __m128i*)(const void*)s);
23010 x = _mm_shuffle_epi8(x, shuffle);
23011 _mm_storeu_si128((__m128i*)(void*)d, x);
23013 s += 4 * 4;
23014 d += 4 * 4;
23015 n -= 4;
23018 while (n--) {
23019 uint8_t s0 = s[0];
23020 uint8_t s1 = s[1];
23021 uint8_t s2 = s[2];
23022 uint8_t s3 = s[3];
23023 d[0] = s2;
23024 d[1] = s1;
23025 d[2] = s0;
23026 d[3] = s3;
23027 s += 4;
23028 d += 4;
23030 return len;
23032 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
23033 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
23035 static uint64_t //
23036 wuffs_private_impl__swizzle_swap_rgbx_bgrx(uint8_t* dst_ptr,
23037 size_t dst_len,
23038 uint8_t* dst_palette_ptr,
23039 size_t dst_palette_len,
23040 const uint8_t* src_ptr,
23041 size_t src_len) {
23042 size_t len = (dst_len < src_len ? dst_len : src_len) / 4;
23043 uint8_t* d = dst_ptr;
23044 const uint8_t* s = src_ptr;
23046 size_t n = len;
23047 while (n--) {
23048 uint8_t s0 = s[0];
23049 uint8_t s1 = s[1];
23050 uint8_t s2 = s[2];
23051 uint8_t s3 = s[3];
23052 d[0] = s2;
23053 d[1] = s1;
23054 d[2] = s0;
23055 d[3] = s3;
23056 s += 4;
23057 d += 4;
23059 return len;
23062 // --------
23064 static uint64_t //
23065 wuffs_private_impl__swizzle_copy_1_1(uint8_t* dst_ptr,
23066 size_t dst_len,
23067 uint8_t* dst_palette_ptr,
23068 size_t dst_palette_len,
23069 const uint8_t* src_ptr,
23070 size_t src_len) {
23071 size_t len = (dst_len < src_len) ? dst_len : src_len;
23072 if (len > 0) {
23073 memmove(dst_ptr, src_ptr, len);
23075 return len;
23078 static uint64_t //
23079 wuffs_private_impl__swizzle_copy_2_2(uint8_t* dst_ptr,
23080 size_t dst_len,
23081 uint8_t* dst_palette_ptr,
23082 size_t dst_palette_len,
23083 const uint8_t* src_ptr,
23084 size_t src_len) {
23085 size_t dst_len2 = dst_len / 2;
23086 size_t src_len2 = src_len / 2;
23087 size_t len = (dst_len2 < src_len2) ? dst_len2 : src_len2;
23088 if (len > 0) {
23089 memmove(dst_ptr, src_ptr, len * 2);
23091 return len;
23094 static uint64_t //
23095 wuffs_private_impl__swizzle_copy_3_3(uint8_t* dst_ptr,
23096 size_t dst_len,
23097 uint8_t* dst_palette_ptr,
23098 size_t dst_palette_len,
23099 const uint8_t* src_ptr,
23100 size_t src_len) {
23101 size_t dst_len3 = dst_len / 3;
23102 size_t src_len3 = src_len / 3;
23103 size_t len = (dst_len3 < src_len3) ? dst_len3 : src_len3;
23104 if (len > 0) {
23105 memmove(dst_ptr, src_ptr, len * 3);
23107 return len;
23110 static uint64_t //
23111 wuffs_private_impl__swizzle_copy_4_4(uint8_t* dst_ptr,
23112 size_t dst_len,
23113 uint8_t* dst_palette_ptr,
23114 size_t dst_palette_len,
23115 const uint8_t* src_ptr,
23116 size_t src_len) {
23117 size_t dst_len4 = dst_len / 4;
23118 size_t src_len4 = src_len / 4;
23119 size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
23120 if (len > 0) {
23121 memmove(dst_ptr, src_ptr, len * 4);
23123 return len;
23126 static uint64_t //
23127 wuffs_private_impl__swizzle_copy_8_8(uint8_t* dst_ptr,
23128 size_t dst_len,
23129 uint8_t* dst_palette_ptr,
23130 size_t dst_palette_len,
23131 const uint8_t* src_ptr,
23132 size_t src_len) {
23133 size_t dst_len8 = dst_len / 8;
23134 size_t src_len8 = src_len / 8;
23135 size_t len = (dst_len8 < src_len8) ? dst_len8 : src_len8;
23136 if (len > 0) {
23137 memmove(dst_ptr, src_ptr, len * 8);
23139 return len;
23142 // --------
23144 static uint64_t //
23145 wuffs_private_impl__swizzle_bgr_565__bgr(uint8_t* dst_ptr,
23146 size_t dst_len,
23147 uint8_t* dst_palette_ptr,
23148 size_t dst_palette_len,
23149 const uint8_t* src_ptr,
23150 size_t src_len) {
23151 size_t dst_len2 = dst_len / 2;
23152 size_t src_len3 = src_len / 3;
23153 size_t len = (dst_len2 < src_len3) ? dst_len2 : src_len3;
23154 uint8_t* d = dst_ptr;
23155 const uint8_t* s = src_ptr;
23156 size_t n = len;
23158 // TODO: unroll.
23160 while (n >= 1) {
23161 uint32_t b5 = (uint32_t)(s[0] >> 3);
23162 uint32_t g6 = (uint32_t)(s[1] >> 2);
23163 uint32_t r5 = (uint32_t)(s[2] >> 3);
23164 uint32_t rgb_565 = (r5 << 11) | (g6 << 5) | (b5 << 0);
23165 wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565);
23167 s += 1 * 3;
23168 d += 1 * 2;
23169 n -= 1;
23172 return len;
23175 static uint64_t //
23176 wuffs_private_impl__swizzle_bgr_565__bgrx(uint8_t* dst_ptr,
23177 size_t dst_len,
23178 uint8_t* dst_palette_ptr,
23179 size_t dst_palette_len,
23180 const uint8_t* src_ptr,
23181 size_t src_len) {
23182 size_t dst_len2 = dst_len / 2;
23183 size_t src_len4 = src_len / 4;
23184 size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
23185 uint8_t* d = dst_ptr;
23186 const uint8_t* s = src_ptr;
23187 size_t n = len;
23189 // TODO: unroll.
23191 while (n >= 1) {
23192 uint32_t b5 = (uint32_t)(s[0] >> 3);
23193 uint32_t g6 = (uint32_t)(s[1] >> 2);
23194 uint32_t r5 = (uint32_t)(s[2] >> 3);
23195 uint32_t rgb_565 = (r5 << 11) | (g6 << 5) | (b5 << 0);
23196 wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565);
23198 s += 1 * 4;
23199 d += 1 * 2;
23200 n -= 1;
23203 return len;
23206 static uint64_t //
23207 wuffs_private_impl__swizzle_bgr_565__bgra_nonpremul__src(
23208 uint8_t* dst_ptr,
23209 size_t dst_len,
23210 uint8_t* dst_palette_ptr,
23211 size_t dst_palette_len,
23212 const uint8_t* src_ptr,
23213 size_t src_len) {
23214 size_t dst_len2 = dst_len / 2;
23215 size_t src_len4 = src_len / 4;
23216 size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
23217 uint8_t* d = dst_ptr;
23218 const uint8_t* s = src_ptr;
23219 size_t n = len;
23221 // TODO: unroll.
23223 while (n >= 1) {
23224 wuffs_base__poke_u16le__no_bounds_check(
23225 d + (0 * 2),
23226 wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
23227 wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
23228 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)))));
23230 s += 1 * 4;
23231 d += 1 * 2;
23232 n -= 1;
23235 return len;
23238 static uint64_t //
23239 wuffs_private_impl__swizzle_bgr_565__bgra_nonpremul_4x16le__src(
23240 uint8_t* dst_ptr,
23241 size_t dst_len,
23242 uint8_t* dst_palette_ptr,
23243 size_t dst_palette_len,
23244 const uint8_t* src_ptr,
23245 size_t src_len) {
23246 size_t dst_len2 = dst_len / 2;
23247 size_t src_len8 = src_len / 8;
23248 size_t len = (dst_len2 < src_len8) ? dst_len2 : src_len8;
23249 uint8_t* d = dst_ptr;
23250 const uint8_t* s = src_ptr;
23251 size_t n = len;
23253 // TODO: unroll.
23255 while (n >= 1) {
23256 wuffs_base__poke_u16le__no_bounds_check(
23257 d + (0 * 2),
23258 wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
23259 wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(
23260 wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)))));
23262 s += 1 * 8;
23263 d += 1 * 2;
23264 n -= 1;
23267 return len;
23270 static uint64_t //
23271 wuffs_private_impl__swizzle_bgr_565__bgra_nonpremul__src_over(
23272 uint8_t* dst_ptr,
23273 size_t dst_len,
23274 uint8_t* dst_palette_ptr,
23275 size_t dst_palette_len,
23276 const uint8_t* src_ptr,
23277 size_t src_len) {
23278 size_t dst_len2 = dst_len / 2;
23279 size_t src_len4 = src_len / 4;
23280 size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
23281 uint8_t* d = dst_ptr;
23282 const uint8_t* s = src_ptr;
23283 size_t n = len;
23285 // TODO: unroll.
23287 while (n >= 1) {
23288 // Extract 16-bit color components.
23289 uint32_t sa = 0x101 * ((uint32_t)s[3]);
23290 uint32_t sr = 0x101 * ((uint32_t)s[2]);
23291 uint32_t sg = 0x101 * ((uint32_t)s[1]);
23292 uint32_t sb = 0x101 * ((uint32_t)s[0]);
23294 // Convert from 565 color to 16-bit color.
23295 uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2));
23296 uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11);
23297 uint32_t dr = (0x8421 * old_r5) >> 4;
23298 uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5);
23299 uint32_t dg = (0x1041 * old_g6) >> 2;
23300 uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0);
23301 uint32_t db = (0x8421 * old_b5) >> 4;
23303 // Calculate the inverse of the src-alpha: how much of the dst to keep.
23304 uint32_t ia = 0xFFFF - sa;
23306 // Composite src (nonpremul) over dst (premul).
23307 dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
23308 dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
23309 db = ((sb * sa) + (db * ia)) / 0xFFFF;
23311 // Convert from 16-bit color to 565 color and combine the components.
23312 uint32_t new_r5 = 0x1F & (dr >> 11);
23313 uint32_t new_g6 = 0x3F & (dg >> 10);
23314 uint32_t new_b5 = 0x1F & (db >> 11);
23315 uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0);
23316 wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565);
23318 s += 1 * 4;
23319 d += 1 * 2;
23320 n -= 1;
23323 return len;
23326 static uint64_t //
23327 wuffs_private_impl__swizzle_bgr_565__bgra_nonpremul_4x16le__src_over(
23328 uint8_t* dst_ptr,
23329 size_t dst_len,
23330 uint8_t* dst_palette_ptr,
23331 size_t dst_palette_len,
23332 const uint8_t* src_ptr,
23333 size_t src_len) {
23334 size_t dst_len2 = dst_len / 2;
23335 size_t src_len8 = src_len / 8;
23336 size_t len = (dst_len2 < src_len8) ? dst_len2 : src_len8;
23337 uint8_t* d = dst_ptr;
23338 const uint8_t* s = src_ptr;
23339 size_t n = len;
23341 // TODO: unroll.
23343 while (n >= 1) {
23344 // Extract 16-bit color components.
23345 uint32_t sa = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 6));
23346 uint32_t sr = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 4));
23347 uint32_t sg = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 2));
23348 uint32_t sb = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 0));
23350 // Convert from 565 color to 16-bit color.
23351 uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2));
23352 uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11);
23353 uint32_t dr = (0x8421 * old_r5) >> 4;
23354 uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5);
23355 uint32_t dg = (0x1041 * old_g6) >> 2;
23356 uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0);
23357 uint32_t db = (0x8421 * old_b5) >> 4;
23359 // Calculate the inverse of the src-alpha: how much of the dst to keep.
23360 uint32_t ia = 0xFFFF - sa;
23362 // Composite src (nonpremul) over dst (premul).
23363 dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
23364 dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
23365 db = ((sb * sa) + (db * ia)) / 0xFFFF;
23367 // Convert from 16-bit color to 565 color and combine the components.
23368 uint32_t new_r5 = 0x1F & (dr >> 11);
23369 uint32_t new_g6 = 0x3F & (dg >> 10);
23370 uint32_t new_b5 = 0x1F & (db >> 11);
23371 uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0);
23372 wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565);
23374 s += 1 * 8;
23375 d += 1 * 2;
23376 n -= 1;
23379 return len;
23382 static uint64_t //
23383 wuffs_private_impl__swizzle_bgr_565__bgra_premul__src(uint8_t* dst_ptr,
23384 size_t dst_len,
23385 uint8_t* dst_palette_ptr,
23386 size_t dst_palette_len,
23387 const uint8_t* src_ptr,
23388 size_t src_len) {
23389 size_t dst_len2 = dst_len / 2;
23390 size_t src_len4 = src_len / 4;
23391 size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
23392 uint8_t* d = dst_ptr;
23393 const uint8_t* s = src_ptr;
23394 size_t n = len;
23396 // TODO: unroll.
23398 while (n >= 1) {
23399 wuffs_base__poke_u16le__no_bounds_check(
23400 d + (0 * 2), wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
23401 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))));
23403 s += 1 * 4;
23404 d += 1 * 2;
23405 n -= 1;
23408 return len;
23411 static uint64_t //
23412 wuffs_private_impl__swizzle_bgr_565__bgra_premul__src_over(
23413 uint8_t* dst_ptr,
23414 size_t dst_len,
23415 uint8_t* dst_palette_ptr,
23416 size_t dst_palette_len,
23417 const uint8_t* src_ptr,
23418 size_t src_len) {
23419 size_t dst_len2 = dst_len / 2;
23420 size_t src_len4 = src_len / 4;
23421 size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
23422 uint8_t* d = dst_ptr;
23423 const uint8_t* s = src_ptr;
23424 size_t n = len;
23426 // TODO: unroll.
23428 while (n >= 1) {
23429 // Extract 16-bit color components.
23430 uint32_t sa = 0x101 * ((uint32_t)s[3]);
23431 uint32_t sr = 0x101 * ((uint32_t)s[2]);
23432 uint32_t sg = 0x101 * ((uint32_t)s[1]);
23433 uint32_t sb = 0x101 * ((uint32_t)s[0]);
23435 // Convert from 565 color to 16-bit color.
23436 uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2));
23437 uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11);
23438 uint32_t dr = (0x8421 * old_r5) >> 4;
23439 uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5);
23440 uint32_t dg = (0x1041 * old_g6) >> 2;
23441 uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0);
23442 uint32_t db = (0x8421 * old_b5) >> 4;
23444 // Calculate the inverse of the src-alpha: how much of the dst to keep.
23445 uint32_t ia = 0xFFFF - sa;
23447 // Composite src (premul) over dst (premul).
23448 dr = sr + ((dr * ia) / 0xFFFF);
23449 dg = sg + ((dg * ia) / 0xFFFF);
23450 db = sb + ((db * ia) / 0xFFFF);
23452 // Convert from 16-bit color to 565 color and combine the components.
23453 uint32_t new_r5 = 0x1F & (dr >> 11);
23454 uint32_t new_g6 = 0x3F & (dg >> 10);
23455 uint32_t new_b5 = 0x1F & (db >> 11);
23456 uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0);
23457 wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565);
23459 s += 1 * 4;
23460 d += 1 * 2;
23461 n -= 1;
23464 return len;
23467 static uint64_t //
23468 wuffs_private_impl__swizzle_bgr_565__rgb(uint8_t* dst_ptr,
23469 size_t dst_len,
23470 uint8_t* dst_palette_ptr,
23471 size_t dst_palette_len,
23472 const uint8_t* src_ptr,
23473 size_t src_len) {
23474 size_t dst_len2 = dst_len / 2;
23475 size_t src_len3 = src_len / 3;
23476 size_t len = (dst_len2 < src_len3) ? dst_len2 : src_len3;
23477 uint8_t* d = dst_ptr;
23478 const uint8_t* s = src_ptr;
23479 size_t n = len;
23481 // TODO: unroll.
23483 while (n >= 1) {
23484 uint32_t r5 = (uint32_t)(s[0] >> 3);
23485 uint32_t g6 = (uint32_t)(s[1] >> 2);
23486 uint32_t b5 = (uint32_t)(s[2] >> 3);
23487 uint32_t rgb_565 = (r5 << 11) | (g6 << 5) | (b5 << 0);
23488 wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565);
23490 s += 1 * 3;
23491 d += 1 * 2;
23492 n -= 1;
23495 return len;
23498 static uint64_t //
23499 wuffs_private_impl__swizzle_bgr_565__rgba_nonpremul__src(
23500 uint8_t* dst_ptr,
23501 size_t dst_len,
23502 uint8_t* dst_palette_ptr,
23503 size_t dst_palette_len,
23504 const uint8_t* src_ptr,
23505 size_t src_len) {
23506 size_t dst_len2 = dst_len / 2;
23507 size_t src_len4 = src_len / 4;
23508 size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
23509 uint8_t* d = dst_ptr;
23510 const uint8_t* s = src_ptr;
23511 size_t n = len;
23513 // TODO: unroll.
23515 while (n >= 1) {
23516 wuffs_base__poke_u16le__no_bounds_check(
23517 d + (0 * 2),
23518 wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
23519 wuffs_private_impl__swap_u32_argb_abgr(
23520 wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
23521 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))))));
23523 s += 1 * 4;
23524 d += 1 * 2;
23525 n -= 1;
23528 return len;
23531 static uint64_t //
23532 wuffs_private_impl__swizzle_bgr_565__rgba_nonpremul__src_over(
23533 uint8_t* dst_ptr,
23534 size_t dst_len,
23535 uint8_t* dst_palette_ptr,
23536 size_t dst_palette_len,
23537 const uint8_t* src_ptr,
23538 size_t src_len) {
23539 size_t dst_len2 = dst_len / 2;
23540 size_t src_len4 = src_len / 4;
23541 size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
23542 uint8_t* d = dst_ptr;
23543 const uint8_t* s = src_ptr;
23544 size_t n = len;
23546 // TODO: unroll.
23548 while (n >= 1) {
23549 // Extract 16-bit color components.
23550 uint32_t sa = 0x101 * ((uint32_t)s[3]);
23551 uint32_t sb = 0x101 * ((uint32_t)s[2]);
23552 uint32_t sg = 0x101 * ((uint32_t)s[1]);
23553 uint32_t sr = 0x101 * ((uint32_t)s[0]);
23555 // Convert from 565 color to 16-bit color.
23556 uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2));
23557 uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11);
23558 uint32_t dr = (0x8421 * old_r5) >> 4;
23559 uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5);
23560 uint32_t dg = (0x1041 * old_g6) >> 2;
23561 uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0);
23562 uint32_t db = (0x8421 * old_b5) >> 4;
23564 // Calculate the inverse of the src-alpha: how much of the dst to keep.
23565 uint32_t ia = 0xFFFF - sa;
23567 // Composite src (nonpremul) over dst (premul).
23568 dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
23569 dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
23570 db = ((sb * sa) + (db * ia)) / 0xFFFF;
23572 // Convert from 16-bit color to 565 color and combine the components.
23573 uint32_t new_r5 = 0x1F & (dr >> 11);
23574 uint32_t new_g6 = 0x3F & (dg >> 10);
23575 uint32_t new_b5 = 0x1F & (db >> 11);
23576 uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0);
23577 wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565);
23579 s += 1 * 4;
23580 d += 1 * 2;
23581 n -= 1;
23584 return len;
23587 static uint64_t //
23588 wuffs_private_impl__swizzle_bgr_565__rgba_premul__src(uint8_t* dst_ptr,
23589 size_t dst_len,
23590 uint8_t* dst_palette_ptr,
23591 size_t dst_palette_len,
23592 const uint8_t* src_ptr,
23593 size_t src_len) {
23594 size_t dst_len2 = dst_len / 2;
23595 size_t src_len4 = src_len / 4;
23596 size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
23597 uint8_t* d = dst_ptr;
23598 const uint8_t* s = src_ptr;
23599 size_t n = len;
23601 // TODO: unroll.
23603 while (n >= 1) {
23604 wuffs_base__poke_u16le__no_bounds_check(
23605 d + (0 * 2),
23606 wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
23607 wuffs_private_impl__swap_u32_argb_abgr(
23608 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)))));
23610 s += 1 * 4;
23611 d += 1 * 2;
23612 n -= 1;
23615 return len;
23618 static uint64_t //
23619 wuffs_private_impl__swizzle_bgr_565__rgba_premul__src_over(
23620 uint8_t* dst_ptr,
23621 size_t dst_len,
23622 uint8_t* dst_palette_ptr,
23623 size_t dst_palette_len,
23624 const uint8_t* src_ptr,
23625 size_t src_len) {
23626 size_t dst_len2 = dst_len / 2;
23627 size_t src_len4 = src_len / 4;
23628 size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
23629 uint8_t* d = dst_ptr;
23630 const uint8_t* s = src_ptr;
23631 size_t n = len;
23633 // TODO: unroll.
23635 while (n >= 1) {
23636 // Extract 16-bit color components.
23637 uint32_t sa = 0x101 * ((uint32_t)s[3]);
23638 uint32_t sb = 0x101 * ((uint32_t)s[2]);
23639 uint32_t sg = 0x101 * ((uint32_t)s[1]);
23640 uint32_t sr = 0x101 * ((uint32_t)s[0]);
23642 // Convert from 565 color to 16-bit color.
23643 uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2));
23644 uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11);
23645 uint32_t dr = (0x8421 * old_r5) >> 4;
23646 uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5);
23647 uint32_t dg = (0x1041 * old_g6) >> 2;
23648 uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0);
23649 uint32_t db = (0x8421 * old_b5) >> 4;
23651 // Calculate the inverse of the src-alpha: how much of the dst to keep.
23652 uint32_t ia = 0xFFFF - sa;
23654 // Composite src (premul) over dst (premul).
23655 dr = sr + ((dr * ia) / 0xFFFF);
23656 dg = sg + ((dg * ia) / 0xFFFF);
23657 db = sb + ((db * ia) / 0xFFFF);
23659 // Convert from 16-bit color to 565 color and combine the components.
23660 uint32_t new_r5 = 0x1F & (dr >> 11);
23661 uint32_t new_g6 = 0x3F & (dg >> 10);
23662 uint32_t new_b5 = 0x1F & (db >> 11);
23663 uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0);
23664 wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565);
23666 s += 1 * 4;
23667 d += 1 * 2;
23668 n -= 1;
23671 return len;
23674 static uint64_t //
23675 wuffs_private_impl__swizzle_bgr_565__y(uint8_t* dst_ptr,
23676 size_t dst_len,
23677 uint8_t* dst_palette_ptr,
23678 size_t dst_palette_len,
23679 const uint8_t* src_ptr,
23680 size_t src_len) {
23681 size_t dst_len2 = dst_len / 2;
23682 size_t len = (dst_len2 < src_len) ? dst_len2 : src_len;
23683 uint8_t* d = dst_ptr;
23684 const uint8_t* s = src_ptr;
23685 size_t n = len;
23687 // TODO: unroll.
23689 while (n >= 1) {
23690 uint32_t y5 = (uint32_t)(s[0] >> 3);
23691 uint32_t y6 = (uint32_t)(s[0] >> 2);
23692 uint32_t rgb_565 = (y5 << 11) | (y6 << 5) | (y5 << 0);
23693 wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565);
23695 s += 1 * 1;
23696 d += 1 * 2;
23697 n -= 1;
23700 return len;
23703 static uint64_t //
23704 wuffs_private_impl__swizzle_bgr_565__y_16be(uint8_t* dst_ptr,
23705 size_t dst_len,
23706 uint8_t* dst_palette_ptr,
23707 size_t dst_palette_len,
23708 const uint8_t* src_ptr,
23709 size_t src_len) {
23710 size_t dst_len2 = dst_len / 2;
23711 size_t src_len2 = src_len / 2;
23712 size_t len = (dst_len2 < src_len2) ? dst_len2 : src_len2;
23713 uint8_t* d = dst_ptr;
23714 const uint8_t* s = src_ptr;
23715 size_t n = len;
23717 // TODO: unroll.
23719 while (n >= 1) {
23720 uint32_t y5 = (uint32_t)(s[0] >> 3);
23721 uint32_t y6 = (uint32_t)(s[0] >> 2);
23722 uint32_t rgb_565 = (y5 << 11) | (y6 << 5) | (y5 << 0);
23723 wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565);
23725 s += 1 * 2;
23726 d += 1 * 2;
23727 n -= 1;
23730 return len;
23733 static uint64_t //
23734 wuffs_private_impl__swizzle_bgr_565__ya_nonpremul__src(uint8_t* dst_ptr,
23735 size_t dst_len,
23736 uint8_t* dst_palette_ptr,
23737 size_t dst_palette_len,
23738 const uint8_t* src_ptr,
23739 size_t src_len) {
23740 size_t dst_len2 = dst_len / 2;
23741 size_t src_len2 = src_len / 2;
23742 size_t len = (dst_len2 < src_len2) ? dst_len2 : src_len2;
23743 uint8_t* d = dst_ptr;
23744 const uint8_t* s = src_ptr;
23745 size_t n = len;
23747 // TODO: unroll.
23749 while (n >= 1) {
23750 uint32_t s0 = ((uint32_t)(s[1]) << 24) | ((uint32_t)(s[0]) * 0x010101);
23752 wuffs_base__poke_u16le__no_bounds_check(
23753 d + (0 * 2),
23754 wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
23755 wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
23756 s0)));
23758 s += 1 * 2;
23759 d += 1 * 2;
23760 n -= 1;
23763 return len;
23766 static uint64_t //
23767 wuffs_private_impl__swizzle_bgr_565__ya_nonpremul__src_over(
23768 uint8_t* dst_ptr,
23769 size_t dst_len,
23770 uint8_t* dst_palette_ptr,
23771 size_t dst_palette_len,
23772 const uint8_t* src_ptr,
23773 size_t src_len) {
23774 size_t dst_len2 = dst_len / 2;
23775 size_t src_len2 = src_len / 2;
23776 size_t len = (dst_len2 < src_len2) ? dst_len2 : src_len2;
23777 uint8_t* d = dst_ptr;
23778 const uint8_t* s = src_ptr;
23779 size_t n = len;
23781 // TODO: unroll.
23783 while (n >= 1) {
23784 // Extract 16-bit color components.
23785 uint32_t sa = 0x101 * ((uint32_t)s[1]);
23786 uint32_t sy = 0x101 * ((uint32_t)s[0]);
23788 // Convert from 565 color to 16-bit color.
23789 uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2));
23790 uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11);
23791 uint32_t dr = (0x8421 * old_r5) >> 4;
23792 uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5);
23793 uint32_t dg = (0x1041 * old_g6) >> 2;
23794 uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0);
23795 uint32_t db = (0x8421 * old_b5) >> 4;
23797 // Calculate the inverse of the src-alpha: how much of the dst to keep.
23798 uint32_t ia = 0xFFFF - sa;
23800 // Composite src (nonpremul) over dst (premul).
23801 dr = ((sy * sa) + (dr * ia)) / 0xFFFF;
23802 dg = ((sy * sa) + (dg * ia)) / 0xFFFF;
23803 db = ((sy * sa) + (db * ia)) / 0xFFFF;
23805 // Convert from 16-bit color to 565 color and combine the components.
23806 uint32_t new_r5 = 0x1F & (dr >> 11);
23807 uint32_t new_g6 = 0x3F & (dg >> 10);
23808 uint32_t new_b5 = 0x1F & (db >> 11);
23809 uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0);
23810 wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565);
23812 s += 1 * 2;
23813 d += 1 * 2;
23814 n -= 1;
23817 return len;
23820 static uint64_t //
23821 wuffs_private_impl__swizzle_bgr_565__index__src(uint8_t* dst_ptr,
23822 size_t dst_len,
23823 uint8_t* dst_palette_ptr,
23824 size_t dst_palette_len,
23825 const uint8_t* src_ptr,
23826 size_t src_len) {
23827 if (dst_palette_len !=
23828 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
23829 return 0;
23831 size_t dst_len2 = dst_len / 2;
23832 size_t len = (dst_len2 < src_len) ? dst_len2 : src_len;
23833 uint8_t* d = dst_ptr;
23834 const uint8_t* s = src_ptr;
23835 size_t n = len;
23837 const size_t loop_unroll_count = 4;
23839 while (n >= loop_unroll_count) {
23840 wuffs_base__poke_u16le__no_bounds_check(
23841 d + (0 * 2), wuffs_base__peek_u16le__no_bounds_check(
23842 dst_palette_ptr + ((size_t)s[0] * 4)));
23843 wuffs_base__poke_u16le__no_bounds_check(
23844 d + (1 * 2), wuffs_base__peek_u16le__no_bounds_check(
23845 dst_palette_ptr + ((size_t)s[1] * 4)));
23846 wuffs_base__poke_u16le__no_bounds_check(
23847 d + (2 * 2), wuffs_base__peek_u16le__no_bounds_check(
23848 dst_palette_ptr + ((size_t)s[2] * 4)));
23849 wuffs_base__poke_u16le__no_bounds_check(
23850 d + (3 * 2), wuffs_base__peek_u16le__no_bounds_check(
23851 dst_palette_ptr + ((size_t)s[3] * 4)));
23853 s += loop_unroll_count * 1;
23854 d += loop_unroll_count * 2;
23855 n -= loop_unroll_count;
23858 while (n >= 1) {
23859 wuffs_base__poke_u16le__no_bounds_check(
23860 d + (0 * 2), wuffs_base__peek_u16le__no_bounds_check(
23861 dst_palette_ptr + ((size_t)s[0] * 4)));
23863 s += 1 * 1;
23864 d += 1 * 2;
23865 n -= 1;
23868 return len;
23871 static uint64_t //
23872 wuffs_private_impl__swizzle_bgr_565__index_bgra_nonpremul__src_over(
23873 uint8_t* dst_ptr,
23874 size_t dst_len,
23875 uint8_t* dst_palette_ptr,
23876 size_t dst_palette_len,
23877 const uint8_t* src_ptr,
23878 size_t src_len) {
23879 if (dst_palette_len !=
23880 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
23881 return 0;
23883 size_t dst_len2 = dst_len / 2;
23884 size_t len = (dst_len2 < src_len) ? dst_len2 : src_len;
23885 uint8_t* d = dst_ptr;
23886 const uint8_t* s = src_ptr;
23887 size_t n = len;
23889 // TODO: unroll.
23891 while (n >= 1) {
23892 uint32_t d0 = wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
23893 wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2)));
23894 uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
23895 ((size_t)s[0] * 4));
23896 wuffs_base__poke_u16le__no_bounds_check(
23897 d + (0 * 2),
23898 wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
23899 wuffs_private_impl__composite_premul_nonpremul_u32_axxx(d0, s0)));
23901 s += 1 * 1;
23902 d += 1 * 2;
23903 n -= 1;
23906 return len;
23909 static uint64_t //
23910 wuffs_private_impl__swizzle_bgr_565__index_binary_alpha__src_over(
23911 uint8_t* dst_ptr,
23912 size_t dst_len,
23913 uint8_t* dst_palette_ptr,
23914 size_t dst_palette_len,
23915 const uint8_t* src_ptr,
23916 size_t src_len) {
23917 if (dst_palette_len !=
23918 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
23919 return 0;
23921 size_t dst_len2 = dst_len / 2;
23922 size_t len = (dst_len2 < src_len) ? dst_len2 : src_len;
23923 uint8_t* d = dst_ptr;
23924 const uint8_t* s = src_ptr;
23925 size_t n = len;
23927 // TODO: unroll.
23929 while (n >= 1) {
23930 uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
23931 ((size_t)s[0] * 4));
23932 if (s0) {
23933 wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)s0);
23936 s += 1 * 1;
23937 d += 1 * 2;
23938 n -= 1;
23941 return len;
23944 // --------
23946 static uint64_t //
23947 wuffs_private_impl__swizzle_bgr__bgr_565(uint8_t* dst_ptr,
23948 size_t dst_len,
23949 uint8_t* dst_palette_ptr,
23950 size_t dst_palette_len,
23951 const uint8_t* src_ptr,
23952 size_t src_len) {
23953 size_t dst_len3 = dst_len / 3;
23954 size_t src_len2 = src_len / 2;
23955 size_t len = (dst_len3 < src_len2) ? dst_len3 : src_len2;
23956 uint8_t* d = dst_ptr;
23957 const uint8_t* s = src_ptr;
23958 size_t n = len;
23960 // TODO: unroll.
23962 while (n >= 1) {
23963 uint32_t s0 = wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
23964 wuffs_base__peek_u16le__no_bounds_check(s + (0 * 2)));
23965 wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
23967 s += 1 * 2;
23968 d += 1 * 3;
23969 n -= 1;
23972 return len;
23975 static uint64_t //
23976 wuffs_private_impl__swizzle_bgr__bgra_nonpremul__src(uint8_t* dst_ptr,
23977 size_t dst_len,
23978 uint8_t* dst_palette_ptr,
23979 size_t dst_palette_len,
23980 const uint8_t* src_ptr,
23981 size_t src_len) {
23982 size_t dst_len3 = dst_len / 3;
23983 size_t src_len4 = src_len / 4;
23984 size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
23985 uint8_t* d = dst_ptr;
23986 const uint8_t* s = src_ptr;
23987 size_t n = len;
23989 // TODO: unroll.
23991 while (n >= 1) {
23992 uint32_t s0 =
23993 wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
23994 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
23995 wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
23997 s += 1 * 4;
23998 d += 1 * 3;
23999 n -= 1;
24002 return len;
24005 static uint64_t //
24006 wuffs_private_impl__swizzle_bgr__bgra_nonpremul_4x16le__src(
24007 uint8_t* dst_ptr,
24008 size_t dst_len,
24009 uint8_t* dst_palette_ptr,
24010 size_t dst_palette_len,
24011 const uint8_t* src_ptr,
24012 size_t src_len) {
24013 size_t dst_len3 = dst_len / 3;
24014 size_t src_len8 = src_len / 8;
24015 size_t len = (dst_len3 < src_len8) ? dst_len3 : src_len8;
24016 uint8_t* d = dst_ptr;
24017 const uint8_t* s = src_ptr;
24018 size_t n = len;
24020 // TODO: unroll.
24022 while (n >= 1) {
24023 uint32_t s0 =
24024 wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(
24025 wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)));
24026 wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
24028 s += 1 * 8;
24029 d += 1 * 3;
24030 n -= 1;
24033 return len;
24036 static uint64_t //
24037 wuffs_private_impl__swizzle_bgr__bgra_nonpremul__src_over(
24038 uint8_t* dst_ptr,
24039 size_t dst_len,
24040 uint8_t* dst_palette_ptr,
24041 size_t dst_palette_len,
24042 const uint8_t* src_ptr,
24043 size_t src_len) {
24044 size_t dst_len3 = dst_len / 3;
24045 size_t src_len4 = src_len / 4;
24046 size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
24047 uint8_t* d = dst_ptr;
24048 const uint8_t* s = src_ptr;
24049 size_t n = len;
24051 // TODO: unroll.
24053 while (n >= 1) {
24054 // Extract 16-bit color components.
24055 uint32_t dr = 0x101 * ((uint32_t)d[2]);
24056 uint32_t dg = 0x101 * ((uint32_t)d[1]);
24057 uint32_t db = 0x101 * ((uint32_t)d[0]);
24058 uint32_t sa = 0x101 * ((uint32_t)s[3]);
24059 uint32_t sr = 0x101 * ((uint32_t)s[2]);
24060 uint32_t sg = 0x101 * ((uint32_t)s[1]);
24061 uint32_t sb = 0x101 * ((uint32_t)s[0]);
24063 // Calculate the inverse of the src-alpha: how much of the dst to keep.
24064 uint32_t ia = 0xFFFF - sa;
24066 // Composite src (nonpremul) over dst (premul).
24067 dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
24068 dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
24069 db = ((sb * sa) + (db * ia)) / 0xFFFF;
24071 // Convert from 16-bit color to 8-bit color.
24072 d[0] = (uint8_t)(db >> 8);
24073 d[1] = (uint8_t)(dg >> 8);
24074 d[2] = (uint8_t)(dr >> 8);
24076 s += 1 * 4;
24077 d += 1 * 3;
24078 n -= 1;
24081 return len;
24084 static uint64_t //
24085 wuffs_private_impl__swizzle_bgr__bgra_nonpremul_4x16le__src_over(
24086 uint8_t* dst_ptr,
24087 size_t dst_len,
24088 uint8_t* dst_palette_ptr,
24089 size_t dst_palette_len,
24090 const uint8_t* src_ptr,
24091 size_t src_len) {
24092 size_t dst_len3 = dst_len / 3;
24093 size_t src_len8 = src_len / 8;
24094 size_t len = (dst_len3 < src_len8) ? dst_len3 : src_len8;
24095 uint8_t* d = dst_ptr;
24096 const uint8_t* s = src_ptr;
24097 size_t n = len;
24099 // TODO: unroll.
24101 while (n >= 1) {
24102 // Extract 16-bit color components.
24103 uint32_t dr = 0x101 * ((uint32_t)d[2]);
24104 uint32_t dg = 0x101 * ((uint32_t)d[1]);
24105 uint32_t db = 0x101 * ((uint32_t)d[0]);
24106 uint32_t sa = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 6));
24107 uint32_t sr = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 4));
24108 uint32_t sg = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 2));
24109 uint32_t sb = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 0));
24111 // Calculate the inverse of the src-alpha: how much of the dst to keep.
24112 uint32_t ia = 0xFFFF - sa;
24114 // Composite src (nonpremul) over dst (premul).
24115 dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
24116 dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
24117 db = ((sb * sa) + (db * ia)) / 0xFFFF;
24119 // Convert from 16-bit color to 8-bit color.
24120 d[0] = (uint8_t)(db >> 8);
24121 d[1] = (uint8_t)(dg >> 8);
24122 d[2] = (uint8_t)(dr >> 8);
24124 s += 1 * 8;
24125 d += 1 * 3;
24126 n -= 1;
24129 return len;
24132 static uint64_t //
24133 wuffs_private_impl__swizzle_bgr__bgra_premul__src(uint8_t* dst_ptr,
24134 size_t dst_len,
24135 uint8_t* dst_palette_ptr,
24136 size_t dst_palette_len,
24137 const uint8_t* src_ptr,
24138 size_t src_len) {
24139 size_t dst_len3 = dst_len / 3;
24140 size_t src_len4 = src_len / 4;
24141 size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
24142 uint8_t* d = dst_ptr;
24143 const uint8_t* s = src_ptr;
24144 size_t n = len;
24146 while (n >= 1) {
24147 uint8_t s0 = s[0];
24148 uint8_t s1 = s[1];
24149 uint8_t s2 = s[2];
24150 d[0] = s0;
24151 d[1] = s1;
24152 d[2] = s2;
24154 s += 1 * 4;
24155 d += 1 * 3;
24156 n -= 1;
24159 return len;
24162 static uint64_t //
24163 wuffs_private_impl__swizzle_bgr__bgra_premul__src_over(uint8_t* dst_ptr,
24164 size_t dst_len,
24165 uint8_t* dst_palette_ptr,
24166 size_t dst_palette_len,
24167 const uint8_t* src_ptr,
24168 size_t src_len) {
24169 size_t dst_len3 = dst_len / 3;
24170 size_t src_len4 = src_len / 4;
24171 size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
24172 uint8_t* d = dst_ptr;
24173 const uint8_t* s = src_ptr;
24174 size_t n = len;
24176 while (n >= 1) {
24177 // Extract 16-bit color components.
24178 uint32_t dr = 0x101 * ((uint32_t)d[2]);
24179 uint32_t dg = 0x101 * ((uint32_t)d[1]);
24180 uint32_t db = 0x101 * ((uint32_t)d[0]);
24181 uint32_t sa = 0x101 * ((uint32_t)s[3]);
24182 uint32_t sr = 0x101 * ((uint32_t)s[2]);
24183 uint32_t sg = 0x101 * ((uint32_t)s[1]);
24184 uint32_t sb = 0x101 * ((uint32_t)s[0]);
24186 // Calculate the inverse of the src-alpha: how much of the dst to keep.
24187 uint32_t ia = 0xFFFF - sa;
24189 // Composite src (premul) over dst (premul).
24190 dr = sr + ((dr * ia) / 0xFFFF);
24191 dg = sg + ((dg * ia) / 0xFFFF);
24192 db = sb + ((db * ia) / 0xFFFF);
24194 // Convert from 16-bit color to 8-bit color.
24195 d[0] = (uint8_t)(db >> 8);
24196 d[1] = (uint8_t)(dg >> 8);
24197 d[2] = (uint8_t)(dr >> 8);
24199 s += 1 * 4;
24200 d += 1 * 3;
24201 n -= 1;
24204 return len;
24207 static uint64_t //
24208 wuffs_private_impl__swizzle_bgr__rgba_nonpremul__src(uint8_t* dst_ptr,
24209 size_t dst_len,
24210 uint8_t* dst_palette_ptr,
24211 size_t dst_palette_len,
24212 const uint8_t* src_ptr,
24213 size_t src_len) {
24214 size_t dst_len3 = dst_len / 3;
24215 size_t src_len4 = src_len / 4;
24216 size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
24217 uint8_t* d = dst_ptr;
24218 const uint8_t* s = src_ptr;
24219 size_t n = len;
24221 // TODO: unroll.
24223 while (n >= 1) {
24224 uint32_t s0 = wuffs_private_impl__swap_u32_argb_abgr(
24225 wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
24226 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))));
24227 wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
24229 s += 1 * 4;
24230 d += 1 * 3;
24231 n -= 1;
24234 return len;
24237 static uint64_t //
24238 wuffs_private_impl__swizzle_bgr__rgba_nonpremul_4x16le__src(
24239 uint8_t* dst_ptr,
24240 size_t dst_len,
24241 uint8_t* dst_palette_ptr,
24242 size_t dst_palette_len,
24243 const uint8_t* src_ptr,
24244 size_t src_len) {
24245 size_t dst_len3 = dst_len / 3;
24246 size_t src_len8 = src_len / 8;
24247 size_t len = (dst_len3 < src_len8) ? dst_len3 : src_len8;
24248 uint8_t* d = dst_ptr;
24249 const uint8_t* s = src_ptr;
24250 size_t n = len;
24252 // TODO: unroll.
24254 while (n >= 1) {
24255 uint32_t s0 = wuffs_private_impl__swap_u32_argb_abgr(
24256 wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(
24257 wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8))));
24258 wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
24260 s += 1 * 8;
24261 d += 1 * 3;
24262 n -= 1;
24265 return len;
24268 static uint64_t //
24269 wuffs_private_impl__swizzle_bgr__rgba_nonpremul__src_over(
24270 uint8_t* dst_ptr,
24271 size_t dst_len,
24272 uint8_t* dst_palette_ptr,
24273 size_t dst_palette_len,
24274 const uint8_t* src_ptr,
24275 size_t src_len) {
24276 size_t dst_len3 = dst_len / 3;
24277 size_t src_len4 = src_len / 4;
24278 size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
24279 uint8_t* d = dst_ptr;
24280 const uint8_t* s = src_ptr;
24281 size_t n = len;
24283 // TODO: unroll.
24285 while (n >= 1) {
24286 // Extract 16-bit color components.
24287 uint32_t dr = 0x101 * ((uint32_t)d[2]);
24288 uint32_t dg = 0x101 * ((uint32_t)d[1]);
24289 uint32_t db = 0x101 * ((uint32_t)d[0]);
24290 uint32_t sa = 0x101 * ((uint32_t)s[3]);
24291 uint32_t sb = 0x101 * ((uint32_t)s[2]);
24292 uint32_t sg = 0x101 * ((uint32_t)s[1]);
24293 uint32_t sr = 0x101 * ((uint32_t)s[0]);
24295 // Calculate the inverse of the src-alpha: how much of the dst to keep.
24296 uint32_t ia = 0xFFFF - sa;
24298 // Composite src (nonpremul) over dst (premul).
24299 dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
24300 dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
24301 db = ((sb * sa) + (db * ia)) / 0xFFFF;
24303 // Convert from 16-bit color to 8-bit color.
24304 d[0] = (uint8_t)(db >> 8);
24305 d[1] = (uint8_t)(dg >> 8);
24306 d[2] = (uint8_t)(dr >> 8);
24308 s += 1 * 4;
24309 d += 1 * 3;
24310 n -= 1;
24313 return len;
24316 static uint64_t //
24317 wuffs_private_impl__swizzle_bgr__rgba_nonpremul_4x16le__src_over(
24318 uint8_t* dst_ptr,
24319 size_t dst_len,
24320 uint8_t* dst_palette_ptr,
24321 size_t dst_palette_len,
24322 const uint8_t* src_ptr,
24323 size_t src_len) {
24324 size_t dst_len3 = dst_len / 3;
24325 size_t src_len8 = src_len / 8;
24326 size_t len = (dst_len3 < src_len8) ? dst_len3 : src_len8;
24327 uint8_t* d = dst_ptr;
24328 const uint8_t* s = src_ptr;
24329 size_t n = len;
24331 // TODO: unroll.
24333 while (n >= 1) {
24334 // Extract 16-bit color components.
24335 uint32_t dr = 0x101 * ((uint32_t)d[2]);
24336 uint32_t dg = 0x101 * ((uint32_t)d[1]);
24337 uint32_t db = 0x101 * ((uint32_t)d[0]);
24338 uint32_t sa = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 6));
24339 uint32_t sb = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 4));
24340 uint32_t sg = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 2));
24341 uint32_t sr = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 0));
24343 // Calculate the inverse of the src-alpha: how much of the dst to keep.
24344 uint32_t ia = 0xFFFF - sa;
24346 // Composite src (nonpremul) over dst (premul).
24347 dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
24348 dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
24349 db = ((sb * sa) + (db * ia)) / 0xFFFF;
24351 // Convert from 16-bit color to 8-bit color.
24352 d[0] = (uint8_t)(db >> 8);
24353 d[1] = (uint8_t)(dg >> 8);
24354 d[2] = (uint8_t)(dr >> 8);
24356 s += 1 * 8;
24357 d += 1 * 3;
24358 n -= 1;
24361 return len;
24364 static uint64_t //
24365 wuffs_private_impl__swizzle_bgr__rgba_premul__src(uint8_t* dst_ptr,
24366 size_t dst_len,
24367 uint8_t* dst_palette_ptr,
24368 size_t dst_palette_len,
24369 const uint8_t* src_ptr,
24370 size_t src_len) {
24371 size_t dst_len3 = dst_len / 3;
24372 size_t src_len4 = src_len / 4;
24373 size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
24374 uint8_t* d = dst_ptr;
24375 const uint8_t* s = src_ptr;
24376 size_t n = len;
24378 while (n >= 1) {
24379 uint8_t s0 = s[0];
24380 uint8_t s1 = s[1];
24381 uint8_t s2 = s[2];
24382 d[0] = s2;
24383 d[1] = s1;
24384 d[2] = s0;
24386 s += 1 * 4;
24387 d += 1 * 3;
24388 n -= 1;
24391 return len;
24394 static uint64_t //
24395 wuffs_private_impl__swizzle_bgr__rgba_premul__src_over(uint8_t* dst_ptr,
24396 size_t dst_len,
24397 uint8_t* dst_palette_ptr,
24398 size_t dst_palette_len,
24399 const uint8_t* src_ptr,
24400 size_t src_len) {
24401 size_t dst_len3 = dst_len / 3;
24402 size_t src_len4 = src_len / 4;
24403 size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
24404 uint8_t* d = dst_ptr;
24405 const uint8_t* s = src_ptr;
24406 size_t n = len;
24408 while (n >= 1) {
24409 // Extract 16-bit color components.
24410 uint32_t dr = 0x101 * ((uint32_t)d[2]);
24411 uint32_t dg = 0x101 * ((uint32_t)d[1]);
24412 uint32_t db = 0x101 * ((uint32_t)d[0]);
24413 uint32_t sa = 0x101 * ((uint32_t)s[3]);
24414 uint32_t sb = 0x101 * ((uint32_t)s[2]);
24415 uint32_t sg = 0x101 * ((uint32_t)s[1]);
24416 uint32_t sr = 0x101 * ((uint32_t)s[0]);
24418 // Calculate the inverse of the src-alpha: how much of the dst to keep.
24419 uint32_t ia = 0xFFFF - sa;
24421 // Composite src (premul) over dst (premul).
24422 dr = sr + ((dr * ia) / 0xFFFF);
24423 dg = sg + ((dg * ia) / 0xFFFF);
24424 db = sb + ((db * ia) / 0xFFFF);
24426 // Convert from 16-bit color to 8-bit color.
24427 d[0] = (uint8_t)(db >> 8);
24428 d[1] = (uint8_t)(dg >> 8);
24429 d[2] = (uint8_t)(dr >> 8);
24431 s += 1 * 4;
24432 d += 1 * 3;
24433 n -= 1;
24436 return len;
24439 static uint64_t //
24440 wuffs_private_impl__swizzle_bgr__rgbx(uint8_t* dst_ptr,
24441 size_t dst_len,
24442 uint8_t* dst_palette_ptr,
24443 size_t dst_palette_len,
24444 const uint8_t* src_ptr,
24445 size_t src_len) {
24446 size_t dst_len3 = dst_len / 3;
24447 size_t src_len4 = src_len / 4;
24448 size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
24449 uint8_t* d = dst_ptr;
24450 const uint8_t* s = src_ptr;
24451 size_t n = len;
24453 // TODO: unroll.
24455 while (n >= 1) {
24456 uint8_t b0 = s[0];
24457 uint8_t b1 = s[1];
24458 uint8_t b2 = s[2];
24459 d[0] = b2;
24460 d[1] = b1;
24461 d[2] = b0;
24463 s += 1 * 4;
24464 d += 1 * 3;
24465 n -= 1;
24468 return len;
24471 // --------
24473 static uint64_t //
24474 wuffs_private_impl__swizzle_bgra_nonpremul__bgra_nonpremul__src_over(
24475 uint8_t* dst_ptr,
24476 size_t dst_len,
24477 uint8_t* dst_palette_ptr,
24478 size_t dst_palette_len,
24479 const uint8_t* src_ptr,
24480 size_t src_len) {
24481 size_t dst_len4 = dst_len / 4;
24482 size_t src_len4 = src_len / 4;
24483 size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
24484 uint8_t* d = dst_ptr;
24485 const uint8_t* s = src_ptr;
24486 size_t n = len;
24488 while (n >= 1) {
24489 uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
24490 uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
24491 wuffs_base__poke_u32le__no_bounds_check(
24492 d + (0 * 4),
24493 wuffs_private_impl__composite_nonpremul_nonpremul_u32_axxx(d0, s0));
24495 s += 1 * 4;
24496 d += 1 * 4;
24497 n -= 1;
24500 return len;
24503 static uint64_t //
24504 wuffs_private_impl__swizzle_bgra_nonpremul__bgra_nonpremul_4x16le__src(
24505 uint8_t* dst_ptr,
24506 size_t dst_len,
24507 uint8_t* dst_palette_ptr,
24508 size_t dst_palette_len,
24509 const uint8_t* src_ptr,
24510 size_t src_len) {
24511 size_t dst_len4 = dst_len / 4;
24512 size_t src_len8 = src_len / 8;
24513 size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
24514 uint8_t* d = dst_ptr;
24515 const uint8_t* s = src_ptr;
24517 size_t n = len;
24518 while (n >= 1) {
24519 wuffs_base__poke_u32le__no_bounds_check(
24520 d + (0 * 4), wuffs_base__color_u64__as__color_u32(
24521 wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8))));
24523 s += 1 * 8;
24524 d += 1 * 4;
24525 n -= 1;
24527 return len;
24530 static uint64_t //
24531 wuffs_private_impl__swizzle_bgra_nonpremul__bgra_nonpremul_4x16le__src_over(
24532 uint8_t* dst_ptr,
24533 size_t dst_len,
24534 uint8_t* dst_palette_ptr,
24535 size_t dst_palette_len,
24536 const uint8_t* src_ptr,
24537 size_t src_len) {
24538 size_t dst_len4 = dst_len / 4;
24539 size_t src_len8 = src_len / 8;
24540 size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
24541 uint8_t* d = dst_ptr;
24542 const uint8_t* s = src_ptr;
24543 size_t n = len;
24545 while (n >= 1) {
24546 uint64_t d0 = wuffs_base__color_u32__as__color_u64(
24547 wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)));
24548 uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8));
24549 wuffs_base__poke_u32le__no_bounds_check(
24550 d + (0 * 4),
24551 wuffs_base__color_u64__as__color_u32(
24552 wuffs_private_impl__composite_nonpremul_nonpremul_u64_axxx(d0,
24553 s0)));
24555 s += 1 * 8;
24556 d += 1 * 4;
24557 n -= 1;
24560 return len;
24563 static uint64_t //
24564 wuffs_private_impl__swizzle_bgra_nonpremul__bgra_premul__src(
24565 uint8_t* dst_ptr,
24566 size_t dst_len,
24567 uint8_t* dst_palette_ptr,
24568 size_t dst_palette_len,
24569 const uint8_t* src_ptr,
24570 size_t src_len) {
24571 size_t dst_len4 = dst_len / 4;
24572 size_t src_len4 = src_len / 4;
24573 size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
24574 uint8_t* d = dst_ptr;
24575 const uint8_t* s = src_ptr;
24576 size_t n = len;
24578 while (n >= 1) {
24579 uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
24580 wuffs_base__poke_u32le__no_bounds_check(
24581 d + (0 * 4),
24582 wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(s0));
24584 s += 1 * 4;
24585 d += 1 * 4;
24586 n -= 1;
24589 return len;
24592 static uint64_t //
24593 wuffs_private_impl__swizzle_bgra_nonpremul__bgra_premul__src_over(
24594 uint8_t* dst_ptr,
24595 size_t dst_len,
24596 uint8_t* dst_palette_ptr,
24597 size_t dst_palette_len,
24598 const uint8_t* src_ptr,
24599 size_t src_len) {
24600 size_t dst_len4 = dst_len / 4;
24601 size_t src_len4 = src_len / 4;
24602 size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
24603 uint8_t* d = dst_ptr;
24604 const uint8_t* s = src_ptr;
24605 size_t n = len;
24607 while (n >= 1) {
24608 uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
24609 uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
24610 wuffs_base__poke_u32le__no_bounds_check(
24611 d + (0 * 4),
24612 wuffs_private_impl__composite_nonpremul_premul_u32_axxx(d0, s0));
24614 s += 1 * 4;
24615 d += 1 * 4;
24616 n -= 1;
24619 return len;
24622 static uint64_t //
24623 wuffs_private_impl__swizzle_bgra_nonpremul__index_bgra_nonpremul__src_over(
24624 uint8_t* dst_ptr,
24625 size_t dst_len,
24626 uint8_t* dst_palette_ptr,
24627 size_t dst_palette_len,
24628 const uint8_t* src_ptr,
24629 size_t src_len) {
24630 if (dst_palette_len !=
24631 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
24632 return 0;
24634 size_t dst_len4 = dst_len / 4;
24635 size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
24636 uint8_t* d = dst_ptr;
24637 const uint8_t* s = src_ptr;
24638 size_t n = len;
24640 // TODO: unroll.
24642 while (n >= 1) {
24643 uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
24644 uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
24645 ((size_t)s[0] * 4));
24646 wuffs_base__poke_u32le__no_bounds_check(
24647 d + (0 * 4),
24648 wuffs_private_impl__composite_nonpremul_nonpremul_u32_axxx(d0, s0));
24650 s += 1 * 1;
24651 d += 1 * 4;
24652 n -= 1;
24655 return len;
24658 static uint64_t //
24659 wuffs_private_impl__swizzle_bgra_nonpremul__rgba_nonpremul__src_over(
24660 uint8_t* dst_ptr,
24661 size_t dst_len,
24662 uint8_t* dst_palette_ptr,
24663 size_t dst_palette_len,
24664 const uint8_t* src_ptr,
24665 size_t src_len) {
24666 size_t dst_len4 = dst_len / 4;
24667 size_t src_len4 = src_len / 4;
24668 size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
24669 uint8_t* d = dst_ptr;
24670 const uint8_t* s = src_ptr;
24671 size_t n = len;
24673 while (n >= 1) {
24674 uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
24675 uint32_t s0 = wuffs_private_impl__swap_u32_argb_abgr(
24676 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
24677 wuffs_base__poke_u32le__no_bounds_check(
24678 d + (0 * 4),
24679 wuffs_private_impl__composite_nonpremul_nonpremul_u32_axxx(d0, s0));
24681 s += 1 * 4;
24682 d += 1 * 4;
24683 n -= 1;
24686 return len;
24689 static uint64_t //
24690 wuffs_private_impl__swizzle_bgra_nonpremul__rgba_premul__src(
24691 uint8_t* dst_ptr,
24692 size_t dst_len,
24693 uint8_t* dst_palette_ptr,
24694 size_t dst_palette_len,
24695 const uint8_t* src_ptr,
24696 size_t src_len) {
24697 size_t dst_len4 = dst_len / 4;
24698 size_t src_len4 = src_len / 4;
24699 size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
24700 uint8_t* d = dst_ptr;
24701 const uint8_t* s = src_ptr;
24702 size_t n = len;
24704 while (n >= 1) {
24705 uint32_t s0 = wuffs_private_impl__swap_u32_argb_abgr(
24706 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
24707 wuffs_base__poke_u32le__no_bounds_check(
24708 d + (0 * 4),
24709 wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(s0));
24711 s += 1 * 4;
24712 d += 1 * 4;
24713 n -= 1;
24716 return len;
24719 static uint64_t //
24720 wuffs_private_impl__swizzle_bgra_nonpremul__rgba_premul__src_over(
24721 uint8_t* dst_ptr,
24722 size_t dst_len,
24723 uint8_t* dst_palette_ptr,
24724 size_t dst_palette_len,
24725 const uint8_t* src_ptr,
24726 size_t src_len) {
24727 size_t dst_len4 = dst_len / 4;
24728 size_t src_len4 = src_len / 4;
24729 size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
24730 uint8_t* d = dst_ptr;
24731 const uint8_t* s = src_ptr;
24732 size_t n = len;
24734 while (n >= 1) {
24735 uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
24736 uint32_t s0 = wuffs_private_impl__swap_u32_argb_abgr(
24737 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
24738 wuffs_base__poke_u32le__no_bounds_check(
24739 d + (0 * 4),
24740 wuffs_private_impl__composite_nonpremul_premul_u32_axxx(d0, s0));
24742 s += 1 * 4;
24743 d += 1 * 4;
24744 n -= 1;
24747 return len;
24750 static uint64_t //
24751 wuffs_private_impl__swizzle_bgra_nonpremul__ya_nonpremul__src(
24752 uint8_t* dst_ptr,
24753 size_t dst_len,
24754 uint8_t* dst_palette_ptr,
24755 size_t dst_palette_len,
24756 const uint8_t* src_ptr,
24757 size_t src_len) {
24758 size_t dst_len4 = dst_len / 4;
24759 size_t src_len2 = src_len / 2;
24760 size_t len = (dst_len4 < src_len2) ? dst_len4 : src_len2;
24761 uint8_t* d = dst_ptr;
24762 const uint8_t* s = src_ptr;
24763 size_t n = len;
24765 // TODO: unroll.
24767 while (n >= 1) {
24768 uint32_t s0 = ((uint32_t)(s[1]) << 24) | ((uint32_t)(s[0]) * 0x010101);
24769 wuffs_base__poke_u32le__no_bounds_check(d + (0 * 4), s0);
24771 s += 1 * 2;
24772 d += 1 * 4;
24773 n -= 1;
24776 return len;
24779 static uint64_t //
24780 wuffs_private_impl__swizzle_bgra_nonpremul__ya_nonpremul__src_over(
24781 uint8_t* dst_ptr,
24782 size_t dst_len,
24783 uint8_t* dst_palette_ptr,
24784 size_t dst_palette_len,
24785 const uint8_t* src_ptr,
24786 size_t src_len) {
24787 size_t dst_len4 = dst_len / 4;
24788 size_t src_len2 = src_len / 2;
24789 size_t len = (dst_len4 < src_len2) ? dst_len4 : src_len2;
24790 uint8_t* d = dst_ptr;
24791 const uint8_t* s = src_ptr;
24792 size_t n = len;
24794 // TODO: unroll.
24796 while (n >= 1) {
24797 uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
24798 uint32_t s0 = ((uint32_t)(s[1]) << 24) | ((uint32_t)(s[0]) * 0x010101);
24799 wuffs_base__poke_u32le__no_bounds_check(
24800 d + (0 * 4),
24801 wuffs_private_impl__composite_nonpremul_nonpremul_u32_axxx(d0, s0));
24803 s += 1 * 2;
24804 d += 1 * 4;
24805 n -= 1;
24808 return len;
24811 // --------
24813 static uint64_t //
24814 wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__bgra_nonpremul__src(
24815 uint8_t* dst_ptr,
24816 size_t dst_len,
24817 uint8_t* dst_palette_ptr,
24818 size_t dst_palette_len,
24819 const uint8_t* src_ptr,
24820 size_t src_len) {
24821 size_t dst_len8 = dst_len / 8;
24822 size_t src_len4 = src_len / 4;
24823 size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
24824 uint8_t* d = dst_ptr;
24825 const uint8_t* s = src_ptr;
24827 size_t n = len;
24828 while (n >= 1) {
24829 uint8_t s0 = s[0];
24830 uint8_t s1 = s[1];
24831 uint8_t s2 = s[2];
24832 uint8_t s3 = s[3];
24833 d[0] = s0;
24834 d[1] = s0;
24835 d[2] = s1;
24836 d[3] = s1;
24837 d[4] = s2;
24838 d[5] = s2;
24839 d[6] = s3;
24840 d[7] = s3;
24842 s += 1 * 4;
24843 d += 1 * 8;
24844 n -= 1;
24846 return len;
24849 static uint64_t //
24850 wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__bgra_nonpremul__src_over(
24851 uint8_t* dst_ptr,
24852 size_t dst_len,
24853 uint8_t* dst_palette_ptr,
24854 size_t dst_palette_len,
24855 const uint8_t* src_ptr,
24856 size_t src_len) {
24857 size_t dst_len8 = dst_len / 8;
24858 size_t src_len4 = src_len / 4;
24859 size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
24860 uint8_t* d = dst_ptr;
24861 const uint8_t* s = src_ptr;
24863 size_t n = len;
24864 while (n >= 1) {
24865 uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8));
24866 uint64_t s0 = wuffs_base__color_u32__as__color_u64(
24867 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
24868 wuffs_base__poke_u64le__no_bounds_check(
24869 d + (0 * 8),
24870 wuffs_private_impl__composite_nonpremul_nonpremul_u64_axxx(d0, s0));
24872 s += 1 * 4;
24873 d += 1 * 8;
24874 n -= 1;
24876 return len;
24879 static uint64_t //
24880 wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__bgra_nonpremul_4x16le__src_over(
24881 uint8_t* dst_ptr,
24882 size_t dst_len,
24883 uint8_t* dst_palette_ptr,
24884 size_t dst_palette_len,
24885 const uint8_t* src_ptr,
24886 size_t src_len) {
24887 size_t dst_len8 = dst_len / 8;
24888 size_t src_len8 = src_len / 8;
24889 size_t len = (dst_len8 < src_len8) ? dst_len8 : src_len8;
24890 uint8_t* d = dst_ptr;
24891 const uint8_t* s = src_ptr;
24893 size_t n = len;
24894 while (n >= 1) {
24895 uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8));
24896 uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8));
24897 wuffs_base__poke_u64le__no_bounds_check(
24898 d + (0 * 8),
24899 wuffs_private_impl__composite_nonpremul_nonpremul_u64_axxx(d0, s0));
24901 s += 1 * 8;
24902 d += 1 * 8;
24903 n -= 1;
24905 return len;
24908 static uint64_t //
24909 wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__bgra_premul__src(
24910 uint8_t* dst_ptr,
24911 size_t dst_len,
24912 uint8_t* dst_palette_ptr,
24913 size_t dst_palette_len,
24914 const uint8_t* src_ptr,
24915 size_t src_len) {
24916 size_t dst_len8 = dst_len / 8;
24917 size_t src_len4 = src_len / 4;
24918 size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
24919 uint8_t* d = dst_ptr;
24920 const uint8_t* s = src_ptr;
24922 size_t n = len;
24923 while (n >= 1) {
24924 uint64_t s0 = wuffs_base__color_u32__as__color_u64(
24925 wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
24926 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))));
24927 wuffs_base__poke_u64le__no_bounds_check(d + (0 * 8), s0);
24929 s += 1 * 4;
24930 d += 1 * 8;
24931 n -= 1;
24933 return len;
24936 static uint64_t //
24937 wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__bgra_premul__src_over(
24938 uint8_t* dst_ptr,
24939 size_t dst_len,
24940 uint8_t* dst_palette_ptr,
24941 size_t dst_palette_len,
24942 const uint8_t* src_ptr,
24943 size_t src_len) {
24944 size_t dst_len8 = dst_len / 8;
24945 size_t src_len4 = src_len / 4;
24946 size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
24947 uint8_t* d = dst_ptr;
24948 const uint8_t* s = src_ptr;
24950 size_t n = len;
24951 while (n >= 1) {
24952 uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8));
24953 uint64_t s0 = wuffs_base__color_u32__as__color_u64(
24954 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
24955 wuffs_base__poke_u64le__no_bounds_check(
24956 d + (0 * 8),
24957 wuffs_private_impl__composite_nonpremul_premul_u64_axxx(d0, s0));
24959 s += 1 * 4;
24960 d += 1 * 8;
24961 n -= 1;
24963 return len;
24966 static uint64_t //
24967 wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__index_bgra_nonpremul__src_over(
24968 uint8_t* dst_ptr,
24969 size_t dst_len,
24970 uint8_t* dst_palette_ptr,
24971 size_t dst_palette_len,
24972 const uint8_t* src_ptr,
24973 size_t src_len) {
24974 if (dst_palette_len !=
24975 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
24976 return 0;
24978 size_t dst_len8 = dst_len / 8;
24979 size_t len = (dst_len8 < src_len) ? dst_len8 : src_len;
24980 uint8_t* d = dst_ptr;
24981 const uint8_t* s = src_ptr;
24982 size_t n = len;
24984 while (n >= 1) {
24985 uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8));
24986 uint64_t s0 = wuffs_base__color_u32__as__color_u64(
24987 wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
24988 ((size_t)s[0] * 4)));
24989 wuffs_base__poke_u64le__no_bounds_check(
24990 d + (0 * 8),
24991 wuffs_private_impl__composite_nonpremul_nonpremul_u64_axxx(d0, s0));
24993 s += 1 * 1;
24994 d += 1 * 8;
24995 n -= 1;
24998 return len;
25001 static uint64_t //
25002 wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__rgba_nonpremul__src(
25003 uint8_t* dst_ptr,
25004 size_t dst_len,
25005 uint8_t* dst_palette_ptr,
25006 size_t dst_palette_len,
25007 const uint8_t* src_ptr,
25008 size_t src_len) {
25009 size_t dst_len8 = dst_len / 8;
25010 size_t src_len4 = src_len / 4;
25011 size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
25012 uint8_t* d = dst_ptr;
25013 const uint8_t* s = src_ptr;
25015 size_t n = len;
25016 while (n >= 1) {
25017 uint8_t s0 = s[0];
25018 uint8_t s1 = s[1];
25019 uint8_t s2 = s[2];
25020 uint8_t s3 = s[3];
25021 d[0] = s2;
25022 d[1] = s2;
25023 d[2] = s1;
25024 d[3] = s1;
25025 d[4] = s0;
25026 d[5] = s0;
25027 d[6] = s3;
25028 d[7] = s3;
25030 s += 1 * 4;
25031 d += 1 * 8;
25032 n -= 1;
25034 return len;
25037 static uint64_t //
25038 wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__rgba_nonpremul__src_over(
25039 uint8_t* dst_ptr,
25040 size_t dst_len,
25041 uint8_t* dst_palette_ptr,
25042 size_t dst_palette_len,
25043 const uint8_t* src_ptr,
25044 size_t src_len) {
25045 size_t dst_len8 = dst_len / 8;
25046 size_t src_len4 = src_len / 4;
25047 size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
25048 uint8_t* d = dst_ptr;
25049 const uint8_t* s = src_ptr;
25051 size_t n = len;
25052 while (n >= 1) {
25053 uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8));
25054 uint64_t s0 = wuffs_base__color_u32__as__color_u64(
25055 wuffs_private_impl__swap_u32_argb_abgr(
25056 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))));
25057 wuffs_base__poke_u64le__no_bounds_check(
25058 d + (0 * 8),
25059 wuffs_private_impl__composite_nonpremul_nonpremul_u64_axxx(d0, s0));
25061 s += 1 * 4;
25062 d += 1 * 8;
25063 n -= 1;
25065 return len;
25068 static uint64_t //
25069 wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__rgba_premul__src(
25070 uint8_t* dst_ptr,
25071 size_t dst_len,
25072 uint8_t* dst_palette_ptr,
25073 size_t dst_palette_len,
25074 const uint8_t* src_ptr,
25075 size_t src_len) {
25076 size_t dst_len8 = dst_len / 8;
25077 size_t src_len4 = src_len / 4;
25078 size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
25079 uint8_t* d = dst_ptr;
25080 const uint8_t* s = src_ptr;
25082 size_t n = len;
25083 while (n >= 1) {
25084 uint64_t s0 = wuffs_base__color_u32__as__color_u64(
25085 wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
25086 wuffs_private_impl__swap_u32_argb_abgr(
25087 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)))));
25088 wuffs_base__poke_u64le__no_bounds_check(d + (0 * 8), s0);
25090 s += 1 * 4;
25091 d += 1 * 8;
25092 n -= 1;
25094 return len;
25097 static uint64_t //
25098 wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__rgba_premul__src_over(
25099 uint8_t* dst_ptr,
25100 size_t dst_len,
25101 uint8_t* dst_palette_ptr,
25102 size_t dst_palette_len,
25103 const uint8_t* src_ptr,
25104 size_t src_len) {
25105 size_t dst_len8 = dst_len / 8;
25106 size_t src_len4 = src_len / 4;
25107 size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
25108 uint8_t* d = dst_ptr;
25109 const uint8_t* s = src_ptr;
25111 size_t n = len;
25112 while (n >= 1) {
25113 uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8));
25114 uint64_t s0 = wuffs_base__color_u32__as__color_u64(
25115 wuffs_private_impl__swap_u32_argb_abgr(
25116 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))));
25117 wuffs_base__poke_u64le__no_bounds_check(
25118 d + (0 * 8),
25119 wuffs_private_impl__composite_nonpremul_premul_u64_axxx(d0, s0));
25121 s += 1 * 4;
25122 d += 1 * 8;
25123 n -= 1;
25125 return len;
25128 static uint64_t //
25129 wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__ya_nonpremul__src(
25130 uint8_t* dst_ptr,
25131 size_t dst_len,
25132 uint8_t* dst_palette_ptr,
25133 size_t dst_palette_len,
25134 const uint8_t* src_ptr,
25135 size_t src_len) {
25136 size_t dst_len8 = dst_len / 8;
25137 size_t src_len2 = src_len / 2;
25138 size_t len = (dst_len8 < src_len2) ? dst_len8 : src_len2;
25139 uint8_t* d = dst_ptr;
25140 const uint8_t* s = src_ptr;
25142 size_t n = len;
25143 while (n >= 1) {
25144 uint64_t s0 = ((uint64_t)(s[1]) * 0x0101000000000000) |
25145 ((uint64_t)(s[0]) * 0x0000010101010101);
25146 wuffs_base__poke_u64le__no_bounds_check(d + (0 * 8), s0);
25148 s += 1 * 2;
25149 d += 1 * 8;
25150 n -= 1;
25152 return len;
25155 static uint64_t //
25156 wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__ya_nonpremul__src_over(
25157 uint8_t* dst_ptr,
25158 size_t dst_len,
25159 uint8_t* dst_palette_ptr,
25160 size_t dst_palette_len,
25161 const uint8_t* src_ptr,
25162 size_t src_len) {
25163 size_t dst_len8 = dst_len / 8;
25164 size_t src_len2 = src_len / 2;
25165 size_t len = (dst_len8 < src_len2) ? dst_len8 : src_len2;
25166 uint8_t* d = dst_ptr;
25167 const uint8_t* s = src_ptr;
25169 size_t n = len;
25170 while (n >= 1) {
25171 uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8));
25172 uint64_t s0 = ((uint64_t)(s[1]) * 0x0101000000000000) |
25173 ((uint64_t)(s[0]) * 0x0000010101010101);
25174 wuffs_base__poke_u64le__no_bounds_check(
25175 d + (0 * 8),
25176 wuffs_private_impl__composite_nonpremul_nonpremul_u64_axxx(d0, s0));
25178 s += 1 * 2;
25179 d += 1 * 8;
25180 n -= 1;
25182 return len;
25185 // --------
25187 static uint64_t //
25188 wuffs_private_impl__swizzle_bgra_premul__bgra_nonpremul__src(
25189 uint8_t* dst_ptr,
25190 size_t dst_len,
25191 uint8_t* dst_palette_ptr,
25192 size_t dst_palette_len,
25193 const uint8_t* src_ptr,
25194 size_t src_len) {
25195 size_t dst_len4 = dst_len / 4;
25196 size_t src_len4 = src_len / 4;
25197 size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
25198 uint8_t* d = dst_ptr;
25199 const uint8_t* s = src_ptr;
25200 size_t n = len;
25202 // TODO: unroll.
25204 while (n >= 1) {
25205 uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
25206 wuffs_base__poke_u32le__no_bounds_check(
25207 d + (0 * 4),
25208 wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(s0));
25210 s += 1 * 4;
25211 d += 1 * 4;
25212 n -= 1;
25215 return len;
25218 static uint64_t //
25219 wuffs_private_impl__swizzle_bgra_premul__bgra_nonpremul_4x16le__src(
25220 uint8_t* dst_ptr,
25221 size_t dst_len,
25222 uint8_t* dst_palette_ptr,
25223 size_t dst_palette_len,
25224 const uint8_t* src_ptr,
25225 size_t src_len) {
25226 size_t dst_len4 = dst_len / 4;
25227 size_t src_len8 = src_len / 8;
25228 size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
25229 uint8_t* d = dst_ptr;
25230 const uint8_t* s = src_ptr;
25231 size_t n = len;
25233 // TODO: unroll.
25235 while (n >= 1) {
25236 uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8));
25237 wuffs_base__poke_u32le__no_bounds_check(
25238 d + (0 * 4),
25239 wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(s0));
25241 s += 1 * 8;
25242 d += 1 * 4;
25243 n -= 1;
25246 return len;
25249 static uint64_t //
25250 wuffs_private_impl__swizzle_bgra_premul__bgra_nonpremul__src_over(
25251 uint8_t* dst_ptr,
25252 size_t dst_len,
25253 uint8_t* dst_palette_ptr,
25254 size_t dst_palette_len,
25255 const uint8_t* src_ptr,
25256 size_t src_len) {
25257 size_t dst_len4 = dst_len / 4;
25258 size_t src_len4 = src_len / 4;
25259 size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
25260 uint8_t* d = dst_ptr;
25261 const uint8_t* s = src_ptr;
25262 size_t n = len;
25264 // TODO: unroll.
25266 while (n >= 1) {
25267 uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
25268 uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
25269 wuffs_base__poke_u32le__no_bounds_check(
25270 d + (0 * 4),
25271 wuffs_private_impl__composite_premul_nonpremul_u32_axxx(d0, s0));
25273 s += 1 * 4;
25274 d += 1 * 4;
25275 n -= 1;
25278 return len;
25281 static uint64_t //
25282 wuffs_private_impl__swizzle_bgra_premul__bgra_nonpremul_4x16le__src_over(
25283 uint8_t* dst_ptr,
25284 size_t dst_len,
25285 uint8_t* dst_palette_ptr,
25286 size_t dst_palette_len,
25287 const uint8_t* src_ptr,
25288 size_t src_len) {
25289 size_t dst_len4 = dst_len / 4;
25290 size_t src_len8 = src_len / 8;
25291 size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
25292 uint8_t* d = dst_ptr;
25293 const uint8_t* s = src_ptr;
25294 size_t n = len;
25296 // TODO: unroll.
25298 while (n >= 1) {
25299 uint64_t d0 = wuffs_base__color_u32__as__color_u64(
25300 wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)));
25301 uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8));
25302 wuffs_base__poke_u32le__no_bounds_check(
25303 d + (0 * 4),
25304 wuffs_base__color_u64__as__color_u32(
25305 wuffs_private_impl__composite_premul_nonpremul_u64_axxx(d0, s0)));
25307 s += 1 * 8;
25308 d += 1 * 4;
25309 n -= 1;
25312 return len;
25315 static uint64_t //
25316 wuffs_private_impl__swizzle_bgra_premul__bgra_premul__src_over(
25317 uint8_t* dst_ptr,
25318 size_t dst_len,
25319 uint8_t* dst_palette_ptr,
25320 size_t dst_palette_len,
25321 const uint8_t* src_ptr,
25322 size_t src_len) {
25323 size_t dst_len4 = dst_len / 4;
25324 size_t src_len4 = src_len / 4;
25325 size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
25326 uint8_t* d = dst_ptr;
25327 const uint8_t* s = src_ptr;
25328 size_t n = len;
25330 // TODO: unroll.
25332 while (n >= 1) {
25333 uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
25334 uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
25335 wuffs_base__poke_u32le__no_bounds_check(
25336 d + (0 * 4),
25337 wuffs_private_impl__composite_premul_premul_u32_axxx(d0, s0));
25339 s += 1 * 4;
25340 d += 1 * 4;
25341 n -= 1;
25344 return len;
25347 static uint64_t //
25348 wuffs_private_impl__swizzle_bgra_premul__index_bgra_nonpremul__src_over(
25349 uint8_t* dst_ptr,
25350 size_t dst_len,
25351 uint8_t* dst_palette_ptr,
25352 size_t dst_palette_len,
25353 const uint8_t* src_ptr,
25354 size_t src_len) {
25355 if (dst_palette_len !=
25356 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
25357 return 0;
25359 size_t dst_len4 = dst_len / 4;
25360 size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
25361 uint8_t* d = dst_ptr;
25362 const uint8_t* s = src_ptr;
25363 size_t n = len;
25365 // TODO: unroll.
25367 while (n >= 1) {
25368 uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
25369 uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
25370 ((size_t)s[0] * 4));
25371 wuffs_base__poke_u32le__no_bounds_check(
25372 d + (0 * 4),
25373 wuffs_private_impl__composite_premul_nonpremul_u32_axxx(d0, s0));
25375 s += 1 * 1;
25376 d += 1 * 4;
25377 n -= 1;
25380 return len;
25383 static uint64_t //
25384 wuffs_private_impl__swizzle_bgra_premul__rgba_nonpremul__src(
25385 uint8_t* dst_ptr,
25386 size_t dst_len,
25387 uint8_t* dst_palette_ptr,
25388 size_t dst_palette_len,
25389 const uint8_t* src_ptr,
25390 size_t src_len) {
25391 size_t dst_len4 = dst_len / 4;
25392 size_t src_len4 = src_len / 4;
25393 size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
25394 uint8_t* d = dst_ptr;
25395 const uint8_t* s = src_ptr;
25396 size_t n = len;
25398 // TODO: unroll.
25400 while (n >= 1) {
25401 uint32_t s0 = wuffs_private_impl__swap_u32_argb_abgr(
25402 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
25403 wuffs_base__poke_u32le__no_bounds_check(
25404 d + (0 * 4),
25405 wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(s0));
25407 s += 1 * 4;
25408 d += 1 * 4;
25409 n -= 1;
25412 return len;
25415 static uint64_t //
25416 wuffs_private_impl__swizzle_bgra_premul__rgba_nonpremul__src_over(
25417 uint8_t* dst_ptr,
25418 size_t dst_len,
25419 uint8_t* dst_palette_ptr,
25420 size_t dst_palette_len,
25421 const uint8_t* src_ptr,
25422 size_t src_len) {
25423 size_t dst_len4 = dst_len / 4;
25424 size_t src_len4 = src_len / 4;
25425 size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
25426 uint8_t* d = dst_ptr;
25427 const uint8_t* s = src_ptr;
25428 size_t n = len;
25430 // TODO: unroll.
25432 while (n >= 1) {
25433 uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
25434 uint32_t s0 = wuffs_private_impl__swap_u32_argb_abgr(
25435 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
25436 wuffs_base__poke_u32le__no_bounds_check(
25437 d + (0 * 4),
25438 wuffs_private_impl__composite_premul_nonpremul_u32_axxx(d0, s0));
25440 s += 1 * 4;
25441 d += 1 * 4;
25442 n -= 1;
25445 return len;
25448 static uint64_t //
25449 wuffs_private_impl__swizzle_bgra_premul__rgba_nonpremul_4x16le__src(
25450 uint8_t* dst_ptr,
25451 size_t dst_len,
25452 uint8_t* dst_palette_ptr,
25453 size_t dst_palette_len,
25454 const uint8_t* src_ptr,
25455 size_t src_len) {
25456 size_t dst_len4 = dst_len / 4;
25457 size_t src_len8 = src_len / 8;
25458 size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
25459 uint8_t* d = dst_ptr;
25460 const uint8_t* s = src_ptr;
25461 size_t n = len;
25463 // TODO: unroll.
25465 while (n >= 1) {
25466 uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8));
25467 wuffs_base__poke_u32le__no_bounds_check(
25468 d + (0 * 4),
25469 wuffs_private_impl__swap_u32_argb_abgr(
25470 wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(
25471 s0)));
25473 s += 1 * 8;
25474 d += 1 * 4;
25475 n -= 1;
25478 return len;
25481 static uint64_t //
25482 wuffs_private_impl__swizzle_bgra_premul__rgba_nonpremul_4x16le__src_over(
25483 uint8_t* dst_ptr,
25484 size_t dst_len,
25485 uint8_t* dst_palette_ptr,
25486 size_t dst_palette_len,
25487 const uint8_t* src_ptr,
25488 size_t src_len) {
25489 size_t dst_len4 = dst_len / 4;
25490 size_t src_len8 = src_len / 8;
25491 size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
25492 uint8_t* d = dst_ptr;
25493 const uint8_t* s = src_ptr;
25494 size_t n = len;
25496 // TODO: unroll.
25498 while (n >= 1) {
25499 uint64_t d0 = wuffs_base__color_u32__as__color_u64(
25500 wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)));
25501 uint64_t s0 = wuffs_private_impl__swap_u64_argb_abgr(
25502 wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)));
25503 wuffs_base__poke_u32le__no_bounds_check(
25504 d + (0 * 4),
25505 wuffs_base__color_u64__as__color_u32(
25506 wuffs_private_impl__composite_premul_nonpremul_u64_axxx(d0, s0)));
25508 s += 1 * 8;
25509 d += 1 * 4;
25510 n -= 1;
25513 return len;
25516 static uint64_t //
25517 wuffs_private_impl__swizzle_bgra_premul__rgba_premul__src_over(
25518 uint8_t* dst_ptr,
25519 size_t dst_len,
25520 uint8_t* dst_palette_ptr,
25521 size_t dst_palette_len,
25522 const uint8_t* src_ptr,
25523 size_t src_len) {
25524 size_t dst_len4 = dst_len / 4;
25525 size_t src_len4 = src_len / 4;
25526 size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
25527 uint8_t* d = dst_ptr;
25528 const uint8_t* s = src_ptr;
25529 size_t n = len;
25531 while (n >= 1) {
25532 uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
25533 uint32_t s0 = wuffs_private_impl__swap_u32_argb_abgr(
25534 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
25535 wuffs_base__poke_u32le__no_bounds_check(
25536 d + (0 * 4),
25537 wuffs_private_impl__composite_premul_premul_u32_axxx(d0, s0));
25539 s += 1 * 4;
25540 d += 1 * 4;
25541 n -= 1;
25544 return len;
25547 static uint64_t //
25548 wuffs_private_impl__swizzle_bgra_premul__ya_nonpremul__src(
25549 uint8_t* dst_ptr,
25550 size_t dst_len,
25551 uint8_t* dst_palette_ptr,
25552 size_t dst_palette_len,
25553 const uint8_t* src_ptr,
25554 size_t src_len) {
25555 size_t dst_len4 = dst_len / 4;
25556 size_t src_len2 = src_len / 2;
25557 size_t len = (dst_len4 < src_len2) ? dst_len4 : src_len2;
25558 uint8_t* d = dst_ptr;
25559 const uint8_t* s = src_ptr;
25560 size_t n = len;
25562 // TODO: unroll.
25564 while (n >= 1) {
25565 uint32_t s0 = ((uint32_t)(s[1]) << 24) | ((uint32_t)(s[0]) * 0x010101);
25566 wuffs_base__poke_u32le__no_bounds_check(
25567 d + (0 * 4),
25568 wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(s0));
25570 s += 1 * 2;
25571 d += 1 * 4;
25572 n -= 1;
25575 return len;
25578 static uint64_t //
25579 wuffs_private_impl__swizzle_bgra_premul__ya_nonpremul__src_over(
25580 uint8_t* dst_ptr,
25581 size_t dst_len,
25582 uint8_t* dst_palette_ptr,
25583 size_t dst_palette_len,
25584 const uint8_t* src_ptr,
25585 size_t src_len) {
25586 size_t dst_len4 = dst_len / 4;
25587 size_t src_len2 = src_len / 2;
25588 size_t len = (dst_len4 < src_len2) ? dst_len4 : src_len2;
25589 uint8_t* d = dst_ptr;
25590 const uint8_t* s = src_ptr;
25591 size_t n = len;
25593 // TODO: unroll.
25595 while (n >= 1) {
25596 uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
25597 uint32_t s0 = ((uint32_t)(s[1]) << 24) | ((uint32_t)(s[0]) * 0x010101);
25598 wuffs_base__poke_u32le__no_bounds_check(
25599 d + (0 * 4),
25600 wuffs_private_impl__composite_premul_nonpremul_u32_axxx(d0, s0));
25602 s += 1 * 2;
25603 d += 1 * 4;
25604 n -= 1;
25607 return len;
25610 // --------
25612 static uint64_t //
25613 wuffs_private_impl__swizzle_bgrw__bgr(uint8_t* dst_ptr,
25614 size_t dst_len,
25615 uint8_t* dst_palette_ptr,
25616 size_t dst_palette_len,
25617 const uint8_t* src_ptr,
25618 size_t src_len) {
25619 size_t dst_len4 = dst_len / 4;
25620 size_t src_len3 = src_len / 3;
25621 size_t len = (dst_len4 < src_len3) ? dst_len4 : src_len3;
25622 uint8_t* d = dst_ptr;
25623 const uint8_t* s = src_ptr;
25624 size_t n = len;
25626 // TODO: unroll.
25628 while (n >= 1) {
25629 wuffs_base__poke_u32le__no_bounds_check(
25630 d + (0 * 4),
25631 0xFF000000 | wuffs_base__peek_u24le__no_bounds_check(s + (0 * 3)));
25633 s += 1 * 3;
25634 d += 1 * 4;
25635 n -= 1;
25638 return len;
25641 static uint64_t //
25642 wuffs_private_impl__swizzle_bgrw__bgr_565(uint8_t* dst_ptr,
25643 size_t dst_len,
25644 uint8_t* dst_palette_ptr,
25645 size_t dst_palette_len,
25646 const uint8_t* src_ptr,
25647 size_t src_len) {
25648 size_t dst_len4 = dst_len / 4;
25649 size_t src_len2 = src_len / 2;
25650 size_t len = (dst_len4 < src_len2) ? dst_len4 : src_len2;
25651 uint8_t* d = dst_ptr;
25652 const uint8_t* s = src_ptr;
25653 size_t n = len;
25655 // TODO: unroll.
25657 while (n >= 1) {
25658 wuffs_base__poke_u32le__no_bounds_check(
25659 d + (0 * 4), wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
25660 wuffs_base__peek_u16le__no_bounds_check(s + (0 * 2))));
25662 s += 1 * 2;
25663 d += 1 * 4;
25664 n -= 1;
25667 return len;
25670 static uint64_t //
25671 wuffs_private_impl__swizzle_bgrw__bgrx(uint8_t* dst_ptr,
25672 size_t dst_len,
25673 uint8_t* dst_palette_ptr,
25674 size_t dst_palette_len,
25675 const uint8_t* src_ptr,
25676 size_t src_len) {
25677 size_t dst_len4 = dst_len / 4;
25678 size_t src_len4 = src_len / 4;
25679 size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
25680 uint8_t* d = dst_ptr;
25681 const uint8_t* s = src_ptr;
25682 size_t n = len;
25684 // TODO: unroll.
25686 while (n >= 1) {
25687 wuffs_base__poke_u32le__no_bounds_check(
25688 d + (0 * 4),
25689 0xFF000000 | wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
25691 s += 1 * 4;
25692 d += 1 * 4;
25693 n -= 1;
25696 return len;
25699 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
25700 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
25701 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
25702 static uint64_t //
25703 wuffs_private_impl__swizzle_bgrw__bgr__x86_sse42(uint8_t* dst_ptr,
25704 size_t dst_len,
25705 uint8_t* dst_palette_ptr,
25706 size_t dst_palette_len,
25707 const uint8_t* src_ptr,
25708 size_t src_len) {
25709 size_t dst_len4 = dst_len / 4;
25710 size_t src_len3 = src_len / 3;
25711 size_t len = (dst_len4 < src_len3) ? dst_len4 : src_len3;
25712 uint8_t* d = dst_ptr;
25713 const uint8_t* s = src_ptr;
25714 size_t n = len;
25716 __m128i shuffle = _mm_set_epi8(+0x00, +0x0B, +0x0A, +0x09, //
25717 +0x00, +0x08, +0x07, +0x06, //
25718 +0x00, +0x05, +0x04, +0x03, //
25719 +0x00, +0x02, +0x01, +0x00);
25720 __m128i or_ff = _mm_set_epi8(-0x01, +0x00, +0x00, +0x00, //
25721 -0x01, +0x00, +0x00, +0x00, //
25722 -0x01, +0x00, +0x00, +0x00, //
25723 -0x01, +0x00, +0x00, +0x00);
25725 while (n >= 6) {
25726 __m128i x;
25727 x = _mm_lddqu_si128((const __m128i*)(const void*)s);
25728 x = _mm_shuffle_epi8(x, shuffle);
25729 x = _mm_or_si128(x, or_ff);
25730 _mm_storeu_si128((__m128i*)(void*)d, x);
25732 s += 4 * 3;
25733 d += 4 * 4;
25734 n -= 4;
25737 while (n >= 1) {
25738 uint8_t b0 = s[0];
25739 uint8_t b1 = s[1];
25740 uint8_t b2 = s[2];
25741 d[0] = b0;
25742 d[1] = b1;
25743 d[2] = b2;
25744 d[3] = 0xFF;
25746 s += 1 * 3;
25747 d += 1 * 4;
25748 n -= 1;
25751 return len;
25754 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
25755 static uint64_t //
25756 wuffs_private_impl__swizzle_bgrw__rgb__x86_sse42(uint8_t* dst_ptr,
25757 size_t dst_len,
25758 uint8_t* dst_palette_ptr,
25759 size_t dst_palette_len,
25760 const uint8_t* src_ptr,
25761 size_t src_len) {
25762 size_t dst_len4 = dst_len / 4;
25763 size_t src_len3 = src_len / 3;
25764 size_t len = (dst_len4 < src_len3) ? dst_len4 : src_len3;
25765 uint8_t* d = dst_ptr;
25766 const uint8_t* s = src_ptr;
25767 size_t n = len;
25769 __m128i shuffle = _mm_set_epi8(+0x00, +0x09, +0x0A, +0x0B, //
25770 +0x00, +0x06, +0x07, +0x08, //
25771 +0x00, +0x03, +0x04, +0x05, //
25772 +0x00, +0x00, +0x01, +0x02);
25773 __m128i or_ff = _mm_set_epi8(-0x01, +0x00, +0x00, +0x00, //
25774 -0x01, +0x00, +0x00, +0x00, //
25775 -0x01, +0x00, +0x00, +0x00, //
25776 -0x01, +0x00, +0x00, +0x00);
25778 while (n >= 6) {
25779 __m128i x;
25780 x = _mm_lddqu_si128((const __m128i*)(const void*)s);
25781 x = _mm_shuffle_epi8(x, shuffle);
25782 x = _mm_or_si128(x, or_ff);
25783 _mm_storeu_si128((__m128i*)(void*)d, x);
25785 s += 4 * 3;
25786 d += 4 * 4;
25787 n -= 4;
25790 while (n >= 1) {
25791 uint8_t b0 = s[0];
25792 uint8_t b1 = s[1];
25793 uint8_t b2 = s[2];
25794 d[0] = b2;
25795 d[1] = b1;
25796 d[2] = b0;
25797 d[3] = 0xFF;
25799 s += 1 * 3;
25800 d += 1 * 4;
25801 n -= 1;
25804 return len;
25806 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
25807 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
25809 static uint64_t //
25810 wuffs_private_impl__swizzle_bgrw__rgb(uint8_t* dst_ptr,
25811 size_t dst_len,
25812 uint8_t* dst_palette_ptr,
25813 size_t dst_palette_len,
25814 const uint8_t* src_ptr,
25815 size_t src_len) {
25816 size_t dst_len4 = dst_len / 4;
25817 size_t src_len3 = src_len / 3;
25818 size_t len = (dst_len4 < src_len3) ? dst_len4 : src_len3;
25819 uint8_t* d = dst_ptr;
25820 const uint8_t* s = src_ptr;
25821 size_t n = len;
25823 while (n >= 1) {
25824 uint8_t b0 = s[0];
25825 uint8_t b1 = s[1];
25826 uint8_t b2 = s[2];
25827 d[0] = b2;
25828 d[1] = b1;
25829 d[2] = b0;
25830 d[3] = 0xFF;
25832 s += 1 * 3;
25833 d += 1 * 4;
25834 n -= 1;
25837 return len;
25840 static uint64_t //
25841 wuffs_private_impl__swizzle_bgrw__rgbx(uint8_t* dst_ptr,
25842 size_t dst_len,
25843 uint8_t* dst_palette_ptr,
25844 size_t dst_palette_len,
25845 const uint8_t* src_ptr,
25846 size_t src_len) {
25847 size_t dst_len4 = dst_len / 4;
25848 size_t src_len4 = src_len / 4;
25849 size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
25850 uint8_t* d = dst_ptr;
25851 const uint8_t* s = src_ptr;
25852 size_t n = len;
25854 // TODO: unroll.
25856 while (n >= 1) {
25857 uint8_t b0 = s[0];
25858 uint8_t b1 = s[1];
25859 uint8_t b2 = s[2];
25860 d[0] = b2;
25861 d[1] = b1;
25862 d[2] = b0;
25863 d[3] = 0xFF;
25865 s += 1 * 4;
25866 d += 1 * 4;
25867 n -= 1;
25870 return len;
25873 // --------
25875 static uint64_t //
25876 wuffs_private_impl__swizzle_bgrw_4x16le__bgr(uint8_t* dst_ptr,
25877 size_t dst_len,
25878 uint8_t* dst_palette_ptr,
25879 size_t dst_palette_len,
25880 const uint8_t* src_ptr,
25881 size_t src_len) {
25882 size_t dst_len8 = dst_len / 8;
25883 size_t src_len3 = src_len / 3;
25884 size_t len = (dst_len8 < src_len3) ? dst_len8 : src_len3;
25885 uint8_t* d = dst_ptr;
25886 const uint8_t* s = src_ptr;
25887 size_t n = len;
25889 while (n >= 1) {
25890 uint8_t s0 = s[0];
25891 uint8_t s1 = s[1];
25892 uint8_t s2 = s[2];
25893 d[0] = s0;
25894 d[1] = s0;
25895 d[2] = s1;
25896 d[3] = s1;
25897 d[4] = s2;
25898 d[5] = s2;
25899 d[6] = 0xFF;
25900 d[7] = 0xFF;
25902 s += 1 * 3;
25903 d += 1 * 8;
25904 n -= 1;
25907 return len;
25910 static uint64_t //
25911 wuffs_private_impl__swizzle_bgrw_4x16le__bgr_565(uint8_t* dst_ptr,
25912 size_t dst_len,
25913 uint8_t* dst_palette_ptr,
25914 size_t dst_palette_len,
25915 const uint8_t* src_ptr,
25916 size_t src_len) {
25917 size_t dst_len8 = dst_len / 8;
25918 size_t src_len2 = src_len / 2;
25919 size_t len = (dst_len8 < src_len2) ? dst_len8 : src_len2;
25920 uint8_t* d = dst_ptr;
25921 const uint8_t* s = src_ptr;
25922 size_t n = len;
25924 while (n >= 1) {
25925 wuffs_base__poke_u64le__no_bounds_check(
25926 d + (0 * 8),
25927 wuffs_base__color_u32__as__color_u64(
25928 wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
25929 wuffs_base__peek_u16le__no_bounds_check(s + (0 * 2)))));
25931 s += 1 * 2;
25932 d += 1 * 8;
25933 n -= 1;
25936 return len;
25939 static uint64_t //
25940 wuffs_private_impl__swizzle_bgrw_4x16le__bgrx(uint8_t* dst_ptr,
25941 size_t dst_len,
25942 uint8_t* dst_palette_ptr,
25943 size_t dst_palette_len,
25944 const uint8_t* src_ptr,
25945 size_t src_len) {
25946 size_t dst_len8 = dst_len / 8;
25947 size_t src_len4 = src_len / 4;
25948 size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
25949 uint8_t* d = dst_ptr;
25950 const uint8_t* s = src_ptr;
25951 size_t n = len;
25953 while (n >= 1) {
25954 uint8_t s0 = s[0];
25955 uint8_t s1 = s[1];
25956 uint8_t s2 = s[2];
25957 d[0] = s0;
25958 d[1] = s0;
25959 d[2] = s1;
25960 d[3] = s1;
25961 d[4] = s2;
25962 d[5] = s2;
25963 d[6] = 0xFF;
25964 d[7] = 0xFF;
25966 s += 1 * 4;
25967 d += 1 * 8;
25968 n -= 1;
25971 return len;
25974 static uint64_t //
25975 wuffs_private_impl__swizzle_bgrw_4x16le__rgb(uint8_t* dst_ptr,
25976 size_t dst_len,
25977 uint8_t* dst_palette_ptr,
25978 size_t dst_palette_len,
25979 const uint8_t* src_ptr,
25980 size_t src_len) {
25981 size_t dst_len8 = dst_len / 8;
25982 size_t src_len3 = src_len / 3;
25983 size_t len = (dst_len8 < src_len3) ? dst_len8 : src_len3;
25984 uint8_t* d = dst_ptr;
25985 const uint8_t* s = src_ptr;
25986 size_t n = len;
25988 while (n >= 1) {
25989 uint8_t s0 = s[0];
25990 uint8_t s1 = s[1];
25991 uint8_t s2 = s[2];
25992 d[0] = s2;
25993 d[1] = s2;
25994 d[2] = s1;
25995 d[3] = s1;
25996 d[4] = s0;
25997 d[5] = s0;
25998 d[6] = 0xFF;
25999 d[7] = 0xFF;
26001 s += 1 * 3;
26002 d += 1 * 8;
26003 n -= 1;
26006 return len;
26009 // --------
26011 static uint64_t //
26012 wuffs_private_impl__swizzle_rgb__bgr_565(uint8_t* dst_ptr,
26013 size_t dst_len,
26014 uint8_t* dst_palette_ptr,
26015 size_t dst_palette_len,
26016 const uint8_t* src_ptr,
26017 size_t src_len) {
26018 size_t dst_len3 = dst_len / 3;
26019 size_t src_len2 = src_len / 2;
26020 size_t len = (dst_len3 < src_len2) ? dst_len3 : src_len2;
26021 uint8_t* d = dst_ptr;
26022 const uint8_t* s = src_ptr;
26023 size_t n = len;
26025 // TODO: unroll.
26027 while (n >= 1) {
26028 wuffs_base__poke_u24le__no_bounds_check(
26029 d + (0 * 3),
26030 wuffs_private_impl__swap_u32_argb_abgr(
26031 wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
26032 wuffs_base__peek_u16le__no_bounds_check(s + (0 * 2)))));
26034 s += 1 * 2;
26035 d += 1 * 3;
26036 n -= 1;
26039 return len;
26042 // --------
26044 static uint64_t //
26045 wuffs_private_impl__swizzle_rgba_nonpremul__bgra_nonpremul_4x16le__src(
26046 uint8_t* dst_ptr,
26047 size_t dst_len,
26048 uint8_t* dst_palette_ptr,
26049 size_t dst_palette_len,
26050 const uint8_t* src_ptr,
26051 size_t src_len) {
26052 size_t dst_len4 = dst_len / 4;
26053 size_t src_len8 = src_len / 8;
26054 size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
26055 uint8_t* d = dst_ptr;
26056 const uint8_t* s = src_ptr;
26058 size_t n = len;
26059 while (n >= 1) {
26060 wuffs_base__poke_u32le__no_bounds_check(
26061 d + (0 * 4),
26062 wuffs_private_impl__color_u64__as__color_u32__swap_u32_argb_abgr(
26063 wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8))));
26065 s += 1 * 8;
26066 d += 1 * 4;
26067 n -= 1;
26069 return len;
26072 static uint64_t //
26073 wuffs_private_impl__swizzle_rgba_nonpremul__bgra_nonpremul_4x16le__src_over(
26074 uint8_t* dst_ptr,
26075 size_t dst_len,
26076 uint8_t* dst_palette_ptr,
26077 size_t dst_palette_len,
26078 const uint8_t* src_ptr,
26079 size_t src_len) {
26080 size_t dst_len4 = dst_len / 4;
26081 size_t src_len8 = src_len / 8;
26082 size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
26083 uint8_t* d = dst_ptr;
26084 const uint8_t* s = src_ptr;
26085 size_t n = len;
26087 while (n >= 1) {
26088 uint64_t d0 = wuffs_base__color_u32__as__color_u64(
26089 wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)));
26090 uint64_t s0 = wuffs_private_impl__swap_u64_argb_abgr(
26091 wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)));
26092 wuffs_base__poke_u32le__no_bounds_check(
26093 d + (0 * 4),
26094 wuffs_base__color_u64__as__color_u32(
26095 wuffs_private_impl__composite_nonpremul_nonpremul_u64_axxx(d0,
26096 s0)));
26098 s += 1 * 8;
26099 d += 1 * 4;
26100 n -= 1;
26103 return len;
26106 // --------
26108 static uint64_t //
26109 wuffs_private_impl__swizzle_rgbw__bgr_565(uint8_t* dst_ptr,
26110 size_t dst_len,
26111 uint8_t* dst_palette_ptr,
26112 size_t dst_palette_len,
26113 const uint8_t* src_ptr,
26114 size_t src_len) {
26115 size_t dst_len4 = dst_len / 4;
26116 size_t src_len2 = src_len / 2;
26117 size_t len = (dst_len4 < src_len2) ? dst_len4 : src_len2;
26118 uint8_t* d = dst_ptr;
26119 const uint8_t* s = src_ptr;
26120 size_t n = len;
26122 // TODO: unroll.
26124 while (n >= 1) {
26125 wuffs_base__poke_u32le__no_bounds_check(
26126 d + (0 * 4),
26127 wuffs_private_impl__swap_u32_argb_abgr(
26128 wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
26129 wuffs_base__peek_u16le__no_bounds_check(s + (0 * 2)))));
26131 s += 1 * 2;
26132 d += 1 * 4;
26133 n -= 1;
26136 return len;
26139 // --------
26141 static uint64_t //
26142 wuffs_private_impl__swizzle_xxx__index__src(uint8_t* dst_ptr,
26143 size_t dst_len,
26144 uint8_t* dst_palette_ptr,
26145 size_t dst_palette_len,
26146 const uint8_t* src_ptr,
26147 size_t src_len) {
26148 if (dst_palette_len !=
26149 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
26150 return 0;
26152 size_t dst_len3 = dst_len / 3;
26153 size_t len = (dst_len3 < src_len) ? dst_len3 : src_len;
26154 uint8_t* d = dst_ptr;
26155 const uint8_t* s = src_ptr;
26156 size_t n = len;
26158 const size_t loop_unroll_count = 4;
26160 // The comparison in the while condition is ">", not ">=", because with
26161 // ">=", the last 4-byte store could write past the end of the dst slice.
26163 // Each 4-byte store writes one too many bytes, but a subsequent store
26164 // will overwrite that with the correct byte. There is always another
26165 // store, whether a 4-byte store in this loop or a 1-byte store in the
26166 // next loop.
26167 while (n > loop_unroll_count) {
26168 wuffs_base__poke_u32le__no_bounds_check(
26169 d + (0 * 3), wuffs_base__peek_u32le__no_bounds_check(
26170 dst_palette_ptr + ((size_t)s[0] * 4)));
26171 wuffs_base__poke_u32le__no_bounds_check(
26172 d + (1 * 3), wuffs_base__peek_u32le__no_bounds_check(
26173 dst_palette_ptr + ((size_t)s[1] * 4)));
26174 wuffs_base__poke_u32le__no_bounds_check(
26175 d + (2 * 3), wuffs_base__peek_u32le__no_bounds_check(
26176 dst_palette_ptr + ((size_t)s[2] * 4)));
26177 wuffs_base__poke_u32le__no_bounds_check(
26178 d + (3 * 3), wuffs_base__peek_u32le__no_bounds_check(
26179 dst_palette_ptr + ((size_t)s[3] * 4)));
26181 s += loop_unroll_count * 1;
26182 d += loop_unroll_count * 3;
26183 n -= loop_unroll_count;
26186 while (n >= 1) {
26187 uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
26188 ((size_t)s[0] * 4));
26189 wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
26191 s += 1 * 1;
26192 d += 1 * 3;
26193 n -= 1;
26196 return len;
26199 static uint64_t //
26200 wuffs_private_impl__swizzle_xxx__index_bgra_nonpremul__src_over(
26201 uint8_t* dst_ptr,
26202 size_t dst_len,
26203 uint8_t* dst_palette_ptr,
26204 size_t dst_palette_len,
26205 const uint8_t* src_ptr,
26206 size_t src_len) {
26207 if (dst_palette_len !=
26208 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
26209 return 0;
26211 size_t dst_len3 = dst_len / 3;
26212 size_t len = (dst_len3 < src_len) ? dst_len3 : src_len;
26213 uint8_t* d = dst_ptr;
26214 const uint8_t* s = src_ptr;
26215 size_t n = len;
26217 // TODO: unroll.
26219 while (n >= 1) {
26220 uint32_t d0 =
26221 wuffs_base__peek_u24le__no_bounds_check(d + (0 * 3)) | 0xFF000000;
26222 uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
26223 ((size_t)s[0] * 4));
26224 wuffs_base__poke_u24le__no_bounds_check(
26225 d + (0 * 3),
26226 wuffs_private_impl__composite_premul_nonpremul_u32_axxx(d0, s0));
26228 s += 1 * 1;
26229 d += 1 * 3;
26230 n -= 1;
26233 return len;
26236 static uint64_t //
26237 wuffs_private_impl__swizzle_xxx__index_binary_alpha__src_over(
26238 uint8_t* dst_ptr,
26239 size_t dst_len,
26240 uint8_t* dst_palette_ptr,
26241 size_t dst_palette_len,
26242 const uint8_t* src_ptr,
26243 size_t src_len) {
26244 if (dst_palette_len !=
26245 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
26246 return 0;
26248 size_t dst_len3 = dst_len / 3;
26249 size_t len = (dst_len3 < src_len) ? dst_len3 : src_len;
26250 uint8_t* d = dst_ptr;
26251 const uint8_t* s = src_ptr;
26252 size_t n = len;
26254 const size_t loop_unroll_count = 4;
26256 while (n >= loop_unroll_count) {
26257 uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
26258 ((size_t)s[0] * 4));
26259 if (s0) {
26260 wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
26262 uint32_t s1 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
26263 ((size_t)s[1] * 4));
26264 if (s1) {
26265 wuffs_base__poke_u24le__no_bounds_check(d + (1 * 3), s1);
26267 uint32_t s2 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
26268 ((size_t)s[2] * 4));
26269 if (s2) {
26270 wuffs_base__poke_u24le__no_bounds_check(d + (2 * 3), s2);
26272 uint32_t s3 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
26273 ((size_t)s[3] * 4));
26274 if (s3) {
26275 wuffs_base__poke_u24le__no_bounds_check(d + (3 * 3), s3);
26278 s += loop_unroll_count * 1;
26279 d += loop_unroll_count * 3;
26280 n -= loop_unroll_count;
26283 while (n >= 1) {
26284 uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
26285 ((size_t)s[0] * 4));
26286 if (s0) {
26287 wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
26290 s += 1 * 1;
26291 d += 1 * 3;
26292 n -= 1;
26295 return len;
26298 static uint64_t //
26299 wuffs_private_impl__swizzle_xxx__xxxx(uint8_t* dst_ptr,
26300 size_t dst_len,
26301 uint8_t* dst_palette_ptr,
26302 size_t dst_palette_len,
26303 const uint8_t* src_ptr,
26304 size_t src_len) {
26305 size_t dst_len3 = dst_len / 3;
26306 size_t src_len4 = src_len / 4;
26307 size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
26308 uint8_t* d = dst_ptr;
26309 const uint8_t* s = src_ptr;
26310 size_t n = len;
26312 // TODO: unroll.
26314 while (n >= 1) {
26315 wuffs_base__poke_u24le__no_bounds_check(
26316 d + (0 * 3), wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
26318 s += 1 * 4;
26319 d += 1 * 3;
26320 n -= 1;
26323 return len;
26326 static uint64_t //
26327 wuffs_private_impl__swizzle_xxx__y(uint8_t* dst_ptr,
26328 size_t dst_len,
26329 uint8_t* dst_palette_ptr,
26330 size_t dst_palette_len,
26331 const uint8_t* src_ptr,
26332 size_t src_len) {
26333 size_t dst_len3 = dst_len / 3;
26334 size_t len = (dst_len3 < src_len) ? dst_len3 : src_len;
26335 uint8_t* d = dst_ptr;
26336 const uint8_t* s = src_ptr;
26337 size_t n = len;
26339 // TODO: unroll.
26341 while (n >= 1) {
26342 uint8_t s0 = s[0];
26343 d[0] = s0;
26344 d[1] = s0;
26345 d[2] = s0;
26347 s += 1 * 1;
26348 d += 1 * 3;
26349 n -= 1;
26352 return len;
26355 static uint64_t //
26356 wuffs_private_impl__swizzle_xxx__y_16be(uint8_t* dst_ptr,
26357 size_t dst_len,
26358 uint8_t* dst_palette_ptr,
26359 size_t dst_palette_len,
26360 const uint8_t* src_ptr,
26361 size_t src_len) {
26362 size_t dst_len3 = dst_len / 3;
26363 size_t src_len2 = src_len / 2;
26364 size_t len = (dst_len3 < src_len2) ? dst_len3 : src_len2;
26365 uint8_t* d = dst_ptr;
26366 const uint8_t* s = src_ptr;
26367 size_t n = len;
26369 // TODO: unroll.
26371 while (n >= 1) {
26372 uint8_t s0 = s[0];
26373 d[0] = s0;
26374 d[1] = s0;
26375 d[2] = s0;
26377 s += 1 * 2;
26378 d += 1 * 3;
26379 n -= 1;
26382 return len;
26385 static uint64_t //
26386 wuffs_private_impl__swizzle_xxx__ya_nonpremul__src(uint8_t* dst_ptr,
26387 size_t dst_len,
26388 uint8_t* dst_palette_ptr,
26389 size_t dst_palette_len,
26390 const uint8_t* src_ptr,
26391 size_t src_len) {
26392 size_t dst_len3 = dst_len / 3;
26393 size_t src_len2 = src_len / 2;
26394 size_t len = (dst_len3 < src_len2) ? dst_len3 : src_len2;
26395 uint8_t* d = dst_ptr;
26396 const uint8_t* s = src_ptr;
26397 size_t n = len;
26399 // TODO: unroll.
26401 while (n >= 1) {
26402 uint32_t s0 = ((uint32_t)(s[1]) << 24) | ((uint32_t)(s[0]) * 0x010101);
26403 wuffs_base__poke_u24le__no_bounds_check(
26404 d + (0 * 3),
26405 wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(s0));
26407 s += 1 * 2;
26408 d += 1 * 3;
26409 n -= 1;
26412 return len;
26415 static uint64_t //
26416 wuffs_private_impl__swizzle_xxx__ya_nonpremul__src_over(
26417 uint8_t* dst_ptr,
26418 size_t dst_len,
26419 uint8_t* dst_palette_ptr,
26420 size_t dst_palette_len,
26421 const uint8_t* src_ptr,
26422 size_t src_len) {
26423 size_t dst_len3 = dst_len / 3;
26424 size_t src_len2 = src_len / 2;
26425 size_t len = (dst_len3 < src_len2) ? dst_len3 : src_len2;
26426 uint8_t* d = dst_ptr;
26427 const uint8_t* s = src_ptr;
26428 size_t n = len;
26430 // TODO: unroll.
26432 while (n >= 1) {
26433 uint32_t d0 =
26434 wuffs_base__peek_u24le__no_bounds_check(d + (0 * 3)) | 0xFF000000;
26435 uint32_t s0 = ((uint32_t)(s[1]) << 24) | ((uint32_t)(s[0]) * 0x010101);
26436 wuffs_base__poke_u24le__no_bounds_check(
26437 d + (0 * 3),
26438 wuffs_private_impl__composite_premul_nonpremul_u32_axxx(d0, s0));
26440 s += 1 * 2;
26441 d += 1 * 3;
26442 n -= 1;
26445 return len;
26448 // --------
26450 static uint64_t //
26451 wuffs_private_impl__swizzle_xxxx__index__src(uint8_t* dst_ptr,
26452 size_t dst_len,
26453 uint8_t* dst_palette_ptr,
26454 size_t dst_palette_len,
26455 const uint8_t* src_ptr,
26456 size_t src_len) {
26457 if (dst_palette_len !=
26458 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
26459 return 0;
26461 size_t dst_len4 = dst_len / 4;
26462 size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
26463 uint8_t* d = dst_ptr;
26464 const uint8_t* s = src_ptr;
26465 size_t n = len;
26467 const size_t loop_unroll_count = 4;
26469 while (n >= loop_unroll_count) {
26470 wuffs_base__poke_u32le__no_bounds_check(
26471 d + (0 * 4), wuffs_base__peek_u32le__no_bounds_check(
26472 dst_palette_ptr + ((size_t)s[0] * 4)));
26473 wuffs_base__poke_u32le__no_bounds_check(
26474 d + (1 * 4), wuffs_base__peek_u32le__no_bounds_check(
26475 dst_palette_ptr + ((size_t)s[1] * 4)));
26476 wuffs_base__poke_u32le__no_bounds_check(
26477 d + (2 * 4), wuffs_base__peek_u32le__no_bounds_check(
26478 dst_palette_ptr + ((size_t)s[2] * 4)));
26479 wuffs_base__poke_u32le__no_bounds_check(
26480 d + (3 * 4), wuffs_base__peek_u32le__no_bounds_check(
26481 dst_palette_ptr + ((size_t)s[3] * 4)));
26483 s += loop_unroll_count * 1;
26484 d += loop_unroll_count * 4;
26485 n -= loop_unroll_count;
26488 while (n >= 1) {
26489 wuffs_base__poke_u32le__no_bounds_check(
26490 d + (0 * 4), wuffs_base__peek_u32le__no_bounds_check(
26491 dst_palette_ptr + ((size_t)s[0] * 4)));
26493 s += 1 * 1;
26494 d += 1 * 4;
26495 n -= 1;
26498 return len;
26501 static uint64_t //
26502 wuffs_private_impl__swizzle_xxxx__index_binary_alpha__src_over(
26503 uint8_t* dst_ptr,
26504 size_t dst_len,
26505 uint8_t* dst_palette_ptr,
26506 size_t dst_palette_len,
26507 const uint8_t* src_ptr,
26508 size_t src_len) {
26509 if (dst_palette_len !=
26510 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
26511 return 0;
26513 size_t dst_len4 = dst_len / 4;
26514 size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
26515 uint8_t* d = dst_ptr;
26516 const uint8_t* s = src_ptr;
26517 size_t n = len;
26519 const size_t loop_unroll_count = 4;
26521 while (n >= loop_unroll_count) {
26522 uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
26523 ((size_t)s[0] * 4));
26524 if (s0) {
26525 wuffs_base__poke_u32le__no_bounds_check(d + (0 * 4), s0);
26527 uint32_t s1 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
26528 ((size_t)s[1] * 4));
26529 if (s1) {
26530 wuffs_base__poke_u32le__no_bounds_check(d + (1 * 4), s1);
26532 uint32_t s2 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
26533 ((size_t)s[2] * 4));
26534 if (s2) {
26535 wuffs_base__poke_u32le__no_bounds_check(d + (2 * 4), s2);
26537 uint32_t s3 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
26538 ((size_t)s[3] * 4));
26539 if (s3) {
26540 wuffs_base__poke_u32le__no_bounds_check(d + (3 * 4), s3);
26543 s += loop_unroll_count * 1;
26544 d += loop_unroll_count * 4;
26545 n -= loop_unroll_count;
26548 while (n >= 1) {
26549 uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
26550 ((size_t)s[0] * 4));
26551 if (s0) {
26552 wuffs_base__poke_u32le__no_bounds_check(d + (0 * 4), s0);
26555 s += 1 * 1;
26556 d += 1 * 4;
26557 n -= 1;
26560 return len;
26563 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
26564 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
26565 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
26566 static uint64_t //
26567 wuffs_private_impl__swizzle_xxxx__y__x86_sse42(uint8_t* dst_ptr,
26568 size_t dst_len,
26569 uint8_t* dst_palette_ptr,
26570 size_t dst_palette_len,
26571 const uint8_t* src_ptr,
26572 size_t src_len) {
26573 size_t dst_len4 = dst_len / 4;
26574 size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
26575 uint8_t* d = dst_ptr;
26576 const uint8_t* s = src_ptr;
26577 size_t n = len;
26579 __m128i shuffle = _mm_set_epi8(+0x03, +0x03, +0x03, +0x03, //
26580 +0x02, +0x02, +0x02, +0x02, //
26581 +0x01, +0x01, +0x01, +0x01, //
26582 +0x00, +0x00, +0x00, +0x00);
26583 __m128i or_ff = _mm_set_epi8(-0x01, +0x00, +0x00, +0x00, //
26584 -0x01, +0x00, +0x00, +0x00, //
26585 -0x01, +0x00, +0x00, +0x00, //
26586 -0x01, +0x00, +0x00, +0x00);
26588 while (n >= 4) {
26589 __m128i x;
26590 x = _mm_cvtsi32_si128((int)(wuffs_base__peek_u32le__no_bounds_check(s)));
26591 x = _mm_shuffle_epi8(x, shuffle);
26592 x = _mm_or_si128(x, or_ff);
26593 _mm_storeu_si128((__m128i*)(void*)d, x);
26595 s += 4 * 1;
26596 d += 4 * 4;
26597 n -= 4;
26600 while (n >= 1) {
26601 wuffs_base__poke_u32le__no_bounds_check(
26602 d + (0 * 4), 0xFF000000 | (0x010101 * (uint32_t)s[0]));
26604 s += 1 * 1;
26605 d += 1 * 4;
26606 n -= 1;
26609 return len;
26611 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
26612 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
26614 static uint64_t //
26615 wuffs_private_impl__swizzle_xxxx__y(uint8_t* dst_ptr,
26616 size_t dst_len,
26617 uint8_t* dst_palette_ptr,
26618 size_t dst_palette_len,
26619 const uint8_t* src_ptr,
26620 size_t src_len) {
26621 size_t dst_len4 = dst_len / 4;
26622 size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
26623 uint8_t* d = dst_ptr;
26624 const uint8_t* s = src_ptr;
26625 size_t n = len;
26627 while (n >= 1) {
26628 wuffs_base__poke_u32le__no_bounds_check(
26629 d + (0 * 4), 0xFF000000 | (0x010101 * (uint32_t)s[0]));
26631 s += 1 * 1;
26632 d += 1 * 4;
26633 n -= 1;
26636 return len;
26639 static uint64_t //
26640 wuffs_private_impl__swizzle_xxxx__y_16be(uint8_t* dst_ptr,
26641 size_t dst_len,
26642 uint8_t* dst_palette_ptr,
26643 size_t dst_palette_len,
26644 const uint8_t* src_ptr,
26645 size_t src_len) {
26646 size_t dst_len4 = dst_len / 4;
26647 size_t src_len2 = src_len / 2;
26648 size_t len = (dst_len4 < src_len2) ? dst_len4 : src_len2;
26649 uint8_t* d = dst_ptr;
26650 const uint8_t* s = src_ptr;
26651 size_t n = len;
26653 while (n >= 1) {
26654 wuffs_base__poke_u32le__no_bounds_check(
26655 d + (0 * 4), 0xFF000000 | (0x010101 * (uint32_t)s[0]));
26657 s += 1 * 2;
26658 d += 1 * 4;
26659 n -= 1;
26662 return len;
26665 // --------
26667 static uint64_t //
26668 wuffs_private_impl__swizzle_xxxxxxxx__index__src(uint8_t* dst_ptr,
26669 size_t dst_len,
26670 uint8_t* dst_palette_ptr,
26671 size_t dst_palette_len,
26672 const uint8_t* src_ptr,
26673 size_t src_len) {
26674 if (dst_palette_len !=
26675 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
26676 return 0;
26678 size_t dst_len8 = dst_len / 8;
26679 size_t len = (dst_len8 < src_len) ? dst_len8 : src_len;
26680 uint8_t* d = dst_ptr;
26681 const uint8_t* s = src_ptr;
26682 size_t n = len;
26684 while (n >= 1) {
26685 wuffs_base__poke_u64le__no_bounds_check(
26686 d + (0 * 8), wuffs_base__color_u32__as__color_u64(
26687 wuffs_base__peek_u32le__no_bounds_check(
26688 dst_palette_ptr + ((size_t)s[0] * 4))));
26690 s += 1 * 1;
26691 d += 1 * 8;
26692 n -= 1;
26695 return len;
26698 static uint64_t //
26699 wuffs_private_impl__swizzle_xxxxxxxx__index_binary_alpha__src_over(
26700 uint8_t* dst_ptr,
26701 size_t dst_len,
26702 uint8_t* dst_palette_ptr,
26703 size_t dst_palette_len,
26704 const uint8_t* src_ptr,
26705 size_t src_len) {
26706 if (dst_palette_len !=
26707 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
26708 return 0;
26710 size_t dst_len8 = dst_len / 8;
26711 size_t len = (dst_len8 < src_len) ? dst_len8 : src_len;
26712 uint8_t* d = dst_ptr;
26713 const uint8_t* s = src_ptr;
26714 size_t n = len;
26716 while (n >= 1) {
26717 uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
26718 ((size_t)s[0] * 4));
26719 if (s0) {
26720 wuffs_base__poke_u64le__no_bounds_check(
26721 d + (0 * 8), wuffs_base__color_u32__as__color_u64(s0));
26724 s += 1 * 1;
26725 d += 1 * 8;
26726 n -= 1;
26729 return len;
26732 static uint64_t //
26733 wuffs_private_impl__swizzle_xxxxxxxx__y(uint8_t* dst_ptr,
26734 size_t dst_len,
26735 uint8_t* dst_palette_ptr,
26736 size_t dst_palette_len,
26737 const uint8_t* src_ptr,
26738 size_t src_len) {
26739 size_t dst_len8 = dst_len / 8;
26740 size_t len = (dst_len8 < src_len) ? dst_len8 : src_len;
26741 uint8_t* d = dst_ptr;
26742 const uint8_t* s = src_ptr;
26743 size_t n = len;
26745 while (n >= 1) {
26746 wuffs_base__poke_u64le__no_bounds_check(
26747 d + (0 * 8), 0xFFFF000000000000 | (0x010101010101 * (uint64_t)s[0]));
26749 s += 1 * 1;
26750 d += 1 * 8;
26751 n -= 1;
26754 return len;
26757 static uint64_t //
26758 wuffs_private_impl__swizzle_xxxxxxxx__y_16be(uint8_t* dst_ptr,
26759 size_t dst_len,
26760 uint8_t* dst_palette_ptr,
26761 size_t dst_palette_len,
26762 const uint8_t* src_ptr,
26763 size_t src_len) {
26764 size_t dst_len8 = dst_len / 8;
26765 size_t src_len2 = src_len / 2;
26766 size_t len = (dst_len8 < src_len2) ? dst_len8 : src_len2;
26767 uint8_t* d = dst_ptr;
26768 const uint8_t* s = src_ptr;
26769 size_t n = len;
26771 while (n >= 1) {
26772 uint64_t s0 =
26773 ((uint64_t)(wuffs_base__peek_u16be__no_bounds_check(s + (0 * 2))));
26774 wuffs_base__poke_u64le__no_bounds_check(
26775 d + (0 * 8), 0xFFFF000000000000 | (0x000100010001 * s0));
26777 s += 1 * 2;
26778 d += 1 * 8;
26779 n -= 1;
26782 return len;
26785 // --------
26787 static uint64_t //
26788 wuffs_private_impl__swizzle_y__bgra_nonpremul__src(uint8_t* dst_ptr,
26789 size_t dst_len,
26790 uint8_t* dst_palette_ptr,
26791 size_t dst_palette_len,
26792 const uint8_t* src_ptr,
26793 size_t src_len) {
26794 size_t src_len4 = src_len / 4;
26795 size_t len = (dst_len < src_len4) ? dst_len : src_len4;
26796 uint8_t* d = dst_ptr;
26797 const uint8_t* s = src_ptr;
26798 size_t n = len;
26800 while (n >= 1) {
26801 uint32_t s0 =
26802 wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
26803 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
26804 d[0] = wuffs_base__color_u32_argb_premul__as__color_u8_gray(s0);
26806 s += 1 * 4;
26807 d += 1 * 1;
26808 n -= 1;
26811 return len;
26814 static uint64_t //
26815 wuffs_private_impl__swizzle_y__bgra_nonpremul__src_over(
26816 uint8_t* dst_ptr,
26817 size_t dst_len,
26818 uint8_t* dst_palette_ptr,
26819 size_t dst_palette_len,
26820 const uint8_t* src_ptr,
26821 size_t src_len) {
26822 size_t src_len4 = src_len / 4;
26823 size_t len = (dst_len < src_len4) ? dst_len : src_len4;
26824 uint8_t* d = dst_ptr;
26825 const uint8_t* s = src_ptr;
26826 size_t n = len;
26828 while (n >= 1) {
26829 uint32_t d0 = 0xFF000000 | (0x00010101 * ((uint32_t)(d[0])));
26830 uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
26831 d[0] = wuffs_base__color_u32_argb_premul__as__color_u8_gray(
26832 wuffs_private_impl__composite_premul_nonpremul_u32_axxx(d0, s0));
26834 s += 1 * 4;
26835 d += 1 * 1;
26836 n -= 1;
26839 return len;
26842 static uint64_t //
26843 wuffs_private_impl__swizzle_y__bgrx(uint8_t* dst_ptr,
26844 size_t dst_len,
26845 uint8_t* dst_palette_ptr,
26846 size_t dst_palette_len,
26847 const uint8_t* src_ptr,
26848 size_t src_len) {
26849 size_t src_len4 = src_len / 4;
26850 size_t len = (dst_len < src_len4) ? dst_len : src_len4;
26851 uint8_t* d = dst_ptr;
26852 const uint8_t* s = src_ptr;
26853 size_t n = len;
26855 while (n >= 1) {
26856 uint32_t s0 =
26857 0xFF000000 | wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
26858 d[0] = wuffs_base__color_u32_argb_premul__as__color_u8_gray(s0);
26860 s += 1 * 4;
26861 d += 1 * 1;
26862 n -= 1;
26865 return len;
26868 static uint64_t //
26869 wuffs_private_impl__swizzle_y__y_16be(uint8_t* dst_ptr,
26870 size_t dst_len,
26871 uint8_t* dst_palette_ptr,
26872 size_t dst_palette_len,
26873 const uint8_t* src_ptr,
26874 size_t src_len) {
26875 size_t src_len2 = src_len / 2;
26876 size_t len = (dst_len < src_len2) ? dst_len : src_len2;
26877 uint8_t* d = dst_ptr;
26878 const uint8_t* s = src_ptr;
26879 size_t n = len;
26881 while (n >= 1) {
26882 d[0] = s[0];
26884 s += 1 * 2;
26885 d += 1 * 1;
26886 n -= 1;
26889 return len;
26892 static uint64_t //
26893 wuffs_private_impl__swizzle_y_16le__y_16be(uint8_t* dst_ptr,
26894 size_t dst_len,
26895 uint8_t* dst_palette_ptr,
26896 size_t dst_palette_len,
26897 const uint8_t* src_ptr,
26898 size_t src_len) {
26899 size_t dst_len2 = dst_len / 2;
26900 size_t src_len2 = src_len / 2;
26901 size_t len = (dst_len2 < src_len2) ? dst_len2 : src_len2;
26902 uint8_t* d = dst_ptr;
26903 const uint8_t* s = src_ptr;
26904 size_t n = len;
26906 while (n >= 1) {
26907 uint8_t s0 = s[0];
26908 uint8_t s1 = s[1];
26909 d[0] = s1;
26910 d[1] = s0;
26912 s += 1 * 2;
26913 d += 1 * 2;
26914 n -= 1;
26917 return len;
26920 // --------
26922 static uint64_t //
26923 wuffs_private_impl__swizzle_ya_nonpremul__ya_nonpremul__src_over(
26924 uint8_t* dst_ptr,
26925 size_t dst_len,
26926 uint8_t* dst_palette_ptr,
26927 size_t dst_palette_len,
26928 const uint8_t* src_ptr,
26929 size_t src_len) {
26930 size_t dst_len2 = dst_len / 2;
26931 size_t src_len2 = src_len / 2;
26932 size_t len = (dst_len2 < src_len2) ? dst_len2 : src_len2;
26933 uint8_t* d = dst_ptr;
26934 const uint8_t* s = src_ptr;
26935 size_t n = len;
26937 while (n >= 1) {
26938 uint32_t d0 = ((uint32_t)(d[1]) << 24) | ((uint32_t)(d[0]) * 0x010101);
26939 uint32_t s0 = ((uint32_t)(s[1]) << 24) | ((uint32_t)(s[0]) * 0x010101);
26940 uint32_t c0 =
26941 wuffs_private_impl__composite_nonpremul_nonpremul_u32_axxx(d0, s0);
26942 wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)(c0 >> 16));
26944 s += 1 * 2;
26945 d += 1 * 2;
26946 n -= 1;
26949 return len;
26952 // --------
26954 static uint64_t //
26955 wuffs_private_impl__swizzle_transparent_black_src(
26956 uint8_t* dst_ptr,
26957 size_t dst_len,
26958 uint8_t* dst_palette_ptr,
26959 size_t dst_palette_len,
26960 uint64_t num_pixels,
26961 uint32_t dst_pixfmt_bytes_per_pixel) {
26962 uint64_t n = ((uint64_t)dst_len) / dst_pixfmt_bytes_per_pixel;
26963 if (n > num_pixels) {
26964 n = num_pixels;
26966 memset(dst_ptr, 0, ((size_t)(n * dst_pixfmt_bytes_per_pixel)));
26967 return n;
26970 static uint64_t //
26971 wuffs_private_impl__swizzle_transparent_black_src_over(
26972 uint8_t* dst_ptr,
26973 size_t dst_len,
26974 uint8_t* dst_palette_ptr,
26975 size_t dst_palette_len,
26976 uint64_t num_pixels,
26977 uint32_t dst_pixfmt_bytes_per_pixel) {
26978 uint64_t n = ((uint64_t)dst_len) / dst_pixfmt_bytes_per_pixel;
26979 if (n > num_pixels) {
26980 n = num_pixels;
26982 return n;
26985 // --------
26987 static inline WUFFS_BASE__FORCE_INLINE wuffs_base__pixel_swizzler__func //
26988 wuffs_private_impl__pixel_swizzler__prepare__y(
26989 wuffs_base__pixel_swizzler* p,
26990 wuffs_base__pixel_format dst_pixfmt,
26991 wuffs_base__slice_u8 dst_palette,
26992 wuffs_base__slice_u8 src_palette,
26993 wuffs_base__pixel_blend blend) {
26994 switch (dst_pixfmt.repr) {
26995 case WUFFS_BASE__PIXEL_FORMAT__Y:
26996 return wuffs_private_impl__swizzle_copy_1_1;
26998 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
26999 return wuffs_private_impl__swizzle_bgr_565__y;
27001 case WUFFS_BASE__PIXEL_FORMAT__BGR:
27002 case WUFFS_BASE__PIXEL_FORMAT__RGB:
27003 return wuffs_private_impl__swizzle_xxx__y;
27005 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
27006 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
27007 case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
27008 case WUFFS_BASE__PIXEL_FORMAT__BGRX:
27009 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
27010 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
27011 case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
27012 case WUFFS_BASE__PIXEL_FORMAT__RGBX:
27013 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
27014 if (wuffs_base__cpu_arch__have_x86_sse42()) {
27015 return wuffs_private_impl__swizzle_xxxx__y__x86_sse42;
27017 #endif
27018 return wuffs_private_impl__swizzle_xxxx__y;
27020 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
27021 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE:
27022 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL_4X16LE:
27023 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL_4X16LE:
27024 return wuffs_private_impl__swizzle_xxxxxxxx__y;
27026 return NULL;
27029 static inline WUFFS_BASE__FORCE_INLINE wuffs_base__pixel_swizzler__func //
27030 wuffs_private_impl__pixel_swizzler__prepare__y_16be(
27031 wuffs_base__pixel_swizzler* p,
27032 wuffs_base__pixel_format dst_pixfmt,
27033 wuffs_base__slice_u8 dst_palette,
27034 wuffs_base__slice_u8 src_palette,
27035 wuffs_base__pixel_blend blend) {
27036 switch (dst_pixfmt.repr) {
27037 case WUFFS_BASE__PIXEL_FORMAT__Y:
27038 return wuffs_private_impl__swizzle_y__y_16be;
27040 case WUFFS_BASE__PIXEL_FORMAT__Y_16LE:
27041 return wuffs_private_impl__swizzle_y_16le__y_16be;
27043 case WUFFS_BASE__PIXEL_FORMAT__Y_16BE:
27044 return wuffs_private_impl__swizzle_copy_2_2;
27046 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
27047 return wuffs_private_impl__swizzle_bgr_565__y_16be;
27049 case WUFFS_BASE__PIXEL_FORMAT__BGR:
27050 case WUFFS_BASE__PIXEL_FORMAT__RGB:
27051 return wuffs_private_impl__swizzle_xxx__y_16be;
27053 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
27054 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
27055 case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
27056 case WUFFS_BASE__PIXEL_FORMAT__BGRX:
27057 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
27058 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
27059 case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
27060 case WUFFS_BASE__PIXEL_FORMAT__RGBX:
27061 return wuffs_private_impl__swizzle_xxxx__y_16be;
27063 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
27064 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE:
27065 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL_4X16LE:
27066 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL_4X16LE:
27067 return wuffs_private_impl__swizzle_xxxxxxxx__y_16be;
27069 return NULL;
27072 static inline WUFFS_BASE__FORCE_INLINE wuffs_base__pixel_swizzler__func //
27073 wuffs_private_impl__pixel_swizzler__prepare__ya_nonpremul(
27074 wuffs_base__pixel_swizzler* p,
27075 wuffs_base__pixel_format dst_pixfmt,
27076 wuffs_base__slice_u8 dst_palette,
27077 wuffs_base__slice_u8 src_palette,
27078 wuffs_base__pixel_blend blend) {
27079 switch (dst_pixfmt.repr) {
27080 case WUFFS_BASE__PIXEL_FORMAT__YA_NONPREMUL:
27081 switch (blend) {
27082 case WUFFS_BASE__PIXEL_BLEND__SRC:
27083 return wuffs_private_impl__swizzle_copy_2_2;
27084 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27085 return wuffs_private_impl__swizzle_ya_nonpremul__ya_nonpremul__src_over;
27087 return NULL;
27089 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
27090 switch (blend) {
27091 case WUFFS_BASE__PIXEL_BLEND__SRC:
27092 return wuffs_private_impl__swizzle_bgr_565__ya_nonpremul__src;
27093 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27094 return wuffs_private_impl__swizzle_bgr_565__ya_nonpremul__src_over;
27096 return NULL;
27098 case WUFFS_BASE__PIXEL_FORMAT__BGR:
27099 case WUFFS_BASE__PIXEL_FORMAT__RGB:
27100 switch (blend) {
27101 case WUFFS_BASE__PIXEL_BLEND__SRC:
27102 return wuffs_private_impl__swizzle_xxx__ya_nonpremul__src;
27103 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27104 return wuffs_private_impl__swizzle_xxx__ya_nonpremul__src_over;
27106 return NULL;
27108 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
27109 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
27110 switch (blend) {
27111 case WUFFS_BASE__PIXEL_BLEND__SRC:
27112 return wuffs_private_impl__swizzle_bgra_nonpremul__ya_nonpremul__src;
27113 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27114 return wuffs_private_impl__swizzle_bgra_nonpremul__ya_nonpremul__src_over;
27116 return NULL;
27118 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
27119 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
27120 switch (blend) {
27121 case WUFFS_BASE__PIXEL_BLEND__SRC:
27122 return wuffs_private_impl__swizzle_bgra_premul__ya_nonpremul__src;
27123 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27124 return wuffs_private_impl__swizzle_bgra_premul__ya_nonpremul__src_over;
27126 return NULL;
27128 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
27129 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL_4X16LE:
27130 switch (blend) {
27131 case WUFFS_BASE__PIXEL_BLEND__SRC:
27132 return wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__ya_nonpremul__src;
27133 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27134 return wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__ya_nonpremul__src_over;
27136 return NULL;
27138 return NULL;
27141 static inline WUFFS_BASE__FORCE_INLINE wuffs_base__pixel_swizzler__func //
27142 wuffs_private_impl__pixel_swizzler__prepare__indexed__bgra_nonpremul(
27143 wuffs_base__pixel_swizzler* p,
27144 wuffs_base__pixel_format dst_pixfmt,
27145 wuffs_base__slice_u8 dst_palette,
27146 wuffs_base__slice_u8 src_palette,
27147 wuffs_base__pixel_blend blend) {
27148 switch (dst_pixfmt.repr) {
27149 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:
27150 if (wuffs_private_impl__slice_u8__copy_from_slice(dst_palette,
27151 src_palette) !=
27152 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
27153 return NULL;
27155 switch (blend) {
27156 case WUFFS_BASE__PIXEL_BLEND__SRC:
27157 return wuffs_private_impl__swizzle_copy_1_1;
27159 return NULL;
27161 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
27162 switch (blend) {
27163 case WUFFS_BASE__PIXEL_BLEND__SRC:
27164 if (wuffs_private_impl__swizzle_squash_align4_bgr_565_8888(
27165 dst_palette.ptr, dst_palette.len, src_palette.ptr,
27166 src_palette.len, true) !=
27167 (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
27168 return NULL;
27170 return wuffs_private_impl__swizzle_bgr_565__index__src;
27171 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27172 if (wuffs_private_impl__slice_u8__copy_from_slice(dst_palette,
27173 src_palette) !=
27174 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
27175 return NULL;
27177 return wuffs_private_impl__swizzle_bgr_565__index_bgra_nonpremul__src_over;
27179 return NULL;
27181 case WUFFS_BASE__PIXEL_FORMAT__BGR:
27182 switch (blend) {
27183 case WUFFS_BASE__PIXEL_BLEND__SRC:
27184 if (wuffs_private_impl__swizzle_bgra_premul__bgra_nonpremul__src(
27185 dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
27186 src_palette.len) !=
27187 (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
27188 return NULL;
27190 return wuffs_private_impl__swizzle_xxx__index__src;
27191 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27192 if (wuffs_private_impl__slice_u8__copy_from_slice(dst_palette,
27193 src_palette) !=
27194 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
27195 return NULL;
27197 return wuffs_private_impl__swizzle_xxx__index_bgra_nonpremul__src_over;
27199 return NULL;
27201 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
27202 if (wuffs_private_impl__slice_u8__copy_from_slice(dst_palette,
27203 src_palette) !=
27204 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
27205 return NULL;
27207 switch (blend) {
27208 case WUFFS_BASE__PIXEL_BLEND__SRC:
27209 return wuffs_private_impl__swizzle_xxxx__index__src;
27210 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27211 return wuffs_private_impl__swizzle_bgra_nonpremul__index_bgra_nonpremul__src_over;
27213 return NULL;
27215 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
27216 if (wuffs_private_impl__slice_u8__copy_from_slice(dst_palette,
27217 src_palette) !=
27218 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
27219 return NULL;
27221 switch (blend) {
27222 case WUFFS_BASE__PIXEL_BLEND__SRC:
27223 return wuffs_private_impl__swizzle_xxxxxxxx__index__src;
27224 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27225 return wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__index_bgra_nonpremul__src_over;
27227 return NULL;
27229 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
27230 switch (blend) {
27231 case WUFFS_BASE__PIXEL_BLEND__SRC:
27232 if (wuffs_private_impl__swizzle_bgra_premul__bgra_nonpremul__src(
27233 dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
27234 src_palette.len) !=
27235 (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
27236 return NULL;
27238 return wuffs_private_impl__swizzle_xxxx__index__src;
27239 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27240 if (wuffs_private_impl__slice_u8__copy_from_slice(dst_palette,
27241 src_palette) !=
27242 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
27243 return NULL;
27245 return wuffs_private_impl__swizzle_bgra_premul__index_bgra_nonpremul__src_over;
27247 return NULL;
27249 case WUFFS_BASE__PIXEL_FORMAT__RGB:
27250 switch (blend) {
27251 case WUFFS_BASE__PIXEL_BLEND__SRC:
27252 if (wuffs_private_impl__swizzle_bgra_premul__rgba_nonpremul__src(
27253 dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
27254 src_palette.len) !=
27255 (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
27256 return NULL;
27258 return wuffs_private_impl__swizzle_xxx__index__src;
27259 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27260 if (wuffs_private_impl__swizzle_swap_rgbx_bgrx(
27261 dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
27262 src_palette.len) !=
27263 (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
27264 return NULL;
27266 return wuffs_private_impl__swizzle_xxx__index_bgra_nonpremul__src_over;
27268 return NULL;
27270 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
27271 if (wuffs_private_impl__swizzle_swap_rgbx_bgrx(
27272 dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
27273 src_palette.len) !=
27274 (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
27275 return NULL;
27277 switch (blend) {
27278 case WUFFS_BASE__PIXEL_BLEND__SRC:
27279 return wuffs_private_impl__swizzle_xxxx__index__src;
27280 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27281 return wuffs_private_impl__swizzle_bgra_nonpremul__index_bgra_nonpremul__src_over;
27283 return NULL;
27285 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
27286 switch (blend) {
27287 case WUFFS_BASE__PIXEL_BLEND__SRC:
27288 if (wuffs_private_impl__swizzle_bgra_premul__rgba_nonpremul__src(
27289 dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
27290 src_palette.len) !=
27291 (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
27292 return NULL;
27294 return wuffs_private_impl__swizzle_xxxx__index__src;
27295 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27296 if (wuffs_private_impl__swizzle_swap_rgbx_bgrx(
27297 dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
27298 src_palette.len) !=
27299 (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
27300 return NULL;
27302 return wuffs_private_impl__swizzle_bgra_premul__index_bgra_nonpremul__src_over;
27304 return NULL;
27306 case WUFFS_BASE__PIXEL_FORMAT__RGBX:
27307 // TODO.
27308 break;
27310 return NULL;
27313 static inline WUFFS_BASE__FORCE_INLINE wuffs_base__pixel_swizzler__func //
27314 wuffs_private_impl__pixel_swizzler__prepare__indexed__bgra_binary(
27315 wuffs_base__pixel_swizzler* p,
27316 wuffs_base__pixel_format dst_pixfmt,
27317 wuffs_base__slice_u8 dst_palette,
27318 wuffs_base__slice_u8 src_palette,
27319 wuffs_base__pixel_blend blend) {
27320 switch (dst_pixfmt.repr) {
27321 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:
27322 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL:
27323 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY:
27324 if (wuffs_private_impl__slice_u8__copy_from_slice(dst_palette,
27325 src_palette) !=
27326 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
27327 return NULL;
27329 switch (blend) {
27330 case WUFFS_BASE__PIXEL_BLEND__SRC:
27331 return wuffs_private_impl__swizzle_copy_1_1;
27333 return NULL;
27335 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
27336 if (wuffs_private_impl__swizzle_squash_align4_bgr_565_8888(
27337 dst_palette.ptr, dst_palette.len, src_palette.ptr,
27338 src_palette.len, false) !=
27339 (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
27340 return NULL;
27342 switch (blend) {
27343 case WUFFS_BASE__PIXEL_BLEND__SRC:
27344 return wuffs_private_impl__swizzle_bgr_565__index__src;
27345 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27346 return wuffs_private_impl__swizzle_bgr_565__index_binary_alpha__src_over;
27348 return NULL;
27350 case WUFFS_BASE__PIXEL_FORMAT__BGR:
27351 if (wuffs_private_impl__slice_u8__copy_from_slice(dst_palette,
27352 src_palette) !=
27353 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
27354 return NULL;
27356 switch (blend) {
27357 case WUFFS_BASE__PIXEL_BLEND__SRC:
27358 return wuffs_private_impl__swizzle_xxx__index__src;
27359 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27360 return wuffs_private_impl__swizzle_xxx__index_binary_alpha__src_over;
27362 return NULL;
27364 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
27365 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
27366 case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
27367 if (wuffs_private_impl__slice_u8__copy_from_slice(dst_palette,
27368 src_palette) !=
27369 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
27370 return NULL;
27372 switch (blend) {
27373 case WUFFS_BASE__PIXEL_BLEND__SRC:
27374 return wuffs_private_impl__swizzle_xxxx__index__src;
27375 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27376 return wuffs_private_impl__swizzle_xxxx__index_binary_alpha__src_over;
27378 return NULL;
27380 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
27381 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE:
27382 if (wuffs_private_impl__slice_u8__copy_from_slice(dst_palette,
27383 src_palette) !=
27384 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
27385 return NULL;
27387 switch (blend) {
27388 case WUFFS_BASE__PIXEL_BLEND__SRC:
27389 return wuffs_private_impl__swizzle_xxxxxxxx__index__src;
27390 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27391 return wuffs_private_impl__swizzle_xxxxxxxx__index_binary_alpha__src_over;
27393 return NULL;
27395 case WUFFS_BASE__PIXEL_FORMAT__RGB:
27396 if (wuffs_private_impl__swizzle_swap_rgbx_bgrx(
27397 dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
27398 src_palette.len) !=
27399 (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
27400 return NULL;
27402 switch (blend) {
27403 case WUFFS_BASE__PIXEL_BLEND__SRC:
27404 return wuffs_private_impl__swizzle_xxx__index__src;
27405 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27406 return wuffs_private_impl__swizzle_xxx__index_binary_alpha__src_over;
27408 return NULL;
27410 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
27411 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
27412 case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
27413 if (wuffs_private_impl__swizzle_swap_rgbx_bgrx(
27414 dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
27415 src_palette.len) !=
27416 (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
27417 return NULL;
27419 switch (blend) {
27420 case WUFFS_BASE__PIXEL_BLEND__SRC:
27421 return wuffs_private_impl__swizzle_xxxx__index__src;
27422 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27423 return wuffs_private_impl__swizzle_xxxx__index_binary_alpha__src_over;
27425 return NULL;
27427 return NULL;
27430 static inline WUFFS_BASE__FORCE_INLINE wuffs_base__pixel_swizzler__func //
27431 wuffs_private_impl__pixel_swizzler__prepare__bgr_565(
27432 wuffs_base__pixel_swizzler* p,
27433 wuffs_base__pixel_format dst_pixfmt,
27434 wuffs_base__slice_u8 dst_palette,
27435 wuffs_base__slice_u8 src_palette,
27436 wuffs_base__pixel_blend blend) {
27437 switch (dst_pixfmt.repr) {
27438 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
27439 return wuffs_private_impl__swizzle_copy_2_2;
27441 case WUFFS_BASE__PIXEL_FORMAT__BGR:
27442 return wuffs_private_impl__swizzle_bgr__bgr_565;
27444 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
27445 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
27446 case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
27447 case WUFFS_BASE__PIXEL_FORMAT__BGRX:
27448 return wuffs_private_impl__swizzle_bgrw__bgr_565;
27450 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
27451 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE:
27452 return wuffs_private_impl__swizzle_bgrw_4x16le__bgr_565;
27454 case WUFFS_BASE__PIXEL_FORMAT__RGB:
27455 return wuffs_private_impl__swizzle_rgb__bgr_565;
27457 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
27458 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
27459 case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
27460 case WUFFS_BASE__PIXEL_FORMAT__RGBX:
27461 return wuffs_private_impl__swizzle_rgbw__bgr_565;
27463 return NULL;
27466 static inline WUFFS_BASE__FORCE_INLINE wuffs_base__pixel_swizzler__func //
27467 wuffs_private_impl__pixel_swizzler__prepare__bgr(
27468 wuffs_base__pixel_swizzler* p,
27469 wuffs_base__pixel_format dst_pixfmt,
27470 wuffs_base__slice_u8 dst_palette,
27471 wuffs_base__slice_u8 src_palette,
27472 wuffs_base__pixel_blend blend) {
27473 switch (dst_pixfmt.repr) {
27474 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
27475 return wuffs_private_impl__swizzle_bgr_565__bgr;
27477 case WUFFS_BASE__PIXEL_FORMAT__BGR:
27478 return wuffs_private_impl__swizzle_copy_3_3;
27480 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
27481 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
27482 case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
27483 case WUFFS_BASE__PIXEL_FORMAT__BGRX:
27484 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
27485 if (wuffs_base__cpu_arch__have_x86_sse42()) {
27486 return wuffs_private_impl__swizzle_bgrw__bgr__x86_sse42;
27488 #endif
27489 return wuffs_private_impl__swizzle_bgrw__bgr;
27491 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
27492 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE:
27493 return wuffs_private_impl__swizzle_bgrw_4x16le__bgr;
27495 case WUFFS_BASE__PIXEL_FORMAT__RGB:
27496 return wuffs_private_impl__swizzle_swap_rgb_bgr;
27498 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
27499 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
27500 case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
27501 case WUFFS_BASE__PIXEL_FORMAT__RGBX:
27502 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
27503 if (wuffs_base__cpu_arch__have_x86_sse42()) {
27504 return wuffs_private_impl__swizzle_bgrw__rgb__x86_sse42;
27506 #endif
27507 return wuffs_private_impl__swizzle_bgrw__rgb;
27509 return NULL;
27512 static inline WUFFS_BASE__FORCE_INLINE wuffs_base__pixel_swizzler__func //
27513 wuffs_private_impl__pixel_swizzler__prepare__bgra_nonpremul(
27514 wuffs_base__pixel_swizzler* p,
27515 wuffs_base__pixel_format dst_pixfmt,
27516 wuffs_base__slice_u8 dst_palette,
27517 wuffs_base__slice_u8 src_palette,
27518 wuffs_base__pixel_blend blend) {
27519 switch (dst_pixfmt.repr) {
27520 case WUFFS_BASE__PIXEL_FORMAT__Y:
27521 switch (blend) {
27522 case WUFFS_BASE__PIXEL_BLEND__SRC:
27523 return wuffs_private_impl__swizzle_y__bgra_nonpremul__src;
27524 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27525 return wuffs_private_impl__swizzle_y__bgra_nonpremul__src_over;
27527 return NULL;
27529 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
27530 switch (blend) {
27531 case WUFFS_BASE__PIXEL_BLEND__SRC:
27532 return wuffs_private_impl__swizzle_bgr_565__bgra_nonpremul__src;
27533 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27534 return wuffs_private_impl__swizzle_bgr_565__bgra_nonpremul__src_over;
27536 return NULL;
27538 case WUFFS_BASE__PIXEL_FORMAT__BGR:
27539 switch (blend) {
27540 case WUFFS_BASE__PIXEL_BLEND__SRC:
27541 return wuffs_private_impl__swizzle_bgr__bgra_nonpremul__src;
27542 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27543 return wuffs_private_impl__swizzle_bgr__bgra_nonpremul__src_over;
27545 return NULL;
27547 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
27548 switch (blend) {
27549 case WUFFS_BASE__PIXEL_BLEND__SRC:
27550 return wuffs_private_impl__swizzle_copy_4_4;
27551 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27552 return wuffs_private_impl__swizzle_bgra_nonpremul__bgra_nonpremul__src_over;
27554 return NULL;
27556 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
27557 switch (blend) {
27558 case WUFFS_BASE__PIXEL_BLEND__SRC:
27559 return wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__bgra_nonpremul__src;
27560 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27561 return wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__bgra_nonpremul__src_over;
27563 return NULL;
27565 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
27566 switch (blend) {
27567 case WUFFS_BASE__PIXEL_BLEND__SRC:
27568 return wuffs_private_impl__swizzle_bgra_premul__bgra_nonpremul__src;
27569 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27570 return wuffs_private_impl__swizzle_bgra_premul__bgra_nonpremul__src_over;
27572 return NULL;
27574 case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
27575 case WUFFS_BASE__PIXEL_FORMAT__BGRX:
27576 // TODO.
27577 break;
27579 case WUFFS_BASE__PIXEL_FORMAT__RGB:
27580 switch (blend) {
27581 case WUFFS_BASE__PIXEL_BLEND__SRC:
27582 return wuffs_private_impl__swizzle_bgr__rgba_nonpremul__src;
27583 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27584 return wuffs_private_impl__swizzle_bgr__rgba_nonpremul__src_over;
27586 return NULL;
27588 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
27589 switch (blend) {
27590 case WUFFS_BASE__PIXEL_BLEND__SRC:
27591 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
27592 if (wuffs_base__cpu_arch__have_x86_sse42()) {
27593 return wuffs_private_impl__swizzle_swap_rgbx_bgrx__x86_sse42;
27595 #endif
27596 return wuffs_private_impl__swizzle_swap_rgbx_bgrx;
27597 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27598 return wuffs_private_impl__swizzle_bgra_nonpremul__rgba_nonpremul__src_over;
27600 return NULL;
27602 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
27603 switch (blend) {
27604 case WUFFS_BASE__PIXEL_BLEND__SRC:
27605 return wuffs_private_impl__swizzle_bgra_premul__rgba_nonpremul__src;
27606 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27607 return wuffs_private_impl__swizzle_bgra_premul__rgba_nonpremul__src_over;
27609 return NULL;
27611 case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
27612 case WUFFS_BASE__PIXEL_FORMAT__RGBX:
27613 // TODO.
27614 break;
27616 return NULL;
27619 static inline WUFFS_BASE__FORCE_INLINE wuffs_base__pixel_swizzler__func //
27620 wuffs_private_impl__pixel_swizzler__prepare__bgra_nonpremul_4x16le(
27621 wuffs_base__pixel_swizzler* p,
27622 wuffs_base__pixel_format dst_pixfmt,
27623 wuffs_base__slice_u8 dst_palette,
27624 wuffs_base__slice_u8 src_palette,
27625 wuffs_base__pixel_blend blend) {
27626 switch (dst_pixfmt.repr) {
27627 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
27628 switch (blend) {
27629 case WUFFS_BASE__PIXEL_BLEND__SRC:
27630 return wuffs_private_impl__swizzle_bgr_565__bgra_nonpremul_4x16le__src;
27631 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27632 return wuffs_private_impl__swizzle_bgr_565__bgra_nonpremul_4x16le__src_over;
27634 return NULL;
27636 case WUFFS_BASE__PIXEL_FORMAT__BGR:
27637 switch (blend) {
27638 case WUFFS_BASE__PIXEL_BLEND__SRC:
27639 return wuffs_private_impl__swizzle_bgr__bgra_nonpremul_4x16le__src;
27640 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27641 return wuffs_private_impl__swizzle_bgr__bgra_nonpremul_4x16le__src_over;
27643 return NULL;
27645 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
27646 switch (blend) {
27647 case WUFFS_BASE__PIXEL_BLEND__SRC:
27648 return wuffs_private_impl__swizzle_bgra_nonpremul__bgra_nonpremul_4x16le__src;
27649 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27650 return wuffs_private_impl__swizzle_bgra_nonpremul__bgra_nonpremul_4x16le__src_over;
27652 return NULL;
27654 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
27655 switch (blend) {
27656 case WUFFS_BASE__PIXEL_BLEND__SRC:
27657 return wuffs_private_impl__swizzle_copy_8_8;
27658 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27659 return wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__bgra_nonpremul_4x16le__src_over;
27661 return NULL;
27663 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
27664 switch (blend) {
27665 case WUFFS_BASE__PIXEL_BLEND__SRC:
27666 return wuffs_private_impl__swizzle_bgra_premul__bgra_nonpremul_4x16le__src;
27667 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27668 return wuffs_private_impl__swizzle_bgra_premul__bgra_nonpremul_4x16le__src_over;
27670 return NULL;
27672 case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
27673 case WUFFS_BASE__PIXEL_FORMAT__BGRX:
27674 // TODO.
27675 break;
27677 case WUFFS_BASE__PIXEL_FORMAT__RGB:
27678 switch (blend) {
27679 case WUFFS_BASE__PIXEL_BLEND__SRC:
27680 return wuffs_private_impl__swizzle_bgr__rgba_nonpremul_4x16le__src;
27681 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27682 return wuffs_private_impl__swizzle_bgr__rgba_nonpremul_4x16le__src_over;
27684 return NULL;
27686 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
27687 switch (blend) {
27688 case WUFFS_BASE__PIXEL_BLEND__SRC:
27689 return wuffs_private_impl__swizzle_rgba_nonpremul__bgra_nonpremul_4x16le__src;
27690 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27691 return wuffs_private_impl__swizzle_rgba_nonpremul__bgra_nonpremul_4x16le__src_over;
27693 break;
27695 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
27696 switch (blend) {
27697 case WUFFS_BASE__PIXEL_BLEND__SRC:
27698 return wuffs_private_impl__swizzle_bgra_premul__rgba_nonpremul_4x16le__src;
27699 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27700 return wuffs_private_impl__swizzle_bgra_premul__rgba_nonpremul_4x16le__src_over;
27702 return NULL;
27704 case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
27705 case WUFFS_BASE__PIXEL_FORMAT__RGBX:
27706 // TODO.
27707 break;
27709 return NULL;
27712 static inline WUFFS_BASE__FORCE_INLINE wuffs_base__pixel_swizzler__func //
27713 wuffs_private_impl__pixel_swizzler__prepare__bgra_premul(
27714 wuffs_base__pixel_swizzler* p,
27715 wuffs_base__pixel_format dst_pixfmt,
27716 wuffs_base__slice_u8 dst_palette,
27717 wuffs_base__slice_u8 src_palette,
27718 wuffs_base__pixel_blend blend) {
27719 switch (dst_pixfmt.repr) {
27720 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
27721 switch (blend) {
27722 case WUFFS_BASE__PIXEL_BLEND__SRC:
27723 return wuffs_private_impl__swizzle_bgr_565__bgra_premul__src;
27724 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27725 return wuffs_private_impl__swizzle_bgr_565__bgra_premul__src_over;
27727 return NULL;
27729 case WUFFS_BASE__PIXEL_FORMAT__BGR:
27730 switch (blend) {
27731 case WUFFS_BASE__PIXEL_BLEND__SRC:
27732 return wuffs_private_impl__swizzle_bgr__bgra_premul__src;
27733 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27734 return wuffs_private_impl__swizzle_bgr__bgra_premul__src_over;
27736 return NULL;
27738 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
27739 switch (blend) {
27740 case WUFFS_BASE__PIXEL_BLEND__SRC:
27741 return wuffs_private_impl__swizzle_bgra_nonpremul__bgra_premul__src;
27742 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27743 return wuffs_private_impl__swizzle_bgra_nonpremul__bgra_premul__src_over;
27745 return NULL;
27747 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
27748 switch (blend) {
27749 case WUFFS_BASE__PIXEL_BLEND__SRC:
27750 return wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__bgra_premul__src;
27751 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27752 return wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__bgra_premul__src_over;
27754 return NULL;
27756 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
27757 switch (blend) {
27758 case WUFFS_BASE__PIXEL_BLEND__SRC:
27759 return wuffs_private_impl__swizzle_copy_4_4;
27760 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27761 return wuffs_private_impl__swizzle_bgra_premul__bgra_premul__src_over;
27763 return NULL;
27765 case WUFFS_BASE__PIXEL_FORMAT__RGB:
27766 switch (blend) {
27767 case WUFFS_BASE__PIXEL_BLEND__SRC:
27768 return wuffs_private_impl__swizzle_bgr__rgba_premul__src;
27769 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27770 return wuffs_private_impl__swizzle_bgr__rgba_premul__src_over;
27772 return NULL;
27774 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
27775 switch (blend) {
27776 case WUFFS_BASE__PIXEL_BLEND__SRC:
27777 return wuffs_private_impl__swizzle_bgra_nonpremul__rgba_premul__src;
27778 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27779 return wuffs_private_impl__swizzle_bgra_nonpremul__rgba_premul__src_over;
27781 return NULL;
27783 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
27784 switch (blend) {
27785 case WUFFS_BASE__PIXEL_BLEND__SRC:
27786 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
27787 if (wuffs_base__cpu_arch__have_x86_sse42()) {
27788 return wuffs_private_impl__swizzle_swap_rgbx_bgrx__x86_sse42;
27790 #endif
27791 return wuffs_private_impl__swizzle_swap_rgbx_bgrx;
27792 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27793 return wuffs_private_impl__swizzle_bgra_premul__rgba_premul__src_over;
27795 return NULL;
27797 return NULL;
27800 static inline WUFFS_BASE__FORCE_INLINE wuffs_base__pixel_swizzler__func //
27801 wuffs_private_impl__pixel_swizzler__prepare__bgrx(
27802 wuffs_base__pixel_swizzler* p,
27803 wuffs_base__pixel_format dst_pixfmt,
27804 wuffs_base__slice_u8 dst_palette,
27805 wuffs_base__slice_u8 src_palette,
27806 wuffs_base__pixel_blend blend) {
27807 switch (dst_pixfmt.repr) {
27808 case WUFFS_BASE__PIXEL_FORMAT__Y:
27809 return wuffs_private_impl__swizzle_y__bgrx;
27811 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
27812 return wuffs_private_impl__swizzle_bgr_565__bgrx;
27814 case WUFFS_BASE__PIXEL_FORMAT__BGR:
27815 return wuffs_private_impl__swizzle_xxx__xxxx;
27817 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
27818 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
27819 case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
27820 return wuffs_private_impl__swizzle_bgrw__bgrx;
27822 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
27823 return wuffs_private_impl__swizzle_bgrw_4x16le__bgrx;
27825 case WUFFS_BASE__PIXEL_FORMAT__BGRX:
27826 return wuffs_private_impl__swizzle_copy_4_4;
27828 case WUFFS_BASE__PIXEL_FORMAT__RGB:
27829 return wuffs_private_impl__swizzle_bgr__rgbx;
27831 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
27832 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
27833 case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
27834 case WUFFS_BASE__PIXEL_FORMAT__RGBX:
27835 return wuffs_private_impl__swizzle_bgrw__rgbx;
27837 return NULL;
27840 static inline WUFFS_BASE__FORCE_INLINE wuffs_base__pixel_swizzler__func //
27841 wuffs_private_impl__pixel_swizzler__prepare__rgb(
27842 wuffs_base__pixel_swizzler* p,
27843 wuffs_base__pixel_format dst_pixfmt,
27844 wuffs_base__slice_u8 dst_palette,
27845 wuffs_base__slice_u8 src_palette,
27846 wuffs_base__pixel_blend blend) {
27847 switch (dst_pixfmt.repr) {
27848 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
27849 return wuffs_private_impl__swizzle_bgr_565__rgb;
27851 case WUFFS_BASE__PIXEL_FORMAT__BGR:
27852 return wuffs_private_impl__swizzle_swap_rgb_bgr;
27854 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
27855 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
27856 case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
27857 case WUFFS_BASE__PIXEL_FORMAT__BGRX:
27858 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
27859 if (wuffs_base__cpu_arch__have_x86_sse42()) {
27860 return wuffs_private_impl__swizzle_bgrw__rgb__x86_sse42;
27862 #endif
27863 return wuffs_private_impl__swizzle_bgrw__rgb;
27865 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
27866 return wuffs_private_impl__swizzle_bgrw_4x16le__rgb;
27868 case WUFFS_BASE__PIXEL_FORMAT__RGB:
27869 return wuffs_private_impl__swizzle_copy_3_3;
27871 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
27872 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
27873 case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
27874 case WUFFS_BASE__PIXEL_FORMAT__RGBX:
27875 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
27876 if (wuffs_base__cpu_arch__have_x86_sse42()) {
27877 return wuffs_private_impl__swizzle_bgrw__bgr__x86_sse42;
27879 #endif
27880 return wuffs_private_impl__swizzle_bgrw__bgr;
27882 return NULL;
27885 static inline WUFFS_BASE__FORCE_INLINE wuffs_base__pixel_swizzler__func //
27886 wuffs_private_impl__pixel_swizzler__prepare__rgba_nonpremul(
27887 wuffs_base__pixel_swizzler* p,
27888 wuffs_base__pixel_format dst_pixfmt,
27889 wuffs_base__slice_u8 dst_palette,
27890 wuffs_base__slice_u8 src_palette,
27891 wuffs_base__pixel_blend blend) {
27892 switch (dst_pixfmt.repr) {
27893 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
27894 switch (blend) {
27895 case WUFFS_BASE__PIXEL_BLEND__SRC:
27896 return wuffs_private_impl__swizzle_bgr_565__rgba_nonpremul__src;
27897 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27898 return wuffs_private_impl__swizzle_bgr_565__rgba_nonpremul__src_over;
27900 return NULL;
27902 case WUFFS_BASE__PIXEL_FORMAT__BGR:
27903 switch (blend) {
27904 case WUFFS_BASE__PIXEL_BLEND__SRC:
27905 return wuffs_private_impl__swizzle_bgr__rgba_nonpremul__src;
27906 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27907 return wuffs_private_impl__swizzle_bgr__rgba_nonpremul__src_over;
27909 return NULL;
27911 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
27912 switch (blend) {
27913 case WUFFS_BASE__PIXEL_BLEND__SRC:
27914 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
27915 if (wuffs_base__cpu_arch__have_x86_sse42()) {
27916 return wuffs_private_impl__swizzle_swap_rgbx_bgrx__x86_sse42;
27918 #endif
27919 return wuffs_private_impl__swizzle_swap_rgbx_bgrx;
27920 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27921 return wuffs_private_impl__swizzle_bgra_nonpremul__rgba_nonpremul__src_over;
27923 return NULL;
27925 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
27926 switch (blend) {
27927 case WUFFS_BASE__PIXEL_BLEND__SRC:
27928 return wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__rgba_nonpremul__src;
27929 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27930 return wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__rgba_nonpremul__src_over;
27932 return NULL;
27934 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
27935 switch (blend) {
27936 case WUFFS_BASE__PIXEL_BLEND__SRC:
27937 return wuffs_private_impl__swizzle_bgra_premul__rgba_nonpremul__src;
27938 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27939 return wuffs_private_impl__swizzle_bgra_premul__rgba_nonpremul__src_over;
27941 return NULL;
27943 case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
27944 case WUFFS_BASE__PIXEL_FORMAT__BGRX:
27945 // TODO.
27946 break;
27948 case WUFFS_BASE__PIXEL_FORMAT__RGB:
27949 switch (blend) {
27950 case WUFFS_BASE__PIXEL_BLEND__SRC:
27951 return wuffs_private_impl__swizzle_bgr__bgra_nonpremul__src;
27952 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27953 return wuffs_private_impl__swizzle_bgr__bgra_nonpremul__src_over;
27955 return NULL;
27957 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
27958 switch (blend) {
27959 case WUFFS_BASE__PIXEL_BLEND__SRC:
27960 return wuffs_private_impl__swizzle_copy_4_4;
27961 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27962 return wuffs_private_impl__swizzle_bgra_nonpremul__bgra_nonpremul__src_over;
27964 return NULL;
27966 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
27967 switch (blend) {
27968 case WUFFS_BASE__PIXEL_BLEND__SRC:
27969 return wuffs_private_impl__swizzle_bgra_premul__bgra_nonpremul__src;
27970 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27971 return wuffs_private_impl__swizzle_bgra_premul__bgra_nonpremul__src_over;
27973 return NULL;
27975 case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
27976 case WUFFS_BASE__PIXEL_FORMAT__RGBX:
27977 // TODO.
27978 break;
27980 return NULL;
27983 static inline WUFFS_BASE__FORCE_INLINE wuffs_base__pixel_swizzler__func //
27984 wuffs_private_impl__pixel_swizzler__prepare__rgba_premul(
27985 wuffs_base__pixel_swizzler* p,
27986 wuffs_base__pixel_format dst_pixfmt,
27987 wuffs_base__slice_u8 dst_palette,
27988 wuffs_base__slice_u8 src_palette,
27989 wuffs_base__pixel_blend blend) {
27990 switch (dst_pixfmt.repr) {
27991 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
27992 switch (blend) {
27993 case WUFFS_BASE__PIXEL_BLEND__SRC:
27994 return wuffs_private_impl__swizzle_bgr_565__rgba_premul__src;
27995 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
27996 return wuffs_private_impl__swizzle_bgr_565__rgba_premul__src_over;
27998 return NULL;
28000 case WUFFS_BASE__PIXEL_FORMAT__BGR:
28001 switch (blend) {
28002 case WUFFS_BASE__PIXEL_BLEND__SRC:
28003 return wuffs_private_impl__swizzle_bgr__rgba_premul__src;
28004 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
28005 return wuffs_private_impl__swizzle_bgr__rgba_premul__src_over;
28007 return NULL;
28009 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
28010 switch (blend) {
28011 case WUFFS_BASE__PIXEL_BLEND__SRC:
28012 return wuffs_private_impl__swizzle_bgra_nonpremul__rgba_premul__src;
28013 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
28014 return wuffs_private_impl__swizzle_bgra_nonpremul__rgba_premul__src_over;
28016 return NULL;
28018 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
28019 switch (blend) {
28020 case WUFFS_BASE__PIXEL_BLEND__SRC:
28021 return wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__rgba_premul__src;
28022 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
28023 return wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__rgba_premul__src_over;
28025 return NULL;
28027 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
28028 switch (blend) {
28029 case WUFFS_BASE__PIXEL_BLEND__SRC:
28030 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
28031 if (wuffs_base__cpu_arch__have_x86_sse42()) {
28032 return wuffs_private_impl__swizzle_swap_rgbx_bgrx__x86_sse42;
28034 #endif
28035 return wuffs_private_impl__swizzle_swap_rgbx_bgrx;
28036 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
28037 return wuffs_private_impl__swizzle_bgra_premul__rgba_premul__src_over;
28039 return NULL;
28041 case WUFFS_BASE__PIXEL_FORMAT__RGB:
28042 switch (blend) {
28043 case WUFFS_BASE__PIXEL_BLEND__SRC:
28044 return wuffs_private_impl__swizzle_bgr__bgra_premul__src;
28045 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
28046 return wuffs_private_impl__swizzle_bgr__bgra_premul__src_over;
28048 return NULL;
28050 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
28051 switch (blend) {
28052 case WUFFS_BASE__PIXEL_BLEND__SRC:
28053 return wuffs_private_impl__swizzle_bgra_nonpremul__bgra_premul__src;
28054 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
28055 return wuffs_private_impl__swizzle_bgra_nonpremul__bgra_premul__src_over;
28057 return NULL;
28059 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
28060 switch (blend) {
28061 case WUFFS_BASE__PIXEL_BLEND__SRC:
28062 return wuffs_private_impl__swizzle_copy_4_4;
28063 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
28064 return wuffs_private_impl__swizzle_bgra_premul__bgra_premul__src_over;
28066 return NULL;
28068 return NULL;
28071 // --------
28073 WUFFS_BASE__MAYBE_STATIC wuffs_base__status //
28074 wuffs_base__pixel_swizzler__prepare(wuffs_base__pixel_swizzler* p,
28075 wuffs_base__pixel_format dst_pixfmt,
28076 wuffs_base__slice_u8 dst_palette,
28077 wuffs_base__pixel_format src_pixfmt,
28078 wuffs_base__slice_u8 src_palette,
28079 wuffs_base__pixel_blend blend) {
28080 if (!p) {
28081 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
28083 p->private_impl.func = NULL;
28084 p->private_impl.transparent_black_func = NULL;
28085 p->private_impl.dst_pixfmt_bytes_per_pixel = 0;
28086 p->private_impl.src_pixfmt_bytes_per_pixel = 0;
28088 // ----
28090 #if defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ENABLE_ALLOWLIST)
28091 switch (dst_pixfmt.repr) {
28092 #if defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ALLOW_BGR_565)
28093 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
28094 break;
28095 #endif
28096 #if defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ALLOW_BGR)
28097 case WUFFS_BASE__PIXEL_FORMAT__BGR:
28098 break;
28099 #endif
28100 #if defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ALLOW_BGRA_NONPREMUL)
28101 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
28102 break;
28103 #endif
28104 #if defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ALLOW_BGRA_NONPREMUL_4X16LE)
28105 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
28106 break;
28107 #endif
28108 #if defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ALLOW_BGRA_PREMUL)
28109 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
28110 break;
28111 #endif
28112 #if defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ALLOW_RGB)
28113 case WUFFS_BASE__PIXEL_FORMAT__RGB:
28114 break;
28115 #endif
28116 #if defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ALLOW_RGBA_NONPREMUL)
28117 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
28118 break;
28119 #endif
28120 #if defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ALLOW_RGBA_PREMUL)
28121 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
28122 break;
28123 #endif
28124 default:
28125 return wuffs_base__make_status(
28126 wuffs_base__error__disabled_by_wuffs_config_dst_pixel_format_enable_allowlist);
28128 #endif // defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ENABLE_ALLOWLIST)
28130 // ----
28132 wuffs_base__pixel_swizzler__func func = NULL;
28133 wuffs_base__pixel_swizzler__transparent_black_func transparent_black_func =
28134 NULL;
28136 uint32_t dst_pixfmt_bits_per_pixel =
28137 wuffs_base__pixel_format__bits_per_pixel(&dst_pixfmt);
28138 if ((dst_pixfmt_bits_per_pixel == 0) ||
28139 ((dst_pixfmt_bits_per_pixel & 7) != 0)) {
28140 return wuffs_base__make_status(
28141 wuffs_base__error__unsupported_pixel_swizzler_option);
28144 uint32_t src_pixfmt_bits_per_pixel =
28145 wuffs_base__pixel_format__bits_per_pixel(&src_pixfmt);
28146 if ((src_pixfmt_bits_per_pixel == 0) ||
28147 ((src_pixfmt_bits_per_pixel & 7) != 0)) {
28148 return wuffs_base__make_status(
28149 wuffs_base__error__unsupported_pixel_swizzler_option);
28152 // TODO: support many more formats.
28154 switch (blend) {
28155 case WUFFS_BASE__PIXEL_BLEND__SRC:
28156 transparent_black_func =
28157 wuffs_private_impl__swizzle_transparent_black_src;
28158 break;
28160 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
28161 transparent_black_func =
28162 wuffs_private_impl__swizzle_transparent_black_src_over;
28163 break;
28166 switch (src_pixfmt.repr) {
28167 case WUFFS_BASE__PIXEL_FORMAT__Y:
28168 func = wuffs_private_impl__pixel_swizzler__prepare__y(
28169 p, dst_pixfmt, dst_palette, src_palette, blend);
28170 break;
28172 case WUFFS_BASE__PIXEL_FORMAT__Y_16BE:
28173 func = wuffs_private_impl__pixel_swizzler__prepare__y_16be(
28174 p, dst_pixfmt, dst_palette, src_palette, blend);
28175 break;
28177 case WUFFS_BASE__PIXEL_FORMAT__YA_NONPREMUL:
28178 func = wuffs_private_impl__pixel_swizzler__prepare__ya_nonpremul(
28179 p, dst_pixfmt, dst_palette, src_palette, blend);
28180 break;
28182 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:
28183 func =
28184 wuffs_private_impl__pixel_swizzler__prepare__indexed__bgra_nonpremul(
28185 p, dst_pixfmt, dst_palette, src_palette, blend);
28186 break;
28188 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY:
28189 func = wuffs_private_impl__pixel_swizzler__prepare__indexed__bgra_binary(
28190 p, dst_pixfmt, dst_palette, src_palette, blend);
28191 break;
28193 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
28194 func = wuffs_private_impl__pixel_swizzler__prepare__bgr_565(
28195 p, dst_pixfmt, dst_palette, src_palette, blend);
28196 break;
28198 case WUFFS_BASE__PIXEL_FORMAT__BGR:
28199 func = wuffs_private_impl__pixel_swizzler__prepare__bgr(
28200 p, dst_pixfmt, dst_palette, src_palette, blend);
28201 break;
28203 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
28204 func = wuffs_private_impl__pixel_swizzler__prepare__bgra_nonpremul(
28205 p, dst_pixfmt, dst_palette, src_palette, blend);
28206 break;
28208 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
28209 func = wuffs_private_impl__pixel_swizzler__prepare__bgra_nonpremul_4x16le(
28210 p, dst_pixfmt, dst_palette, src_palette, blend);
28211 break;
28213 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
28214 func = wuffs_private_impl__pixel_swizzler__prepare__bgra_premul(
28215 p, dst_pixfmt, dst_palette, src_palette, blend);
28216 break;
28218 case WUFFS_BASE__PIXEL_FORMAT__BGRX:
28219 func = wuffs_private_impl__pixel_swizzler__prepare__bgrx(
28220 p, dst_pixfmt, dst_palette, src_palette, blend);
28221 break;
28223 case WUFFS_BASE__PIXEL_FORMAT__RGB:
28224 func = wuffs_private_impl__pixel_swizzler__prepare__rgb(
28225 p, dst_pixfmt, dst_palette, src_palette, blend);
28226 break;
28228 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
28229 func = wuffs_private_impl__pixel_swizzler__prepare__rgba_nonpremul(
28230 p, dst_pixfmt, dst_palette, src_palette, blend);
28231 break;
28233 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
28234 func = wuffs_private_impl__pixel_swizzler__prepare__rgba_premul(
28235 p, dst_pixfmt, dst_palette, src_palette, blend);
28236 break;
28239 p->private_impl.func = func;
28240 p->private_impl.transparent_black_func = transparent_black_func;
28241 p->private_impl.dst_pixfmt_bytes_per_pixel = dst_pixfmt_bits_per_pixel / 8;
28242 p->private_impl.src_pixfmt_bytes_per_pixel = src_pixfmt_bits_per_pixel / 8;
28243 return wuffs_base__make_status(
28244 func ? NULL : wuffs_base__error__unsupported_pixel_swizzler_option);
28247 WUFFS_BASE__MAYBE_STATIC uint64_t //
28248 wuffs_base__pixel_swizzler__limited_swizzle_u32_interleaved_from_reader(
28249 const wuffs_base__pixel_swizzler* p,
28250 uint32_t up_to_num_pixels,
28251 wuffs_base__slice_u8 dst,
28252 wuffs_base__slice_u8 dst_palette,
28253 const uint8_t** ptr_iop_r,
28254 const uint8_t* io2_r) {
28255 if (p && p->private_impl.func) {
28256 const uint8_t* iop_r = *ptr_iop_r;
28257 uint64_t src_len = wuffs_base__u64__min(
28258 ((uint64_t)up_to_num_pixels) *
28259 ((uint64_t)p->private_impl.src_pixfmt_bytes_per_pixel),
28260 ((uint64_t)(io2_r - iop_r)));
28261 uint64_t n =
28262 (*p->private_impl.func)(dst.ptr, dst.len, dst_palette.ptr,
28263 dst_palette.len, iop_r, (size_t)src_len);
28264 *ptr_iop_r += n * p->private_impl.src_pixfmt_bytes_per_pixel;
28265 return n;
28267 return 0;
28270 WUFFS_BASE__MAYBE_STATIC uint64_t //
28271 wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(
28272 const wuffs_base__pixel_swizzler* p,
28273 wuffs_base__slice_u8 dst,
28274 wuffs_base__slice_u8 dst_palette,
28275 const uint8_t** ptr_iop_r,
28276 const uint8_t* io2_r) {
28277 if (p && p->private_impl.func) {
28278 const uint8_t* iop_r = *ptr_iop_r;
28279 uint64_t src_len = ((uint64_t)(io2_r - iop_r));
28280 uint64_t n =
28281 (*p->private_impl.func)(dst.ptr, dst.len, dst_palette.ptr,
28282 dst_palette.len, iop_r, (size_t)src_len);
28283 *ptr_iop_r += n * p->private_impl.src_pixfmt_bytes_per_pixel;
28284 return n;
28286 return 0;
28289 WUFFS_BASE__MAYBE_STATIC uint64_t //
28290 wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(
28291 const wuffs_base__pixel_swizzler* p,
28292 wuffs_base__slice_u8 dst,
28293 wuffs_base__slice_u8 dst_palette,
28294 wuffs_base__slice_u8 src) {
28295 if (p && p->private_impl.func) {
28296 return (*p->private_impl.func)(dst.ptr, dst.len, dst_palette.ptr,
28297 dst_palette.len, src.ptr, src.len);
28299 return 0;
28302 WUFFS_BASE__MAYBE_STATIC uint64_t //
28303 wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(
28304 const wuffs_base__pixel_swizzler* p,
28305 wuffs_base__slice_u8 dst,
28306 wuffs_base__slice_u8 dst_palette,
28307 uint64_t num_pixels) {
28308 if (p && p->private_impl.transparent_black_func) {
28309 return (*p->private_impl.transparent_black_func)(
28310 dst.ptr, dst.len, dst_palette.ptr, dst_palette.len, num_pixels,
28311 p->private_impl.dst_pixfmt_bytes_per_pixel);
28313 return 0;
28316 // --------
28318 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3)
28319 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2")
28320 static void //
28321 wuffs_private_impl__swizzle_ycc__convert_3_bgrx_x86_avx2(
28322 wuffs_base__pixel_buffer* dst,
28323 uint32_t x,
28324 uint32_t x_end,
28325 uint32_t y,
28326 const uint8_t* up0,
28327 const uint8_t* up1,
28328 const uint8_t* up2);
28330 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2")
28331 static void //
28332 wuffs_private_impl__swizzle_ycc__convert_3_rgbx_x86_avx2(
28333 wuffs_base__pixel_buffer* dst,
28334 uint32_t x,
28335 uint32_t x_end,
28336 uint32_t y,
28337 const uint8_t* up0,
28338 const uint8_t* up1,
28339 const uint8_t* up2);
28341 #if defined(__GNUC__) && !defined(__clang__)
28342 // No-op.
28343 #else
28344 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2")
28345 static const uint8_t* //
28346 wuffs_private_impl__swizzle_ycc__upsample_inv_h2v2_triangle_x86_avx2(
28347 uint8_t* dst_ptr,
28348 const uint8_t* src_ptr_major,
28349 const uint8_t* src_ptr_minor,
28350 size_t src_len,
28351 uint32_t h1v2_bias_ignored,
28352 bool first_column,
28353 bool last_column);
28354 #endif
28355 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3)
28357 // --------
28359 static inline uint32_t //
28360 wuffs_private_impl__u32__max_of_4(uint32_t a,
28361 uint32_t b,
28362 uint32_t c,
28363 uint32_t d) {
28364 return wuffs_base__u32__max( //
28365 wuffs_base__u32__max(a, b), //
28366 wuffs_base__u32__max(c, d));
28369 static inline uint32_t //
28370 wuffs_private_impl__u32__min_of_5(uint32_t a,
28371 uint32_t b,
28372 uint32_t c,
28373 uint32_t d,
28374 uint32_t e) {
28375 return wuffs_base__u32__min( //
28376 wuffs_base__u32__min( //
28377 wuffs_base__u32__min(a, b), //
28378 wuffs_base__u32__min(c, d)), //
28382 // --------
28384 typedef void (*wuffs_private_impl__swizzle_ycc__convert_4_func)(
28385 wuffs_base__pixel_buffer* dst,
28386 uint32_t x,
28387 uint32_t x_end,
28388 uint32_t y,
28389 const uint8_t* up0,
28390 const uint8_t* up1,
28391 const uint8_t* up2,
28392 const uint8_t* up3);
28394 static void //
28395 wuffs_private_impl__swizzle_cmyk__convert_4_general(
28396 wuffs_base__pixel_buffer* dst,
28397 uint32_t x,
28398 uint32_t x_end,
28399 uint32_t y,
28400 const uint8_t* up0,
28401 const uint8_t* up1,
28402 const uint8_t* up2,
28403 const uint8_t* up3) {
28404 for (; x < x_end; x++) {
28405 // It's called CMYK but, but for Adobe CMYK JPEG images in practice, it's
28406 // RGBW: 0xFFu means no ink instead of full ink. Note that a double
28407 // inversion is a no-op, so inversions might be implicit in the code below.
28408 uint32_t r = ((uint32_t)(*up0++));
28409 uint32_t g = ((uint32_t)(*up1++));
28410 uint32_t b = ((uint32_t)(*up2++));
28411 uint32_t w = ((uint32_t)(*up3++));
28412 r = ((r * w) + 0x7Fu) / 0xFFu;
28413 g = ((g * w) + 0x7Fu) / 0xFFu;
28414 b = ((b * w) + 0x7Fu) / 0xFFu;
28415 wuffs_base__pixel_buffer__set_color_u32_at(
28416 dst, x, y, 0xFF000000u | (r << 16u) | (g << 8u) | (b << 0u));
28420 static void //
28421 wuffs_private_impl__swizzle_ycck__convert_4_general(
28422 wuffs_base__pixel_buffer* dst,
28423 uint32_t x,
28424 uint32_t x_end,
28425 uint32_t y,
28426 const uint8_t* up0,
28427 const uint8_t* up1,
28428 const uint8_t* up2,
28429 const uint8_t* up3) {
28430 for (; x < x_end; x++) {
28431 // We invert once again: 0xFFu means no ink instead of full ink.
28432 uint32_t color = //
28433 wuffs_base__color_ycc__as__color_u32( //
28434 *up0++, *up1++, *up2++);
28435 uint32_t r = 0xFFu - (0xFFu & (color >> 16u));
28436 uint32_t g = 0xFFu - (0xFFu & (color >> 8u));
28437 uint32_t b = 0xFFu - (0xFFu & (color >> 0u));
28438 uint32_t w = ((uint32_t)(*up3++));
28439 r = ((r * w) + 0x7Fu) / 0xFFu;
28440 g = ((g * w) + 0x7Fu) / 0xFFu;
28441 b = ((b * w) + 0x7Fu) / 0xFFu;
28442 wuffs_base__pixel_buffer__set_color_u32_at(
28443 dst, x, y, 0xFF000000u | (r << 16u) | (g << 8u) | (b << 0u));
28447 // --------
28449 typedef void (*wuffs_private_impl__swizzle_ycc__convert_3_func)(
28450 wuffs_base__pixel_buffer* dst,
28451 uint32_t x,
28452 uint32_t x_end,
28453 uint32_t y,
28454 const uint8_t* up0,
28455 const uint8_t* up1,
28456 const uint8_t* up2);
28458 static void //
28459 wuffs_private_impl__swizzle_rgb__convert_3_general(
28460 wuffs_base__pixel_buffer* dst,
28461 uint32_t x,
28462 uint32_t x_end,
28463 uint32_t y,
28464 const uint8_t* up0,
28465 const uint8_t* up1,
28466 const uint8_t* up2) {
28467 for (; x < x_end; x++) {
28468 uint32_t color = 0xFF000000u | //
28469 (((uint32_t)(*up0++)) << 16u) | //
28470 (((uint32_t)(*up1++)) << 8u) | //
28471 (((uint32_t)(*up2++)) << 0u);
28472 wuffs_base__pixel_buffer__set_color_u32_at(dst, x, y, color);
28476 static void //
28477 wuffs_private_impl__swizzle_ycc__convert_3_general(
28478 wuffs_base__pixel_buffer* dst,
28479 uint32_t x,
28480 uint32_t x_end,
28481 uint32_t y,
28482 const uint8_t* up0,
28483 const uint8_t* up1,
28484 const uint8_t* up2) {
28485 for (; x < x_end; x++) {
28486 uint32_t color = //
28487 wuffs_base__color_ycc__as__color_u32( //
28488 *up0++, *up1++, *up2++);
28489 wuffs_base__pixel_buffer__set_color_u32_at(dst, x, y, color);
28493 static void //
28494 wuffs_private_impl__swizzle_ycc__convert_3_bgrx(wuffs_base__pixel_buffer* dst,
28495 uint32_t x,
28496 uint32_t x_end,
28497 uint32_t y,
28498 const uint8_t* up0,
28499 const uint8_t* up1,
28500 const uint8_t* up2) {
28501 size_t dst_stride = dst->private_impl.planes[0].stride;
28502 uint8_t* dst_iter = dst->private_impl.planes[0].ptr +
28503 (dst_stride * ((size_t)y)) + (4u * ((size_t)x));
28505 for (; x < x_end; x++) {
28506 uint32_t color = //
28507 wuffs_base__color_ycc__as__color_u32( //
28508 *up0++, *up1++, *up2++);
28509 wuffs_base__poke_u32le__no_bounds_check(dst_iter, color);
28510 dst_iter += 4u;
28514 static void //
28515 wuffs_private_impl__swizzle_ycc__convert_3_rgbx(wuffs_base__pixel_buffer* dst,
28516 uint32_t x,
28517 uint32_t x_end,
28518 uint32_t y,
28519 const uint8_t* up0,
28520 const uint8_t* up1,
28521 const uint8_t* up2) {
28522 size_t dst_stride = dst->private_impl.planes[0].stride;
28523 uint8_t* dst_iter = dst->private_impl.planes[0].ptr +
28524 (dst_stride * ((size_t)y)) + (4u * ((size_t)x));
28526 for (; x < x_end; x++) {
28527 uint32_t color = //
28528 wuffs_base__color_ycc__as__color_u32_abgr( //
28529 *up0++, *up1++, *up2++);
28530 wuffs_base__poke_u32le__no_bounds_check(dst_iter, color);
28531 dst_iter += 4u;
28535 // --------
28537 // wuffs_private_impl__swizzle_ycc__upsample_func upsamples to a destination
28538 // slice at least 480 (YCCK) or 672 (YCC) bytes long and whose src_len
28539 // (multiplied by 1, 2, 3 or 4) is positive but no more than that. This 480 or
28540 // 672 length is just under 1/4 or 1/3 of the scratch_buffer_2k slice length.
28541 // Both (480 * 4) = 1920 and (672 * 3) = 2016 are less than 2048.
28543 // 480 and 672 are nice round numbers because a JPEG MCU is 1, 2, 3 or 4 blocks
28544 // wide and each block is 8 pixels wide. We have:
28545 // 480 = 1 * 8 * 60, 672 = 1 * 8 * 84
28546 // 480 = 2 * 8 * 30, 672 = 2 * 8 * 42
28547 // 480 = 3 * 8 * 20, 672 = 3 * 8 * 28
28548 // 480 = 4 * 8 * 15, 672 = 4 * 8 * 21
28550 // Box filters are equivalent to nearest neighbor upsampling. These ignore the
28551 // src_ptr_minor, h1v2_bias, first_column and last_column arguments.
28553 // Triangle filters use a 3:1 ratio (in 1 dimension), or 9:3:3:1 (in 2
28554 // dimensions), which is higher quality (less blocky) but also higher
28555 // computational effort.
28557 // In theory, we could use triangle filters for any (inv_h, inv_v) combination.
28558 // In practice, matching libjpeg-turbo, we only implement it for the common
28559 // chroma subsampling ratios (YCC420, YCC422 or YCC440), corresponding to an
28560 // (inv_h, inv_v) pair of (2, 2), (2, 1) or (1, 2).
28561 typedef const uint8_t* (*wuffs_private_impl__swizzle_ycc__upsample_func)(
28562 uint8_t* dst_ptr,
28563 const uint8_t* src_ptr_major, // Nearest row.
28564 const uint8_t* src_ptr_minor, // Adjacent row, alternating above or below.
28565 size_t src_len,
28566 uint32_t h1v2_bias,
28567 bool first_column,
28568 bool last_column);
28570 static const uint8_t* //
28571 wuffs_private_impl__swizzle_ycc__upsample_inv_h1vn_box(
28572 uint8_t* dst_ptr,
28573 const uint8_t* src_ptr_major,
28574 const uint8_t* src_ptr_minor_ignored,
28575 size_t src_len,
28576 uint32_t h1v2_bias_ignored,
28577 bool first_column_ignored,
28578 bool last_column_ignored) {
28579 return src_ptr_major;
28582 static const uint8_t* //
28583 wuffs_private_impl__swizzle_ycc__upsample_inv_h2vn_box(
28584 uint8_t* dst_ptr,
28585 const uint8_t* src_ptr_major,
28586 const uint8_t* src_ptr_minor_ignored,
28587 size_t src_len,
28588 uint32_t h1v2_bias_ignored,
28589 bool first_column_ignored,
28590 bool last_column_ignored) {
28591 uint8_t* dp = dst_ptr;
28592 const uint8_t* sp = src_ptr_major;
28593 while (src_len--) {
28594 uint8_t sv = *sp++;
28595 *dp++ = sv;
28596 *dp++ = sv;
28598 return dst_ptr;
28601 static const uint8_t* //
28602 wuffs_private_impl__swizzle_ycc__upsample_inv_h3vn_box(
28603 uint8_t* dst_ptr,
28604 const uint8_t* src_ptr_major,
28605 const uint8_t* src_ptr_minor_ignored,
28606 size_t src_len,
28607 uint32_t h1v2_bias_ignored,
28608 bool first_column_ignored,
28609 bool last_column_ignored) {
28610 uint8_t* dp = dst_ptr;
28611 const uint8_t* sp = src_ptr_major;
28612 while (src_len--) {
28613 uint8_t sv = *sp++;
28614 *dp++ = sv;
28615 *dp++ = sv;
28616 *dp++ = sv;
28618 return dst_ptr;
28621 static const uint8_t* //
28622 wuffs_private_impl__swizzle_ycc__upsample_inv_h4vn_box(
28623 uint8_t* dst_ptr,
28624 const uint8_t* src_ptr_major,
28625 const uint8_t* src_ptr_minor_ignored,
28626 size_t src_len,
28627 uint32_t h1v2_bias_ignored,
28628 bool first_column_ignored,
28629 bool last_column_ignored) {
28630 uint8_t* dp = dst_ptr;
28631 const uint8_t* sp = src_ptr_major;
28632 while (src_len--) {
28633 uint8_t sv = *sp++;
28634 *dp++ = sv;
28635 *dp++ = sv;
28636 *dp++ = sv;
28637 *dp++ = sv;
28639 return dst_ptr;
28642 static const uint8_t* //
28643 wuffs_private_impl__swizzle_ycc__upsample_inv_h1v2_triangle(
28644 uint8_t* dst_ptr,
28645 const uint8_t* src_ptr_major,
28646 const uint8_t* src_ptr_minor,
28647 size_t src_len,
28648 uint32_t h1v2_bias,
28649 bool first_column,
28650 bool last_column) {
28651 uint8_t* dp = dst_ptr;
28652 const uint8_t* sp_major = src_ptr_major;
28653 const uint8_t* sp_minor = src_ptr_minor;
28654 while (src_len--) {
28655 *dp++ = (uint8_t)(((3u * ((uint32_t)(*sp_major++))) + //
28656 (1u * ((uint32_t)(*sp_minor++))) + //
28657 h1v2_bias) >>
28658 2u);
28660 return dst_ptr;
28663 static const uint8_t* //
28664 wuffs_private_impl__swizzle_ycc__upsample_inv_h2v1_triangle(
28665 uint8_t* dst_ptr,
28666 const uint8_t* src_ptr_major,
28667 const uint8_t* src_ptr_minor,
28668 size_t src_len,
28669 uint32_t h1v2_bias_ignored,
28670 bool first_column,
28671 bool last_column) {
28672 uint8_t* dp = dst_ptr;
28673 const uint8_t* sp = src_ptr_major;
28675 if (first_column) {
28676 src_len--;
28677 if ((src_len <= 0u) && last_column) {
28678 uint8_t sv = *sp++;
28679 *dp++ = sv;
28680 *dp++ = sv;
28681 return dst_ptr;
28683 uint32_t svp1 = sp[+1];
28684 uint8_t sv = *sp++;
28685 *dp++ = sv;
28686 *dp++ = (uint8_t)(((3u * (uint32_t)sv) + svp1 + 2u) >> 2u);
28687 if (src_len <= 0u) {
28688 return dst_ptr;
28692 if (last_column) {
28693 src_len--;
28696 for (; src_len > 0u; src_len--) {
28697 uint32_t svm1 = sp[-1];
28698 uint32_t svp1 = sp[+1];
28699 uint32_t sv3 = 3u * (uint32_t)(*sp++);
28700 *dp++ = (uint8_t)((sv3 + svm1 + 1u) >> 2u);
28701 *dp++ = (uint8_t)((sv3 + svp1 + 2u) >> 2u);
28704 if (last_column) {
28705 uint32_t svm1 = sp[-1];
28706 uint8_t sv = *sp++;
28707 *dp++ = (uint8_t)(((3u * (uint32_t)sv) + svm1 + 1u) >> 2u);
28708 *dp++ = sv;
28711 return dst_ptr;
28714 static const uint8_t* //
28715 wuffs_private_impl__swizzle_ycc__upsample_inv_h2v2_triangle(
28716 uint8_t* dst_ptr,
28717 const uint8_t* src_ptr_major,
28718 const uint8_t* src_ptr_minor,
28719 size_t src_len,
28720 uint32_t h1v2_bias_ignored,
28721 bool first_column,
28722 bool last_column) {
28723 uint8_t* dp = dst_ptr;
28724 const uint8_t* sp_major = src_ptr_major;
28725 const uint8_t* sp_minor = src_ptr_minor;
28727 if (first_column) {
28728 src_len--;
28729 if ((src_len <= 0u) && last_column) {
28730 uint32_t sv = (12u * ((uint32_t)(*sp_major++))) + //
28731 (4u * ((uint32_t)(*sp_minor++)));
28732 *dp++ = (uint8_t)((sv + 8u) >> 4u);
28733 *dp++ = (uint8_t)((sv + 7u) >> 4u);
28734 return dst_ptr;
28737 uint32_t sv_major_m1 = sp_major[-0]; // Clamp offset to zero.
28738 uint32_t sv_minor_m1 = sp_minor[-0]; // Clamp offset to zero.
28739 uint32_t sv_major_p1 = sp_major[+1];
28740 uint32_t sv_minor_p1 = sp_minor[+1];
28742 uint32_t sv = (9u * ((uint32_t)(*sp_major++))) + //
28743 (3u * ((uint32_t)(*sp_minor++)));
28744 *dp++ = (uint8_t)((sv + (3u * sv_major_m1) + (sv_minor_m1) + 8u) >> 4u);
28745 *dp++ = (uint8_t)((sv + (3u * sv_major_p1) + (sv_minor_p1) + 7u) >> 4u);
28746 if (src_len <= 0u) {
28747 return dst_ptr;
28751 if (last_column) {
28752 src_len--;
28755 for (; src_len > 0u; src_len--) {
28756 uint32_t sv_major_m1 = sp_major[-1];
28757 uint32_t sv_minor_m1 = sp_minor[-1];
28758 uint32_t sv_major_p1 = sp_major[+1];
28759 uint32_t sv_minor_p1 = sp_minor[+1];
28761 uint32_t sv = (9u * ((uint32_t)(*sp_major++))) + //
28762 (3u * ((uint32_t)(*sp_minor++)));
28763 *dp++ = (uint8_t)((sv + (3u * sv_major_m1) + (sv_minor_m1) + 8u) >> 4u);
28764 *dp++ = (uint8_t)((sv + (3u * sv_major_p1) + (sv_minor_p1) + 7u) >> 4u);
28767 if (last_column) {
28768 uint32_t sv_major_m1 = sp_major[-1];
28769 uint32_t sv_minor_m1 = sp_minor[-1];
28770 uint32_t sv_major_p1 = sp_major[+0]; // Clamp offset to zero.
28771 uint32_t sv_minor_p1 = sp_minor[+0]; // Clamp offset to zero.
28773 uint32_t sv = (9u * ((uint32_t)(*sp_major++))) + //
28774 (3u * ((uint32_t)(*sp_minor++)));
28775 *dp++ = (uint8_t)((sv + (3u * sv_major_m1) + (sv_minor_m1) + 8u) >> 4u);
28776 *dp++ = (uint8_t)((sv + (3u * sv_major_p1) + (sv_minor_p1) + 7u) >> 4u);
28779 return dst_ptr;
28782 // wuffs_private_impl__swizzle_ycc__upsample_funcs is indexed by inv_h and then
28783 // inv_v.
28784 static const wuffs_private_impl__swizzle_ycc__upsample_func
28785 wuffs_private_impl__swizzle_ycc__upsample_funcs[4][4] = {
28787 wuffs_private_impl__swizzle_ycc__upsample_inv_h1vn_box,
28788 wuffs_private_impl__swizzle_ycc__upsample_inv_h1vn_box,
28789 wuffs_private_impl__swizzle_ycc__upsample_inv_h1vn_box,
28790 wuffs_private_impl__swizzle_ycc__upsample_inv_h1vn_box,
28793 wuffs_private_impl__swizzle_ycc__upsample_inv_h2vn_box,
28794 wuffs_private_impl__swizzle_ycc__upsample_inv_h2vn_box,
28795 wuffs_private_impl__swizzle_ycc__upsample_inv_h2vn_box,
28796 wuffs_private_impl__swizzle_ycc__upsample_inv_h2vn_box,
28799 wuffs_private_impl__swizzle_ycc__upsample_inv_h3vn_box,
28800 wuffs_private_impl__swizzle_ycc__upsample_inv_h3vn_box,
28801 wuffs_private_impl__swizzle_ycc__upsample_inv_h3vn_box,
28802 wuffs_private_impl__swizzle_ycc__upsample_inv_h3vn_box,
28805 wuffs_private_impl__swizzle_ycc__upsample_inv_h4vn_box,
28806 wuffs_private_impl__swizzle_ycc__upsample_inv_h4vn_box,
28807 wuffs_private_impl__swizzle_ycc__upsample_inv_h4vn_box,
28808 wuffs_private_impl__swizzle_ycc__upsample_inv_h4vn_box,
28812 static inline uint32_t //
28813 wuffs_private_impl__swizzle_has_triangle_upsampler(uint32_t inv_h,
28814 uint32_t inv_v) {
28815 if (inv_h == 1u) {
28816 return inv_v == 2u;
28817 } else if (inv_h == 2u) {
28818 return (inv_v == 1u) || (inv_v == 2u);
28820 return false;
28823 // --------
28825 // All of the wuffs_private_impl__swizzle_ycc__etc functions have
28826 // preconditions. See all of the checks made in
28827 // wuffs_base__pixel_swizzler__swizzle_ycck before calling these functions. For
28828 // example, (width > 0) is a precondition, but there are many more.
28830 static void //
28831 wuffs_private_impl__swizzle_ycck__general__triangle_filter_edge_row(
28832 wuffs_base__pixel_buffer* dst,
28833 uint32_t width,
28834 uint32_t y,
28835 const uint8_t* src_ptr0,
28836 const uint8_t* src_ptr1,
28837 const uint8_t* src_ptr2,
28838 const uint8_t* src_ptr3,
28839 uint32_t stride0,
28840 uint32_t stride1,
28841 uint32_t stride2,
28842 uint32_t stride3,
28843 uint32_t inv_h0,
28844 uint32_t inv_h1,
28845 uint32_t inv_h2,
28846 uint32_t inv_h3,
28847 uint32_t inv_v0,
28848 uint32_t inv_v1,
28849 uint32_t inv_v2,
28850 uint32_t inv_v3,
28851 uint32_t half_width_for_2to1,
28852 uint32_t h1v2_bias,
28853 uint8_t* scratch_buffer_2k_ptr,
28854 wuffs_private_impl__swizzle_ycc__upsample_func upfunc0,
28855 wuffs_private_impl__swizzle_ycc__upsample_func upfunc1,
28856 wuffs_private_impl__swizzle_ycc__upsample_func upfunc2,
28857 wuffs_private_impl__swizzle_ycc__upsample_func upfunc3,
28858 wuffs_private_impl__swizzle_ycc__convert_4_func conv4func) {
28859 const uint8_t* src0 = src_ptr0 + ((y / inv_v0) * (size_t)stride0);
28860 const uint8_t* src1 = src_ptr1 + ((y / inv_v1) * (size_t)stride1);
28861 const uint8_t* src2 = src_ptr2 + ((y / inv_v2) * (size_t)stride2);
28862 const uint8_t* src3 = src_ptr3 + ((y / inv_v3) * (size_t)stride3);
28863 uint32_t total_src_len0 = 0u;
28864 uint32_t total_src_len1 = 0u;
28865 uint32_t total_src_len2 = 0u;
28866 uint32_t total_src_len3 = 0u;
28868 uint32_t x = 0u;
28869 while (x < width) {
28870 bool first_column = x == 0u;
28871 uint32_t end = x + 480u;
28872 if (end > width) {
28873 end = width;
28876 uint32_t src_len0 = ((end - x) + inv_h0 - 1u) / inv_h0;
28877 uint32_t src_len1 = ((end - x) + inv_h1 - 1u) / inv_h1;
28878 uint32_t src_len2 = ((end - x) + inv_h2 - 1u) / inv_h2;
28879 uint32_t src_len3 = ((end - x) + inv_h3 - 1u) / inv_h3;
28880 total_src_len0 += src_len0;
28881 total_src_len1 += src_len1;
28882 total_src_len2 += src_len2;
28883 total_src_len3 += src_len3;
28885 const uint8_t* src_ptr_x0 = src0 + (x / inv_h0);
28886 const uint8_t* up0 = (*upfunc0)( //
28887 scratch_buffer_2k_ptr + (0u * 480u), //
28888 src_ptr_x0, //
28889 src_ptr_x0, //
28890 src_len0, //
28891 h1v2_bias, //
28892 first_column, //
28893 (total_src_len0 >= half_width_for_2to1));
28895 const uint8_t* src_ptr_x1 = src1 + (x / inv_h1);
28896 const uint8_t* up1 = (*upfunc1)( //
28897 scratch_buffer_2k_ptr + (1u * 480u), //
28898 src_ptr_x1, //
28899 src_ptr_x1, //
28900 src_len1, //
28901 h1v2_bias, //
28902 first_column, //
28903 (total_src_len1 >= half_width_for_2to1));
28905 const uint8_t* src_ptr_x2 = src2 + (x / inv_h2);
28906 const uint8_t* up2 = (*upfunc2)( //
28907 scratch_buffer_2k_ptr + (2u * 480u), //
28908 src_ptr_x2, //
28909 src_ptr_x2, //
28910 src_len2, //
28911 h1v2_bias, //
28912 first_column, //
28913 (total_src_len2 >= half_width_for_2to1));
28915 const uint8_t* src_ptr_x3 = src3 + (x / inv_h3);
28916 const uint8_t* up3 = (*upfunc3)( //
28917 scratch_buffer_2k_ptr + (3u * 480u), //
28918 src_ptr_x3, //
28919 src_ptr_x3, //
28920 src_len3, //
28921 h1v2_bias, //
28922 first_column, //
28923 (total_src_len3 >= half_width_for_2to1));
28925 (*conv4func)(dst, x, end, y, up0, up1, up2, up3);
28926 x = end;
28930 static void //
28931 wuffs_private_impl__swizzle_ycck__general__triangle_filter(
28932 wuffs_base__pixel_buffer* dst,
28933 uint32_t x_min_incl,
28934 uint32_t x_max_excl,
28935 uint32_t y_min_incl,
28936 uint32_t y_max_excl,
28937 const uint8_t* src_ptr0,
28938 const uint8_t* src_ptr1,
28939 const uint8_t* src_ptr2,
28940 const uint8_t* src_ptr3,
28941 uint32_t stride0,
28942 uint32_t stride1,
28943 uint32_t stride2,
28944 uint32_t stride3,
28945 uint32_t inv_h0,
28946 uint32_t inv_h1,
28947 uint32_t inv_h2,
28948 uint32_t inv_h3,
28949 uint32_t inv_v0,
28950 uint32_t inv_v1,
28951 uint32_t inv_v2,
28952 uint32_t inv_v3,
28953 uint32_t half_width_for_2to1,
28954 uint32_t half_height_for_2to1,
28955 uint8_t* scratch_buffer_2k_ptr,
28956 wuffs_private_impl__swizzle_ycc__upsample_func (*upfuncs)[4][4],
28957 wuffs_private_impl__swizzle_ycc__convert_4_func conv4func) {
28958 if ((x_min_incl != 0) || (y_min_incl != 0)) {
28959 return;
28962 wuffs_private_impl__swizzle_ycc__upsample_func upfunc0 =
28963 (*upfuncs)[(inv_h0 - 1u) & 3u][(inv_v0 - 1u) & 3u];
28964 wuffs_private_impl__swizzle_ycc__upsample_func upfunc1 =
28965 (*upfuncs)[(inv_h1 - 1u) & 3u][(inv_v1 - 1u) & 3u];
28966 wuffs_private_impl__swizzle_ycc__upsample_func upfunc2 =
28967 (*upfuncs)[(inv_h2 - 1u) & 3u][(inv_v2 - 1u) & 3u];
28968 wuffs_private_impl__swizzle_ycc__upsample_func upfunc3 =
28969 (*upfuncs)[(inv_h3 - 1u) & 3u][(inv_v3 - 1u) & 3u];
28971 // First row.
28972 uint32_t h1v2_bias = 1u;
28973 wuffs_private_impl__swizzle_ycck__general__triangle_filter_edge_row(
28974 dst, x_max_excl, 0u, //
28975 src_ptr0, src_ptr1, src_ptr2, src_ptr3, //
28976 stride0, stride1, stride2, stride3, //
28977 inv_h0, inv_h1, inv_h2, inv_h3, //
28978 inv_v0, inv_v1, inv_v2, inv_v3, //
28979 half_width_for_2to1, //
28980 h1v2_bias, //
28981 scratch_buffer_2k_ptr, //
28982 upfunc0, upfunc1, upfunc2, upfunc3, conv4func);
28983 h1v2_bias = 2u;
28985 // Middle rows.
28986 bool last_row = y_max_excl == 2u * half_height_for_2to1;
28987 uint32_t middle_y_max_excl = last_row ? (y_max_excl - 1u) : y_max_excl;
28988 uint32_t y;
28989 for (y = 1u; y < middle_y_max_excl; y++) {
28990 const uint8_t* src0_major = src_ptr0 + ((y / inv_v0) * (size_t)stride0);
28991 const uint8_t* src0_minor =
28992 (inv_v0 != 2u)
28993 ? src0_major
28994 : ((y & 1u) ? (src0_major + stride0) : (src0_major - stride0));
28995 const uint8_t* src1_major = src_ptr1 + ((y / inv_v1) * (size_t)stride1);
28996 const uint8_t* src1_minor =
28997 (inv_v1 != 2u)
28998 ? src1_major
28999 : ((y & 1u) ? (src1_major + stride1) : (src1_major - stride1));
29000 const uint8_t* src2_major = src_ptr2 + ((y / inv_v2) * (size_t)stride2);
29001 const uint8_t* src2_minor =
29002 (inv_v2 != 2u)
29003 ? src2_major
29004 : ((y & 1u) ? (src2_major + stride2) : (src2_major - stride2));
29005 const uint8_t* src3_major = src_ptr3 + ((y / inv_v3) * (size_t)stride3);
29006 const uint8_t* src3_minor =
29007 (inv_v3 != 2u)
29008 ? src3_major
29009 : ((y & 1u) ? (src3_major + stride3) : (src3_major - stride3));
29010 uint32_t total_src_len0 = 0u;
29011 uint32_t total_src_len1 = 0u;
29012 uint32_t total_src_len2 = 0u;
29013 uint32_t total_src_len3 = 0u;
29015 uint32_t x = 0u;
29016 while (x < x_max_excl) {
29017 bool first_column = x == 0u;
29018 uint32_t end = x + 480u;
29019 if (end > x_max_excl) {
29020 end = x_max_excl;
29023 uint32_t src_len0 = ((end - x) + inv_h0 - 1u) / inv_h0;
29024 uint32_t src_len1 = ((end - x) + inv_h1 - 1u) / inv_h1;
29025 uint32_t src_len2 = ((end - x) + inv_h2 - 1u) / inv_h2;
29026 uint32_t src_len3 = ((end - x) + inv_h3 - 1u) / inv_h3;
29027 total_src_len0 += src_len0;
29028 total_src_len1 += src_len1;
29029 total_src_len2 += src_len2;
29030 total_src_len3 += src_len3;
29032 const uint8_t* up0 = (*upfunc0)( //
29033 scratch_buffer_2k_ptr + (0u * 480u), //
29034 src0_major + (x / inv_h0), //
29035 src0_minor + (x / inv_h0), //
29036 src_len0, //
29037 h1v2_bias, //
29038 first_column, //
29039 (total_src_len0 >= half_width_for_2to1));
29041 const uint8_t* up1 = (*upfunc1)( //
29042 scratch_buffer_2k_ptr + (1u * 480u), //
29043 src1_major + (x / inv_h1), //
29044 src1_minor + (x / inv_h1), //
29045 src_len1, //
29046 h1v2_bias, //
29047 first_column, //
29048 (total_src_len1 >= half_width_for_2to1));
29050 const uint8_t* up2 = (*upfunc2)( //
29051 scratch_buffer_2k_ptr + (2u * 480u), //
29052 src2_major + (x / inv_h2), //
29053 src2_minor + (x / inv_h2), //
29054 src_len2, //
29055 h1v2_bias, //
29056 first_column, //
29057 (total_src_len2 >= half_width_for_2to1));
29059 const uint8_t* up3 = (*upfunc3)( //
29060 scratch_buffer_2k_ptr + (3u * 480u), //
29061 src3_major + (x / inv_h3), //
29062 src3_minor + (x / inv_h3), //
29063 src_len3, //
29064 h1v2_bias, //
29065 first_column, //
29066 (total_src_len3 >= half_width_for_2to1));
29068 (*conv4func)(dst, x, end, y, up0, up1, up2, up3);
29069 x = end;
29072 h1v2_bias ^= 3u;
29075 // Last row.
29076 if (middle_y_max_excl != y_max_excl) {
29077 wuffs_private_impl__swizzle_ycck__general__triangle_filter_edge_row(
29078 dst, x_max_excl, middle_y_max_excl, //
29079 src_ptr0, src_ptr1, src_ptr2, src_ptr3, //
29080 stride0, stride1, stride2, stride3, //
29081 inv_h0, inv_h1, inv_h2, inv_h3, //
29082 inv_v0, inv_v1, inv_v2, inv_v3, //
29083 half_width_for_2to1, //
29084 h1v2_bias, //
29085 scratch_buffer_2k_ptr, //
29086 upfunc0, upfunc1, upfunc2, upfunc3, conv4func);
29090 static void //
29091 wuffs_private_impl__swizzle_ycc__general__triangle_filter_edge_row(
29092 wuffs_base__pixel_buffer* dst,
29093 uint32_t width,
29094 uint32_t y,
29095 const uint8_t* src_ptr0,
29096 const uint8_t* src_ptr1,
29097 const uint8_t* src_ptr2,
29098 uint32_t stride0,
29099 uint32_t stride1,
29100 uint32_t stride2,
29101 uint32_t inv_h0,
29102 uint32_t inv_h1,
29103 uint32_t inv_h2,
29104 uint32_t inv_v0,
29105 uint32_t inv_v1,
29106 uint32_t inv_v2,
29107 uint32_t half_width_for_2to1,
29108 uint32_t h1v2_bias,
29109 uint8_t* scratch_buffer_2k_ptr,
29110 wuffs_private_impl__swizzle_ycc__upsample_func upfunc0,
29111 wuffs_private_impl__swizzle_ycc__upsample_func upfunc1,
29112 wuffs_private_impl__swizzle_ycc__upsample_func upfunc2,
29113 wuffs_private_impl__swizzle_ycc__convert_3_func conv3func) {
29114 const uint8_t* src0 = src_ptr0 + ((y / inv_v0) * (size_t)stride0);
29115 const uint8_t* src1 = src_ptr1 + ((y / inv_v1) * (size_t)stride1);
29116 const uint8_t* src2 = src_ptr2 + ((y / inv_v2) * (size_t)stride2);
29117 uint32_t total_src_len0 = 0u;
29118 uint32_t total_src_len1 = 0u;
29119 uint32_t total_src_len2 = 0u;
29121 uint32_t x = 0u;
29122 while (x < width) {
29123 bool first_column = x == 0u;
29124 uint32_t end = x + 672u;
29125 if (end > width) {
29126 end = width;
29129 uint32_t src_len0 = ((end - x) + inv_h0 - 1u) / inv_h0;
29130 uint32_t src_len1 = ((end - x) + inv_h1 - 1u) / inv_h1;
29131 uint32_t src_len2 = ((end - x) + inv_h2 - 1u) / inv_h2;
29132 total_src_len0 += src_len0;
29133 total_src_len1 += src_len1;
29134 total_src_len2 += src_len2;
29136 const uint8_t* src_ptr_x0 = src0 + (x / inv_h0);
29137 const uint8_t* up0 = (*upfunc0)( //
29138 scratch_buffer_2k_ptr + (0u * 672u), //
29139 src_ptr_x0, //
29140 src_ptr_x0, //
29141 src_len0, //
29142 h1v2_bias, //
29143 first_column, //
29144 (total_src_len0 >= half_width_for_2to1));
29146 const uint8_t* src_ptr_x1 = src1 + (x / inv_h1);
29147 const uint8_t* up1 = (*upfunc1)( //
29148 scratch_buffer_2k_ptr + (1u * 672u), //
29149 src_ptr_x1, //
29150 src_ptr_x1, //
29151 src_len1, //
29152 h1v2_bias, //
29153 first_column, //
29154 (total_src_len1 >= half_width_for_2to1));
29156 const uint8_t* src_ptr_x2 = src2 + (x / inv_h2);
29157 const uint8_t* up2 = (*upfunc2)( //
29158 scratch_buffer_2k_ptr + (2u * 672u), //
29159 src_ptr_x2, //
29160 src_ptr_x2, //
29161 src_len2, //
29162 h1v2_bias, //
29163 first_column, //
29164 (total_src_len2 >= half_width_for_2to1));
29166 (*conv3func)(dst, x, end, y, up0, up1, up2);
29167 x = end;
29171 static void //
29172 wuffs_private_impl__swizzle_ycc__general__triangle_filter(
29173 wuffs_base__pixel_buffer* dst,
29174 uint32_t x_min_incl,
29175 uint32_t x_max_excl,
29176 uint32_t y_min_incl,
29177 uint32_t y_max_excl,
29178 const uint8_t* src_ptr0,
29179 const uint8_t* src_ptr1,
29180 const uint8_t* src_ptr2,
29181 uint32_t stride0,
29182 uint32_t stride1,
29183 uint32_t stride2,
29184 uint32_t inv_h0,
29185 uint32_t inv_h1,
29186 uint32_t inv_h2,
29187 uint32_t inv_v0,
29188 uint32_t inv_v1,
29189 uint32_t inv_v2,
29190 uint32_t half_width_for_2to1,
29191 uint32_t half_height_for_2to1,
29192 uint8_t* scratch_buffer_2k_ptr,
29193 wuffs_private_impl__swizzle_ycc__upsample_func (*upfuncs)[4][4],
29194 wuffs_private_impl__swizzle_ycc__convert_3_func conv3func) {
29195 if ((x_min_incl != 0) || (y_min_incl != 0)) {
29196 return;
29199 wuffs_private_impl__swizzle_ycc__upsample_func upfunc0 =
29200 (*upfuncs)[(inv_h0 - 1u) & 3u][(inv_v0 - 1u) & 3u];
29201 wuffs_private_impl__swizzle_ycc__upsample_func upfunc1 =
29202 (*upfuncs)[(inv_h1 - 1u) & 3u][(inv_v1 - 1u) & 3u];
29203 wuffs_private_impl__swizzle_ycc__upsample_func upfunc2 =
29204 (*upfuncs)[(inv_h2 - 1u) & 3u][(inv_v2 - 1u) & 3u];
29206 // First row.
29207 uint32_t h1v2_bias = 1u;
29208 wuffs_private_impl__swizzle_ycc__general__triangle_filter_edge_row(
29209 dst, x_max_excl, 0u, //
29210 src_ptr0, src_ptr1, src_ptr2, //
29211 stride0, stride1, stride2, //
29212 inv_h0, inv_h1, inv_h2, //
29213 inv_v0, inv_v1, inv_v2, //
29214 half_width_for_2to1, //
29215 h1v2_bias, //
29216 scratch_buffer_2k_ptr, //
29217 upfunc0, upfunc1, upfunc2, conv3func);
29218 h1v2_bias = 2u;
29220 // Middle rows.
29221 bool last_row = y_max_excl == 2u * half_height_for_2to1;
29222 uint32_t middle_y_max_excl = last_row ? (y_max_excl - 1u) : y_max_excl;
29223 uint32_t y;
29224 for (y = 1u; y < middle_y_max_excl; y++) {
29225 const uint8_t* src0_major = src_ptr0 + ((y / inv_v0) * (size_t)stride0);
29226 const uint8_t* src0_minor =
29227 (inv_v0 != 2u)
29228 ? src0_major
29229 : ((y & 1u) ? (src0_major + stride0) : (src0_major - stride0));
29230 const uint8_t* src1_major = src_ptr1 + ((y / inv_v1) * (size_t)stride1);
29231 const uint8_t* src1_minor =
29232 (inv_v1 != 2u)
29233 ? src1_major
29234 : ((y & 1u) ? (src1_major + stride1) : (src1_major - stride1));
29235 const uint8_t* src2_major = src_ptr2 + ((y / inv_v2) * (size_t)stride2);
29236 const uint8_t* src2_minor =
29237 (inv_v2 != 2u)
29238 ? src2_major
29239 : ((y & 1u) ? (src2_major + stride2) : (src2_major - stride2));
29240 uint32_t total_src_len0 = 0u;
29241 uint32_t total_src_len1 = 0u;
29242 uint32_t total_src_len2 = 0u;
29244 uint32_t x = 0u;
29245 while (x < x_max_excl) {
29246 bool first_column = x == 0u;
29247 uint32_t end = x + 672u;
29248 if (end > x_max_excl) {
29249 end = x_max_excl;
29252 uint32_t src_len0 = ((end - x) + inv_h0 - 1u) / inv_h0;
29253 uint32_t src_len1 = ((end - x) + inv_h1 - 1u) / inv_h1;
29254 uint32_t src_len2 = ((end - x) + inv_h2 - 1u) / inv_h2;
29255 total_src_len0 += src_len0;
29256 total_src_len1 += src_len1;
29257 total_src_len2 += src_len2;
29259 const uint8_t* up0 = (*upfunc0)( //
29260 scratch_buffer_2k_ptr + (0u * 672u), //
29261 src0_major + (x / inv_h0), //
29262 src0_minor + (x / inv_h0), //
29263 src_len0, //
29264 h1v2_bias, //
29265 first_column, //
29266 (total_src_len0 >= half_width_for_2to1));
29268 const uint8_t* up1 = (*upfunc1)( //
29269 scratch_buffer_2k_ptr + (1u * 672u), //
29270 src1_major + (x / inv_h1), //
29271 src1_minor + (x / inv_h1), //
29272 src_len1, //
29273 h1v2_bias, //
29274 first_column, //
29275 (total_src_len1 >= half_width_for_2to1));
29277 const uint8_t* up2 = (*upfunc2)( //
29278 scratch_buffer_2k_ptr + (2u * 672u), //
29279 src2_major + (x / inv_h2), //
29280 src2_minor + (x / inv_h2), //
29281 src_len2, //
29282 h1v2_bias, //
29283 first_column, //
29284 (total_src_len2 >= half_width_for_2to1));
29286 (*conv3func)(dst, x, end, y, up0, up1, up2);
29287 x = end;
29290 h1v2_bias ^= 3u;
29293 // Last row.
29294 if (middle_y_max_excl != y_max_excl) {
29295 wuffs_private_impl__swizzle_ycc__general__triangle_filter_edge_row(
29296 dst, x_max_excl, middle_y_max_excl, //
29297 src_ptr0, src_ptr1, src_ptr2, //
29298 stride0, stride1, stride2, //
29299 inv_h0, inv_h1, inv_h2, //
29300 inv_v0, inv_v1, inv_v2, //
29301 half_width_for_2to1, //
29302 h1v2_bias, //
29303 scratch_buffer_2k_ptr, //
29304 upfunc0, upfunc1, upfunc2, conv3func);
29308 static void //
29309 wuffs_private_impl__swizzle_ycc__general__box_filter(
29310 wuffs_base__pixel_buffer* dst,
29311 uint32_t x_min_incl,
29312 uint32_t x_max_excl,
29313 uint32_t y_min_incl,
29314 uint32_t y_max_excl,
29315 const uint8_t* src_ptr0,
29316 const uint8_t* src_ptr1,
29317 const uint8_t* src_ptr2,
29318 uint32_t stride0,
29319 uint32_t stride1,
29320 uint32_t stride2,
29321 uint32_t inv_h0,
29322 uint32_t inv_h1,
29323 uint32_t inv_h2,
29324 uint32_t inv_v0,
29325 uint32_t inv_v1,
29326 uint32_t inv_v2,
29327 uint32_t half_width_for_2to1,
29328 uint32_t half_height_for_2to1,
29329 uint8_t* scratch_buffer_2k_ptr,
29330 wuffs_private_impl__swizzle_ycc__upsample_func (*upfuncs)[4][4],
29331 wuffs_private_impl__swizzle_ycc__convert_3_func conv3func) {
29332 wuffs_private_impl__swizzle_ycc__upsample_func upfunc0 =
29333 (*upfuncs)[(inv_h0 - 1u) & 3u][(inv_v0 - 1u) & 3u];
29334 wuffs_private_impl__swizzle_ycc__upsample_func upfunc1 =
29335 (*upfuncs)[(inv_h1 - 1u) & 3u][(inv_v1 - 1u) & 3u];
29336 wuffs_private_impl__swizzle_ycc__upsample_func upfunc2 =
29337 (*upfuncs)[(inv_h2 - 1u) & 3u][(inv_v2 - 1u) & 3u];
29339 uint32_t y;
29340 for (y = y_min_incl; y < y_max_excl; y++) {
29341 const uint8_t* src0_major =
29342 src_ptr0 + (((y - y_min_incl) / inv_v0) * (size_t)stride0);
29343 const uint8_t* src1_major =
29344 src_ptr1 + (((y - y_min_incl) / inv_v1) * (size_t)stride1);
29345 const uint8_t* src2_major =
29346 src_ptr2 + (((y - y_min_incl) / inv_v2) * (size_t)stride2);
29348 uint32_t x = x_min_incl;
29349 while (x < x_max_excl) {
29350 uint32_t end = x + 672u;
29351 if (end > x_max_excl) {
29352 end = x_max_excl;
29355 uint32_t src_len0 = ((end - x) + inv_h0 - 1u) / inv_h0;
29356 uint32_t src_len1 = ((end - x) + inv_h1 - 1u) / inv_h1;
29357 uint32_t src_len2 = ((end - x) + inv_h2 - 1u) / inv_h2;
29359 const uint8_t* up0 = (*upfunc0)( //
29360 scratch_buffer_2k_ptr + (0u * 672u), //
29361 src0_major + ((x - x_min_incl) / inv_h0), //
29362 src0_major + ((x - x_min_incl) / inv_h0), //
29363 src_len0, //
29364 0u, false, false);
29366 const uint8_t* up1 = (*upfunc1)( //
29367 scratch_buffer_2k_ptr + (1u * 672u), //
29368 src1_major + ((x - x_min_incl) / inv_h1), //
29369 src1_major + ((x - x_min_incl) / inv_h1), //
29370 src_len1, //
29371 0u, false, false);
29373 const uint8_t* up2 = (*upfunc2)( //
29374 scratch_buffer_2k_ptr + (2u * 672u), //
29375 src2_major + ((x - x_min_incl) / inv_h2), //
29376 src2_major + ((x - x_min_incl) / inv_h2), //
29377 src_len2, //
29378 0u, false, false);
29380 (*conv3func)(dst, x, end, y, up0, up1, up2);
29381 x = end;
29386 static void //
29387 wuffs_private_impl__swizzle_ycck__general__box_filter(
29388 wuffs_base__pixel_buffer* dst,
29389 uint32_t x_min_incl,
29390 uint32_t x_max_excl,
29391 uint32_t y_min_incl,
29392 uint32_t y_max_excl,
29393 const uint8_t* src_ptr0,
29394 const uint8_t* src_ptr1,
29395 const uint8_t* src_ptr2,
29396 const uint8_t* src_ptr3,
29397 uint32_t stride0,
29398 uint32_t stride1,
29399 uint32_t stride2,
29400 uint32_t stride3,
29401 uint32_t inv_h0,
29402 uint32_t inv_h1,
29403 uint32_t inv_h2,
29404 uint32_t inv_h3,
29405 uint32_t inv_v0,
29406 uint32_t inv_v1,
29407 uint32_t inv_v2,
29408 uint32_t inv_v3,
29409 uint32_t half_width_for_2to1,
29410 uint32_t half_height_for_2to1,
29411 uint8_t* scratch_buffer_2k_ptr,
29412 wuffs_private_impl__swizzle_ycc__upsample_func (*upfuncs)[4][4],
29413 wuffs_private_impl__swizzle_ycc__convert_4_func conv4func) {
29414 wuffs_private_impl__swizzle_ycc__upsample_func upfunc0 =
29415 (*upfuncs)[(inv_h0 - 1u) & 3u][(inv_v0 - 1u) & 3u];
29416 wuffs_private_impl__swizzle_ycc__upsample_func upfunc1 =
29417 (*upfuncs)[(inv_h1 - 1u) & 3u][(inv_v1 - 1u) & 3u];
29418 wuffs_private_impl__swizzle_ycc__upsample_func upfunc2 =
29419 (*upfuncs)[(inv_h2 - 1u) & 3u][(inv_v2 - 1u) & 3u];
29420 wuffs_private_impl__swizzle_ycc__upsample_func upfunc3 =
29421 (*upfuncs)[(inv_h3 - 1u) & 3u][(inv_v3 - 1u) & 3u];
29423 uint32_t y;
29424 for (y = y_min_incl; y < y_max_excl; y++) {
29425 const uint8_t* src0_major =
29426 src_ptr0 + (((y - y_min_incl) / inv_v0) * (size_t)stride0);
29427 const uint8_t* src1_major =
29428 src_ptr1 + (((y - y_min_incl) / inv_v1) * (size_t)stride1);
29429 const uint8_t* src2_major =
29430 src_ptr2 + (((y - y_min_incl) / inv_v2) * (size_t)stride2);
29431 const uint8_t* src3_major =
29432 src_ptr3 + (((y - y_min_incl) / inv_v3) * (size_t)stride3);
29434 uint32_t x = x_min_incl;
29435 while (x < x_max_excl) {
29436 uint32_t end = x + 480u;
29437 if (end > x_max_excl) {
29438 end = x_max_excl;
29441 uint32_t src_len0 = ((end - x) + inv_h0 - 1u) / inv_h0;
29442 uint32_t src_len1 = ((end - x) + inv_h1 - 1u) / inv_h1;
29443 uint32_t src_len2 = ((end - x) + inv_h2 - 1u) / inv_h2;
29444 uint32_t src_len3 = ((end - x) + inv_h3 - 1u) / inv_h3;
29446 const uint8_t* up0 = (*upfunc0)( //
29447 scratch_buffer_2k_ptr + (0u * 480u), //
29448 src0_major + ((x - x_min_incl) / inv_h0), //
29449 src0_major + ((x - x_min_incl) / inv_h0), //
29450 src_len0, //
29451 0u, false, false);
29453 const uint8_t* up1 = (*upfunc1)( //
29454 scratch_buffer_2k_ptr + (1u * 480u), //
29455 src1_major + ((x - x_min_incl) / inv_h1), //
29456 src1_major + ((x - x_min_incl) / inv_h1), //
29457 src_len1, //
29458 0u, false, false);
29460 const uint8_t* up2 = (*upfunc2)( //
29461 scratch_buffer_2k_ptr + (2u * 480u), //
29462 src2_major + ((x - x_min_incl) / inv_h2), //
29463 src2_major + ((x - x_min_incl) / inv_h2), //
29464 src_len2, //
29465 0u, false, false);
29467 const uint8_t* up3 = (*upfunc3)( //
29468 scratch_buffer_2k_ptr + (3u * 480u), //
29469 src3_major + ((x - x_min_incl) / inv_h3), //
29470 src3_major + ((x - x_min_incl) / inv_h3), //
29471 src_len3, //
29472 0u, false, false);
29474 (*conv4func)(dst, x, end, y, up0, up1, up2, up3);
29475 x = end;
29480 // --------
29482 // wuffs_private_impl__swizzle_flattened_length is like
29483 // wuffs_base__table__flattened_length but returns uint64_t (not size_t) and
29484 // also accounts for subsampling.
29485 static uint64_t //
29486 wuffs_private_impl__swizzle_flattened_length(uint32_t width,
29487 uint32_t height,
29488 uint32_t stride,
29489 uint32_t inv_h,
29490 uint32_t inv_v) {
29491 uint64_t scaled_width = (((uint64_t)width) + (inv_h - 1u)) / inv_h;
29492 uint64_t scaled_height = (((uint64_t)height) + (inv_v - 1u)) / inv_v;
29493 if (scaled_height <= 0u) {
29494 return 0u;
29496 return ((scaled_height - 1u) * stride) + scaled_width;
29499 WUFFS_BASE__MAYBE_STATIC wuffs_base__status //
29500 wuffs_base__pixel_swizzler__swizzle_ycck(
29501 const wuffs_base__pixel_swizzler* p,
29502 wuffs_base__pixel_buffer* dst,
29503 wuffs_base__slice_u8 dst_palette,
29504 uint32_t x_min_incl,
29505 uint32_t x_max_excl,
29506 uint32_t y_min_incl,
29507 uint32_t y_max_excl,
29508 wuffs_base__slice_u8 src0,
29509 wuffs_base__slice_u8 src1,
29510 wuffs_base__slice_u8 src2,
29511 wuffs_base__slice_u8 src3,
29512 uint32_t width0,
29513 uint32_t width1,
29514 uint32_t width2,
29515 uint32_t width3,
29516 uint32_t height0,
29517 uint32_t height1,
29518 uint32_t height2,
29519 uint32_t height3,
29520 uint32_t stride0,
29521 uint32_t stride1,
29522 uint32_t stride2,
29523 uint32_t stride3,
29524 uint8_t h0,
29525 uint8_t h1,
29526 uint8_t h2,
29527 uint8_t h3,
29528 uint8_t v0,
29529 uint8_t v1,
29530 uint8_t v2,
29531 uint8_t v3,
29532 bool is_rgb_or_cmyk,
29533 bool triangle_filter_for_2to1,
29534 wuffs_base__slice_u8 scratch_buffer_2k) {
29535 if (!p) {
29536 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
29537 } else if (!dst || //
29538 (x_min_incl > x_max_excl) || //
29539 (x_max_excl > 0xFFFFu) || //
29540 (y_min_incl > y_max_excl) || //
29541 (y_max_excl > 0xFFFFu) || //
29542 (4u <= ((unsigned int)h0 - 1u)) || //
29543 (4u <= ((unsigned int)h1 - 1u)) || //
29544 (4u <= ((unsigned int)h2 - 1u)) || //
29545 (4u <= ((unsigned int)v0 - 1u)) || //
29546 (4u <= ((unsigned int)v1 - 1u)) || //
29547 (4u <= ((unsigned int)v2 - 1u)) || //
29548 (triangle_filter_for_2to1 && ((x_min_incl | y_min_incl) > 0u)) ||
29549 (scratch_buffer_2k.len < 2048u)) {
29550 return wuffs_base__make_status(wuffs_base__error__bad_argument);
29552 if ((h3 != 0u) || (v3 != 0u)) {
29553 if ((4u <= ((unsigned int)h3 - 1u)) || //
29554 (4u <= ((unsigned int)v3 - 1u))) {
29555 return wuffs_base__make_status(wuffs_base__error__bad_argument);
29559 uint32_t max_incl_h = wuffs_private_impl__u32__max_of_4(h0, h1, h2, h3);
29560 uint32_t max_incl_v = wuffs_private_impl__u32__max_of_4(v0, v1, v2, v3);
29562 // Calculate the inverse h and v ratios.
29564 // It also canonicalizes (h=2 and max_incl_h=4) as equivalent to (h=1 and
29565 // max_incl_h=2). In both cases, the inv_h value is 2.
29566 uint32_t inv_h0 = max_incl_h / h0;
29567 uint32_t inv_h1 = max_incl_h / h1;
29568 uint32_t inv_h2 = max_incl_h / h2;
29569 uint32_t inv_h3 = h3 ? (max_incl_h / h3) : 0u;
29570 uint32_t inv_v0 = max_incl_v / v0;
29571 uint32_t inv_v1 = max_incl_v / v1;
29572 uint32_t inv_v2 = max_incl_v / v2;
29573 uint32_t inv_v3 = v3 ? (max_incl_v / v3) : 0u;
29575 if (x_min_incl != 0) {
29576 if ((x_min_incl % inv_h0) || (x_min_incl % inv_h1) ||
29577 (x_min_incl % inv_h2) || (inv_h3 && (x_min_incl % inv_h3))) {
29578 return wuffs_base__make_status(wuffs_base__error__bad_argument);
29581 if (y_min_incl != 0) {
29582 if ((y_min_incl % inv_v0) || (y_min_incl % inv_v1) ||
29583 (y_min_incl % inv_v2) || (inv_v3 && (y_min_incl % inv_v3))) {
29584 return wuffs_base__make_status(wuffs_base__error__bad_argument);
29588 uint32_t half_width_for_2to1 = ((x_max_excl - x_min_incl) + 1u) / 2u;
29589 if (inv_h0 == 2) {
29590 half_width_for_2to1 = wuffs_base__u32__min(half_width_for_2to1, width0);
29592 if (inv_h1 == 2) {
29593 half_width_for_2to1 = wuffs_base__u32__min(half_width_for_2to1, width1);
29595 if (inv_h2 == 2) {
29596 half_width_for_2to1 = wuffs_base__u32__min(half_width_for_2to1, width2);
29598 if (inv_h3 == 2) {
29599 half_width_for_2to1 = wuffs_base__u32__min(half_width_for_2to1, width3);
29602 uint32_t half_height_for_2to1 = ((y_max_excl - y_min_incl) + 1u) / 2u;
29603 if (inv_v0 == 2) {
29604 half_height_for_2to1 = wuffs_base__u32__min(half_height_for_2to1, height0);
29606 if (inv_v1 == 2) {
29607 half_height_for_2to1 = wuffs_base__u32__min(half_height_for_2to1, height1);
29609 if (inv_v2 == 2) {
29610 half_height_for_2to1 = wuffs_base__u32__min(half_height_for_2to1, height2);
29612 if (inv_v3 == 2) {
29613 half_height_for_2to1 = wuffs_base__u32__min(half_height_for_2to1, height3);
29616 x_max_excl = wuffs_base__u32__min( //
29617 wuffs_base__pixel_config__width(&dst->pixcfg), //
29618 x_min_incl + wuffs_private_impl__u32__min_of_5( //
29619 x_max_excl - x_min_incl, //
29620 width0 * inv_h0, //
29621 width1 * inv_h1, //
29622 width2 * inv_h2, //
29623 inv_h3 ? (width3 * inv_h3) : 0xFFFFFFFF));
29624 y_max_excl = wuffs_base__u32__min( //
29625 wuffs_base__pixel_config__height(&dst->pixcfg), //
29626 y_min_incl + wuffs_private_impl__u32__min_of_5( //
29627 y_max_excl - y_min_incl, //
29628 height0 * inv_v0, //
29629 height1 * inv_v1, //
29630 height2 * inv_v2, //
29631 inv_v3 ? (height3 * inv_v3) : 0xFFFFFFFF));
29633 if ((x_min_incl >= x_max_excl) || (y_min_incl >= y_max_excl)) {
29634 return wuffs_base__make_status(NULL);
29636 uint32_t width = x_max_excl - x_min_incl;
29637 uint32_t height = y_max_excl - y_min_incl;
29639 if (((h0 * inv_h0) != max_incl_h) || //
29640 ((h1 * inv_h1) != max_incl_h) || //
29641 ((h2 * inv_h2) != max_incl_h) || //
29642 ((v0 * inv_v0) != max_incl_v) || //
29643 ((v1 * inv_v1) != max_incl_v) || //
29644 ((v2 * inv_v2) != max_incl_v) || //
29645 (src0.len < wuffs_private_impl__swizzle_flattened_length(
29646 width, height, stride0, inv_h0, inv_v0)) ||
29647 (src1.len < wuffs_private_impl__swizzle_flattened_length(
29648 width, height, stride1, inv_h1, inv_v1)) ||
29649 (src2.len < wuffs_private_impl__swizzle_flattened_length(
29650 width, height, stride2, inv_h2, inv_v2))) {
29651 return wuffs_base__make_status(wuffs_base__error__bad_argument);
29653 if ((h3 != 0u) || (v3 != 0u)) {
29654 if (((h3 * inv_h3) != max_incl_h) || //
29655 ((v3 * inv_v3) != max_incl_v) || //
29656 (src3.len < wuffs_private_impl__swizzle_flattened_length(
29657 width, height, stride3, inv_h3, inv_v3))) {
29658 return wuffs_base__make_status(wuffs_base__error__bad_argument);
29662 if (wuffs_base__pixel_format__is_planar(&dst->pixcfg.private_impl.pixfmt)) {
29663 // TODO: see wuffs_base__pixel_buffer__set_color_u32_at's TODO.
29664 return wuffs_base__make_status(
29665 wuffs_base__error__unsupported_pixel_swizzler_option);
29668 // ----
29670 #if defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ENABLE_ALLOWLIST)
29671 switch (dst->pixcfg.private_impl.pixfmt.repr) {
29672 #if defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ALLOW_BGR_565)
29673 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
29674 break;
29675 #endif
29676 #if defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ALLOW_BGR)
29677 case WUFFS_BASE__PIXEL_FORMAT__BGR:
29678 break;
29679 #endif
29680 #if defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ALLOW_BGRA_NONPREMUL)
29681 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
29682 break;
29683 #endif
29684 #if defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ALLOW_BGRA_NONPREMUL_4X16LE)
29685 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
29686 break;
29687 #endif
29688 #if defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ALLOW_BGRA_PREMUL)
29689 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
29690 break;
29691 #endif
29692 #if defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ALLOW_RGB)
29693 case WUFFS_BASE__PIXEL_FORMAT__RGB:
29694 break;
29695 #endif
29696 #if defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ALLOW_RGBA_NONPREMUL)
29697 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
29698 break;
29699 #endif
29700 #if defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ALLOW_RGBA_PREMUL)
29701 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
29702 break;
29703 #endif
29704 default:
29705 return wuffs_base__make_status(
29706 wuffs_base__error__disabled_by_wuffs_config_dst_pixel_format_enable_allowlist);
29708 #else // defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ENABLE_ALLOWLIST)
29709 switch (dst->pixcfg.private_impl.pixfmt.repr) {
29710 case WUFFS_BASE__PIXEL_FORMAT__Y:
29711 case WUFFS_BASE__PIXEL_FORMAT__Y_16LE:
29712 case WUFFS_BASE__PIXEL_FORMAT__Y_16BE:
29713 case WUFFS_BASE__PIXEL_FORMAT__YA_NONPREMUL:
29714 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:
29715 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL:
29716 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY:
29717 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
29718 case WUFFS_BASE__PIXEL_FORMAT__BGR:
29719 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
29720 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
29721 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
29722 case WUFFS_BASE__PIXEL_FORMAT__BGRX:
29723 case WUFFS_BASE__PIXEL_FORMAT__RGB:
29724 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
29725 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
29726 case WUFFS_BASE__PIXEL_FORMAT__RGBX:
29727 break;
29729 default:
29730 // TODO: see wuffs_base__pixel_buffer__set_color_u32_at's TODO.
29731 return wuffs_base__make_status(
29732 wuffs_base__error__unsupported_pixel_swizzler_option);
29734 #endif // defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ENABLE_ALLOWLIST)
29736 // ----
29738 wuffs_private_impl__swizzle_ycc__convert_3_func conv3func = NULL;
29740 if (is_rgb_or_cmyk) {
29741 conv3func = &wuffs_private_impl__swizzle_rgb__convert_3_general;
29742 } else {
29743 switch (dst->pixcfg.private_impl.pixfmt.repr) {
29744 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
29745 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
29746 case WUFFS_BASE__PIXEL_FORMAT__BGRX:
29747 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3)
29748 if (wuffs_base__cpu_arch__have_x86_avx2()) {
29749 conv3func = &wuffs_private_impl__swizzle_ycc__convert_3_bgrx_x86_avx2;
29750 break;
29752 #endif
29753 conv3func = &wuffs_private_impl__swizzle_ycc__convert_3_bgrx;
29754 break;
29755 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
29756 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
29757 case WUFFS_BASE__PIXEL_FORMAT__RGBX:
29758 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3)
29759 if (wuffs_base__cpu_arch__have_x86_avx2()) {
29760 conv3func = &wuffs_private_impl__swizzle_ycc__convert_3_rgbx_x86_avx2;
29761 break;
29763 #endif
29764 conv3func = &wuffs_private_impl__swizzle_ycc__convert_3_rgbx;
29765 break;
29766 default:
29767 conv3func = &wuffs_private_impl__swizzle_ycc__convert_3_general;
29768 break;
29772 void (*func3)(wuffs_base__pixel_buffer * dst, //
29773 uint32_t x_min_incl, //
29774 uint32_t x_max_excl, //
29775 uint32_t y_min_incl, //
29776 uint32_t y_max_excl, //
29777 const uint8_t* src_ptr0, //
29778 const uint8_t* src_ptr1, //
29779 const uint8_t* src_ptr2, //
29780 uint32_t stride0, //
29781 uint32_t stride1, //
29782 uint32_t stride2, //
29783 uint32_t inv_h0, //
29784 uint32_t inv_h1, //
29785 uint32_t inv_h2, //
29786 uint32_t inv_v0, //
29787 uint32_t inv_v1, //
29788 uint32_t inv_v2, //
29789 uint32_t half_width_for_2to1, //
29790 uint32_t half_height_for_2to1, //
29791 uint8_t* scratch_buffer_2k_ptr, //
29792 wuffs_private_impl__swizzle_ycc__upsample_func(*upfuncs)[4][4],
29793 wuffs_private_impl__swizzle_ycc__convert_3_func conv3func) =
29794 &wuffs_private_impl__swizzle_ycc__general__box_filter;
29796 void (*func4)(wuffs_base__pixel_buffer * dst, //
29797 uint32_t x_min_incl, //
29798 uint32_t x_max_excl, //
29799 uint32_t y_min_incl, //
29800 uint32_t y_max_excl, //
29801 const uint8_t* src_ptr0, //
29802 const uint8_t* src_ptr1, //
29803 const uint8_t* src_ptr2, //
29804 const uint8_t* src_ptr3, //
29805 uint32_t stride0, //
29806 uint32_t stride1, //
29807 uint32_t stride2, //
29808 uint32_t stride3, //
29809 uint32_t inv_h0, //
29810 uint32_t inv_h1, //
29811 uint32_t inv_h2, //
29812 uint32_t inv_h3, //
29813 uint32_t inv_v0, //
29814 uint32_t inv_v1, //
29815 uint32_t inv_v2, //
29816 uint32_t inv_v3, //
29817 uint32_t half_width_for_2to1, //
29818 uint32_t half_height_for_2to1, //
29819 uint8_t* scratch_buffer_2k_ptr, //
29820 wuffs_private_impl__swizzle_ycc__upsample_func(*upfuncs)[4][4],
29821 wuffs_private_impl__swizzle_ycc__convert_4_func conv4func) =
29822 &wuffs_private_impl__swizzle_ycck__general__box_filter;
29824 wuffs_private_impl__swizzle_ycc__upsample_func upfuncs[4][4];
29825 memcpy(&upfuncs, &wuffs_private_impl__swizzle_ycc__upsample_funcs,
29826 sizeof upfuncs);
29828 if (triangle_filter_for_2to1 &&
29829 (wuffs_private_impl__swizzle_has_triangle_upsampler(inv_h0, inv_v0) ||
29830 wuffs_private_impl__swizzle_has_triangle_upsampler(inv_h1, inv_v1) ||
29831 wuffs_private_impl__swizzle_has_triangle_upsampler(inv_h2, inv_v2) ||
29832 wuffs_private_impl__swizzle_has_triangle_upsampler(inv_h3, inv_v3))) {
29833 func3 = &wuffs_private_impl__swizzle_ycc__general__triangle_filter;
29834 func4 = &wuffs_private_impl__swizzle_ycck__general__triangle_filter;
29836 upfuncs[0][1] = wuffs_private_impl__swizzle_ycc__upsample_inv_h1v2_triangle;
29837 upfuncs[1][0] = wuffs_private_impl__swizzle_ycc__upsample_inv_h2v1_triangle;
29838 upfuncs[1][1] = wuffs_private_impl__swizzle_ycc__upsample_inv_h2v2_triangle;
29840 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3)
29841 #if defined(__GNUC__) && !defined(__clang__)
29842 // Don't use our AVX2 implementation for GCC (but do use it for clang). For
29843 // some unknown reason, GCC performs noticably better on the non-SIMD
29844 // version. Possibly because GCC's auto-vectorizer is smarter (just with
29845 // SSE2, not AVX2) than our hand-written code, but that's just a guess.
29847 // See commits 51bc60ef9298cb2efc1b29a9681191f66d49820d and
29848 // cd769a0cdf1b5affee13f6089b995f3d39569cb4 for benchmark numbers.
29850 // See also https://godbolt.org/z/MbhbPGEz4 for Debian Bullseye's clang 11
29851 // versus gcc 10, where only gcc auto-vectorizes, although later clang
29852 // versions will also auto-vectorize.
29853 #else
29854 if (wuffs_base__cpu_arch__have_x86_avx2()) {
29855 upfuncs[1][1] =
29856 wuffs_private_impl__swizzle_ycc__upsample_inv_h2v2_triangle_x86_avx2;
29858 #endif
29859 #endif
29862 if ((h3 != 0u) || (v3 != 0u)) {
29863 wuffs_private_impl__swizzle_ycc__convert_4_func conv4func =
29864 is_rgb_or_cmyk ? &wuffs_private_impl__swizzle_cmyk__convert_4_general
29865 : &wuffs_private_impl__swizzle_ycck__convert_4_general;
29866 (*func4)( //
29867 dst, x_min_incl, x_max_excl, y_min_incl, y_max_excl, //
29868 src0.ptr, src1.ptr, src2.ptr, src3.ptr, //
29869 stride0, stride1, stride2, stride3, //
29870 inv_h0, inv_h1, inv_h2, inv_h3, //
29871 inv_v0, inv_v1, inv_v2, inv_v3, //
29872 half_width_for_2to1, half_height_for_2to1, //
29873 scratch_buffer_2k.ptr, &upfuncs, conv4func);
29875 } else {
29876 (*func3)( //
29877 dst, x_min_incl, x_max_excl, y_min_incl, y_max_excl, //
29878 src0.ptr, src1.ptr, src2.ptr, //
29879 stride0, stride1, stride2, //
29880 inv_h0, inv_h1, inv_h2, //
29881 inv_v0, inv_v1, inv_v2, //
29882 half_width_for_2to1, half_height_for_2to1, //
29883 scratch_buffer_2k.ptr, &upfuncs, conv3func);
29886 return wuffs_base__make_status(NULL);
29889 // --------
29891 // ‼ WUFFS MULTI-FILE SECTION +x86_avx2
29892 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3)
29893 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2")
29894 static void //
29895 wuffs_private_impl__swizzle_ycc__convert_3_bgrx_x86_avx2(
29896 wuffs_base__pixel_buffer* dst,
29897 uint32_t x,
29898 uint32_t x_end,
29899 uint32_t y,
29900 const uint8_t* up0,
29901 const uint8_t* up1,
29902 const uint8_t* up2) {
29903 if ((x + 32u) > x_end) {
29904 wuffs_private_impl__swizzle_ycc__convert_3_bgrx( //
29905 dst, x, x_end, y, up0, up1, up2);
29906 return;
29909 size_t dst_stride = dst->private_impl.planes[0].stride;
29910 uint8_t* dst_iter = dst->private_impl.planes[0].ptr +
29911 (dst_stride * ((size_t)y)) + (4u * ((size_t)x));
29913 // u0001 = u16x16 [0x0001 .. 0x0001]
29914 // u00FF = u16x16 [0x00FF .. 0x00FF]
29915 // uFF80 = u16x16 [0xFF80 .. 0xFF80]
29916 // uFFFF = u16x16 [0xFFFF .. 0xFFFF]
29917 const __m256i u0001 = _mm256_set1_epi16(+0x0001);
29918 const __m256i u00FF = _mm256_set1_epi16(+0x00FF);
29919 const __m256i uFF80 = _mm256_set1_epi16(-0x0080);
29920 const __m256i uFFFF = _mm256_set1_epi16(-0x0001);
29922 // p8000_p0000 = u16x16 [0x8000 0x0000 .. 0x8000 0x0000]
29923 const __m256i p8000_p0000 = _mm256_set_epi16( //
29924 +0x0000, -0x8000, +0x0000, -0x8000, //
29925 +0x0000, -0x8000, +0x0000, -0x8000, //
29926 +0x0000, -0x8000, +0x0000, -0x8000, //
29927 +0x0000, -0x8000, +0x0000, -0x8000);
29929 // Per wuffs_base__color_ycc__as__color_u32, the formulae:
29931 // R = Y + 1.40200 * Cr
29932 // G = Y - 0.34414 * Cb - 0.71414 * Cr
29933 // B = Y + 1.77200 * Cb
29935 // When scaled by 1<<16:
29937 // 0.34414 becomes 0x0581A = 22554.
29938 // 0.71414 becomes 0x0B6D2 = 46802.
29939 // 1.40200 becomes 0x166E9 = 91881.
29940 // 1.77200 becomes 0x1C5A2 = 116130.
29942 // Separate the integer and fractional parts, since we work with signed
29943 // 16-bit SIMD lanes. The fractional parts range from -0.5 .. +0.5 (as
29944 // floating-point) which is from -0x8000 .. +0x8000 (as fixed-point).
29946 // -0x3A5E = -0x20000 + 0x1C5A2 The B:Cb factor.
29947 // +0x66E9 = -0x10000 + 0x166E9 The R:Cr factor.
29948 // -0x581A = +0x00000 - 0x0581A The G:Cb factor.
29949 // +0x492E = +0x10000 - 0x0B6D2 The G:Cr factor.
29950 const __m256i m3A5E = _mm256_set1_epi16(-0x3A5E);
29951 const __m256i p66E9 = _mm256_set1_epi16(+0x66E9);
29952 const __m256i m581A_p492E = _mm256_set_epi16( //
29953 +0x492E, -0x581A, +0x492E, -0x581A, //
29954 +0x492E, -0x581A, +0x492E, -0x581A, //
29955 +0x492E, -0x581A, +0x492E, -0x581A, //
29956 +0x492E, -0x581A, +0x492E, -0x581A);
29958 while (x < x_end) {
29959 // Load chroma values in even and odd columns (the high 8 bits of each
29960 // u16x16 element are zero) and then subtract 0x0080.
29962 // cb_all = u8x32 [cb.00 cb.01 cb.02 cb.03 .. cb.1C cb.1D cb.1E cb.1F]
29963 // cb_eve = i16x16 [cb.00-0x80 cb.02-0x80 .. cb.1C-0x80 cb.1E-0x80 ]
29964 // cb_odd = i16x16 [cb.01-0x80 cb.03-0x80 .. cb.1D-0x80 cb.1F-0x80 ]
29966 // Ditto for the cr_xxx Chroma-Red values.
29967 __m256i cb_all = _mm256_lddqu_si256((const __m256i*)(const void*)up1);
29968 __m256i cr_all = _mm256_lddqu_si256((const __m256i*)(const void*)up2);
29969 __m256i cb_eve = _mm256_add_epi16(uFF80, _mm256_and_si256(cb_all, u00FF));
29970 __m256i cr_eve = _mm256_add_epi16(uFF80, _mm256_and_si256(cr_all, u00FF));
29971 __m256i cb_odd = _mm256_add_epi16(uFF80, _mm256_srli_epi16(cb_all, 8));
29972 __m256i cr_odd = _mm256_add_epi16(uFF80, _mm256_srli_epi16(cr_all, 8));
29974 // ----
29976 // Calculate:
29978 // B-Y = (+1.77200 * Cb) as floating-point
29979 // R-Y = (+1.40200 * Cr) as floating-point
29981 // B-Y = ((0x2_0000 - 0x3A5E) * Cb) as fixed-point
29982 // R-Y = ((0x1_0000 + 0x66E9) * Cr) as fixed-point
29984 // B-Y = ((-0x3A5E * Cb) + ("2.0" * Cb))
29985 // R-Y = ((+0x66E9 * Cr) + ("1.0" * Cr))
29987 // Multiply by m3A5E or p66E9, taking the high 16 bits. There's also a
29988 // doubling (add x to itself), adding-of-1 and halving (shift right by 1).
29989 // That makes multiply-and-take-high round to nearest (instead of down).
29990 __m256i tmp_by_eve = _mm256_srai_epi16(
29991 _mm256_add_epi16(
29992 _mm256_mulhi_epi16(_mm256_add_epi16(cb_eve, cb_eve), m3A5E), u0001),
29994 __m256i tmp_by_odd = _mm256_srai_epi16(
29995 _mm256_add_epi16(
29996 _mm256_mulhi_epi16(_mm256_add_epi16(cb_odd, cb_odd), m3A5E), u0001),
29998 __m256i tmp_ry_eve = _mm256_srai_epi16(
29999 _mm256_add_epi16(
30000 _mm256_mulhi_epi16(_mm256_add_epi16(cr_eve, cr_eve), p66E9), u0001),
30002 __m256i tmp_ry_odd = _mm256_srai_epi16(
30003 _mm256_add_epi16(
30004 _mm256_mulhi_epi16(_mm256_add_epi16(cr_odd, cr_odd), p66E9), u0001),
30007 // Add (2 * Cb) and (1 * Cr).
30008 __m256i by_eve =
30009 _mm256_add_epi16(tmp_by_eve, _mm256_add_epi16(cb_eve, cb_eve));
30010 __m256i by_odd =
30011 _mm256_add_epi16(tmp_by_odd, _mm256_add_epi16(cb_odd, cb_odd));
30012 __m256i ry_eve = _mm256_add_epi16(tmp_ry_eve, cr_eve);
30013 __m256i ry_odd = _mm256_add_epi16(tmp_ry_odd, cr_odd);
30015 // ----
30017 // Calculate:
30019 // G-Y = (-0.34414 * Cb) +
30020 // (-0.71414 * Cr) as floating-point
30022 // G-Y = ((+0x0_0000 - 0x581A) * Cb) +
30023 // ((-0x1_0000 + 0x492E) * Cr) as fixed-point
30025 // G-Y = (-0x581A * Cb) +
30026 // (+0x492E * Cr) - ("1.0" * Cr)
30028 // Multiply-add to get ((-0x581A * Cb) + (+0x492E * Cr)).
30029 __m256i tmp0_gy_eve_lo = _mm256_madd_epi16( //
30030 _mm256_unpacklo_epi16(cb_eve, cr_eve), m581A_p492E);
30031 __m256i tmp0_gy_eve_hi = _mm256_madd_epi16( //
30032 _mm256_unpackhi_epi16(cb_eve, cr_eve), m581A_p492E);
30033 __m256i tmp0_gy_odd_lo = _mm256_madd_epi16( //
30034 _mm256_unpacklo_epi16(cb_odd, cr_odd), m581A_p492E);
30035 __m256i tmp0_gy_odd_hi = _mm256_madd_epi16( //
30036 _mm256_unpackhi_epi16(cb_odd, cr_odd), m581A_p492E);
30038 // Divide the i32x8 vectors by (1 << 16), rounding to nearest.
30039 __m256i tmp1_gy_eve_lo =
30040 _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_eve_lo, p8000_p0000), 16);
30041 __m256i tmp1_gy_eve_hi =
30042 _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_eve_hi, p8000_p0000), 16);
30043 __m256i tmp1_gy_odd_lo =
30044 _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_odd_lo, p8000_p0000), 16);
30045 __m256i tmp1_gy_odd_hi =
30046 _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_odd_hi, p8000_p0000), 16);
30048 // Pack the ((-0x581A * Cb) + (+0x492E * Cr)) as i16x16 and subtract Cr.
30049 __m256i gy_eve = _mm256_sub_epi16(
30050 _mm256_packs_epi32(tmp1_gy_eve_lo, tmp1_gy_eve_hi), cr_eve);
30051 __m256i gy_odd = _mm256_sub_epi16(
30052 _mm256_packs_epi32(tmp1_gy_odd_lo, tmp1_gy_odd_hi), cr_odd);
30054 // ----
30056 // Add Y to (B-Y), (G-Y) and (R-Y) to produce B, G and R.
30058 // For the resultant packed_x_xxx vectors, only elements 0 ..= 7 and 16 ..=
30059 // 23 of the 32-element vectors matter (since we'll unpacklo but not
30060 // unpackhi them). Let … denote 8 ignored consecutive u8 values and let %
30061 // denote 0xFF. We'll end this section with:
30063 // packed_b_eve = u8x32 [b00 b02 .. b0C b0E … b10 b12 .. b1C b1E …]
30064 // packed_b_odd = u8x32 [b01 b03 .. b0D b0F … b11 b13 .. b1D b1F …]
30065 // packed_g_eve = u8x32 [g00 g02 .. g0C g0E … g10 g12 .. g1C g1E …]
30066 // packed_g_odd = u8x32 [g01 g03 .. g0D g0F … g11 g13 .. g1D g1F …]
30067 // packed_r_eve = u8x32 [r00 r02 .. r0C r0E … r10 r12 .. r1C r1E …]
30068 // packed_r_odd = u8x32 [r01 r03 .. r0D r0F … r11 r13 .. r1D r1F …]
30069 // uFFFF = u8x32 [ % % .. % % … % % .. % % …]
30071 __m256i yy_all = _mm256_lddqu_si256((const __m256i*)(const void*)up0);
30072 __m256i yy_eve = _mm256_and_si256(yy_all, u00FF);
30073 __m256i yy_odd = _mm256_srli_epi16(yy_all, 8);
30075 __m256i loose_b_eve = _mm256_add_epi16(by_eve, yy_eve);
30076 __m256i loose_b_odd = _mm256_add_epi16(by_odd, yy_odd);
30077 __m256i packed_b_eve = _mm256_packus_epi16(loose_b_eve, loose_b_eve);
30078 __m256i packed_b_odd = _mm256_packus_epi16(loose_b_odd, loose_b_odd);
30080 __m256i loose_g_eve = _mm256_add_epi16(gy_eve, yy_eve);
30081 __m256i loose_g_odd = _mm256_add_epi16(gy_odd, yy_odd);
30082 __m256i packed_g_eve = _mm256_packus_epi16(loose_g_eve, loose_g_eve);
30083 __m256i packed_g_odd = _mm256_packus_epi16(loose_g_odd, loose_g_odd);
30085 __m256i loose_r_eve = _mm256_add_epi16(ry_eve, yy_eve);
30086 __m256i loose_r_odd = _mm256_add_epi16(ry_odd, yy_odd);
30087 __m256i packed_r_eve = _mm256_packus_epi16(loose_r_eve, loose_r_eve);
30088 __m256i packed_r_odd = _mm256_packus_epi16(loose_r_odd, loose_r_odd);
30090 // ----
30092 // Mix those values (unpacking in 8, 16 and then 32 bit units) to get the
30093 // desired BGRX/RGBX order.
30095 // From here onwards, all of our __m256i registers are u8x32.
30097 // mix00 = [b00 g00 b02 g02 .. b0E g0E b10 g10 .. b1C g1C b1E g1E]
30098 // mix01 = [b01 g01 b03 g03 .. b0F g0F b11 g11 .. b1D g1D b1F g1F]
30099 // mix02 = [r00 % r02 % .. r0E % r10 % .. r1C % r1E %]
30100 // mix03 = [r01 % r03 % .. r0F % r11 % .. r1D % r1F %]
30102 // See also § below.
30103 __m256i mix00 = _mm256_unpacklo_epi8(packed_b_eve, packed_g_eve);
30104 __m256i mix01 = _mm256_unpacklo_epi8(packed_b_odd, packed_g_odd);
30105 __m256i mix02 = _mm256_unpacklo_epi8(packed_r_eve, uFFFF);
30106 __m256i mix03 = _mm256_unpacklo_epi8(packed_r_odd, uFFFF);
30108 // mix10 = [b00 g00 r00 % b02 g02 r02 % b04 g04 r04 % b06 g06 r06 %
30109 // b10 g10 r10 % b12 g12 r12 % b14 g14 r14 % b16 g16 r16 %]
30110 // mix11 = [b01 g01 r01 % b03 g03 r03 % b05 g05 r05 % b07 g07 r07 %
30111 // b11 g11 r11 % b13 g13 r13 % b15 g15 r15 % b17 g17 r17 %]
30112 // mix12 = [b08 g08 r08 % b0A g0A r0A % b0C g0C r0C % b0E g0E r0E %
30113 // b18 g18 r18 % b1A g1A r1A % b1C g1C r1C % b1E g1E r1E %]
30114 // mix13 = [b09 g09 r09 % b0B g0B r0B % b0D g0D r0D % b0F g0F r0F %
30115 // b19 g19 r19 % b1B g1B r1B % b1D g1D r1D % b1F g1F r1F %]
30116 __m256i mix10 = _mm256_unpacklo_epi16(mix00, mix02);
30117 __m256i mix11 = _mm256_unpacklo_epi16(mix01, mix03);
30118 __m256i mix12 = _mm256_unpackhi_epi16(mix00, mix02);
30119 __m256i mix13 = _mm256_unpackhi_epi16(mix01, mix03);
30121 // mix20 = [b00 g00 r00 % b01 g01 r01 % b02 g02 r02 % b03 g03 r03 %
30122 // b10 g10 r10 % b11 g11 r11 % b12 g12 r12 % b13 g13 r13 %]
30123 // mix21 = [b04 g04 r04 % b05 g05 r05 % b06 g06 r06 % b07 g07 r07 %
30124 // b14 g14 r14 % b15 g15 r15 % b16 g16 r16 % b17 g17 r17 %]
30125 // mix22 = [b08 g08 r08 % b09 g09 r09 % b0A g0A r0A % b0B g0B r0B %
30126 // b18 g18 r18 % b19 g19 r19 % b1A g1A r1A % b1B g1B r1B %]
30127 // mix23 = [b0C g0C r0C % b0D g0D r0D % b0E g0E r0E % b0F g0F r0F %
30128 // b1C g1C r1C % b1D g1D r1D % b1E g1E r1E % b1F g1F r1F %]
30129 __m256i mix20 = _mm256_unpacklo_epi32(mix10, mix11);
30130 __m256i mix21 = _mm256_unpackhi_epi32(mix10, mix11);
30131 __m256i mix22 = _mm256_unpacklo_epi32(mix12, mix13);
30132 __m256i mix23 = _mm256_unpackhi_epi32(mix12, mix13);
30134 // mix30 = [b00 g00 r00 % b01 g01 r01 % b02 g02 r02 % b03 g03 r03 %
30135 // b04 g04 r04 % b05 g05 r05 % b06 g06 r06 % b07 g07 r07 %]
30136 // mix31 = [b08 g08 r08 % b09 g09 r09 % b0A g0A r0A % b0B g0B r0B %
30137 // b0C g0C r0C % b0D g0D r0D % b0E g0E r0E % b0F g0F r0F %]
30138 // mix32 = [b10 g10 r10 % b11 g11 r11 % b12 g12 r12 % b13 g13 r13 %
30139 // b14 g14 r14 % b15 g15 r15 % b16 g16 r16 % b17 g17 r17 %]
30140 // mix33 = [b18 g18 r18 % b19 g19 r19 % b1A g1A r1A % b1B g1B r1B %
30141 // b1C g1C r1C % b1D g1D r1D % b1E g1E r1E % b1F g1F r1F %]
30142 __m256i mix30 = _mm256_permute2x128_si256(mix20, mix21, 0x20);
30143 __m256i mix31 = _mm256_permute2x128_si256(mix22, mix23, 0x20);
30144 __m256i mix32 = _mm256_permute2x128_si256(mix20, mix21, 0x31);
30145 __m256i mix33 = _mm256_permute2x128_si256(mix22, mix23, 0x31);
30147 // Write out four u8x32 SIMD registers (128 bytes, 32 BGRX/RGBX pixels).
30148 _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x00), mix30);
30149 _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x20), mix31);
30150 _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x40), mix32);
30151 _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x60), mix33);
30153 // Advance by up to 32 pixels. The first iteration might be smaller than 32
30154 // so that all of the remaining steps are exactly 32.
30155 uint32_t n = 32u - (31u & (x - x_end));
30156 dst_iter += 4u * n;
30157 up0 += n;
30158 up1 += n;
30159 up2 += n;
30160 x += n;
30164 // The rgbx flavor (below) is exactly the same as the bgrx flavor (above)
30165 // except for the lines marked with a § and that comments were stripped.
30166 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2")
30167 static void //
30168 wuffs_private_impl__swizzle_ycc__convert_3_rgbx_x86_avx2(
30169 wuffs_base__pixel_buffer* dst,
30170 uint32_t x,
30171 uint32_t x_end,
30172 uint32_t y,
30173 const uint8_t* up0,
30174 const uint8_t* up1,
30175 const uint8_t* up2) {
30176 if ((x + 32u) > x_end) {
30177 wuffs_private_impl__swizzle_ycc__convert_3_bgrx( //
30178 dst, x, x_end, y, up0, up1, up2);
30179 return;
30182 size_t dst_stride = dst->private_impl.planes[0].stride;
30183 uint8_t* dst_iter = dst->private_impl.planes[0].ptr +
30184 (dst_stride * ((size_t)y)) + (4u * ((size_t)x));
30186 const __m256i u0001 = _mm256_set1_epi16(+0x0001);
30187 const __m256i u00FF = _mm256_set1_epi16(+0x00FF);
30188 const __m256i uFF80 = _mm256_set1_epi16(-0x0080);
30189 const __m256i uFFFF = _mm256_set1_epi16(-0x0001);
30191 const __m256i p8000_p0000 = _mm256_set_epi16( //
30192 +0x0000, -0x8000, +0x0000, -0x8000, //
30193 +0x0000, -0x8000, +0x0000, -0x8000, //
30194 +0x0000, -0x8000, +0x0000, -0x8000, //
30195 +0x0000, -0x8000, +0x0000, -0x8000);
30197 const __m256i m3A5E = _mm256_set1_epi16(-0x3A5E);
30198 const __m256i p66E9 = _mm256_set1_epi16(+0x66E9);
30199 const __m256i m581A_p492E = _mm256_set_epi16( //
30200 +0x492E, -0x581A, +0x492E, -0x581A, //
30201 +0x492E, -0x581A, +0x492E, -0x581A, //
30202 +0x492E, -0x581A, +0x492E, -0x581A, //
30203 +0x492E, -0x581A, +0x492E, -0x581A);
30205 while (x < x_end) {
30206 __m256i cb_all = _mm256_lddqu_si256((const __m256i*)(const void*)up1);
30207 __m256i cr_all = _mm256_lddqu_si256((const __m256i*)(const void*)up2);
30208 __m256i cb_eve = _mm256_add_epi16(uFF80, _mm256_and_si256(cb_all, u00FF));
30209 __m256i cr_eve = _mm256_add_epi16(uFF80, _mm256_and_si256(cr_all, u00FF));
30210 __m256i cb_odd = _mm256_add_epi16(uFF80, _mm256_srli_epi16(cb_all, 8));
30211 __m256i cr_odd = _mm256_add_epi16(uFF80, _mm256_srli_epi16(cr_all, 8));
30213 __m256i tmp_by_eve = _mm256_srai_epi16(
30214 _mm256_add_epi16(
30215 _mm256_mulhi_epi16(_mm256_add_epi16(cb_eve, cb_eve), m3A5E), u0001),
30217 __m256i tmp_by_odd = _mm256_srai_epi16(
30218 _mm256_add_epi16(
30219 _mm256_mulhi_epi16(_mm256_add_epi16(cb_odd, cb_odd), m3A5E), u0001),
30221 __m256i tmp_ry_eve = _mm256_srai_epi16(
30222 _mm256_add_epi16(
30223 _mm256_mulhi_epi16(_mm256_add_epi16(cr_eve, cr_eve), p66E9), u0001),
30225 __m256i tmp_ry_odd = _mm256_srai_epi16(
30226 _mm256_add_epi16(
30227 _mm256_mulhi_epi16(_mm256_add_epi16(cr_odd, cr_odd), p66E9), u0001),
30230 __m256i by_eve =
30231 _mm256_add_epi16(tmp_by_eve, _mm256_add_epi16(cb_eve, cb_eve));
30232 __m256i by_odd =
30233 _mm256_add_epi16(tmp_by_odd, _mm256_add_epi16(cb_odd, cb_odd));
30234 __m256i ry_eve = _mm256_add_epi16(tmp_ry_eve, cr_eve);
30235 __m256i ry_odd = _mm256_add_epi16(tmp_ry_odd, cr_odd);
30237 __m256i tmp0_gy_eve_lo = _mm256_madd_epi16( //
30238 _mm256_unpacklo_epi16(cb_eve, cr_eve), m581A_p492E);
30239 __m256i tmp0_gy_eve_hi = _mm256_madd_epi16( //
30240 _mm256_unpackhi_epi16(cb_eve, cr_eve), m581A_p492E);
30241 __m256i tmp0_gy_odd_lo = _mm256_madd_epi16( //
30242 _mm256_unpacklo_epi16(cb_odd, cr_odd), m581A_p492E);
30243 __m256i tmp0_gy_odd_hi = _mm256_madd_epi16( //
30244 _mm256_unpackhi_epi16(cb_odd, cr_odd), m581A_p492E);
30246 __m256i tmp1_gy_eve_lo =
30247 _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_eve_lo, p8000_p0000), 16);
30248 __m256i tmp1_gy_eve_hi =
30249 _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_eve_hi, p8000_p0000), 16);
30250 __m256i tmp1_gy_odd_lo =
30251 _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_odd_lo, p8000_p0000), 16);
30252 __m256i tmp1_gy_odd_hi =
30253 _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_odd_hi, p8000_p0000), 16);
30255 __m256i gy_eve = _mm256_sub_epi16(
30256 _mm256_packs_epi32(tmp1_gy_eve_lo, tmp1_gy_eve_hi), cr_eve);
30257 __m256i gy_odd = _mm256_sub_epi16(
30258 _mm256_packs_epi32(tmp1_gy_odd_lo, tmp1_gy_odd_hi), cr_odd);
30260 __m256i yy_all = _mm256_lddqu_si256((const __m256i*)(const void*)up0);
30261 __m256i yy_eve = _mm256_and_si256(yy_all, u00FF);
30262 __m256i yy_odd = _mm256_srli_epi16(yy_all, 8);
30264 __m256i loose_b_eve = _mm256_add_epi16(by_eve, yy_eve);
30265 __m256i loose_b_odd = _mm256_add_epi16(by_odd, yy_odd);
30266 __m256i packed_b_eve = _mm256_packus_epi16(loose_b_eve, loose_b_eve);
30267 __m256i packed_b_odd = _mm256_packus_epi16(loose_b_odd, loose_b_odd);
30269 __m256i loose_g_eve = _mm256_add_epi16(gy_eve, yy_eve);
30270 __m256i loose_g_odd = _mm256_add_epi16(gy_odd, yy_odd);
30271 __m256i packed_g_eve = _mm256_packus_epi16(loose_g_eve, loose_g_eve);
30272 __m256i packed_g_odd = _mm256_packus_epi16(loose_g_odd, loose_g_odd);
30274 __m256i loose_r_eve = _mm256_add_epi16(ry_eve, yy_eve);
30275 __m256i loose_r_odd = _mm256_add_epi16(ry_odd, yy_odd);
30276 __m256i packed_r_eve = _mm256_packus_epi16(loose_r_eve, loose_r_eve);
30277 __m256i packed_r_odd = _mm256_packus_epi16(loose_r_odd, loose_r_odd);
30279 // § Note the swapped B and R channels.
30280 __m256i mix00 = _mm256_unpacklo_epi8(packed_r_eve, packed_g_eve);
30281 __m256i mix01 = _mm256_unpacklo_epi8(packed_r_odd, packed_g_odd);
30282 __m256i mix02 = _mm256_unpacklo_epi8(packed_b_eve, uFFFF);
30283 __m256i mix03 = _mm256_unpacklo_epi8(packed_b_odd, uFFFF);
30285 __m256i mix10 = _mm256_unpacklo_epi16(mix00, mix02);
30286 __m256i mix11 = _mm256_unpacklo_epi16(mix01, mix03);
30287 __m256i mix12 = _mm256_unpackhi_epi16(mix00, mix02);
30288 __m256i mix13 = _mm256_unpackhi_epi16(mix01, mix03);
30290 __m256i mix20 = _mm256_unpacklo_epi32(mix10, mix11);
30291 __m256i mix21 = _mm256_unpackhi_epi32(mix10, mix11);
30292 __m256i mix22 = _mm256_unpacklo_epi32(mix12, mix13);
30293 __m256i mix23 = _mm256_unpackhi_epi32(mix12, mix13);
30295 __m256i mix30 = _mm256_permute2x128_si256(mix20, mix21, 0x20);
30296 __m256i mix31 = _mm256_permute2x128_si256(mix22, mix23, 0x20);
30297 __m256i mix32 = _mm256_permute2x128_si256(mix20, mix21, 0x31);
30298 __m256i mix33 = _mm256_permute2x128_si256(mix22, mix23, 0x31);
30300 _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x00), mix30);
30301 _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x20), mix31);
30302 _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x40), mix32);
30303 _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x60), mix33);
30305 uint32_t n = 32u - (31u & (x - x_end));
30306 dst_iter += 4u * n;
30307 up0 += n;
30308 up1 += n;
30309 up2 += n;
30310 x += n;
30314 #if defined(__GNUC__) && !defined(__clang__)
30315 // No-op.
30316 #else
30317 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2")
30318 static const uint8_t* //
30319 wuffs_private_impl__swizzle_ycc__upsample_inv_h2v2_triangle_x86_avx2(
30320 uint8_t* dst_ptr,
30321 const uint8_t* src_ptr_major,
30322 const uint8_t* src_ptr_minor,
30323 size_t src_len,
30324 uint32_t h1v2_bias_ignored,
30325 bool first_column,
30326 bool last_column) {
30327 uint8_t* dp = dst_ptr;
30328 const uint8_t* sp_major = src_ptr_major;
30329 const uint8_t* sp_minor = src_ptr_minor;
30331 if (first_column) {
30332 src_len--;
30333 if ((src_len <= 0u) && last_column) {
30334 uint32_t sv = (12u * ((uint32_t)(*sp_major++))) + //
30335 (4u * ((uint32_t)(*sp_minor++)));
30336 *dp++ = (uint8_t)((sv + 8u) >> 4u);
30337 *dp++ = (uint8_t)((sv + 7u) >> 4u);
30338 return dst_ptr;
30341 uint32_t sv_major_m1 = sp_major[-0]; // Clamp offset to zero.
30342 uint32_t sv_minor_m1 = sp_minor[-0]; // Clamp offset to zero.
30343 uint32_t sv_major_p1 = sp_major[+1];
30344 uint32_t sv_minor_p1 = sp_minor[+1];
30346 uint32_t sv = (9u * ((uint32_t)(*sp_major++))) + //
30347 (3u * ((uint32_t)(*sp_minor++)));
30348 *dp++ = (uint8_t)((sv + (3u * sv_major_m1) + (sv_minor_m1) + 8u) >> 4u);
30349 *dp++ = (uint8_t)((sv + (3u * sv_major_p1) + (sv_minor_p1) + 7u) >> 4u);
30350 if (src_len <= 0u) {
30351 return dst_ptr;
30355 if (last_column) {
30356 src_len--;
30359 if (src_len < 32) {
30360 // This fallback is the same as the non-SIMD-capable code path.
30361 for (; src_len > 0u; src_len--) {
30362 uint32_t sv_major_m1 = sp_major[-1];
30363 uint32_t sv_minor_m1 = sp_minor[-1];
30364 uint32_t sv_major_p1 = sp_major[+1];
30365 uint32_t sv_minor_p1 = sp_minor[+1];
30367 uint32_t sv = (9u * ((uint32_t)(*sp_major++))) + //
30368 (3u * ((uint32_t)(*sp_minor++)));
30369 *dp++ = (uint8_t)((sv + (3u * sv_major_m1) + (sv_minor_m1) + 8u) >> 4u);
30370 *dp++ = (uint8_t)((sv + (3u * sv_major_p1) + (sv_minor_p1) + 7u) >> 4u);
30373 } else {
30374 while (src_len > 0u) {
30375 // Load 1+32+1 samples (six u8x32 vectors) from the major (jxx) and minor
30376 // (nxx) rows.
30378 // major_p0 = [j00 j01 j02 j03 .. j28 j29 j30 j31] // p0 = "plus 0"
30379 // minor_p0 = [n00 n01 n02 n03 .. n28 n29 n30 n31] // p0 = "plus 0"
30380 // major_m1 = [jm1 j00 j01 j02 .. j27 j28 j29 j30] // m1 = "minus 1"
30381 // minor_m1 = [nm1 n00 n01 n02 .. n27 n28 n29 n30] // m1 = "minus 1"
30382 // major_p1 = [j01 j02 j03 j04 .. j29 j30 j31 j32] // p1 = "plus 1"
30383 // minor_p1 = [n01 n02 n03 n04 .. n29 n30 n31 n32] // p1 = "plus 1"
30384 __m256i major_p0 =
30385 _mm256_lddqu_si256((const __m256i*)(const void*)(sp_major + 0));
30386 __m256i minor_p0 =
30387 _mm256_lddqu_si256((const __m256i*)(const void*)(sp_minor + 0));
30388 __m256i major_m1 =
30389 _mm256_lddqu_si256((const __m256i*)(const void*)(sp_major - 1));
30390 __m256i minor_m1 =
30391 _mm256_lddqu_si256((const __m256i*)(const void*)(sp_minor - 1));
30392 __m256i major_p1 =
30393 _mm256_lddqu_si256((const __m256i*)(const void*)(sp_major + 1));
30394 __m256i minor_p1 =
30395 _mm256_lddqu_si256((const __m256i*)(const void*)(sp_minor + 1));
30397 // Unpack, staying with u8x32 vectors.
30399 // step1_p0_lo = [j00 n00 j01 n01 .. j07 n07 j16 n16 j17 n17 .. j23 n23]
30400 // step1_p0_hi = [j08 n08 j09 n09 .. j15 n15 j24 n24 j25 n25 .. j31 n31]
30401 // step1_m1_lo = [jm1 nm1 j00 n00 .. j06 n06 j15 n15 j16 n16 .. j22 n22]
30402 // step1_m1_hi = [j07 n07 j08 n08 .. j14 n14 j23 n23 j24 n24 .. j30 n30]
30403 // step1_p1_lo = [j01 n01 j02 n02 .. j08 n08 j17 n17 j18 n18 .. j24 n24]
30404 // step1_p1_hi = [j09 n09 j10 n10 .. j16 n16 j25 n25 j26 n26 .. j32 n32]
30405 __m256i step1_p0_lo = _mm256_unpacklo_epi8(major_p0, minor_p0);
30406 __m256i step1_p0_hi = _mm256_unpackhi_epi8(major_p0, minor_p0);
30407 __m256i step1_m1_lo = _mm256_unpacklo_epi8(major_m1, minor_m1);
30408 __m256i step1_m1_hi = _mm256_unpackhi_epi8(major_m1, minor_m1);
30409 __m256i step1_p1_lo = _mm256_unpacklo_epi8(major_p1, minor_p1);
30410 __m256i step1_p1_hi = _mm256_unpackhi_epi8(major_p1, minor_p1);
30412 // Multiply-add to get u16x16 vectors.
30414 // step2_p0_lo = [9*j00+3*n00 9*j01+3*n01 .. 9*j23+3*n23]
30415 // step2_p0_hi = [9*j08+3*n08 9*j09+3*n09 .. 9*j31+3*n31]
30416 // step2_m1_lo = [3*jm1+1*nm1 3*j00+1*n00 .. 3*j22+1*n22]
30417 // step2_m1_hi = [3*j07+1*n07 3*j08+1*n08 .. 3*j30+1*n30]
30418 // step2_p1_lo = [3*j01+1*n01 3*j02+1*n02 .. 3*j24+1*n24]
30419 // step2_p1_hi = [3*j09+1*n09 3*j10+1*n10 .. 3*j32+1*n32]
30420 const __m256i k0309 = _mm256_set1_epi16(0x0309);
30421 const __m256i k0103 = _mm256_set1_epi16(0x0103);
30422 __m256i step2_p0_lo = _mm256_maddubs_epi16(step1_p0_lo, k0309);
30423 __m256i step2_p0_hi = _mm256_maddubs_epi16(step1_p0_hi, k0309);
30424 __m256i step2_m1_lo = _mm256_maddubs_epi16(step1_m1_lo, k0103);
30425 __m256i step2_m1_hi = _mm256_maddubs_epi16(step1_m1_hi, k0103);
30426 __m256i step2_p1_lo = _mm256_maddubs_epi16(step1_p1_lo, k0103);
30427 __m256i step2_p1_hi = _mm256_maddubs_epi16(step1_p1_hi, k0103);
30429 // Compute the weighted sums of (p0, m1) and (p0, p1). For example:
30431 // step3_m1_lo[00] = ((9*j00) + (3*n00) + (3*jm1) + (1*nm1)) as u16
30432 // step3_p1_hi[15] = ((9*j31) + (3*n31) + (3*j32) + (1*n32)) as u16
30433 __m256i step3_m1_lo = _mm256_add_epi16(step2_p0_lo, step2_m1_lo);
30434 __m256i step3_m1_hi = _mm256_add_epi16(step2_p0_hi, step2_m1_hi);
30435 __m256i step3_p1_lo = _mm256_add_epi16(step2_p0_lo, step2_p1_lo);
30436 __m256i step3_p1_hi = _mm256_add_epi16(step2_p0_hi, step2_p1_hi);
30438 // Bias by 8 (on the left) or 7 (on the right) and then divide by 16
30439 // (which is 9+3+3+1) to get a weighted average. On the left (m1), shift
30440 // the u16 right value by 4. On the right (p1), shift right by 4 and then
30441 // shift left by 8 so that, when still in the u16x16 little-endian
30442 // interpretation, we have:
30443 // - m1_element = (etcetera + 8) >> 4
30444 // - p1_element = ((etcetera + 7) >> 4) << 8
30446 // step4_m1_lo = [0x00?? 0x00?? ... 0x00?? 0x00??]
30447 // step4_p1_lo = [0x??00 0x??00 ... 0x??00 0x??00]
30448 // step4_m1_hi = [0x00?? 0x00?? ... 0x00?? 0x00??]
30449 // step4_p1_hi = [0x??00 0x??00 ... 0x??00 0x??00]
30450 __m256i step4_m1_lo = _mm256_srli_epi16(
30451 _mm256_add_epi16(step3_m1_lo, _mm256_set1_epi16(8)), 4);
30452 __m256i step4_p1_lo = _mm256_slli_epi16(
30453 _mm256_srli_epi16(_mm256_add_epi16(step3_p1_lo, _mm256_set1_epi16(7)),
30456 __m256i step4_m1_hi = _mm256_srli_epi16(
30457 _mm256_add_epi16(step3_m1_hi, _mm256_set1_epi16(8)), 4);
30458 __m256i step4_p1_hi = _mm256_slli_epi16(
30459 _mm256_srli_epi16(_mm256_add_epi16(step3_p1_hi, _mm256_set1_epi16(7)),
30463 // Bitwise-or two "0x00"-rich u16x16 vectors to get a u8x32 vector. Do
30464 // that twice. Once for the low columns and once for the high columns.
30466 // In terms of jxx (major row) or nxx (minor row) source samples:
30467 // - low columns means ( 0 .. 8; 16 .. 24).
30468 // - high columns means ( 8 .. 16; 24 .. 32).
30470 // In terms of dxx destination samples (there are twice as many):
30471 // - low columns means ( 0 .. 16; 32 .. 48).
30472 // - high columns means (16 .. 32; 48 .. 64).
30474 // step5_lo = [d00 d01 .. d14 d15 d32 d33 .. d46 d47]
30475 // step5_hi = [d16 d17 .. d30 d31 d48 d49 .. d62 d63]
30477 // The d00, d02 ... d62 even elements come from (p0, m1) weighted sums.
30478 // The d01, d03 ... d63 odd elements come from (p0, p1) weighted sums.
30479 __m256i step5_lo = _mm256_or_si256(step4_m1_lo, step4_p1_lo);
30480 __m256i step5_hi = _mm256_or_si256(step4_m1_hi, step4_p1_hi);
30482 // Permute and store.
30484 // step6_00_31 = [d00 d01 .. d14 d15 d16 d17 .. d30 d31]
30485 // step6_32_63 = [d32 d33 .. d46 d47 d48 d49 .. d62 d63]
30486 __m256i step6_00_31 = _mm256_permute2x128_si256(step5_lo, step5_hi, 0x20);
30487 __m256i step6_32_63 = _mm256_permute2x128_si256(step5_lo, step5_hi, 0x31);
30488 _mm256_storeu_si256((__m256i*)(void*)(dp + 0x00), step6_00_31);
30489 _mm256_storeu_si256((__m256i*)(void*)(dp + 0x20), step6_32_63);
30491 // Advance by up to 32 source samples (64 destination samples). The first
30492 // iteration might be smaller than 32 so that all of the remaining steps
30493 // are exactly 32.
30494 size_t n = 32u - (31u & (0u - src_len));
30495 dp += 2u * n;
30496 sp_major += n;
30497 sp_minor += n;
30498 src_len -= n;
30502 if (last_column) {
30503 uint32_t sv_major_m1 = sp_major[-1];
30504 uint32_t sv_minor_m1 = sp_minor[-1];
30505 uint32_t sv_major_p1 = sp_major[+0]; // Clamp offset to zero.
30506 uint32_t sv_minor_p1 = sp_minor[+0]; // Clamp offset to zero.
30508 uint32_t sv = (9u * ((uint32_t)(*sp_major++))) + //
30509 (3u * ((uint32_t)(*sp_minor++)));
30510 *dp++ = (uint8_t)((sv + (3u * sv_major_m1) + (sv_minor_m1) + 8u) >> 4u);
30511 *dp++ = (uint8_t)((sv + (3u * sv_major_p1) + (sv_minor_p1) + 7u) >> 4u);
30514 return dst_ptr;
30516 #endif
30517 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3)
30518 // ‼ WUFFS MULTI-FILE SECTION -x86_avx2
30520 #endif // !defined(WUFFS_CONFIG__MODULES) ||
30521 // defined(WUFFS_CONFIG__MODULE__BASE) ||
30522 // defined(WUFFS_CONFIG__MODULE__BASE__PIXCONV)
30524 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
30525 defined(WUFFS_CONFIG__MODULE__BASE__UTF8)
30527 // ---------------- Unicode and UTF-8
30529 WUFFS_BASE__MAYBE_STATIC size_t //
30530 wuffs_base__utf_8__encode(wuffs_base__slice_u8 dst, uint32_t code_point) {
30531 if (code_point <= 0x7F) {
30532 if (dst.len >= 1) {
30533 dst.ptr[0] = (uint8_t)(code_point);
30534 return 1;
30537 } else if (code_point <= 0x07FF) {
30538 if (dst.len >= 2) {
30539 dst.ptr[0] = (uint8_t)(0xC0 | ((code_point >> 6)));
30540 dst.ptr[1] = (uint8_t)(0x80 | ((code_point >> 0) & 0x3F));
30541 return 2;
30544 } else if (code_point <= 0xFFFF) {
30545 if ((dst.len >= 3) && ((code_point < 0xD800) || (0xDFFF < code_point))) {
30546 dst.ptr[0] = (uint8_t)(0xE0 | ((code_point >> 12)));
30547 dst.ptr[1] = (uint8_t)(0x80 | ((code_point >> 6) & 0x3F));
30548 dst.ptr[2] = (uint8_t)(0x80 | ((code_point >> 0) & 0x3F));
30549 return 3;
30552 } else if (code_point <= 0x10FFFF) {
30553 if (dst.len >= 4) {
30554 dst.ptr[0] = (uint8_t)(0xF0 | ((code_point >> 18)));
30555 dst.ptr[1] = (uint8_t)(0x80 | ((code_point >> 12) & 0x3F));
30556 dst.ptr[2] = (uint8_t)(0x80 | ((code_point >> 6) & 0x3F));
30557 dst.ptr[3] = (uint8_t)(0x80 | ((code_point >> 0) & 0x3F));
30558 return 4;
30562 return 0;
30565 // wuffs_base__utf_8__byte_length_minus_1 is the byte length (minus 1) of a
30566 // UTF-8 encoded code point, based on the encoding's initial byte.
30567 // - 0x00 is 1-byte UTF-8 (ASCII).
30568 // - 0x01 is the start of 2-byte UTF-8.
30569 // - 0x02 is the start of 3-byte UTF-8.
30570 // - 0x03 is the start of 4-byte UTF-8.
30571 // - 0x40 is a UTF-8 tail byte.
30572 // - 0x80 is invalid UTF-8.
30574 // RFC 3629 (UTF-8) gives this grammar for valid UTF-8:
30575 // UTF8-1 = %x00-7F
30576 // UTF8-2 = %xC2-DF UTF8-tail
30577 // UTF8-3 = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) /
30578 // %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )
30579 // UTF8-4 = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) /
30580 // %xF4 %x80-8F 2( UTF8-tail )
30581 // UTF8-tail = %x80-BF
30582 static const uint8_t wuffs_base__utf_8__byte_length_minus_1[256] = {
30583 // 0 1 2 3 4 5 6 7
30584 // 8 9 A B C D E F
30585 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00 ..= 0x07.
30586 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x08 ..= 0x0F.
30587 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x10 ..= 0x17.
30588 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x18 ..= 0x1F.
30589 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x20 ..= 0x27.
30590 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x28 ..= 0x2F.
30591 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x30 ..= 0x37.
30592 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x38 ..= 0x3F.
30594 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x40 ..= 0x47.
30595 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x48 ..= 0x4F.
30596 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50 ..= 0x57.
30597 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x58 ..= 0x5F.
30598 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x60 ..= 0x67.
30599 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x68 ..= 0x6F.
30600 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x70 ..= 0x77.
30601 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x78 ..= 0x7F.
30603 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x80 ..= 0x87.
30604 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x88 ..= 0x8F.
30605 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x90 ..= 0x97.
30606 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x98 ..= 0x9F.
30607 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0xA0 ..= 0xA7.
30608 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0xA8 ..= 0xAF.
30609 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0xB0 ..= 0xB7.
30610 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0xB8 ..= 0xBF.
30612 0x80, 0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xC0 ..= 0xC7.
30613 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xC8 ..= 0xCF.
30614 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xD0 ..= 0xD7.
30615 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xD8 ..= 0xDF.
30616 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, // 0xE0 ..= 0xE7.
30617 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, // 0xE8 ..= 0xEF.
30618 0x03, 0x03, 0x03, 0x03, 0x03, 0x80, 0x80, 0x80, // 0xF0 ..= 0xF7.
30619 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xF8 ..= 0xFF.
30620 // 0 1 2 3 4 5 6 7
30621 // 8 9 A B C D E F
30624 WUFFS_BASE__MAYBE_STATIC wuffs_base__utf_8__next__output //
30625 wuffs_base__utf_8__next(const uint8_t* s_ptr, size_t s_len) {
30626 if (s_len == 0) {
30627 return wuffs_base__make_utf_8__next__output(0, 0);
30629 uint32_t c = s_ptr[0];
30630 switch (wuffs_base__utf_8__byte_length_minus_1[c & 0xFF]) {
30631 case 0:
30632 return wuffs_base__make_utf_8__next__output(c, 1);
30634 case 1:
30635 if (s_len < 2) {
30636 break;
30638 c = wuffs_base__peek_u16le__no_bounds_check(s_ptr);
30639 if ((c & 0xC000) != 0x8000) {
30640 break;
30642 c = (0x0007C0 & (c << 6)) | (0x00003F & (c >> 8));
30643 return wuffs_base__make_utf_8__next__output(c, 2);
30645 case 2:
30646 if (s_len < 3) {
30647 break;
30649 c = wuffs_base__peek_u24le__no_bounds_check(s_ptr);
30650 if ((c & 0xC0C000) != 0x808000) {
30651 break;
30653 c = (0x00F000 & (c << 12)) | (0x000FC0 & (c >> 2)) |
30654 (0x00003F & (c >> 16));
30655 if ((c <= 0x07FF) || ((0xD800 <= c) && (c <= 0xDFFF))) {
30656 break;
30658 return wuffs_base__make_utf_8__next__output(c, 3);
30660 case 3:
30661 if (s_len < 4) {
30662 break;
30664 c = wuffs_base__peek_u32le__no_bounds_check(s_ptr);
30665 if ((c & 0xC0C0C000) != 0x80808000) {
30666 break;
30668 c = (0x1C0000 & (c << 18)) | (0x03F000 & (c << 4)) |
30669 (0x000FC0 & (c >> 10)) | (0x00003F & (c >> 24));
30670 if ((c <= 0xFFFF) || (0x110000 <= c)) {
30671 break;
30673 return wuffs_base__make_utf_8__next__output(c, 4);
30676 return wuffs_base__make_utf_8__next__output(
30677 WUFFS_BASE__UNICODE_REPLACEMENT_CHARACTER, 1);
30680 WUFFS_BASE__MAYBE_STATIC wuffs_base__utf_8__next__output //
30681 wuffs_base__utf_8__next_from_end(const uint8_t* s_ptr, size_t s_len) {
30682 if (s_len == 0) {
30683 return wuffs_base__make_utf_8__next__output(0, 0);
30685 const uint8_t* ptr = &s_ptr[s_len - 1];
30686 if (*ptr < 0x80) {
30687 return wuffs_base__make_utf_8__next__output(*ptr, 1);
30689 } else if (*ptr < 0xC0) {
30690 const uint8_t* too_far = &s_ptr[(s_len > 4) ? (s_len - 4) : 0];
30691 uint32_t n = 1;
30692 while (ptr != too_far) {
30693 ptr--;
30694 n++;
30695 if (*ptr < 0x80) {
30696 break;
30697 } else if (*ptr < 0xC0) {
30698 continue;
30700 wuffs_base__utf_8__next__output o = wuffs_base__utf_8__next(ptr, n);
30701 if (o.byte_length != n) {
30702 break;
30704 return o;
30708 return wuffs_base__make_utf_8__next__output(
30709 WUFFS_BASE__UNICODE_REPLACEMENT_CHARACTER, 1);
30712 WUFFS_BASE__MAYBE_STATIC size_t //
30713 wuffs_base__utf_8__longest_valid_prefix(const uint8_t* s_ptr, size_t s_len) {
30714 // TODO: possibly optimize the all-ASCII case (4 or 8 bytes at a time).
30716 // TODO: possibly optimize this by manually inlining the
30717 // wuffs_base__utf_8__next calls.
30718 size_t original_len = s_len;
30719 while (s_len > 0) {
30720 wuffs_base__utf_8__next__output o = wuffs_base__utf_8__next(s_ptr, s_len);
30721 if ((o.code_point > 0x7F) && (o.byte_length == 1)) {
30722 break;
30724 s_ptr += o.byte_length;
30725 s_len -= o.byte_length;
30727 return original_len - s_len;
30730 WUFFS_BASE__MAYBE_STATIC size_t //
30731 wuffs_base__ascii__longest_valid_prefix(const uint8_t* s_ptr, size_t s_len) {
30732 // TODO: possibly optimize this by checking 4 or 8 bytes at a time.
30733 const uint8_t* original_ptr = s_ptr;
30734 const uint8_t* p = s_ptr;
30735 const uint8_t* q = s_ptr + s_len;
30736 for (; (p != q) && ((*p & 0x80) == 0); p++) {
30738 return (size_t)(p - original_ptr);
30741 #endif // !defined(WUFFS_CONFIG__MODULES) ||
30742 // defined(WUFFS_CONFIG__MODULE__BASE) ||
30743 // defined(WUFFS_CONFIG__MODULE__BASE__UTF8)
30745 #ifdef __cplusplus
30746 } // extern "C"
30747 #endif
30749 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ADLER32)
30751 // ---------------- Status Codes Implementations
30753 // ---------------- Private Consts
30755 // ---------------- Private Initializer Prototypes
30757 // ---------------- Private Function Prototypes
30759 WUFFS_BASE__GENERATED_C_CODE
30760 static wuffs_base__empty_struct
30761 wuffs_adler32__hasher__up(
30762 wuffs_adler32__hasher* self,
30763 wuffs_base__slice_u8 a_x);
30765 WUFFS_BASE__GENERATED_C_CODE
30766 static wuffs_base__empty_struct
30767 wuffs_adler32__hasher__up__choosy_default(
30768 wuffs_adler32__hasher* self,
30769 wuffs_base__slice_u8 a_x);
30771 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON)
30772 WUFFS_BASE__GENERATED_C_CODE
30773 static wuffs_base__empty_struct
30774 wuffs_adler32__hasher__up_arm_neon(
30775 wuffs_adler32__hasher* self,
30776 wuffs_base__slice_u8 a_x);
30777 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON)
30779 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
30780 WUFFS_BASE__GENERATED_C_CODE
30781 static wuffs_base__empty_struct
30782 wuffs_adler32__hasher__up_x86_sse42(
30783 wuffs_adler32__hasher* self,
30784 wuffs_base__slice_u8 a_x);
30785 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
30787 // ---------------- VTables
30789 const wuffs_base__hasher_u32__func_ptrs
30790 wuffs_adler32__hasher__func_ptrs_for__wuffs_base__hasher_u32 = {
30791 (uint32_t(*)(const void*))(&wuffs_adler32__hasher__checksum_u32),
30792 (uint64_t(*)(const void*,
30793 uint32_t))(&wuffs_adler32__hasher__get_quirk),
30794 (wuffs_base__status(*)(void*,
30795 uint32_t,
30796 uint64_t))(&wuffs_adler32__hasher__set_quirk),
30797 (wuffs_base__empty_struct(*)(void*,
30798 wuffs_base__slice_u8))(&wuffs_adler32__hasher__update),
30799 (uint32_t(*)(void*,
30800 wuffs_base__slice_u8))(&wuffs_adler32__hasher__update_u32),
30803 // ---------------- Initializer Implementations
30805 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
30806 wuffs_adler32__hasher__initialize(
30807 wuffs_adler32__hasher* self,
30808 size_t sizeof_star_self,
30809 uint64_t wuffs_version,
30810 uint32_t options){
30811 if (!self) {
30812 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
30814 if (sizeof(*self) != sizeof_star_self) {
30815 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
30817 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
30818 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
30819 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
30822 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
30823 // The whole point of this if-check is to detect an uninitialized *self.
30824 // We disable the warning on GCC. Clang-5.0 does not have this warning.
30825 #if !defined(__clang__) && defined(__GNUC__)
30826 #pragma GCC diagnostic push
30827 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
30828 #endif
30829 if (self->private_impl.magic != 0) {
30830 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
30832 #if !defined(__clang__) && defined(__GNUC__)
30833 #pragma GCC diagnostic pop
30834 #endif
30835 } else {
30836 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
30837 memset(self, 0, sizeof(*self));
30838 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
30839 } else {
30840 memset(&(self->private_impl), 0, sizeof(self->private_impl));
30844 self->private_impl.choosy_up = &wuffs_adler32__hasher__up__choosy_default;
30846 self->private_impl.magic = WUFFS_BASE__MAGIC;
30847 self->private_impl.vtable_for__wuffs_base__hasher_u32.vtable_name =
30848 wuffs_base__hasher_u32__vtable_name;
30849 self->private_impl.vtable_for__wuffs_base__hasher_u32.function_pointers =
30850 (const void*)(&wuffs_adler32__hasher__func_ptrs_for__wuffs_base__hasher_u32);
30851 return wuffs_base__make_status(NULL);
30854 wuffs_adler32__hasher*
30855 wuffs_adler32__hasher__alloc(void) {
30856 wuffs_adler32__hasher* x =
30857 (wuffs_adler32__hasher*)(calloc(1, sizeof(wuffs_adler32__hasher)));
30858 if (!x) {
30859 return NULL;
30861 if (wuffs_adler32__hasher__initialize(
30862 x, sizeof(wuffs_adler32__hasher), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
30863 free(x);
30864 return NULL;
30866 return x;
30869 size_t
30870 sizeof__wuffs_adler32__hasher(void) {
30871 return sizeof(wuffs_adler32__hasher);
30874 // ---------------- Function Implementations
30876 // -------- func adler32.hasher.get_quirk
30878 WUFFS_BASE__GENERATED_C_CODE
30879 WUFFS_BASE__MAYBE_STATIC uint64_t
30880 wuffs_adler32__hasher__get_quirk(
30881 const wuffs_adler32__hasher* self,
30882 uint32_t a_key) {
30883 if (!self) {
30884 return 0;
30886 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
30887 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
30888 return 0;
30891 return 0u;
30894 // -------- func adler32.hasher.set_quirk
30896 WUFFS_BASE__GENERATED_C_CODE
30897 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
30898 wuffs_adler32__hasher__set_quirk(
30899 wuffs_adler32__hasher* self,
30900 uint32_t a_key,
30901 uint64_t a_value) {
30902 if (!self) {
30903 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
30905 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
30906 return wuffs_base__make_status(
30907 (self->private_impl.magic == WUFFS_BASE__DISABLED)
30908 ? wuffs_base__error__disabled_by_previous_error
30909 : wuffs_base__error__initialize_not_called);
30912 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
30915 // -------- func adler32.hasher.update
30917 WUFFS_BASE__GENERATED_C_CODE
30918 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
30919 wuffs_adler32__hasher__update(
30920 wuffs_adler32__hasher* self,
30921 wuffs_base__slice_u8 a_x) {
30922 if (!self) {
30923 return wuffs_base__make_empty_struct();
30925 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
30926 return wuffs_base__make_empty_struct();
30929 if ( ! self->private_impl.f_started) {
30930 self->private_impl.f_started = true;
30931 self->private_impl.f_state = 1u;
30932 self->private_impl.choosy_up = (
30933 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON)
30934 wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_adler32__hasher__up_arm_neon :
30935 #endif
30936 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
30937 wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_adler32__hasher__up_x86_sse42 :
30938 #endif
30939 self->private_impl.choosy_up);
30941 wuffs_adler32__hasher__up(self, a_x);
30942 return wuffs_base__make_empty_struct();
30945 // -------- func adler32.hasher.update_u32
30947 WUFFS_BASE__GENERATED_C_CODE
30948 WUFFS_BASE__MAYBE_STATIC uint32_t
30949 wuffs_adler32__hasher__update_u32(
30950 wuffs_adler32__hasher* self,
30951 wuffs_base__slice_u8 a_x) {
30952 if (!self) {
30953 return 0;
30955 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
30956 return 0;
30959 wuffs_adler32__hasher__update(self, a_x);
30960 return self->private_impl.f_state;
30963 // -------- func adler32.hasher.up
30965 WUFFS_BASE__GENERATED_C_CODE
30966 static wuffs_base__empty_struct
30967 wuffs_adler32__hasher__up(
30968 wuffs_adler32__hasher* self,
30969 wuffs_base__slice_u8 a_x) {
30970 return (*self->private_impl.choosy_up)(self, a_x);
30973 WUFFS_BASE__GENERATED_C_CODE
30974 static wuffs_base__empty_struct
30975 wuffs_adler32__hasher__up__choosy_default(
30976 wuffs_adler32__hasher* self,
30977 wuffs_base__slice_u8 a_x) {
30978 uint32_t v_s1 = 0;
30979 uint32_t v_s2 = 0;
30980 wuffs_base__slice_u8 v_remaining = {0};
30981 wuffs_base__slice_u8 v_p = {0};
30983 v_s1 = ((self->private_impl.f_state) & 0xFFFFu);
30984 v_s2 = ((self->private_impl.f_state) >> (32u - 16u));
30985 while (((uint64_t)(a_x.len)) > 0u) {
30986 v_remaining = wuffs_base__slice_u8__subslice_j(a_x, 0u);
30987 if (((uint64_t)(a_x.len)) > 5552u) {
30988 v_remaining = wuffs_base__slice_u8__subslice_i(a_x, 5552u);
30989 a_x = wuffs_base__slice_u8__subslice_j(a_x, 5552u);
30992 wuffs_base__slice_u8 i_slice_p = a_x;
30993 v_p.ptr = i_slice_p.ptr;
30994 v_p.len = 1;
30995 const uint8_t* i_end0_p = wuffs_private_impl__ptr_u8_plus_len(v_p.ptr, (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 8) * 8));
30996 while (v_p.ptr < i_end0_p) {
30997 v_s1 += ((uint32_t)(v_p.ptr[0u]));
30998 v_s2 += v_s1;
30999 v_p.ptr += 1;
31000 v_s1 += ((uint32_t)(v_p.ptr[0u]));
31001 v_s2 += v_s1;
31002 v_p.ptr += 1;
31003 v_s1 += ((uint32_t)(v_p.ptr[0u]));
31004 v_s2 += v_s1;
31005 v_p.ptr += 1;
31006 v_s1 += ((uint32_t)(v_p.ptr[0u]));
31007 v_s2 += v_s1;
31008 v_p.ptr += 1;
31009 v_s1 += ((uint32_t)(v_p.ptr[0u]));
31010 v_s2 += v_s1;
31011 v_p.ptr += 1;
31012 v_s1 += ((uint32_t)(v_p.ptr[0u]));
31013 v_s2 += v_s1;
31014 v_p.ptr += 1;
31015 v_s1 += ((uint32_t)(v_p.ptr[0u]));
31016 v_s2 += v_s1;
31017 v_p.ptr += 1;
31018 v_s1 += ((uint32_t)(v_p.ptr[0u]));
31019 v_s2 += v_s1;
31020 v_p.ptr += 1;
31022 v_p.len = 1;
31023 const uint8_t* i_end1_p = wuffs_private_impl__ptr_u8_plus_len(i_slice_p.ptr, i_slice_p.len);
31024 while (v_p.ptr < i_end1_p) {
31025 v_s1 += ((uint32_t)(v_p.ptr[0u]));
31026 v_s2 += v_s1;
31027 v_p.ptr += 1;
31029 v_p.len = 0;
31031 v_s1 %= 65521u;
31032 v_s2 %= 65521u;
31033 a_x = v_remaining;
31035 self->private_impl.f_state = (((v_s2 & 65535u) << 16u) | (v_s1 & 65535u));
31036 return wuffs_base__make_empty_struct();
31039 // -------- func adler32.hasher.checksum_u32
31041 WUFFS_BASE__GENERATED_C_CODE
31042 WUFFS_BASE__MAYBE_STATIC uint32_t
31043 wuffs_adler32__hasher__checksum_u32(
31044 const wuffs_adler32__hasher* self) {
31045 if (!self) {
31046 return 0;
31048 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
31049 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
31050 return 0;
31053 return self->private_impl.f_state;
31056 // ‼ WUFFS MULTI-FILE SECTION +arm_neon
31057 // -------- func adler32.hasher.up_arm_neon
31059 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON)
31060 WUFFS_BASE__GENERATED_C_CODE
31061 static wuffs_base__empty_struct
31062 wuffs_adler32__hasher__up_arm_neon(
31063 wuffs_adler32__hasher* self,
31064 wuffs_base__slice_u8 a_x) {
31065 uint32_t v_s1 = 0;
31066 uint32_t v_s2 = 0;
31067 wuffs_base__slice_u8 v_remaining = {0};
31068 wuffs_base__slice_u8 v_p = {0};
31069 uint8x16_t v_p__left = {0};
31070 uint8x16_t v_p_right = {0};
31071 uint32x4_t v_v1 = {0};
31072 uint32x4_t v_v2 = {0};
31073 uint16x8_t v_col0 = {0};
31074 uint16x8_t v_col1 = {0};
31075 uint16x8_t v_col2 = {0};
31076 uint16x8_t v_col3 = {0};
31077 uint32x2_t v_sum1 = {0};
31078 uint32x2_t v_sum2 = {0};
31079 uint32x2_t v_sum12 = {0};
31080 uint32_t v_num_iterate_bytes = 0;
31081 uint64_t v_tail_index = 0;
31083 v_s1 = ((self->private_impl.f_state) & 0xFFFFu);
31084 v_s2 = ((self->private_impl.f_state) >> (32u - 16u));
31085 while ((((uint64_t)(a_x.len)) > 0u) && ((15u & ((uint32_t)(0xFFFu & (uintptr_t)(a_x.ptr)))) != 0u)) {
31086 v_s1 += ((uint32_t)(a_x.ptr[0u]));
31087 v_s2 += v_s1;
31088 a_x = wuffs_base__slice_u8__subslice_i(a_x, 1u);
31090 v_s1 %= 65521u;
31091 v_s2 %= 65521u;
31092 while (((uint64_t)(a_x.len)) > 0u) {
31093 v_remaining = wuffs_base__slice_u8__subslice_j(a_x, 0u);
31094 if (((uint64_t)(a_x.len)) > 5536u) {
31095 v_remaining = wuffs_base__slice_u8__subslice_i(a_x, 5536u);
31096 a_x = wuffs_base__slice_u8__subslice_j(a_x, 5536u);
31098 v_num_iterate_bytes = ((uint32_t)((((uint64_t)(a_x.len)) & 4294967264u)));
31099 v_s2 += ((uint32_t)(v_s1 * v_num_iterate_bytes));
31100 v_v1 = vdupq_n_u32(0u);
31101 v_v2 = vdupq_n_u32(0u);
31102 v_col0 = vdupq_n_u16(0u);
31103 v_col1 = vdupq_n_u16(0u);
31104 v_col2 = vdupq_n_u16(0u);
31105 v_col3 = vdupq_n_u16(0u);
31107 wuffs_base__slice_u8 i_slice_p = a_x;
31108 v_p.ptr = i_slice_p.ptr;
31109 v_p.len = 32;
31110 const uint8_t* i_end0_p = wuffs_private_impl__ptr_u8_plus_len(v_p.ptr, (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 32) * 32));
31111 while (v_p.ptr < i_end0_p) {
31112 v_p__left = vld1q_u8(v_p.ptr);
31113 v_p_right = vld1q_u8(v_p.ptr + 16u);
31114 v_v2 = vaddq_u32(v_v2, v_v1);
31115 v_v1 = vpadalq_u16(v_v1, vpadalq_u8(vpaddlq_u8(v_p__left), v_p_right));
31116 v_col0 = vaddw_u8(v_col0, vget_low_u8(v_p__left));
31117 v_col1 = vaddw_u8(v_col1, vget_high_u8(v_p__left));
31118 v_col2 = vaddw_u8(v_col2, vget_low_u8(v_p_right));
31119 v_col3 = vaddw_u8(v_col3, vget_high_u8(v_p_right));
31120 v_p.ptr += 32;
31122 v_p.len = 0;
31124 v_v2 = vshlq_n_u32(v_v2, 5u);
31125 v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col0), ((uint16x4_t){32u, 31u, 30u, 29u}));
31126 v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col0), ((uint16x4_t){28u, 27u, 26u, 25u}));
31127 v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col1), ((uint16x4_t){24u, 23u, 22u, 21u}));
31128 v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col1), ((uint16x4_t){20u, 19u, 18u, 17u}));
31129 v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col2), ((uint16x4_t){16u, 15u, 14u, 13u}));
31130 v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col2), ((uint16x4_t){12u, 11u, 10u, 9u}));
31131 v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col3), ((uint16x4_t){8u, 7u, 6u, 5u}));
31132 v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col3), ((uint16x4_t){4u, 3u, 2u, 1u}));
31133 v_sum1 = vpadd_u32(vget_low_u32(v_v1), vget_high_u32(v_v1));
31134 v_sum2 = vpadd_u32(vget_low_u32(v_v2), vget_high_u32(v_v2));
31135 v_sum12 = vpadd_u32(v_sum1, v_sum2);
31136 v_s1 += vget_lane_u32(v_sum12, 0u);
31137 v_s2 += vget_lane_u32(v_sum12, 1u);
31138 v_tail_index = (((uint64_t)(a_x.len)) & 18446744073709551584u);
31139 if (v_tail_index < ((uint64_t)(a_x.len))) {
31141 wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, v_tail_index);
31142 v_p.ptr = i_slice_p.ptr;
31143 v_p.len = 1;
31144 const uint8_t* i_end0_p = wuffs_private_impl__ptr_u8_plus_len(i_slice_p.ptr, i_slice_p.len);
31145 while (v_p.ptr < i_end0_p) {
31146 v_s1 += ((uint32_t)(v_p.ptr[0u]));
31147 v_s2 += v_s1;
31148 v_p.ptr += 1;
31150 v_p.len = 0;
31153 v_s1 %= 65521u;
31154 v_s2 %= 65521u;
31155 a_x = v_remaining;
31157 self->private_impl.f_state = (((v_s2 & 65535u) << 16u) | (v_s1 & 65535u));
31158 return wuffs_base__make_empty_struct();
31160 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON)
31161 // ‼ WUFFS MULTI-FILE SECTION -arm_neon
31163 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
31164 // -------- func adler32.hasher.up_x86_sse42
31166 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
31167 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
31168 WUFFS_BASE__GENERATED_C_CODE
31169 static wuffs_base__empty_struct
31170 wuffs_adler32__hasher__up_x86_sse42(
31171 wuffs_adler32__hasher* self,
31172 wuffs_base__slice_u8 a_x) {
31173 uint32_t v_s1 = 0;
31174 uint32_t v_s2 = 0;
31175 wuffs_base__slice_u8 v_remaining = {0};
31176 wuffs_base__slice_u8 v_p = {0};
31177 __m128i v_zeroes = {0};
31178 __m128i v_ones = {0};
31179 __m128i v_weights__left = {0};
31180 __m128i v_weights_right = {0};
31181 __m128i v_q__left = {0};
31182 __m128i v_q_right = {0};
31183 __m128i v_v1 = {0};
31184 __m128i v_v2 = {0};
31185 __m128i v_v2j = {0};
31186 __m128i v_v2k = {0};
31187 uint32_t v_num_iterate_bytes = 0;
31188 uint64_t v_tail_index = 0;
31190 v_zeroes = _mm_set1_epi16((int16_t)(0u));
31191 v_ones = _mm_set1_epi16((int16_t)(1u));
31192 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));
31193 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));
31194 v_s1 = ((self->private_impl.f_state) & 0xFFFFu);
31195 v_s2 = ((self->private_impl.f_state) >> (32u - 16u));
31196 while (((uint64_t)(a_x.len)) > 0u) {
31197 v_remaining = wuffs_base__slice_u8__subslice_j(a_x, 0u);
31198 if (((uint64_t)(a_x.len)) > 5536u) {
31199 v_remaining = wuffs_base__slice_u8__subslice_i(a_x, 5536u);
31200 a_x = wuffs_base__slice_u8__subslice_j(a_x, 5536u);
31202 v_num_iterate_bytes = ((uint32_t)((((uint64_t)(a_x.len)) & 4294967264u)));
31203 v_s2 += ((uint32_t)(v_s1 * v_num_iterate_bytes));
31204 v_v1 = _mm_setzero_si128();
31205 v_v2j = _mm_setzero_si128();
31206 v_v2k = _mm_setzero_si128();
31208 wuffs_base__slice_u8 i_slice_p = a_x;
31209 v_p.ptr = i_slice_p.ptr;
31210 v_p.len = 32;
31211 const uint8_t* i_end0_p = wuffs_private_impl__ptr_u8_plus_len(v_p.ptr, (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 32) * 32));
31212 while (v_p.ptr < i_end0_p) {
31213 v_q__left = _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr));
31214 v_q_right = _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 16u));
31215 v_v2j = _mm_add_epi32(v_v2j, v_v1);
31216 v_v1 = _mm_add_epi32(v_v1, _mm_sad_epu8(v_q__left, v_zeroes));
31217 v_v1 = _mm_add_epi32(v_v1, _mm_sad_epu8(v_q_right, v_zeroes));
31218 v_v2k = _mm_add_epi32(v_v2k, _mm_madd_epi16(v_ones, _mm_maddubs_epi16(v_q__left, v_weights__left)));
31219 v_v2k = _mm_add_epi32(v_v2k, _mm_madd_epi16(v_ones, _mm_maddubs_epi16(v_q_right, v_weights_right)));
31220 v_p.ptr += 32;
31222 v_p.len = 0;
31224 v_v1 = _mm_add_epi32(v_v1, _mm_shuffle_epi32(v_v1, (int32_t)(177u)));
31225 v_v1 = _mm_add_epi32(v_v1, _mm_shuffle_epi32(v_v1, (int32_t)(78u)));
31226 v_s1 += ((uint32_t)(_mm_cvtsi128_si32(v_v1)));
31227 v_v2 = _mm_add_epi32(v_v2k, _mm_slli_epi32(v_v2j, (int32_t)(5u)));
31228 v_v2 = _mm_add_epi32(v_v2, _mm_shuffle_epi32(v_v2, (int32_t)(177u)));
31229 v_v2 = _mm_add_epi32(v_v2, _mm_shuffle_epi32(v_v2, (int32_t)(78u)));
31230 v_s2 += ((uint32_t)(_mm_cvtsi128_si32(v_v2)));
31231 v_tail_index = (((uint64_t)(a_x.len)) & 18446744073709551584u);
31232 if (v_tail_index < ((uint64_t)(a_x.len))) {
31234 wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, v_tail_index);
31235 v_p.ptr = i_slice_p.ptr;
31236 v_p.len = 1;
31237 const uint8_t* i_end0_p = wuffs_private_impl__ptr_u8_plus_len(i_slice_p.ptr, i_slice_p.len);
31238 while (v_p.ptr < i_end0_p) {
31239 v_s1 += ((uint32_t)(v_p.ptr[0u]));
31240 v_s2 += v_s1;
31241 v_p.ptr += 1;
31243 v_p.len = 0;
31246 v_s1 %= 65521u;
31247 v_s2 %= 65521u;
31248 a_x = v_remaining;
31250 self->private_impl.f_state = (((v_s2 & 65535u) << 16u) | (v_s1 & 65535u));
31251 return wuffs_base__make_empty_struct();
31253 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
31254 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
31256 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ADLER32)
31258 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BMP)
31260 // ---------------- Status Codes Implementations
31262 const char wuffs_bmp__error__bad_header[] = "#bmp: bad header";
31263 const char wuffs_bmp__error__bad_rle_compression[] = "#bmp: bad RLE compression";
31264 const char wuffs_bmp__error__truncated_input[] = "#bmp: truncated input";
31265 const char wuffs_bmp__error__unsupported_bmp_file[] = "#bmp: unsupported BMP file";
31266 const char wuffs_bmp__note__internal_note_short_read[] = "@bmp: internal note: short read";
31268 // ---------------- Private Consts
31270 #define WUFFS_BMP__COMPRESSION_NONE 0u
31272 #define WUFFS_BMP__COMPRESSION_RLE8 1u
31274 #define WUFFS_BMP__COMPRESSION_RLE4 2u
31276 #define WUFFS_BMP__COMPRESSION_BITFIELDS 3u
31278 #define WUFFS_BMP__COMPRESSION_JPEG 4u
31280 #define WUFFS_BMP__COMPRESSION_PNG 5u
31282 #define WUFFS_BMP__COMPRESSION_ALPHABITFIELDS 6u
31284 #define WUFFS_BMP__COMPRESSION_LOW_BIT_DEPTH 256u
31286 #define WUFFS_BMP__RLE_STATE_NEUTRAL 0u
31288 #define WUFFS_BMP__RLE_STATE_RUN 1u
31290 #define WUFFS_BMP__RLE_STATE_ESCAPE 2u
31292 #define WUFFS_BMP__RLE_STATE_LITERAL 3u
31294 #define WUFFS_BMP__RLE_STATE_DELTA_X 4u
31296 #define WUFFS_BMP__RLE_STATE_DELTA_Y 5u
31298 // ---------------- Private Initializer Prototypes
31300 // ---------------- Private Function Prototypes
31302 WUFFS_BASE__GENERATED_C_CODE
31303 static wuffs_base__status
31304 wuffs_bmp__decoder__do_decode_image_config(
31305 wuffs_bmp__decoder* self,
31306 wuffs_base__image_config* a_dst,
31307 wuffs_base__io_buffer* a_src);
31309 WUFFS_BASE__GENERATED_C_CODE
31310 static wuffs_base__status
31311 wuffs_bmp__decoder__do_decode_frame_config(
31312 wuffs_bmp__decoder* self,
31313 wuffs_base__frame_config* a_dst,
31314 wuffs_base__io_buffer* a_src);
31316 WUFFS_BASE__GENERATED_C_CODE
31317 static wuffs_base__status
31318 wuffs_bmp__decoder__do_decode_frame(
31319 wuffs_bmp__decoder* self,
31320 wuffs_base__pixel_buffer* a_dst,
31321 wuffs_base__io_buffer* a_src,
31322 wuffs_base__pixel_blend a_blend,
31323 wuffs_base__slice_u8 a_workbuf,
31324 wuffs_base__decode_frame_options* a_opts);
31326 WUFFS_BASE__GENERATED_C_CODE
31327 static wuffs_base__status
31328 wuffs_bmp__decoder__swizzle_none(
31329 wuffs_bmp__decoder* self,
31330 wuffs_base__pixel_buffer* a_dst,
31331 wuffs_base__io_buffer* a_src);
31333 WUFFS_BASE__GENERATED_C_CODE
31334 static wuffs_base__status
31335 wuffs_bmp__decoder__swizzle_rle(
31336 wuffs_bmp__decoder* self,
31337 wuffs_base__pixel_buffer* a_dst,
31338 wuffs_base__io_buffer* a_src);
31340 WUFFS_BASE__GENERATED_C_CODE
31341 static wuffs_base__status
31342 wuffs_bmp__decoder__swizzle_bitfields(
31343 wuffs_bmp__decoder* self,
31344 wuffs_base__pixel_buffer* a_dst,
31345 wuffs_base__io_buffer* a_src);
31347 WUFFS_BASE__GENERATED_C_CODE
31348 static wuffs_base__status
31349 wuffs_bmp__decoder__swizzle_low_bit_depth(
31350 wuffs_bmp__decoder* self,
31351 wuffs_base__pixel_buffer* a_dst,
31352 wuffs_base__io_buffer* a_src);
31354 WUFFS_BASE__GENERATED_C_CODE
31355 static wuffs_base__status
31356 wuffs_bmp__decoder__do_tell_me_more(
31357 wuffs_bmp__decoder* self,
31358 wuffs_base__io_buffer* a_dst,
31359 wuffs_base__more_information* a_minfo,
31360 wuffs_base__io_buffer* a_src);
31362 WUFFS_BASE__GENERATED_C_CODE
31363 static wuffs_base__status
31364 wuffs_bmp__decoder__read_palette(
31365 wuffs_bmp__decoder* self,
31366 wuffs_base__io_buffer* a_src);
31368 WUFFS_BASE__GENERATED_C_CODE
31369 static wuffs_base__status
31370 wuffs_bmp__decoder__process_masks(
31371 wuffs_bmp__decoder* self);
31373 // ---------------- VTables
31375 const wuffs_base__image_decoder__func_ptrs
31376 wuffs_bmp__decoder__func_ptrs_for__wuffs_base__image_decoder = {
31377 (wuffs_base__status(*)(void*,
31378 wuffs_base__pixel_buffer*,
31379 wuffs_base__io_buffer*,
31380 wuffs_base__pixel_blend,
31381 wuffs_base__slice_u8,
31382 wuffs_base__decode_frame_options*))(&wuffs_bmp__decoder__decode_frame),
31383 (wuffs_base__status(*)(void*,
31384 wuffs_base__frame_config*,
31385 wuffs_base__io_buffer*))(&wuffs_bmp__decoder__decode_frame_config),
31386 (wuffs_base__status(*)(void*,
31387 wuffs_base__image_config*,
31388 wuffs_base__io_buffer*))(&wuffs_bmp__decoder__decode_image_config),
31389 (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_bmp__decoder__frame_dirty_rect),
31390 (uint64_t(*)(const void*,
31391 uint32_t))(&wuffs_bmp__decoder__get_quirk),
31392 (uint32_t(*)(const void*))(&wuffs_bmp__decoder__num_animation_loops),
31393 (uint64_t(*)(const void*))(&wuffs_bmp__decoder__num_decoded_frame_configs),
31394 (uint64_t(*)(const void*))(&wuffs_bmp__decoder__num_decoded_frames),
31395 (wuffs_base__status(*)(void*,
31396 uint64_t,
31397 uint64_t))(&wuffs_bmp__decoder__restart_frame),
31398 (wuffs_base__status(*)(void*,
31399 uint32_t,
31400 uint64_t))(&wuffs_bmp__decoder__set_quirk),
31401 (wuffs_base__empty_struct(*)(void*,
31402 uint32_t,
31403 bool))(&wuffs_bmp__decoder__set_report_metadata),
31404 (wuffs_base__status(*)(void*,
31405 wuffs_base__io_buffer*,
31406 wuffs_base__more_information*,
31407 wuffs_base__io_buffer*))(&wuffs_bmp__decoder__tell_me_more),
31408 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_bmp__decoder__workbuf_len),
31411 // ---------------- Initializer Implementations
31413 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
31414 wuffs_bmp__decoder__initialize(
31415 wuffs_bmp__decoder* self,
31416 size_t sizeof_star_self,
31417 uint64_t wuffs_version,
31418 uint32_t options){
31419 if (!self) {
31420 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
31422 if (sizeof(*self) != sizeof_star_self) {
31423 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
31425 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
31426 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
31427 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
31430 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
31431 // The whole point of this if-check is to detect an uninitialized *self.
31432 // We disable the warning on GCC. Clang-5.0 does not have this warning.
31433 #if !defined(__clang__) && defined(__GNUC__)
31434 #pragma GCC diagnostic push
31435 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
31436 #endif
31437 if (self->private_impl.magic != 0) {
31438 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
31440 #if !defined(__clang__) && defined(__GNUC__)
31441 #pragma GCC diagnostic pop
31442 #endif
31443 } else {
31444 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
31445 memset(self, 0, sizeof(*self));
31446 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
31447 } else {
31448 memset(&(self->private_impl), 0, sizeof(self->private_impl));
31452 self->private_impl.magic = WUFFS_BASE__MAGIC;
31453 self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
31454 wuffs_base__image_decoder__vtable_name;
31455 self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
31456 (const void*)(&wuffs_bmp__decoder__func_ptrs_for__wuffs_base__image_decoder);
31457 return wuffs_base__make_status(NULL);
31460 wuffs_bmp__decoder*
31461 wuffs_bmp__decoder__alloc(void) {
31462 wuffs_bmp__decoder* x =
31463 (wuffs_bmp__decoder*)(calloc(1, sizeof(wuffs_bmp__decoder)));
31464 if (!x) {
31465 return NULL;
31467 if (wuffs_bmp__decoder__initialize(
31468 x, sizeof(wuffs_bmp__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
31469 free(x);
31470 return NULL;
31472 return x;
31475 size_t
31476 sizeof__wuffs_bmp__decoder(void) {
31477 return sizeof(wuffs_bmp__decoder);
31480 // ---------------- Function Implementations
31482 // -------- func bmp.decoder.get_quirk
31484 WUFFS_BASE__GENERATED_C_CODE
31485 WUFFS_BASE__MAYBE_STATIC uint64_t
31486 wuffs_bmp__decoder__get_quirk(
31487 const wuffs_bmp__decoder* self,
31488 uint32_t a_key) {
31489 if (!self) {
31490 return 0;
31492 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
31493 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
31494 return 0;
31497 return 0u;
31500 // -------- func bmp.decoder.set_quirk
31502 WUFFS_BASE__GENERATED_C_CODE
31503 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
31504 wuffs_bmp__decoder__set_quirk(
31505 wuffs_bmp__decoder* self,
31506 uint32_t a_key,
31507 uint64_t a_value) {
31508 if (!self) {
31509 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
31511 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
31512 return wuffs_base__make_status(
31513 (self->private_impl.magic == WUFFS_BASE__DISABLED)
31514 ? wuffs_base__error__disabled_by_previous_error
31515 : wuffs_base__error__initialize_not_called);
31518 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
31521 // -------- func bmp.decoder.decode_image_config
31523 WUFFS_BASE__GENERATED_C_CODE
31524 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
31525 wuffs_bmp__decoder__decode_image_config(
31526 wuffs_bmp__decoder* self,
31527 wuffs_base__image_config* a_dst,
31528 wuffs_base__io_buffer* a_src) {
31529 if (!self) {
31530 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
31532 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
31533 return wuffs_base__make_status(
31534 (self->private_impl.magic == WUFFS_BASE__DISABLED)
31535 ? wuffs_base__error__disabled_by_previous_error
31536 : wuffs_base__error__initialize_not_called);
31538 if (!a_src) {
31539 self->private_impl.magic = WUFFS_BASE__DISABLED;
31540 return wuffs_base__make_status(wuffs_base__error__bad_argument);
31542 if ((self->private_impl.active_coroutine != 0) &&
31543 (self->private_impl.active_coroutine != 1)) {
31544 self->private_impl.magic = WUFFS_BASE__DISABLED;
31545 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
31547 self->private_impl.active_coroutine = 0;
31548 wuffs_base__status status = wuffs_base__make_status(NULL);
31550 wuffs_base__status v_status = wuffs_base__make_status(NULL);
31552 uint32_t coro_susp_point = self->private_impl.p_decode_image_config;
31553 switch (coro_susp_point) {
31554 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
31556 while (true) {
31558 wuffs_base__status t_0 = wuffs_bmp__decoder__do_decode_image_config(self, a_dst, a_src);
31559 v_status = t_0;
31561 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
31562 status = wuffs_base__make_status(wuffs_bmp__error__truncated_input);
31563 goto exit;
31565 status = v_status;
31566 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
31570 self->private_impl.p_decode_image_config = 0;
31571 goto exit;
31574 goto suspend;
31575 suspend:
31576 self->private_impl.p_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
31577 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
31579 goto exit;
31580 exit:
31581 if (wuffs_base__status__is_error(&status)) {
31582 self->private_impl.magic = WUFFS_BASE__DISABLED;
31584 return status;
31587 // -------- func bmp.decoder.do_decode_image_config
31589 WUFFS_BASE__GENERATED_C_CODE
31590 static wuffs_base__status
31591 wuffs_bmp__decoder__do_decode_image_config(
31592 wuffs_bmp__decoder* self,
31593 wuffs_base__image_config* a_dst,
31594 wuffs_base__io_buffer* a_src) {
31595 wuffs_base__status status = wuffs_base__make_status(NULL);
31597 uint32_t v_magic = 0;
31598 uint32_t v_width = 0;
31599 uint32_t v_height = 0;
31600 uint32_t v_planes = 0;
31601 uint32_t v_n = 0;
31602 uint32_t v_dst_pixfmt = 0;
31603 uint32_t v_byte_width = 0;
31605 const uint8_t* iop_a_src = NULL;
31606 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31607 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31608 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31609 if (a_src && a_src->data.ptr) {
31610 io0_a_src = a_src->data.ptr;
31611 io1_a_src = io0_a_src + a_src->meta.ri;
31612 iop_a_src = io1_a_src;
31613 io2_a_src = io0_a_src + a_src->meta.wi;
31616 uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config;
31617 switch (coro_susp_point) {
31618 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
31620 if ((self->private_impl.f_call_sequence != 0u) || (self->private_impl.f_io_redirect_fourcc == 1u)) {
31621 status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
31622 goto exit;
31623 } else if (self->private_impl.f_io_redirect_fourcc != 0u) {
31624 status = wuffs_base__make_status(wuffs_base__note__i_o_redirect);
31625 goto ok;
31628 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
31629 uint32_t t_0;
31630 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
31631 t_0 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
31632 iop_a_src += 2;
31633 } else {
31634 self->private_data.s_do_decode_image_config.scratch = 0;
31635 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
31636 while (true) {
31637 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31638 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31639 goto suspend;
31641 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
31642 uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
31643 *scratch <<= 8;
31644 *scratch >>= 8;
31645 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
31646 if (num_bits_0 == 8) {
31647 t_0 = ((uint32_t)(*scratch));
31648 break;
31650 num_bits_0 += 8u;
31651 *scratch |= ((uint64_t)(num_bits_0)) << 56;
31654 v_magic = t_0;
31656 if (v_magic != 19778u) {
31657 status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
31658 goto exit;
31660 self->private_data.s_do_decode_image_config.scratch = 8u;
31661 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
31662 if (self->private_data.s_do_decode_image_config.scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
31663 self->private_data.s_do_decode_image_config.scratch -= ((uint64_t)(io2_a_src - iop_a_src));
31664 iop_a_src = io2_a_src;
31665 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31666 goto suspend;
31668 iop_a_src += self->private_data.s_do_decode_image_config.scratch;
31670 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
31671 uint32_t t_1;
31672 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
31673 t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
31674 iop_a_src += 4;
31675 } else {
31676 self->private_data.s_do_decode_image_config.scratch = 0;
31677 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
31678 while (true) {
31679 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31680 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31681 goto suspend;
31683 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
31684 uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
31685 *scratch <<= 8;
31686 *scratch >>= 8;
31687 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
31688 if (num_bits_1 == 24) {
31689 t_1 = ((uint32_t)(*scratch));
31690 break;
31692 num_bits_1 += 8u;
31693 *scratch |= ((uint64_t)(num_bits_1)) << 56;
31696 self->private_impl.f_padding = t_1;
31698 if (self->private_impl.f_padding < 14u) {
31699 status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
31700 goto exit;
31702 self->private_impl.f_padding -= 14u;
31703 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))));
31705 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
31706 uint32_t t_2;
31707 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
31708 t_2 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
31709 iop_a_src += 4;
31710 } else {
31711 self->private_data.s_do_decode_image_config.scratch = 0;
31712 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
31713 while (true) {
31714 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31715 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31716 goto suspend;
31718 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
31719 uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
31720 *scratch <<= 8;
31721 *scratch >>= 8;
31722 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
31723 if (num_bits_2 == 24) {
31724 t_2 = ((uint32_t)(*scratch));
31725 break;
31727 num_bits_2 += 8u;
31728 *scratch |= ((uint64_t)(num_bits_2)) << 56;
31731 self->private_impl.f_bitmap_info_len = t_2;
31733 if (self->private_impl.f_padding < self->private_impl.f_bitmap_info_len) {
31734 status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
31735 goto exit;
31737 self->private_impl.f_padding -= self->private_impl.f_bitmap_info_len;
31738 if (self->private_impl.f_bitmap_info_len == 12u) {
31740 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
31741 uint32_t t_3;
31742 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
31743 t_3 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
31744 iop_a_src += 2;
31745 } else {
31746 self->private_data.s_do_decode_image_config.scratch = 0;
31747 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
31748 while (true) {
31749 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31750 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31751 goto suspend;
31753 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
31754 uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56));
31755 *scratch <<= 8;
31756 *scratch >>= 8;
31757 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3;
31758 if (num_bits_3 == 8) {
31759 t_3 = ((uint32_t)(*scratch));
31760 break;
31762 num_bits_3 += 8u;
31763 *scratch |= ((uint64_t)(num_bits_3)) << 56;
31766 self->private_impl.f_width = t_3;
31769 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
31770 uint32_t t_4;
31771 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
31772 t_4 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
31773 iop_a_src += 2;
31774 } else {
31775 self->private_data.s_do_decode_image_config.scratch = 0;
31776 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
31777 while (true) {
31778 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31779 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31780 goto suspend;
31782 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
31783 uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
31784 *scratch <<= 8;
31785 *scratch >>= 8;
31786 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
31787 if (num_bits_4 == 8) {
31788 t_4 = ((uint32_t)(*scratch));
31789 break;
31791 num_bits_4 += 8u;
31792 *scratch |= ((uint64_t)(num_bits_4)) << 56;
31795 self->private_impl.f_height = t_4;
31798 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
31799 uint32_t t_5;
31800 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
31801 t_5 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
31802 iop_a_src += 2;
31803 } else {
31804 self->private_data.s_do_decode_image_config.scratch = 0;
31805 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
31806 while (true) {
31807 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31808 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31809 goto suspend;
31811 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
31812 uint32_t num_bits_5 = ((uint32_t)(*scratch >> 56));
31813 *scratch <<= 8;
31814 *scratch >>= 8;
31815 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_5;
31816 if (num_bits_5 == 8) {
31817 t_5 = ((uint32_t)(*scratch));
31818 break;
31820 num_bits_5 += 8u;
31821 *scratch |= ((uint64_t)(num_bits_5)) << 56;
31824 v_planes = t_5;
31826 if (v_planes != 1u) {
31827 status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
31828 goto exit;
31831 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
31832 uint32_t t_6;
31833 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
31834 t_6 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
31835 iop_a_src += 2;
31836 } else {
31837 self->private_data.s_do_decode_image_config.scratch = 0;
31838 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
31839 while (true) {
31840 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31841 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31842 goto suspend;
31844 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
31845 uint32_t num_bits_6 = ((uint32_t)(*scratch >> 56));
31846 *scratch <<= 8;
31847 *scratch >>= 8;
31848 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_6;
31849 if (num_bits_6 == 8) {
31850 t_6 = ((uint32_t)(*scratch));
31851 break;
31853 num_bits_6 += 8u;
31854 *scratch |= ((uint64_t)(num_bits_6)) << 56;
31857 self->private_impl.f_bits_per_pixel = t_6;
31859 } else if (self->private_impl.f_bitmap_info_len == 16u) {
31861 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
31862 uint32_t t_7;
31863 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
31864 t_7 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
31865 iop_a_src += 4;
31866 } else {
31867 self->private_data.s_do_decode_image_config.scratch = 0;
31868 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(17);
31869 while (true) {
31870 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31871 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31872 goto suspend;
31874 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
31875 uint32_t num_bits_7 = ((uint32_t)(*scratch >> 56));
31876 *scratch <<= 8;
31877 *scratch >>= 8;
31878 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_7;
31879 if (num_bits_7 == 24) {
31880 t_7 = ((uint32_t)(*scratch));
31881 break;
31883 num_bits_7 += 8u;
31884 *scratch |= ((uint64_t)(num_bits_7)) << 56;
31887 v_width = t_7;
31889 if (v_width > 2147483647u) {
31890 status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
31891 goto exit;
31892 } else if (v_width > 16777215u) {
31893 status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension);
31894 goto exit;
31896 self->private_impl.f_width = v_width;
31898 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(18);
31899 uint32_t t_8;
31900 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
31901 t_8 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
31902 iop_a_src += 4;
31903 } else {
31904 self->private_data.s_do_decode_image_config.scratch = 0;
31905 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(19);
31906 while (true) {
31907 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31908 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31909 goto suspend;
31911 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
31912 uint32_t num_bits_8 = ((uint32_t)(*scratch >> 56));
31913 *scratch <<= 8;
31914 *scratch >>= 8;
31915 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_8;
31916 if (num_bits_8 == 24) {
31917 t_8 = ((uint32_t)(*scratch));
31918 break;
31920 num_bits_8 += 8u;
31921 *scratch |= ((uint64_t)(num_bits_8)) << 56;
31924 v_height = t_8;
31926 if (v_height > 2147483647u) {
31927 status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
31928 goto exit;
31929 } else if (v_height > 16777215u) {
31930 status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension);
31931 goto exit;
31933 self->private_impl.f_height = v_height;
31935 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(20);
31936 uint32_t t_9;
31937 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
31938 t_9 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
31939 iop_a_src += 2;
31940 } else {
31941 self->private_data.s_do_decode_image_config.scratch = 0;
31942 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(21);
31943 while (true) {
31944 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31945 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31946 goto suspend;
31948 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
31949 uint32_t num_bits_9 = ((uint32_t)(*scratch >> 56));
31950 *scratch <<= 8;
31951 *scratch >>= 8;
31952 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_9;
31953 if (num_bits_9 == 8) {
31954 t_9 = ((uint32_t)(*scratch));
31955 break;
31957 num_bits_9 += 8u;
31958 *scratch |= ((uint64_t)(num_bits_9)) << 56;
31961 v_planes = t_9;
31963 if (v_planes != 1u) {
31964 status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
31965 goto exit;
31968 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(22);
31969 uint32_t t_10;
31970 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
31971 t_10 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
31972 iop_a_src += 2;
31973 } else {
31974 self->private_data.s_do_decode_image_config.scratch = 0;
31975 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(23);
31976 while (true) {
31977 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31978 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31979 goto suspend;
31981 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
31982 uint32_t num_bits_10 = ((uint32_t)(*scratch >> 56));
31983 *scratch <<= 8;
31984 *scratch >>= 8;
31985 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_10;
31986 if (num_bits_10 == 8) {
31987 t_10 = ((uint32_t)(*scratch));
31988 break;
31990 num_bits_10 += 8u;
31991 *scratch |= ((uint64_t)(num_bits_10)) << 56;
31994 self->private_impl.f_bits_per_pixel = t_10;
31996 } else {
31998 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(24);
31999 uint32_t t_11;
32000 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
32001 t_11 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
32002 iop_a_src += 4;
32003 } else {
32004 self->private_data.s_do_decode_image_config.scratch = 0;
32005 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(25);
32006 while (true) {
32007 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
32008 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32009 goto suspend;
32011 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
32012 uint32_t num_bits_11 = ((uint32_t)(*scratch >> 56));
32013 *scratch <<= 8;
32014 *scratch >>= 8;
32015 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_11;
32016 if (num_bits_11 == 24) {
32017 t_11 = ((uint32_t)(*scratch));
32018 break;
32020 num_bits_11 += 8u;
32021 *scratch |= ((uint64_t)(num_bits_11)) << 56;
32024 v_width = t_11;
32026 if (v_width > 2147483647u) {
32027 status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
32028 goto exit;
32029 } else if (v_width > 16777215u) {
32030 status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension);
32031 goto exit;
32033 self->private_impl.f_width = v_width;
32035 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(26);
32036 uint32_t t_12;
32037 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
32038 t_12 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
32039 iop_a_src += 4;
32040 } else {
32041 self->private_data.s_do_decode_image_config.scratch = 0;
32042 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(27);
32043 while (true) {
32044 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
32045 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32046 goto suspend;
32048 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
32049 uint32_t num_bits_12 = ((uint32_t)(*scratch >> 56));
32050 *scratch <<= 8;
32051 *scratch >>= 8;
32052 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_12;
32053 if (num_bits_12 == 24) {
32054 t_12 = ((uint32_t)(*scratch));
32055 break;
32057 num_bits_12 += 8u;
32058 *scratch |= ((uint64_t)(num_bits_12)) << 56;
32061 v_height = t_12;
32063 if (v_height == 2147483648u) {
32064 status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
32065 goto exit;
32066 } else if (v_height > 2147483648u) {
32067 v_height = ((uint32_t)(0u - v_height));
32068 if (v_height > 16777215u) {
32069 status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension);
32070 goto exit;
32072 self->private_impl.f_height = v_height;
32073 self->private_impl.f_top_down = true;
32074 } else if (v_height > 16777215u) {
32075 status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension);
32076 goto exit;
32077 } else {
32078 self->private_impl.f_height = v_height;
32081 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(28);
32082 uint32_t t_13;
32083 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
32084 t_13 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
32085 iop_a_src += 2;
32086 } else {
32087 self->private_data.s_do_decode_image_config.scratch = 0;
32088 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(29);
32089 while (true) {
32090 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
32091 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32092 goto suspend;
32094 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
32095 uint32_t num_bits_13 = ((uint32_t)(*scratch >> 56));
32096 *scratch <<= 8;
32097 *scratch >>= 8;
32098 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_13;
32099 if (num_bits_13 == 8) {
32100 t_13 = ((uint32_t)(*scratch));
32101 break;
32103 num_bits_13 += 8u;
32104 *scratch |= ((uint64_t)(num_bits_13)) << 56;
32107 v_planes = t_13;
32109 if (v_planes != 1u) {
32110 status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
32111 goto exit;
32114 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(30);
32115 uint32_t t_14;
32116 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
32117 t_14 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
32118 iop_a_src += 2;
32119 } else {
32120 self->private_data.s_do_decode_image_config.scratch = 0;
32121 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(31);
32122 while (true) {
32123 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
32124 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32125 goto suspend;
32127 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
32128 uint32_t num_bits_14 = ((uint32_t)(*scratch >> 56));
32129 *scratch <<= 8;
32130 *scratch >>= 8;
32131 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_14;
32132 if (num_bits_14 == 8) {
32133 t_14 = ((uint32_t)(*scratch));
32134 break;
32136 num_bits_14 += 8u;
32137 *scratch |= ((uint64_t)(num_bits_14)) << 56;
32140 self->private_impl.f_bits_per_pixel = t_14;
32143 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(32);
32144 uint32_t t_15;
32145 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
32146 t_15 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
32147 iop_a_src += 4;
32148 } else {
32149 self->private_data.s_do_decode_image_config.scratch = 0;
32150 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(33);
32151 while (true) {
32152 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
32153 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32154 goto suspend;
32156 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
32157 uint32_t num_bits_15 = ((uint32_t)(*scratch >> 56));
32158 *scratch <<= 8;
32159 *scratch >>= 8;
32160 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_15;
32161 if (num_bits_15 == 24) {
32162 t_15 = ((uint32_t)(*scratch));
32163 break;
32165 num_bits_15 += 8u;
32166 *scratch |= ((uint64_t)(num_bits_15)) << 56;
32169 self->private_impl.f_compression = t_15;
32171 if (self->private_impl.f_bits_per_pixel == 0u) {
32172 if (self->private_impl.f_compression == 4u) {
32173 self->private_impl.f_io_redirect_fourcc = 1246774599u;
32174 status = wuffs_base__make_status(wuffs_base__note__i_o_redirect);
32175 goto ok;
32176 } else if (self->private_impl.f_compression == 5u) {
32177 self->private_impl.f_io_redirect_fourcc = 1347307296u;
32178 status = wuffs_base__make_status(wuffs_base__note__i_o_redirect);
32179 goto ok;
32181 status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
32182 goto exit;
32184 self->private_data.s_do_decode_image_config.scratch = 20u;
32185 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(34);
32186 if (self->private_data.s_do_decode_image_config.scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
32187 self->private_data.s_do_decode_image_config.scratch -= ((uint64_t)(io2_a_src - iop_a_src));
32188 iop_a_src = io2_a_src;
32189 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32190 goto suspend;
32192 iop_a_src += self->private_data.s_do_decode_image_config.scratch;
32193 if (self->private_impl.f_bitmap_info_len == 40u) {
32194 if (self->private_impl.f_bits_per_pixel >= 16u) {
32195 if (self->private_impl.f_padding >= 16u) {
32196 self->private_impl.f_bitmap_info_len = 56u;
32197 self->private_impl.f_padding -= 16u;
32198 } else if (self->private_impl.f_padding >= 12u) {
32199 self->private_impl.f_bitmap_info_len = 52u;
32200 self->private_impl.f_padding -= 12u;
32203 } else if ((self->private_impl.f_bitmap_info_len != 52u) &&
32204 (self->private_impl.f_bitmap_info_len != 56u) &&
32205 (self->private_impl.f_bitmap_info_len != 64u) &&
32206 (self->private_impl.f_bitmap_info_len != 108u) &&
32207 (self->private_impl.f_bitmap_info_len != 124u)) {
32208 status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
32209 goto exit;
32211 if (self->private_impl.f_compression == 6u) {
32212 self->private_impl.f_compression = 3u;
32214 if (self->private_impl.f_compression == 3u) {
32215 if (self->private_impl.f_bitmap_info_len >= 52u) {
32217 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(35);
32218 uint32_t t_16;
32219 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
32220 t_16 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
32221 iop_a_src += 4;
32222 } else {
32223 self->private_data.s_do_decode_image_config.scratch = 0;
32224 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(36);
32225 while (true) {
32226 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
32227 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32228 goto suspend;
32230 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
32231 uint32_t num_bits_16 = ((uint32_t)(*scratch >> 56));
32232 *scratch <<= 8;
32233 *scratch >>= 8;
32234 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_16;
32235 if (num_bits_16 == 24) {
32236 t_16 = ((uint32_t)(*scratch));
32237 break;
32239 num_bits_16 += 8u;
32240 *scratch |= ((uint64_t)(num_bits_16)) << 56;
32243 self->private_impl.f_channel_masks[2u] = t_16;
32246 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(37);
32247 uint32_t t_17;
32248 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
32249 t_17 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
32250 iop_a_src += 4;
32251 } else {
32252 self->private_data.s_do_decode_image_config.scratch = 0;
32253 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(38);
32254 while (true) {
32255 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
32256 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32257 goto suspend;
32259 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
32260 uint32_t num_bits_17 = ((uint32_t)(*scratch >> 56));
32261 *scratch <<= 8;
32262 *scratch >>= 8;
32263 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_17;
32264 if (num_bits_17 == 24) {
32265 t_17 = ((uint32_t)(*scratch));
32266 break;
32268 num_bits_17 += 8u;
32269 *scratch |= ((uint64_t)(num_bits_17)) << 56;
32272 self->private_impl.f_channel_masks[1u] = t_17;
32275 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(39);
32276 uint32_t t_18;
32277 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
32278 t_18 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
32279 iop_a_src += 4;
32280 } else {
32281 self->private_data.s_do_decode_image_config.scratch = 0;
32282 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(40);
32283 while (true) {
32284 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
32285 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32286 goto suspend;
32288 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
32289 uint32_t num_bits_18 = ((uint32_t)(*scratch >> 56));
32290 *scratch <<= 8;
32291 *scratch >>= 8;
32292 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_18;
32293 if (num_bits_18 == 24) {
32294 t_18 = ((uint32_t)(*scratch));
32295 break;
32297 num_bits_18 += 8u;
32298 *scratch |= ((uint64_t)(num_bits_18)) << 56;
32301 self->private_impl.f_channel_masks[0u] = t_18;
32303 if (self->private_impl.f_bitmap_info_len >= 56u) {
32305 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(41);
32306 uint32_t t_19;
32307 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
32308 t_19 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
32309 iop_a_src += 4;
32310 } else {
32311 self->private_data.s_do_decode_image_config.scratch = 0;
32312 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(42);
32313 while (true) {
32314 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
32315 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32316 goto suspend;
32318 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
32319 uint32_t num_bits_19 = ((uint32_t)(*scratch >> 56));
32320 *scratch <<= 8;
32321 *scratch >>= 8;
32322 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_19;
32323 if (num_bits_19 == 24) {
32324 t_19 = ((uint32_t)(*scratch));
32325 break;
32327 num_bits_19 += 8u;
32328 *scratch |= ((uint64_t)(num_bits_19)) << 56;
32331 self->private_impl.f_channel_masks[3u] = t_19;
32333 self->private_data.s_do_decode_image_config.scratch = ((uint32_t)(self->private_impl.f_bitmap_info_len - 56u));
32334 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(43);
32335 if (self->private_data.s_do_decode_image_config.scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
32336 self->private_data.s_do_decode_image_config.scratch -= ((uint64_t)(io2_a_src - iop_a_src));
32337 iop_a_src = io2_a_src;
32338 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32339 goto suspend;
32341 iop_a_src += self->private_data.s_do_decode_image_config.scratch;
32343 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)) {
32344 if (self->private_impl.f_bits_per_pixel == 24u) {
32345 self->private_impl.f_compression = 0u;
32346 } else if (self->private_impl.f_bits_per_pixel == 32u) {
32347 if ((self->private_impl.f_channel_masks[3u] == 0u) || (self->private_impl.f_channel_masks[3u] == 4278190080u)) {
32348 self->private_impl.f_compression = 0u;
32352 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(44);
32353 status = wuffs_bmp__decoder__process_masks(self);
32354 if (status.repr) {
32355 goto suspend;
32358 } else if (self->private_impl.f_bitmap_info_len >= 40u) {
32359 v_n = (self->private_impl.f_bitmap_info_len - 40u);
32360 self->private_data.s_do_decode_image_config.scratch = v_n;
32361 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(45);
32362 if (self->private_data.s_do_decode_image_config.scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
32363 self->private_data.s_do_decode_image_config.scratch -= ((uint64_t)(io2_a_src - iop_a_src));
32364 iop_a_src = io2_a_src;
32365 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32366 goto suspend;
32368 iop_a_src += self->private_data.s_do_decode_image_config.scratch;
32369 } else {
32370 status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
32371 goto exit;
32374 if (self->private_impl.f_compression != 3u) {
32375 if (self->private_impl.f_bits_per_pixel < 16u) {
32376 if (a_src) {
32377 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
32379 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(46);
32380 status = wuffs_bmp__decoder__read_palette(self, a_src);
32381 if (a_src) {
32382 iop_a_src = a_src->data.ptr + a_src->meta.ri;
32384 if (status.repr) {
32385 goto suspend;
32389 if (self->private_impl.f_compression == 0u) {
32390 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)) {
32391 self->private_impl.f_src_pixfmt = 2198077448u;
32392 self->private_impl.f_compression = 256u;
32393 } else if (self->private_impl.f_bits_per_pixel == 8u) {
32394 self->private_impl.f_src_pixfmt = 2198077448u;
32395 } else if (self->private_impl.f_bits_per_pixel == 16u) {
32396 self->private_impl.f_compression = 3u;
32397 self->private_impl.f_channel_masks[0u] = 31u;
32398 self->private_impl.f_channel_masks[1u] = 992u;
32399 self->private_impl.f_channel_masks[2u] = 31744u;
32400 self->private_impl.f_channel_masks[3u] = 0u;
32401 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(47);
32402 status = wuffs_bmp__decoder__process_masks(self);
32403 if (status.repr) {
32404 goto suspend;
32406 self->private_impl.f_src_pixfmt = 2164308923u;
32407 } else if (self->private_impl.f_bits_per_pixel == 24u) {
32408 self->private_impl.f_src_pixfmt = 2147485832u;
32409 } else if (self->private_impl.f_bits_per_pixel == 32u) {
32410 if (self->private_impl.f_channel_masks[3u] == 0u) {
32411 self->private_impl.f_src_pixfmt = 2415954056u;
32412 } else {
32413 self->private_impl.f_src_pixfmt = 2164295816u;
32415 } else {
32416 status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
32417 goto exit;
32419 } else if (self->private_impl.f_compression == 1u) {
32420 if (self->private_impl.f_bits_per_pixel == 8u) {
32421 self->private_impl.f_src_pixfmt = 2198077448u;
32422 } else {
32423 status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
32424 goto exit;
32426 } else if (self->private_impl.f_compression == 2u) {
32427 if (self->private_impl.f_bits_per_pixel == 4u) {
32428 self->private_impl.f_src_pixfmt = 2198077448u;
32429 } else {
32430 status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
32431 goto exit;
32433 } else if (self->private_impl.f_compression == 3u) {
32434 if ((self->private_impl.f_bits_per_pixel == 16u) || (self->private_impl.f_bits_per_pixel == 32u)) {
32435 self->private_impl.f_src_pixfmt = 2164308923u;
32436 } else {
32437 status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
32438 goto exit;
32440 } else {
32441 status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
32442 goto exit;
32444 if (((self->private_impl.f_bitmap_info_len < 40u) || (self->private_impl.f_bitmap_info_len == 64u)) &&
32445 (self->private_impl.f_bits_per_pixel != 1u) &&
32446 (self->private_impl.f_bits_per_pixel != 4u) &&
32447 (self->private_impl.f_bits_per_pixel != 8u) &&
32448 (self->private_impl.f_bits_per_pixel != 24u)) {
32449 status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
32450 goto exit;
32452 if (self->private_impl.f_bits_per_pixel == 1u) {
32453 v_byte_width = ((self->private_impl.f_width >> 3u) + (((self->private_impl.f_width & 7u) + 7u) >> 3u));
32454 self->private_impl.f_pad_per_row = ((4u - (v_byte_width & 3u)) & 3u);
32455 } else if (self->private_impl.f_bits_per_pixel == 2u) {
32456 v_byte_width = ((self->private_impl.f_width >> 2u) + (((self->private_impl.f_width & 3u) + 3u) >> 2u));
32457 self->private_impl.f_pad_per_row = ((4u - (v_byte_width & 3u)) & 3u);
32458 } else if (self->private_impl.f_bits_per_pixel == 4u) {
32459 v_byte_width = ((self->private_impl.f_width >> 1u) + (self->private_impl.f_width & 1u));
32460 self->private_impl.f_pad_per_row = ((4u - (v_byte_width & 3u)) & 3u);
32461 } else if (self->private_impl.f_bits_per_pixel == 8u) {
32462 self->private_impl.f_pad_per_row = ((4u - (self->private_impl.f_width & 3u)) & 3u);
32463 } else if (self->private_impl.f_bits_per_pixel == 16u) {
32464 self->private_impl.f_pad_per_row = ((self->private_impl.f_width & 1u) * 2u);
32465 } else if (self->private_impl.f_bits_per_pixel == 24u) {
32466 self->private_impl.f_pad_per_row = (self->private_impl.f_width & 3u);
32467 } else if (self->private_impl.f_bits_per_pixel == 32u) {
32468 self->private_impl.f_pad_per_row = 0u;
32470 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)));
32471 if (a_dst != NULL) {
32472 v_dst_pixfmt = 2164295816u;
32473 if ((self->private_impl.f_channel_num_bits[0u] > 8u) ||
32474 (self->private_impl.f_channel_num_bits[1u] > 8u) ||
32475 (self->private_impl.f_channel_num_bits[2u] > 8u) ||
32476 (self->private_impl.f_channel_num_bits[3u] > 8u)) {
32477 v_dst_pixfmt = 2164308923u;
32478 } else if (((self->private_impl.f_src_pixfmt == 2198077448u) || (self->private_impl.f_src_pixfmt == 2147485832u) || (self->private_impl.f_src_pixfmt == 2415954056u)) || ((self->private_impl.f_src_pixfmt == 2164308923u) && (self->private_impl.f_channel_masks[3u] == 0u))) {
32479 v_dst_pixfmt = 2415954056u;
32481 wuffs_base__image_config__set(
32482 a_dst,
32483 v_dst_pixfmt,
32485 self->private_impl.f_width,
32486 self->private_impl.f_height,
32487 self->private_impl.f_frame_config_io_position,
32488 (self->private_impl.f_channel_masks[3u] == 0u));
32490 self->private_impl.f_call_sequence = 32u;
32493 self->private_impl.p_do_decode_image_config = 0;
32494 goto exit;
32497 goto suspend;
32498 suspend:
32499 self->private_impl.p_do_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
32501 goto exit;
32502 exit:
32503 if (a_src && a_src->data.ptr) {
32504 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
32507 return status;
32510 // -------- func bmp.decoder.decode_frame_config
32512 WUFFS_BASE__GENERATED_C_CODE
32513 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
32514 wuffs_bmp__decoder__decode_frame_config(
32515 wuffs_bmp__decoder* self,
32516 wuffs_base__frame_config* a_dst,
32517 wuffs_base__io_buffer* a_src) {
32518 if (!self) {
32519 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
32521 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
32522 return wuffs_base__make_status(
32523 (self->private_impl.magic == WUFFS_BASE__DISABLED)
32524 ? wuffs_base__error__disabled_by_previous_error
32525 : wuffs_base__error__initialize_not_called);
32527 if (!a_src) {
32528 self->private_impl.magic = WUFFS_BASE__DISABLED;
32529 return wuffs_base__make_status(wuffs_base__error__bad_argument);
32531 if ((self->private_impl.active_coroutine != 0) &&
32532 (self->private_impl.active_coroutine != 2)) {
32533 self->private_impl.magic = WUFFS_BASE__DISABLED;
32534 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
32536 self->private_impl.active_coroutine = 0;
32537 wuffs_base__status status = wuffs_base__make_status(NULL);
32539 wuffs_base__status v_status = wuffs_base__make_status(NULL);
32541 uint32_t coro_susp_point = self->private_impl.p_decode_frame_config;
32542 switch (coro_susp_point) {
32543 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
32545 while (true) {
32547 wuffs_base__status t_0 = wuffs_bmp__decoder__do_decode_frame_config(self, a_dst, a_src);
32548 v_status = t_0;
32550 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
32551 status = wuffs_base__make_status(wuffs_bmp__error__truncated_input);
32552 goto exit;
32554 status = v_status;
32555 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
32559 self->private_impl.p_decode_frame_config = 0;
32560 goto exit;
32563 goto suspend;
32564 suspend:
32565 self->private_impl.p_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
32566 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
32568 goto exit;
32569 exit:
32570 if (wuffs_base__status__is_error(&status)) {
32571 self->private_impl.magic = WUFFS_BASE__DISABLED;
32573 return status;
32576 // -------- func bmp.decoder.do_decode_frame_config
32578 WUFFS_BASE__GENERATED_C_CODE
32579 static wuffs_base__status
32580 wuffs_bmp__decoder__do_decode_frame_config(
32581 wuffs_bmp__decoder* self,
32582 wuffs_base__frame_config* a_dst,
32583 wuffs_base__io_buffer* a_src) {
32584 wuffs_base__status status = wuffs_base__make_status(NULL);
32586 const uint8_t* iop_a_src = NULL;
32587 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32588 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32589 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32590 if (a_src && a_src->data.ptr) {
32591 io0_a_src = a_src->data.ptr;
32592 io1_a_src = io0_a_src + a_src->meta.ri;
32593 iop_a_src = io1_a_src;
32594 io2_a_src = io0_a_src + a_src->meta.wi;
32597 uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config;
32598 switch (coro_susp_point) {
32599 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
32601 if (self->private_impl.f_call_sequence == 32u) {
32602 } else if (self->private_impl.f_call_sequence < 32u) {
32603 if (a_src) {
32604 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
32606 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
32607 status = wuffs_bmp__decoder__do_decode_image_config(self, NULL, a_src);
32608 if (a_src) {
32609 iop_a_src = a_src->data.ptr + a_src->meta.ri;
32611 if (status.repr) {
32612 goto suspend;
32614 } else if (self->private_impl.f_call_sequence == 40u) {
32615 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)))) {
32616 status = wuffs_base__make_status(wuffs_base__error__bad_restart);
32617 goto exit;
32619 } else if (self->private_impl.f_call_sequence == 64u) {
32620 self->private_impl.f_call_sequence = 96u;
32621 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
32622 goto ok;
32623 } else {
32624 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
32625 goto ok;
32627 if (a_dst != NULL) {
32628 wuffs_base__frame_config__set(
32629 a_dst,
32630 wuffs_base__utility__make_rect_ie_u32(
32633 self->private_impl.f_width,
32634 self->private_impl.f_height),
32635 ((wuffs_base__flicks)(0u)),
32637 self->private_impl.f_frame_config_io_position,
32639 true,
32640 false,
32641 4278190080u);
32643 self->private_impl.f_call_sequence = 64u;
32646 self->private_impl.p_do_decode_frame_config = 0;
32647 goto exit;
32650 goto suspend;
32651 suspend:
32652 self->private_impl.p_do_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
32654 goto exit;
32655 exit:
32656 if (a_src && a_src->data.ptr) {
32657 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
32660 return status;
32663 // -------- func bmp.decoder.decode_frame
32665 WUFFS_BASE__GENERATED_C_CODE
32666 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
32667 wuffs_bmp__decoder__decode_frame(
32668 wuffs_bmp__decoder* self,
32669 wuffs_base__pixel_buffer* a_dst,
32670 wuffs_base__io_buffer* a_src,
32671 wuffs_base__pixel_blend a_blend,
32672 wuffs_base__slice_u8 a_workbuf,
32673 wuffs_base__decode_frame_options* a_opts) {
32674 if (!self) {
32675 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
32677 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
32678 return wuffs_base__make_status(
32679 (self->private_impl.magic == WUFFS_BASE__DISABLED)
32680 ? wuffs_base__error__disabled_by_previous_error
32681 : wuffs_base__error__initialize_not_called);
32683 if (!a_dst || !a_src) {
32684 self->private_impl.magic = WUFFS_BASE__DISABLED;
32685 return wuffs_base__make_status(wuffs_base__error__bad_argument);
32687 if ((self->private_impl.active_coroutine != 0) &&
32688 (self->private_impl.active_coroutine != 3)) {
32689 self->private_impl.magic = WUFFS_BASE__DISABLED;
32690 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
32692 self->private_impl.active_coroutine = 0;
32693 wuffs_base__status status = wuffs_base__make_status(NULL);
32695 wuffs_base__status v_status = wuffs_base__make_status(NULL);
32697 uint32_t coro_susp_point = self->private_impl.p_decode_frame;
32698 switch (coro_susp_point) {
32699 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
32701 while (true) {
32703 wuffs_base__status t_0 = wuffs_bmp__decoder__do_decode_frame(self,
32704 a_dst,
32705 a_src,
32706 a_blend,
32707 a_workbuf,
32708 a_opts);
32709 v_status = t_0;
32711 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
32712 status = wuffs_base__make_status(wuffs_bmp__error__truncated_input);
32713 goto exit;
32715 status = v_status;
32716 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
32720 self->private_impl.p_decode_frame = 0;
32721 goto exit;
32724 goto suspend;
32725 suspend:
32726 self->private_impl.p_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
32727 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
32729 goto exit;
32730 exit:
32731 if (wuffs_base__status__is_error(&status)) {
32732 self->private_impl.magic = WUFFS_BASE__DISABLED;
32734 return status;
32737 // -------- func bmp.decoder.do_decode_frame
32739 WUFFS_BASE__GENERATED_C_CODE
32740 static wuffs_base__status
32741 wuffs_bmp__decoder__do_decode_frame(
32742 wuffs_bmp__decoder* self,
32743 wuffs_base__pixel_buffer* a_dst,
32744 wuffs_base__io_buffer* a_src,
32745 wuffs_base__pixel_blend a_blend,
32746 wuffs_base__slice_u8 a_workbuf,
32747 wuffs_base__decode_frame_options* a_opts) {
32748 wuffs_base__status status = wuffs_base__make_status(NULL);
32750 wuffs_base__status v_status = wuffs_base__make_status(NULL);
32752 const uint8_t* iop_a_src = NULL;
32753 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32754 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32755 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32756 if (a_src && a_src->data.ptr) {
32757 io0_a_src = a_src->data.ptr;
32758 io1_a_src = io0_a_src + a_src->meta.ri;
32759 iop_a_src = io1_a_src;
32760 io2_a_src = io0_a_src + a_src->meta.wi;
32763 uint32_t coro_susp_point = self->private_impl.p_do_decode_frame;
32764 switch (coro_susp_point) {
32765 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
32767 if (self->private_impl.f_call_sequence == 64u) {
32768 } else if (self->private_impl.f_call_sequence < 64u) {
32769 if (a_src) {
32770 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
32772 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
32773 status = wuffs_bmp__decoder__do_decode_frame_config(self, NULL, a_src);
32774 if (a_src) {
32775 iop_a_src = a_src->data.ptr + a_src->meta.ri;
32777 if (status.repr) {
32778 goto suspend;
32780 } else {
32781 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
32782 goto ok;
32784 self->private_data.s_do_decode_frame.scratch = self->private_impl.f_padding;
32785 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
32786 if (self->private_data.s_do_decode_frame.scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
32787 self->private_data.s_do_decode_frame.scratch -= ((uint64_t)(io2_a_src - iop_a_src));
32788 iop_a_src = io2_a_src;
32789 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32790 goto suspend;
32792 iop_a_src += self->private_data.s_do_decode_frame.scratch;
32793 if ((self->private_impl.f_width > 0u) && (self->private_impl.f_height > 0u)) {
32794 self->private_impl.f_dst_x = 0u;
32795 if (self->private_impl.f_top_down) {
32796 self->private_impl.f_dst_y = 0u;
32797 self->private_impl.f_dst_y_inc = 1u;
32798 } else {
32799 self->private_impl.f_dst_y = ((uint32_t)(self->private_impl.f_height - 1u));
32800 self->private_impl.f_dst_y_inc = 4294967295u;
32802 v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
32803 wuffs_base__pixel_buffer__pixel_format(a_dst),
32804 wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8_ij(self->private_data.f_scratch, 1024, 2048)),
32805 wuffs_base__utility__make_pixel_format(self->private_impl.f_src_pixfmt),
32806 wuffs_base__make_slice_u8(self->private_data.f_src_palette, 1024),
32807 a_blend);
32808 if ( ! wuffs_base__status__is_ok(&v_status)) {
32809 status = v_status;
32810 if (wuffs_base__status__is_error(&status)) {
32811 goto exit;
32812 } else if (wuffs_base__status__is_suspension(&status)) {
32813 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
32814 goto exit;
32816 goto ok;
32818 while (true) {
32819 if (self->private_impl.f_compression == 0u) {
32820 if (a_src) {
32821 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
32823 v_status = wuffs_bmp__decoder__swizzle_none(self, a_dst, a_src);
32824 if (a_src) {
32825 iop_a_src = a_src->data.ptr + a_src->meta.ri;
32827 } else if (self->private_impl.f_compression < 3u) {
32828 if (a_src) {
32829 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
32831 v_status = wuffs_bmp__decoder__swizzle_rle(self, a_dst, a_src);
32832 if (a_src) {
32833 iop_a_src = a_src->data.ptr + a_src->meta.ri;
32835 } else if (self->private_impl.f_compression == 3u) {
32836 if (a_src) {
32837 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
32839 v_status = wuffs_bmp__decoder__swizzle_bitfields(self, a_dst, a_src);
32840 if (a_src) {
32841 iop_a_src = a_src->data.ptr + a_src->meta.ri;
32843 } else {
32844 if (a_src) {
32845 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
32847 v_status = wuffs_bmp__decoder__swizzle_low_bit_depth(self, a_dst, a_src);
32848 if (a_src) {
32849 iop_a_src = a_src->data.ptr + a_src->meta.ri;
32852 if (wuffs_base__status__is_ok(&v_status)) {
32853 break;
32854 } else if (v_status.repr != wuffs_bmp__note__internal_note_short_read) {
32855 status = v_status;
32856 if (wuffs_base__status__is_error(&status)) {
32857 goto exit;
32858 } else if (wuffs_base__status__is_suspension(&status)) {
32859 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
32860 goto exit;
32862 goto ok;
32864 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32865 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
32867 self->private_data.s_do_decode_frame.scratch = self->private_impl.f_pending_pad;
32868 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
32869 if (self->private_data.s_do_decode_frame.scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
32870 self->private_data.s_do_decode_frame.scratch -= ((uint64_t)(io2_a_src - iop_a_src));
32871 iop_a_src = io2_a_src;
32872 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32873 goto suspend;
32875 iop_a_src += self->private_data.s_do_decode_frame.scratch;
32876 self->private_impl.f_pending_pad = 0u;
32878 self->private_impl.f_call_sequence = 96u;
32881 self->private_impl.p_do_decode_frame = 0;
32882 goto exit;
32885 goto suspend;
32886 suspend:
32887 self->private_impl.p_do_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
32889 goto exit;
32890 exit:
32891 if (a_src && a_src->data.ptr) {
32892 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
32895 return status;
32898 // -------- func bmp.decoder.swizzle_none
32900 WUFFS_BASE__GENERATED_C_CODE
32901 static wuffs_base__status
32902 wuffs_bmp__decoder__swizzle_none(
32903 wuffs_bmp__decoder* self,
32904 wuffs_base__pixel_buffer* a_dst,
32905 wuffs_base__io_buffer* a_src) {
32906 wuffs_base__status status = wuffs_base__make_status(NULL);
32908 wuffs_base__pixel_format v_dst_pixfmt = {0};
32909 uint32_t v_dst_bits_per_pixel = 0;
32910 uint32_t v_dst_bytes_per_pixel = 0;
32911 uint64_t v_dst_bytes_per_row = 0;
32912 uint32_t v_src_bytes_per_pixel = 0;
32913 wuffs_base__slice_u8 v_dst_palette = {0};
32914 wuffs_base__table_u8 v_tab = {0};
32915 wuffs_base__slice_u8 v_dst = {0};
32916 uint64_t v_i = 0;
32917 uint64_t v_j = 0;
32918 uint64_t v_n = 0;
32920 const uint8_t* iop_a_src = NULL;
32921 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32922 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32923 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32924 if (a_src && a_src->data.ptr) {
32925 io0_a_src = a_src->data.ptr;
32926 io1_a_src = io0_a_src + a_src->meta.ri;
32927 iop_a_src = io1_a_src;
32928 io2_a_src = io0_a_src + a_src->meta.wi;
32931 v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
32932 v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
32933 if ((v_dst_bits_per_pixel & 7u) != 0u) {
32934 status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
32935 goto exit;
32937 v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u);
32938 v_dst_bytes_per_row = ((uint64_t)((self->private_impl.f_width * v_dst_bytes_per_pixel)));
32939 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));
32940 v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
32941 label__outer__continue:;
32942 while (true) {
32943 while (self->private_impl.f_pending_pad > 0u) {
32944 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
32945 status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
32946 goto ok;
32948 self->private_impl.f_pending_pad -= 1u;
32949 iop_a_src += 1u;
32951 while (true) {
32952 if (self->private_impl.f_dst_x == self->private_impl.f_width) {
32953 self->private_impl.f_dst_x = 0u;
32954 self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc;
32955 if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
32956 if (self->private_impl.f_height > 0u) {
32957 self->private_impl.f_pending_pad = self->private_impl.f_pad_per_row;
32959 goto label__outer__break;
32960 } else if (self->private_impl.f_pad_per_row != 0u) {
32961 self->private_impl.f_pending_pad = self->private_impl.f_pad_per_row;
32962 goto label__outer__continue;
32965 v_dst = wuffs_private_impl__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
32966 if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) {
32967 v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row);
32969 v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_dst_bytes_per_pixel)));
32970 if (v_i >= ((uint64_t)(v_dst.len))) {
32971 if (self->private_impl.f_bits_per_pixel > 32u) {
32972 status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
32973 goto exit;
32975 v_src_bytes_per_pixel = (self->private_impl.f_bits_per_pixel / 8u);
32976 if (v_src_bytes_per_pixel == 0u) {
32977 status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
32978 goto exit;
32980 v_n = (((uint64_t)(io2_a_src - iop_a_src)) / ((uint64_t)(v_src_bytes_per_pixel)));
32981 v_n = wuffs_base__u64__min(v_n, ((uint64_t)(((uint32_t)(self->private_impl.f_width - self->private_impl.f_dst_x)))));
32982 v_j = v_n;
32983 while (v_j >= 8u) {
32984 if (((uint64_t)(io2_a_src - iop_a_src)) >= ((uint64_t)((v_src_bytes_per_pixel * 8u)))) {
32985 iop_a_src += (v_src_bytes_per_pixel * 8u);
32987 v_j -= 8u;
32989 while (v_j > 0u) {
32990 if (((uint64_t)(io2_a_src - iop_a_src)) >= ((uint64_t)((v_src_bytes_per_pixel * 1u)))) {
32991 iop_a_src += (v_src_bytes_per_pixel * 1u);
32993 v_j -= 1u;
32995 } else {
32996 v_n = wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(
32997 &self->private_impl.f_swizzler,
32998 wuffs_base__slice_u8__subslice_i(v_dst, v_i),
32999 v_dst_palette,
33000 &iop_a_src,
33001 io2_a_src);
33003 if (v_n == 0u) {
33004 status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
33005 goto ok;
33007 wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n)));
33010 label__outer__break:;
33011 status = wuffs_base__make_status(NULL);
33012 goto ok;
33015 goto exit;
33016 exit:
33017 if (a_src && a_src->data.ptr) {
33018 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33021 return status;
33024 // -------- func bmp.decoder.swizzle_rle
33026 WUFFS_BASE__GENERATED_C_CODE
33027 static wuffs_base__status
33028 wuffs_bmp__decoder__swizzle_rle(
33029 wuffs_bmp__decoder* self,
33030 wuffs_base__pixel_buffer* a_dst,
33031 wuffs_base__io_buffer* a_src) {
33032 wuffs_base__status status = wuffs_base__make_status(NULL);
33034 wuffs_base__pixel_format v_dst_pixfmt = {0};
33035 uint32_t v_dst_bits_per_pixel = 0;
33036 uint32_t v_dst_bytes_per_pixel = 0;
33037 uint64_t v_dst_bytes_per_row = 0;
33038 wuffs_base__slice_u8 v_dst_palette = {0};
33039 wuffs_base__table_u8 v_tab = {0};
33040 wuffs_base__slice_u8 v_row = {0};
33041 wuffs_base__slice_u8 v_dst = {0};
33042 uint64_t v_i = 0;
33043 uint64_t v_n = 0;
33044 uint32_t v_p0 = 0;
33045 uint8_t v_code = 0;
33046 uint8_t v_indexes[2] = {0};
33047 uint32_t v_rle_state = 0;
33048 uint32_t v_chunk_bits = 0;
33049 uint32_t v_chunk_count = 0;
33051 const uint8_t* iop_a_src = NULL;
33052 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33053 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33054 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33055 if (a_src && a_src->data.ptr) {
33056 io0_a_src = a_src->data.ptr;
33057 io1_a_src = io0_a_src + a_src->meta.ri;
33058 iop_a_src = io1_a_src;
33059 io2_a_src = io0_a_src + a_src->meta.wi;
33062 v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
33063 v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
33064 if ((v_dst_bits_per_pixel & 7u) != 0u) {
33065 status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
33066 goto exit;
33068 v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u);
33069 v_dst_bytes_per_row = ((uint64_t)((self->private_impl.f_width * v_dst_bytes_per_pixel)));
33070 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));
33071 v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
33072 v_rle_state = self->private_impl.f_rle_state;
33073 label__outer__continue:;
33074 while (true) {
33075 v_row = wuffs_private_impl__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
33076 if (v_dst_bytes_per_row < ((uint64_t)(v_row.len))) {
33077 v_row = wuffs_base__slice_u8__subslice_j(v_row, v_dst_bytes_per_row);
33079 label__middle__continue:;
33080 while (true) {
33081 v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_dst_bytes_per_pixel)));
33082 if (v_i <= ((uint64_t)(v_row.len))) {
33083 v_dst = wuffs_base__slice_u8__subslice_i(v_row, v_i);
33084 } else {
33085 v_dst = wuffs_base__utility__empty_slice_u8();
33087 while (true) {
33088 if (v_rle_state == 0u) {
33089 if (((uint64_t)(io2_a_src - iop_a_src)) < 1u) {
33090 break;
33092 v_code = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
33093 iop_a_src += 1u;
33094 if (v_code == 0u) {
33095 v_rle_state = 2u;
33096 continue;
33098 self->private_impl.f_rle_length = ((uint32_t)(v_code));
33099 v_rle_state = 1u;
33100 continue;
33101 } else if (v_rle_state == 1u) {
33102 if (((uint64_t)(io2_a_src - iop_a_src)) < 1u) {
33103 break;
33105 v_code = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
33106 iop_a_src += 1u;
33107 if (self->private_impl.f_bits_per_pixel == 8u) {
33108 v_p0 = 0u;
33109 while (v_p0 < self->private_impl.f_rle_length) {
33110 self->private_data.f_scratch[v_p0] = v_code;
33111 v_p0 += 1u;
33113 } else {
33114 v_indexes[0u] = ((uint8_t)(((uint8_t)(v_code >> 4u))));
33115 v_indexes[1u] = ((uint8_t)(v_code & 15u));
33116 v_p0 = 0u;
33117 while (v_p0 < self->private_impl.f_rle_length) {
33118 self->private_data.f_scratch[(v_p0 + 0u)] = v_indexes[0u];
33119 self->private_data.f_scratch[(v_p0 + 1u)] = v_indexes[1u];
33120 v_p0 += 2u;
33123 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));
33124 wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_dst_x, self->private_impl.f_rle_length);
33125 v_rle_state = 0u;
33126 goto label__middle__continue;
33127 } else if (v_rle_state == 2u) {
33128 if (((uint64_t)(io2_a_src - iop_a_src)) < 1u) {
33129 break;
33131 v_code = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
33132 iop_a_src += 1u;
33133 if (v_code < 2u) {
33134 if ((self->private_impl.f_dst_y >= self->private_impl.f_height) && (v_code == 0u)) {
33135 status = wuffs_base__make_status(wuffs_bmp__error__bad_rle_compression);
33136 goto exit;
33138 wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(&self->private_impl.f_swizzler, v_dst, v_dst_palette, 18446744073709551615u);
33139 self->private_impl.f_dst_x = 0u;
33140 self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc;
33141 if (v_code > 0u) {
33142 goto label__outer__break;
33144 v_rle_state = 0u;
33145 goto label__outer__continue;
33146 } else if (v_code == 2u) {
33147 v_rle_state = 4u;
33148 continue;
33150 self->private_impl.f_rle_length = ((uint32_t)(v_code));
33151 self->private_impl.f_rle_padded = ((self->private_impl.f_bits_per_pixel == 8u) && (((uint8_t)(v_code & 1u)) != 0u));
33152 v_rle_state = 3u;
33153 continue;
33154 } else if (v_rle_state == 3u) {
33155 if (self->private_impl.f_bits_per_pixel == 8u) {
33156 v_n = wuffs_base__pixel_swizzler__limited_swizzle_u32_interleaved_from_reader(
33157 &self->private_impl.f_swizzler,
33158 self->private_impl.f_rle_length,
33159 v_dst,
33160 v_dst_palette,
33161 &iop_a_src,
33162 io2_a_src);
33163 wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n)));
33164 wuffs_private_impl__u32__sat_sub_indirect(&self->private_impl.f_rle_length, ((uint32_t)(v_n)));
33165 } else {
33166 v_chunk_count = ((self->private_impl.f_rle_length + 3u) / 4u);
33167 v_p0 = 0u;
33168 while ((v_chunk_count > 0u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 2u)) {
33169 v_chunk_bits = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
33170 iop_a_src += 2u;
33171 self->private_data.f_scratch[(v_p0 + 0u)] = ((uint8_t)((15u & (v_chunk_bits >> 12u))));
33172 self->private_data.f_scratch[(v_p0 + 1u)] = ((uint8_t)((15u & (v_chunk_bits >> 8u))));
33173 self->private_data.f_scratch[(v_p0 + 2u)] = ((uint8_t)((15u & (v_chunk_bits >> 4u))));
33174 self->private_data.f_scratch[(v_p0 + 3u)] = ((uint8_t)((15u & (v_chunk_bits >> 0u))));
33175 v_p0 = ((v_p0 & 255u) + 4u);
33176 v_chunk_count -= 1u;
33178 v_p0 = wuffs_base__u32__min(v_p0, self->private_impl.f_rle_length);
33179 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));
33180 wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_dst_x, v_p0);
33181 wuffs_private_impl__u32__sat_sub_indirect(&self->private_impl.f_rle_length, v_p0);
33183 if (self->private_impl.f_rle_length > 0u) {
33184 break;
33186 if (self->private_impl.f_rle_padded) {
33187 if (((uint64_t)(io2_a_src - iop_a_src)) < 1u) {
33188 break;
33190 iop_a_src += 1u;
33191 self->private_impl.f_rle_padded = false;
33193 v_rle_state = 0u;
33194 goto label__middle__continue;
33195 } else if (v_rle_state == 4u) {
33196 if (((uint64_t)(io2_a_src - iop_a_src)) < 1u) {
33197 break;
33199 self->private_impl.f_rle_delta_x = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
33200 iop_a_src += 1u;
33201 v_rle_state = 5u;
33202 continue;
33204 if (((uint64_t)(io2_a_src - iop_a_src)) < 1u) {
33205 break;
33207 v_code = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
33208 iop_a_src += 1u;
33209 if (self->private_impl.f_rle_delta_x > 0u) {
33210 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)));
33211 wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(self->private_impl.f_rle_delta_x)));
33212 self->private_impl.f_rle_delta_x = 0u;
33213 if (self->private_impl.f_dst_x > self->private_impl.f_width) {
33214 status = wuffs_base__make_status(wuffs_bmp__error__bad_rle_compression);
33215 goto exit;
33218 if (v_code > 0u) {
33219 #if defined(__GNUC__)
33220 #pragma GCC diagnostic push
33221 #pragma GCC diagnostic ignored "-Wconversion"
33222 #endif
33223 v_code -= 1u;
33224 #if defined(__GNUC__)
33225 #pragma GCC diagnostic pop
33226 #endif
33227 while (true) {
33228 self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc;
33229 if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
33230 status = wuffs_base__make_status(wuffs_bmp__error__bad_rle_compression);
33231 goto exit;
33233 v_row = wuffs_private_impl__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
33234 if (v_dst_bytes_per_row < ((uint64_t)(v_row.len))) {
33235 v_row = wuffs_base__slice_u8__subslice_j(v_row, v_dst_bytes_per_row);
33237 if (v_code <= 0u) {
33238 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)));
33239 break;
33241 wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(&self->private_impl.f_swizzler, v_row, v_dst_palette, 18446744073709551615u);
33242 #if defined(__GNUC__)
33243 #pragma GCC diagnostic push
33244 #pragma GCC diagnostic ignored "-Wconversion"
33245 #endif
33246 v_code -= 1u;
33247 #if defined(__GNUC__)
33248 #pragma GCC diagnostic pop
33249 #endif
33252 v_rle_state = 0u;
33253 goto label__middle__continue;
33255 self->private_impl.f_rle_state = v_rle_state;
33256 status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
33257 goto ok;
33260 label__outer__break:;
33261 while (self->private_impl.f_dst_y < self->private_impl.f_height) {
33262 v_row = wuffs_private_impl__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
33263 if (v_dst_bytes_per_row < ((uint64_t)(v_row.len))) {
33264 v_row = wuffs_base__slice_u8__subslice_j(v_row, v_dst_bytes_per_row);
33266 wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(&self->private_impl.f_swizzler, v_row, v_dst_palette, 18446744073709551615u);
33267 self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc;
33269 status = wuffs_base__make_status(NULL);
33270 goto ok;
33273 goto exit;
33274 exit:
33275 if (a_src && a_src->data.ptr) {
33276 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33279 return status;
33282 // -------- func bmp.decoder.swizzle_bitfields
33284 WUFFS_BASE__GENERATED_C_CODE
33285 static wuffs_base__status
33286 wuffs_bmp__decoder__swizzle_bitfields(
33287 wuffs_bmp__decoder* self,
33288 wuffs_base__pixel_buffer* a_dst,
33289 wuffs_base__io_buffer* a_src) {
33290 wuffs_base__status status = wuffs_base__make_status(NULL);
33292 wuffs_base__pixel_format v_dst_pixfmt = {0};
33293 uint32_t v_dst_bits_per_pixel = 0;
33294 uint32_t v_dst_bytes_per_pixel = 0;
33295 uint64_t v_dst_bytes_per_row = 0;
33296 wuffs_base__slice_u8 v_dst_palette = {0};
33297 wuffs_base__table_u8 v_tab = {0};
33298 wuffs_base__slice_u8 v_dst = {0};
33299 uint64_t v_i = 0;
33300 uint64_t v_n = 0;
33301 uint32_t v_p0 = 0;
33302 uint32_t v_p1 = 0;
33303 uint32_t v_p1_temp = 0;
33304 uint32_t v_num_bits = 0;
33305 uint32_t v_c = 0;
33306 uint32_t v_c32 = 0;
33307 uint32_t v_channel = 0;
33309 const uint8_t* iop_a_src = NULL;
33310 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33311 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33312 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33313 if (a_src && a_src->data.ptr) {
33314 io0_a_src = a_src->data.ptr;
33315 io1_a_src = io0_a_src + a_src->meta.ri;
33316 iop_a_src = io1_a_src;
33317 io2_a_src = io0_a_src + a_src->meta.wi;
33320 v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
33321 v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
33322 if ((v_dst_bits_per_pixel & 7u) != 0u) {
33323 status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
33324 goto exit;
33326 v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u);
33327 v_dst_bytes_per_row = ((uint64_t)((self->private_impl.f_width * v_dst_bytes_per_pixel)));
33328 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));
33329 v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
33330 label__outer__continue:;
33331 while (true) {
33332 while (self->private_impl.f_pending_pad > 0u) {
33333 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
33334 status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
33335 goto ok;
33337 self->private_impl.f_pending_pad -= 1u;
33338 iop_a_src += 1u;
33340 while (true) {
33341 if (self->private_impl.f_dst_x == self->private_impl.f_width) {
33342 self->private_impl.f_dst_x = 0u;
33343 self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc;
33344 if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
33345 if (self->private_impl.f_height > 0u) {
33346 self->private_impl.f_pending_pad = self->private_impl.f_pad_per_row;
33348 goto label__outer__break;
33349 } else if (self->private_impl.f_pad_per_row != 0u) {
33350 self->private_impl.f_pending_pad = self->private_impl.f_pad_per_row;
33351 goto label__outer__continue;
33354 v_p1_temp = ((uint32_t)(self->private_impl.f_width - self->private_impl.f_dst_x));
33355 v_p1 = wuffs_base__u32__min(v_p1_temp, 256u);
33356 v_p0 = 0u;
33357 while (v_p0 < v_p1) {
33358 if (self->private_impl.f_bits_per_pixel == 16u) {
33359 if (((uint64_t)(io2_a_src - iop_a_src)) < 2u) {
33360 break;
33362 v_c32 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
33363 iop_a_src += 2u;
33364 } else {
33365 if (((uint64_t)(io2_a_src - iop_a_src)) < 4u) {
33366 break;
33368 v_c32 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
33369 iop_a_src += 4u;
33371 v_channel = 0u;
33372 while (v_channel < 4u) {
33373 if (self->private_impl.f_channel_num_bits[v_channel] == 0u) {
33374 self->private_data.f_scratch[((8u * v_p0) + (2u * v_channel) + 0u)] = 255u;
33375 self->private_data.f_scratch[((8u * v_p0) + (2u * v_channel) + 1u)] = 255u;
33376 } else {
33377 v_c = ((v_c32 & self->private_impl.f_channel_masks[v_channel]) >> self->private_impl.f_channel_shifts[v_channel]);
33378 v_num_bits = ((uint32_t)(self->private_impl.f_channel_num_bits[v_channel]));
33379 while (v_num_bits < 16u) {
33380 v_c |= ((uint32_t)(v_c << v_num_bits));
33381 v_num_bits *= 2u;
33383 v_c >>= (v_num_bits - 16u);
33384 self->private_data.f_scratch[((8u * v_p0) + (2u * v_channel) + 0u)] = ((uint8_t)((v_c >> 0u)));
33385 self->private_data.f_scratch[((8u * v_p0) + (2u * v_channel) + 1u)] = ((uint8_t)((v_c >> 8u)));
33387 v_channel += 1u;
33389 v_p0 += 1u;
33391 v_dst = wuffs_private_impl__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
33392 if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) {
33393 v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row);
33395 v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_dst_bytes_per_pixel)));
33396 if (v_i >= ((uint64_t)(v_dst.len))) {
33397 v_n = ((uint64_t)(v_p0));
33398 } else {
33399 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)));
33401 if (v_n == 0u) {
33402 status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
33403 goto ok;
33405 wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n)));
33408 label__outer__break:;
33409 status = wuffs_base__make_status(NULL);
33410 goto ok;
33413 goto exit;
33414 exit:
33415 if (a_src && a_src->data.ptr) {
33416 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33419 return status;
33422 // -------- func bmp.decoder.swizzle_low_bit_depth
33424 WUFFS_BASE__GENERATED_C_CODE
33425 static wuffs_base__status
33426 wuffs_bmp__decoder__swizzle_low_bit_depth(
33427 wuffs_bmp__decoder* self,
33428 wuffs_base__pixel_buffer* a_dst,
33429 wuffs_base__io_buffer* a_src) {
33430 wuffs_base__status status = wuffs_base__make_status(NULL);
33432 wuffs_base__pixel_format v_dst_pixfmt = {0};
33433 uint32_t v_dst_bits_per_pixel = 0;
33434 uint32_t v_dst_bytes_per_pixel = 0;
33435 uint64_t v_dst_bytes_per_row = 0;
33436 wuffs_base__slice_u8 v_dst_palette = {0};
33437 wuffs_base__table_u8 v_tab = {0};
33438 wuffs_base__slice_u8 v_dst = {0};
33439 uint64_t v_i = 0;
33440 uint64_t v_n = 0;
33441 uint32_t v_p0 = 0;
33442 uint32_t v_chunk_bits = 0;
33443 uint32_t v_chunk_count = 0;
33444 uint32_t v_pixels_per_chunk = 0;
33446 const uint8_t* iop_a_src = NULL;
33447 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33448 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33449 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33450 if (a_src && a_src->data.ptr) {
33451 io0_a_src = a_src->data.ptr;
33452 io1_a_src = io0_a_src + a_src->meta.ri;
33453 iop_a_src = io1_a_src;
33454 io2_a_src = io0_a_src + a_src->meta.wi;
33457 v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
33458 v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
33459 if ((v_dst_bits_per_pixel & 7u) != 0u) {
33460 status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
33461 goto exit;
33463 v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u);
33464 v_dst_bytes_per_row = ((uint64_t)((self->private_impl.f_width * v_dst_bytes_per_pixel)));
33465 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));
33466 v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
33467 while (true) {
33468 if (self->private_impl.f_dst_x == self->private_impl.f_width) {
33469 self->private_impl.f_dst_x = 0u;
33470 self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc;
33471 if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
33472 break;
33475 v_dst = wuffs_private_impl__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
33476 if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) {
33477 v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row);
33479 v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_dst_bytes_per_pixel)));
33480 if (v_i >= ((uint64_t)(v_dst.len))) {
33481 if (self->private_impl.f_bits_per_pixel == 1u) {
33482 v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 31u) / 32u);
33483 v_pixels_per_chunk = 32u;
33484 } else if (self->private_impl.f_bits_per_pixel == 2u) {
33485 v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 15u) / 16u);
33486 v_pixels_per_chunk = 16u;
33487 } else {
33488 v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 7u) / 8u);
33489 v_pixels_per_chunk = 8u;
33491 while ((v_chunk_count >= 64u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 256u)) {
33492 iop_a_src += 256u;
33493 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))));
33494 v_chunk_count -= 64u;
33496 while ((v_chunk_count >= 8u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 32u)) {
33497 iop_a_src += 32u;
33498 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))));
33499 v_chunk_count -= 8u;
33501 while (v_chunk_count > 0u) {
33502 if (((uint64_t)(io2_a_src - iop_a_src)) < 4u) {
33503 status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
33504 goto ok;
33506 iop_a_src += 4u;
33507 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))));
33508 v_chunk_count -= 1u;
33510 continue;
33512 v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_i);
33513 v_p0 = 0u;
33514 if (self->private_impl.f_bits_per_pixel == 1u) {
33515 v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 31u) / 32u);
33516 v_chunk_count = wuffs_base__u32__min(v_chunk_count, 16u);
33517 while ((v_chunk_count > 0u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 4u)) {
33518 v_chunk_bits = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
33519 iop_a_src += 4u;
33520 self->private_data.f_scratch[(v_p0 + 0u)] = ((uint8_t)((1u & (v_chunk_bits >> 31u))));
33521 self->private_data.f_scratch[(v_p0 + 1u)] = ((uint8_t)((1u & (v_chunk_bits >> 30u))));
33522 self->private_data.f_scratch[(v_p0 + 2u)] = ((uint8_t)((1u & (v_chunk_bits >> 29u))));
33523 self->private_data.f_scratch[(v_p0 + 3u)] = ((uint8_t)((1u & (v_chunk_bits >> 28u))));
33524 self->private_data.f_scratch[(v_p0 + 4u)] = ((uint8_t)((1u & (v_chunk_bits >> 27u))));
33525 self->private_data.f_scratch[(v_p0 + 5u)] = ((uint8_t)((1u & (v_chunk_bits >> 26u))));
33526 self->private_data.f_scratch[(v_p0 + 6u)] = ((uint8_t)((1u & (v_chunk_bits >> 25u))));
33527 self->private_data.f_scratch[(v_p0 + 7u)] = ((uint8_t)((1u & (v_chunk_bits >> 24u))));
33528 self->private_data.f_scratch[(v_p0 + 8u)] = ((uint8_t)((1u & (v_chunk_bits >> 23u))));
33529 self->private_data.f_scratch[(v_p0 + 9u)] = ((uint8_t)((1u & (v_chunk_bits >> 22u))));
33530 self->private_data.f_scratch[(v_p0 + 10u)] = ((uint8_t)((1u & (v_chunk_bits >> 21u))));
33531 self->private_data.f_scratch[(v_p0 + 11u)] = ((uint8_t)((1u & (v_chunk_bits >> 20u))));
33532 self->private_data.f_scratch[(v_p0 + 12u)] = ((uint8_t)((1u & (v_chunk_bits >> 19u))));
33533 self->private_data.f_scratch[(v_p0 + 13u)] = ((uint8_t)((1u & (v_chunk_bits >> 18u))));
33534 self->private_data.f_scratch[(v_p0 + 14u)] = ((uint8_t)((1u & (v_chunk_bits >> 17u))));
33535 self->private_data.f_scratch[(v_p0 + 15u)] = ((uint8_t)((1u & (v_chunk_bits >> 16u))));
33536 self->private_data.f_scratch[(v_p0 + 16u)] = ((uint8_t)((1u & (v_chunk_bits >> 15u))));
33537 self->private_data.f_scratch[(v_p0 + 17u)] = ((uint8_t)((1u & (v_chunk_bits >> 14u))));
33538 self->private_data.f_scratch[(v_p0 + 18u)] = ((uint8_t)((1u & (v_chunk_bits >> 13u))));
33539 self->private_data.f_scratch[(v_p0 + 19u)] = ((uint8_t)((1u & (v_chunk_bits >> 12u))));
33540 self->private_data.f_scratch[(v_p0 + 20u)] = ((uint8_t)((1u & (v_chunk_bits >> 11u))));
33541 self->private_data.f_scratch[(v_p0 + 21u)] = ((uint8_t)((1u & (v_chunk_bits >> 10u))));
33542 self->private_data.f_scratch[(v_p0 + 22u)] = ((uint8_t)((1u & (v_chunk_bits >> 9u))));
33543 self->private_data.f_scratch[(v_p0 + 23u)] = ((uint8_t)((1u & (v_chunk_bits >> 8u))));
33544 self->private_data.f_scratch[(v_p0 + 24u)] = ((uint8_t)((1u & (v_chunk_bits >> 7u))));
33545 self->private_data.f_scratch[(v_p0 + 25u)] = ((uint8_t)((1u & (v_chunk_bits >> 6u))));
33546 self->private_data.f_scratch[(v_p0 + 26u)] = ((uint8_t)((1u & (v_chunk_bits >> 5u))));
33547 self->private_data.f_scratch[(v_p0 + 27u)] = ((uint8_t)((1u & (v_chunk_bits >> 4u))));
33548 self->private_data.f_scratch[(v_p0 + 28u)] = ((uint8_t)((1u & (v_chunk_bits >> 3u))));
33549 self->private_data.f_scratch[(v_p0 + 29u)] = ((uint8_t)((1u & (v_chunk_bits >> 2u))));
33550 self->private_data.f_scratch[(v_p0 + 30u)] = ((uint8_t)((1u & (v_chunk_bits >> 1u))));
33551 self->private_data.f_scratch[(v_p0 + 31u)] = ((uint8_t)((1u & (v_chunk_bits >> 0u))));
33552 v_p0 = ((v_p0 & 511u) + 32u);
33553 v_chunk_count -= 1u;
33555 } else if (self->private_impl.f_bits_per_pixel == 2u) {
33556 v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 15u) / 16u);
33557 v_chunk_count = wuffs_base__u32__min(v_chunk_count, 32u);
33558 while ((v_chunk_count > 0u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 4u)) {
33559 v_chunk_bits = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
33560 iop_a_src += 4u;
33561 self->private_data.f_scratch[(v_p0 + 0u)] = ((uint8_t)((3u & (v_chunk_bits >> 30u))));
33562 self->private_data.f_scratch[(v_p0 + 1u)] = ((uint8_t)((3u & (v_chunk_bits >> 28u))));
33563 self->private_data.f_scratch[(v_p0 + 2u)] = ((uint8_t)((3u & (v_chunk_bits >> 26u))));
33564 self->private_data.f_scratch[(v_p0 + 3u)] = ((uint8_t)((3u & (v_chunk_bits >> 24u))));
33565 self->private_data.f_scratch[(v_p0 + 4u)] = ((uint8_t)((3u & (v_chunk_bits >> 22u))));
33566 self->private_data.f_scratch[(v_p0 + 5u)] = ((uint8_t)((3u & (v_chunk_bits >> 20u))));
33567 self->private_data.f_scratch[(v_p0 + 6u)] = ((uint8_t)((3u & (v_chunk_bits >> 18u))));
33568 self->private_data.f_scratch[(v_p0 + 7u)] = ((uint8_t)((3u & (v_chunk_bits >> 16u))));
33569 self->private_data.f_scratch[(v_p0 + 8u)] = ((uint8_t)((3u & (v_chunk_bits >> 14u))));
33570 self->private_data.f_scratch[(v_p0 + 9u)] = ((uint8_t)((3u & (v_chunk_bits >> 12u))));
33571 self->private_data.f_scratch[(v_p0 + 10u)] = ((uint8_t)((3u & (v_chunk_bits >> 10u))));
33572 self->private_data.f_scratch[(v_p0 + 11u)] = ((uint8_t)((3u & (v_chunk_bits >> 8u))));
33573 self->private_data.f_scratch[(v_p0 + 12u)] = ((uint8_t)((3u & (v_chunk_bits >> 6u))));
33574 self->private_data.f_scratch[(v_p0 + 13u)] = ((uint8_t)((3u & (v_chunk_bits >> 4u))));
33575 self->private_data.f_scratch[(v_p0 + 14u)] = ((uint8_t)((3u & (v_chunk_bits >> 2u))));
33576 self->private_data.f_scratch[(v_p0 + 15u)] = ((uint8_t)((3u & (v_chunk_bits >> 0u))));
33577 v_p0 = ((v_p0 & 511u) + 16u);
33578 v_chunk_count -= 1u;
33580 } else {
33581 v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 7u) / 8u);
33582 v_chunk_count = wuffs_base__u32__min(v_chunk_count, 64u);
33583 while ((v_chunk_count > 0u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 4u)) {
33584 v_chunk_bits = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
33585 iop_a_src += 4u;
33586 self->private_data.f_scratch[(v_p0 + 0u)] = ((uint8_t)((15u & (v_chunk_bits >> 28u))));
33587 self->private_data.f_scratch[(v_p0 + 1u)] = ((uint8_t)((15u & (v_chunk_bits >> 24u))));
33588 self->private_data.f_scratch[(v_p0 + 2u)] = ((uint8_t)((15u & (v_chunk_bits >> 20u))));
33589 self->private_data.f_scratch[(v_p0 + 3u)] = ((uint8_t)((15u & (v_chunk_bits >> 16u))));
33590 self->private_data.f_scratch[(v_p0 + 4u)] = ((uint8_t)((15u & (v_chunk_bits >> 12u))));
33591 self->private_data.f_scratch[(v_p0 + 5u)] = ((uint8_t)((15u & (v_chunk_bits >> 8u))));
33592 self->private_data.f_scratch[(v_p0 + 6u)] = ((uint8_t)((15u & (v_chunk_bits >> 4u))));
33593 self->private_data.f_scratch[(v_p0 + 7u)] = ((uint8_t)((15u & (v_chunk_bits >> 0u))));
33594 v_p0 = ((v_p0 & 511u) + 8u);
33595 v_chunk_count -= 1u;
33598 v_p0 = wuffs_base__u32__min(v_p0, wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x));
33599 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));
33600 if (v_n == 0u) {
33601 status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
33602 goto ok;
33604 wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n)));
33606 status = wuffs_base__make_status(NULL);
33607 goto ok;
33610 goto exit;
33611 exit:
33612 if (a_src && a_src->data.ptr) {
33613 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33616 return status;
33619 // -------- func bmp.decoder.frame_dirty_rect
33621 WUFFS_BASE__GENERATED_C_CODE
33622 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
33623 wuffs_bmp__decoder__frame_dirty_rect(
33624 const wuffs_bmp__decoder* self) {
33625 if (!self) {
33626 return wuffs_base__utility__empty_rect_ie_u32();
33628 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
33629 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
33630 return wuffs_base__utility__empty_rect_ie_u32();
33633 return wuffs_base__utility__make_rect_ie_u32(
33636 self->private_impl.f_width,
33637 self->private_impl.f_height);
33640 // -------- func bmp.decoder.num_animation_loops
33642 WUFFS_BASE__GENERATED_C_CODE
33643 WUFFS_BASE__MAYBE_STATIC uint32_t
33644 wuffs_bmp__decoder__num_animation_loops(
33645 const wuffs_bmp__decoder* self) {
33646 if (!self) {
33647 return 0;
33649 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
33650 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
33651 return 0;
33654 return 0u;
33657 // -------- func bmp.decoder.num_decoded_frame_configs
33659 WUFFS_BASE__GENERATED_C_CODE
33660 WUFFS_BASE__MAYBE_STATIC uint64_t
33661 wuffs_bmp__decoder__num_decoded_frame_configs(
33662 const wuffs_bmp__decoder* self) {
33663 if (!self) {
33664 return 0;
33666 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
33667 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
33668 return 0;
33671 if (self->private_impl.f_call_sequence > 32u) {
33672 return 1u;
33674 return 0u;
33677 // -------- func bmp.decoder.num_decoded_frames
33679 WUFFS_BASE__GENERATED_C_CODE
33680 WUFFS_BASE__MAYBE_STATIC uint64_t
33681 wuffs_bmp__decoder__num_decoded_frames(
33682 const wuffs_bmp__decoder* self) {
33683 if (!self) {
33684 return 0;
33686 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
33687 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
33688 return 0;
33691 if (self->private_impl.f_call_sequence > 64u) {
33692 return 1u;
33694 return 0u;
33697 // -------- func bmp.decoder.restart_frame
33699 WUFFS_BASE__GENERATED_C_CODE
33700 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
33701 wuffs_bmp__decoder__restart_frame(
33702 wuffs_bmp__decoder* self,
33703 uint64_t a_index,
33704 uint64_t a_io_position) {
33705 if (!self) {
33706 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
33708 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
33709 return wuffs_base__make_status(
33710 (self->private_impl.magic == WUFFS_BASE__DISABLED)
33711 ? wuffs_base__error__disabled_by_previous_error
33712 : wuffs_base__error__initialize_not_called);
33715 if (self->private_impl.f_call_sequence < 32u) {
33716 return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
33718 if (a_index != 0u) {
33719 return wuffs_base__make_status(wuffs_base__error__bad_argument);
33721 self->private_impl.f_call_sequence = 40u;
33722 self->private_impl.f_frame_config_io_position = a_io_position;
33723 return wuffs_base__make_status(NULL);
33726 // -------- func bmp.decoder.set_report_metadata
33728 WUFFS_BASE__GENERATED_C_CODE
33729 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
33730 wuffs_bmp__decoder__set_report_metadata(
33731 wuffs_bmp__decoder* self,
33732 uint32_t a_fourcc,
33733 bool a_report) {
33734 return wuffs_base__make_empty_struct();
33737 // -------- func bmp.decoder.tell_me_more
33739 WUFFS_BASE__GENERATED_C_CODE
33740 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
33741 wuffs_bmp__decoder__tell_me_more(
33742 wuffs_bmp__decoder* self,
33743 wuffs_base__io_buffer* a_dst,
33744 wuffs_base__more_information* a_minfo,
33745 wuffs_base__io_buffer* a_src) {
33746 if (!self) {
33747 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
33749 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
33750 return wuffs_base__make_status(
33751 (self->private_impl.magic == WUFFS_BASE__DISABLED)
33752 ? wuffs_base__error__disabled_by_previous_error
33753 : wuffs_base__error__initialize_not_called);
33755 if (!a_dst || !a_src) {
33756 self->private_impl.magic = WUFFS_BASE__DISABLED;
33757 return wuffs_base__make_status(wuffs_base__error__bad_argument);
33759 if ((self->private_impl.active_coroutine != 0) &&
33760 (self->private_impl.active_coroutine != 4)) {
33761 self->private_impl.magic = WUFFS_BASE__DISABLED;
33762 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
33764 self->private_impl.active_coroutine = 0;
33765 wuffs_base__status status = wuffs_base__make_status(NULL);
33767 wuffs_base__status v_status = wuffs_base__make_status(NULL);
33769 uint32_t coro_susp_point = self->private_impl.p_tell_me_more;
33770 switch (coro_susp_point) {
33771 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
33773 while (true) {
33775 wuffs_base__status t_0 = wuffs_bmp__decoder__do_tell_me_more(self, a_dst, a_minfo, a_src);
33776 v_status = t_0;
33778 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
33779 status = wuffs_base__make_status(wuffs_bmp__error__truncated_input);
33780 goto exit;
33782 status = v_status;
33783 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
33787 self->private_impl.p_tell_me_more = 0;
33788 goto exit;
33791 goto suspend;
33792 suspend:
33793 self->private_impl.p_tell_me_more = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
33794 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 4 : 0;
33796 goto exit;
33797 exit:
33798 if (wuffs_base__status__is_error(&status)) {
33799 self->private_impl.magic = WUFFS_BASE__DISABLED;
33801 return status;
33804 // -------- func bmp.decoder.do_tell_me_more
33806 WUFFS_BASE__GENERATED_C_CODE
33807 static wuffs_base__status
33808 wuffs_bmp__decoder__do_tell_me_more(
33809 wuffs_bmp__decoder* self,
33810 wuffs_base__io_buffer* a_dst,
33811 wuffs_base__more_information* a_minfo,
33812 wuffs_base__io_buffer* a_src) {
33813 wuffs_base__status status = wuffs_base__make_status(NULL);
33815 if (self->private_impl.f_io_redirect_fourcc <= 1u) {
33816 status = wuffs_base__make_status(wuffs_base__error__no_more_information);
33817 goto exit;
33819 if (a_minfo != NULL) {
33820 wuffs_base__more_information__set(a_minfo,
33822 self->private_impl.f_io_redirect_fourcc,
33824 self->private_impl.f_io_redirect_pos,
33825 18446744073709551615u);
33827 self->private_impl.f_io_redirect_fourcc = 1u;
33829 goto ok;
33831 goto exit;
33832 exit:
33833 return status;
33836 // -------- func bmp.decoder.workbuf_len
33838 WUFFS_BASE__GENERATED_C_CODE
33839 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
33840 wuffs_bmp__decoder__workbuf_len(
33841 const wuffs_bmp__decoder* self) {
33842 if (!self) {
33843 return wuffs_base__utility__empty_range_ii_u64();
33845 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
33846 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
33847 return wuffs_base__utility__empty_range_ii_u64();
33850 return wuffs_base__utility__make_range_ii_u64(0u, 0u);
33853 // -------- func bmp.decoder.read_palette
33855 WUFFS_BASE__GENERATED_C_CODE
33856 static wuffs_base__status
33857 wuffs_bmp__decoder__read_palette(
33858 wuffs_bmp__decoder* self,
33859 wuffs_base__io_buffer* a_src) {
33860 wuffs_base__status status = wuffs_base__make_status(NULL);
33862 uint32_t v_i = 0;
33863 uint32_t v_argb = 0;
33865 const uint8_t* iop_a_src = NULL;
33866 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33867 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33868 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33869 if (a_src && a_src->data.ptr) {
33870 io0_a_src = a_src->data.ptr;
33871 io1_a_src = io0_a_src + a_src->meta.ri;
33872 iop_a_src = io1_a_src;
33873 io2_a_src = io0_a_src + a_src->meta.wi;
33876 uint32_t coro_susp_point = self->private_impl.p_read_palette;
33877 if (coro_susp_point) {
33878 v_i = self->private_data.s_read_palette.v_i;
33880 switch (coro_susp_point) {
33881 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
33883 if (self->private_impl.f_bitmap_info_len == 12u) {
33884 while ((v_i < 256u) && (self->private_impl.f_padding >= 3u)) {
33885 self->private_impl.f_padding -= 3u;
33887 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
33888 uint32_t t_0;
33889 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) {
33890 t_0 = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src)));
33891 iop_a_src += 3;
33892 } else {
33893 self->private_data.s_read_palette.scratch = 0;
33894 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
33895 while (true) {
33896 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
33897 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33898 goto suspend;
33900 uint64_t* scratch = &self->private_data.s_read_palette.scratch;
33901 uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
33902 *scratch <<= 8;
33903 *scratch >>= 8;
33904 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
33905 if (num_bits_0 == 16) {
33906 t_0 = ((uint32_t)(*scratch));
33907 break;
33909 num_bits_0 += 8u;
33910 *scratch |= ((uint64_t)(num_bits_0)) << 56;
33913 v_argb = t_0;
33915 v_argb |= 4278190080u;
33916 self->private_data.f_src_palette[((4u * v_i) + 0u)] = ((uint8_t)((v_argb >> 0u)));
33917 self->private_data.f_src_palette[((4u * v_i) + 1u)] = ((uint8_t)((v_argb >> 8u)));
33918 self->private_data.f_src_palette[((4u * v_i) + 2u)] = ((uint8_t)((v_argb >> 16u)));
33919 self->private_data.f_src_palette[((4u * v_i) + 3u)] = ((uint8_t)((v_argb >> 24u)));
33920 v_i += 1u;
33922 } else {
33923 while ((v_i < 256u) && (self->private_impl.f_padding >= 4u)) {
33924 self->private_impl.f_padding -= 4u;
33926 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
33927 uint32_t t_1;
33928 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
33929 t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
33930 iop_a_src += 4;
33931 } else {
33932 self->private_data.s_read_palette.scratch = 0;
33933 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
33934 while (true) {
33935 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
33936 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33937 goto suspend;
33939 uint64_t* scratch = &self->private_data.s_read_palette.scratch;
33940 uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
33941 *scratch <<= 8;
33942 *scratch >>= 8;
33943 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
33944 if (num_bits_1 == 24) {
33945 t_1 = ((uint32_t)(*scratch));
33946 break;
33948 num_bits_1 += 8u;
33949 *scratch |= ((uint64_t)(num_bits_1)) << 56;
33952 v_argb = t_1;
33954 v_argb |= 4278190080u;
33955 self->private_data.f_src_palette[((4u * v_i) + 0u)] = ((uint8_t)((v_argb >> 0u)));
33956 self->private_data.f_src_palette[((4u * v_i) + 1u)] = ((uint8_t)((v_argb >> 8u)));
33957 self->private_data.f_src_palette[((4u * v_i) + 2u)] = ((uint8_t)((v_argb >> 16u)));
33958 self->private_data.f_src_palette[((4u * v_i) + 3u)] = ((uint8_t)((v_argb >> 24u)));
33959 v_i += 1u;
33962 while (v_i < 256u) {
33963 self->private_data.f_src_palette[((4u * v_i) + 0u)] = 0u;
33964 self->private_data.f_src_palette[((4u * v_i) + 1u)] = 0u;
33965 self->private_data.f_src_palette[((4u * v_i) + 2u)] = 0u;
33966 self->private_data.f_src_palette[((4u * v_i) + 3u)] = 255u;
33967 v_i += 1u;
33970 goto ok;
33972 self->private_impl.p_read_palette = 0;
33973 goto exit;
33976 goto suspend;
33977 suspend:
33978 self->private_impl.p_read_palette = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
33979 self->private_data.s_read_palette.v_i = v_i;
33981 goto exit;
33982 exit:
33983 if (a_src && a_src->data.ptr) {
33984 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33987 return status;
33990 // -------- func bmp.decoder.process_masks
33992 WUFFS_BASE__GENERATED_C_CODE
33993 static wuffs_base__status
33994 wuffs_bmp__decoder__process_masks(
33995 wuffs_bmp__decoder* self) {
33996 wuffs_base__status status = wuffs_base__make_status(NULL);
33998 uint32_t v_i = 0;
33999 uint32_t v_mask = 0;
34000 uint32_t v_n = 0;
34002 while (v_i < 4u) {
34003 v_mask = self->private_impl.f_channel_masks[v_i];
34004 if (v_mask != 0u) {
34005 v_n = 0u;
34006 while ((v_mask & 1u) == 0u) {
34007 v_n += 1u;
34008 v_mask >>= 1u;
34010 self->private_impl.f_channel_shifts[v_i] = ((uint8_t)((v_n & 31u)));
34011 v_n = 0u;
34012 while ((v_mask & 1u) == 1u) {
34013 v_n += 1u;
34014 v_mask >>= 1u;
34016 if ((v_mask != 0u) || (v_n > 32u)) {
34017 status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
34018 goto exit;
34020 self->private_impl.f_channel_num_bits[v_i] = ((uint8_t)(v_n));
34021 } else if (v_i != 3u) {
34022 status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
34023 goto exit;
34025 v_i += 1u;
34028 goto ok;
34030 goto exit;
34031 exit:
34032 return status;
34035 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BMP)
34037 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BZIP2)
34039 // ---------------- Status Codes Implementations
34041 const char wuffs_bzip2__error__bad_huffman_code_over_subscribed[] = "#bzip2: bad Huffman code (over-subscribed)";
34042 const char wuffs_bzip2__error__bad_huffman_code_under_subscribed[] = "#bzip2: bad Huffman code (under-subscribed)";
34043 const char wuffs_bzip2__error__bad_block_header[] = "#bzip2: bad block header";
34044 const char wuffs_bzip2__error__bad_block_length[] = "#bzip2: bad block length";
34045 const char wuffs_bzip2__error__bad_checksum[] = "#bzip2: bad checksum";
34046 const char wuffs_bzip2__error__bad_header[] = "#bzip2: bad header";
34047 const char wuffs_bzip2__error__bad_number_of_sections[] = "#bzip2: bad number of sections";
34048 const char wuffs_bzip2__error__truncated_input[] = "#bzip2: truncated input";
34049 const char wuffs_bzip2__error__unsupported_block_randomization[] = "#bzip2: unsupported block randomization";
34050 const char wuffs_bzip2__error__internal_error_inconsistent_huffman_decoder_state[] = "#bzip2: internal error: inconsistent Huffman decoder state";
34052 // ---------------- Private Consts
34054 static const uint8_t
34055 WUFFS_BZIP2__CLAMP_TO_5[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
34056 0u, 1u, 2u, 3u, 4u, 5u, 5u, 5u,
34059 static const uint32_t
34060 WUFFS_BZIP2__REV_CRC32_TABLE[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
34061 0u, 79764919u, 159529838u, 222504665u, 319059676u, 398814059u, 445009330u, 507990021u,
34062 638119352u, 583659535u, 797628118u, 726387553u, 890018660u, 835552979u, 1015980042u, 944750013u,
34063 1276238704u, 1221641927u, 1167319070u, 1095957929u, 1595256236u, 1540665371u, 1452775106u, 1381403509u,
34064 1780037320u, 1859660671u, 1671105958u, 1733955601u, 2031960084u, 2111593891u, 1889500026u, 1952343757u,
34065 2552477408u, 2632100695u, 2443283854u, 2506133561u, 2334638140u, 2414271883u, 2191915858u, 2254759653u,
34066 3190512472u, 3135915759u, 3081330742u, 3009969537u, 2905550212u, 2850959411u, 2762807018u, 2691435357u,
34067 3560074640u, 3505614887u, 3719321342u, 3648080713u, 3342211916u, 3287746299u, 3467911202u, 3396681109u,
34068 4063920168u, 4143685023u, 4223187782u, 4286162673u, 3779000052u, 3858754371u, 3904687514u, 3967668269u,
34069 881225847u, 809987520u, 1023691545u, 969234094u, 662832811u, 591600412u, 771767749u, 717299826u,
34070 311336399u, 374308984u, 453813921u, 533576470u, 25881363u, 88864420u, 134795389u, 214552010u,
34071 2023205639u, 2086057648u, 1897238633u, 1976864222u, 1804852699u, 1867694188u, 1645340341u, 1724971778u,
34072 1587496639u, 1516133128u, 1461550545u, 1406951526u, 1302016099u, 1230646740u, 1142491917u, 1087903418u,
34073 2896545431u, 2825181984u, 2770861561u, 2716262478u, 3215044683u, 3143675388u, 3055782693u, 3001194130u,
34074 2326604591u, 2389456536u, 2200899649u, 2280525302u, 2578013683u, 2640855108u, 2418763421u, 2498394922u,
34075 3769900519u, 3832873040u, 3912640137u, 3992402750u, 4088425275u, 4151408268u, 4197601365u, 4277358050u,
34076 3334271071u, 3263032808u, 3476998961u, 3422541446u, 3585640067u, 3514407732u, 3694837229u, 3640369242u,
34077 1762451694u, 1842216281u, 1619975040u, 1682949687u, 2047383090u, 2127137669u, 1938468188u, 2001449195u,
34078 1325665622u, 1271206113u, 1183200824u, 1111960463u, 1543535498u, 1489069629u, 1434599652u, 1363369299u,
34079 622672798u, 568075817u, 748617968u, 677256519u, 907627842u, 853037301u, 1067152940u, 995781531u,
34080 51762726u, 131386257u, 177728840u, 240578815u, 269590778u, 349224269u, 429104020u, 491947555u,
34081 4046411278u, 4126034873u, 4172115296u, 4234965207u, 3794477266u, 3874110821u, 3953728444u, 4016571915u,
34082 3609705398u, 3555108353u, 3735388376u, 3664026991u, 3290680682u, 3236090077u, 3449943556u, 3378572211u,
34083 3174993278u, 3120533705u, 3032266256u, 2961025959u, 2923101090u, 2868635157u, 2813903052u, 2742672763u,
34084 2604032198u, 2683796849u, 2461293480u, 2524268063u, 2284983834u, 2364738477u, 2175806836u, 2238787779u,
34085 1569362073u, 1498123566u, 1409854455u, 1355396672u, 1317987909u, 1246755826u, 1192025387u, 1137557660u,
34086 2072149281u, 2135122070u, 1912620623u, 1992383480u, 1753615357u, 1816598090u, 1627664531u, 1707420964u,
34087 295390185u, 358241886u, 404320391u, 483945776u, 43990325u, 106832002u, 186451547u, 266083308u,
34088 932423249u, 861060070u, 1041341759u, 986742920u, 613929101u, 542559546u, 756411363u, 701822548u,
34089 3316196985u, 3244833742u, 3425377559u, 3370778784u, 3601682597u, 3530312978u, 3744426955u, 3689838204u,
34090 3819031489u, 3881883254u, 3928223919u, 4007849240u, 4037393693u, 4100235434u, 4180117107u, 4259748804u,
34091 2310601993u, 2373574846u, 2151335527u, 2231098320u, 2596047829u, 2659030626u, 2470359227u, 2550115596u,
34092 2947551409u, 2876312838u, 2788305887u, 2733848168u, 3165939309u, 3094707162u, 3040238851u, 2985771188u,
34095 // ---------------- Private Initializer Prototypes
34097 // ---------------- Private Function Prototypes
34099 WUFFS_BASE__GENERATED_C_CODE
34100 static wuffs_base__status
34101 wuffs_bzip2__decoder__do_transform_io(
34102 wuffs_bzip2__decoder* self,
34103 wuffs_base__io_buffer* a_dst,
34104 wuffs_base__io_buffer* a_src,
34105 wuffs_base__slice_u8 a_workbuf);
34107 WUFFS_BASE__GENERATED_C_CODE
34108 static wuffs_base__status
34109 wuffs_bzip2__decoder__prepare_block(
34110 wuffs_bzip2__decoder* self,
34111 wuffs_base__io_buffer* a_src);
34113 WUFFS_BASE__GENERATED_C_CODE
34114 static wuffs_base__status
34115 wuffs_bzip2__decoder__read_code_lengths(
34116 wuffs_bzip2__decoder* self,
34117 wuffs_base__io_buffer* a_src);
34119 WUFFS_BASE__GENERATED_C_CODE
34120 static wuffs_base__status
34121 wuffs_bzip2__decoder__build_huffman_tree(
34122 wuffs_bzip2__decoder* self,
34123 uint32_t a_which);
34125 WUFFS_BASE__GENERATED_C_CODE
34126 static wuffs_base__empty_struct
34127 wuffs_bzip2__decoder__build_huffman_table(
34128 wuffs_bzip2__decoder* self,
34129 uint32_t a_which);
34131 WUFFS_BASE__GENERATED_C_CODE
34132 static wuffs_base__empty_struct
34133 wuffs_bzip2__decoder__invert_bwt(
34134 wuffs_bzip2__decoder* self);
34136 WUFFS_BASE__GENERATED_C_CODE
34137 static wuffs_base__empty_struct
34138 wuffs_bzip2__decoder__flush_fast(
34139 wuffs_bzip2__decoder* self,
34140 wuffs_base__io_buffer* a_dst);
34142 WUFFS_BASE__GENERATED_C_CODE
34143 static wuffs_base__status
34144 wuffs_bzip2__decoder__flush_slow(
34145 wuffs_bzip2__decoder* self,
34146 wuffs_base__io_buffer* a_dst);
34148 WUFFS_BASE__GENERATED_C_CODE
34149 static wuffs_base__status
34150 wuffs_bzip2__decoder__decode_huffman_fast(
34151 wuffs_bzip2__decoder* self,
34152 wuffs_base__io_buffer* a_src);
34154 WUFFS_BASE__GENERATED_C_CODE
34155 static wuffs_base__status
34156 wuffs_bzip2__decoder__decode_huffman_slow(
34157 wuffs_bzip2__decoder* self,
34158 wuffs_base__io_buffer* a_src);
34160 // ---------------- VTables
34162 const wuffs_base__io_transformer__func_ptrs
34163 wuffs_bzip2__decoder__func_ptrs_for__wuffs_base__io_transformer = {
34164 (wuffs_base__optional_u63(*)(const void*))(&wuffs_bzip2__decoder__dst_history_retain_length),
34165 (uint64_t(*)(const void*,
34166 uint32_t))(&wuffs_bzip2__decoder__get_quirk),
34167 (wuffs_base__status(*)(void*,
34168 uint32_t,
34169 uint64_t))(&wuffs_bzip2__decoder__set_quirk),
34170 (wuffs_base__status(*)(void*,
34171 wuffs_base__io_buffer*,
34172 wuffs_base__io_buffer*,
34173 wuffs_base__slice_u8))(&wuffs_bzip2__decoder__transform_io),
34174 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_bzip2__decoder__workbuf_len),
34177 // ---------------- Initializer Implementations
34179 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
34180 wuffs_bzip2__decoder__initialize(
34181 wuffs_bzip2__decoder* self,
34182 size_t sizeof_star_self,
34183 uint64_t wuffs_version,
34184 uint32_t options){
34185 if (!self) {
34186 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
34188 if (sizeof(*self) != sizeof_star_self) {
34189 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
34191 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
34192 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
34193 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
34196 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
34197 // The whole point of this if-check is to detect an uninitialized *self.
34198 // We disable the warning on GCC. Clang-5.0 does not have this warning.
34199 #if !defined(__clang__) && defined(__GNUC__)
34200 #pragma GCC diagnostic push
34201 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
34202 #endif
34203 if (self->private_impl.magic != 0) {
34204 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
34206 #if !defined(__clang__) && defined(__GNUC__)
34207 #pragma GCC diagnostic pop
34208 #endif
34209 } else {
34210 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
34211 memset(self, 0, sizeof(*self));
34212 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
34213 } else {
34214 memset(&(self->private_impl), 0, sizeof(self->private_impl));
34218 self->private_impl.magic = WUFFS_BASE__MAGIC;
34219 self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name =
34220 wuffs_base__io_transformer__vtable_name;
34221 self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers =
34222 (const void*)(&wuffs_bzip2__decoder__func_ptrs_for__wuffs_base__io_transformer);
34223 return wuffs_base__make_status(NULL);
34226 wuffs_bzip2__decoder*
34227 wuffs_bzip2__decoder__alloc(void) {
34228 wuffs_bzip2__decoder* x =
34229 (wuffs_bzip2__decoder*)(calloc(1, sizeof(wuffs_bzip2__decoder)));
34230 if (!x) {
34231 return NULL;
34233 if (wuffs_bzip2__decoder__initialize(
34234 x, sizeof(wuffs_bzip2__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
34235 free(x);
34236 return NULL;
34238 return x;
34241 size_t
34242 sizeof__wuffs_bzip2__decoder(void) {
34243 return sizeof(wuffs_bzip2__decoder);
34246 // ---------------- Function Implementations
34248 // -------- func bzip2.decoder.get_quirk
34250 WUFFS_BASE__GENERATED_C_CODE
34251 WUFFS_BASE__MAYBE_STATIC uint64_t
34252 wuffs_bzip2__decoder__get_quirk(
34253 const wuffs_bzip2__decoder* self,
34254 uint32_t a_key) {
34255 if (!self) {
34256 return 0;
34258 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
34259 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
34260 return 0;
34263 if ((a_key == 1u) && self->private_impl.f_ignore_checksum) {
34264 return 1u;
34266 return 0u;
34269 // -------- func bzip2.decoder.set_quirk
34271 WUFFS_BASE__GENERATED_C_CODE
34272 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
34273 wuffs_bzip2__decoder__set_quirk(
34274 wuffs_bzip2__decoder* self,
34275 uint32_t a_key,
34276 uint64_t a_value) {
34277 if (!self) {
34278 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
34280 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
34281 return wuffs_base__make_status(
34282 (self->private_impl.magic == WUFFS_BASE__DISABLED)
34283 ? wuffs_base__error__disabled_by_previous_error
34284 : wuffs_base__error__initialize_not_called);
34287 if (a_key == 1u) {
34288 self->private_impl.f_ignore_checksum = (a_value > 0u);
34289 return wuffs_base__make_status(NULL);
34291 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
34294 // -------- func bzip2.decoder.dst_history_retain_length
34296 WUFFS_BASE__GENERATED_C_CODE
34297 WUFFS_BASE__MAYBE_STATIC wuffs_base__optional_u63
34298 wuffs_bzip2__decoder__dst_history_retain_length(
34299 const wuffs_bzip2__decoder* self) {
34300 if (!self) {
34301 return wuffs_base__utility__make_optional_u63(false, 0u);
34303 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
34304 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
34305 return wuffs_base__utility__make_optional_u63(false, 0u);
34308 return wuffs_base__utility__make_optional_u63(true, 0u);
34311 // -------- func bzip2.decoder.workbuf_len
34313 WUFFS_BASE__GENERATED_C_CODE
34314 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
34315 wuffs_bzip2__decoder__workbuf_len(
34316 const wuffs_bzip2__decoder* self) {
34317 if (!self) {
34318 return wuffs_base__utility__empty_range_ii_u64();
34320 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
34321 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
34322 return wuffs_base__utility__empty_range_ii_u64();
34325 return wuffs_base__utility__make_range_ii_u64(0u, 0u);
34328 // -------- func bzip2.decoder.transform_io
34330 WUFFS_BASE__GENERATED_C_CODE
34331 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
34332 wuffs_bzip2__decoder__transform_io(
34333 wuffs_bzip2__decoder* self,
34334 wuffs_base__io_buffer* a_dst,
34335 wuffs_base__io_buffer* a_src,
34336 wuffs_base__slice_u8 a_workbuf) {
34337 if (!self) {
34338 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
34340 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
34341 return wuffs_base__make_status(
34342 (self->private_impl.magic == WUFFS_BASE__DISABLED)
34343 ? wuffs_base__error__disabled_by_previous_error
34344 : wuffs_base__error__initialize_not_called);
34346 if (!a_dst || !a_src) {
34347 self->private_impl.magic = WUFFS_BASE__DISABLED;
34348 return wuffs_base__make_status(wuffs_base__error__bad_argument);
34350 if ((self->private_impl.active_coroutine != 0) &&
34351 (self->private_impl.active_coroutine != 1)) {
34352 self->private_impl.magic = WUFFS_BASE__DISABLED;
34353 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
34355 self->private_impl.active_coroutine = 0;
34356 wuffs_base__status status = wuffs_base__make_status(NULL);
34358 wuffs_base__status v_status = wuffs_base__make_status(NULL);
34360 uint32_t coro_susp_point = self->private_impl.p_transform_io;
34361 switch (coro_susp_point) {
34362 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
34364 while (true) {
34366 wuffs_base__status t_0 = wuffs_bzip2__decoder__do_transform_io(self, a_dst, a_src, a_workbuf);
34367 v_status = t_0;
34369 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
34370 status = wuffs_base__make_status(wuffs_bzip2__error__truncated_input);
34371 goto exit;
34373 status = v_status;
34374 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
34378 self->private_impl.p_transform_io = 0;
34379 goto exit;
34382 goto suspend;
34383 suspend:
34384 self->private_impl.p_transform_io = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
34385 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
34387 goto exit;
34388 exit:
34389 if (wuffs_base__status__is_error(&status)) {
34390 self->private_impl.magic = WUFFS_BASE__DISABLED;
34392 return status;
34395 // -------- func bzip2.decoder.do_transform_io
34397 WUFFS_BASE__GENERATED_C_CODE
34398 static wuffs_base__status
34399 wuffs_bzip2__decoder__do_transform_io(
34400 wuffs_bzip2__decoder* self,
34401 wuffs_base__io_buffer* a_dst,
34402 wuffs_base__io_buffer* a_src,
34403 wuffs_base__slice_u8 a_workbuf) {
34404 wuffs_base__status status = wuffs_base__make_status(NULL);
34406 uint8_t v_c8 = 0;
34407 uint32_t v_i = 0;
34408 uint64_t v_tag = 0;
34409 wuffs_base__status v_status = wuffs_base__make_status(NULL);
34410 uint32_t v_final_checksum_want = 0;
34412 const uint8_t* iop_a_src = NULL;
34413 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34414 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34415 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34416 if (a_src && a_src->data.ptr) {
34417 io0_a_src = a_src->data.ptr;
34418 io1_a_src = io0_a_src + a_src->meta.ri;
34419 iop_a_src = io1_a_src;
34420 io2_a_src = io0_a_src + a_src->meta.wi;
34423 uint32_t coro_susp_point = self->private_impl.p_do_transform_io;
34424 if (coro_susp_point) {
34425 v_i = self->private_data.s_do_transform_io.v_i;
34426 v_tag = self->private_data.s_do_transform_io.v_tag;
34427 v_final_checksum_want = self->private_data.s_do_transform_io.v_final_checksum_want;
34429 switch (coro_susp_point) {
34430 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
34433 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
34434 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
34435 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34436 goto suspend;
34438 uint8_t t_0 = *iop_a_src++;
34439 v_c8 = t_0;
34441 if (v_c8 != 66u) {
34442 status = wuffs_base__make_status(wuffs_bzip2__error__bad_header);
34443 goto exit;
34446 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
34447 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
34448 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34449 goto suspend;
34451 uint8_t t_1 = *iop_a_src++;
34452 v_c8 = t_1;
34454 if (v_c8 != 90u) {
34455 status = wuffs_base__make_status(wuffs_bzip2__error__bad_header);
34456 goto exit;
34459 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
34460 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
34461 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34462 goto suspend;
34464 uint8_t t_2 = *iop_a_src++;
34465 v_c8 = t_2;
34467 if (v_c8 != 104u) {
34468 status = wuffs_base__make_status(wuffs_bzip2__error__bad_header);
34469 goto exit;
34472 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
34473 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
34474 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34475 goto suspend;
34477 uint8_t t_3 = *iop_a_src++;
34478 v_c8 = t_3;
34480 if ((v_c8 < 49u) || (57u < v_c8)) {
34481 status = wuffs_base__make_status(wuffs_bzip2__error__bad_header);
34482 goto exit;
34484 self->private_impl.f_max_incl_block_size = (((uint32_t)(((uint8_t)(v_c8 - 48u)))) * 100000u);
34485 while (true) {
34486 v_tag = 0u;
34487 v_i = 0u;
34488 while (v_i < 48u) {
34489 if (self->private_impl.f_n_bits <= 0u) {
34491 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
34492 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
34493 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34494 goto suspend;
34496 uint8_t t_4 = *iop_a_src++;
34497 v_c8 = t_4;
34499 self->private_impl.f_bits = (((uint32_t)(v_c8)) << 24u);
34500 self->private_impl.f_n_bits = 8u;
34502 v_tag <<= 1u;
34503 v_tag |= ((uint64_t)((self->private_impl.f_bits >> 31u)));
34504 self->private_impl.f_bits <<= 1u;
34505 self->private_impl.f_n_bits -= 1u;
34506 v_i += 1u;
34508 if (v_tag == 25779555029136u) {
34509 break;
34510 } else if (v_tag != 54156738319193u) {
34511 status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_header);
34512 goto exit;
34514 if (a_src) {
34515 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
34517 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
34518 status = wuffs_bzip2__decoder__prepare_block(self, a_src);
34519 if (a_src) {
34520 iop_a_src = a_src->data.ptr + a_src->meta.ri;
34522 if (status.repr) {
34523 goto suspend;
34525 self->private_impl.f_block_size = 0u;
34526 self->private_impl.f_decode_huffman_finished = false;
34527 self->private_impl.f_decode_huffman_which = WUFFS_BZIP2__CLAMP_TO_5[((uint8_t)(self->private_data.f_huffman_selectors[0u] & 7u))];
34528 self->private_impl.f_decode_huffman_ticks = 50u;
34529 self->private_impl.f_decode_huffman_section = 0u;
34530 self->private_impl.f_decode_huffman_run_shift = 0u;
34531 while ( ! self->private_impl.f_decode_huffman_finished) {
34532 if (a_src) {
34533 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
34535 v_status = wuffs_bzip2__decoder__decode_huffman_fast(self, a_src);
34536 if (a_src) {
34537 iop_a_src = a_src->data.ptr + a_src->meta.ri;
34539 if (wuffs_base__status__is_error(&v_status)) {
34540 status = v_status;
34541 goto exit;
34542 } else if (self->private_impl.f_decode_huffman_finished) {
34543 break;
34545 if (a_src) {
34546 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
34548 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
34549 status = wuffs_bzip2__decoder__decode_huffman_slow(self, a_src);
34550 if (a_src) {
34551 iop_a_src = a_src->data.ptr + a_src->meta.ri;
34553 if (status.repr) {
34554 goto suspend;
34557 wuffs_bzip2__decoder__invert_bwt(self);
34558 self->private_impl.f_block_checksum_have = 4294967295u;
34559 if (self->private_impl.f_original_pointer >= self->private_impl.f_block_size) {
34560 status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_length);
34561 goto exit;
34563 self->private_impl.f_flush_pointer = (self->private_data.f_bwt[self->private_impl.f_original_pointer] >> 12u);
34564 self->private_impl.f_flush_repeat_count = 0u;
34565 self->private_impl.f_flush_prev = 0u;
34566 while (self->private_impl.f_block_size > 0u) {
34567 wuffs_bzip2__decoder__flush_fast(self, a_dst);
34568 if (self->private_impl.f_block_size <= 0u) {
34569 break;
34571 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
34572 status = wuffs_bzip2__decoder__flush_slow(self, a_dst);
34573 if (status.repr) {
34574 goto suspend;
34577 self->private_impl.f_block_checksum_have ^= 4294967295u;
34578 if ( ! self->private_impl.f_ignore_checksum && (self->private_impl.f_block_checksum_have != self->private_impl.f_block_checksum_want)) {
34579 status = wuffs_base__make_status(wuffs_bzip2__error__bad_checksum);
34580 goto exit;
34582 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))));
34584 v_final_checksum_want = 0u;
34585 v_i = 0u;
34586 while (v_i < 32u) {
34587 if (self->private_impl.f_n_bits <= 0u) {
34589 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
34590 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
34591 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34592 goto suspend;
34594 uint8_t t_5 = *iop_a_src++;
34595 v_c8 = t_5;
34597 self->private_impl.f_bits = (((uint32_t)(v_c8)) << 24u);
34598 self->private_impl.f_n_bits = 8u;
34600 v_final_checksum_want <<= 1u;
34601 v_final_checksum_want |= (self->private_impl.f_bits >> 31u);
34602 self->private_impl.f_bits <<= 1u;
34603 self->private_impl.f_n_bits -= 1u;
34604 v_i += 1u;
34606 if ( ! self->private_impl.f_ignore_checksum && (self->private_impl.f_final_checksum_have != v_final_checksum_want)) {
34607 status = wuffs_base__make_status(wuffs_bzip2__error__bad_checksum);
34608 goto exit;
34611 goto ok;
34613 self->private_impl.p_do_transform_io = 0;
34614 goto exit;
34617 goto suspend;
34618 suspend:
34619 self->private_impl.p_do_transform_io = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
34620 self->private_data.s_do_transform_io.v_i = v_i;
34621 self->private_data.s_do_transform_io.v_tag = v_tag;
34622 self->private_data.s_do_transform_io.v_final_checksum_want = v_final_checksum_want;
34624 goto exit;
34625 exit:
34626 if (a_src && a_src->data.ptr) {
34627 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
34630 return status;
34633 // -------- func bzip2.decoder.prepare_block
34635 WUFFS_BASE__GENERATED_C_CODE
34636 static wuffs_base__status
34637 wuffs_bzip2__decoder__prepare_block(
34638 wuffs_bzip2__decoder* self,
34639 wuffs_base__io_buffer* a_src) {
34640 wuffs_base__status status = wuffs_base__make_status(NULL);
34642 uint8_t v_c8 = 0;
34643 uint32_t v_i = 0;
34644 uint32_t v_j = 0;
34645 uint32_t v_selector = 0;
34646 uint32_t v_sel_ff = 0;
34647 uint8_t v_movee = 0;
34648 wuffs_base__status v_status = wuffs_base__make_status(NULL);
34650 const uint8_t* iop_a_src = NULL;
34651 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34652 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34653 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34654 if (a_src && a_src->data.ptr) {
34655 io0_a_src = a_src->data.ptr;
34656 io1_a_src = io0_a_src + a_src->meta.ri;
34657 iop_a_src = io1_a_src;
34658 io2_a_src = io0_a_src + a_src->meta.wi;
34661 uint32_t coro_susp_point = self->private_impl.p_prepare_block;
34662 if (coro_susp_point) {
34663 v_i = self->private_data.s_prepare_block.v_i;
34664 v_selector = self->private_data.s_prepare_block.v_selector;
34666 switch (coro_susp_point) {
34667 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
34669 self->private_impl.f_block_checksum_want = 0u;
34670 v_i = 0u;
34671 while (v_i < 32u) {
34672 if (self->private_impl.f_n_bits <= 0u) {
34674 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
34675 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
34676 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34677 goto suspend;
34679 uint8_t t_0 = *iop_a_src++;
34680 v_c8 = t_0;
34682 self->private_impl.f_bits = (((uint32_t)(v_c8)) << 24u);
34683 self->private_impl.f_n_bits = 8u;
34685 self->private_impl.f_block_checksum_want <<= 1u;
34686 self->private_impl.f_block_checksum_want |= (self->private_impl.f_bits >> 31u);
34687 self->private_impl.f_bits <<= 1u;
34688 self->private_impl.f_n_bits -= 1u;
34689 v_i += 1u;
34691 if (self->private_impl.f_n_bits <= 0u) {
34693 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
34694 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
34695 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34696 goto suspend;
34698 uint8_t t_1 = *iop_a_src++;
34699 v_c8 = t_1;
34701 self->private_impl.f_bits = (((uint32_t)(v_c8)) << 24u);
34702 self->private_impl.f_n_bits = 8u;
34704 if ((self->private_impl.f_bits >> 31u) != 0u) {
34705 status = wuffs_base__make_status(wuffs_bzip2__error__unsupported_block_randomization);
34706 goto exit;
34708 self->private_impl.f_bits <<= 1u;
34709 self->private_impl.f_n_bits -= 1u;
34710 self->private_impl.f_original_pointer = 0u;
34711 v_i = 0u;
34712 while (v_i < 24u) {
34713 if (self->private_impl.f_n_bits <= 0u) {
34715 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
34716 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
34717 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34718 goto suspend;
34720 uint8_t t_2 = *iop_a_src++;
34721 v_c8 = t_2;
34723 self->private_impl.f_bits = (((uint32_t)(v_c8)) << 24u);
34724 self->private_impl.f_n_bits = 8u;
34726 self->private_impl.f_original_pointer <<= 1u;
34727 self->private_impl.f_original_pointer |= (self->private_impl.f_bits >> 31u);
34728 self->private_impl.f_bits <<= 1u;
34729 self->private_impl.f_n_bits -= 1u;
34730 v_i += 1u;
34732 v_i = 0u;
34733 while (v_i < 256u) {
34734 self->private_data.f_presence[v_i] = 0u;
34735 v_i += 1u;
34737 v_i = 0u;
34738 while (v_i < 256u) {
34739 if (self->private_impl.f_n_bits <= 0u) {
34741 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
34742 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
34743 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34744 goto suspend;
34746 uint8_t t_3 = *iop_a_src++;
34747 v_c8 = t_3;
34749 self->private_impl.f_bits = (((uint32_t)(v_c8)) << 24u);
34750 self->private_impl.f_n_bits = 8u;
34752 if ((self->private_impl.f_bits >> 31u) != 0u) {
34753 self->private_data.f_presence[v_i] = 1u;
34755 self->private_impl.f_bits <<= 1u;
34756 self->private_impl.f_n_bits -= 1u;
34757 v_i += 16u;
34759 self->private_data.f_scratch = 0u;
34760 v_i = 0u;
34761 while (v_i < 256u) {
34762 if (self->private_data.f_presence[v_i] == 0u) {
34763 v_i += 16u;
34764 continue;
34766 while (true) {
34767 if (self->private_impl.f_n_bits <= 0u) {
34769 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
34770 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
34771 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34772 goto suspend;
34774 uint8_t t_4 = *iop_a_src++;
34775 v_c8 = t_4;
34777 self->private_impl.f_bits = (((uint32_t)(v_c8)) << 24u);
34778 self->private_impl.f_n_bits = 8u;
34780 self->private_data.f_scratch += (self->private_impl.f_bits >> 31u);
34781 self->private_data.f_presence[(v_i & 255u)] = ((uint8_t)((self->private_impl.f_bits >> 31u)));
34782 self->private_impl.f_bits <<= 1u;
34783 self->private_impl.f_n_bits -= 1u;
34784 v_i += 1u;
34785 if ((v_i & 15u) == 0u) {
34786 break;
34790 if ((self->private_data.f_scratch < 1u) || (256u < self->private_data.f_scratch)) {
34791 status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_header);
34792 goto exit;
34794 self->private_impl.f_num_symbols = (self->private_data.f_scratch + 2u);
34795 self->private_data.f_scratch = 0u;
34796 v_i = 0u;
34797 while (v_i < 3u) {
34798 if (self->private_impl.f_n_bits <= 0u) {
34800 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
34801 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
34802 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34803 goto suspend;
34805 uint8_t t_5 = *iop_a_src++;
34806 v_c8 = t_5;
34808 self->private_impl.f_bits = (((uint32_t)(v_c8)) << 24u);
34809 self->private_impl.f_n_bits = 8u;
34811 self->private_data.f_scratch <<= 1u;
34812 self->private_data.f_scratch |= (self->private_impl.f_bits >> 31u);
34813 self->private_impl.f_bits <<= 1u;
34814 self->private_impl.f_n_bits -= 1u;
34815 v_i += 1u;
34817 if ((self->private_data.f_scratch < 2u) || (6u < self->private_data.f_scratch)) {
34818 status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_header);
34819 goto exit;
34821 self->private_impl.f_num_huffman_codes = self->private_data.f_scratch;
34822 self->private_data.f_scratch = 0u;
34823 v_i = 0u;
34824 while (v_i < 15u) {
34825 if (self->private_impl.f_n_bits <= 0u) {
34827 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
34828 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
34829 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34830 goto suspend;
34832 uint8_t t_6 = *iop_a_src++;
34833 v_c8 = t_6;
34835 self->private_impl.f_bits = (((uint32_t)(v_c8)) << 24u);
34836 self->private_impl.f_n_bits = 8u;
34838 self->private_data.f_scratch <<= 1u;
34839 self->private_data.f_scratch |= (self->private_impl.f_bits >> 31u);
34840 self->private_impl.f_bits <<= 1u;
34841 self->private_impl.f_n_bits -= 1u;
34842 v_i += 1u;
34844 if ((self->private_data.f_scratch < 1u) || (18001u < self->private_data.f_scratch)) {
34845 status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_header);
34846 goto exit;
34848 self->private_impl.f_num_sections = self->private_data.f_scratch;
34849 v_i = 0u;
34850 while (v_i < self->private_impl.f_num_huffman_codes) {
34851 self->private_data.f_mtft[v_i] = ((uint8_t)(v_i));
34852 v_i += 1u;
34854 v_i = 0u;
34855 while (v_i < self->private_impl.f_num_sections) {
34856 v_selector = 0u;
34857 while (true) {
34858 if (self->private_impl.f_n_bits <= 0u) {
34860 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
34861 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
34862 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34863 goto suspend;
34865 uint8_t t_7 = *iop_a_src++;
34866 v_c8 = t_7;
34868 self->private_impl.f_bits = (((uint32_t)(v_c8)) << 24u);
34869 self->private_impl.f_n_bits = 8u;
34871 if ((self->private_impl.f_bits >> 31u) == 0u) {
34872 self->private_impl.f_bits <<= 1u;
34873 self->private_impl.f_n_bits -= 1u;
34874 break;
34876 self->private_impl.f_bits <<= 1u;
34877 self->private_impl.f_n_bits -= 1u;
34878 v_selector += 1u;
34879 if (v_selector >= self->private_impl.f_num_huffman_codes) {
34880 status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_header);
34881 goto exit;
34884 if (v_selector == 0u) {
34885 self->private_data.f_huffman_selectors[v_i] = self->private_data.f_mtft[0u];
34886 } else {
34887 v_sel_ff = (v_selector & 255u);
34888 v_movee = self->private_data.f_mtft[v_sel_ff];
34889 wuffs_private_impl__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));
34890 self->private_data.f_mtft[0u] = v_movee;
34891 self->private_data.f_huffman_selectors[v_i] = v_movee;
34893 v_i += 1u;
34895 v_i = 0u;
34896 while (v_i < self->private_impl.f_num_huffman_codes) {
34897 if (a_src) {
34898 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
34900 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
34901 status = wuffs_bzip2__decoder__read_code_lengths(self, a_src);
34902 if (a_src) {
34903 iop_a_src = a_src->data.ptr + a_src->meta.ri;
34905 if (status.repr) {
34906 goto suspend;
34908 v_status = wuffs_bzip2__decoder__build_huffman_tree(self, v_i);
34909 if (wuffs_base__status__is_error(&v_status)) {
34910 status = v_status;
34911 goto exit;
34913 wuffs_bzip2__decoder__build_huffman_table(self, v_i);
34914 v_i += 1u;
34916 v_i = 0u;
34917 v_j = 0u;
34918 while (v_i < 256u) {
34919 if (self->private_data.f_presence[v_i] != 0u) {
34920 self->private_data.f_mtft[(v_j & 255u)] = ((uint8_t)(v_i));
34921 v_j += 1u;
34923 v_i += 1u;
34925 v_i = 0u;
34926 while (v_i < 256u) {
34927 self->private_data.f_letter_counts[v_i] = 0u;
34928 v_i += 1u;
34931 goto ok;
34933 self->private_impl.p_prepare_block = 0;
34934 goto exit;
34937 goto suspend;
34938 suspend:
34939 self->private_impl.p_prepare_block = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
34940 self->private_data.s_prepare_block.v_i = v_i;
34941 self->private_data.s_prepare_block.v_selector = v_selector;
34943 goto exit;
34944 exit:
34945 if (a_src && a_src->data.ptr) {
34946 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
34949 return status;
34952 // -------- func bzip2.decoder.read_code_lengths
34954 WUFFS_BASE__GENERATED_C_CODE
34955 static wuffs_base__status
34956 wuffs_bzip2__decoder__read_code_lengths(
34957 wuffs_bzip2__decoder* self,
34958 wuffs_base__io_buffer* a_src) {
34959 wuffs_base__status status = wuffs_base__make_status(NULL);
34961 uint8_t v_c8 = 0;
34962 uint32_t v_i = 0;
34963 uint32_t v_code_length = 0;
34965 const uint8_t* iop_a_src = NULL;
34966 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34967 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34968 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34969 if (a_src && a_src->data.ptr) {
34970 io0_a_src = a_src->data.ptr;
34971 io1_a_src = io0_a_src + a_src->meta.ri;
34972 iop_a_src = io1_a_src;
34973 io2_a_src = io0_a_src + a_src->meta.wi;
34976 uint32_t coro_susp_point = self->private_impl.p_read_code_lengths;
34977 if (coro_susp_point) {
34978 v_i = self->private_data.s_read_code_lengths.v_i;
34979 v_code_length = self->private_data.s_read_code_lengths.v_code_length;
34981 switch (coro_susp_point) {
34982 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
34984 self->private_impl.f_code_lengths_bitmask = 0u;
34985 v_i = 0u;
34986 while (v_i < 5u) {
34987 if (self->private_impl.f_n_bits <= 0u) {
34989 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
34990 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
34991 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34992 goto suspend;
34994 uint8_t t_0 = *iop_a_src++;
34995 v_c8 = t_0;
34997 self->private_impl.f_bits = (((uint32_t)(v_c8)) << 24u);
34998 self->private_impl.f_n_bits = 8u;
35000 v_code_length <<= 1u;
35001 v_code_length |= (self->private_impl.f_bits >> 31u);
35002 self->private_impl.f_bits <<= 1u;
35003 self->private_impl.f_n_bits -= 1u;
35004 v_i += 1u;
35006 v_i = 0u;
35007 while (v_i < self->private_impl.f_num_symbols) {
35008 while (true) {
35009 if ((v_code_length < 1u) || (20u < v_code_length)) {
35010 status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_header);
35011 goto exit;
35013 if (self->private_impl.f_n_bits <= 0u) {
35015 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
35016 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
35017 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
35018 goto suspend;
35020 uint8_t t_1 = *iop_a_src++;
35021 v_c8 = t_1;
35023 self->private_impl.f_bits = (((uint32_t)(v_c8)) << 24u);
35024 self->private_impl.f_n_bits = 8u;
35026 if ((self->private_impl.f_bits >> 31u) == 0u) {
35027 self->private_impl.f_bits <<= 1u;
35028 self->private_impl.f_n_bits -= 1u;
35029 break;
35031 self->private_impl.f_bits <<= 1u;
35032 self->private_impl.f_n_bits -= 1u;
35033 if (self->private_impl.f_n_bits <= 0u) {
35035 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
35036 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
35037 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
35038 goto suspend;
35040 uint8_t t_2 = *iop_a_src++;
35041 v_c8 = t_2;
35043 self->private_impl.f_bits = (((uint32_t)(v_c8)) << 24u);
35044 self->private_impl.f_n_bits = 8u;
35046 if ((self->private_impl.f_bits >> 31u) == 0u) {
35047 v_code_length += 1u;
35048 } else {
35049 v_code_length -= 1u;
35051 self->private_impl.f_bits <<= 1u;
35052 self->private_impl.f_n_bits -= 1u;
35054 self->private_impl.f_code_lengths_bitmask |= (((uint32_t)(1u)) << (v_code_length & 31u));
35055 self->private_data.f_bwt[v_i] = v_code_length;
35056 v_i += 1u;
35059 goto ok;
35061 self->private_impl.p_read_code_lengths = 0;
35062 goto exit;
35065 goto suspend;
35066 suspend:
35067 self->private_impl.p_read_code_lengths = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
35068 self->private_data.s_read_code_lengths.v_i = v_i;
35069 self->private_data.s_read_code_lengths.v_code_length = v_code_length;
35071 goto exit;
35072 exit:
35073 if (a_src && a_src->data.ptr) {
35074 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
35077 return status;
35080 // -------- func bzip2.decoder.build_huffman_tree
35082 WUFFS_BASE__GENERATED_C_CODE
35083 static wuffs_base__status
35084 wuffs_bzip2__decoder__build_huffman_tree(
35085 wuffs_bzip2__decoder* self,
35086 uint32_t a_which) {
35087 uint32_t v_code_length = 0;
35088 uint32_t v_symbol_index = 0;
35089 uint32_t v_num_branch_nodes = 0;
35090 uint32_t v_stack_height = 0;
35091 uint32_t v_stack_values[21] = {0};
35092 uint32_t v_node_index = 0;
35093 uint16_t v_leaf_value = 0;
35095 self->private_data.f_huffman_trees[a_which][0u][0u] = 0u;
35096 self->private_data.f_huffman_trees[a_which][0u][1u] = 0u;
35097 v_num_branch_nodes = 1u;
35098 v_stack_height = 1u;
35099 v_stack_values[0u] = 0u;
35100 v_code_length = 1u;
35101 while (v_code_length <= 20u) {
35102 if ((self->private_impl.f_code_lengths_bitmask & (((uint32_t)(1u)) << v_code_length)) == 0u) {
35103 v_code_length += 1u;
35104 continue;
35106 v_symbol_index = 0u;
35107 while (v_symbol_index < self->private_impl.f_num_symbols) {
35108 if (self->private_data.f_bwt[v_symbol_index] != v_code_length) {
35109 v_symbol_index += 1u;
35110 continue;
35112 while (true) {
35113 if (v_stack_height <= 0u) {
35114 return wuffs_base__make_status(wuffs_bzip2__error__bad_huffman_code_over_subscribed);
35115 } else if (v_stack_height >= v_code_length) {
35116 break;
35118 v_node_index = v_stack_values[(v_stack_height - 1u)];
35119 if (self->private_data.f_huffman_trees[a_which][v_node_index][0u] == 0u) {
35120 self->private_data.f_huffman_trees[a_which][v_node_index][0u] = ((uint16_t)(v_num_branch_nodes));
35121 } else {
35122 self->private_data.f_huffman_trees[a_which][v_node_index][1u] = ((uint16_t)(v_num_branch_nodes));
35124 if (v_num_branch_nodes >= 257u) {
35125 return wuffs_base__make_status(wuffs_bzip2__error__bad_huffman_code_under_subscribed);
35127 v_stack_values[v_stack_height] = v_num_branch_nodes;
35128 self->private_data.f_huffman_trees[a_which][v_num_branch_nodes][0u] = 0u;
35129 self->private_data.f_huffman_trees[a_which][v_num_branch_nodes][1u] = 0u;
35130 v_num_branch_nodes += 1u;
35131 v_stack_height += 1u;
35133 v_node_index = v_stack_values[(v_stack_height - 1u)];
35134 if (v_symbol_index < 2u) {
35135 v_leaf_value = ((uint16_t)((769u + v_symbol_index)));
35136 } else if ((v_symbol_index + 1u) < self->private_impl.f_num_symbols) {
35137 v_leaf_value = ((uint16_t)((511u + v_symbol_index)));
35138 } else {
35139 v_leaf_value = 768u;
35141 if (self->private_data.f_huffman_trees[a_which][v_node_index][0u] == 0u) {
35142 self->private_data.f_huffman_trees[a_which][v_node_index][0u] = v_leaf_value;
35143 } else {
35144 self->private_data.f_huffman_trees[a_which][v_node_index][1u] = v_leaf_value;
35145 v_stack_height -= 1u;
35146 while (v_stack_height > 0u) {
35147 v_node_index = v_stack_values[(v_stack_height - 1u)];
35148 if (self->private_data.f_huffman_trees[a_which][v_node_index][1u] == 0u) {
35149 break;
35151 v_stack_height -= 1u;
35154 v_symbol_index += 1u;
35156 v_code_length += 1u;
35158 if (v_stack_height != 0u) {
35159 return wuffs_base__make_status(wuffs_bzip2__error__bad_huffman_code_under_subscribed);
35161 return wuffs_base__make_status(NULL);
35164 // -------- func bzip2.decoder.build_huffman_table
35166 WUFFS_BASE__GENERATED_C_CODE
35167 static wuffs_base__empty_struct
35168 wuffs_bzip2__decoder__build_huffman_table(
35169 wuffs_bzip2__decoder* self,
35170 uint32_t a_which) {
35171 uint32_t v_i = 0;
35172 uint32_t v_bits = 0;
35173 uint16_t v_n_bits = 0;
35174 uint16_t v_child = 0;
35176 while (v_i < 256u) {
35177 v_bits = (v_i << 24u);
35178 v_n_bits = 0u;
35179 v_child = 0u;
35180 while ((v_child < 257u) && (v_n_bits < 8u)) {
35181 v_child = self->private_data.f_huffman_trees[a_which][v_child][(v_bits >> 31u)];
35182 v_bits <<= 1u;
35183 #if defined(__GNUC__)
35184 #pragma GCC diagnostic push
35185 #pragma GCC diagnostic ignored "-Wconversion"
35186 #endif
35187 v_n_bits += 1u;
35188 #if defined(__GNUC__)
35189 #pragma GCC diagnostic pop
35190 #endif
35192 self->private_data.f_huffman_tables[a_which][v_i] = ((uint16_t)(((uint16_t)(v_child | ((uint16_t)(v_n_bits << 12u))))));
35193 v_i += 1u;
35195 return wuffs_base__make_empty_struct();
35198 // -------- func bzip2.decoder.invert_bwt
35200 WUFFS_BASE__GENERATED_C_CODE
35201 static wuffs_base__empty_struct
35202 wuffs_bzip2__decoder__invert_bwt(
35203 wuffs_bzip2__decoder* self) {
35204 uint32_t v_i = 0;
35205 uint32_t v_letter = 0;
35206 uint32_t v_sum = 0;
35207 uint32_t v_old_sum = 0;
35209 v_sum = 0u;
35210 v_i = 0u;
35211 while (v_i < 256u) {
35212 v_old_sum = v_sum;
35213 v_sum += self->private_data.f_letter_counts[v_i];
35214 self->private_data.f_letter_counts[v_i] = v_old_sum;
35215 v_i += 1u;
35217 v_i = 0u;
35218 while (v_i < self->private_impl.f_block_size) {
35219 v_letter = (self->private_data.f_bwt[v_i] & 255u);
35220 self->private_data.f_bwt[(self->private_data.f_letter_counts[v_letter] & 1048575u)] |= (v_i << 12u);
35221 self->private_data.f_letter_counts[v_letter] += 1u;
35222 v_i += 1u;
35224 return wuffs_base__make_empty_struct();
35227 // -------- func bzip2.decoder.flush_fast
35229 WUFFS_BASE__GENERATED_C_CODE
35230 static wuffs_base__empty_struct
35231 wuffs_bzip2__decoder__flush_fast(
35232 wuffs_bzip2__decoder* self,
35233 wuffs_base__io_buffer* a_dst) {
35234 uint32_t v_flush_pointer = 0;
35235 uint32_t v_flush_repeat_count = 0;
35236 uint8_t v_flush_prev = 0;
35237 uint32_t v_block_checksum_have = 0;
35238 uint32_t v_block_size = 0;
35239 uint32_t v_entry = 0;
35240 uint8_t v_curr = 0;
35242 uint8_t* iop_a_dst = NULL;
35243 uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35244 uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35245 uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35246 if (a_dst && a_dst->data.ptr) {
35247 io0_a_dst = a_dst->data.ptr;
35248 io1_a_dst = io0_a_dst + a_dst->meta.wi;
35249 iop_a_dst = io1_a_dst;
35250 io2_a_dst = io0_a_dst + a_dst->data.len;
35251 if (a_dst->meta.closed) {
35252 io2_a_dst = iop_a_dst;
35256 v_flush_pointer = self->private_impl.f_flush_pointer;
35257 v_flush_repeat_count = self->private_impl.f_flush_repeat_count;
35258 v_flush_prev = self->private_impl.f_flush_prev;
35259 v_block_checksum_have = self->private_impl.f_block_checksum_have;
35260 v_block_size = self->private_impl.f_block_size;
35261 while ((v_block_size > 0u) && (((uint64_t)(io2_a_dst - iop_a_dst)) >= 255u)) {
35262 if (v_flush_repeat_count < 4u) {
35263 v_entry = self->private_data.f_bwt[v_flush_pointer];
35264 v_curr = ((uint8_t)(v_entry));
35265 v_flush_pointer = (v_entry >> 12u);
35266 if (v_curr == v_flush_prev) {
35267 v_flush_repeat_count += 1u;
35268 } else {
35269 v_flush_repeat_count = 1u;
35271 v_block_checksum_have = (WUFFS_BZIP2__REV_CRC32_TABLE[((uint8_t)(((uint8_t)((v_block_checksum_have >> 24u))) ^ v_curr))] ^ ((uint32_t)(v_block_checksum_have << 8u)));
35272 (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, v_curr), iop_a_dst += 1);
35273 v_flush_prev = v_curr;
35274 v_block_size -= 1u;
35275 } else {
35276 v_entry = self->private_data.f_bwt[v_flush_pointer];
35277 v_curr = ((uint8_t)(v_entry));
35278 v_flush_pointer = (v_entry >> 12u);
35279 v_flush_repeat_count = ((uint32_t)(v_curr));
35280 while (v_flush_repeat_count > 0u) {
35281 v_block_checksum_have = (WUFFS_BZIP2__REV_CRC32_TABLE[((uint8_t)(((uint8_t)((v_block_checksum_have >> 24u))) ^ v_flush_prev))] ^ ((uint32_t)(v_block_checksum_have << 8u)));
35282 if (((uint64_t)(io2_a_dst - iop_a_dst)) > 0u) {
35283 (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, v_flush_prev), iop_a_dst += 1);
35285 v_flush_repeat_count -= 1u;
35287 v_flush_repeat_count = 0u;
35288 v_flush_prev = v_curr;
35289 v_block_size -= 1u;
35292 self->private_impl.f_flush_pointer = v_flush_pointer;
35293 self->private_impl.f_flush_repeat_count = v_flush_repeat_count;
35294 self->private_impl.f_flush_prev = v_flush_prev;
35295 self->private_impl.f_block_checksum_have = v_block_checksum_have;
35296 if (v_block_size <= 900000u) {
35297 self->private_impl.f_block_size = v_block_size;
35299 if (a_dst && a_dst->data.ptr) {
35300 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
35303 return wuffs_base__make_empty_struct();
35306 // -------- func bzip2.decoder.flush_slow
35308 WUFFS_BASE__GENERATED_C_CODE
35309 static wuffs_base__status
35310 wuffs_bzip2__decoder__flush_slow(
35311 wuffs_bzip2__decoder* self,
35312 wuffs_base__io_buffer* a_dst) {
35313 wuffs_base__status status = wuffs_base__make_status(NULL);
35315 uint32_t v_flush_pointer = 0;
35316 uint32_t v_flush_repeat_count = 0;
35317 uint8_t v_flush_prev = 0;
35318 uint32_t v_block_checksum_have = 0;
35319 uint32_t v_block_size = 0;
35320 uint32_t v_entry = 0;
35321 uint8_t v_curr = 0;
35323 uint8_t* iop_a_dst = NULL;
35324 uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35325 uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35326 uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35327 if (a_dst && a_dst->data.ptr) {
35328 io0_a_dst = a_dst->data.ptr;
35329 io1_a_dst = io0_a_dst + a_dst->meta.wi;
35330 iop_a_dst = io1_a_dst;
35331 io2_a_dst = io0_a_dst + a_dst->data.len;
35332 if (a_dst->meta.closed) {
35333 io2_a_dst = iop_a_dst;
35337 uint32_t coro_susp_point = self->private_impl.p_flush_slow;
35338 if (coro_susp_point) {
35339 v_flush_pointer = self->private_data.s_flush_slow.v_flush_pointer;
35340 v_flush_repeat_count = self->private_data.s_flush_slow.v_flush_repeat_count;
35341 v_flush_prev = self->private_data.s_flush_slow.v_flush_prev;
35342 v_block_checksum_have = self->private_data.s_flush_slow.v_block_checksum_have;
35343 v_block_size = self->private_data.s_flush_slow.v_block_size;
35344 v_curr = self->private_data.s_flush_slow.v_curr;
35346 switch (coro_susp_point) {
35347 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
35349 v_flush_pointer = self->private_impl.f_flush_pointer;
35350 v_flush_repeat_count = self->private_impl.f_flush_repeat_count;
35351 v_flush_prev = self->private_impl.f_flush_prev;
35352 v_block_checksum_have = self->private_impl.f_block_checksum_have;
35353 v_block_size = self->private_impl.f_block_size;
35354 while ((v_block_size > 0u) && ! (self->private_impl.p_flush_slow != 0)) {
35355 if (v_flush_repeat_count < 4u) {
35356 v_entry = self->private_data.f_bwt[v_flush_pointer];
35357 v_curr = ((uint8_t)(v_entry));
35358 v_flush_pointer = (v_entry >> 12u);
35359 if (v_curr == v_flush_prev) {
35360 v_flush_repeat_count += 1u;
35361 } else {
35362 v_flush_repeat_count = 1u;
35364 v_block_checksum_have = (WUFFS_BZIP2__REV_CRC32_TABLE[((uint8_t)(((uint8_t)((v_block_checksum_have >> 24u))) ^ v_curr))] ^ ((uint32_t)(v_block_checksum_have << 8u)));
35365 self->private_data.s_flush_slow.scratch = v_curr;
35366 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
35367 if (iop_a_dst == io2_a_dst) {
35368 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
35369 goto suspend;
35371 *iop_a_dst++ = ((uint8_t)(self->private_data.s_flush_slow.scratch));
35372 v_flush_prev = v_curr;
35373 v_block_size -= 1u;
35374 } else {
35375 v_entry = self->private_data.f_bwt[v_flush_pointer];
35376 v_curr = ((uint8_t)(v_entry));
35377 v_flush_pointer = (v_entry >> 12u);
35378 v_flush_repeat_count = ((uint32_t)(v_curr));
35379 while (v_flush_repeat_count > 0u) {
35380 v_block_checksum_have = (WUFFS_BZIP2__REV_CRC32_TABLE[((uint8_t)(((uint8_t)((v_block_checksum_have >> 24u))) ^ v_flush_prev))] ^ ((uint32_t)(v_block_checksum_have << 8u)));
35381 self->private_data.s_flush_slow.scratch = v_flush_prev;
35382 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
35383 if (iop_a_dst == io2_a_dst) {
35384 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
35385 goto suspend;
35387 *iop_a_dst++ = ((uint8_t)(self->private_data.s_flush_slow.scratch));
35388 v_flush_repeat_count -= 1u;
35390 v_flush_repeat_count = 0u;
35391 v_flush_prev = v_curr;
35392 v_block_size -= 1u;
35395 self->private_impl.f_flush_pointer = v_flush_pointer;
35396 self->private_impl.f_flush_repeat_count = v_flush_repeat_count;
35397 self->private_impl.f_flush_prev = v_flush_prev;
35398 self->private_impl.f_block_checksum_have = v_block_checksum_have;
35399 if (v_block_size <= 900000u) {
35400 self->private_impl.f_block_size = v_block_size;
35403 goto ok;
35405 self->private_impl.p_flush_slow = 0;
35406 goto exit;
35409 goto suspend;
35410 suspend:
35411 self->private_impl.p_flush_slow = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
35412 self->private_data.s_flush_slow.v_flush_pointer = v_flush_pointer;
35413 self->private_data.s_flush_slow.v_flush_repeat_count = v_flush_repeat_count;
35414 self->private_data.s_flush_slow.v_flush_prev = v_flush_prev;
35415 self->private_data.s_flush_slow.v_block_checksum_have = v_block_checksum_have;
35416 self->private_data.s_flush_slow.v_block_size = v_block_size;
35417 self->private_data.s_flush_slow.v_curr = v_curr;
35419 goto exit;
35420 exit:
35421 if (a_dst && a_dst->data.ptr) {
35422 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
35425 return status;
35428 // -------- func bzip2.decoder.decode_huffman_fast
35430 WUFFS_BASE__GENERATED_C_CODE
35431 static wuffs_base__status
35432 wuffs_bzip2__decoder__decode_huffman_fast(
35433 wuffs_bzip2__decoder* self,
35434 wuffs_base__io_buffer* a_src) {
35435 wuffs_base__status status = wuffs_base__make_status(NULL);
35437 uint32_t v_bits = 0;
35438 uint32_t v_n_bits = 0;
35439 uint32_t v_block_size = 0;
35440 uint8_t v_which = 0;
35441 uint32_t v_ticks = 0;
35442 uint32_t v_section = 0;
35443 uint32_t v_run_shift = 0;
35444 uint16_t v_table_entry = 0;
35445 uint16_t v_child = 0;
35446 uint32_t v_child_ff = 0;
35447 uint32_t v_i = 0;
35448 uint32_t v_j = 0;
35449 uint32_t v_output = 0;
35450 uint32_t v_run = 0;
35451 uint32_t v_mtft0 = 0;
35453 const uint8_t* iop_a_src = NULL;
35454 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35455 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35456 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35457 if (a_src && a_src->data.ptr) {
35458 io0_a_src = a_src->data.ptr;
35459 io1_a_src = io0_a_src + a_src->meta.ri;
35460 iop_a_src = io1_a_src;
35461 io2_a_src = io0_a_src + a_src->meta.wi;
35464 v_bits = self->private_impl.f_bits;
35465 v_n_bits = self->private_impl.f_n_bits;
35466 v_block_size = self->private_impl.f_block_size;
35467 v_which = self->private_impl.f_decode_huffman_which;
35468 v_ticks = self->private_impl.f_decode_huffman_ticks;
35469 v_section = self->private_impl.f_decode_huffman_section;
35470 v_run_shift = self->private_impl.f_decode_huffman_run_shift;
35471 while (((uint64_t)(io2_a_src - iop_a_src)) >= 4u) {
35472 if (v_ticks > 0u) {
35473 v_ticks -= 1u;
35474 } else {
35475 v_ticks = 49u;
35476 v_section += 1u;
35477 if (v_section >= self->private_impl.f_num_sections) {
35478 status = wuffs_base__make_status(wuffs_bzip2__error__bad_number_of_sections);
35479 goto exit;
35481 v_which = WUFFS_BZIP2__CLAMP_TO_5[((uint8_t)(self->private_data.f_huffman_selectors[(v_section & 32767u)] & 7u))];
35483 v_bits |= (wuffs_base__peek_u32be__no_bounds_check(iop_a_src) >> v_n_bits);
35484 iop_a_src += ((31u - v_n_bits) >> 3u);
35485 v_n_bits |= 24u;
35486 v_table_entry = self->private_data.f_huffman_tables[v_which][(v_bits >> 24u)];
35487 v_bits <<= ((uint16_t)(v_table_entry >> 12u));
35488 v_n_bits -= ((uint32_t)(((uint16_t)(v_table_entry >> 12u))));
35489 v_child = ((uint16_t)(v_table_entry & 1023u));
35490 while (v_child < 257u) {
35491 v_child = self->private_data.f_huffman_trees[v_which][v_child][(v_bits >> 31u)];
35492 v_bits <<= 1u;
35493 if (v_n_bits <= 0u) {
35494 status = wuffs_base__make_status(wuffs_bzip2__error__internal_error_inconsistent_huffman_decoder_state);
35495 goto exit;
35497 v_n_bits -= 1u;
35499 if (v_child < 768u) {
35500 v_child_ff = ((uint32_t)(((uint16_t)(v_child & 255u))));
35501 v_output = ((uint32_t)(self->private_data.f_mtft[v_child_ff]));
35502 wuffs_private_impl__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));
35503 self->private_data.f_mtft[0u] = ((uint8_t)(v_output));
35504 self->private_data.f_letter_counts[v_output] += 1u;
35505 self->private_data.f_bwt[v_block_size] = v_output;
35506 if (v_block_size >= self->private_impl.f_max_incl_block_size) {
35507 status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_length);
35508 goto exit;
35510 v_block_size += 1u;
35511 v_run_shift = 0u;
35512 continue;
35513 } else if (v_child == 768u) {
35514 self->private_impl.f_decode_huffman_finished = true;
35515 break;
35517 if (v_run_shift >= 23u) {
35518 status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_length);
35519 goto exit;
35521 v_run = ((((uint32_t)(v_child)) & 3u) << v_run_shift);
35522 v_run_shift += 1u;
35523 v_i = v_block_size;
35524 v_j = (v_run + v_block_size);
35525 if (v_j > self->private_impl.f_max_incl_block_size) {
35526 status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_length);
35527 goto exit;
35529 v_block_size = v_j;
35530 v_mtft0 = ((uint32_t)(self->private_data.f_mtft[0u]));
35531 self->private_data.f_letter_counts[v_mtft0] += v_run;
35532 while (v_i < v_j) {
35533 self->private_data.f_bwt[v_i] = v_mtft0;
35534 v_i += 1u;
35537 self->private_impl.f_bits = v_bits;
35538 self->private_impl.f_n_bits = v_n_bits;
35539 self->private_impl.f_block_size = v_block_size;
35540 self->private_impl.f_decode_huffman_which = v_which;
35541 self->private_impl.f_decode_huffman_ticks = v_ticks;
35542 self->private_impl.f_decode_huffman_section = v_section;
35543 self->private_impl.f_decode_huffman_run_shift = v_run_shift;
35544 status = wuffs_base__make_status(NULL);
35545 goto ok;
35548 goto exit;
35549 exit:
35550 if (a_src && a_src->data.ptr) {
35551 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
35554 return status;
35557 // -------- func bzip2.decoder.decode_huffman_slow
35559 WUFFS_BASE__GENERATED_C_CODE
35560 static wuffs_base__status
35561 wuffs_bzip2__decoder__decode_huffman_slow(
35562 wuffs_bzip2__decoder* self,
35563 wuffs_base__io_buffer* a_src) {
35564 wuffs_base__status status = wuffs_base__make_status(NULL);
35566 uint8_t v_c8 = 0;
35567 uint32_t v_node_index = 0;
35568 uint16_t v_child = 0;
35569 uint32_t v_child_ff = 0;
35570 uint32_t v_i = 0;
35571 uint32_t v_j = 0;
35572 uint32_t v_output = 0;
35573 uint32_t v_run = 0;
35574 uint32_t v_mtft0 = 0;
35576 const uint8_t* iop_a_src = NULL;
35577 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35578 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35579 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35580 if (a_src && a_src->data.ptr) {
35581 io0_a_src = a_src->data.ptr;
35582 io1_a_src = io0_a_src + a_src->meta.ri;
35583 iop_a_src = io1_a_src;
35584 io2_a_src = io0_a_src + a_src->meta.wi;
35587 uint32_t coro_susp_point = self->private_impl.p_decode_huffman_slow;
35588 if (coro_susp_point) {
35589 v_node_index = self->private_data.s_decode_huffman_slow.v_node_index;
35591 switch (coro_susp_point) {
35592 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
35594 while ( ! (self->private_impl.p_decode_huffman_slow != 0)) {
35595 if (self->private_impl.f_decode_huffman_ticks > 0u) {
35596 self->private_impl.f_decode_huffman_ticks -= 1u;
35597 } else {
35598 self->private_impl.f_decode_huffman_ticks = 49u;
35599 self->private_impl.f_decode_huffman_section += 1u;
35600 if (self->private_impl.f_decode_huffman_section >= self->private_impl.f_num_sections) {
35601 status = wuffs_base__make_status(wuffs_bzip2__error__bad_number_of_sections);
35602 goto exit;
35604 self->private_impl.f_decode_huffman_which = WUFFS_BZIP2__CLAMP_TO_5[((uint8_t)(self->private_data.f_huffman_selectors[(self->private_impl.f_decode_huffman_section & 32767u)] & 7u))];
35606 v_node_index = 0u;
35607 while (true) {
35608 if (self->private_impl.f_n_bits <= 0u) {
35610 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
35611 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
35612 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
35613 goto suspend;
35615 uint8_t t_0 = *iop_a_src++;
35616 v_c8 = t_0;
35618 self->private_impl.f_bits = (((uint32_t)(v_c8)) << 24u);
35619 self->private_impl.f_n_bits = 8u;
35621 v_child = self->private_data.f_huffman_trees[self->private_impl.f_decode_huffman_which][v_node_index][(self->private_impl.f_bits >> 31u)];
35622 self->private_impl.f_bits <<= 1u;
35623 self->private_impl.f_n_bits -= 1u;
35624 if (v_child < 257u) {
35625 v_node_index = ((uint32_t)(v_child));
35626 continue;
35627 } else if (v_child < 768u) {
35628 v_child_ff = ((uint32_t)(((uint16_t)(v_child & 255u))));
35629 v_output = ((uint32_t)(self->private_data.f_mtft[v_child_ff]));
35630 wuffs_private_impl__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));
35631 self->private_data.f_mtft[0u] = ((uint8_t)(v_output));
35632 self->private_data.f_letter_counts[v_output] += 1u;
35633 self->private_data.f_bwt[self->private_impl.f_block_size] = v_output;
35634 if (self->private_impl.f_block_size >= self->private_impl.f_max_incl_block_size) {
35635 status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_length);
35636 goto exit;
35638 self->private_impl.f_block_size += 1u;
35639 self->private_impl.f_decode_huffman_run_shift = 0u;
35640 break;
35641 } else if (v_child == 768u) {
35642 self->private_impl.f_decode_huffman_finished = true;
35643 goto label__outer__break;
35645 if (self->private_impl.f_decode_huffman_run_shift >= 23u) {
35646 status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_length);
35647 goto exit;
35649 v_run = ((((uint32_t)(v_child)) & 3u) << self->private_impl.f_decode_huffman_run_shift);
35650 self->private_impl.f_decode_huffman_run_shift += 1u;
35651 v_i = self->private_impl.f_block_size;
35652 v_j = (v_run + self->private_impl.f_block_size);
35653 if (v_j > self->private_impl.f_max_incl_block_size) {
35654 status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_length);
35655 goto exit;
35657 self->private_impl.f_block_size = v_j;
35658 v_mtft0 = ((uint32_t)(self->private_data.f_mtft[0u]));
35659 self->private_data.f_letter_counts[v_mtft0] += v_run;
35660 while (v_i < v_j) {
35661 self->private_data.f_bwt[v_i] = v_mtft0;
35662 v_i += 1u;
35664 break;
35667 label__outer__break:;
35669 goto ok;
35671 self->private_impl.p_decode_huffman_slow = 0;
35672 goto exit;
35675 goto suspend;
35676 suspend:
35677 self->private_impl.p_decode_huffman_slow = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
35678 self->private_data.s_decode_huffman_slow.v_node_index = v_node_index;
35680 goto exit;
35681 exit:
35682 if (a_src && a_src->data.ptr) {
35683 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
35686 return status;
35689 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BZIP2)
35691 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CBOR)
35693 // ---------------- Status Codes Implementations
35695 const char wuffs_cbor__error__bad_input[] = "#cbor: bad input";
35696 const char wuffs_cbor__error__unsupported_recursion_depth[] = "#cbor: unsupported recursion depth";
35697 const char wuffs_cbor__error__internal_error_inconsistent_i_o[] = "#cbor: internal error: inconsistent I/O";
35698 const char wuffs_cbor__error__internal_error_inconsistent_token_length[] = "#cbor: internal error: inconsistent token length";
35700 // ---------------- Private Consts
35702 static const uint32_t
35703 WUFFS_CBOR__LITERALS[4] WUFFS_BASE__POTENTIALLY_UNUSED = {
35704 8388612u, 8388616u, 8388610u, 8388609u,
35707 static const uint8_t
35708 WUFFS_CBOR__TOKEN_LENGTHS[32] WUFFS_BASE__POTENTIALLY_UNUSED = {
35709 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u,
35710 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u,
35711 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u,
35712 2u, 3u, 5u, 9u, 0u, 0u, 0u, 1u,
35715 // ---------------- Private Initializer Prototypes
35717 // ---------------- Private Function Prototypes
35719 // ---------------- VTables
35721 const wuffs_base__token_decoder__func_ptrs
35722 wuffs_cbor__decoder__func_ptrs_for__wuffs_base__token_decoder = {
35723 (wuffs_base__status(*)(void*,
35724 wuffs_base__token_buffer*,
35725 wuffs_base__io_buffer*,
35726 wuffs_base__slice_u8))(&wuffs_cbor__decoder__decode_tokens),
35727 (uint64_t(*)(const void*,
35728 uint32_t))(&wuffs_cbor__decoder__get_quirk),
35729 (wuffs_base__status(*)(void*,
35730 uint32_t,
35731 uint64_t))(&wuffs_cbor__decoder__set_quirk),
35732 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_cbor__decoder__workbuf_len),
35735 // ---------------- Initializer Implementations
35737 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
35738 wuffs_cbor__decoder__initialize(
35739 wuffs_cbor__decoder* self,
35740 size_t sizeof_star_self,
35741 uint64_t wuffs_version,
35742 uint32_t options){
35743 if (!self) {
35744 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
35746 if (sizeof(*self) != sizeof_star_self) {
35747 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
35749 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
35750 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
35751 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
35754 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
35755 // The whole point of this if-check is to detect an uninitialized *self.
35756 // We disable the warning on GCC. Clang-5.0 does not have this warning.
35757 #if !defined(__clang__) && defined(__GNUC__)
35758 #pragma GCC diagnostic push
35759 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
35760 #endif
35761 if (self->private_impl.magic != 0) {
35762 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
35764 #if !defined(__clang__) && defined(__GNUC__)
35765 #pragma GCC diagnostic pop
35766 #endif
35767 } else {
35768 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
35769 memset(self, 0, sizeof(*self));
35770 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
35771 } else {
35772 memset(&(self->private_impl), 0, sizeof(self->private_impl));
35776 self->private_impl.magic = WUFFS_BASE__MAGIC;
35777 self->private_impl.vtable_for__wuffs_base__token_decoder.vtable_name =
35778 wuffs_base__token_decoder__vtable_name;
35779 self->private_impl.vtable_for__wuffs_base__token_decoder.function_pointers =
35780 (const void*)(&wuffs_cbor__decoder__func_ptrs_for__wuffs_base__token_decoder);
35781 return wuffs_base__make_status(NULL);
35784 wuffs_cbor__decoder*
35785 wuffs_cbor__decoder__alloc(void) {
35786 wuffs_cbor__decoder* x =
35787 (wuffs_cbor__decoder*)(calloc(1, sizeof(wuffs_cbor__decoder)));
35788 if (!x) {
35789 return NULL;
35791 if (wuffs_cbor__decoder__initialize(
35792 x, sizeof(wuffs_cbor__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
35793 free(x);
35794 return NULL;
35796 return x;
35799 size_t
35800 sizeof__wuffs_cbor__decoder(void) {
35801 return sizeof(wuffs_cbor__decoder);
35804 // ---------------- Function Implementations
35806 // -------- func cbor.decoder.get_quirk
35808 WUFFS_BASE__GENERATED_C_CODE
35809 WUFFS_BASE__MAYBE_STATIC uint64_t
35810 wuffs_cbor__decoder__get_quirk(
35811 const wuffs_cbor__decoder* self,
35812 uint32_t a_key) {
35813 if (!self) {
35814 return 0;
35816 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
35817 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
35818 return 0;
35821 return 0u;
35824 // -------- func cbor.decoder.set_quirk
35826 WUFFS_BASE__GENERATED_C_CODE
35827 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
35828 wuffs_cbor__decoder__set_quirk(
35829 wuffs_cbor__decoder* self,
35830 uint32_t a_key,
35831 uint64_t a_value) {
35832 if (!self) {
35833 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
35835 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
35836 return wuffs_base__make_status(
35837 (self->private_impl.magic == WUFFS_BASE__DISABLED)
35838 ? wuffs_base__error__disabled_by_previous_error
35839 : wuffs_base__error__initialize_not_called);
35842 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
35845 // -------- func cbor.decoder.workbuf_len
35847 WUFFS_BASE__GENERATED_C_CODE
35848 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
35849 wuffs_cbor__decoder__workbuf_len(
35850 const wuffs_cbor__decoder* self) {
35851 if (!self) {
35852 return wuffs_base__utility__empty_range_ii_u64();
35854 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
35855 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
35856 return wuffs_base__utility__empty_range_ii_u64();
35859 return wuffs_base__utility__empty_range_ii_u64();
35862 // -------- func cbor.decoder.decode_tokens
35864 WUFFS_BASE__GENERATED_C_CODE
35865 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
35866 wuffs_cbor__decoder__decode_tokens(
35867 wuffs_cbor__decoder* self,
35868 wuffs_base__token_buffer* a_dst,
35869 wuffs_base__io_buffer* a_src,
35870 wuffs_base__slice_u8 a_workbuf) {
35871 if (!self) {
35872 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
35874 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
35875 return wuffs_base__make_status(
35876 (self->private_impl.magic == WUFFS_BASE__DISABLED)
35877 ? wuffs_base__error__disabled_by_previous_error
35878 : wuffs_base__error__initialize_not_called);
35880 if (!a_dst || !a_src) {
35881 self->private_impl.magic = WUFFS_BASE__DISABLED;
35882 return wuffs_base__make_status(wuffs_base__error__bad_argument);
35884 if ((self->private_impl.active_coroutine != 0) &&
35885 (self->private_impl.active_coroutine != 1)) {
35886 self->private_impl.magic = WUFFS_BASE__DISABLED;
35887 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
35889 self->private_impl.active_coroutine = 0;
35890 wuffs_base__status status = wuffs_base__make_status(NULL);
35892 uint64_t v_string_length = 0;
35893 uint64_t v_n64 = 0;
35894 uint32_t v_depth = 0;
35895 uint32_t v_stack_byte = 0;
35896 uint32_t v_stack_bit = 0;
35897 uint32_t v_stack_val = 0;
35898 uint32_t v_token_length = 0;
35899 uint32_t v_vminor = 0;
35900 uint32_t v_vminor_alt = 0;
35901 uint32_t v_continued = 0;
35902 uint8_t v_c8 = 0;
35903 uint8_t v_c_major = 0;
35904 uint8_t v_c_minor = 0;
35905 bool v_tagged = false;
35906 uint8_t v_indefinite_string_major_type = 0;
35908 wuffs_base__token* iop_a_dst = NULL;
35909 wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35910 wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35911 wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35912 if (a_dst && a_dst->data.ptr) {
35913 io0_a_dst = a_dst->data.ptr;
35914 io1_a_dst = io0_a_dst + a_dst->meta.wi;
35915 iop_a_dst = io1_a_dst;
35916 io2_a_dst = io0_a_dst + a_dst->data.len;
35917 if (a_dst->meta.closed) {
35918 io2_a_dst = iop_a_dst;
35921 const uint8_t* iop_a_src = NULL;
35922 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35923 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35924 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35925 if (a_src && a_src->data.ptr) {
35926 io0_a_src = a_src->data.ptr;
35927 io1_a_src = io0_a_src + a_src->meta.ri;
35928 iop_a_src = io1_a_src;
35929 io2_a_src = io0_a_src + a_src->meta.wi;
35932 uint32_t coro_susp_point = self->private_impl.p_decode_tokens;
35933 if (coro_susp_point) {
35934 v_string_length = self->private_data.s_decode_tokens.v_string_length;
35935 v_depth = self->private_data.s_decode_tokens.v_depth;
35936 v_tagged = self->private_data.s_decode_tokens.v_tagged;
35937 v_indefinite_string_major_type = self->private_data.s_decode_tokens.v_indefinite_string_major_type;
35939 switch (coro_susp_point) {
35940 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
35942 if (self->private_impl.f_end_of_data) {
35943 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
35944 goto ok;
35946 label__outer__continue:;
35947 while (true) {
35948 while (true) {
35949 do {
35950 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 1u) {
35951 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
35952 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
35953 goto label__outer__continue;
35955 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
35956 if (a_src && a_src->meta.closed) {
35957 status = wuffs_base__make_status(wuffs_cbor__error__bad_input);
35958 goto exit;
35960 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
35961 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
35962 goto label__outer__continue;
35964 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
35965 if ((v_indefinite_string_major_type != 0u) && (v_indefinite_string_major_type != ((uint8_t)(v_c8 >> 5u)))) {
35966 if (v_c8 != 255u) {
35967 status = wuffs_base__make_status(wuffs_cbor__error__bad_input);
35968 goto exit;
35970 v_vminor = 4194560u;
35971 if (v_indefinite_string_major_type == 3u) {
35972 v_vminor |= 19u;
35974 v_indefinite_string_major_type = 0u;
35975 iop_a_src += 1u;
35976 *iop_a_dst++ = wuffs_base__make_token(
35977 (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
35978 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
35979 goto label__goto_parsed_a_leaf_value__break;
35981 iop_a_src += 1u;
35982 v_c_major = ((uint8_t)(((uint8_t)(v_c8 >> 5u))));
35983 v_c_minor = ((uint8_t)(v_c8 & 31u));
35984 if (v_c_minor < 24u) {
35985 v_string_length = ((uint64_t)(v_c_minor));
35986 } else {
35987 while (true) {
35988 if (v_c_minor == 24u) {
35989 if (((uint64_t)(io2_a_src - iop_a_src)) >= 1u) {
35990 v_string_length = ((uint64_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src)));
35991 iop_a_src += 1u;
35992 break;
35994 } else if (v_c_minor == 25u) {
35995 if (((uint64_t)(io2_a_src - iop_a_src)) >= 2u) {
35996 v_string_length = ((uint64_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
35997 iop_a_src += 2u;
35998 break;
36000 } else if (v_c_minor == 26u) {
36001 if (((uint64_t)(io2_a_src - iop_a_src)) >= 4u) {
36002 v_string_length = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
36003 iop_a_src += 4u;
36004 break;
36006 } else if (v_c_minor == 27u) {
36007 if (((uint64_t)(io2_a_src - iop_a_src)) >= 8u) {
36008 v_string_length = wuffs_base__peek_u64be__no_bounds_check(iop_a_src);
36009 iop_a_src += 8u;
36010 break;
36012 } else {
36013 v_string_length = 0u;
36014 break;
36016 if (iop_a_src > io1_a_src) {
36017 iop_a_src--;
36018 if (a_src && a_src->meta.closed) {
36019 status = wuffs_base__make_status(wuffs_cbor__error__bad_input);
36020 goto exit;
36022 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
36023 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
36024 goto label__outer__continue;
36026 status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_i_o);
36027 goto exit;
36030 if (v_c_major == 0u) {
36031 if (v_c_minor < 26u) {
36032 *iop_a_dst++ = wuffs_base__make_token(
36033 (((uint64_t)((14680064u | ((uint32_t)((v_string_length & 65535u)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
36034 (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
36035 goto label__goto_parsed_a_leaf_value__break;
36036 } else if (v_c_minor < 28u) {
36037 *iop_a_dst++ = wuffs_base__make_token(
36038 (((uint64_t)((14680064u | ((uint32_t)((v_string_length >> 46u)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
36039 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
36040 (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
36041 *iop_a_dst++ = wuffs_base__make_token(
36042 (~(v_string_length & 70368744177663u) << WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT) |
36043 (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
36044 goto label__goto_parsed_a_leaf_value__break;
36046 } else if (v_c_major == 1u) {
36047 if (v_c_minor < 26u) {
36048 *iop_a_dst++ = wuffs_base__make_token(
36049 (((uint64_t)((12582912u | (2097151u - ((uint32_t)((v_string_length & 65535u))))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
36050 (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
36051 goto label__goto_parsed_a_leaf_value__break;
36052 } else if (v_c_minor < 28u) {
36053 if (v_string_length < 9223372036854775808u) {
36054 *iop_a_dst++ = wuffs_base__make_token(
36055 (((uint64_t)((12582912u | (2097151u - ((uint32_t)((v_string_length >> 46u))))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
36056 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
36057 (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
36058 *iop_a_dst++ = wuffs_base__make_token(
36059 (~((18446744073709551615u - v_string_length) & 70368744177663u) << WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT) |
36060 (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
36061 } else {
36062 *iop_a_dst++ = wuffs_base__make_token(
36063 (((uint64_t)(787997u)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) |
36064 (((uint64_t)(16777216u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
36065 (((uint64_t)(9u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
36067 goto label__goto_parsed_a_leaf_value__break;
36069 } else if (v_c_major == 2u) {
36070 if (v_c_minor < 28u) {
36071 if (v_string_length == 0u) {
36072 *iop_a_dst++ = wuffs_base__make_token(
36073 (((uint64_t)(4194560u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
36074 (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
36075 goto label__goto_parsed_a_leaf_value__break;
36077 *iop_a_dst++ = wuffs_base__make_token(
36078 (((uint64_t)(4194560u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
36079 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
36080 (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
36081 } else if (v_c_minor == 31u) {
36082 if (v_indefinite_string_major_type != 0u) {
36083 break;
36085 v_indefinite_string_major_type = 2u;
36086 *iop_a_dst++ = wuffs_base__make_token(
36087 (((uint64_t)(4194560u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
36088 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
36089 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
36090 goto label__outer__continue;
36091 } else {
36092 break;
36094 while (true) {
36095 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
36096 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
36097 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
36098 continue;
36100 v_n64 = wuffs_base__u64__min(v_string_length, ((uint64_t)(io2_a_src - iop_a_src)));
36101 v_token_length = ((uint32_t)((v_n64 & 65535u)));
36102 if (v_n64 > 65535u) {
36103 v_token_length = 65535u;
36104 } else if (v_token_length <= 0u) {
36105 if (a_src && a_src->meta.closed) {
36106 status = wuffs_base__make_status(wuffs_cbor__error__bad_input);
36107 goto exit;
36109 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
36110 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
36111 continue;
36113 if (((uint64_t)(io2_a_src - iop_a_src)) < ((uint64_t)(v_token_length))) {
36114 status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_token_length);
36115 goto exit;
36117 v_string_length -= ((uint64_t)(v_token_length));
36118 v_continued = 0u;
36119 if ((v_string_length > 0u) || (v_indefinite_string_major_type > 0u)) {
36120 v_continued = 1u;
36122 iop_a_src += v_token_length;
36123 *iop_a_dst++ = wuffs_base__make_token(
36124 (((uint64_t)(4194816u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
36125 (((uint64_t)(v_continued)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
36126 (((uint64_t)(v_token_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
36127 if (v_string_length > 0u) {
36128 continue;
36129 } else if (v_indefinite_string_major_type > 0u) {
36130 goto label__outer__continue;
36132 goto label__goto_parsed_a_leaf_value__break;
36134 } else if (v_c_major == 3u) {
36135 if (v_c_minor < 28u) {
36136 if (v_string_length == 0u) {
36137 *iop_a_dst++ = wuffs_base__make_token(
36138 (((uint64_t)(4194579u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
36139 (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
36140 goto label__goto_parsed_a_leaf_value__break;
36142 *iop_a_dst++ = wuffs_base__make_token(
36143 (((uint64_t)(4194579u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
36144 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
36145 (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
36146 } else if (v_c_minor == 31u) {
36147 if (v_indefinite_string_major_type != 0u) {
36148 break;
36150 v_indefinite_string_major_type = 3u;
36151 *iop_a_dst++ = wuffs_base__make_token(
36152 (((uint64_t)(4194579u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
36153 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
36154 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
36155 goto label__outer__continue;
36156 } else {
36157 break;
36159 while (true) {
36160 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
36161 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
36162 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
36163 continue;
36165 v_n64 = wuffs_base__u64__min(v_string_length, 65535u);
36166 v_n64 = ((uint64_t)(wuffs_base__utf_8__longest_valid_prefix(iop_a_src,
36167 ((size_t)(wuffs_base__u64__min(((uint64_t)(io2_a_src - iop_a_src)), v_n64))))));
36168 v_token_length = ((uint32_t)((v_n64 & 65535u)));
36169 if (v_token_length <= 0u) {
36170 if ((a_src && a_src->meta.closed) || (((uint64_t)(io2_a_src - iop_a_src)) >= 4u)) {
36171 status = wuffs_base__make_status(wuffs_cbor__error__bad_input);
36172 goto exit;
36174 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
36175 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7);
36176 continue;
36178 if (((uint64_t)(io2_a_src - iop_a_src)) < ((uint64_t)(v_token_length))) {
36179 status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_token_length);
36180 goto exit;
36182 v_string_length -= ((uint64_t)(v_token_length));
36183 v_continued = 0u;
36184 if ((v_string_length > 0u) || (v_indefinite_string_major_type > 0u)) {
36185 v_continued = 1u;
36187 iop_a_src += v_token_length;
36188 *iop_a_dst++ = wuffs_base__make_token(
36189 (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
36190 (((uint64_t)(v_continued)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
36191 (((uint64_t)(v_token_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
36192 if (v_string_length > 0u) {
36193 continue;
36194 } else if (v_indefinite_string_major_type > 0u) {
36195 goto label__outer__continue;
36197 goto label__goto_parsed_a_leaf_value__break;
36199 } else if (v_c_major == 4u) {
36200 if (WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor] == 0u) {
36201 break;
36202 } else if (v_depth >= 1024u) {
36203 v_token_length = ((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor]));
36204 while ((v_token_length > 0u) && (iop_a_src > io1_a_src)) {
36205 iop_a_src--;
36206 v_token_length -= 1u;
36208 status = wuffs_base__make_status(wuffs_cbor__error__unsupported_recursion_depth);
36209 goto exit;
36211 v_vminor = 2105361u;
36212 v_vminor_alt = 2101282u;
36213 if (v_depth > 0u) {
36214 v_stack_byte = ((v_depth - 1u) / 16u);
36215 v_stack_bit = (((v_depth - 1u) & 15u) * 2u);
36216 if (0u == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1u)) << v_stack_bit))) {
36217 v_vminor = 2105377u;
36218 v_vminor_alt = 2105378u;
36219 } else {
36220 v_vminor = 2105409u;
36221 v_vminor_alt = 2113570u;
36224 *iop_a_dst++ = wuffs_base__make_token(
36225 (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
36226 (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
36227 if (v_c_minor == 0u) {
36228 *iop_a_dst++ = wuffs_base__make_token(
36229 (((uint64_t)(v_vminor_alt)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
36230 (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
36231 goto label__goto_parsed_a_leaf_value__break;
36233 v_stack_byte = (v_depth / 16u);
36234 v_stack_bit = ((v_depth & 15u) * 2u);
36235 self->private_data.f_stack[v_stack_byte] &= (4294967295u ^ (((uint32_t)(3u)) << v_stack_bit));
36236 self->private_data.f_container_num_remaining[v_depth] = v_string_length;
36237 v_depth += 1u;
36238 v_tagged = false;
36239 goto label__outer__continue;
36240 } else if (v_c_major == 5u) {
36241 if (WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor] == 0u) {
36242 break;
36243 } else if (v_depth >= 1024u) {
36244 v_token_length = ((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor]));
36245 while ((v_token_length > 0u) && (iop_a_src > io1_a_src)) {
36246 iop_a_src--;
36247 v_token_length -= 1u;
36249 status = wuffs_base__make_status(wuffs_cbor__error__unsupported_recursion_depth);
36250 goto exit;
36252 v_vminor = 2113553u;
36253 v_vminor_alt = 2101314u;
36254 if (v_depth > 0u) {
36255 v_stack_byte = ((v_depth - 1u) / 16u);
36256 v_stack_bit = (((v_depth - 1u) & 15u) * 2u);
36257 if (0u == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1u)) << v_stack_bit))) {
36258 v_vminor = 2113569u;
36259 v_vminor_alt = 2105410u;
36260 } else {
36261 v_vminor = 2113601u;
36262 v_vminor_alt = 2113602u;
36265 *iop_a_dst++ = wuffs_base__make_token(
36266 (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
36267 (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
36268 if (v_c_minor == 0u) {
36269 *iop_a_dst++ = wuffs_base__make_token(
36270 (((uint64_t)(v_vminor_alt)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
36271 (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
36272 goto label__goto_parsed_a_leaf_value__break;
36274 v_stack_byte = (v_depth / 16u);
36275 v_stack_bit = ((v_depth & 15u) * 2u);
36276 self->private_data.f_stack[v_stack_byte] |= (((uint32_t)(3u)) << v_stack_bit);
36277 self->private_data.f_container_num_remaining[v_depth] = v_string_length;
36278 v_depth += 1u;
36279 v_tagged = false;
36280 goto label__outer__continue;
36281 } else if (v_c_major == 6u) {
36282 if (v_c_minor >= 28u) {
36283 break;
36285 if (v_string_length < 262144u) {
36286 *iop_a_dst++ = wuffs_base__make_token(
36287 (((uint64_t)(787997u)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) |
36288 (((uint64_t)((4194304u | ((uint32_t)(v_string_length))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
36289 (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
36290 } else {
36291 *iop_a_dst++ = wuffs_base__make_token(
36292 (((uint64_t)(787997u)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) |
36293 (((uint64_t)((4194304u | ((uint32_t)((v_string_length >> 46u)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
36294 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
36295 (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
36296 *iop_a_dst++ = wuffs_base__make_token(
36297 (~(v_string_length & 70368744177663u) << WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT) |
36298 (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
36300 v_tagged = true;
36301 goto label__outer__continue;
36302 } else if (v_c_major == 7u) {
36303 if (v_c_minor < 20u) {
36304 *iop_a_dst++ = wuffs_base__make_token(
36305 (((uint64_t)(787997u)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) |
36306 (((uint64_t)((8388608u | ((uint32_t)((v_string_length & 255u)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
36307 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
36308 goto label__goto_parsed_a_leaf_value__break;
36309 } else if (v_c_minor < 24u) {
36310 *iop_a_dst++ = wuffs_base__make_token(
36311 (((uint64_t)(WUFFS_CBOR__LITERALS[((uint8_t)(v_c_minor & 3u))])) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
36312 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
36313 goto label__goto_parsed_a_leaf_value__break;
36314 } else if (v_c_minor == 24u) {
36315 if (v_string_length < 24u) {
36316 if ( ! (iop_a_src > io1_a_src)) {
36317 status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_i_o);
36318 goto exit;
36320 iop_a_src--;
36321 break;
36323 *iop_a_dst++ = wuffs_base__make_token(
36324 (((uint64_t)(787997u)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) |
36325 (((uint64_t)((8388608u | ((uint32_t)((v_string_length & 255u)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
36326 (((uint64_t)(2u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
36327 goto label__goto_parsed_a_leaf_value__break;
36328 } else if (v_c_minor < 28u) {
36329 *iop_a_dst++ = wuffs_base__make_token(
36330 (((uint64_t)(10490113u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
36331 (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
36332 goto label__goto_parsed_a_leaf_value__break;
36333 } else if (v_c_minor == 31u) {
36334 if (v_tagged || (v_depth <= 0u)) {
36335 break;
36337 v_depth -= 1u;
36338 if (self->private_data.f_container_num_remaining[v_depth] != 0u) {
36339 break;
36341 v_stack_byte = (v_depth / 16u);
36342 v_stack_bit = ((v_depth & 15u) * 2u);
36343 v_stack_val = (3u & (self->private_data.f_stack[v_stack_byte] >> v_stack_bit));
36344 if (v_stack_val == 1u) {
36345 break;
36347 if (v_stack_val != 3u) {
36348 v_vminor_alt = 2097186u;
36349 } else {
36350 v_vminor_alt = 2097218u;
36352 if (v_depth <= 0u) {
36353 v_vminor_alt |= 4096u;
36354 } else {
36355 v_stack_byte = ((v_depth - 1u) / 16u);
36356 v_stack_bit = (((v_depth - 1u) & 15u) * 2u);
36357 if (0u == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1u)) << v_stack_bit))) {
36358 v_vminor_alt |= 8192u;
36359 } else {
36360 v_vminor_alt |= 16384u;
36363 *iop_a_dst++ = wuffs_base__make_token(
36364 (((uint64_t)(v_vminor_alt)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
36365 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
36366 goto label__goto_parsed_a_leaf_value__break;
36369 } while (0);
36370 if (iop_a_src > io1_a_src) {
36371 iop_a_src--;
36372 status = wuffs_base__make_status(wuffs_cbor__error__bad_input);
36373 goto exit;
36375 status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_i_o);
36376 goto exit;
36378 label__goto_parsed_a_leaf_value__break:;
36379 v_tagged = false;
36380 while (v_depth > 0u) {
36381 v_stack_byte = ((v_depth - 1u) / 16u);
36382 v_stack_bit = (((v_depth - 1u) & 15u) * 2u);
36383 self->private_data.f_stack[v_stack_byte] ^= (((uint32_t)(1u)) << (v_stack_bit + 1u));
36384 if (1u == (3u & (self->private_data.f_stack[v_stack_byte] >> v_stack_bit))) {
36385 goto label__outer__continue;
36387 if (self->private_data.f_container_num_remaining[(v_depth - 1u)] <= 0u) {
36388 goto label__outer__continue;
36390 self->private_data.f_container_num_remaining[(v_depth - 1u)] -= 1u;
36391 if (self->private_data.f_container_num_remaining[(v_depth - 1u)] > 0u) {
36392 goto label__outer__continue;
36394 while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
36395 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
36396 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8);
36397 continue;
36399 v_depth -= 1u;
36400 v_stack_byte = (v_depth / 16u);
36401 v_stack_bit = ((v_depth & 15u) * 2u);
36402 if (0u == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1u)) << v_stack_bit))) {
36403 v_vminor_alt = 2097186u;
36404 } else {
36405 v_vminor_alt = 2097218u;
36407 if (v_depth <= 0u) {
36408 v_vminor_alt |= 4096u;
36409 } else {
36410 v_stack_byte = ((v_depth - 1u) / 16u);
36411 v_stack_bit = (((v_depth - 1u) & 15u) * 2u);
36412 if (0u == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1u)) << v_stack_bit))) {
36413 v_vminor_alt |= 8192u;
36414 } else {
36415 v_vminor_alt |= 16384u;
36418 *iop_a_dst++ = wuffs_base__make_token(
36419 (((uint64_t)(v_vminor_alt)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
36420 (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
36422 break;
36424 self->private_impl.f_end_of_data = true;
36427 self->private_impl.p_decode_tokens = 0;
36428 goto exit;
36431 goto suspend;
36432 suspend:
36433 self->private_impl.p_decode_tokens = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
36434 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
36435 self->private_data.s_decode_tokens.v_string_length = v_string_length;
36436 self->private_data.s_decode_tokens.v_depth = v_depth;
36437 self->private_data.s_decode_tokens.v_tagged = v_tagged;
36438 self->private_data.s_decode_tokens.v_indefinite_string_major_type = v_indefinite_string_major_type;
36440 goto exit;
36441 exit:
36442 if (a_dst && a_dst->data.ptr) {
36443 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
36445 if (a_src && a_src->data.ptr) {
36446 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
36449 if (wuffs_base__status__is_error(&status)) {
36450 self->private_impl.magic = WUFFS_BASE__DISABLED;
36452 return status;
36455 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CBOR)
36457 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CRC32)
36459 // ---------------- Status Codes Implementations
36461 // ---------------- Private Consts
36463 static const uint32_t
36464 WUFFS_CRC32__IEEE_TABLE[16][256] WUFFS_BASE__POTENTIALLY_UNUSED = {
36466 0u, 1996959894u, 3993919788u, 2567524794u, 124634137u, 1886057615u, 3915621685u, 2657392035u,
36467 249268274u, 2044508324u, 3772115230u, 2547177864u, 162941995u, 2125561021u, 3887607047u, 2428444049u,
36468 498536548u, 1789927666u, 4089016648u, 2227061214u, 450548861u, 1843258603u, 4107580753u, 2211677639u,
36469 325883990u, 1684777152u, 4251122042u, 2321926636u, 335633487u, 1661365465u, 4195302755u, 2366115317u,
36470 997073096u, 1281953886u, 3579855332u, 2724688242u, 1006888145u, 1258607687u, 3524101629u, 2768942443u,
36471 901097722u, 1119000684u, 3686517206u, 2898065728u, 853044451u, 1172266101u, 3705015759u, 2882616665u,
36472 651767980u, 1373503546u, 3369554304u, 3218104598u, 565507253u, 1454621731u, 3485111705u, 3099436303u,
36473 671266974u, 1594198024u, 3322730930u, 2970347812u, 795835527u, 1483230225u, 3244367275u, 3060149565u,
36474 1994146192u, 31158534u, 2563907772u, 4023717930u, 1907459465u, 112637215u, 2680153253u, 3904427059u,
36475 2013776290u, 251722036u, 2517215374u, 3775830040u, 2137656763u, 141376813u, 2439277719u, 3865271297u,
36476 1802195444u, 476864866u, 2238001368u, 4066508878u, 1812370925u, 453092731u, 2181625025u, 4111451223u,
36477 1706088902u, 314042704u, 2344532202u, 4240017532u, 1658658271u, 366619977u, 2362670323u, 4224994405u,
36478 1303535960u, 984961486u, 2747007092u, 3569037538u, 1256170817u, 1037604311u, 2765210733u, 3554079995u,
36479 1131014506u, 879679996u, 2909243462u, 3663771856u, 1141124467u, 855842277u, 2852801631u, 3708648649u,
36480 1342533948u, 654459306u, 3188396048u, 3373015174u, 1466479909u, 544179635u, 3110523913u, 3462522015u,
36481 1591671054u, 702138776u, 2966460450u, 3352799412u, 1504918807u, 783551873u, 3082640443u, 3233442989u,
36482 3988292384u, 2596254646u, 62317068u, 1957810842u, 3939845945u, 2647816111u, 81470997u, 1943803523u,
36483 3814918930u, 2489596804u, 225274430u, 2053790376u, 3826175755u, 2466906013u, 167816743u, 2097651377u,
36484 4027552580u, 2265490386u, 503444072u, 1762050814u, 4150417245u, 2154129355u, 426522225u, 1852507879u,
36485 4275313526u, 2312317920u, 282753626u, 1742555852u, 4189708143u, 2394877945u, 397917763u, 1622183637u,
36486 3604390888u, 2714866558u, 953729732u, 1340076626u, 3518719985u, 2797360999u, 1068828381u, 1219638859u,
36487 3624741850u, 2936675148u, 906185462u, 1090812512u, 3747672003u, 2825379669u, 829329135u, 1181335161u,
36488 3412177804u, 3160834842u, 628085408u, 1382605366u, 3423369109u, 3138078467u, 570562233u, 1426400815u,
36489 3317316542u, 2998733608u, 733239954u, 1555261956u, 3268935591u, 3050360625u, 752459403u, 1541320221u,
36490 2607071920u, 3965973030u, 1969922972u, 40735498u, 2617837225u, 3943577151u, 1913087877u, 83908371u,
36491 2512341634u, 3803740692u, 2075208622u, 213261112u, 2463272603u, 3855990285u, 2094854071u, 198958881u,
36492 2262029012u, 4057260610u, 1759359992u, 534414190u, 2176718541u, 4139329115u, 1873836001u, 414664567u,
36493 2282248934u, 4279200368u, 1711684554u, 285281116u, 2405801727u, 4167216745u, 1634467795u, 376229701u,
36494 2685067896u, 3608007406u, 1308918612u, 956543938u, 2808555105u, 3495958263u, 1231636301u, 1047427035u,
36495 2932959818u, 3654703836u, 1088359270u, 936918000u, 2847714899u, 3736837829u, 1202900863u, 817233897u,
36496 3183342108u, 3401237130u, 1404277552u, 615818150u, 3134207493u, 3453421203u, 1423857449u, 601450431u,
36497 3009837614u, 3294710456u, 1567103746u, 711928724u, 3020668471u, 3272380065u, 1510334235u, 755167117u,
36498 }, {
36499 0u, 421212481u, 842424962u, 724390851u, 1684849924u, 2105013317u, 1448781702u, 1329698503u,
36500 3369699848u, 3519200073u, 4210026634u, 3824474571u, 2897563404u, 3048111693u, 2659397006u, 2274893007u,
36501 1254232657u, 1406739216u, 2029285587u, 1643069842u, 783210325u, 934667796u, 479770071u, 92505238u,
36502 2182846553u, 2600511768u, 2955803355u, 2838940570u, 3866582365u, 4285295644u, 3561045983u, 3445231262u,
36503 2508465314u, 2359236067u, 2813478432u, 3198777185u, 4058571174u, 3908292839u, 3286139684u, 3670389349u,
36504 1566420650u, 1145479147u, 1869335592u, 1987116393u, 959540142u, 539646703u, 185010476u, 303839341u,
36505 3745920755u, 3327985586u, 3983561841u, 4100678960u, 3140154359u, 2721170102u, 2300350837u, 2416418868u,
36506 396344571u, 243568058u, 631889529u, 1018359608u, 1945336319u, 1793607870u, 1103436669u, 1490954812u,
36507 4034481925u, 3915546180u, 3259968903u, 3679722694u, 2484439553u, 2366552896u, 2787371139u, 3208174018u,
36508 950060301u, 565965900u, 177645455u, 328046286u, 1556873225u, 1171730760u, 1861902987u, 2011255754u,
36509 3132841300u, 2745199637u, 2290958294u, 2442530455u, 3738671184u, 3352078609u, 3974232786u, 4126854035u,
36510 1919080284u, 1803150877u, 1079293406u, 1498383519u, 370020952u, 253043481u, 607678682u, 1025720731u,
36511 1711106983u, 2095471334u, 1472923941u, 1322268772u, 26324643u, 411738082u, 866634785u, 717028704u,
36512 2904875439u, 3024081134u, 2668790573u, 2248782444u, 3376948395u, 3495106026u, 4219356713u, 3798300520u,
36513 792689142u, 908347575u, 487136116u, 68299317u, 1263779058u, 1380486579u, 2036719216u, 1618931505u,
36514 3890672638u, 4278043327u, 3587215740u, 3435896893u, 2206873338u, 2593195963u, 2981909624u, 2829542713u,
36515 998479947u, 580430090u, 162921161u, 279890824u, 1609522511u, 1190423566u, 1842954189u, 1958874764u,
36516 4082766403u, 3930137346u, 3245109441u, 3631694208u, 2536953671u, 2385372678u, 2768287173u, 3155920004u,
36517 1900120602u, 1750776667u, 1131931800u, 1517083097u, 355290910u, 204897887u, 656092572u, 1040194781u,
36518 3113746450u, 2692952403u, 2343461520u, 2461357009u, 3723805974u, 3304059991u, 4022511508u, 4141455061u,
36519 2919742697u, 3072101800u, 2620513899u, 2234183466u, 3396041197u, 3547351212u, 4166851439u, 3779471918u,
36520 1725839073u, 2143618976u, 1424512099u, 1307796770u, 45282277u, 464110244u, 813994343u, 698327078u,
36521 3838160568u, 4259225593u, 3606301754u, 3488152955u, 2158586812u, 2578602749u, 2996767038u, 2877569151u,
36522 740041904u, 889656817u, 506086962u, 120682355u, 1215357364u, 1366020341u, 2051441462u, 1667084919u,
36523 3422213966u, 3538019855u, 4190942668u, 3772220557u, 2945847882u, 3062702859u, 2644537544u, 2226864521u,
36524 52649286u, 439905287u, 823476164u, 672009861u, 1733269570u, 2119477507u, 1434057408u, 1281543041u,
36525 2167981343u, 2552493150u, 3004082077u, 2853541596u, 3847487515u, 4233048410u, 3613549209u, 3464057816u,
36526 1239502615u, 1358593622u, 2077699477u, 1657543892u, 764250643u, 882293586u, 532408465u, 111204816u,
36527 1585378284u, 1197851309u, 1816695150u, 1968414767u, 974272232u, 587794345u, 136598634u, 289367339u,
36528 2527558116u, 2411481253u, 2760973158u, 3179948583u, 4073438432u, 3956313505u, 3237863010u, 3655790371u,
36529 347922877u, 229101820u, 646611775u, 1066513022u, 1892689081u, 1774917112u, 1122387515u, 1543337850u,
36530 3697634229u, 3313392372u, 3998419255u, 4148705398u, 3087642289u, 2702352368u, 2319436851u, 2468674930u,
36531 }, {
36532 0u, 29518391u, 59036782u, 38190681u, 118073564u, 114017003u, 76381362u, 89069189u,
36533 236147128u, 265370511u, 228034006u, 206958561u, 152762724u, 148411219u, 178138378u, 190596925u,
36534 472294256u, 501532999u, 530741022u, 509615401u, 456068012u, 451764635u, 413917122u, 426358261u,
36535 305525448u, 334993663u, 296822438u, 275991697u, 356276756u, 352202787u, 381193850u, 393929805u,
36536 944588512u, 965684439u, 1003065998u, 973863097u, 1061482044u, 1049003019u, 1019230802u, 1023561829u,
36537 912136024u, 933002607u, 903529270u, 874031361u, 827834244u, 815125939u, 852716522u, 856752605u,
36538 611050896u, 631869351u, 669987326u, 640506825u, 593644876u, 580921211u, 551983394u, 556069653u,
36539 712553512u, 733666847u, 704405574u, 675154545u, 762387700u, 749958851u, 787859610u, 792175277u,
36540 1889177024u, 1901651959u, 1931368878u, 1927033753u, 2006131996u, 1985040171u, 1947726194u, 1976933189u,
36541 2122964088u, 2135668303u, 2098006038u, 2093965857u, 2038461604u, 2017599123u, 2047123658u, 2076625661u,
36542 1824272048u, 1836991623u, 1866005214u, 1861914857u, 1807058540u, 1786244187u, 1748062722u, 1777547317u,
36543 1655668488u, 1668093247u, 1630251878u, 1625932113u, 1705433044u, 1684323811u, 1713505210u, 1742760333u,
36544 1222101792u, 1226154263u, 1263738702u, 1251046777u, 1339974652u, 1310460363u, 1281013650u, 1301863845u,
36545 1187289752u, 1191637167u, 1161842422u, 1149379777u, 1103966788u, 1074747507u, 1112139306u, 1133218845u,
36546 1425107024u, 1429406311u, 1467333694u, 1454888457u, 1408811148u, 1379576507u, 1350309090u, 1371438805u,
36547 1524775400u, 1528845279u, 1499917702u, 1487177649u, 1575719220u, 1546255107u, 1584350554u, 1605185389u,
36548 3778354048u, 3774312887u, 3803303918u, 3816007129u, 3862737756u, 3892238699u, 3854067506u, 3833203973u,
36549 4012263992u, 4007927823u, 3970080342u, 3982554209u, 3895452388u, 3924658387u, 3953866378u, 3932773565u,
36550 4245928176u, 4241609415u, 4271336606u, 4283762345u, 4196012076u, 4225268251u, 4187931714u, 4166823541u,
36551 4076923208u, 4072833919u, 4035198246u, 4047918865u, 4094247316u, 4123732899u, 4153251322u, 4132437965u,
36552 3648544096u, 3636082519u, 3673983246u, 3678331705u, 3732010428u, 3753090955u, 3723829714u, 3694611429u,
36553 3614117080u, 3601426159u, 3572488374u, 3576541825u, 3496125444u, 3516976691u, 3555094634u, 3525581405u,
36554 3311336976u, 3298595879u, 3336186494u, 3340255305u, 3260503756u, 3281337595u, 3251864226u, 3222399125u,
36555 3410866088u, 3398419871u, 3368647622u, 3372945905u, 3427010420u, 3448139075u, 3485520666u, 3456284973u,
36556 2444203584u, 2423127159u, 2452308526u, 2481530905u, 2527477404u, 2539934891u, 2502093554u, 2497740997u,
36557 2679949304u, 2659102159u, 2620920726u, 2650438049u, 2562027300u, 2574714131u, 2603727690u, 2599670141u,
36558 2374579504u, 2353749767u, 2383274334u, 2412743529u, 2323684844u, 2336421851u, 2298759554u, 2294686645u,
36559 2207933576u, 2186809023u, 2149495014u, 2178734801u, 2224278612u, 2236720739u, 2266437690u, 2262135309u,
36560 2850214048u, 2820717207u, 2858812622u, 2879680249u, 2934667388u, 2938704459u, 2909776914u, 2897069605u,
36561 2817622296u, 2788420399u, 2759153014u, 2780249921u, 2700618180u, 2704950259u, 2742877610u, 2730399645u,
36562 3049550800u, 3020298727u, 3057690558u, 3078802825u, 2999835404u, 3004150075u, 2974355298u, 2961925461u,
36563 3151438440u, 3121956959u, 3092510214u, 3113327665u, 3168701108u, 3172786307u, 3210370778u, 3197646061u,
36564 }, {
36565 0u, 3099354981u, 2852767883u, 313896942u, 2405603159u, 937357362u, 627793884u, 2648127673u,
36566 3316918511u, 2097696650u, 1874714724u, 3607201537u, 1255587768u, 4067088605u, 3772741427u, 1482887254u,
36567 1343838111u, 3903140090u, 4195393300u, 1118632049u, 3749429448u, 1741137837u, 1970407491u, 3452858150u,
36568 2511175536u, 756094997u, 1067759611u, 2266550430u, 449832999u, 2725482306u, 2965774508u, 142231497u,
36569 2687676222u, 412010587u, 171665333u, 2995192016u, 793786473u, 2548850444u, 2237264098u, 1038456711u,
36570 1703315409u, 3711623348u, 3482275674u, 1999841343u, 3940814982u, 1381529571u, 1089329165u, 4166106984u,
36571 4029413537u, 1217896388u, 1512189994u, 3802027855u, 2135519222u, 3354724499u, 3577784189u, 1845280792u,
36572 899665998u, 2367928107u, 2677414085u, 657096608u, 3137160985u, 37822588u, 284462994u, 2823350519u,
36573 2601801789u, 598228824u, 824021174u, 2309093331u, 343330666u, 2898962447u, 3195996129u, 113467524u,
36574 1587572946u, 3860600759u, 4104763481u, 1276501820u, 3519211397u, 1769898208u, 2076913422u, 3279374443u,
36575 3406630818u, 1941006535u, 1627703081u, 3652755532u, 1148164341u, 4241751952u, 3999682686u, 1457141531u,
36576 247015245u, 3053797416u, 2763059142u, 470583459u, 2178658330u, 963106687u, 735213713u, 2473467892u,
36577 992409347u, 2207944806u, 2435792776u, 697522413u, 3024379988u, 217581361u, 508405983u, 2800865210u,
36578 4271038444u, 1177467017u, 1419450215u, 3962007554u, 1911572667u, 3377213406u, 3690561584u, 1665525589u,
36579 1799331996u, 3548628985u, 3241568279u, 2039091058u, 3831314379u, 1558270126u, 1314193216u, 4142438437u,
36580 2928380019u, 372764438u, 75645176u, 3158189981u, 568925988u, 2572515393u, 2346768303u, 861712586u,
36581 3982079547u, 1441124702u, 1196457648u, 4293663189u, 1648042348u, 3666298377u, 3358779879u, 1888390786u,
36582 686661332u, 2421291441u, 2196002399u, 978858298u, 2811169155u, 523464422u, 226935048u, 3040519789u,
36583 3175145892u, 100435649u, 390670639u, 2952089162u, 841119475u, 2325614998u, 2553003640u, 546822429u,
36584 2029308235u, 3225988654u, 3539796416u, 1782671013u, 4153826844u, 1328167289u, 1570739863u, 3844338162u,
36585 1298864389u, 4124540512u, 3882013070u, 1608431339u, 3255406162u, 2058742071u, 1744848601u, 3501990332u,
36586 2296328682u, 811816591u, 584513889u, 2590678532u, 129869501u, 3204563416u, 2914283062u, 352848211u,
36587 494030490u, 2781751807u, 3078325777u, 264757620u, 2450577869u, 715964072u, 941166918u, 2158327331u,
36588 3636881013u, 1618608400u, 1926213374u, 3396585883u, 1470427426u, 4011365959u, 4255988137u, 1158766284u,
36589 1984818694u, 3471935843u, 3695453837u, 1693991400u, 4180638033u, 1100160564u, 1395044826u, 3952793279u,
36590 3019491049u, 189112716u, 435162722u, 2706139399u, 1016811966u, 2217162459u, 2526189877u, 774831696u,
36591 643086745u, 2666061564u, 2354934034u, 887166583u, 2838900430u, 294275499u, 54519365u, 3145957664u,
36592 3823145334u, 1532818963u, 1240029693u, 4048895640u, 1820460577u, 3560857924u, 3331051178u, 2117577167u,
36593 3598663992u, 1858283101u, 2088143283u, 3301633750u, 1495127663u, 3785470218u, 4078182116u, 1269332353u,
36594 332098007u, 2876706482u, 3116540252u, 25085497u, 2628386432u, 605395429u, 916469259u, 2384220526u,
36595 2254837415u, 1054503362u, 745528876u, 2496903497u, 151290352u, 2981684885u, 2735556987u, 464596510u,
36596 1137851976u, 4218313005u, 3923506883u, 1365741990u, 3434129695u, 1946996346u, 1723425172u, 3724871409u,
36597 }, {
36598 0u, 1029712304u, 2059424608u, 1201699536u, 4118849216u, 3370159984u, 2403399072u, 2988497936u,
36599 812665793u, 219177585u, 1253054625u, 2010132753u, 3320900865u, 4170237105u, 3207642721u, 2186319825u,
36600 1625331586u, 1568718386u, 438355170u, 658566482u, 2506109250u, 2818578674u, 4020265506u, 3535817618u,
36601 1351670851u, 1844508147u, 709922595u, 389064339u, 2769320579u, 2557498163u, 3754961379u, 3803185235u,
36602 3250663172u, 4238411444u, 3137436772u, 2254525908u, 876710340u, 153198708u, 1317132964u, 1944187668u,
36603 4054934725u, 3436268917u, 2339452837u, 3054575125u, 70369797u, 961670069u, 2129760613u, 1133623509u,
36604 2703341702u, 2621542710u, 3689016294u, 3867263574u, 1419845190u, 1774270454u, 778128678u, 318858390u,
36605 2438067015u, 2888948471u, 3952189479u, 3606153623u, 1691440519u, 1504803895u, 504432359u, 594620247u,
36606 1492342857u, 1704161785u, 573770537u, 525542041u, 2910060169u, 2417219385u, 3618876905u, 3939730521u,
36607 1753420680u, 1440954936u, 306397416u, 790849880u, 2634265928u, 2690882808u, 3888375336u, 3668168600u,
36608 940822475u, 91481723u, 1121164459u, 2142483739u, 3448989963u, 4042473659u, 3075684971u, 2318603227u,
36609 140739594u, 889433530u, 1923340138u, 1338244826u, 4259521226u, 3229813626u, 2267247018u, 3124975642u,
36610 2570221389u, 2756861693u, 3824297005u, 3734113693u, 1823658381u, 1372780605u, 376603373u, 722643805u,
36611 2839690380u, 2485261628u, 3548540908u, 4007806556u, 1556257356u, 1638052860u, 637716780u, 459464860u,
36612 4191346895u, 3300051327u, 2199040943u, 3195181599u, 206718479u, 825388991u, 1989285231u, 1274166495u,
36613 3382881038u, 4106388158u, 3009607790u, 2382549470u, 1008864718u, 21111934u, 1189240494u, 2072147742u,
36614 2984685714u, 2357631266u, 3408323570u, 4131834434u, 1147541074u, 2030452706u, 1051084082u, 63335554u,
36615 2174155603u, 3170292451u, 4216760371u, 3325460867u, 1947622803u, 1232499747u, 248909555u, 867575619u,
36616 3506841360u, 3966111392u, 2881909872u, 2527485376u, 612794832u, 434546784u, 1581699760u, 1663499008u,
36617 3782634705u, 3692447073u, 2612412337u, 2799048193u, 351717905u, 697754529u, 1849071985u, 1398190273u,
36618 1881644950u, 1296545318u, 182963446u, 931652934u, 2242328918u, 3100053734u, 4284967478u, 3255255942u,
36619 1079497815u, 2100821479u, 983009079u, 133672583u, 3050795671u, 2293717799u, 3474399735u, 4067887175u,
36620 281479188u, 765927844u, 1778867060u, 1466397380u, 3846680276u, 3626469220u, 2676489652u, 2733102084u,
36621 548881365u, 500656741u, 1517752501u, 1729575173u, 3577210133u, 3898068133u, 2952246901u, 2459410373u,
36622 3910527195u, 3564487019u, 2480257979u, 2931134987u, 479546907u, 569730987u, 1716854139u, 1530213579u,
36623 3647316762u, 3825568426u, 2745561210u, 2663766474u, 753206746u, 293940330u, 1445287610u, 1799716618u,
36624 2314567513u, 3029685993u, 4080348217u, 3461678473u, 2088098201u, 1091956777u, 112560889u, 1003856713u,
36625 3112514712u, 2229607720u, 3276105720u, 4263857736u, 1275433560u, 1902492648u, 918929720u, 195422344u,
36626 685033439u, 364179055u, 1377080511u, 1869921551u, 3713294623u, 3761522863u, 2811507327u, 2599689167u,
36627 413436958u, 633644462u, 1650777982u, 1594160846u, 3978570462u, 3494118254u, 2548332990u, 2860797966u,
36628 1211387997u, 1968470509u, 854852413u, 261368461u, 3182753437u, 2161434413u, 3346310653u, 4195650637u,
36629 2017729436u, 1160000044u, 42223868u, 1071931724u, 2378480988u, 2963576044u, 4144295484u, 3395602316u,
36630 }, {
36631 0u, 3411858341u, 1304994059u, 2257875630u, 2609988118u, 1355649459u, 3596215069u, 486879416u,
36632 3964895853u, 655315400u, 2711298918u, 1791488195u, 2009251963u, 3164476382u, 973758832u, 4048990933u,
36633 64357019u, 3364540734u, 1310630800u, 2235723829u, 2554806413u, 1394316072u, 3582976390u, 517157411u,
36634 4018503926u, 618222419u, 2722963965u, 1762783832u, 1947517664u, 3209171269u, 970744811u, 4068520014u,
36635 128714038u, 3438335635u, 1248109629u, 2167961496u, 2621261600u, 1466012805u, 3522553387u, 447296910u,
36636 3959392091u, 547575038u, 2788632144u, 1835791861u, 1886307661u, 3140622056u, 1034314822u, 4143626211u,
36637 75106221u, 3475428360u, 1236444838u, 2196665603u, 2682996155u, 1421317662u, 3525567664u, 427767573u,
36638 3895035328u, 594892389u, 2782995659u, 1857943406u, 1941489622u, 3101955187u, 1047553757u, 4113347960u,
36639 257428076u, 3288652233u, 1116777319u, 2311878850u, 2496219258u, 1603640287u, 3640781169u, 308099796u,
36640 3809183745u, 676813732u, 2932025610u, 1704983215u, 2023410199u, 3016104370u, 894593820u, 4262377657u,
36641 210634999u, 3352484690u, 1095150076u, 2316991065u, 2535410401u, 1547934020u, 3671583722u, 294336591u,
36642 3772615322u, 729897279u, 2903845777u, 1716123700u, 2068629644u, 2953845545u, 914647431u, 4258839074u,
36643 150212442u, 3282623743u, 1161604689u, 2388688372u, 2472889676u, 1480171241u, 3735940167u, 368132066u,
36644 3836185911u, 805002898u, 2842635324u, 1647574937u, 2134298401u, 3026852996u, 855535146u, 4188192143u,
36645 186781121u, 3229539940u, 1189784778u, 2377547631u, 2427670487u, 1542429810u, 3715886812u, 371670393u,
36646 3882979244u, 741170185u, 2864262823u, 1642462466u, 2095107514u, 3082559007u, 824732849u, 4201955092u,
36647 514856152u, 3589064573u, 1400419795u, 2552522358u, 2233554638u, 1316849003u, 3370776517u, 62202976u,
36648 4075001525u, 968836368u, 3207280574u, 1954014235u, 1769133219u, 2720925446u, 616199592u, 4024870413u,
36649 493229635u, 3594175974u, 1353627464u, 2616354029u, 2264355925u, 1303087088u, 3409966430u, 6498043u,
36650 4046820398u, 979978123u, 3170710821u, 2007099008u, 1789187640u, 2717386141u, 661419827u, 3962610838u,
36651 421269998u, 3527459403u, 1423225061u, 2676515648u, 2190300152u, 1238466653u, 3477467891u, 68755798u,
36652 4115633027u, 1041448998u, 3095868040u, 1943789869u, 1860096405u, 2776760880u, 588673182u, 3897205563u,
36653 449450869u, 3516317904u, 1459794558u, 2623431131u, 2170245475u, 1242006214u, 3432247400u, 131015629u,
36654 4137259288u, 1036337853u, 3142660115u, 1879958454u, 1829294862u, 2790523051u, 549483013u, 3952910752u,
36655 300424884u, 3669282065u, 1545650111u, 2541513754u, 2323209378u, 1092980487u, 3350330793u, 216870412u,
36656 4256931033u, 921128828u, 2960342482u, 2066738807u, 1714085583u, 2910195050u, 736264132u, 3770592353u,
36657 306060335u, 3647131530u, 1610005796u, 2494197377u, 2309971513u, 1123257756u, 3295149874u, 255536279u,
36658 4268596802u, 892423655u, 3013951305u, 2029645036u, 1711070292u, 2929725425u, 674528607u, 3815288570u,
36659 373562242u, 3709388839u, 1535949449u, 2429577516u, 2379569556u, 1183418929u, 3223189663u, 188820282u,
36660 4195850735u, 827017802u, 3084859620u, 2089020225u, 1636228089u, 2866415708u, 743340786u, 3876759895u,
36661 361896217u, 3738094268u, 1482340370u, 2466671543u, 2382584591u, 1163888810u, 3284924932u, 144124321u,
36662 4190215028u, 849168593u, 3020503679u, 2136336858u, 1649465698u, 2836138695u, 798521449u, 3838094284u,
36663 }, {
36664 0u, 2792819636u, 2543784233u, 837294749u, 4098827283u, 1379413927u, 1674589498u, 3316072078u,
36665 871321191u, 2509784531u, 2758827854u, 34034938u, 3349178996u, 1641505216u, 1346337629u, 4131942633u,
36666 1742642382u, 3249117050u, 4030828007u, 1446413907u, 2475800797u, 904311657u, 68069876u, 2725880384u,
36667 1412551337u, 4064729373u, 3283010432u, 1708771380u, 2692675258u, 101317902u, 937551763u, 2442587175u,
36668 3485284764u, 1774858792u, 1478633653u, 4266992385u, 1005723023u, 2642744891u, 2892827814u, 169477906u,
36669 4233263099u, 1512406095u, 1808623314u, 3451546982u, 136139752u, 2926205020u, 2676114113u, 972376437u,
36670 2825102674u, 236236518u, 1073525883u, 2576072655u, 1546420545u, 4200303349u, 3417542760u, 1841601500u,
36671 2609703733u, 1039917185u, 202635804u, 2858742184u, 1875103526u, 3384067218u, 4166835727u, 1579931067u,
36672 1141601657u, 3799809741u, 3549717584u, 1977839588u, 2957267306u, 372464350u, 668680259u, 2175552503u,
36673 2011446046u, 3516084394u, 3766168119u, 1175200131u, 2209029901u, 635180217u, 338955812u, 2990736784u,
36674 601221559u, 2242044419u, 3024812190u, 306049834u, 3617246628u, 1911408144u, 1074125965u, 3866285881u,
36675 272279504u, 3058543716u, 2275784441u, 567459149u, 3832906691u, 1107462263u, 1944752874u, 3583875422u,
36676 2343980261u, 767641425u, 472473036u, 3126744696u, 2147051766u, 3649987394u, 3899029983u, 1309766251u,
36677 3092841090u, 506333494u, 801510315u, 2310084639u, 1276520081u, 3932237093u, 3683203000u, 2113813516u,
36678 3966292011u, 1243601823u, 2079834370u, 3716205238u, 405271608u, 3192979340u, 2411259153u, 701492901u,
36679 3750207052u, 2045810168u, 1209569125u, 4000285905u, 734575199u, 2378150379u, 3159862134u, 438345922u,
36680 2283203314u, 778166598u, 529136603u, 3120492655u, 2086260449u, 3660498261u, 3955679176u, 1303499900u,
36681 3153699989u, 495890209u, 744928700u, 2316418568u, 1337360518u, 3921775410u, 3626602927u, 2120129051u,
36682 4022892092u, 1237286280u, 2018993941u, 3726666913u, 461853231u, 3186645403u, 2350400262u, 711936178u,
36683 3693557851u, 2052076527u, 1270360434u, 3989775046u, 677911624u, 2384402428u, 3220639073u, 427820757u,
36684 1202443118u, 3789347034u, 3493118535u, 1984154099u, 3018127229u, 362020041u, 612099668u, 2181885408u,
36685 1950653705u, 3526596285u, 3822816288u, 1168934804u, 2148251930u, 645706414u, 395618355u, 2984485767u,
36686 544559008u, 2248295444u, 3085590153u, 295523645u, 3560598451u, 1917673479u, 1134918298u, 3855773998u,
36687 328860103u, 3052210803u, 2214924526u, 577903450u, 3889505748u, 1101147744u, 1883911421u, 3594338121u,
36688 3424493451u, 1785369663u, 1535282850u, 4260726038u, 944946072u, 2653270060u, 2949491377u, 163225861u,
36689 4294103532u, 1501944408u, 1752023237u, 3457862513u, 196998655u, 2915761739u, 2619532502u, 978710370u,
36690 2881684293u, 229902577u, 1012666988u, 2586515928u, 1603020630u, 4193987810u, 3356702335u, 1852063179u,
36691 2553040162u, 1046169238u, 263412747u, 2848217023u, 1818454321u, 3390333573u, 4227627032u, 1569420204u,
36692 60859927u, 2782375331u, 2487203646u, 843627658u, 4159668740u, 1368951216u, 1617990445u, 3322386585u,
36693 810543216u, 2520310724u, 2815490393u, 27783917u, 3288386659u, 1652017111u, 1402985802u, 4125677310u,
36694 1685994201u, 3255382381u, 4091620336u, 1435902020u, 2419138250u, 910562686u, 128847843u, 2715354199u,
36695 1469150398u, 4058414858u, 3222168983u, 1719234083u, 2749255853u, 94984985u, 876691844u, 2453031472u,
36696 }, {
36697 0u, 3433693342u, 1109723005u, 2391738339u, 2219446010u, 1222643300u, 3329165703u, 180685081u,
36698 3555007413u, 525277995u, 2445286600u, 1567235158u, 1471092047u, 2600801745u, 361370162u, 3642757804u,
36699 2092642603u, 2953916853u, 1050555990u, 4063508168u, 4176560081u, 878395215u, 3134470316u, 1987983410u,
36700 2942184094u, 1676945920u, 3984272867u, 567356797u, 722740324u, 3887998202u, 1764827929u, 2778407815u,
36701 4185285206u, 903635656u, 3142804779u, 2012833205u, 2101111980u, 2979425330u, 1058630609u, 4088621903u,
36702 714308067u, 3862526333u, 1756790430u, 2753330688u, 2933487385u, 1651734407u, 3975966820u, 542535930u,
36703 2244825981u, 1231508451u, 3353891840u, 188896414u, 25648519u, 3442302233u, 1134713594u, 2399689316u,
36704 1445480648u, 2592229462u, 336416693u, 3634843435u, 3529655858u, 516441772u, 2420588879u, 1559052753u,
36705 698204909u, 3845636723u, 1807271312u, 2803025166u, 2916600855u, 1635634313u, 4025666410u, 593021940u,
36706 4202223960u, 919787974u, 3093159461u, 1962401467u, 2117261218u, 2996361020u, 1008193759u, 4038971457u,
36707 1428616134u, 2576151384u, 386135227u, 3685348389u, 3513580860u, 499580322u, 2471098945u, 1608776415u,
36708 2260985971u, 1248454893u, 3303468814u, 139259792u, 42591881u, 3458459159u, 1085071860u, 2349261162u,
36709 3505103035u, 474062885u, 2463016902u, 1583654744u, 1419882049u, 2550902495u, 377792828u, 3660491170u,
36710 51297038u, 3483679632u, 1093385331u, 2374089965u, 2269427188u, 1273935210u, 3311514249u, 164344343u,
36711 2890961296u, 1627033870u, 4000683757u, 585078387u, 672833386u, 3836780532u, 1782552599u, 2794821769u,
36712 2142603813u, 3005188795u, 1032883544u, 4047146438u, 4227826911u, 928351297u, 3118105506u, 1970307900u,
36713 1396409818u, 2677114180u, 287212199u, 3719594553u, 3614542624u, 467372990u, 2505346141u, 1509854403u,
36714 2162073199u, 1282711281u, 3271268626u, 240228748u, 76845205u, 3359543307u, 1186043880u, 2317064054u,
36715 796964081u, 3811226735u, 1839575948u, 2702160658u, 2882189835u, 1734392469u, 3924802934u, 625327592u,
36716 4234522436u, 818917338u, 3191908409u, 1927981223u, 2016387518u, 3028656416u, 973776579u, 4137723485u,
36717 2857232268u, 1726474002u, 3899187441u, 616751215u, 772270454u, 3803048424u, 1814228491u, 2693328533u,
36718 2041117753u, 3036871847u, 999160644u, 4146592730u, 4259508931u, 826864221u, 3217552830u, 1936586016u,
36719 3606501031u, 442291769u, 2496909786u, 1484378436u, 1388107869u, 2652297411u, 278519584u, 3694387134u,
36720 85183762u, 3384397196u, 1194773103u, 2342308593u, 2170143720u, 1307820918u, 3279733909u, 265733131u,
36721 2057717559u, 3054258089u, 948125770u, 4096344276u, 4276898253u, 843467091u, 3167309488u, 1885556270u,
36722 2839764098u, 1709792284u, 3949353983u, 667704161u, 755585656u, 3785577190u, 1865176325u, 2743489947u,
36723 102594076u, 3401021058u, 1144549729u, 2291298815u, 2186770662u, 1325234296u, 3228729243u, 215514885u,
36724 3589828009u, 424832311u, 2547870420u, 1534552650u, 1370645331u, 2635621325u, 328688686u, 3745342640u,
36725 2211456353u, 1333405183u, 3254067740u, 224338562u, 127544219u, 3408931589u, 1170156774u, 2299866232u,
36726 1345666772u, 2627681866u, 303053225u, 3736746295u, 3565105198u, 416624816u, 2522494803u, 1525692365u,
36727 4285207626u, 868291796u, 3176010551u, 1910772649u, 2065767088u, 3079346734u, 956571085u, 4121828691u,
36728 747507711u, 3760459617u, 1856702594u, 2717976604u, 2831417605u, 1684930971u, 3940615800u, 642451174u,
36731 0u, 393942083u, 787884166u, 965557445u, 1575768332u, 1251427663u, 1931114890u, 1684106697u,
36732 3151536664u, 2896410203u, 2502855326u, 2186649309u, 3862229780u, 4048545623u, 3368213394u, 3753496529u,
36733 2898281073u, 3149616690u, 2184604407u, 2504883892u, 4046197629u, 3864463166u, 3755621371u, 3366006712u,
36734 387506281u, 6550570u, 971950319u, 781573292u, 1257550181u, 1569695014u, 1677892067u, 1937345952u,
36735 2196865699u, 2508887776u, 2886183461u, 3145514598u, 3743273903u, 3362179052u, 4058774313u, 3868258154u,
36736 958996667u, 777139448u, 400492605u, 10755198u, 1690661303u, 1941857780u, 1244879153u, 1565019506u,
36737 775012562u, 961205393u, 13101140u, 398261271u, 1943900638u, 1688634781u, 1563146584u, 1246801179u,
36738 2515100362u, 2190636681u, 3139390028u, 2892258831u, 3355784134u, 3749586821u, 3874691904u, 4052225795u,
36739 3734110983u, 3387496260u, 4033096577u, 3877584834u, 2206093835u, 2483373640u, 2911402637u, 3136515790u,
36740 1699389727u, 1915860316u, 1270647193u, 1556585946u, 950464531u, 803071056u, 374397077u, 19647702u,
36741 1917993334u, 1697207605u, 1554278896u, 1272937907u, 800985210u, 952435769u, 21510396u, 372452543u,
36742 3381322606u, 3740399405u, 3883715560u, 4027047851u, 2489758306u, 2199758369u, 3130039012u, 2917895847u,
36743 1550025124u, 1259902439u, 1922410786u, 1710144865u, 26202280u, 385139947u, 796522542u, 939715693u,
36744 3887801276u, 4039129087u, 3377269562u, 3728088953u, 3126293168u, 2905368307u, 2493602358u, 2212122229u,
36745 4037264341u, 3889747862u, 3730172755u, 3375300368u, 2907673305u, 3124004506u, 2209987167u, 2495786524u,
36746 1266377165u, 1543533966u, 1703758155u, 1928748296u, 379007169u, 32253058u, 945887303u, 790236164u,
36747 1716846671u, 1898845196u, 1218652361u, 1608006794u, 1002000707u, 750929152u, 357530053u, 36990342u,
36748 3717046871u, 3405166100u, 4084959953u, 3825245842u, 2153902939u, 2535122712u, 2929187805u, 3119304606u,
36749 3398779454u, 3723384445u, 3831720632u, 4078468859u, 2541294386u, 2147616625u, 3113171892u, 2935238647u,
36750 1900929062u, 1714877541u, 1606142112u, 1220599011u, 748794154u, 1004184937u, 39295404u, 355241455u,
36751 3835986668u, 4091516591u, 3394415210u, 3710500393u, 3108557792u, 2922629027u, 2545875814u, 2160455461u,
36752 1601970420u, 1208431799u, 1904871538u, 1727077425u, 43020792u, 367748539u, 744905086u, 991776061u,
36753 1214562461u, 1595921630u, 1720903707u, 1911159896u, 361271697u, 49513938u, 998160663u, 738569556u,
36754 4089209477u, 3838277318u, 3712633347u, 3392233024u, 2924491657u, 3106613194u, 2158369551u, 2547846988u,
36755 3100050248u, 2948339467u, 2519804878u, 2169126797u, 3844821572u, 4065347079u, 3420289730u, 3701894785u,
36756 52404560u, 342144275u, 770279894u, 982687125u, 1593045084u, 1233708063u, 1879431386u, 1736363161u,
36757 336019769u, 58479994u, 988899775u, 764050940u, 1240141877u, 1586496630u, 1729968307u, 1885744368u,
36758 2950685473u, 3097818978u, 2166999975u, 2522013668u, 4063474221u, 3846743662u, 3703937707u, 3418263272u,
36759 976650731u, 760059304u, 348170605u, 62635310u, 1742393575u, 1889649828u, 1227683937u, 1582820386u,
36760 2179867635u, 2526361520u, 2937588597u, 3093503798u, 3691148031u, 3413731004u, 4076100217u, 3851374138u,
36761 2532754330u, 2173556697u, 3087067932u, 2944139103u, 3407516310u, 3697379029u, 3857496592u, 4070026835u,
36762 758014338u, 978679233u, 64506116u, 346250567u, 1891774606u, 1740186829u, 1580472328u, 1229917259u,
36763 }, {
36764 0u, 4022496062u, 83218493u, 3946298115u, 166436986u, 3861498692u, 220098631u, 3806075769u,
36765 332873972u, 4229245898u, 388141257u, 4175494135u, 440197262u, 4127099824u, 516501683u, 4044053389u,
36766 665747944u, 3362581206u, 593187285u, 3432594155u, 776282514u, 3246869164u, 716239279u, 3312622225u,
36767 880394524u, 3686509090u, 814485793u, 3746462239u, 1033003366u, 3528460888u, 963096923u, 3601193573u,
36768 1331495888u, 2694801646u, 1269355501u, 2758457555u, 1186374570u, 2843003028u, 1111716759u, 2910918825u,
36769 1552565028u, 3007850522u, 1484755737u, 3082680359u, 1432478558u, 3131279456u, 1368666979u, 3193329757u,
36770 1760789048u, 2268195078u, 1812353541u, 2210675003u, 1628971586u, 2396670332u, 1710092927u, 2318375233u,
36771 2066006732u, 2498144754u, 2144408305u, 2417195471u, 1926193846u, 2634877320u, 1983558283u, 2583222709u,
36772 2662991776u, 1903717534u, 2588923805u, 1972223139u, 2538711002u, 2022952164u, 2477029351u, 2087066841u,
36773 2372749140u, 1655647338u, 2308478825u, 1717238871u, 2223433518u, 1799654416u, 2155034387u, 1873894445u,
36774 3105130056u, 1456926070u, 3185661557u, 1378041163u, 2969511474u, 1597852940u, 3020617231u, 1539874097u,
36775 2864957116u, 1157737858u, 2922780289u, 1106542015u, 2737333958u, 1290407416u, 2816325371u, 1210047941u,
36776 3521578096u, 1042640718u, 3574781005u, 986759027u, 3624707082u, 936300340u, 3707335735u, 859512585u,
36777 3257943172u, 770846650u, 3334837433u, 688390023u, 3420185854u, 605654976u, 3475911875u, 552361981u,
36778 4132013464u, 428600998u, 4072428965u, 494812827u, 4288816610u, 274747100u, 4216845791u, 345349857u,
36779 3852387692u, 173846098u, 3781891409u, 245988975u, 3967116566u, 62328360u, 3900749099u, 121822741u,
36780 3859089665u, 164061759u, 3807435068u, 221426178u, 4025395579u, 2933317u, 3944446278u, 81334904u,
36781 4124199413u, 437265099u, 4045904328u, 518386422u, 4231653775u, 335250097u, 4174133682u, 386814604u,
36782 3249244393u, 778691543u, 3311294676u, 714879978u, 3359647891u, 662848429u, 3434477742u, 595039120u,
36783 3531393053u, 1035903779u, 3599308832u, 961245982u, 3684132967u, 877986649u, 3747788890u, 815846244u,
36784 2841119441u, 1184522735u, 2913852140u, 1114616274u, 2696129195u, 1332855189u, 2756082326u, 1266946472u,
36785 3129952805u, 1431118107u, 3195705880u, 1371074854u, 3009735263u, 1554415969u, 3079748194u, 1481855324u,
36786 2398522169u, 1630855175u, 2315475716u, 1707159610u, 2266835779u, 1759461501u, 2213084030u, 1814728768u,
36787 2636237773u, 1927520499u, 2580814832u, 1981182158u, 2496293815u, 2064121993u, 2420095882u, 2147340468u,
36788 2025787041u, 2541577631u, 2085281436u, 2475210146u, 1901375195u, 2660681189u, 1973518054u, 2590184920u,
36789 1801997909u, 2225743211u, 1872600680u, 2153772374u, 1652813359u, 2369881361u, 1719025170u, 2310296876u,
36790 1594986313u, 2966676599u, 1541693300u, 3022402634u, 1459236659u, 3107472397u, 1376780046u, 3184366640u,
36791 1288097725u, 2734990467u, 1211309952u, 2817619134u, 1160605639u, 2867791097u, 1104723962u, 2920993988u,
36792 937561457u, 3626001999u, 857201996u, 3704993394u, 1040821515u, 3519792693u, 989625654u, 3577615880u,
36793 607473029u, 3421972155u, 549494200u, 3473077894u, 769584639u, 3256649409u, 690699714u, 3337180924u,
36794 273452185u, 4287555495u, 347692196u, 4219156378u, 430386403u, 4133832669u, 491977950u, 4069562336u,
36795 60542061u, 3965298515u, 124656720u, 3903616878u, 175139863u, 3853649705u, 243645482u, 3779581716u,
36796 }, {
36797 0u, 3247366080u, 1483520449u, 2581751297u, 2967040898u, 1901571138u, 3904227907u, 691737987u,
36798 3133399365u, 2068659845u, 3803142276u, 589399876u, 169513671u, 3415493895u, 1383475974u, 2482566342u,
36799 2935407819u, 1870142219u, 4137319690u, 924099274u, 506443593u, 3751897225u, 1178799752u, 2278412616u,
36800 339027342u, 3585866318u, 1280941135u, 2379694991u, 2766951948u, 1700956620u, 4236308429u, 1024339981u,
36801 2258407383u, 1192382487u, 3740284438u, 528411094u, 910556245u, 4157285269u, 1848198548u, 2946996820u,
36802 1012887186u, 4258378066u, 1681119059u, 2780629139u, 2357599504u, 1292419792u, 3572147409u, 358906641u,
36803 678054684u, 3924071644u, 1879503581u, 2978491677u, 2561882270u, 1497229150u, 3235873119u, 22109855u,
36804 2460592729u, 1395094937u, 3401913240u, 189516888u, 577821147u, 3825075739u, 2048679962u, 3146956762u,
36805 3595049455u, 398902831u, 2384764974u, 1336573934u, 1720805997u, 2803873197u, 1056822188u, 4285729900u,
36806 1821112490u, 2902796138u, 887570795u, 4117339819u, 3696397096u, 500978920u, 2218668777u, 1169222953u,
36807 2025774372u, 3106931428u, 550659301u, 3780950821u, 3362238118u, 166293862u, 2416645991u, 1367722151u,
36808 3262987361u, 66315169u, 2584839584u, 1537170016u, 1923370979u, 3005911075u, 717813282u, 3947244002u,
36809 1356109368u, 2438613496u, 146288633u, 3375820857u, 3759007162u, 562248314u, 3093388411u, 2045739963u,
36810 3927406461u, 731490493u, 2994458300u, 1945440636u, 1523451135u, 2604718911u, 44219710u, 3274466046u,
36811 4263662323u, 1068272947u, 2790189874u, 1740649714u, 1325080945u, 2406874801u, 379033776u, 3608758128u,
36812 1155642294u, 2238671990u, 479005303u, 3708016055u, 4097359924u, 901128180u, 2891217397u, 1843045941u,
36813 2011248031u, 3060787807u, 797805662u, 3993195422u, 3342353949u, 112630237u, 2673147868u, 1591353372u,
36814 3441611994u, 212601626u, 2504944923u, 1421914843u, 2113644376u, 3161815192u, 630660761u, 3826893145u,
36815 3642224980u, 412692116u, 2172340373u, 1089836885u, 1775141590u, 2822790422u, 832715543u, 4029474007u,
36816 1674842129u, 2723860433u, 1001957840u, 4197873168u, 3540870035u, 310623315u, 2338445906u, 1257178514u,
36817 4051548744u, 821257608u, 2836464521u, 1755307081u, 1101318602u, 2150241802u, 432566283u, 3628511179u,
36818 1270766349u, 2318435533u, 332587724u, 3529260300u, 4217841807u, 988411727u, 2735444302u, 1652903566u,
36819 1602977411u, 2651169091u, 132630338u, 3328776322u, 4015131905u, 786223809u, 3074340032u, 1991273216u,
36820 3846741958u, 616972294u, 3173262855u, 2091579847u, 1435626564u, 2485072772u, 234706309u, 3430124101u,
36821 2712218736u, 1613231024u, 4190475697u, 944458353u, 292577266u, 3506339890u, 1226630707u, 2291284467u,
36822 459984181u, 3672380149u, 1124496628u, 2189994804u, 2880683703u, 1782407543u, 4091479926u, 844224694u,
36823 257943739u, 3469817723u, 1462980986u, 2529005242u, 3213269817u, 2114471161u, 3890881272u, 644152632u,
36824 3046902270u, 1947391550u, 3991973951u, 746483711u, 88439420u, 3301680572u, 1563018173u, 2628197501u,
36825 657826727u, 3871046759u, 2136545894u, 3201811878u, 2548879397u, 1449267173u, 3481299428u, 235845156u,
36826 2650161890u, 1551408418u, 3315268387u, 68429027u, 758067552u, 3970035360u, 1967360161u, 3033356129u,
36827 2311284588u, 1213053100u, 3517963949u, 270598509u, 958010606u, 4170500910u, 1635167535u, 2700636911u,
36828 855672361u, 4069415401u, 1802256360u, 2866995240u, 2212099499u, 1113008747u, 3686091882u, 440112042u,
36829 }, {
36830 0u, 2611301487u, 3963330207u, 2006897392u, 50740095u, 2560849680u, 4013794784u, 1956178319u,
36831 101480190u, 2645113489u, 3929532513u, 1905435662u, 84561281u, 2662269422u, 3912356638u, 1922342769u,
36832 202960380u, 2545787283u, 3760419683u, 2072395532u, 253679235u, 2495322860u, 3810871324u, 2021655667u,
36833 169122562u, 2444351341u, 3861841309u, 2106214898u, 152215677u, 2461527058u, 3844685538u, 2123133581u,
36834 405920760u, 2207553431u, 4094313831u, 1873742088u, 456646791u, 2157096168u, 4144791064u, 1823027831u,
36835 507358470u, 2241388905u, 4060492697u, 1772322806u, 490444409u, 2258557462u, 4043311334u, 1789215881u,
36836 338245124u, 2408348267u, 4161972379u, 1672996084u, 388959611u, 2357870868u, 4212429796u, 1622269835u,
36837 304431354u, 2306870421u, 4263435877u, 1706791434u, 287538053u, 2324051946u, 4246267162u, 1723705717u,
36838 811841520u, 2881944479u, 3696765295u, 1207788800u, 862293135u, 2831204576u, 3747484176u, 1157324415u,
36839 913293582u, 2915732833u, 3662962577u, 1106318334u, 896137841u, 2932651550u, 3646055662u, 1123494017u,
36840 1014716940u, 2816349795u, 3493905555u, 1273334012u, 1065181555u, 2765630748u, 3544645612u, 1222882179u,
36841 980888818u, 2714919069u, 3595350637u, 1307180546u, 963712909u, 2731826146u, 3578431762u, 1324336509u,
36842 676490248u, 3019317351u, 3295277719u, 1607253752u, 726947703u, 2968591128u, 3345992168u, 1556776327u,
36843 777919222u, 3053147801u, 3261432937u, 1505806342u, 760750473u, 3070062054u, 3244539670u, 1522987897u,
36844 608862708u, 3220163995u, 3362856811u, 1406423812u, 659339915u, 3169449700u, 3413582868u, 1355966587u,
36845 575076106u, 3118709605u, 3464325525u, 1440228858u, 557894773u, 3135602714u, 3447411434u, 1457397381u,
36846 1623683040u, 4217512847u, 2365387135u, 391757072u, 1673614495u, 4167309552u, 2415577600u, 341804655u,
36847 1724586270u, 4251866481u, 2331019137u, 290835438u, 1707942497u, 4268256782u, 2314648830u, 307490961u,
36848 1826587164u, 4152020595u, 2162433155u, 457265388u, 1876539747u, 4101829900u, 2212636668u, 407333779u,
36849 1792275682u, 4051089549u, 2263378557u, 491595282u, 1775619997u, 4067460082u, 2246988034u, 508239213u,
36850 2029433880u, 3813931127u, 2496473735u, 258500328u, 2079362919u, 3763716872u, 2546668024u, 208559511u,
36851 2130363110u, 3848244873u, 2462145657u, 157552662u, 2113730969u, 3864638966u, 2445764358u, 174205801u,
36852 1961777636u, 4014675339u, 2564147067u, 57707284u, 2011718299u, 3964481268u, 2614361092u, 7778411u,
36853 1927425818u, 3913769845u, 2665066885u, 92077546u, 1910772837u, 3930150922u, 2648673018u, 108709525u,
36854 1352980496u, 3405878399u, 3164554895u, 658115296u, 1403183983u, 3355946752u, 3214507504u, 607924639u,
36855 1453895406u, 3440239233u, 3130208369u, 557218846u, 1437504913u, 3456883198u, 3113552654u, 573589345u,
36856 1555838444u, 3340335491u, 2961681267u, 723707676u, 1606028947u, 3290383100u, 3011612684u, 673504355u,
36857 1521500946u, 3239382909u, 3062619533u, 758026722u, 1505130605u, 3256038402u, 3045975794u, 774417053u,
36858 1217725416u, 3543158663u, 2762906999u, 1057739032u, 1267939479u, 3493229816u, 2812847624u, 1007544935u,
36859 1318679830u, 3577493881u, 2728586121u, 956803046u, 1302285929u, 3594125830u, 2711933174u, 973184153u,
36860 1150152212u, 3743982203u, 2830528651u, 856898788u, 1200346475u, 3694041348u, 2880457716u, 806684571u,
36861 1115789546u, 3643069573u, 2931426933u, 891243034u, 1099408277u, 3659722746u, 2914794762u, 907637093u,
36862 }, {
36863 0u, 3717650821u, 1616688459u, 3184159950u, 3233376918u, 489665299u, 2699419613u, 2104690264u,
36864 1510200173u, 2274691816u, 979330598u, 3888758691u, 2595928571u, 1194090622u, 4209380528u, 661706037u,
36865 3020400346u, 1771143007u, 3562738577u, 164481556u, 1958661196u, 2837976521u, 350386439u, 3379863682u,
36866 3993269687u, 865250354u, 2388181244u, 1406015865u, 784146209u, 4079732388u, 1323412074u, 2474079215u,
36867 3011398645u, 1860735600u, 3542286014u, 246687547u, 1942430051u, 2924607718u, 328963112u, 3456978349u,
36868 3917322392u, 887832861u, 2300653011u, 1421341782u, 700772878u, 4099025803u, 1234716485u, 2483986112u,
36869 125431087u, 3673109674u, 1730500708u, 3132326369u, 3351283641u, 441867836u, 2812031730u, 2047535991u,
36870 1568292418u, 2163009479u, 1025936137u, 3769651852u, 2646824148u, 1079348561u, 4255113631u, 537475098u,
36871 3180171691u, 1612400686u, 3721471200u, 4717925u, 2100624189u, 2694980280u, 493375094u, 3237910515u,
36872 3884860102u, 974691139u, 2278750093u, 1514417672u, 657926224u, 4204917205u, 1198234907u, 2600289438u,
36873 160053105u, 3558665972u, 1775665722u, 3024116671u, 3375586791u, 346391650u, 2842683564u, 1962488105u,
36874 1401545756u, 2384412057u, 869618007u, 3997403346u, 2469432970u, 1319524111u, 4083956673u, 788193860u,
36875 250862174u, 3546612699u, 1856990997u, 3006903952u, 3461001416u, 333211981u, 2920678787u, 1937824774u,
36876 1425017139u, 2305216694u, 883735672u, 3912918525u, 2487837605u, 1239398944u, 4095071982u, 696455019u,
36877 3136584836u, 1734518017u, 3668494799u, 121507914u, 2051872274u, 2816200599u, 437363545u, 3347544796u,
36878 3774328809u, 1029797484u, 2158697122u, 1564328743u, 542033279u, 4258798842u, 1074950196u, 2642717105u,
36879 2691310871u, 2113731730u, 3224801372u, 497043929u, 1624461185u, 3175454212u, 9435850u, 3709412175u,
36880 4201248378u, 671035391u, 2587181873u, 1201904308u, 986750188u, 3880142185u, 1519135143u, 2266689570u,
36881 342721485u, 3388693064u, 1949382278u, 2846355203u, 3570723163u, 155332830u, 3028835344u, 1763607957u,
36882 1315852448u, 2482538789u, 775087595u, 4087626862u, 2396469814u, 1396827059u, 4002123645u, 857560824u,
36883 320106210u, 3464673127u, 1934154665u, 2933785132u, 3551331444u, 238804465u, 3018961215u, 1852270778u,
36884 1226292623u, 2491507722u, 692783300u, 4108177729u, 2309936921u, 1412959900u, 3924976210u, 879016919u,
36885 2803091512u, 2055541181u, 3343875443u, 450471158u, 1739236014u, 3124525867u, 133568485u, 3663777376u,
36886 4245691221u, 545702608u, 2639048222u, 1088059291u, 1034514883u, 3762268230u, 1576387720u, 2153979149u,
36887 501724348u, 3228659001u, 2109407735u, 2687359090u, 3713981994u, 13109167u, 3171052385u, 1620357860u,
36888 1206151121u, 2591211092u, 666423962u, 4197321503u, 2271022407u, 1523307714u, 3875649548u, 982999433u,
36889 2850034278u, 1953942499u, 3384583981u, 338329256u, 1767471344u, 3033506165u, 151375291u, 3566408766u,
36890 4091789579u, 779425934u, 2478797888u, 1311354309u, 861580189u, 4006375960u, 1392910038u, 2391852883u,
36891 2929327945u, 1930372812u, 3469036034u, 324244359u, 1847629279u, 3015068762u, 243015828u, 3555391761u,
36892 4103744548u, 688715169u, 2496043375u, 1229996266u, 874727090u, 3920994103u, 1417671673u, 2313759356u,
36893 446585235u, 3339223062u, 2059594968u, 2807313757u, 3660002053u, 129100416u, 3128657486u, 1743609803u,
36894 1084066558u, 2634765179u, 549535669u, 4250396208u, 2149900392u, 1571961325u, 3765982499u, 1039043750u,
36895 }, {
36896 0u, 2635063670u, 3782132909u, 2086741467u, 430739227u, 2225303149u, 4173482934u, 1707977408u,
36897 861478454u, 2924937024u, 3526875803u, 1329085421u, 720736557u, 3086643291u, 3415954816u, 1452586230u,
36898 1722956908u, 4223524122u, 2279405761u, 450042295u, 2132718455u, 3792785921u, 2658170842u, 58693292u,
36899 1441473114u, 3370435372u, 3028674295u, 696911745u, 1279765825u, 3511176247u, 2905172460u, 807831706u,
36900 3445913816u, 1349228974u, 738901109u, 2969918723u, 3569940419u, 1237784245u, 900084590u, 2829701656u,
36901 4265436910u, 1664255896u, 525574723u, 2187084597u, 3885099509u, 2057177219u, 117386584u, 2616249390u,
36902 2882946228u, 920233410u, 1253605401u, 3619119471u, 2994391983u, 796207833u, 1393823490u, 3457937012u,
36903 2559531650u, 92322804u, 2044829231u, 3840835417u, 2166609305u, 472659183u, 1615663412u, 4249022530u,
36904 1102706673u, 3702920839u, 2698457948u, 1037619754u, 1477802218u, 3306854812u, 3111894087u, 611605809u,
36905 1927342535u, 4025419953u, 2475568490u, 243387420u, 1800169180u, 4131620778u, 2317525617u, 388842247u,
36906 655084445u, 3120835307u, 3328511792u, 1533734470u, 1051149446u, 2745738736u, 3754524715u, 1120297309u,
36907 340972971u, 2304586973u, 4114354438u, 1748234352u, 234773168u, 2431761350u, 3968900637u, 1906278251u,
36908 2363330345u, 299003487u, 1840466820u, 4038896370u, 2507210802u, 142532932u, 1948239007u, 3910149609u,
36909 3213136159u, 579563625u, 1592415666u, 3286611140u, 2787646980u, 992477042u, 1195825833u, 3662232543u,
36910 3933188933u, 2002801203u, 184645608u, 2517538462u, 4089658462u, 1858919720u, 313391347u, 2409765253u,
36911 3644239219u, 1144605701u, 945318366u, 2773977256u, 3231326824u, 1570095902u, 569697989u, 3170568115u,
36912 2205413346u, 511446676u, 1646078799u, 4279421497u, 2598330617u, 131105167u, 2075239508u, 3871229218u,
36913 2955604436u, 757403810u, 1363424633u, 3427521551u, 2844163791u, 881434553u, 1223211618u, 3588709140u,
36914 3854685070u, 2026779384u, 78583587u, 2577462869u, 4235025557u, 1633861091u, 486774840u, 2148301134u,
36915 3600338360u, 1268198606u, 938871061u, 2868504675u, 3476308643u, 1379640277u, 777684494u, 3008718712u,
36916 1310168890u, 3541595724u, 2943964055u, 846639841u, 1471879201u, 3400857943u, 3067468940u, 735723002u,
36917 2102298892u, 3762382970u, 2619362721u, 19901655u, 1692534295u, 4193118049u, 2240594618u, 411247564u,
36918 681945942u, 3047836192u, 3385552891u, 1422167693u, 822682701u, 2886124859u, 3496468704u, 1298661782u,
36919 469546336u, 2264093718u, 4203901389u, 1738379451u, 38812283u, 2673859341u, 3812556502u, 2117148576u,
36920 3268024339u, 1606809957u, 598006974u, 3198893512u, 3680933640u, 1181316734u, 973624229u, 2802299603u,
36921 4052944421u, 1822222163u, 285065864u, 2381456382u, 3896478014u, 1966106696u, 156323219u, 2489232613u,
36922 2759337087u, 964150537u, 1159127250u, 3625517476u, 3184831332u, 551242258u, 1555722185u, 3249901247u,
36923 2535537225u, 170842943u, 1984954084u, 3946848146u, 2391651666u, 327308324u, 1877176831u, 4075589769u,
36924 263086283u, 2460058045u, 4005602406u, 1942963472u, 369291216u, 2332888742u, 4151061373u, 1784924683u,
36925 1022852861u, 2717425547u, 3717839440u, 1083595558u, 626782694u, 3092517008u, 3291821387u, 1497027645u,
36926 1763466407u, 4094934481u, 2289211402u, 360544636u, 1890636732u, 3988730570u, 2447251217u, 215086695u,
36927 1514488465u, 3343557607u, 3140191804u, 639919946u, 1139395978u, 3739626748u, 2726758695u, 1065936977u,
36928 }, {
36929 0u, 3120290792u, 2827399569u, 293431929u, 2323408227u, 864534155u, 586863858u, 2600537882u,
36930 3481914503u, 1987188591u, 1729068310u, 3740575486u, 1173727716u, 4228805132u, 3983743093u, 1418249117u,
36931 1147313999u, 4254680231u, 3974377182u, 1428157750u, 3458136620u, 2011505092u, 1721256893u, 3747844181u,
36932 2347455432u, 839944224u, 594403929u, 2593536433u, 26687147u, 3094146371u, 2836498234u, 283794642u,
36933 2294627998u, 826205558u, 541298447u, 2578994407u, 45702141u, 3141697557u, 2856315500u, 331624836u,
36934 1196225049u, 4273416689u, 4023010184u, 1446090848u, 3442513786u, 1959480466u, 1706436331u, 3696098563u,
36935 3433538001u, 1968994873u, 1679888448u, 3722103720u, 1188807858u, 4280295258u, 3999102243u, 1470541515u,
36936 53374294u, 3134568126u, 2879970503u, 307431215u, 2303854645u, 816436189u, 567589284u, 2553242188u,
36937 3405478781u, 1929420949u, 1652411116u, 3682996484u, 1082596894u, 4185703926u, 3892424591u, 1375368295u,
36938 91404282u, 3163122706u, 2918450795u, 336584067u, 2400113305u, 922028401u, 663249672u, 2658384096u,
36939 2392450098u, 929185754u, 639587747u, 2682555979u, 82149713u, 3172883129u, 2892181696u, 362343208u,
36940 1091578037u, 4176212829u, 3918960932u, 1349337804u, 3412872662u, 1922537022u, 1676344391u, 3658557359u,
36941 1111377379u, 4224032267u, 3937989746u, 1396912026u, 3359776896u, 1908013928u, 1623494929u, 3644803833u,
36942 2377615716u, 877417100u, 623982837u, 2630542109u, 130804743u, 3190831087u, 2941083030u, 381060734u,
36943 106748588u, 3215393092u, 2933549885u, 388083925u, 2350956495u, 903570471u, 614862430u, 2640172470u,
36944 3386185259u, 1882115523u, 1632872378u, 3634920530u, 1135178568u, 4199721120u, 3945775833u, 1389631793u,
36945 1317531835u, 4152109907u, 3858841898u, 1610259138u, 3304822232u, 2097172016u, 1820140617u, 3582394273u,
36946 2165193788u, 955639764u, 696815021u, 2423477829u, 192043359u, 2995356343u, 2750736590u, 437203750u,
36947 182808564u, 3005133852u, 2724453989u, 462947725u, 2157513367u, 962777471u, 673168134u, 2447663342u,
36948 3312231283u, 2090301595u, 1844056802u, 3557935370u, 1326499344u, 4142603768u, 3885397889u, 1584245865u,
36949 3326266917u, 2142836173u, 1858371508u, 3611272284u, 1279175494u, 4123357358u, 3837270743u, 1564721471u,
36950 164299426u, 2955991370u, 2706223923u, 414607579u, 2209834945u, 978107433u, 724686416u, 2462715320u,
36951 2183156074u, 1004243586u, 715579643u, 2472360723u, 140260361u, 2980573153u, 2698675608u, 421617264u,
36952 1302961645u, 4099032581u, 3845074044u, 1557460884u, 3352688782u, 2116952934u, 1867729183u, 3601371895u,
36953 2222754758u, 1032278062u, 754596439u, 2499928511u, 234942117u, 3086693709u, 2793824052u, 528319708u,
36954 1274365761u, 4061043881u, 3816027856u, 1518873912u, 3246989858u, 2020800970u, 1762628531u, 3505670235u,
36955 3223196809u, 2045103969u, 1754834200u, 3512958704u, 1247965674u, 4086934018u, 3806642299u, 1528765331u,
36956 261609486u, 3060532198u, 2802936223u, 518697591u, 2246819181u, 1007707781u, 762121468u, 2492913428u,
36957 213497176u, 3041029808u, 2755593417u, 499441441u, 2261110843u, 1061030867u, 776167850u, 2545465922u,
36958 3274734047u, 2060165687u, 1807140942u, 3528266662u, 1229724860u, 4038575956u, 3788156205u, 1479636677u,
36959 1222322711u, 4045468159u, 3764231046u, 1504067694u, 3265744756u, 2069664924u, 1780612837u, 3554288909u,
36960 2270357136u, 1051278712u, 802445057u, 2519698665u, 221152243u, 3033880603u, 2779263586u, 475261322u,
36961 }, {
36962 0u, 2926088593u, 2275419491u, 701019378u, 3560000647u, 2052709654u, 1402038756u, 4261017717u,
36963 1930665807u, 3715829470u, 4105419308u, 1524313021u, 2804077512u, 155861593u, 545453739u, 2397726522u,
36964 3861331614u, 1213181711u, 1636244477u, 3488582252u, 840331801u, 2625561480u, 3048626042u, 467584747u,
36965 2503254481u, 995897408u, 311723186u, 3170637091u, 1090907478u, 4016929991u, 3332753461u, 1758288292u,
36966 390036349u, 3109546732u, 2426363422u, 1056427919u, 3272488954u, 1835443819u, 1152258713u, 3938878216u,
36967 1680663602u, 3393484195u, 3817652561u, 1306808512u, 2954733749u, 510998820u, 935169494u, 2580880455u,
36968 4044899811u, 1601229938u, 1991794816u, 3637571857u, 623446372u, 2336332021u, 2726898695u, 216120726u,
36969 2181814956u, 744704829u, 95158223u, 2881711710u, 1446680107u, 4166125498u, 3516576584u, 2146575065u,
36970 780072698u, 2148951915u, 2849952665u, 129384968u, 4199529085u, 1411853292u, 2112855838u, 3548843663u,
36971 1567451573u, 4077254692u, 3670887638u, 1957027143u, 2304517426u, 657765539u, 251396177u, 2694091200u,
36972 3361327204u, 1714510325u, 1341779207u, 3784408214u, 476611811u, 2986349938u, 2613617024u, 899690513u,
36973 3142211371u, 354600634u, 1021997640u, 2458051545u, 1870338988u, 3239283261u, 3906682575u, 1186180958u,
36974 960597383u, 2536053782u, 3202459876u, 277428597u, 3983589632u, 1125666961u, 1792074851u, 3300423154u,
36975 1246892744u, 3829039961u, 3455203243u, 1671079482u, 2657312335u, 806080478u, 432241452u, 3081497277u,
36976 3748049689u, 1896751752u, 1489409658u, 4138600427u, 190316446u, 2772397583u, 2365053693u, 580864876u,
36977 2893360214u, 35503559u, 735381813u, 2243795108u, 2017747153u, 3593269568u, 4293150130u, 1368183843u,
36978 1560145396u, 4069882981u, 3680356503u, 1966430470u, 2295112051u, 648294626u, 258769936u, 2701399425u,
36979 804156091u, 2173100842u, 2823706584u, 103204425u, 4225711676u, 1438101421u, 2088704863u, 3524758222u,
36980 3134903146u, 347226875u, 1031468553u, 2467456920u, 1860935661u, 3229814396u, 3914054286u, 1193487135u,
36981 3385412645u, 1738661300u, 1315531078u, 3758225623u, 502792354u, 3012596019u, 2589468097u, 875607120u,
36982 1271043721u, 3853125400u, 3429020650u, 1644831355u, 2683558414u, 832261023u, 408158061u, 3057348348u,
36983 953223622u, 2528745559u, 3211865253u, 286899508u, 3974120769u, 1116263632u, 1799381026u, 3307794867u,
36984 2917509143u, 59586950u, 709201268u, 2217549029u, 2043995280u, 3619452161u, 4269064691u, 1344032866u,
36985 3740677976u, 1889445577u, 1498812987u, 4148069290u, 180845535u, 2762992206u, 2372361916u, 588238637u,
36986 1921194766u, 3706423967u, 4112727661u, 1531686908u, 2796705673u, 148555288u, 554857194u, 2407195515u,
36987 26248257u, 2952271312u, 2251333922u, 676868275u, 3584149702u, 2076793175u, 1375858085u, 4234771508u,
36988 2493785488u, 986493953u, 319029491u, 3178008930u, 1083533591u, 4009621638u, 3342158964u, 1767759333u,
36989 3887577823u, 1239362382u, 1612160956u, 3464433197u, 864482904u, 2649647049u, 3022443323u, 441336490u,
36990 1706844275u, 3419730402u, 3793503504u, 1282724993u, 2978819316u, 535149925u, 908921239u, 2554697734u,
36991 380632892u, 3100077741u, 2433735263u, 1063734222u, 3265180603u, 1828069930u, 1161729752u, 3948283721u,
36992 2207997677u, 770953084u, 71007118u, 2857626143u, 1470763626u, 4190274555u, 3490330377u, 2120394392u,
36993 4035494306u, 1591758899u, 1999168705u, 3644880208u, 616140069u, 2328960180u, 2736367686u, 225524183u,
36997 // ---------------- Private Initializer Prototypes
36999 // ---------------- Private Function Prototypes
37001 WUFFS_BASE__GENERATED_C_CODE
37002 static wuffs_base__empty_struct
37003 wuffs_crc32__ieee_hasher__up(
37004 wuffs_crc32__ieee_hasher* self,
37005 wuffs_base__slice_u8 a_x);
37007 WUFFS_BASE__GENERATED_C_CODE
37008 static wuffs_base__empty_struct
37009 wuffs_crc32__ieee_hasher__up__choosy_default(
37010 wuffs_crc32__ieee_hasher* self,
37011 wuffs_base__slice_u8 a_x);
37013 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_CRC32)
37014 WUFFS_BASE__GENERATED_C_CODE
37015 static wuffs_base__empty_struct
37016 wuffs_crc32__ieee_hasher__up_arm_crc32(
37017 wuffs_crc32__ieee_hasher* self,
37018 wuffs_base__slice_u8 a_x);
37019 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_CRC32)
37021 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
37022 WUFFS_BASE__GENERATED_C_CODE
37023 static wuffs_base__empty_struct
37024 wuffs_crc32__ieee_hasher__up_x86_sse42(
37025 wuffs_crc32__ieee_hasher* self,
37026 wuffs_base__slice_u8 a_x);
37027 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
37029 // ---------------- VTables
37031 const wuffs_base__hasher_u32__func_ptrs
37032 wuffs_crc32__ieee_hasher__func_ptrs_for__wuffs_base__hasher_u32 = {
37033 (uint32_t(*)(const void*))(&wuffs_crc32__ieee_hasher__checksum_u32),
37034 (uint64_t(*)(const void*,
37035 uint32_t))(&wuffs_crc32__ieee_hasher__get_quirk),
37036 (wuffs_base__status(*)(void*,
37037 uint32_t,
37038 uint64_t))(&wuffs_crc32__ieee_hasher__set_quirk),
37039 (wuffs_base__empty_struct(*)(void*,
37040 wuffs_base__slice_u8))(&wuffs_crc32__ieee_hasher__update),
37041 (uint32_t(*)(void*,
37042 wuffs_base__slice_u8))(&wuffs_crc32__ieee_hasher__update_u32),
37045 // ---------------- Initializer Implementations
37047 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
37048 wuffs_crc32__ieee_hasher__initialize(
37049 wuffs_crc32__ieee_hasher* self,
37050 size_t sizeof_star_self,
37051 uint64_t wuffs_version,
37052 uint32_t options){
37053 if (!self) {
37054 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
37056 if (sizeof(*self) != sizeof_star_self) {
37057 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
37059 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
37060 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
37061 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
37064 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
37065 // The whole point of this if-check is to detect an uninitialized *self.
37066 // We disable the warning on GCC. Clang-5.0 does not have this warning.
37067 #if !defined(__clang__) && defined(__GNUC__)
37068 #pragma GCC diagnostic push
37069 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
37070 #endif
37071 if (self->private_impl.magic != 0) {
37072 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
37074 #if !defined(__clang__) && defined(__GNUC__)
37075 #pragma GCC diagnostic pop
37076 #endif
37077 } else {
37078 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
37079 memset(self, 0, sizeof(*self));
37080 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
37081 } else {
37082 memset(&(self->private_impl), 0, sizeof(self->private_impl));
37086 self->private_impl.choosy_up = &wuffs_crc32__ieee_hasher__up__choosy_default;
37088 self->private_impl.magic = WUFFS_BASE__MAGIC;
37089 self->private_impl.vtable_for__wuffs_base__hasher_u32.vtable_name =
37090 wuffs_base__hasher_u32__vtable_name;
37091 self->private_impl.vtable_for__wuffs_base__hasher_u32.function_pointers =
37092 (const void*)(&wuffs_crc32__ieee_hasher__func_ptrs_for__wuffs_base__hasher_u32);
37093 return wuffs_base__make_status(NULL);
37096 wuffs_crc32__ieee_hasher*
37097 wuffs_crc32__ieee_hasher__alloc(void) {
37098 wuffs_crc32__ieee_hasher* x =
37099 (wuffs_crc32__ieee_hasher*)(calloc(1, sizeof(wuffs_crc32__ieee_hasher)));
37100 if (!x) {
37101 return NULL;
37103 if (wuffs_crc32__ieee_hasher__initialize(
37104 x, sizeof(wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
37105 free(x);
37106 return NULL;
37108 return x;
37111 size_t
37112 sizeof__wuffs_crc32__ieee_hasher(void) {
37113 return sizeof(wuffs_crc32__ieee_hasher);
37116 // ---------------- Function Implementations
37118 // -------- func crc32.ieee_hasher.get_quirk
37120 WUFFS_BASE__GENERATED_C_CODE
37121 WUFFS_BASE__MAYBE_STATIC uint64_t
37122 wuffs_crc32__ieee_hasher__get_quirk(
37123 const wuffs_crc32__ieee_hasher* self,
37124 uint32_t a_key) {
37125 if (!self) {
37126 return 0;
37128 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
37129 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
37130 return 0;
37133 return 0u;
37136 // -------- func crc32.ieee_hasher.set_quirk
37138 WUFFS_BASE__GENERATED_C_CODE
37139 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
37140 wuffs_crc32__ieee_hasher__set_quirk(
37141 wuffs_crc32__ieee_hasher* self,
37142 uint32_t a_key,
37143 uint64_t a_value) {
37144 if (!self) {
37145 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
37147 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
37148 return wuffs_base__make_status(
37149 (self->private_impl.magic == WUFFS_BASE__DISABLED)
37150 ? wuffs_base__error__disabled_by_previous_error
37151 : wuffs_base__error__initialize_not_called);
37154 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
37157 // -------- func crc32.ieee_hasher.update
37159 WUFFS_BASE__GENERATED_C_CODE
37160 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
37161 wuffs_crc32__ieee_hasher__update(
37162 wuffs_crc32__ieee_hasher* self,
37163 wuffs_base__slice_u8 a_x) {
37164 if (!self) {
37165 return wuffs_base__make_empty_struct();
37167 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
37168 return wuffs_base__make_empty_struct();
37171 if (self->private_impl.f_state == 0u) {
37172 self->private_impl.choosy_up = (
37173 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_CRC32)
37174 wuffs_base__cpu_arch__have_arm_crc32() ? &wuffs_crc32__ieee_hasher__up_arm_crc32 :
37175 #endif
37176 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
37177 wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_crc32__ieee_hasher__up_x86_sse42 :
37178 #endif
37179 self->private_impl.choosy_up);
37181 wuffs_crc32__ieee_hasher__up(self, a_x);
37182 return wuffs_base__make_empty_struct();
37185 // -------- func crc32.ieee_hasher.update_u32
37187 WUFFS_BASE__GENERATED_C_CODE
37188 WUFFS_BASE__MAYBE_STATIC uint32_t
37189 wuffs_crc32__ieee_hasher__update_u32(
37190 wuffs_crc32__ieee_hasher* self,
37191 wuffs_base__slice_u8 a_x) {
37192 if (!self) {
37193 return 0;
37195 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
37196 return 0;
37199 wuffs_crc32__ieee_hasher__update(self, a_x);
37200 return self->private_impl.f_state;
37203 // -------- func crc32.ieee_hasher.up
37205 WUFFS_BASE__GENERATED_C_CODE
37206 static wuffs_base__empty_struct
37207 wuffs_crc32__ieee_hasher__up(
37208 wuffs_crc32__ieee_hasher* self,
37209 wuffs_base__slice_u8 a_x) {
37210 return (*self->private_impl.choosy_up)(self, a_x);
37213 WUFFS_BASE__GENERATED_C_CODE
37214 static wuffs_base__empty_struct
37215 wuffs_crc32__ieee_hasher__up__choosy_default(
37216 wuffs_crc32__ieee_hasher* self,
37217 wuffs_base__slice_u8 a_x) {
37218 uint32_t v_s = 0;
37219 wuffs_base__slice_u8 v_p = {0};
37221 v_s = (4294967295u ^ self->private_impl.f_state);
37223 wuffs_base__slice_u8 i_slice_p = a_x;
37224 v_p.ptr = i_slice_p.ptr;
37225 v_p.len = 16;
37226 const uint8_t* i_end0_p = wuffs_private_impl__ptr_u8_plus_len(v_p.ptr, (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 32) * 32));
37227 while (v_p.ptr < i_end0_p) {
37228 v_s ^= ((((uint32_t)(v_p.ptr[0u])) << 0u) |
37229 (((uint32_t)(v_p.ptr[1u])) << 8u) |
37230 (((uint32_t)(v_p.ptr[2u])) << 16u) |
37231 (((uint32_t)(v_p.ptr[3u])) << 24u));
37232 v_s = (WUFFS_CRC32__IEEE_TABLE[0u][v_p.ptr[15u]] ^
37233 WUFFS_CRC32__IEEE_TABLE[1u][v_p.ptr[14u]] ^
37234 WUFFS_CRC32__IEEE_TABLE[2u][v_p.ptr[13u]] ^
37235 WUFFS_CRC32__IEEE_TABLE[3u][v_p.ptr[12u]] ^
37236 WUFFS_CRC32__IEEE_TABLE[4u][v_p.ptr[11u]] ^
37237 WUFFS_CRC32__IEEE_TABLE[5u][v_p.ptr[10u]] ^
37238 WUFFS_CRC32__IEEE_TABLE[6u][v_p.ptr[9u]] ^
37239 WUFFS_CRC32__IEEE_TABLE[7u][v_p.ptr[8u]] ^
37240 WUFFS_CRC32__IEEE_TABLE[8u][v_p.ptr[7u]] ^
37241 WUFFS_CRC32__IEEE_TABLE[9u][v_p.ptr[6u]] ^
37242 WUFFS_CRC32__IEEE_TABLE[10u][v_p.ptr[5u]] ^
37243 WUFFS_CRC32__IEEE_TABLE[11u][v_p.ptr[4u]] ^
37244 WUFFS_CRC32__IEEE_TABLE[12u][(255u & (v_s >> 24u))] ^
37245 WUFFS_CRC32__IEEE_TABLE[13u][(255u & (v_s >> 16u))] ^
37246 WUFFS_CRC32__IEEE_TABLE[14u][(255u & (v_s >> 8u))] ^
37247 WUFFS_CRC32__IEEE_TABLE[15u][(255u & (v_s >> 0u))]);
37248 v_p.ptr += 16;
37249 v_s ^= ((((uint32_t)(v_p.ptr[0u])) << 0u) |
37250 (((uint32_t)(v_p.ptr[1u])) << 8u) |
37251 (((uint32_t)(v_p.ptr[2u])) << 16u) |
37252 (((uint32_t)(v_p.ptr[3u])) << 24u));
37253 v_s = (WUFFS_CRC32__IEEE_TABLE[0u][v_p.ptr[15u]] ^
37254 WUFFS_CRC32__IEEE_TABLE[1u][v_p.ptr[14u]] ^
37255 WUFFS_CRC32__IEEE_TABLE[2u][v_p.ptr[13u]] ^
37256 WUFFS_CRC32__IEEE_TABLE[3u][v_p.ptr[12u]] ^
37257 WUFFS_CRC32__IEEE_TABLE[4u][v_p.ptr[11u]] ^
37258 WUFFS_CRC32__IEEE_TABLE[5u][v_p.ptr[10u]] ^
37259 WUFFS_CRC32__IEEE_TABLE[6u][v_p.ptr[9u]] ^
37260 WUFFS_CRC32__IEEE_TABLE[7u][v_p.ptr[8u]] ^
37261 WUFFS_CRC32__IEEE_TABLE[8u][v_p.ptr[7u]] ^
37262 WUFFS_CRC32__IEEE_TABLE[9u][v_p.ptr[6u]] ^
37263 WUFFS_CRC32__IEEE_TABLE[10u][v_p.ptr[5u]] ^
37264 WUFFS_CRC32__IEEE_TABLE[11u][v_p.ptr[4u]] ^
37265 WUFFS_CRC32__IEEE_TABLE[12u][(255u & (v_s >> 24u))] ^
37266 WUFFS_CRC32__IEEE_TABLE[13u][(255u & (v_s >> 16u))] ^
37267 WUFFS_CRC32__IEEE_TABLE[14u][(255u & (v_s >> 8u))] ^
37268 WUFFS_CRC32__IEEE_TABLE[15u][(255u & (v_s >> 0u))]);
37269 v_p.ptr += 16;
37271 v_p.len = 16;
37272 const uint8_t* i_end1_p = wuffs_private_impl__ptr_u8_plus_len(v_p.ptr, (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 16) * 16));
37273 while (v_p.ptr < i_end1_p) {
37274 v_s ^= ((((uint32_t)(v_p.ptr[0u])) << 0u) |
37275 (((uint32_t)(v_p.ptr[1u])) << 8u) |
37276 (((uint32_t)(v_p.ptr[2u])) << 16u) |
37277 (((uint32_t)(v_p.ptr[3u])) << 24u));
37278 v_s = (WUFFS_CRC32__IEEE_TABLE[0u][v_p.ptr[15u]] ^
37279 WUFFS_CRC32__IEEE_TABLE[1u][v_p.ptr[14u]] ^
37280 WUFFS_CRC32__IEEE_TABLE[2u][v_p.ptr[13u]] ^
37281 WUFFS_CRC32__IEEE_TABLE[3u][v_p.ptr[12u]] ^
37282 WUFFS_CRC32__IEEE_TABLE[4u][v_p.ptr[11u]] ^
37283 WUFFS_CRC32__IEEE_TABLE[5u][v_p.ptr[10u]] ^
37284 WUFFS_CRC32__IEEE_TABLE[6u][v_p.ptr[9u]] ^
37285 WUFFS_CRC32__IEEE_TABLE[7u][v_p.ptr[8u]] ^
37286 WUFFS_CRC32__IEEE_TABLE[8u][v_p.ptr[7u]] ^
37287 WUFFS_CRC32__IEEE_TABLE[9u][v_p.ptr[6u]] ^
37288 WUFFS_CRC32__IEEE_TABLE[10u][v_p.ptr[5u]] ^
37289 WUFFS_CRC32__IEEE_TABLE[11u][v_p.ptr[4u]] ^
37290 WUFFS_CRC32__IEEE_TABLE[12u][(255u & (v_s >> 24u))] ^
37291 WUFFS_CRC32__IEEE_TABLE[13u][(255u & (v_s >> 16u))] ^
37292 WUFFS_CRC32__IEEE_TABLE[14u][(255u & (v_s >> 8u))] ^
37293 WUFFS_CRC32__IEEE_TABLE[15u][(255u & (v_s >> 0u))]);
37294 v_p.ptr += 16;
37296 v_p.len = 1;
37297 const uint8_t* i_end2_p = wuffs_private_impl__ptr_u8_plus_len(i_slice_p.ptr, i_slice_p.len);
37298 while (v_p.ptr < i_end2_p) {
37299 v_s = (WUFFS_CRC32__IEEE_TABLE[0u][((uint8_t)(((uint8_t)(v_s)) ^ v_p.ptr[0u]))] ^ (v_s >> 8u));
37300 v_p.ptr += 1;
37302 v_p.len = 0;
37304 self->private_impl.f_state = (4294967295u ^ v_s);
37305 return wuffs_base__make_empty_struct();
37308 // -------- func crc32.ieee_hasher.checksum_u32
37310 WUFFS_BASE__GENERATED_C_CODE
37311 WUFFS_BASE__MAYBE_STATIC uint32_t
37312 wuffs_crc32__ieee_hasher__checksum_u32(
37313 const wuffs_crc32__ieee_hasher* self) {
37314 if (!self) {
37315 return 0;
37317 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
37318 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
37319 return 0;
37322 return self->private_impl.f_state;
37325 // ‼ WUFFS MULTI-FILE SECTION +arm_crc32
37326 // -------- func crc32.ieee_hasher.up_arm_crc32
37328 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_CRC32)
37329 WUFFS_BASE__GENERATED_C_CODE
37330 static wuffs_base__empty_struct
37331 wuffs_crc32__ieee_hasher__up_arm_crc32(
37332 wuffs_crc32__ieee_hasher* self,
37333 wuffs_base__slice_u8 a_x) {
37334 wuffs_base__slice_u8 v_p = {0};
37335 uint32_t v_s = 0;
37337 v_s = (4294967295u ^ self->private_impl.f_state);
37338 while ((((uint64_t)(a_x.len)) > 0u) && ((15u & ((uint32_t)(0xFFFu & (uintptr_t)(a_x.ptr)))) != 0u)) {
37339 v_s = __crc32b(v_s, a_x.ptr[0u]);
37340 a_x = wuffs_base__slice_u8__subslice_i(a_x, 1u);
37343 wuffs_base__slice_u8 i_slice_p = a_x;
37344 v_p.ptr = i_slice_p.ptr;
37345 v_p.len = 8;
37346 const uint8_t* i_end0_p = wuffs_private_impl__ptr_u8_plus_len(v_p.ptr, (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 128) * 128));
37347 while (v_p.ptr < i_end0_p) {
37348 v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
37349 v_p.ptr += 8;
37350 v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
37351 v_p.ptr += 8;
37352 v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
37353 v_p.ptr += 8;
37354 v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
37355 v_p.ptr += 8;
37356 v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
37357 v_p.ptr += 8;
37358 v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
37359 v_p.ptr += 8;
37360 v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
37361 v_p.ptr += 8;
37362 v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
37363 v_p.ptr += 8;
37364 v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
37365 v_p.ptr += 8;
37366 v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
37367 v_p.ptr += 8;
37368 v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
37369 v_p.ptr += 8;
37370 v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
37371 v_p.ptr += 8;
37372 v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
37373 v_p.ptr += 8;
37374 v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
37375 v_p.ptr += 8;
37376 v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
37377 v_p.ptr += 8;
37378 v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
37379 v_p.ptr += 8;
37381 v_p.len = 8;
37382 const uint8_t* i_end1_p = wuffs_private_impl__ptr_u8_plus_len(v_p.ptr, (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 8) * 8));
37383 while (v_p.ptr < i_end1_p) {
37384 v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
37385 v_p.ptr += 8;
37387 v_p.len = 1;
37388 const uint8_t* i_end2_p = wuffs_private_impl__ptr_u8_plus_len(i_slice_p.ptr, i_slice_p.len);
37389 while (v_p.ptr < i_end2_p) {
37390 v_s = __crc32b(v_s, v_p.ptr[0u]);
37391 v_p.ptr += 1;
37393 v_p.len = 0;
37395 self->private_impl.f_state = (4294967295u ^ v_s);
37396 return wuffs_base__make_empty_struct();
37398 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_CRC32)
37399 // ‼ WUFFS MULTI-FILE SECTION -arm_crc32
37401 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
37402 // -------- func crc32.ieee_hasher.up_x86_sse42
37404 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
37405 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
37406 WUFFS_BASE__GENERATED_C_CODE
37407 static wuffs_base__empty_struct
37408 wuffs_crc32__ieee_hasher__up_x86_sse42(
37409 wuffs_crc32__ieee_hasher* self,
37410 wuffs_base__slice_u8 a_x) {
37411 uint32_t v_s = 0;
37412 __m128i v_kk = {0};
37413 __m128i v_x0 = {0};
37414 __m128i v_x1 = {0};
37415 __m128i v_x2 = {0};
37416 __m128i v_x3 = {0};
37417 __m128i v_x4 = {0};
37418 __m128i v_x5 = {0};
37419 __m128i v_x6 = {0};
37420 __m128i v_x7 = {0};
37421 __m128i v_y0 = {0};
37422 __m128i v_y1 = {0};
37423 __m128i v_y2 = {0};
37424 __m128i v_y3 = {0};
37425 __m128i v_y4 = {0};
37426 __m128i v_y5 = {0};
37427 __m128i v_y6 = {0};
37428 __m128i v_y7 = {0};
37430 v_s = (4294967295u ^ self->private_impl.f_state);
37431 while ((((uint64_t)(a_x.len)) > 0u) && ((15u & ((uint32_t)(0xFFFu & (uintptr_t)(a_x.ptr)))) != 0u)) {
37432 v_s = (WUFFS_CRC32__IEEE_TABLE[0u][((uint8_t)(((uint8_t)(v_s)) ^ a_x.ptr[0u]))] ^ (v_s >> 8u));
37433 a_x = wuffs_base__slice_u8__subslice_i(a_x, 1u);
37435 if (((uint64_t)(a_x.len)) >= 128u) {
37436 v_x0 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 0u));
37437 v_x1 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 16u));
37438 v_x2 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 32u));
37439 v_x3 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 48u));
37440 v_x4 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 64u));
37441 v_x5 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 80u));
37442 v_x6 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 96u));
37443 v_x7 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 112u));
37444 v_kk = _mm_set_epi32((int32_t)(0u), (int32_t)(2433674945u), (int32_t)(0u), (int32_t)(872412467u));
37445 v_x0 = _mm_xor_si128(v_x0, _mm_cvtsi32_si128((int32_t)(v_s)));
37446 a_x = wuffs_base__slice_u8__subslice_i(a_x, 128u);
37447 while (((uint64_t)(a_x.len)) >= 128u) {
37448 v_y0 = _mm_clmulepi64_si128(v_x0, v_kk, (int32_t)(0u));
37449 v_x0 = _mm_clmulepi64_si128(v_x0, v_kk, (int32_t)(17u));
37450 v_y1 = _mm_clmulepi64_si128(v_x1, v_kk, (int32_t)(0u));
37451 v_x1 = _mm_clmulepi64_si128(v_x1, v_kk, (int32_t)(17u));
37452 v_y2 = _mm_clmulepi64_si128(v_x2, v_kk, (int32_t)(0u));
37453 v_x2 = _mm_clmulepi64_si128(v_x2, v_kk, (int32_t)(17u));
37454 v_y3 = _mm_clmulepi64_si128(v_x3, v_kk, (int32_t)(0u));
37455 v_x3 = _mm_clmulepi64_si128(v_x3, v_kk, (int32_t)(17u));
37456 v_y4 = _mm_clmulepi64_si128(v_x4, v_kk, (int32_t)(0u));
37457 v_x4 = _mm_clmulepi64_si128(v_x4, v_kk, (int32_t)(17u));
37458 v_y5 = _mm_clmulepi64_si128(v_x5, v_kk, (int32_t)(0u));
37459 v_x5 = _mm_clmulepi64_si128(v_x5, v_kk, (int32_t)(17u));
37460 v_y6 = _mm_clmulepi64_si128(v_x6, v_kk, (int32_t)(0u));
37461 v_x6 = _mm_clmulepi64_si128(v_x6, v_kk, (int32_t)(17u));
37462 v_y7 = _mm_clmulepi64_si128(v_x7, v_kk, (int32_t)(0u));
37463 v_x7 = _mm_clmulepi64_si128(v_x7, v_kk, (int32_t)(17u));
37464 v_y0 = _mm_xor_si128(v_y0, _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 0u)));
37465 v_x0 = _mm_xor_si128(v_x0, v_y0);
37466 v_y1 = _mm_xor_si128(v_y1, _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 16u)));
37467 v_x1 = _mm_xor_si128(v_x1, v_y1);
37468 v_y2 = _mm_xor_si128(v_y2, _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 32u)));
37469 v_x2 = _mm_xor_si128(v_x2, v_y2);
37470 v_y3 = _mm_xor_si128(v_y3, _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 48u)));
37471 v_x3 = _mm_xor_si128(v_x3, v_y3);
37472 v_y4 = _mm_xor_si128(v_y4, _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 64u)));
37473 v_x4 = _mm_xor_si128(v_x4, v_y4);
37474 v_y5 = _mm_xor_si128(v_y5, _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 80u)));
37475 v_x5 = _mm_xor_si128(v_x5, v_y5);
37476 v_y6 = _mm_xor_si128(v_y6, _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 96u)));
37477 v_x6 = _mm_xor_si128(v_x6, v_y6);
37478 v_y7 = _mm_xor_si128(v_y7, _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 112u)));
37479 v_x7 = _mm_xor_si128(v_x7, v_y7);
37480 a_x = wuffs_base__slice_u8__subslice_i(a_x, 128u);
37482 v_kk = _mm_set_epi32((int32_t)(0u), (int32_t)(3433693342u), (int32_t)(0u), (int32_t)(2926088593u));
37483 v_y0 = _mm_clmulepi64_si128(v_x0, v_kk, (int32_t)(0u));
37484 v_x0 = _mm_clmulepi64_si128(v_x0, v_kk, (int32_t)(17u));
37485 v_y2 = _mm_clmulepi64_si128(v_x2, v_kk, (int32_t)(0u));
37486 v_x2 = _mm_clmulepi64_si128(v_x2, v_kk, (int32_t)(17u));
37487 v_y4 = _mm_clmulepi64_si128(v_x4, v_kk, (int32_t)(0u));
37488 v_x4 = _mm_clmulepi64_si128(v_x4, v_kk, (int32_t)(17u));
37489 v_y6 = _mm_clmulepi64_si128(v_x6, v_kk, (int32_t)(0u));
37490 v_x6 = _mm_clmulepi64_si128(v_x6, v_kk, (int32_t)(17u));
37491 v_y0 = _mm_xor_si128(v_y0, v_x1);
37492 v_x0 = _mm_xor_si128(v_x0, v_y0);
37493 v_y2 = _mm_xor_si128(v_y2, v_x3);
37494 v_x2 = _mm_xor_si128(v_x2, v_y2);
37495 v_y4 = _mm_xor_si128(v_y4, v_x5);
37496 v_x4 = _mm_xor_si128(v_x4, v_y4);
37497 v_y6 = _mm_xor_si128(v_y6, v_x7);
37498 v_x6 = _mm_xor_si128(v_x6, v_y6);
37499 v_kk = _mm_set_epi32((int32_t)(0u), (int32_t)(2166711591u), (int32_t)(0u), (int32_t)(4057597354u));
37500 v_y0 = _mm_clmulepi64_si128(v_x0, v_kk, (int32_t)(0u));
37501 v_x0 = _mm_clmulepi64_si128(v_x0, v_kk, (int32_t)(17u));
37502 v_y4 = _mm_clmulepi64_si128(v_x4, v_kk, (int32_t)(0u));
37503 v_x4 = _mm_clmulepi64_si128(v_x4, v_kk, (int32_t)(17u));
37504 v_y0 = _mm_xor_si128(v_y0, v_x2);
37505 v_x0 = _mm_xor_si128(v_x0, v_y0);
37506 v_y4 = _mm_xor_si128(v_y4, v_x6);
37507 v_x4 = _mm_xor_si128(v_x4, v_y4);
37508 v_kk = _mm_set_epi32((int32_t)(0u), (int32_t)(496309207u), (int32_t)(0u), (int32_t)(2402626965u));
37509 v_y0 = _mm_clmulepi64_si128(v_x0, v_kk, (int32_t)(0u));
37510 v_x0 = _mm_clmulepi64_si128(v_x0, v_kk, (int32_t)(17u));
37511 v_y0 = _mm_xor_si128(v_y0, v_x4);
37512 v_x0 = _mm_xor_si128(v_x0, v_y0);
37513 v_kk = _mm_set_epi32((int32_t)(1u), (int32_t)(3681617473u), (int32_t)(3034951717u), (int32_t)(4144043585u));
37514 v_s = ((uint32_t)(_mm_extract_epi32(_mm_clmulepi64_si128(_mm_clmulepi64_si128(_mm_cvtsi64_si128((int64_t)(((uint64_t)(_mm_extract_epi64(v_x0, (int32_t)(0u)))))), v_kk, (int32_t)(0u)), v_kk, (int32_t)(16u)), (int32_t)(2u))));
37515 v_kk = _mm_set_epi32((int32_t)(1u), (int32_t)(3681617473u), (int32_t)(3034951717u), (int32_t)(4144043585u));
37516 v_s = ((uint32_t)(_mm_extract_epi32(_mm_clmulepi64_si128(_mm_clmulepi64_si128(_mm_cvtsi64_si128((int64_t)((((uint64_t)(_mm_extract_epi64(v_x0, (int32_t)(1u)))) ^ ((uint64_t)(v_s))))), v_kk, (int32_t)(0u)), v_kk, (int32_t)(16u)), (int32_t)(2u))));
37518 while (((uint64_t)(a_x.len)) >= 8u) {
37519 v_kk = _mm_set_epi32((int32_t)(1u), (int32_t)(3681617473u), (int32_t)(3034951717u), (int32_t)(4144043585u));
37520 v_s = ((uint32_t)(_mm_extract_epi32(_mm_clmulepi64_si128(_mm_clmulepi64_si128(_mm_cvtsi64_si128((int64_t)((wuffs_base__peek_u64le__no_bounds_check(a_x.ptr) ^ ((uint64_t)(v_s))))), v_kk, (int32_t)(0u)), v_kk, (int32_t)(16u)), (int32_t)(2u))));
37521 a_x = wuffs_base__slice_u8__subslice_i(a_x, 8u);
37523 while (((uint64_t)(a_x.len)) > 0u) {
37524 v_s = (WUFFS_CRC32__IEEE_TABLE[0u][((uint8_t)(((uint8_t)(v_s)) ^ a_x.ptr[0u]))] ^ (v_s >> 8u));
37525 a_x = wuffs_base__slice_u8__subslice_i(a_x, 1u);
37527 self->private_impl.f_state = (4294967295u ^ v_s);
37528 return wuffs_base__make_empty_struct();
37530 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
37531 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
37533 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CRC32)
37535 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CRC64)
37537 // ---------------- Status Codes Implementations
37539 // ---------------- Private Consts
37541 static const uint64_t
37542 WUFFS_CRC64__ECMA_TABLE[8][256] WUFFS_BASE__POTENTIALLY_UNUSED = {
37544 0u, 12911341560706588527u, 17619267392293085275u, 5164075066763771700u, 8921845837811637811u, 14483170935171449180u, 10328150133527543400u, 4357999468653093127u,
37545 17843691675623275622u, 4940391307328217865u, 226782375002905661u, 12685511915359257426u, 10119945210068853333u, 4566377562367245626u, 8715998937306186254u, 14689403211693301089u,
37546 9051005139383707209u, 14895072503764629798u, 9880782614656435730u, 4193374422961527165u, 453564750005811322u, 13070904082541799189u, 17496296445768931361u, 4747102235666401102u,
37547 9960315520700766767u, 4113029525020509504u, 9132755124734491252u, 14812441257301386523u, 17431997874612372508u, 4811156168024382323u, 391483189436228679u, 13132671735097031464u,
37548 18102010278767414418u, 5195199925788447741u, 1131375642422963401u, 13591081480414639014u, 9288535643022529185u, 3731739485546663374u, 8386748845923054330u, 14361410892855143829u,
37549 907129500011622644u, 13814943346342178715u, 17875617253995106479u, 5421418680781082560u, 8594564625313771207u, 14152643483341451688u, 9494204471332802204u, 3525329033817543155u,
37550 9704381199536204507u, 3855837706121835956u, 8226059050041019008u, 13908973417437222383u, 18265510249468982504u, 5643692520190618503u, 718348998302913715u, 13463047253836762076u,
37551 8146277531524994749u, 13989069943491807698u, 9622312336048764646u, 3938150108875254153u, 782966378872457358u, 13399312233903888353u, 18327840216347633877u, 5582173445676054458u,
37552 7257036000092981153u, 15535280666427316430u, 10390399851576895482u, 2529986302517213333u, 2262751284845926802u, 12414353723947190013u, 16997392145760156105u, 6398650419759490726u,
37553 10599130201908394951u, 2322133910755632296u, 7463478971093326748u, 15329644185724306675u, 16773497691846108660u, 6622864283287239323u, 2036569382881248687u, 12640783567252986560u,
37554 1814259000023245288u, 12250853444207230599u, 17125426475222188467u, 6811676960462675676u, 7132938157145702363u, 15119434731753103540u, 10842837361562165120u, 2690676064372932847u,
37555 17189129250627542414u, 6747026957542163169u, 1875814858707893717u, 12188560364711551674u, 10762704257491731389u, 2770420489343360210u, 7050658067635086310u, 15201536148867841161u,
37556 11493583972846619443u, 3219832958944941148u, 7711675412243671912u, 15576564987190227975u, 16452118100082038016u, 6305011443818121839u, 1213047649942025563u, 11816267669673208372u,
37557 7503259434831574869u, 15784731923736995898u, 11287385040381237006u, 3425713581329221729u, 1436697996605827430u, 11591809733187859977u, 16677985422973077821u, 6078267261889762898u,
37558 16292555063049989498u, 5851447209550246421u, 1630020308903038241u, 11939238787801010766u, 11081681957373440841u, 3090674103720225830u, 7876300217750508306u, 16023932746787097725u,
37559 1565932757744914716u, 12003503911822413427u, 16230825569204842823u, 5913566482019610152u, 7956607163135676207u, 15944361922680361024u, 11164346891352108916u, 3008957496780927003u,
37560 14514072000185962306u, 8809633696146542637u, 4460922918905818905u, 10287960411460399222u, 12879331835779764593u, 113391187501452830u, 5059972605034426666u, 17660565739912801861u,
37561 4525502569691853604u, 10224187249629523019u, 14576435430675780479u, 8748148222884465680u, 4980157760350383383u, 17740628527280140920u, 12797300839518981452u, 195741594718114339u,
37562 13040162471224305931u, 565687821211481700u, 4644267821511264592u, 17536326748496696895u, 14926957942186653496u, 8937808626997553239u, 4297282312656885603u, 9839608450464401420u,
37563 4852190599768102253u, 17327666750234135042u, 13245728566574478646u, 359174499151456857u, 4073138765762497374u, 10063573324157604913u, 14700457781105076997u, 9163920108173816938u,
37564 3628518000046490576u, 9328460452529085631u, 14330211790445699979u, 8498696072880078052u, 5299565100954197475u, 18061012165519327884u, 13623353920925351352u, 1018284691440624343u,
37565 14265876314291404726u, 8562713237611094233u, 3566469078572851181u, 9390260331795218562u, 13702854325316886917u, 937907429353946858u, 5381352128745865694u, 17978417549248290481u,
37566 5746791986423309721u, 18225777846762470134u, 13494053915084326338u, 606523824971012781u, 3751629717415787434u, 9745292510640121029u, 13876787882151992305u, 8338992711486538910u,
37567 13285957365033343487u, 815010154451519120u, 5540840978686720420u, 18431906428167644875u, 14101316135270172620u, 8115412784602421411u, 3978303581567838103u, 9519354766961195256u,
37568 12527462061959317731u, 2230461459452909452u, 6439665917889882296u, 16893009583564617687u, 15423350824487343824u, 7288217715337890239u, 2490078880175191691u, 10493603952060017124u,
37569 6520081235612152965u, 16813546994155744234u, 12610022887636243678u, 2148641156328442801u, 2426095299884051126u, 10557972909709735385u, 15361512820870335213u, 7350228890552538498u,
37570 15006518869663149738u, 7165105895222849989u, 2649782550477098737u, 10947027550912647582u, 12362696414880903321u, 1783234539286425590u, 6851427162658443458u, 17022309211647725485u,
37571 2873395993211654860u, 10722532847870938531u, 15232418832718623383u, 6938393941075996152u, 6642978682516671743u, 17230443782969840528u, 12156534523779525796u, 1989151790783919051u,
37572 6263731030979658865u, 16556202624882645790u, 11702894419100492842u, 1245039440087595845u, 3260040617806076482u, 11390642587947386157u, 15688795063501830681u, 7680756410435167606u,
37573 11622868312827688983u, 1324891275238549368u, 6181348207440451660u, 16638201170595874595u, 15752600435501016612u, 7616209416359311691u, 3321489341258335871u, 11328242235714328848u,
37574 3131865515489829432u, 10977756817953029463u, 16137146508898304611u, 7844397531750915340u, 5811434156413844491u, 16395372229761246052u, 11827132964039220304u, 1660744670629167935u,
37575 15913214326271352414u, 8068573254449152305u, 2905717078206922245u, 11204220263579804010u, 12035829987123708013u, 1452858539103461122u, 6017914993561854006u, 16189773752444600153u,
37576 }, {
37577 0u, 6118555238288912653u, 12237110476577825306u, 18247330833359770391u, 13942380710360636081u, 10778293617712507836u, 7543452712389327019u, 4343374206906190246u,
37578 1162559746622204903u, 4957131115480832746u, 13398436261328603645u, 17084888254066768112u, 15086905424778654038u, 9634902877839851611u, 8686748413812380492u, 3198961161184305729u,
37579 2325119493244409806u, 8407378615347160771u, 9914262230961665492u, 15960741045388068057u, 16229058527915052415u, 13101053971319389298u, 5254506258681524069u, 2018377927885299304u,
37580 3487552142959377449u, 7246080283574668580u, 11075676491871100467u, 14798208821638459198u, 17373496827624760984u, 11957750539307177877u, 6397922322368611458u, 873845550624159119u,
37581 4650238986488819612u, 1468611264581623441u, 16814757230694321542u, 13669406796222545035u, 9364600845881799981u, 15356367945216001056u, 2893367039927949111u, 8993183146101597754u,
37582 5812680741028562043u, 307286854339917174u, 17976181078471403105u, 12506848973898782572u, 10509012517363048138u, 14213073068277772231u, 4036755855770598608u, 7848658706446142941u,
37583 6975104285918754898u, 3757679901787621727u, 14492160567149337160u, 11382574084698991429u, 11651310343450272483u, 17679087685142107118u, 604386294999662841u, 6668229816820511220u,
37584 8137636784695169973u, 2596263716583940792u, 15653459723670892975u, 10220140060479144098u, 12795844644737222916u, 16535671346696648713u, 1747691101248318238u, 5523790692630174227u,
37585 9300477972977639224u, 15418239225476001333u, 2937222529163246882u, 8947075512310451247u, 4642267913777087881u, 1478833794519692420u, 16842993350473770899u, 13643422681269376670u,
37586 10462937938231096543u, 14256895642581861842u, 4098594218943518405u, 7784568886045304776u, 5786734079855898222u, 335485660068962147u, 17986366292203195508u, 12498915352811683193u,
37587 11625361482057124086u, 17707288688936286715u, 614573708679834348u, 6660293997941431265u, 6929031904881267271u, 3801500275841901386u, 14553996732492558429u, 11318486464284246352u,
37588 12787875770090627857u, 16545891676414235164u, 1775925023235784971u, 5497808777625382918u, 8073511711541197216u, 2658137194938402989u, 15697317412892285882u, 10174030228858301111u,
37589 13950208571837509796u, 10768213751408296361u, 7515359803575243454u, 4369215658492879795u, 64266086328445461u, 6056541296517372696u, 12193111774187735055u, 18293581128395077890u,
37590 15112713823828466499u, 9606842886146402894u, 8676701462472931673u, 3206755967968430164u, 1208772589999325682u, 4913169729330573567u, 13336459633641022440u, 17149116886581154533u,
37591 16275273569390339946u, 13057090384914568807u, 5192527433167881584u, 2082608760381092989u, 2350925692077440475u, 8379320821714095318u, 9904217479574233025u, 15968533654375526092u,
37592 17437760713698643085u, 11895738795633802624u, 6353925819959930519u, 920093647833407386u, 3495382202496636476u, 7235998217053677361u, 11047581385260348454u, 14824052473177163051u,
37593 10447068876609200373u, 14128364157388739064u, 4118967294799201007u, 7908597456515216354u, 5874445058326493764u, 391603411424480073u, 17894151024620902494u, 12447300791057279315u,
37594 9284535827554175762u, 15289779793358354975u, 2957667589039384840u, 9071030930460645381u, 4729911307347480995u, 1535020299074674862u, 16750846767572792249u, 13591740465559749300u,
37595 12735909365018523451u, 16453465302197274166u, 1832394617641637153u, 5585730863000118316u, 8197188437887036810u, 2678299164963691655u, 15569137772090609552u, 10158372272797335197u,
37596 11573468159711796444u, 17614790262716542417u, 670971320137924294u, 6748289234561093579u, 7052776217202099821u, 3821593491595032416u, 14425748405936874615u, 11302896163253294458u,
37597 15020497008676966249u, 9555230900528283236u, 8764415362900159859u, 3262871967819308158u, 1229147417359668696u, 5037195377843840213u, 13320587995882862530u, 17020586948957226703u,
37598 13858063809762534542u, 10716528681989657987u, 7603000551683802772u, 4425403642365261721u, 84709666887204415u, 6180499360129388338u, 12177172482473303077u, 18165119875451415848u,
37599 17309582619392432295u, 11880078264510294442u, 6477599625422879421u, 940257368289594288u, 3551850046471569942u, 7323923223311315739u, 10995617555250765836u, 14731624552464748801u,
37600 16147023423082394432u, 13041502936518885965u, 5316274389876805978u, 2102700497890566231u, 2407324781779167729u, 8467313413945678076u, 9852321304593615851u, 15876037047908055782u,
37601 1291018766690942925u, 4973072573440528064u, 13274480430592564695u, 17064442507263798490u, 15030719607150486908u, 9547259896855319665u, 8738431316985759590u, 3291108156134209131u,
37602 128532172656890922u, 6134424711959717159u, 12113082593034745392u, 18226958170089932605u, 13886262546419256987u, 10690581952315096982u, 7595066862094806145u, 4435588787024731532u,
37603 3580050981226981379u, 7297974293382715662u, 10987681667836234265u, 14741811897106152212u, 17353402924945863346u, 11834005814401532863u, 6413511935936860328u, 1002093465131966885u,
37604 2417545179998651364u, 8459344608371405545u, 9826339458661147134u, 15904271038397419763u, 16208896970474576213u, 12977377931899316312u, 5270164626790366031u, 2146558256149678658u,
37605 5864365122984562769u, 399431204366950748u, 17919992407673188939u, 12419207813205476166u, 10385054866335763168u, 14192630174644861933u, 4165217520762185978u, 7864598685623228919u,
37606 4701851384154880950u, 1560828767195761339u, 16758641643428190636u, 13581693582721149089u, 9240574510442684679u, 15335992705270927370u, 3021896290089222941u, 9009054371811832336u,
37607 8153224920554538911u, 2724514274940876434u, 15633368673088300421u, 10096393516356015240u, 12707851639919861038u, 16479271570068024355u, 1840187295666814772u, 5575686180147088953u,
37608 6990764404993272952u, 3885857308630146421u, 14471996434107354722u, 11258899592309161839u, 11563386024119531209u, 17622620253752952772u, 696814903175779539u, 6720194058879067614u,
37609 }, {
37610 0u, 4542972359516777931u, 9085944719033555862u, 4691664355513513565u, 18171889438067111724u, 14061474303606774503u, 9383328711027027130u, 13633424072306524529u,
37611 7676286055365832925u, 6164376987427609878u, 1481798532234586955u, 3142253189322229376u, 10855962452864321521u, 12223826156538735162u, 16771372852738792551u, 15543052108730888620u,
37612 15352572110731665850u, 16862791698018765937u, 12328753974855219756u, 10669987536837040103u, 2963597064469173910u, 1597421751597874013u, 6284506378644458752u, 7511137813735006411u,
37613 13801544397233820007u, 9260261528098962604u, 13951919735851666161u, 18344511890033026874u, 4874982405016790603u, 8983709158270585728u, 4445237816650825181u, 196831773885239318u,
37614 4091022007653359089u, 562346998784700474u, 5103132815620245095u, 8780357948041161644u, 14189083196432476893u, 18150173592266475286u, 13474345022262784331u, 9652793049543924864u,
37615 5927194128938347820u, 7875246409875505383u, 3194843503195748026u, 1395478681687169905u, 12569012757288917504u, 10477056948030502859u, 15022275627470012822u, 17253916197967211613u,
37616 17134349580696108107u, 15186860751721288064u, 10655150290339489757u, 12453952663903504918u, 1289987737384422247u, 3381381201708377772u, 8066289525279445233u, 5835212509754572090u,
37617 9749964810033581206u, 13278076374523191645u, 17967418316541171456u, 14290755639648123595u, 8890475633301650362u, 4929947589851190897u, 393663547770478636u, 4214651972966108647u,
37618 8182044015306718178u, 5658655167774316073u, 1124693997569400948u, 3499391957275839935u, 10206265631240490190u, 12873559114121502981u, 17560715896082323288u, 14753743294414502547u,
37619 1948880861322201919u, 2594127930539943668u, 7285718382500778153u, 6491924633276939618u, 16655531858934856723u, 15577868310755742168u, 11039333611388512133u, 11977453108914408014u,
37620 11854388257876695640u, 11207451878732806035u, 15750492819751010766u, 16545974958769302533u, 6389687006391496052u, 7469038772501250239u, 2790957363374339810u, 1851148384058628905u,
37621 14845159798643632773u, 17370237963685480270u, 12687582131971748115u, 10311195790054169816u, 3615017233668480425u, 946035540305899618u, 5493509258033841727u, 8302171348940565492u,
37622 5281120895271462419u, 8521283507583323096u, 3989500891288354181u, 600787064567550030u, 13071075951463747903u, 9974957613568212212u, 14659789384177486505u, 17616368207971182434u,
37623 2579975474768844494u, 2073357103652371205u, 6762762403416755544u, 7120694423275413651u, 16132579050558890466u, 16206641305794825257u, 11670425019509144180u, 11456679111066785727u,
37624 11260412520859862953u, 11767594448091671138u, 16308316081471249471u, 15949821717821010420u, 6947506857025941637u, 6872882154850049358u, 2196985003345963795u, 2411294364755134168u,
37625 17780951266603300724u, 14540225107906894527u, 9859895179702381794u, 13249171359945539881u, 787327095540957272u, 3884007889973030291u, 8429303945932217294u, 5472161678768272901u,
37626 16364088030613436356u, 15858029804260760079u, 11317310335548632146u, 11674676600264311193u, 2249387995138801896u, 2322888996435045667u, 6998783914551679870u, 6785602652076537525u,
37627 9916730820443375385u, 13156333278251739858u, 17836661041797717135u, 14448512960480194884u, 8480501340405739573u, 5384944246861192702u, 839650424281590691u, 3795664592519366248u,
37628 3897761722644403838u, 656471011406904245u, 5188255861079887336u, 8578093388688728099u, 14571436765001556306u, 17668683201823263897u, 12983849266553879236u, 10026146741872662287u,
37629 6669836397870376611u, 7177582867921406824u, 2488175334770097461u, 2129119614032302334u, 11583119667977343375u, 11507929313807383620u, 16044147764761037337u, 16259017374083049426u,
37630 15843330937415051829u, 16489139217633298430u, 11946100509993103779u, 11151742071862860904u, 2878174689517968665u, 1799951022334374098u, 6478030266801178255u, 7416715545229372228u,
37631 12779374012782992104u, 10255423946675697443u, 14938077545002500478u, 17313340186040954037u, 5581914726748679620u, 8249768321177223183u, 3702296768117257810u, 894758378090191769u,
37632 1067805515879173007u, 3592318064290702916u, 8126281399163064345u, 5750455340522077650u, 17509465798031703203u, 14841048614271029608u, 10153889598922762037u, 12961990299524614910u,
37633 7230034467336960850u, 6583663697231173273u, 1892071080611799236u, 2686992928761285903u, 10987018516067683454u, 12065805765134311861u, 16604342697881130984u, 15665095101429070371u,
37634 10562241790542924838u, 12510858718452294125u, 17042567015166646192u, 15242640940723501691u, 7979001782576708362u, 5886480219318720193u, 1201574129135100060u, 3433774845539634519u,
37635 17875696825445760251u, 14346457162030502192u, 9657117384671061869u, 13334903762452155046u, 305328503063841751u, 4266984645440464412u, 8803266454141587521u, 4981154328058445194u,
37636 5159950949537688988u, 8687502257518297175u, 4146714207304742410u, 470617173809470401u, 13525524806833511088u, 9565558111887030139u, 14241388846550827302u, 18061812720343526637u,
37637 3250597773715660097u, 1303669193657626762u, 5984074333724313303u, 7782311056298339100u, 15074661043719826029u, 17165493152098584486u, 12620272307991097851u, 10389759836427934768u,
37638 12273052416502600151u, 10761709128327461916u, 15295744618112993857u, 16955639155056813962u, 6232173811933554427u, 7599472825692375856u, 2912390363305901421u, 1684630829289181350u,
37639 13895013714051883274u, 18437420284065877185u, 13745764309700098716u, 9352044056584181591u, 4393970006691927590u, 284119552558480365u, 4822588729510268336u, 9072122871209877627u,
37640 9177754244107333741u, 4635909983525117350u, 92935459340889083u, 4486092121981797936u, 9471751652205676353u, 13581038687731985034u, 18259186513699183831u, 14010214853299335452u,
37641 1574654191081914544u, 3085435160094502267u, 7768015779946060582u, 6108684823746459373u, 16858607891864434588u, 15491872287116188247u, 10944323357536545802u, 12171520400656925121u,
37642 }, {
37643 0u, 2156813408461955548u, 4313626816923911096u, 2752718492472304228u, 8627253633847822192u, 7661928252530632364u, 5505436984944608456u, 5875429064940414228u,
37644 17254507267695644384u, 17481523150583344956u, 15323856505061264728u, 14503785508944014468u, 11010873969889216912u, 9592933115173218380u, 11750858129880828456u, 13762408288327199732u,
37645 5489899806547772229u, 5899293950881604249u, 8641596751236382973u, 7639112309309301025u, 4290280838231655477u, 2766522915734824425u, 24548853041579917u, 2141951263632483921u,
37646 11764625126767791525u, 13739024951972572281u, 10995904098661322269u, 9617374173086412737u, 15347829100153899733u, 14488356108428585737u, 17231728733602892141u, 17495903608387299505u,
37647 10979799613095544458u, 9623805157521532758u, 11798587901763208498u, 13714458609834648814u, 17283193502472765946u, 17452775347443867686u, 15278224618618602050u, 14549338234851124126u,
37648 8580561676463310954u, 7708699370463537590u, 5533045831469648850u, 5847881786764880398u, 49097706083159834u, 2107935609010204358u, 4283902527264967842u, 2782645096555375998u,
37649 15298762408106657231u, 14537220494637179923u, 17261466032775972471u, 17465946411177207723u, 11811312492909331135u, 13692276008895521635u, 10968273481005252871u, 9644925621600215259u,
37650 4261616546501692207u, 2795266376586341107u, 70185227798988951u, 2096376465831291211u, 5520961050865536095u, 5868452604588535171u, 8593836137267777511u, 7687075229128879675u,
37651 11680230827506930577u, 13832259058284016205u, 11080421551794245673u, 9523735455073038837u, 15394057194608301281u, 14432953972299937085u, 17185658977434064729u, 17550865948466574981u,
37652 5579070418531851633u, 5801301123735731373u, 8552830750928559817u, 7736981982542757653u, 4239857041646656001u, 2826138345940532189u, 75412445699561913u, 2082177495183685733u,
37653 17161123352926621908u, 17565732457015587080u, 15417398740927075180u, 14419136389292487344u, 11066091662939297700u, 9546555762013386360u, 11695763573529760796u, 13808381012597372352u,
37654 98195412166319668u, 2067810197125185512u, 4215871218020408716u, 2841563382736944208u, 8567805054529935684u, 7712554084374493336u, 5565290193110751996u, 5824680096370817824u,
37655 4213277561403610395u, 2852497928146826439u, 118647349622822563u, 2038740285422565247u, 5603244184571253355u, 5777048188553278391u, 8511711324634206675u, 7778039831901335567u,
37656 15351860113773370363u, 14475212630091872807u, 17208772955998935107u, 17527831139023518111u, 11724816064851319947u, 13787876126790335831u, 11055209722282565427u, 9549167182608629487u,
37657 8523233093003384414u, 7756906139291137922u, 5590532753172682214u, 5799235221864313914u, 140370455597977902u, 2025555993157185778u, 4192752931662582422u, 2864620100732154698u,
37658 11041922101731072190u, 9570786891571902818u, 11736905209177070342u, 13767318537498720986u, 17187672274535555022u, 17539385849830522386u, 15374150458257759350u, 14462604578592423338u,
37659 15486092620961298855u, 14629711868178897019u, 17092483903335922207u, 17355247692313779139u, 11624791503456485079u, 13600030943165030155u, 11137009302703308143u, 9754815117126884531u,
37660 4151744643171039047u, 2626583331457439387u, 162377516962444543u, 2282879863086044451u, 5631712546292871223u, 6037452326221451755u, 8501327171535303567u, 7499692239708246611u,
37661 11158140837063703266u, 9743299917872012094u, 11602602247471462746u, 13612749016692676742u, 17105661501857119634u, 17333526894853233742u, 15473963965085515306u, 14650238604571402230u,
37662 8479714083293312002u, 7512977616177960414u, 5652276691881064378u, 6025361010828170854u, 150824891399123826u, 2303974039851176622u, 4164354990367371466u, 2604286280411140374u,
37663 5659250822143950637u, 6009834889821986545u, 8454565055791594645u, 7546392787102457161u, 4121809449076176989u, 2656298618920900993u, 211263906290727909u, 2233791159333640761u,
37664 11672732454520566221u, 13552292306546298897u, 11106145987650286197u, 9785898338790069161u, 15440531030182573757u, 14675335027319969633u, 17121240571213837573u, 17326570184971408601u,
37665 196390824332639336u, 2258328937796115892u, 4135620394250371024u, 2632959299571932684u, 8431742436040817432u, 7560729365405768388u, 5683126765473888416u, 5994308631384381820u,
37666 17135610109059871368u, 17303780593489122132u, 15425108168748986672u, 14699314298944934124u, 11130580386221503992u, 9770921945649714212u, 11649360192741635648u, 13566070240564762524u,
37667 8426555122807220790u, 7574959341548112874u, 5704995856293652878u, 5963537623700588626u, 237294699245645126u, 2208312048661695642u, 4077480570845130494u, 2700071425513574178u,
37668 11206488369142506710u, 9686112028953249034u, 11554096377106556782u, 13670376701660284594u, 17023422649268413350u, 17424940338905547386u, 15556079663802671134u, 14559229772221530562u,
37669 4089596066908350835u, 2679540256679954607u, 224121464376355531u, 2230046074588744471u, 5727171952466636291u, 5950815117732351967u, 8405427952099257787u, 7586487769270013031u,
37670 15543464952953907091u, 14581513594800801359u, 17034988434643772459u, 17403850594581005815u, 11533527867866456291u, 13682454788587061567u, 11228114617197060955u, 9672831084924650119u,
37671 17046466186006768828u, 17401835225210195296u, 15513812278582275844u, 14601417988320120536u, 11181065506345364428u, 9711332585899690512u, 11598470443728627828u, 13625782737014311336u,
37672 280740911195955804u, 2165085734748128128u, 4051111986314371556u, 2726642315882184760u, 8385505863325164844u, 7616087770173211888u, 5729240201464309396u, 5939354855465699144u,
37673 11574598932837183481u, 13641322155266051621u, 11203874897631210561u, 9696991643941850525u, 15500005765847099529u, 14624770467483748693u, 17061326039500450609u, 17377293083093715693u,
37674 5752625691707646233u, 5925581285101240517u, 8361067032314929825u, 7631051003498906493u, 4066548076212889193u, 2702667407911749557u, 266366940911429073u, 2187862166416278541u,
37675 }, {
37676 0u, 6642096280510406750u, 13284192561020813500u, 16462795876764246242u, 16315823105410768893u, 13708963636559134627u, 6500836570635362113u, 439922346977066783u,
37677 6197597939812213119u, 733872460607717665u, 17174658310779658691u, 12859417258165748125u, 13001673141270724226u, 16736026809386770140u, 879844693954133566u, 5771540452186644064u,
37678 12395195879624426238u, 17305613297699152544u, 1467744921215435330u, 5220531075568771612u, 5650300446275329283u, 1316336633116425565u, 17740532779662220735u, 12258375912742239713u,
37679 18016332033719362433u, 11973850846087693279u, 4781749989466252093u, 2193612730179060579u, 1759689387908267132u, 4919860766213921826u, 11543080904373288128u, 18166453874549300382u,
37680 14614610554166352761u, 10879836598703668007u, 8253805222095936453u, 3361408799105547163u, 2935489842430870660u, 8399638907315561690u, 10441062151137543224u, 14757009366268798054u,
37681 11300600892550658566u, 13906759146888600152u, 2632673266232851130u, 8693166652788693732u, 9132946036408395259u, 2491556468171146661u, 14331668736193815879u, 11153489555886392601u,
37682 7409848711186274695u, 4249257595424012761u, 16037314857127418171u, 9413239572791867749u, 9563499978932504186u, 15606406401646028324u, 4387225460358121158u, 6976068332272625304u,
37683 3519378775816534264u, 7852640824571713702u, 9839721532427843652u, 15321459211647031322u, 15184496315767285509u, 10274783960564057947u, 7701371084599273401u, 3949009615571978215u,
37684 539203352115488887u, 6581683165424715817u, 13772373076031531211u, 16360516657443457173u, 16507610444191872906u, 13347445937900984276u, 6722817598211094326u, 99441604310980456u,
37685 5870979684861741320u, 960568039155968342u, 16799277814631123380u, 13046489736199563754u, 12904108438562707189u, 17238069777753355947u, 814716683761407561u, 6296880972452001303u,
37686 12357655745765665417u, 17821378201246059223u, 1379747099228580405u, 5694995023857257067u, 5265346532465702260u, 1530999186474390826u, 17386333305577387464u, 12494636173022434710u,
37687 18265892072816790518u, 11623803214076996520u, 4983112936342293322u, 1804507146630605588u, 2238305212630619147u, 4845162757404030037u, 12054694172541097143u, 18115614168568345833u,
37688 14819697422372549390u, 10486441695742104400u, 8498515190848025522u, 3016776137306395628u, 3442815973027425523u, 8352525304506551469u, 10925090729870978127u, 14677459070913039377u,
37689 11216336045685248625u, 14376925237369287215u, 2590274523633996493u, 9214355580338500243u, 8774450920716242316u, 2731551919773330898u, 13952136664545250608u, 11363291318662491502u,
37690 7038757551633068528u, 4432606169309893038u, 15705281649143427404u, 9644785238863483154u, 9494645848386137613u, 16136034042300943955u, 4294513027018469041u, 7472698529450626799u,
37691 4011857131457007759u, 7746628612951437521u, 10373500843358195763u, 15265904688119197805u, 15402742169198546802u, 9938598876682809132u, 7898019231143956430u, 3582070091934478224u,
37692 1078406704230977774u, 5970139571501035696u, 13163366330849431634u, 16897748309796073484u, 17049000381336047379u, 12733717820530814797u, 6107119981172920239u, 643361792051163121u,
37693 6410046491609887121u, 349161128571523535u, 16190407203032477997u, 13583585392940618099u, 13445635196422188652u, 16624205252526067250u, 198883208621960912u, 6840937431151644302u,
37694 11741959369723482640u, 18365299631022420558u, 1921136078311936684u, 5081265949533565682u, 4656338829252136429u, 2068229881835728307u, 17925537898651110737u, 11883093821164285199u,
37695 17650059563187254127u, 12167860639460954929u, 5524638460789093331u, 1190641388963713933u, 1629433367522815122u, 5382257181810330828u, 12593761944904002606u, 17504208224571739248u,
37696 14134199920450915223u, 10956049054195313609u, 8970094247992396587u, 2328741787718953845u, 2759494198457160810u, 8819954874021999668u, 11389990047714514134u, 13996106797082358920u,
37697 10530693064931404520u, 14846677937748691638u, 3061998372948781652u, 8526176301674629642u, 8091274350704555285u, 3198835872954668363u, 14416890915810522537u, 10682083699634542071u,
37698 7503655637611612521u, 3751252662574033207u, 15021960841764981205u, 10112215774463453579u, 9966225872684586644u, 15448000658827392714u, 3609014293261211176u, 7942304654960916086u,
37699 4476610425261238294u, 7065420035288041544u, 9690325514808060074u, 15733189881789008116u, 15874467260079749099u, 9250420838410950581u, 7212375292832610135u, 4051821833783301897u,
37700 688179623118076057u, 6170372224719608007u, 12814440204992854053u, 17148438651140642939u, 16997030381696051044u, 13244209591132604218u, 6033552274612791256u, 1123099122930255750u,
37701 6885631946054851046u, 262293608834169272u, 16705050609013102938u, 13544914965422553348u, 13683025758949262875u, 16271127284595091013u, 412415468322195111u, 6454862019777308409u,
37702 11927910341603441255u, 17988788832627006009u, 2148953154424896219u, 4755777988240824965u, 5180549047267992986u, 2001980365486523844u, 18428711160677000486u, 11786650616022549880u,
37703 17548901841432484632u, 12657171448130714438u, 5463103839546661796u, 1728714438829439994u, 1290082918514197733u, 5605359706950509755u, 12231113943998710873u, 17694874057198724103u,
37704 14077515103266137056u, 11488706867561743294u, 8865212338619786076u, 2822341649514070786u, 2391433177253116957u, 9015472726907116611u, 11054926469989481633u, 14215482952762858751u,
37705 10763369033251996319u, 14515766235920655041u, 3244216653174833699u, 8153963644554617469u, 8589026054036938082u, 3107253741862419772u, 14945397058901253598u, 10612099275430968704u,
37706 8023714262914015518u, 3707732413820797248u, 15493257225902875042u, 10029072425162228220u, 10174906129304731363u, 15067338284929851069u, 3850131242430201439u, 7584939832928591361u,
37707 4133108057121652833u, 7311251501606674495u, 9295800309597257949u, 15937155243838988419u, 15796038462287912860u, 9735579710801330114u, 7164140183868956448u, 4558017662132191102u,
37708 }, {
37709 0u, 7026975924517234630u, 14053951849034469260u, 11713158812725061706u, 1498566550037692829u, 8453026741656872539u, 15547077823203331601u, 13134332388348864983u,
37710 2997133100075385658u, 5193532126013515004u, 16906053483313745078u, 10023477084983765872u, 4421425403924087463u, 6690338751863514465u, 18326734871926164779u, 11516110084014746349u,
37711 5994266200150771316u, 3651077923391955378u, 10387064252027030008u, 17411644826573123134u, 5180286430728521705u, 2765428220391841839u, 9578516152858789989u, 16530863678517358499u,
37712 8842850807848174926u, 1962664170658947720u, 13380677503727028930u, 15579466327313067268u, 7958959654645957843u, 1150444288916906773u, 12500388506175163231u, 14771411239789669529u,
37713 11988532400301542632u, 14401112944851970862u, 7302155846783910756u, 347530691846251682u, 12867955000885349749u, 15208934917731379891u, 8186843028093092601u, 1160054057126929727u,
37714 10360572861457043410u, 17171366937719040020u, 5530856440783683678u, 3262112454209283992u, 11170013709381963343u, 18052407625221859721u, 6344013830343901635u, 4147432248901248517u,
37715 17685701615696349852u, 10733466276663946586u, 3925328341317895440u, 6340298665266291414u, 16265807495604570881u, 9241127928571882695u, 2500178400086410381u, 4843267757373072203u,
37716 15917919309291915686u, 13646779991004769888u, 2300888577833813546u, 9109287431904666092u, 14423962049646856251u, 12225267820500938749u, 803223682168014775u, 7683504840782913649u,
37717 16025789128531904341u, 13827140552201887891u, 2120809441137969369u, 9001136188144267039u, 14604311693567821512u, 12333148557000565006u, 695061383692503364u, 7503436758785666690u,
37718 17866059964468495471u, 10841338299774886825u, 3817174930229677027u, 6160221704524114981u, 16373686056186185202u, 9421479739856314932u, 2320108114253859454u, 4735107671358188984u,
37719 10180636633891078433u, 17063072784830850791u, 5638869205660782253u, 3442330069771397483u, 11061712881567367356u, 17872478072565786490u, 6524224908418567984u, 4255451551249279222u,
37720 11880240423364919835u, 14221174549956093405u, 7482375666214882711u, 455541244296276561u, 12688027660687803270u, 15100631886079386688u, 8294864497802497034u, 1340262959281482700u,
37721 8662912472460168125u, 1854372134182743163u, 13488687978245964849u, 15759686224643400695u, 7850656682635790880u, 970516889046347238u, 12680597330532582828u, 14879432787265004138u,
37722 5885971969496909959u, 3471141773623390017u, 10567281927262422795u, 17519657531808653517u, 5000356800172820762u, 2657127470508076764u, 9686535514746144406u, 16711074697083887952u,
37723 3105005063510429129u, 5373890534425651727u, 16725976600334615109u, 9915323596096578947u, 4601777155667627092u, 6798217371950640018u, 18218574863809332184u, 11336039720248747038u,
37724 180360639130832627u, 7134845665859430709u, 13945800545768817023u, 11533079735570376377u, 1606447364336029550u, 8633376307814525096u, 15367009681565827298u, 13026170149548992292u,
37725 3321048140255203375u, 5733767250183223273u, 17086394267351834531u, 10131907641284540517u, 4241618882275938738u, 6582455852881933940u, 18002272376288534078u, 10975340495589554680u,
37726 540800415553098517u, 7351451582082282707u, 14161821513074465945u, 11892934580260027231u, 1390122767385006728u, 8272655212095272270u, 15006873517571333380u, 12810430501506267842u,
37727 9023334491325470299u, 2070960623556915613u, 13704726720259086807u, 16119558478964112913u, 7634349860459354054u, 609813203025260544u, 12320443409048229962u, 14663675712440713100u,
37728 6101997361665611105u, 3831000989484282535u, 10927717295939115757u, 17736259059608567083u, 4640216228507718908u, 2441383434118427450u, 9470215342716377968u, 16350357972595129526u,
37729 9820495924665654471u, 16847328885758262017u, 5422549171225416523u, 3081613207998608525u, 11277738411321564506u, 18232337151134792348u, 6884660139542794966u, 4472053216375158032u,
37730 11663933463862517757u, 13860471001487472699u, 7122221882022416497u, 239784031886489527u, 13048449816837135968u, 15317220237859158438u, 8510903102498558444u, 1700135351162517034u,
37731 15809464669166377651u, 13466419319190748533u, 1760673139591009599u, 8785396677427507961u, 14964751332429765422u, 12549754610540477672u, 911082488592553122u, 7863291466191287140u,
37732 17505901828360837513u, 10625576643111779919u, 3600872305391818245u, 5799522617425244611u, 16589728995604994068u, 9781356593166352338u, 2680525918562965400u, 4951691578960654430u,
37733 17325824944920336250u, 10517423154702741692u, 3708744268365486326u, 5979881026315534128u, 16481568986909349607u, 9601286230029496609u, 2860877669727689067u, 5059570199676927661u,
37734 15701313365271581760u, 13286340242614875014u, 1941033778092694476u, 8893266419348519946u, 14784683190314112477u, 12441592372201976347u, 1018963302412737105u, 8043641032810315159u,
37735 11771943938993819918u, 14040690898222216904u, 6942283547246780034u, 131491994814691652u, 13228658641689481363u, 15425241784889898837u, 8402600130983321375u, 1520207950847359193u,
37736 10000713600345641524u, 16955341590498866674u, 5314254941016153528u, 2901677057735113342u, 11385757773804508073u, 18412548169088955503u, 6704730509582687269u, 4363752465879022563u,
37737 6210010127020858258u, 4011218604585024596u, 10747781068851303454u, 17627964906259002328u, 4820427307211528719u, 2549402735887646153u, 9361914515530929539u, 16170428419360240197u,
37738 9203554311335254184u, 2178971175377796974u, 13596434743901280036u, 15939620083439087842u, 7742371330630129973u, 790022104701665011u, 12140516069312059065u, 14555372680310567295u,
37739 360721278261665254u, 7243300338934250016u, 14269691331718861418u, 12073295142069515692u, 1281960468464901243u, 8092587130592951229u, 15187223161047700471u, 12918311238500824113u,
37740 3212894728672059100u, 5553690289885640986u, 17266752615629050192u, 10239779664840078998u, 4061548595831021377u, 6474295767462639751u, 18110150936257777869u, 11155692307469580043u,
37741 }, {
37742 0u, 2517245393515406572u, 5034490787030813144u, 7435750759411199284u, 10068981574061626288u, 12201157653998401372u, 14871501518822398568u, 17045318164640841348u,
37743 9628913577918544357u, 12056075433989135625u, 13870769438669140029u, 16326061061730899153u, 1016952077871524437u, 3239211695253081785u, 5459183210385793933u, 7578968205522831201u,
37744 11067918171351838031u, 13508029996328618403u, 15872723984458359959u, 18349972777811820667u, 1307470557354262271u, 3515654148887976467u, 6339673239971903271u, 8436375012170683339u,
37745 2033904155743048874u, 4528066323082129478u, 6478423390506163570u, 8865607338129291678u, 10918366420771587866u, 13072499669943034870u, 15157936411045662402u, 17344703028974807598u,
37746 11667391723826758683u, 9441211325989495031u, 16444045520167767491u, 14329311757255665967u, 3050858413050517419u, 628778578755597127u, 8036894684654706291u, 5577642697640442527u,
37747 2614941114708524542u, 478839856218937618u, 7031308297775952934u, 4862538486186004682u, 12679346479943806542u, 10167187506301176482u, 16872750024341366678u, 14467534086004917114u,
37748 4067808311486097748u, 1917635425212288440u, 9056132646164258956u, 6864284009665987680u, 12956846781012327140u, 10457633378212404744u, 17731214676258583356u, 15347951510183778256u,
37749 13678285260964991153u, 11474057634298917981u, 17873974704293108073u, 15772186515461651845u, 3922409453435093761u, 1477250791027468269u, 8336488571297909465u, 5863164957556321845u,
37750 15063804914172139187u, 17573731408537121375u, 10724047561790938987u, 13131499433903012743u, 6535100908406441219u, 8673469987586793967u, 2265113888856263899u, 4431612735036172343u,
37751 6101716826101034838u, 8521560882533092282u, 1257557157511194254u, 3719041779816530530u, 16073789369309412582u, 18302240886422657034u, 11155285395280885054u, 13267751491267498450u,
37752 5229882229417049084u, 7672809353916620560u, 957679712437875236u, 3433240205686757064u, 14062616595551905868u, 16269110787469675680u, 9725076972372009364u, 11824592944582215032u,
37753 14786588404820918809u, 17283564772171425525u, 9865866699426761665u, 12251361247433944877u, 5082513026899726761u, 7234957975966594373u, 240568853608110193u, 2430150771060047005u,
37754 8135616622972195496u, 5911125624750880324u, 3835270850424576880u, 1717722887501053852u, 18112265292328517912u, 15687370158510810612u, 13728568019331975360u, 11271004332422294572u,
37755 17674167644946721613u, 15539754686561718177u, 12725302718847165077u, 10553717607734429305u, 9150035367232403709u, 6635062193578351633u, 4261933579054297381u, 1858407040333796809u,
37756 16825062113507622887u, 14668696227990231819u, 12439147139764057663u, 10254616302904316627u, 7116415003206659159u, 4624520499557157051u, 2818284765131990415u, 428829699325493603u,
37757 7844818906870187522u, 5634399380472423150u, 2954501582054936538u, 860032292373900086u, 16672977142595818930u, 14235136279826723166u, 11726329915112643690u, 9246813302127474822u,
37758 3513487962258617315u, 1309817375275636495u, 8438743075148003899u, 6337546835477044951u, 13510341259434958931u, 11065716548023207103u, 18347741267953084811u, 15874986514718330215u,
37759 13070201816812882438u, 10920562880461237994u, 17346939975173587934u, 15155660198108440370u, 4530227777712527798u, 2031571415669472602u, 8863225470072344686u, 6480554254231811202u,
37760 12203433652202069676u, 10066744842596399680u, 17043121765066184564u, 14873799311837557656u, 2515114315022388508u, 2382082824317424u, 7438083559633061060u, 5032329272252129320u,
37761 3241337884980569929u, 1014584229661574053u, 7576621447749742225u, 5461349336866867837u, 12053812688995611897u, 9631145302510833685u, 16328262745174523169u, 13868458115447806413u,
37762 10459764458834098168u, 12954464700354433812u, 15345618707833241120u, 17733376188870843084u, 1915359424875750472u, 4070045040789094564u, 6866480411373514128u, 9053834855311329660u,
37763 1479513538183220765u, 3920177730975673073u, 5860963271950469061u, 8338799892386374441u, 11471931442405006765u, 13680653107046267201u, 15774533275401163893u, 17871808579940708505u,
37764 626467317811485367u, 3053060038512016987u, 5579874205336949615u, 8034632152261867395u, 9443377510452431111u, 11665044903776710123u, 14326943696444768479u, 16446171926791300147u,
37765 10165026053799453522u, 12681679222183806910u, 14469915951933188746u, 16870619158449294950u, 481137707216220386u, 2612744652856644622u, 4860301542120094010u, 7033584512875404758u,
37766 16271233245944390992u, 14060243759811248572u, 11822251249501760648u, 9727246909562751076u, 7670541700849153760u, 5232109988680716812u, 3435445775002107704u, 955373222128557012u,
37767 7237229143405862069u, 5080272407415421017u, 2427958334666397037u, 242871556844564865u, 17281429885116092165u, 14788965422804986857u, 12253699033039161053u, 9863708918048465457u,
37768 8671167069616523295u, 6537293559533907187u, 4433853414635209159u, 2262842661302265131u, 17575888975148309423u, 15061467343334031171u, 13129122476067492471u, 10726182388697724571u,
37769 18300070734464807418u, 16076131279156974870u, 13270124387156703266u, 11153162876657622222u, 8523867158108594762u, 6099511471519499942u, 3716814080667593618u, 1259824750463930238u,
37770 4622362935074513227u, 7118752576211060135u, 431206655032469651u, 2816149936058911871u, 14670999143827763963u, 16822869460218058263u, 10252375625438018339u, 12441418369480155087u,
37771 14232830006413318318u, 16675182499310091330u, 9249040999114314102u, 11724062320027170202u, 5636569530263980830u, 7842476994894082034u, 857659398650987206u, 2956624102806742570u,
37772 15689637813740375044u, 18110037535197587688u, 11268798760944846300u, 13730874507508556080u, 5909003164109873076u, 8137989456584309592u, 1720064584747800172u, 3833100915362378368u,
37773 6637197082762229217u, 9147658351414628621u, 1856069252600036409u, 4264091358266300629u, 15537483516989711953u, 17676408262268928701u, 10555910046260817801u, 12723000017772809061u,
37774 }, {
37775 0u, 15762200328042667840u, 2856835172924432389u, 18238190752146915141u, 5713670345848864778u, 10805715811487326026u, 7561135427655163919u, 12848797446532677455u,
37776 11427340691697729556u, 4911321075843194708u, 13345174655120580625u, 7173389830452510545u, 15122270855310327838u, 820654137405644638u, 17760118084036943899u, 3226275954771115867u,
37777 12678913378224905901u, 8451595299172663789u, 9822642151686389416u, 5976168202979041768u, 16194808345499688615u, 4179641502022828519u, 14346779660905021090u, 2135996745225445858u,
37778 3558579666237890233u, 16995468946051088889u, 1641308274811289276u, 14733962144962732540u, 9090961916423626419u, 11859948271085519347u, 6452551909542231734u, 9453764156601606646u,
37779 14785799433083167711u, 1697614691135618207u, 16903190598345327578u, 3470771065211313306u, 9402037001392841685u, 6396285171454065813u, 11952336405958083536u, 9178809987380452496u,
37780 6027971268800324555u, 9878982515431963787u, 8359283004045657038u, 12591138999497481358u, 2084233168694272961u, 14290549069261356161u, 4271993490450891716u, 16282692837778922628u,
37781 7117159332475780466u, 13293411258189767218u, 4999205320339463543u, 11519692655715205687u, 3282616549622578552u, 17811921192019632696u, 732879648334208381u, 15029958398333780541u,
37782 18181923832847252838u, 2805107922438644262u, 15850048426093911395u, 92388385340408355u, 12905103819084463468u, 7612972483059622444u, 10717907374994120041u, 5621392111171994153u,
37783 629311348378851643u, 15133597752622646907u, 3395229382271236414u, 17699378041462564478u, 5183867188229904689u, 11335100742646646385u, 6941542130422626612u, 13469099241846138484u,
37784 10821536956051937583u, 5517832210058282607u, 12792570342908131626u, 7725577015716947562u, 15665448522205731109u, 277059068684322405u, 18357619974760904992u, 2629481737494357600u,
37785 12055942537600649110u, 9075274912216783062u, 9289461107078326163u, 6508930745710590163u, 16718566008091314076u, 3655465612432595164u, 14961454118931310489u, 1522030784741112025u,
37786 4168466337388545922u, 16386289672930760898u, 2196870928291817351u, 14177982363995224263u, 8543986980901783432u, 12406505804242475208u, 5852377756745475981u, 10054645982306597069u,
37787 14234318664951560932u, 2248669261341992356u, 16298510681658284769u, 4076149859246245281u, 9998410640678927086u, 5800610134637962670u, 12494386096293518059u, 8636334373997692331u,
37788 6565233099245157104u, 9341293662428177840u, 8987461698644630261u, 11963660006880118197u, 1465759296668416762u, 14909722918146729402u, 3743309483160705791u, 16810949547632248255u,
37789 7673845564465570889u, 12736298827739970313u, 5610215844877288524u, 10909381007990496012u, 2681314179816367171u, 18413922163761052419u, 184776770680816710u, 15577635352405072646u,
37790 17647610443766686813u, 3338994288425483037u, 15225944966119244888u, 717191546761911064u, 13520897736746902615u, 6997878541721926423u, 11242784222343988306u, 5096087965850491666u,
37791 1258622696757703286u, 14684288965200833846u, 3950222953022231155u, 17036158029906267443u, 6790458764542472828u, 9548224856613104956u, 8762045755503235705u, 11756540858562383161u,
37792 10367734376459809378u, 6151638724996853026u, 12124837022850257511u, 8285082520580115751u, 13883084260845253224u, 1879138195689975080u, 16649556998353834605u, 4445490780332133677u,
37793 13727827248377474267u, 7223104792207356827u, 11035664420116565214u, 4870673773980832670u, 17422178244240010449u, 3131857036752565137u, 15451154031433895124u, 924103331921597332u,
37794 2311784730144877775u, 18062687245331231631u, 554118137368644810u, 15928680121837474698u, 8024872609708797125u, 13105623011270275973u, 5258963474988715200u, 10539833548380279680u,
37795 15872427342139003305u, 502333042764009193u, 18150549824433566124u, 2404114375865757420u, 10596187595637903779u, 5310779519913856739u, 13017861491421180326u, 7932573568563556070u,
37796 4814384572959953341u, 10983915471956430589u, 7310931224865190328u, 13820193315420761848u, 980423156880069047u, 15503004023780282103u, 3044061569482224050u, 17329913425393921778u,
37797 8336932674777091844u, 12181156958151692356u, 6059373863990406913u, 10279938678082531393u, 4393741856583634702u, 16593268045114871886u, 1971504083133951755u, 13970910599835103307u,
37798 17087973961803566864u, 4006576835745435728u, 14591990156772618005u, 1170861220680101973u, 11704755513490951962u, 8705792948709298266u, 9640554597612056351u, 6878321524855255135u,
37799 1858937689852799821u, 14083548048513152013u, 4497338522683984712u, 16489741062169236488u, 6235036951360285511u, 10104345546597921799u, 8152299718492490562u, 12365860697102636034u,
37800 9753200483853429593u, 6765745319621112857u, 11601220269275925340u, 8809399250468705308u, 14416405870873226067u, 1346516287098352659u, 17272668747995384662u, 3821952007586370582u,
37801 13130466198490314208u, 7820039919040899744u, 10492627387899532773u, 5414409408661555877u, 17974923397289260522u, 2579810761044912810u, 16057098401758057967u, 317732763665910447u,
37802 2931518593336833524u, 17442526084696124084u, 1084062204544407025u, 15399436031514938033u, 7486618966321411582u, 13644576356632980158u, 4629793036166665723u, 11168576964637084347u,
37803 15347691128931141778u, 1027777753507534802u, 17534896747071563927u, 3019349226222860247u, 11220431689754577048u, 4686116923914377176u, 13552315720802183325u, 7398828111596124125u,
37804 5362628359632734342u, 10436379358185592774u, 7912374160093407363u, 13218332977821366211u, 369553541361633420u, 16113456511805446092u, 2487515902914439305u, 17887166489985742793u,
37805 8865757316743550527u, 11653040814255671679u, 6677988576850966074u, 9660905738751846778u, 3765703796660934197u, 17220887603689539957u, 1434383093523822128u, 14508740362393577840u,
37806 16546065181022836267u, 4549193289962883435u, 13995757083443852846u, 1766676892172462446u, 12309576339732698657u, 8100554995509053793u, 10192175931700983332u, 6327407589325138276u,
37810 static const uint8_t
37811 WUFFS_CRC64__ECMA_X86_SSE42_FOLD1[16] WUFFS_BASE__POTENTIALLY_UNUSED = {
37812 228u, 58u, 57u, 202u, 151u, 212u, 93u, 224u,
37813 64u, 95u, 135u, 199u, 175u, 149u, 190u, 218u,
37816 static const uint8_t
37817 WUFFS_CRC64__ECMA_X86_SSE42_FOLD2[16] WUFFS_BASE__POTENTIALLY_UNUSED = {
37818 68u, 250u, 158u, 138u, 0u, 91u, 9u, 96u,
37819 81u, 175u, 225u, 15u, 163u, 83u, 230u, 59u,
37822 static const uint8_t
37823 WUFFS_CRC64__ECMA_X86_SSE42_FOLD4[16] WUFFS_BASE__POTENTIALLY_UNUSED = {
37824 243u, 65u, 212u, 157u, 187u, 239u, 227u, 106u,
37825 244u, 45u, 132u, 167u, 84u, 96u, 31u, 8u,
37828 static const uint8_t
37829 WUFFS_CRC64__ECMA_X86_SSE42_FOLD8[16] WUFFS_BASE__POTENTIALLY_UNUSED = {
37830 0u, 16u, 204u, 79u, 29u, 215u, 87u, 135u,
37831 64u, 231u, 61u, 247u, 42u, 107u, 216u, 215u,
37834 static const uint8_t
37835 WUFFS_CRC64__ECMA_X86_SSE42_MUPX[16] WUFFS_BASE__POTENTIALLY_UNUSED = {
37836 213u, 99u, 41u, 23u, 108u, 70u, 62u, 156u,
37837 133u, 30u, 14u, 175u, 43u, 175u, 216u, 146u,
37840 // ---------------- Private Initializer Prototypes
37842 // ---------------- Private Function Prototypes
37844 WUFFS_BASE__GENERATED_C_CODE
37845 static wuffs_base__empty_struct
37846 wuffs_crc64__ecma_hasher__up(
37847 wuffs_crc64__ecma_hasher* self,
37848 wuffs_base__slice_u8 a_x);
37850 WUFFS_BASE__GENERATED_C_CODE
37851 static wuffs_base__empty_struct
37852 wuffs_crc64__ecma_hasher__up__choosy_default(
37853 wuffs_crc64__ecma_hasher* self,
37854 wuffs_base__slice_u8 a_x);
37856 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
37857 WUFFS_BASE__GENERATED_C_CODE
37858 static wuffs_base__empty_struct
37859 wuffs_crc64__ecma_hasher__up_x86_sse42(
37860 wuffs_crc64__ecma_hasher* self,
37861 wuffs_base__slice_u8 a_x);
37862 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
37864 // ---------------- VTables
37866 const wuffs_base__hasher_u64__func_ptrs
37867 wuffs_crc64__ecma_hasher__func_ptrs_for__wuffs_base__hasher_u64 = {
37868 (uint64_t(*)(const void*))(&wuffs_crc64__ecma_hasher__checksum_u64),
37869 (uint64_t(*)(const void*,
37870 uint32_t))(&wuffs_crc64__ecma_hasher__get_quirk),
37871 (wuffs_base__status(*)(void*,
37872 uint32_t,
37873 uint64_t))(&wuffs_crc64__ecma_hasher__set_quirk),
37874 (wuffs_base__empty_struct(*)(void*,
37875 wuffs_base__slice_u8))(&wuffs_crc64__ecma_hasher__update),
37876 (uint64_t(*)(void*,
37877 wuffs_base__slice_u8))(&wuffs_crc64__ecma_hasher__update_u64),
37880 // ---------------- Initializer Implementations
37882 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
37883 wuffs_crc64__ecma_hasher__initialize(
37884 wuffs_crc64__ecma_hasher* self,
37885 size_t sizeof_star_self,
37886 uint64_t wuffs_version,
37887 uint32_t options){
37888 if (!self) {
37889 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
37891 if (sizeof(*self) != sizeof_star_self) {
37892 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
37894 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
37895 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
37896 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
37899 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
37900 // The whole point of this if-check is to detect an uninitialized *self.
37901 // We disable the warning on GCC. Clang-5.0 does not have this warning.
37902 #if !defined(__clang__) && defined(__GNUC__)
37903 #pragma GCC diagnostic push
37904 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
37905 #endif
37906 if (self->private_impl.magic != 0) {
37907 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
37909 #if !defined(__clang__) && defined(__GNUC__)
37910 #pragma GCC diagnostic pop
37911 #endif
37912 } else {
37913 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
37914 memset(self, 0, sizeof(*self));
37915 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
37916 } else {
37917 memset(&(self->private_impl), 0, sizeof(self->private_impl));
37921 self->private_impl.choosy_up = &wuffs_crc64__ecma_hasher__up__choosy_default;
37923 self->private_impl.magic = WUFFS_BASE__MAGIC;
37924 self->private_impl.vtable_for__wuffs_base__hasher_u64.vtable_name =
37925 wuffs_base__hasher_u64__vtable_name;
37926 self->private_impl.vtable_for__wuffs_base__hasher_u64.function_pointers =
37927 (const void*)(&wuffs_crc64__ecma_hasher__func_ptrs_for__wuffs_base__hasher_u64);
37928 return wuffs_base__make_status(NULL);
37931 wuffs_crc64__ecma_hasher*
37932 wuffs_crc64__ecma_hasher__alloc(void) {
37933 wuffs_crc64__ecma_hasher* x =
37934 (wuffs_crc64__ecma_hasher*)(calloc(1, sizeof(wuffs_crc64__ecma_hasher)));
37935 if (!x) {
37936 return NULL;
37938 if (wuffs_crc64__ecma_hasher__initialize(
37939 x, sizeof(wuffs_crc64__ecma_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
37940 free(x);
37941 return NULL;
37943 return x;
37946 size_t
37947 sizeof__wuffs_crc64__ecma_hasher(void) {
37948 return sizeof(wuffs_crc64__ecma_hasher);
37951 // ---------------- Function Implementations
37953 // -------- func crc64.ecma_hasher.get_quirk
37955 WUFFS_BASE__GENERATED_C_CODE
37956 WUFFS_BASE__MAYBE_STATIC uint64_t
37957 wuffs_crc64__ecma_hasher__get_quirk(
37958 const wuffs_crc64__ecma_hasher* self,
37959 uint32_t a_key) {
37960 if (!self) {
37961 return 0;
37963 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
37964 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
37965 return 0;
37968 return 0u;
37971 // -------- func crc64.ecma_hasher.set_quirk
37973 WUFFS_BASE__GENERATED_C_CODE
37974 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
37975 wuffs_crc64__ecma_hasher__set_quirk(
37976 wuffs_crc64__ecma_hasher* self,
37977 uint32_t a_key,
37978 uint64_t a_value) {
37979 if (!self) {
37980 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
37982 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
37983 return wuffs_base__make_status(
37984 (self->private_impl.magic == WUFFS_BASE__DISABLED)
37985 ? wuffs_base__error__disabled_by_previous_error
37986 : wuffs_base__error__initialize_not_called);
37989 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
37992 // -------- func crc64.ecma_hasher.update
37994 WUFFS_BASE__GENERATED_C_CODE
37995 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
37996 wuffs_crc64__ecma_hasher__update(
37997 wuffs_crc64__ecma_hasher* self,
37998 wuffs_base__slice_u8 a_x) {
37999 if (!self) {
38000 return wuffs_base__make_empty_struct();
38002 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
38003 return wuffs_base__make_empty_struct();
38006 if (self->private_impl.f_state == 0u) {
38007 self->private_impl.choosy_up = (
38008 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
38009 wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_crc64__ecma_hasher__up_x86_sse42 :
38010 #endif
38011 self->private_impl.choosy_up);
38013 wuffs_crc64__ecma_hasher__up(self, a_x);
38014 return wuffs_base__make_empty_struct();
38017 // -------- func crc64.ecma_hasher.update_u64
38019 WUFFS_BASE__GENERATED_C_CODE
38020 WUFFS_BASE__MAYBE_STATIC uint64_t
38021 wuffs_crc64__ecma_hasher__update_u64(
38022 wuffs_crc64__ecma_hasher* self,
38023 wuffs_base__slice_u8 a_x) {
38024 if (!self) {
38025 return 0;
38027 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
38028 return 0;
38031 wuffs_crc64__ecma_hasher__update(self, a_x);
38032 return wuffs_crc64__ecma_hasher__checksum_u64(self);
38035 // -------- func crc64.ecma_hasher.up
38037 WUFFS_BASE__GENERATED_C_CODE
38038 static wuffs_base__empty_struct
38039 wuffs_crc64__ecma_hasher__up(
38040 wuffs_crc64__ecma_hasher* self,
38041 wuffs_base__slice_u8 a_x) {
38042 return (*self->private_impl.choosy_up)(self, a_x);
38045 WUFFS_BASE__GENERATED_C_CODE
38046 static wuffs_base__empty_struct
38047 wuffs_crc64__ecma_hasher__up__choosy_default(
38048 wuffs_crc64__ecma_hasher* self,
38049 wuffs_base__slice_u8 a_x) {
38050 uint64_t v_s = 0;
38051 wuffs_base__slice_u8 v_p = {0};
38053 v_s = (18446744073709551615u ^ self->private_impl.f_state);
38055 wuffs_base__slice_u8 i_slice_p = a_x;
38056 v_p.ptr = i_slice_p.ptr;
38057 v_p.len = 8;
38058 const uint8_t* i_end0_p = wuffs_private_impl__ptr_u8_plus_len(v_p.ptr, (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 8) * 8));
38059 while (v_p.ptr < i_end0_p) {
38060 v_s ^= ((((uint64_t)(v_p.ptr[0u])) << 0u) |
38061 (((uint64_t)(v_p.ptr[1u])) << 8u) |
38062 (((uint64_t)(v_p.ptr[2u])) << 16u) |
38063 (((uint64_t)(v_p.ptr[3u])) << 24u) |
38064 (((uint64_t)(v_p.ptr[4u])) << 32u) |
38065 (((uint64_t)(v_p.ptr[5u])) << 40u) |
38066 (((uint64_t)(v_p.ptr[6u])) << 48u) |
38067 (((uint64_t)(v_p.ptr[7u])) << 56u));
38068 v_s = (WUFFS_CRC64__ECMA_TABLE[0u][(255u & (v_s >> 56u))] ^
38069 WUFFS_CRC64__ECMA_TABLE[1u][(255u & (v_s >> 48u))] ^
38070 WUFFS_CRC64__ECMA_TABLE[2u][(255u & (v_s >> 40u))] ^
38071 WUFFS_CRC64__ECMA_TABLE[3u][(255u & (v_s >> 32u))] ^
38072 WUFFS_CRC64__ECMA_TABLE[4u][(255u & (v_s >> 24u))] ^
38073 WUFFS_CRC64__ECMA_TABLE[5u][(255u & (v_s >> 16u))] ^
38074 WUFFS_CRC64__ECMA_TABLE[6u][(255u & (v_s >> 8u))] ^
38075 WUFFS_CRC64__ECMA_TABLE[7u][(255u & (v_s >> 0u))]);
38076 v_p.ptr += 8;
38078 v_p.len = 1;
38079 const uint8_t* i_end1_p = wuffs_private_impl__ptr_u8_plus_len(i_slice_p.ptr, i_slice_p.len);
38080 while (v_p.ptr < i_end1_p) {
38081 v_s = (WUFFS_CRC64__ECMA_TABLE[0u][((uint8_t)(((uint8_t)(v_s)) ^ v_p.ptr[0u]))] ^ (v_s >> 8u));
38082 v_p.ptr += 1;
38084 v_p.len = 0;
38086 self->private_impl.f_state = (18446744073709551615u ^ v_s);
38087 return wuffs_base__make_empty_struct();
38090 // -------- func crc64.ecma_hasher.checksum_u64
38092 WUFFS_BASE__GENERATED_C_CODE
38093 WUFFS_BASE__MAYBE_STATIC uint64_t
38094 wuffs_crc64__ecma_hasher__checksum_u64(
38095 const wuffs_crc64__ecma_hasher* self) {
38096 if (!self) {
38097 return 0;
38099 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
38100 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
38101 return 0;
38104 return self->private_impl.f_state;
38107 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
38108 // -------- func crc64.ecma_hasher.up_x86_sse42
38110 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
38111 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
38112 WUFFS_BASE__GENERATED_C_CODE
38113 static wuffs_base__empty_struct
38114 wuffs_crc64__ecma_hasher__up_x86_sse42(
38115 wuffs_crc64__ecma_hasher* self,
38116 wuffs_base__slice_u8 a_x) {
38117 uint64_t v_s = 0;
38118 wuffs_base__slice_u8 v_p = {0};
38119 uint8_t v_buf[48] = {0};
38120 __m128i v_xa = {0};
38121 __m128i v_xb = {0};
38122 __m128i v_xc = {0};
38123 __m128i v_xd = {0};
38124 __m128i v_xe = {0};
38125 __m128i v_xf = {0};
38126 __m128i v_xg = {0};
38127 __m128i v_xh = {0};
38128 __m128i v_mu1 = {0};
38129 __m128i v_mu2 = {0};
38130 __m128i v_mu4 = {0};
38131 __m128i v_mu8 = {0};
38132 __m128i v_mupx = {0};
38134 v_s = (18446744073709551615u ^ self->private_impl.f_state);
38135 while ((((uint64_t)(a_x.len)) > 0u) && ((15u & ((uint32_t)(0xFFFu & (uintptr_t)(a_x.ptr)))) != 0u)) {
38136 v_s = (WUFFS_CRC64__ECMA_TABLE[0u][((uint8_t)(((uint8_t)(v_s)) ^ a_x.ptr[0u]))] ^ (v_s >> 8u));
38137 a_x = wuffs_base__slice_u8__subslice_i(a_x, 1u);
38139 do {
38140 do {
38141 if (((uint64_t)(a_x.len)) >= 128u) {
38142 } else if (((uint64_t)(a_x.len)) >= 64u) {
38143 v_xa = _mm_xor_si128(_mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 0u)), _mm_cvtsi64_si128((int64_t)(v_s)));
38144 v_xb = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 16u));
38145 v_xc = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 32u));
38146 v_xd = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 48u));
38147 a_x = wuffs_base__slice_u8__subslice_i(a_x, 64u);
38148 break;
38149 } else if (((uint64_t)(a_x.len)) >= 32u) {
38150 v_xa = _mm_xor_si128(_mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 0u)), _mm_cvtsi64_si128((int64_t)(v_s)));
38151 v_xb = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 16u));
38152 a_x = wuffs_base__slice_u8__subslice_i(a_x, 32u);
38153 goto label__chain2__break;
38154 } else {
38156 wuffs_base__slice_u8 i_slice_p = a_x;
38157 v_p.ptr = i_slice_p.ptr;
38158 v_p.len = 1;
38159 const uint8_t* i_end0_p = wuffs_private_impl__ptr_u8_plus_len(i_slice_p.ptr, i_slice_p.len);
38160 while (v_p.ptr < i_end0_p) {
38161 v_s = (WUFFS_CRC64__ECMA_TABLE[0u][((uint8_t)(((uint8_t)(v_s)) ^ v_p.ptr[0u]))] ^ (v_s >> 8u));
38162 v_p.ptr += 1;
38164 v_p.len = 0;
38166 self->private_impl.f_state = (18446744073709551615u ^ v_s);
38167 return wuffs_base__make_empty_struct();
38169 v_xa = _mm_xor_si128(_mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 0u)), _mm_cvtsi64_si128((int64_t)(v_s)));
38170 v_xb = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 16u));
38171 v_xc = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 32u));
38172 v_xd = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 48u));
38173 v_xe = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 64u));
38174 v_xf = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 80u));
38175 v_xg = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 96u));
38176 v_xh = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 112u));
38177 a_x = wuffs_base__slice_u8__subslice_i(a_x, 128u);
38178 v_mu8 = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC64__ECMA_X86_SSE42_FOLD8));
38179 while (((uint64_t)(a_x.len)) >= 128u) {
38180 v_xa = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xa, v_mu8, (int32_t)(0u)), _mm_clmulepi64_si128(v_xa, v_mu8, (int32_t)(17u))), _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 0u)));
38181 v_xb = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xb, v_mu8, (int32_t)(0u)), _mm_clmulepi64_si128(v_xb, v_mu8, (int32_t)(17u))), _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 16u)));
38182 v_xc = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xc, v_mu8, (int32_t)(0u)), _mm_clmulepi64_si128(v_xc, v_mu8, (int32_t)(17u))), _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 32u)));
38183 v_xd = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xd, v_mu8, (int32_t)(0u)), _mm_clmulepi64_si128(v_xd, v_mu8, (int32_t)(17u))), _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 48u)));
38184 v_xe = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xe, v_mu8, (int32_t)(0u)), _mm_clmulepi64_si128(v_xe, v_mu8, (int32_t)(17u))), _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 64u)));
38185 v_xf = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xf, v_mu8, (int32_t)(0u)), _mm_clmulepi64_si128(v_xf, v_mu8, (int32_t)(17u))), _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 80u)));
38186 v_xg = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xg, v_mu8, (int32_t)(0u)), _mm_clmulepi64_si128(v_xg, v_mu8, (int32_t)(17u))), _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 96u)));
38187 v_xh = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xh, v_mu8, (int32_t)(0u)), _mm_clmulepi64_si128(v_xh, v_mu8, (int32_t)(17u))), _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 112u)));
38188 a_x = wuffs_base__slice_u8__subslice_i(a_x, 128u);
38190 v_mu4 = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC64__ECMA_X86_SSE42_FOLD4));
38191 v_xa = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xa, v_mu4, (int32_t)(0u)), _mm_clmulepi64_si128(v_xa, v_mu4, (int32_t)(17u))), v_xe);
38192 v_xb = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xb, v_mu4, (int32_t)(0u)), _mm_clmulepi64_si128(v_xb, v_mu4, (int32_t)(17u))), v_xf);
38193 v_xc = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xc, v_mu4, (int32_t)(0u)), _mm_clmulepi64_si128(v_xc, v_mu4, (int32_t)(17u))), v_xg);
38194 v_xd = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xd, v_mu4, (int32_t)(0u)), _mm_clmulepi64_si128(v_xd, v_mu4, (int32_t)(17u))), v_xh);
38195 if (((uint64_t)(a_x.len)) > 64u) {
38196 v_xa = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xa, v_mu4, (int32_t)(0u)), _mm_clmulepi64_si128(v_xa, v_mu4, (int32_t)(17u))), _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 0u)));
38197 v_xb = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xb, v_mu4, (int32_t)(0u)), _mm_clmulepi64_si128(v_xb, v_mu4, (int32_t)(17u))), _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 16u)));
38198 v_xc = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xc, v_mu4, (int32_t)(0u)), _mm_clmulepi64_si128(v_xc, v_mu4, (int32_t)(17u))), _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 32u)));
38199 v_xd = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xd, v_mu4, (int32_t)(0u)), _mm_clmulepi64_si128(v_xd, v_mu4, (int32_t)(17u))), _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 48u)));
38200 a_x = wuffs_base__slice_u8__subslice_i(a_x, 64u);
38202 } while (0);
38203 v_mu2 = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC64__ECMA_X86_SSE42_FOLD2));
38204 v_xa = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xa, v_mu2, (int32_t)(0u)), _mm_clmulepi64_si128(v_xa, v_mu2, (int32_t)(17u))), v_xc);
38205 v_xb = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xb, v_mu2, (int32_t)(0u)), _mm_clmulepi64_si128(v_xb, v_mu2, (int32_t)(17u))), v_xd);
38206 if (((uint64_t)(a_x.len)) > 32u) {
38207 v_xa = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xa, v_mu2, (int32_t)(0u)), _mm_clmulepi64_si128(v_xa, v_mu2, (int32_t)(17u))), _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 0u)));
38208 v_xb = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xb, v_mu2, (int32_t)(0u)), _mm_clmulepi64_si128(v_xb, v_mu2, (int32_t)(17u))), _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 16u)));
38209 a_x = wuffs_base__slice_u8__subslice_i(a_x, 32u);
38211 } while (0);
38212 label__chain2__break:;
38213 v_mu1 = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC64__ECMA_X86_SSE42_FOLD1));
38214 v_xa = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xa, v_mu1, (int32_t)(0u)), _mm_clmulepi64_si128(v_xa, v_mu1, (int32_t)(17u))), v_xb);
38215 if (((uint64_t)(a_x.len)) > 24u) {
38216 v_xa = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xa, v_mu1, (int32_t)(0u)), _mm_clmulepi64_si128(v_xa, v_mu1, (int32_t)(17u))), _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 0u)));
38217 a_x = wuffs_base__slice_u8__subslice_i(a_x, 16u);
38218 if (((uint64_t)(a_x.len)) > 24u) {
38219 return wuffs_base__make_empty_struct();
38222 _mm_storeu_si128((__m128i*)(void*)(v_buf + (24u - ((uint64_t)(a_x.len)))), v_xa);
38223 wuffs_private_impl__slice_u8__copy_from_slice(wuffs_base__make_slice_u8_ij(v_buf, ((24u - ((uint64_t)(a_x.len))) + 16u), 48), a_x);
38224 v_mu2 = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC64__ECMA_X86_SSE42_FOLD2));
38225 v_xa = _mm_lddqu_si128((const __m128i*)(const void*)(v_buf + 0u));
38226 v_xb = _mm_lddqu_si128((const __m128i*)(const void*)(v_buf + 16u));
38227 v_xc = _mm_lddqu_si128((const __m128i*)(const void*)(v_buf + 32u));
38228 v_xd = _mm_xor_si128(_mm_clmulepi64_si128(v_xa, v_mu2, (int32_t)(0u)), _mm_clmulepi64_si128(v_xa, v_mu2, (int32_t)(17u)));
38229 v_xe = _mm_xor_si128(_mm_clmulepi64_si128(v_xb, v_mu1, (int32_t)(0u)), _mm_clmulepi64_si128(v_xb, v_mu1, (int32_t)(17u)));
38230 v_xa = _mm_xor_si128(v_xd, _mm_xor_si128(v_xe, v_xc));
38231 v_mupx = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC64__ECMA_X86_SSE42_MUPX));
38232 v_xb = _mm_clmulepi64_si128(v_xa, v_mupx, (int32_t)(0u));
38233 v_xc = _mm_clmulepi64_si128(v_xb, v_mupx, (int32_t)(16u));
38234 v_s = ((uint64_t)(_mm_extract_epi64(_mm_xor_si128(_mm_xor_si128(v_xc, _mm_slli_si128(v_xb, (int32_t)(8u))), v_xa), (int32_t)(1u))));
38235 self->private_impl.f_state = (18446744073709551615u ^ v_s);
38236 return wuffs_base__make_empty_struct();
38238 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
38239 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
38241 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CRC64)
38243 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__DEFLATE)
38245 // ---------------- Status Codes Implementations
38247 const char wuffs_deflate__error__bad_huffman_code_over_subscribed[] = "#deflate: bad Huffman code (over-subscribed)";
38248 const char wuffs_deflate__error__bad_huffman_code_under_subscribed[] = "#deflate: bad Huffman code (under-subscribed)";
38249 const char wuffs_deflate__error__bad_huffman_code_length_count[] = "#deflate: bad Huffman code length count";
38250 const char wuffs_deflate__error__bad_huffman_code_length_repetition[] = "#deflate: bad Huffman code length repetition";
38251 const char wuffs_deflate__error__bad_huffman_code[] = "#deflate: bad Huffman code";
38252 const char wuffs_deflate__error__bad_huffman_minimum_code_length[] = "#deflate: bad Huffman minimum code length";
38253 const char wuffs_deflate__error__bad_block[] = "#deflate: bad block";
38254 const char wuffs_deflate__error__bad_distance[] = "#deflate: bad distance";
38255 const char wuffs_deflate__error__bad_distance_code_count[] = "#deflate: bad distance code count";
38256 const char wuffs_deflate__error__bad_literal_length_code_count[] = "#deflate: bad literal/length code count";
38257 const char wuffs_deflate__error__inconsistent_stored_block_length[] = "#deflate: inconsistent stored block length";
38258 const char wuffs_deflate__error__missing_end_of_block_code[] = "#deflate: missing end-of-block code";
38259 const char wuffs_deflate__error__no_huffman_codes[] = "#deflate: no Huffman codes";
38260 const char wuffs_deflate__error__truncated_input[] = "#deflate: truncated input";
38261 const char wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state[] = "#deflate: internal error: inconsistent Huffman decoder state";
38262 const char wuffs_deflate__error__internal_error_inconsistent_i_o[] = "#deflate: internal error: inconsistent I/O";
38263 const char wuffs_deflate__error__internal_error_inconsistent_distance[] = "#deflate: internal error: inconsistent distance";
38264 const char wuffs_deflate__error__internal_error_inconsistent_n_bits[] = "#deflate: internal error: inconsistent n_bits";
38266 // ---------------- Private Consts
38268 static const uint8_t
38269 WUFFS_DEFLATE__CODE_ORDER[19] WUFFS_BASE__POTENTIALLY_UNUSED = {
38270 16u, 17u, 18u, 0u, 8u, 7u, 9u, 6u,
38271 10u, 5u, 11u, 4u, 12u, 3u, 13u, 2u,
38272 14u, 1u, 15u,
38275 static const uint8_t
38276 WUFFS_DEFLATE__REVERSE8[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
38277 0u, 128u, 64u, 192u, 32u, 160u, 96u, 224u,
38278 16u, 144u, 80u, 208u, 48u, 176u, 112u, 240u,
38279 8u, 136u, 72u, 200u, 40u, 168u, 104u, 232u,
38280 24u, 152u, 88u, 216u, 56u, 184u, 120u, 248u,
38281 4u, 132u, 68u, 196u, 36u, 164u, 100u, 228u,
38282 20u, 148u, 84u, 212u, 52u, 180u, 116u, 244u,
38283 12u, 140u, 76u, 204u, 44u, 172u, 108u, 236u,
38284 28u, 156u, 92u, 220u, 60u, 188u, 124u, 252u,
38285 2u, 130u, 66u, 194u, 34u, 162u, 98u, 226u,
38286 18u, 146u, 82u, 210u, 50u, 178u, 114u, 242u,
38287 10u, 138u, 74u, 202u, 42u, 170u, 106u, 234u,
38288 26u, 154u, 90u, 218u, 58u, 186u, 122u, 250u,
38289 6u, 134u, 70u, 198u, 38u, 166u, 102u, 230u,
38290 22u, 150u, 86u, 214u, 54u, 182u, 118u, 246u,
38291 14u, 142u, 78u, 206u, 46u, 174u, 110u, 238u,
38292 30u, 158u, 94u, 222u, 62u, 190u, 126u, 254u,
38293 1u, 129u, 65u, 193u, 33u, 161u, 97u, 225u,
38294 17u, 145u, 81u, 209u, 49u, 177u, 113u, 241u,
38295 9u, 137u, 73u, 201u, 41u, 169u, 105u, 233u,
38296 25u, 153u, 89u, 217u, 57u, 185u, 121u, 249u,
38297 5u, 133u, 69u, 197u, 37u, 165u, 101u, 229u,
38298 21u, 149u, 85u, 213u, 53u, 181u, 117u, 245u,
38299 13u, 141u, 77u, 205u, 45u, 173u, 109u, 237u,
38300 29u, 157u, 93u, 221u, 61u, 189u, 125u, 253u,
38301 3u, 131u, 67u, 195u, 35u, 163u, 99u, 227u,
38302 19u, 147u, 83u, 211u, 51u, 179u, 115u, 243u,
38303 11u, 139u, 75u, 203u, 43u, 171u, 107u, 235u,
38304 27u, 155u, 91u, 219u, 59u, 187u, 123u, 251u,
38305 7u, 135u, 71u, 199u, 39u, 167u, 103u, 231u,
38306 23u, 151u, 87u, 215u, 55u, 183u, 119u, 247u,
38307 15u, 143u, 79u, 207u, 47u, 175u, 111u, 239u,
38308 31u, 159u, 95u, 223u, 63u, 191u, 127u, 255u,
38311 static const uint32_t
38312 WUFFS_DEFLATE__LCODE_MAGIC_NUMBERS[32] WUFFS_BASE__POTENTIALLY_UNUSED = {
38313 1073741824u, 1073742080u, 1073742336u, 1073742592u, 1073742848u, 1073743104u, 1073743360u, 1073743616u,
38314 1073743888u, 1073744400u, 1073744912u, 1073745424u, 1073745952u, 1073746976u, 1073748000u, 1073749024u,
38315 1073750064u, 1073752112u, 1073754160u, 1073756208u, 1073758272u, 1073762368u, 1073766464u, 1073770560u,
38316 1073774672u, 1073782864u, 1073791056u, 1073799248u, 1073807104u, 134217728u, 134217728u, 134217728u,
38319 static const uint32_t
38320 WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[32] WUFFS_BASE__POTENTIALLY_UNUSED = {
38321 1073741824u, 1073742080u, 1073742336u, 1073742592u, 1073742864u, 1073743376u, 1073743904u, 1073744928u,
38322 1073745968u, 1073748016u, 1073750080u, 1073754176u, 1073758288u, 1073766480u, 1073774688u, 1073791072u,
38323 1073807472u, 1073840240u, 1073873024u, 1073938560u, 1074004112u, 1074135184u, 1074266272u, 1074528416u,
38324 1074790576u, 1075314864u, 1075839168u, 1076887744u, 1077936336u, 1080033488u, 134217728u, 134217728u,
38327 #define WUFFS_DEFLATE__HUFFS_TABLE_SIZE 1024u
38329 #define WUFFS_DEFLATE__HUFFS_TABLE_MASK 1023u
38331 // ---------------- Private Initializer Prototypes
38333 // ---------------- Private Function Prototypes
38335 WUFFS_BASE__GENERATED_C_CODE
38336 static wuffs_base__status
38337 wuffs_deflate__decoder__do_transform_io(
38338 wuffs_deflate__decoder* self,
38339 wuffs_base__io_buffer* a_dst,
38340 wuffs_base__io_buffer* a_src,
38341 wuffs_base__slice_u8 a_workbuf);
38343 WUFFS_BASE__GENERATED_C_CODE
38344 static wuffs_base__status
38345 wuffs_deflate__decoder__decode_blocks(
38346 wuffs_deflate__decoder* self,
38347 wuffs_base__io_buffer* a_dst,
38348 wuffs_base__io_buffer* a_src);
38350 WUFFS_BASE__GENERATED_C_CODE
38351 static wuffs_base__status
38352 wuffs_deflate__decoder__decode_uncompressed(
38353 wuffs_deflate__decoder* self,
38354 wuffs_base__io_buffer* a_dst,
38355 wuffs_base__io_buffer* a_src);
38357 WUFFS_BASE__GENERATED_C_CODE
38358 static wuffs_base__status
38359 wuffs_deflate__decoder__init_fixed_huffman(
38360 wuffs_deflate__decoder* self);
38362 WUFFS_BASE__GENERATED_C_CODE
38363 static wuffs_base__status
38364 wuffs_deflate__decoder__init_dynamic_huffman(
38365 wuffs_deflate__decoder* self,
38366 wuffs_base__io_buffer* a_src);
38368 WUFFS_BASE__GENERATED_C_CODE
38369 static wuffs_base__status
38370 wuffs_deflate__decoder__init_huff(
38371 wuffs_deflate__decoder* self,
38372 uint32_t a_which,
38373 uint32_t a_n_codes0,
38374 uint32_t a_n_codes1,
38375 uint32_t a_base_symbol);
38377 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3)
38378 WUFFS_BASE__GENERATED_C_CODE
38379 static wuffs_base__status
38380 wuffs_deflate__decoder__decode_huffman_bmi2(
38381 wuffs_deflate__decoder* self,
38382 wuffs_base__io_buffer* a_dst,
38383 wuffs_base__io_buffer* a_src);
38384 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3)
38386 WUFFS_BASE__GENERATED_C_CODE
38387 static wuffs_base__status
38388 wuffs_deflate__decoder__decode_huffman_fast32(
38389 wuffs_deflate__decoder* self,
38390 wuffs_base__io_buffer* a_dst,
38391 wuffs_base__io_buffer* a_src);
38393 WUFFS_BASE__GENERATED_C_CODE
38394 static wuffs_base__status
38395 wuffs_deflate__decoder__decode_huffman_fast64(
38396 wuffs_deflate__decoder* self,
38397 wuffs_base__io_buffer* a_dst,
38398 wuffs_base__io_buffer* a_src);
38400 WUFFS_BASE__GENERATED_C_CODE
38401 static wuffs_base__status
38402 wuffs_deflate__decoder__decode_huffman_fast64__choosy_default(
38403 wuffs_deflate__decoder* self,
38404 wuffs_base__io_buffer* a_dst,
38405 wuffs_base__io_buffer* a_src);
38407 WUFFS_BASE__GENERATED_C_CODE
38408 static wuffs_base__status
38409 wuffs_deflate__decoder__decode_huffman_slow(
38410 wuffs_deflate__decoder* self,
38411 wuffs_base__io_buffer* a_dst,
38412 wuffs_base__io_buffer* a_src);
38414 // ---------------- VTables
38416 const wuffs_base__io_transformer__func_ptrs
38417 wuffs_deflate__decoder__func_ptrs_for__wuffs_base__io_transformer = {
38418 (wuffs_base__optional_u63(*)(const void*))(&wuffs_deflate__decoder__dst_history_retain_length),
38419 (uint64_t(*)(const void*,
38420 uint32_t))(&wuffs_deflate__decoder__get_quirk),
38421 (wuffs_base__status(*)(void*,
38422 uint32_t,
38423 uint64_t))(&wuffs_deflate__decoder__set_quirk),
38424 (wuffs_base__status(*)(void*,
38425 wuffs_base__io_buffer*,
38426 wuffs_base__io_buffer*,
38427 wuffs_base__slice_u8))(&wuffs_deflate__decoder__transform_io),
38428 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_deflate__decoder__workbuf_len),
38431 // ---------------- Initializer Implementations
38433 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
38434 wuffs_deflate__decoder__initialize(
38435 wuffs_deflate__decoder* self,
38436 size_t sizeof_star_self,
38437 uint64_t wuffs_version,
38438 uint32_t options){
38439 if (!self) {
38440 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
38442 if (sizeof(*self) != sizeof_star_self) {
38443 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
38445 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
38446 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
38447 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
38450 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
38451 // The whole point of this if-check is to detect an uninitialized *self.
38452 // We disable the warning on GCC. Clang-5.0 does not have this warning.
38453 #if !defined(__clang__) && defined(__GNUC__)
38454 #pragma GCC diagnostic push
38455 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
38456 #endif
38457 if (self->private_impl.magic != 0) {
38458 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
38460 #if !defined(__clang__) && defined(__GNUC__)
38461 #pragma GCC diagnostic pop
38462 #endif
38463 } else {
38464 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
38465 memset(self, 0, sizeof(*self));
38466 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
38467 } else {
38468 memset(&(self->private_impl), 0, sizeof(self->private_impl));
38472 self->private_impl.choosy_decode_huffman_fast64 = &wuffs_deflate__decoder__decode_huffman_fast64__choosy_default;
38474 self->private_impl.magic = WUFFS_BASE__MAGIC;
38475 self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name =
38476 wuffs_base__io_transformer__vtable_name;
38477 self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers =
38478 (const void*)(&wuffs_deflate__decoder__func_ptrs_for__wuffs_base__io_transformer);
38479 return wuffs_base__make_status(NULL);
38482 wuffs_deflate__decoder*
38483 wuffs_deflate__decoder__alloc(void) {
38484 wuffs_deflate__decoder* x =
38485 (wuffs_deflate__decoder*)(calloc(1, sizeof(wuffs_deflate__decoder)));
38486 if (!x) {
38487 return NULL;
38489 if (wuffs_deflate__decoder__initialize(
38490 x, sizeof(wuffs_deflate__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
38491 free(x);
38492 return NULL;
38494 return x;
38497 size_t
38498 sizeof__wuffs_deflate__decoder(void) {
38499 return sizeof(wuffs_deflate__decoder);
38502 // ---------------- Function Implementations
38504 // -------- func deflate.decoder.add_history
38506 WUFFS_BASE__GENERATED_C_CODE
38507 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
38508 wuffs_deflate__decoder__add_history(
38509 wuffs_deflate__decoder* self,
38510 wuffs_base__slice_u8 a_hist) {
38511 if (!self) {
38512 return wuffs_base__make_empty_struct();
38514 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
38515 return wuffs_base__make_empty_struct();
38518 wuffs_base__slice_u8 v_s = {0};
38519 uint64_t v_n_copied = 0;
38520 uint32_t v_already_full = 0;
38522 v_s = a_hist;
38523 if (((uint64_t)(v_s.len)) >= 32768u) {
38524 v_s = wuffs_private_impl__slice_u8__suffix(v_s, 32768u);
38525 wuffs_private_impl__slice_u8__copy_from_slice(wuffs_base__make_slice_u8(self->private_data.f_history, 32768), v_s);
38526 self->private_impl.f_history_index = 32768u;
38527 } else {
38528 v_n_copied = wuffs_private_impl__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);
38529 if (v_n_copied < ((uint64_t)(v_s.len))) {
38530 v_s = wuffs_base__slice_u8__subslice_i(v_s, v_n_copied);
38531 v_n_copied = wuffs_private_impl__slice_u8__copy_from_slice(wuffs_base__make_slice_u8(self->private_data.f_history, 32768), v_s);
38532 self->private_impl.f_history_index = (((uint32_t)((v_n_copied & 32767u))) + 32768u);
38533 } else {
38534 v_already_full = 0u;
38535 if (self->private_impl.f_history_index >= 32768u) {
38536 v_already_full = 32768u;
38538 self->private_impl.f_history_index = ((self->private_impl.f_history_index & 32767u) + ((uint32_t)((v_n_copied & 32767u))) + v_already_full);
38541 wuffs_private_impl__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));
38542 return wuffs_base__make_empty_struct();
38545 // -------- func deflate.decoder.get_quirk
38547 WUFFS_BASE__GENERATED_C_CODE
38548 WUFFS_BASE__MAYBE_STATIC uint64_t
38549 wuffs_deflate__decoder__get_quirk(
38550 const wuffs_deflate__decoder* self,
38551 uint32_t a_key) {
38552 if (!self) {
38553 return 0;
38555 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
38556 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
38557 return 0;
38560 return 0u;
38563 // -------- func deflate.decoder.set_quirk
38565 WUFFS_BASE__GENERATED_C_CODE
38566 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
38567 wuffs_deflate__decoder__set_quirk(
38568 wuffs_deflate__decoder* self,
38569 uint32_t a_key,
38570 uint64_t a_value) {
38571 if (!self) {
38572 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
38574 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
38575 return wuffs_base__make_status(
38576 (self->private_impl.magic == WUFFS_BASE__DISABLED)
38577 ? wuffs_base__error__disabled_by_previous_error
38578 : wuffs_base__error__initialize_not_called);
38581 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
38584 // -------- func deflate.decoder.dst_history_retain_length
38586 WUFFS_BASE__GENERATED_C_CODE
38587 WUFFS_BASE__MAYBE_STATIC wuffs_base__optional_u63
38588 wuffs_deflate__decoder__dst_history_retain_length(
38589 const wuffs_deflate__decoder* self) {
38590 if (!self) {
38591 return wuffs_base__utility__make_optional_u63(false, 0u);
38593 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
38594 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
38595 return wuffs_base__utility__make_optional_u63(false, 0u);
38598 return wuffs_base__utility__make_optional_u63(true, 0u);
38601 // -------- func deflate.decoder.workbuf_len
38603 WUFFS_BASE__GENERATED_C_CODE
38604 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
38605 wuffs_deflate__decoder__workbuf_len(
38606 const wuffs_deflate__decoder* self) {
38607 if (!self) {
38608 return wuffs_base__utility__empty_range_ii_u64();
38610 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
38611 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
38612 return wuffs_base__utility__empty_range_ii_u64();
38615 return wuffs_base__utility__make_range_ii_u64(1u, 1u);
38618 // -------- func deflate.decoder.transform_io
38620 WUFFS_BASE__GENERATED_C_CODE
38621 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
38622 wuffs_deflate__decoder__transform_io(
38623 wuffs_deflate__decoder* self,
38624 wuffs_base__io_buffer* a_dst,
38625 wuffs_base__io_buffer* a_src,
38626 wuffs_base__slice_u8 a_workbuf) {
38627 if (!self) {
38628 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
38630 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
38631 return wuffs_base__make_status(
38632 (self->private_impl.magic == WUFFS_BASE__DISABLED)
38633 ? wuffs_base__error__disabled_by_previous_error
38634 : wuffs_base__error__initialize_not_called);
38636 if (!a_dst || !a_src) {
38637 self->private_impl.magic = WUFFS_BASE__DISABLED;
38638 return wuffs_base__make_status(wuffs_base__error__bad_argument);
38640 if ((self->private_impl.active_coroutine != 0) &&
38641 (self->private_impl.active_coroutine != 1)) {
38642 self->private_impl.magic = WUFFS_BASE__DISABLED;
38643 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
38645 self->private_impl.active_coroutine = 0;
38646 wuffs_base__status status = wuffs_base__make_status(NULL);
38648 wuffs_base__status v_status = wuffs_base__make_status(NULL);
38650 uint32_t coro_susp_point = self->private_impl.p_transform_io;
38651 switch (coro_susp_point) {
38652 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
38654 while (true) {
38656 wuffs_base__status t_0 = wuffs_deflate__decoder__do_transform_io(self, a_dst, a_src, a_workbuf);
38657 v_status = t_0;
38659 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
38660 status = wuffs_base__make_status(wuffs_deflate__error__truncated_input);
38661 goto exit;
38663 status = v_status;
38664 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
38668 self->private_impl.p_transform_io = 0;
38669 goto exit;
38672 goto suspend;
38673 suspend:
38674 self->private_impl.p_transform_io = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
38675 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
38677 goto exit;
38678 exit:
38679 if (wuffs_base__status__is_error(&status)) {
38680 self->private_impl.magic = WUFFS_BASE__DISABLED;
38682 return status;
38685 // -------- func deflate.decoder.do_transform_io
38687 WUFFS_BASE__GENERATED_C_CODE
38688 static wuffs_base__status
38689 wuffs_deflate__decoder__do_transform_io(
38690 wuffs_deflate__decoder* self,
38691 wuffs_base__io_buffer* a_dst,
38692 wuffs_base__io_buffer* a_src,
38693 wuffs_base__slice_u8 a_workbuf) {
38694 wuffs_base__status status = wuffs_base__make_status(NULL);
38696 uint64_t v_mark = 0;
38697 wuffs_base__status v_status = wuffs_base__make_status(NULL);
38699 uint8_t* iop_a_dst = NULL;
38700 uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38701 uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38702 uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38703 if (a_dst && a_dst->data.ptr) {
38704 io0_a_dst = a_dst->data.ptr;
38705 io1_a_dst = io0_a_dst + a_dst->meta.wi;
38706 iop_a_dst = io1_a_dst;
38707 io2_a_dst = io0_a_dst + a_dst->data.len;
38708 if (a_dst->meta.closed) {
38709 io2_a_dst = iop_a_dst;
38713 uint32_t coro_susp_point = self->private_impl.p_do_transform_io;
38714 switch (coro_susp_point) {
38715 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
38717 self->private_impl.choosy_decode_huffman_fast64 = (
38718 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3)
38719 wuffs_base__cpu_arch__have_x86_bmi2() ? &wuffs_deflate__decoder__decode_huffman_bmi2 :
38720 #endif
38721 self->private_impl.choosy_decode_huffman_fast64);
38722 while (true) {
38723 v_mark = ((uint64_t)(iop_a_dst - io0_a_dst));
38725 if (a_dst) {
38726 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
38728 wuffs_base__status t_0 = wuffs_deflate__decoder__decode_blocks(self, a_dst, a_src);
38729 v_status = t_0;
38730 if (a_dst) {
38731 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
38734 if ( ! wuffs_base__status__is_suspension(&v_status)) {
38735 status = v_status;
38736 if (wuffs_base__status__is_error(&status)) {
38737 goto exit;
38738 } else if (wuffs_base__status__is_suspension(&status)) {
38739 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
38740 goto exit;
38742 goto ok;
38744 wuffs_private_impl__u64__sat_add_indirect(&self->private_impl.f_transformed_history_count, wuffs_private_impl__io__count_since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst))));
38745 wuffs_deflate__decoder__add_history(self, wuffs_private_impl__io__since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst));
38746 status = v_status;
38747 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
38751 self->private_impl.p_do_transform_io = 0;
38752 goto exit;
38755 goto suspend;
38756 suspend:
38757 self->private_impl.p_do_transform_io = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
38759 goto exit;
38760 exit:
38761 if (a_dst && a_dst->data.ptr) {
38762 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
38765 return status;
38768 // -------- func deflate.decoder.decode_blocks
38770 WUFFS_BASE__GENERATED_C_CODE
38771 static wuffs_base__status
38772 wuffs_deflate__decoder__decode_blocks(
38773 wuffs_deflate__decoder* self,
38774 wuffs_base__io_buffer* a_dst,
38775 wuffs_base__io_buffer* a_src) {
38776 wuffs_base__status status = wuffs_base__make_status(NULL);
38778 uint32_t v_final = 0;
38779 uint32_t v_b0 = 0;
38780 uint32_t v_type = 0;
38781 wuffs_base__status v_status = wuffs_base__make_status(NULL);
38783 const uint8_t* iop_a_src = NULL;
38784 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38785 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38786 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38787 if (a_src && a_src->data.ptr) {
38788 io0_a_src = a_src->data.ptr;
38789 io1_a_src = io0_a_src + a_src->meta.ri;
38790 iop_a_src = io1_a_src;
38791 io2_a_src = io0_a_src + a_src->meta.wi;
38794 uint32_t coro_susp_point = self->private_impl.p_decode_blocks;
38795 if (coro_susp_point) {
38796 v_final = self->private_data.s_decode_blocks.v_final;
38798 switch (coro_susp_point) {
38799 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
38801 label__outer__continue:;
38802 while (v_final == 0u) {
38803 while (self->private_impl.f_n_bits < 3u) {
38805 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
38806 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38807 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38808 goto suspend;
38810 uint32_t t_0 = *iop_a_src++;
38811 v_b0 = t_0;
38813 self->private_impl.f_bits |= (v_b0 << (self->private_impl.f_n_bits & 3u));
38814 self->private_impl.f_n_bits = ((self->private_impl.f_n_bits & 3u) + 8u);
38816 v_final = (self->private_impl.f_bits & 1u);
38817 v_type = ((self->private_impl.f_bits >> 1u) & 3u);
38818 self->private_impl.f_bits >>= 3u;
38819 self->private_impl.f_n_bits -= 3u;
38820 if (v_type == 0u) {
38821 if (a_src) {
38822 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38824 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
38825 status = wuffs_deflate__decoder__decode_uncompressed(self, a_dst, a_src);
38826 if (a_src) {
38827 iop_a_src = a_src->data.ptr + a_src->meta.ri;
38829 if (status.repr) {
38830 goto suspend;
38832 continue;
38833 } else if (v_type == 1u) {
38834 v_status = wuffs_deflate__decoder__init_fixed_huffman(self);
38835 if ( ! wuffs_base__status__is_ok(&v_status)) {
38836 status = v_status;
38837 if (wuffs_base__status__is_error(&status)) {
38838 goto exit;
38839 } else if (wuffs_base__status__is_suspension(&status)) {
38840 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
38841 goto exit;
38843 goto ok;
38845 } else if (v_type == 2u) {
38846 if (a_src) {
38847 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38849 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
38850 status = wuffs_deflate__decoder__init_dynamic_huffman(self, a_src);
38851 if (a_src) {
38852 iop_a_src = a_src->data.ptr + a_src->meta.ri;
38854 if (status.repr) {
38855 goto suspend;
38857 } else {
38858 status = wuffs_base__make_status(wuffs_deflate__error__bad_block);
38859 goto exit;
38861 self->private_impl.f_end_of_block = false;
38862 while (true) {
38863 if (sizeof(void*) == 4u) {
38864 if (a_src) {
38865 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38867 v_status = wuffs_deflate__decoder__decode_huffman_fast32(self, a_dst, a_src);
38868 if (a_src) {
38869 iop_a_src = a_src->data.ptr + a_src->meta.ri;
38871 } else {
38872 if (a_src) {
38873 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38875 v_status = wuffs_deflate__decoder__decode_huffman_fast64(self, a_dst, a_src);
38876 if (a_src) {
38877 iop_a_src = a_src->data.ptr + a_src->meta.ri;
38880 if (wuffs_base__status__is_error(&v_status)) {
38881 status = v_status;
38882 goto exit;
38884 if (self->private_impl.f_end_of_block) {
38885 goto label__outer__continue;
38887 if (a_src) {
38888 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38890 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
38891 status = wuffs_deflate__decoder__decode_huffman_slow(self, a_dst, a_src);
38892 if (a_src) {
38893 iop_a_src = a_src->data.ptr + a_src->meta.ri;
38895 if (status.repr) {
38896 goto suspend;
38898 if (self->private_impl.f_end_of_block) {
38899 goto label__outer__continue;
38905 self->private_impl.p_decode_blocks = 0;
38906 goto exit;
38909 goto suspend;
38910 suspend:
38911 self->private_impl.p_decode_blocks = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
38912 self->private_data.s_decode_blocks.v_final = v_final;
38914 goto exit;
38915 exit:
38916 if (a_src && a_src->data.ptr) {
38917 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38920 return status;
38923 // -------- func deflate.decoder.decode_uncompressed
38925 WUFFS_BASE__GENERATED_C_CODE
38926 static wuffs_base__status
38927 wuffs_deflate__decoder__decode_uncompressed(
38928 wuffs_deflate__decoder* self,
38929 wuffs_base__io_buffer* a_dst,
38930 wuffs_base__io_buffer* a_src) {
38931 wuffs_base__status status = wuffs_base__make_status(NULL);
38933 uint32_t v_length = 0;
38934 uint32_t v_n_copied = 0;
38936 uint8_t* iop_a_dst = NULL;
38937 uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38938 uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38939 uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38940 if (a_dst && a_dst->data.ptr) {
38941 io0_a_dst = a_dst->data.ptr;
38942 io1_a_dst = io0_a_dst + a_dst->meta.wi;
38943 iop_a_dst = io1_a_dst;
38944 io2_a_dst = io0_a_dst + a_dst->data.len;
38945 if (a_dst->meta.closed) {
38946 io2_a_dst = iop_a_dst;
38949 const uint8_t* iop_a_src = NULL;
38950 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38951 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38952 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38953 if (a_src && a_src->data.ptr) {
38954 io0_a_src = a_src->data.ptr;
38955 io1_a_src = io0_a_src + a_src->meta.ri;
38956 iop_a_src = io1_a_src;
38957 io2_a_src = io0_a_src + a_src->meta.wi;
38960 uint32_t coro_susp_point = self->private_impl.p_decode_uncompressed;
38961 if (coro_susp_point) {
38962 v_length = self->private_data.s_decode_uncompressed.v_length;
38964 switch (coro_susp_point) {
38965 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
38967 if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7u)) != 0u)) {
38968 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
38969 goto exit;
38971 self->private_impl.f_n_bits = 0u;
38972 self->private_impl.f_bits = 0u;
38974 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
38975 uint32_t t_0;
38976 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38977 t_0 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
38978 iop_a_src += 4;
38979 } else {
38980 self->private_data.s_decode_uncompressed.scratch = 0;
38981 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
38982 while (true) {
38983 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38984 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38985 goto suspend;
38987 uint64_t* scratch = &self->private_data.s_decode_uncompressed.scratch;
38988 uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
38989 *scratch <<= 8;
38990 *scratch >>= 8;
38991 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
38992 if (num_bits_0 == 24) {
38993 t_0 = ((uint32_t)(*scratch));
38994 break;
38996 num_bits_0 += 8u;
38997 *scratch |= ((uint64_t)(num_bits_0)) << 56;
39000 v_length = t_0;
39002 if ((((v_length) & 0xFFFFu) + ((v_length) >> (32u - 16u))) != 65535u) {
39003 status = wuffs_base__make_status(wuffs_deflate__error__inconsistent_stored_block_length);
39004 goto exit;
39006 v_length = ((v_length) & 0xFFFFu);
39007 while (true) {
39008 v_n_copied = wuffs_private_impl__io_writer__limited_copy_u32_from_reader(
39009 &iop_a_dst, io2_a_dst,v_length, &iop_a_src, io2_a_src);
39010 if (v_length <= v_n_copied) {
39011 status = wuffs_base__make_status(NULL);
39012 goto ok;
39014 v_length -= v_n_copied;
39015 if (((uint64_t)(io2_a_dst - iop_a_dst)) == 0u) {
39016 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
39017 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
39018 } else {
39019 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39020 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
39025 self->private_impl.p_decode_uncompressed = 0;
39026 goto exit;
39029 goto suspend;
39030 suspend:
39031 self->private_impl.p_decode_uncompressed = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
39032 self->private_data.s_decode_uncompressed.v_length = v_length;
39034 goto exit;
39035 exit:
39036 if (a_dst && a_dst->data.ptr) {
39037 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
39039 if (a_src && a_src->data.ptr) {
39040 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
39043 return status;
39046 // -------- func deflate.decoder.init_fixed_huffman
39048 WUFFS_BASE__GENERATED_C_CODE
39049 static wuffs_base__status
39050 wuffs_deflate__decoder__init_fixed_huffman(
39051 wuffs_deflate__decoder* self) {
39052 uint32_t v_i = 0;
39053 wuffs_base__status v_status = wuffs_base__make_status(NULL);
39055 while (v_i < 144u) {
39056 self->private_data.f_code_lengths[v_i] = 8u;
39057 v_i += 1u;
39059 while (v_i < 256u) {
39060 self->private_data.f_code_lengths[v_i] = 9u;
39061 v_i += 1u;
39063 while (v_i < 280u) {
39064 self->private_data.f_code_lengths[v_i] = 7u;
39065 v_i += 1u;
39067 while (v_i < 288u) {
39068 self->private_data.f_code_lengths[v_i] = 8u;
39069 v_i += 1u;
39071 while (v_i < 320u) {
39072 self->private_data.f_code_lengths[v_i] = 5u;
39073 v_i += 1u;
39075 v_status = wuffs_deflate__decoder__init_huff(self,
39078 288u,
39079 257u);
39080 if (wuffs_base__status__is_error(&v_status)) {
39081 return v_status;
39083 v_status = wuffs_deflate__decoder__init_huff(self,
39085 288u,
39086 320u,
39087 0u);
39088 if (wuffs_base__status__is_error(&v_status)) {
39089 return v_status;
39091 return wuffs_base__make_status(NULL);
39094 // -------- func deflate.decoder.init_dynamic_huffman
39096 WUFFS_BASE__GENERATED_C_CODE
39097 static wuffs_base__status
39098 wuffs_deflate__decoder__init_dynamic_huffman(
39099 wuffs_deflate__decoder* self,
39100 wuffs_base__io_buffer* a_src) {
39101 wuffs_base__status status = wuffs_base__make_status(NULL);
39103 uint32_t v_bits = 0;
39104 uint32_t v_n_bits = 0;
39105 uint32_t v_b0 = 0;
39106 uint32_t v_n_lit = 0;
39107 uint32_t v_n_dist = 0;
39108 uint32_t v_n_clen = 0;
39109 uint32_t v_i = 0;
39110 uint32_t v_b1 = 0;
39111 wuffs_base__status v_status = wuffs_base__make_status(NULL);
39112 uint32_t v_mask = 0;
39113 uint32_t v_table_entry = 0;
39114 uint32_t v_table_entry_n_bits = 0;
39115 uint32_t v_b2 = 0;
39116 uint32_t v_n_extra_bits = 0;
39117 uint8_t v_rep_symbol = 0;
39118 uint32_t v_rep_count = 0;
39119 uint32_t v_b3 = 0;
39121 const uint8_t* iop_a_src = NULL;
39122 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39123 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39124 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39125 if (a_src && a_src->data.ptr) {
39126 io0_a_src = a_src->data.ptr;
39127 io1_a_src = io0_a_src + a_src->meta.ri;
39128 iop_a_src = io1_a_src;
39129 io2_a_src = io0_a_src + a_src->meta.wi;
39132 uint32_t coro_susp_point = self->private_impl.p_init_dynamic_huffman;
39133 if (coro_susp_point) {
39134 v_bits = self->private_data.s_init_dynamic_huffman.v_bits;
39135 v_n_bits = self->private_data.s_init_dynamic_huffman.v_n_bits;
39136 v_n_lit = self->private_data.s_init_dynamic_huffman.v_n_lit;
39137 v_n_dist = self->private_data.s_init_dynamic_huffman.v_n_dist;
39138 v_n_clen = self->private_data.s_init_dynamic_huffman.v_n_clen;
39139 v_i = self->private_data.s_init_dynamic_huffman.v_i;
39140 v_mask = self->private_data.s_init_dynamic_huffman.v_mask;
39141 v_n_extra_bits = self->private_data.s_init_dynamic_huffman.v_n_extra_bits;
39142 v_rep_symbol = self->private_data.s_init_dynamic_huffman.v_rep_symbol;
39143 v_rep_count = self->private_data.s_init_dynamic_huffman.v_rep_count;
39145 switch (coro_susp_point) {
39146 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
39148 v_bits = self->private_impl.f_bits;
39149 v_n_bits = self->private_impl.f_n_bits;
39150 while (v_n_bits < 14u) {
39152 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
39153 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39154 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39155 goto suspend;
39157 uint32_t t_0 = *iop_a_src++;
39158 v_b0 = t_0;
39160 v_bits |= (v_b0 << v_n_bits);
39161 v_n_bits += 8u;
39163 v_n_lit = (((v_bits) & 0x1Fu) + 257u);
39164 if (v_n_lit > 286u) {
39165 status = wuffs_base__make_status(wuffs_deflate__error__bad_literal_length_code_count);
39166 goto exit;
39168 v_bits >>= 5u;
39169 v_n_dist = (((v_bits) & 0x1Fu) + 1u);
39170 if (v_n_dist > 30u) {
39171 status = wuffs_base__make_status(wuffs_deflate__error__bad_distance_code_count);
39172 goto exit;
39174 v_bits >>= 5u;
39175 v_n_clen = (((v_bits) & 0xFu) + 4u);
39176 v_bits >>= 4u;
39177 v_n_bits -= 14u;
39178 v_i = 0u;
39179 while (v_i < v_n_clen) {
39180 while (v_n_bits < 3u) {
39182 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
39183 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39184 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39185 goto suspend;
39187 uint32_t t_1 = *iop_a_src++;
39188 v_b1 = t_1;
39190 v_bits |= (v_b1 << v_n_bits);
39191 v_n_bits += 8u;
39193 self->private_data.f_code_lengths[WUFFS_DEFLATE__CODE_ORDER[v_i]] = ((uint8_t)((v_bits & 7u)));
39194 v_bits >>= 3u;
39195 v_n_bits -= 3u;
39196 v_i += 1u;
39198 while (v_i < 19u) {
39199 self->private_data.f_code_lengths[WUFFS_DEFLATE__CODE_ORDER[v_i]] = 0u;
39200 v_i += 1u;
39202 v_status = wuffs_deflate__decoder__init_huff(self,
39205 19u,
39206 4095u);
39207 if (wuffs_base__status__is_error(&v_status)) {
39208 status = v_status;
39209 goto exit;
39211 v_mask = ((((uint32_t)(1u)) << self->private_impl.f_n_huffs_bits[0u]) - 1u);
39212 v_i = 0u;
39213 while (v_i < (v_n_lit + v_n_dist)) {
39214 while (true) {
39215 v_table_entry = self->private_data.f_huffs[0u][(v_bits & v_mask)];
39216 v_table_entry_n_bits = (v_table_entry & 15u);
39217 if (v_n_bits >= v_table_entry_n_bits) {
39218 v_bits >>= v_table_entry_n_bits;
39219 v_n_bits -= v_table_entry_n_bits;
39220 break;
39223 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
39224 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39225 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39226 goto suspend;
39228 uint32_t t_2 = *iop_a_src++;
39229 v_b2 = t_2;
39231 v_bits |= (v_b2 << v_n_bits);
39232 v_n_bits += 8u;
39234 if ((v_table_entry >> 24u) != 128u) {
39235 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
39236 goto exit;
39238 v_table_entry = ((v_table_entry >> 8u) & 255u);
39239 if (v_table_entry < 16u) {
39240 self->private_data.f_code_lengths[v_i] = ((uint8_t)(v_table_entry));
39241 v_i += 1u;
39242 continue;
39244 v_n_extra_bits = 0u;
39245 v_rep_symbol = 0u;
39246 v_rep_count = 0u;
39247 if (v_table_entry == 16u) {
39248 v_n_extra_bits = 2u;
39249 if (v_i <= 0u) {
39250 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_length_repetition);
39251 goto exit;
39253 v_rep_symbol = ((uint8_t)(self->private_data.f_code_lengths[(v_i - 1u)] & 15u));
39254 v_rep_count = 3u;
39255 } else if (v_table_entry == 17u) {
39256 v_n_extra_bits = 3u;
39257 v_rep_symbol = 0u;
39258 v_rep_count = 3u;
39259 } else if (v_table_entry == 18u) {
39260 v_n_extra_bits = 7u;
39261 v_rep_symbol = 0u;
39262 v_rep_count = 11u;
39263 } else {
39264 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
39265 goto exit;
39267 while (v_n_bits < v_n_extra_bits) {
39269 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
39270 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39271 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39272 goto suspend;
39274 uint32_t t_3 = *iop_a_src++;
39275 v_b3 = t_3;
39277 v_bits |= (v_b3 << v_n_bits);
39278 v_n_bits += 8u;
39280 v_rep_count += ((v_bits) & WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U32(v_n_extra_bits));
39281 v_bits >>= v_n_extra_bits;
39282 v_n_bits -= v_n_extra_bits;
39283 while (v_rep_count > 0u) {
39284 if (v_i >= (v_n_lit + v_n_dist)) {
39285 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_length_count);
39286 goto exit;
39288 self->private_data.f_code_lengths[v_i] = v_rep_symbol;
39289 v_i += 1u;
39290 v_rep_count -= 1u;
39293 if (v_i != (v_n_lit + v_n_dist)) {
39294 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_length_count);
39295 goto exit;
39297 if (self->private_data.f_code_lengths[256u] == 0u) {
39298 status = wuffs_base__make_status(wuffs_deflate__error__missing_end_of_block_code);
39299 goto exit;
39301 v_status = wuffs_deflate__decoder__init_huff(self,
39304 v_n_lit,
39305 257u);
39306 if (wuffs_base__status__is_error(&v_status)) {
39307 status = v_status;
39308 goto exit;
39310 v_status = wuffs_deflate__decoder__init_huff(self,
39312 v_n_lit,
39313 (v_n_lit + v_n_dist),
39314 0u);
39315 if (wuffs_base__status__is_error(&v_status)) {
39316 status = v_status;
39317 goto exit;
39319 self->private_impl.f_bits = v_bits;
39320 self->private_impl.f_n_bits = v_n_bits;
39322 goto ok;
39324 self->private_impl.p_init_dynamic_huffman = 0;
39325 goto exit;
39328 goto suspend;
39329 suspend:
39330 self->private_impl.p_init_dynamic_huffman = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
39331 self->private_data.s_init_dynamic_huffman.v_bits = v_bits;
39332 self->private_data.s_init_dynamic_huffman.v_n_bits = v_n_bits;
39333 self->private_data.s_init_dynamic_huffman.v_n_lit = v_n_lit;
39334 self->private_data.s_init_dynamic_huffman.v_n_dist = v_n_dist;
39335 self->private_data.s_init_dynamic_huffman.v_n_clen = v_n_clen;
39336 self->private_data.s_init_dynamic_huffman.v_i = v_i;
39337 self->private_data.s_init_dynamic_huffman.v_mask = v_mask;
39338 self->private_data.s_init_dynamic_huffman.v_n_extra_bits = v_n_extra_bits;
39339 self->private_data.s_init_dynamic_huffman.v_rep_symbol = v_rep_symbol;
39340 self->private_data.s_init_dynamic_huffman.v_rep_count = v_rep_count;
39342 goto exit;
39343 exit:
39344 if (a_src && a_src->data.ptr) {
39345 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
39348 return status;
39351 // -------- func deflate.decoder.init_huff
39353 WUFFS_BASE__GENERATED_C_CODE
39354 static wuffs_base__status
39355 wuffs_deflate__decoder__init_huff(
39356 wuffs_deflate__decoder* self,
39357 uint32_t a_which,
39358 uint32_t a_n_codes0,
39359 uint32_t a_n_codes1,
39360 uint32_t a_base_symbol) {
39361 uint16_t v_counts[16] = {0};
39362 uint32_t v_i = 0;
39363 uint32_t v_remaining = 0;
39364 uint16_t v_offsets[16] = {0};
39365 uint32_t v_n_symbols = 0;
39366 uint32_t v_count = 0;
39367 uint16_t v_symbols[320] = {0};
39368 uint32_t v_min_cl = 0;
39369 uint32_t v_max_cl = 0;
39370 uint32_t v_initial_high_bits = 0;
39371 uint32_t v_prev_cl = 0;
39372 uint32_t v_prev_redirect_key = 0;
39373 uint32_t v_top = 0;
39374 uint32_t v_next_top = 0;
39375 uint32_t v_code = 0;
39376 uint32_t v_key = 0;
39377 uint32_t v_value = 0;
39378 uint32_t v_cl = 0;
39379 uint32_t v_redirect_key = 0;
39380 uint32_t v_j = 0;
39381 uint32_t v_reversed_key = 0;
39382 uint32_t v_symbol = 0;
39383 uint32_t v_high_bits = 0;
39384 uint32_t v_delta = 0;
39386 v_i = a_n_codes0;
39387 while (v_i < a_n_codes1) {
39388 if (v_counts[((uint8_t)(self->private_data.f_code_lengths[v_i] & 15u))] >= 320u) {
39389 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
39391 #if defined(__GNUC__)
39392 #pragma GCC diagnostic push
39393 #pragma GCC diagnostic ignored "-Wconversion"
39394 #endif
39395 v_counts[((uint8_t)(self->private_data.f_code_lengths[v_i] & 15u))] += 1u;
39396 #if defined(__GNUC__)
39397 #pragma GCC diagnostic pop
39398 #endif
39399 v_i += 1u;
39401 if ((((uint32_t)(v_counts[0u])) + a_n_codes0) == a_n_codes1) {
39402 return wuffs_base__make_status(wuffs_deflate__error__no_huffman_codes);
39404 v_remaining = 1u;
39405 v_i = 1u;
39406 while (v_i <= 15u) {
39407 if (v_remaining > 1073741824u) {
39408 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
39410 v_remaining <<= 1u;
39411 if (v_remaining < ((uint32_t)(v_counts[v_i]))) {
39412 return wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_over_subscribed);
39414 v_remaining -= ((uint32_t)(v_counts[v_i]));
39415 v_i += 1u;
39417 if (v_remaining != 0u) {
39418 if ((a_which == 1u) && (v_counts[1u] == 1u) && ((((uint32_t)(v_counts[0u])) + a_n_codes0 + 1u) == a_n_codes1)) {
39419 v_i = 0u;
39420 while (v_i <= 29u) {
39421 if (self->private_data.f_code_lengths[(a_n_codes0 + v_i)] == 1u) {
39422 self->private_impl.f_n_huffs_bits[1u] = 1u;
39423 self->private_data.f_huffs[1u][0u] = (WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[v_i] | 1u);
39424 self->private_data.f_huffs[1u][1u] = (WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[31u] | 1u);
39425 return wuffs_base__make_status(NULL);
39427 v_i += 1u;
39430 return wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_under_subscribed);
39432 v_i = 1u;
39433 while (v_i <= 15u) {
39434 v_offsets[v_i] = ((uint16_t)(v_n_symbols));
39435 v_count = ((uint32_t)(v_counts[v_i]));
39436 if (v_n_symbols > (320u - v_count)) {
39437 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
39439 v_n_symbols = (v_n_symbols + v_count);
39440 v_i += 1u;
39442 if (v_n_symbols > 288u) {
39443 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
39445 v_i = a_n_codes0;
39446 while (v_i < a_n_codes1) {
39447 if (v_i < a_n_codes0) {
39448 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
39450 if (self->private_data.f_code_lengths[v_i] != 0u) {
39451 if (v_offsets[((uint8_t)(self->private_data.f_code_lengths[v_i] & 15u))] >= 320u) {
39452 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
39454 v_symbols[v_offsets[((uint8_t)(self->private_data.f_code_lengths[v_i] & 15u))]] = ((uint16_t)((v_i - a_n_codes0)));
39455 #if defined(__GNUC__)
39456 #pragma GCC diagnostic push
39457 #pragma GCC diagnostic ignored "-Wconversion"
39458 #endif
39459 v_offsets[((uint8_t)(self->private_data.f_code_lengths[v_i] & 15u))] += 1u;
39460 #if defined(__GNUC__)
39461 #pragma GCC diagnostic pop
39462 #endif
39464 v_i += 1u;
39466 v_min_cl = 1u;
39467 while (true) {
39468 if (v_counts[v_min_cl] != 0u) {
39469 break;
39471 if (v_min_cl >= 9u) {
39472 return wuffs_base__make_status(wuffs_deflate__error__bad_huffman_minimum_code_length);
39474 v_min_cl += 1u;
39476 v_max_cl = 15u;
39477 while (true) {
39478 if (v_counts[v_max_cl] != 0u) {
39479 break;
39481 if (v_max_cl <= 1u) {
39482 return wuffs_base__make_status(wuffs_deflate__error__no_huffman_codes);
39484 v_max_cl -= 1u;
39486 if (v_max_cl <= 9u) {
39487 self->private_impl.f_n_huffs_bits[a_which] = v_max_cl;
39488 } else {
39489 self->private_impl.f_n_huffs_bits[a_which] = 9u;
39491 v_i = 0u;
39492 if ((v_n_symbols != ((uint32_t)(v_offsets[v_max_cl]))) || (v_n_symbols != ((uint32_t)(v_offsets[15u])))) {
39493 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
39495 if ((a_n_codes0 + ((uint32_t)(v_symbols[0u]))) >= 320u) {
39496 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
39498 v_initial_high_bits = 512u;
39499 if (v_max_cl < 9u) {
39500 v_initial_high_bits = (((uint32_t)(1u)) << v_max_cl);
39502 v_prev_cl = ((uint32_t)(((uint8_t)(self->private_data.f_code_lengths[(a_n_codes0 + ((uint32_t)(v_symbols[0u])))] & 15u))));
39503 v_prev_redirect_key = 4294967295u;
39504 v_top = 0u;
39505 v_next_top = 512u;
39506 v_code = 0u;
39507 v_key = 0u;
39508 v_value = 0u;
39509 while (true) {
39510 if ((a_n_codes0 + ((uint32_t)(v_symbols[v_i]))) >= 320u) {
39511 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
39513 v_cl = ((uint32_t)(((uint8_t)(self->private_data.f_code_lengths[(a_n_codes0 + ((uint32_t)(v_symbols[v_i])))] & 15u))));
39514 if (v_cl > v_prev_cl) {
39515 v_code <<= (v_cl - v_prev_cl);
39516 if (v_code >= 32768u) {
39517 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
39520 v_prev_cl = v_cl;
39521 v_key = v_code;
39522 if (v_cl > 9u) {
39523 v_cl -= 9u;
39524 v_redirect_key = ((v_key >> v_cl) & 511u);
39525 v_key = ((v_key) & WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U32(v_cl));
39526 if (v_prev_redirect_key != v_redirect_key) {
39527 v_prev_redirect_key = v_redirect_key;
39528 v_remaining = (((uint32_t)(1u)) << v_cl);
39529 v_j = v_prev_cl;
39530 while (v_j <= 15u) {
39531 if (v_remaining <= ((uint32_t)(v_counts[v_j]))) {
39532 break;
39534 v_remaining -= ((uint32_t)(v_counts[v_j]));
39535 if (v_remaining > 1073741824u) {
39536 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
39538 v_remaining <<= 1u;
39539 v_j += 1u;
39541 if ((v_j <= 9u) || (15u < v_j)) {
39542 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
39544 v_j -= 9u;
39545 v_initial_high_bits = (((uint32_t)(1u)) << v_j);
39546 v_top = v_next_top;
39547 if ((v_top + (((uint32_t)(1u)) << v_j)) > 1024u) {
39548 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
39550 v_next_top = (v_top + (((uint32_t)(1u)) << v_j));
39551 v_redirect_key = (((uint32_t)(WUFFS_DEFLATE__REVERSE8[(v_redirect_key >> 1u)])) | ((v_redirect_key & 1u) << 8u));
39552 self->private_data.f_huffs[a_which][v_redirect_key] = (268435465u | (v_top << 8u) | (v_j << 4u));
39555 if ((v_key >= 512u) || (v_counts[v_prev_cl] <= 0u)) {
39556 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
39558 #if defined(__GNUC__)
39559 #pragma GCC diagnostic push
39560 #pragma GCC diagnostic ignored "-Wconversion"
39561 #endif
39562 v_counts[v_prev_cl] -= 1u;
39563 #if defined(__GNUC__)
39564 #pragma GCC diagnostic pop
39565 #endif
39566 v_reversed_key = (((uint32_t)(WUFFS_DEFLATE__REVERSE8[(v_key >> 1u)])) | ((v_key & 1u) << 8u));
39567 v_reversed_key >>= (9u - v_cl);
39568 v_symbol = ((uint32_t)(v_symbols[v_i]));
39569 if (v_symbol == 256u) {
39570 v_value = (536870912u | v_cl);
39571 } else if ((v_symbol < 256u) && (a_which == 0u)) {
39572 v_value = (2147483648u | (v_symbol << 8u) | v_cl);
39573 } else if (v_symbol >= a_base_symbol) {
39574 v_symbol -= a_base_symbol;
39575 if (a_which == 0u) {
39576 v_value = (WUFFS_DEFLATE__LCODE_MAGIC_NUMBERS[(v_symbol & 31u)] | v_cl);
39577 } else {
39578 v_value = (WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[(v_symbol & 31u)] | v_cl);
39580 } else {
39581 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
39583 v_high_bits = v_initial_high_bits;
39584 v_delta = (((uint32_t)(1u)) << v_cl);
39585 while (v_high_bits >= v_delta) {
39586 v_high_bits -= v_delta;
39587 if ((v_top + ((v_high_bits | v_reversed_key) & 511u)) >= 1024u) {
39588 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
39590 self->private_data.f_huffs[a_which][(v_top + ((v_high_bits | v_reversed_key) & 511u))] = v_value;
39592 v_i += 1u;
39593 if (v_i >= v_n_symbols) {
39594 break;
39596 v_code += 1u;
39597 if (v_code >= 32768u) {
39598 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
39601 return wuffs_base__make_status(NULL);
39604 // ‼ WUFFS MULTI-FILE SECTION +x86_bmi2
39605 // -------- func deflate.decoder.decode_huffman_bmi2
39607 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3)
39608 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("bmi2")
39609 WUFFS_BASE__GENERATED_C_CODE
39610 static wuffs_base__status
39611 wuffs_deflate__decoder__decode_huffman_bmi2(
39612 wuffs_deflate__decoder* self,
39613 wuffs_base__io_buffer* a_dst,
39614 wuffs_base__io_buffer* a_src) {
39615 wuffs_base__status status = wuffs_base__make_status(NULL);
39617 uint64_t v_bits = 0;
39618 uint32_t v_n_bits = 0;
39619 uint32_t v_table_entry = 0;
39620 uint32_t v_table_entry_n_bits = 0;
39621 uint64_t v_lmask = 0;
39622 uint64_t v_dmask = 0;
39623 uint32_t v_redir_top = 0;
39624 uint32_t v_redir_mask = 0;
39625 uint32_t v_length = 0;
39626 uint32_t v_dist_minus_1 = 0;
39627 uint32_t v_hlen = 0;
39628 uint32_t v_hdist = 0;
39629 uint32_t v_hdist_adjustment = 0;
39631 uint8_t* iop_a_dst = NULL;
39632 uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39633 uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39634 uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39635 if (a_dst && a_dst->data.ptr) {
39636 io0_a_dst = a_dst->data.ptr;
39637 io1_a_dst = io0_a_dst + a_dst->meta.wi;
39638 iop_a_dst = io1_a_dst;
39639 io2_a_dst = io0_a_dst + a_dst->data.len;
39640 if (a_dst->meta.closed) {
39641 io2_a_dst = iop_a_dst;
39644 const uint8_t* iop_a_src = NULL;
39645 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39646 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39647 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39648 if (a_src && a_src->data.ptr) {
39649 io0_a_src = a_src->data.ptr;
39650 io1_a_src = io0_a_src + a_src->meta.ri;
39651 iop_a_src = io1_a_src;
39652 io2_a_src = io0_a_src + a_src->meta.wi;
39655 if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7u)) != 0u)) {
39656 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
39657 goto exit;
39659 v_bits = ((uint64_t)(self->private_impl.f_bits));
39660 v_n_bits = self->private_impl.f_n_bits;
39661 v_lmask = ((((uint64_t)(1u)) << self->private_impl.f_n_huffs_bits[0u]) - 1u);
39662 v_dmask = ((((uint64_t)(1u)) << self->private_impl.f_n_huffs_bits[1u]) - 1u);
39663 if (self->private_impl.f_transformed_history_count < (a_dst ? a_dst->meta.pos : 0u)) {
39664 status = wuffs_base__make_status(wuffs_base__error__bad_i_o_position);
39665 goto exit;
39667 v_hdist_adjustment = ((uint32_t)((self->private_impl.f_transformed_history_count - (a_dst ? a_dst->meta.pos : 0u))));
39668 label__loop__continue:;
39669 while ((((uint64_t)(io2_a_dst - iop_a_dst)) >= 266u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 8u)) {
39670 v_bits |= ((uint64_t)(wuffs_base__peek_u64le__no_bounds_check(iop_a_src) << (v_n_bits & 63u)));
39671 iop_a_src += ((63u - (v_n_bits & 63u)) >> 3u);
39672 v_n_bits |= 56u;
39673 v_table_entry = self->private_data.f_huffs[0u][(v_bits & v_lmask)];
39674 v_table_entry_n_bits = (v_table_entry & 15u);
39675 v_bits >>= v_table_entry_n_bits;
39676 v_n_bits -= v_table_entry_n_bits;
39677 if ((v_table_entry >> 31u) != 0u) {
39678 (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)((v_table_entry >> 8u)))), iop_a_dst += 1);
39679 continue;
39680 } else if ((v_table_entry >> 30u) != 0u) {
39681 } else if ((v_table_entry >> 29u) != 0u) {
39682 self->private_impl.f_end_of_block = true;
39683 break;
39684 } else if ((v_table_entry >> 28u) != 0u) {
39685 v_redir_top = ((v_table_entry >> 8u) & 65535u);
39686 v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u);
39687 v_table_entry = self->private_data.f_huffs[0u][((v_redir_top + (((uint32_t)(v_bits)) & v_redir_mask)) & 1023u)];
39688 v_table_entry_n_bits = (v_table_entry & 15u);
39689 v_bits >>= v_table_entry_n_bits;
39690 v_n_bits -= v_table_entry_n_bits;
39691 if ((v_table_entry >> 31u) != 0u) {
39692 (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)((v_table_entry >> 8u)))), iop_a_dst += 1);
39693 continue;
39694 } else if ((v_table_entry >> 30u) != 0u) {
39695 } else if ((v_table_entry >> 29u) != 0u) {
39696 self->private_impl.f_end_of_block = true;
39697 break;
39698 } else if ((v_table_entry >> 28u) != 0u) {
39699 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
39700 goto exit;
39701 } else if ((v_table_entry >> 27u) != 0u) {
39702 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
39703 goto exit;
39704 } else {
39705 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
39706 goto exit;
39708 } else if ((v_table_entry >> 27u) != 0u) {
39709 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
39710 goto exit;
39711 } else {
39712 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
39713 goto exit;
39715 v_length = (((v_table_entry >> 8u) & 255u) + 3u);
39716 v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u);
39717 if (v_table_entry_n_bits > 0u) {
39718 v_length = (((v_length + 253u + ((uint32_t)(((v_bits) & WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U64(v_table_entry_n_bits))))) & 255u) + 3u);
39719 v_bits >>= v_table_entry_n_bits;
39720 v_n_bits -= v_table_entry_n_bits;
39722 v_table_entry = self->private_data.f_huffs[1u][(v_bits & v_dmask)];
39723 v_table_entry_n_bits = (v_table_entry & 15u);
39724 v_bits >>= v_table_entry_n_bits;
39725 v_n_bits -= v_table_entry_n_bits;
39726 if ((v_table_entry >> 28u) == 1u) {
39727 v_redir_top = ((v_table_entry >> 8u) & 65535u);
39728 v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u);
39729 v_table_entry = self->private_data.f_huffs[1u][((v_redir_top + (((uint32_t)(v_bits)) & v_redir_mask)) & 1023u)];
39730 v_table_entry_n_bits = (v_table_entry & 15u);
39731 v_bits >>= v_table_entry_n_bits;
39732 v_n_bits -= v_table_entry_n_bits;
39734 if ((v_table_entry >> 24u) != 64u) {
39735 if ((v_table_entry >> 24u) == 8u) {
39736 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
39737 goto exit;
39739 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
39740 goto exit;
39742 v_dist_minus_1 = ((v_table_entry >> 8u) & 32767u);
39743 v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u);
39744 v_dist_minus_1 = ((v_dist_minus_1 + ((uint32_t)(((v_bits) & WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U64(v_table_entry_n_bits))))) & 32767u);
39745 v_bits >>= v_table_entry_n_bits;
39746 v_n_bits -= v_table_entry_n_bits;
39747 do {
39748 if (((uint64_t)((v_dist_minus_1 + 1u))) > ((uint64_t)(iop_a_dst - io0_a_dst))) {
39749 v_hlen = 0u;
39750 v_hdist = ((uint32_t)((((uint64_t)((v_dist_minus_1 + 1u))) - ((uint64_t)(iop_a_dst - io0_a_dst)))));
39751 if (v_length > v_hdist) {
39752 v_length -= v_hdist;
39753 v_hlen = v_hdist;
39754 } else {
39755 v_hlen = v_length;
39756 v_length = 0u;
39758 v_hdist += v_hdist_adjustment;
39759 if (self->private_impl.f_history_index < v_hdist) {
39760 status = wuffs_base__make_status(wuffs_deflate__error__bad_distance);
39761 goto exit;
39763 wuffs_private_impl__io_writer__limited_copy_u32_from_slice(
39764 &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));
39765 if (v_length == 0u) {
39766 goto label__loop__continue;
39768 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)))) {
39769 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_distance);
39770 goto exit;
39773 if ((v_dist_minus_1 + 1u) >= 8u) {
39774 wuffs_private_impl__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast(
39775 &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u));
39776 } else if ((v_dist_minus_1 + 1u) == 1u) {
39777 wuffs_private_impl__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast(
39778 &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u));
39779 } else {
39780 wuffs_private_impl__io_writer__limited_copy_u32_from_history_fast(
39781 &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u));
39783 } while (0);
39785 if (v_n_bits > 63u) {
39786 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
39787 goto exit;
39789 while (v_n_bits >= 8u) {
39790 v_n_bits -= 8u;
39791 if (iop_a_src > io1_a_src) {
39792 iop_a_src--;
39793 } else {
39794 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_i_o);
39795 goto exit;
39798 self->private_impl.f_bits = ((uint32_t)((v_bits & ((((uint64_t)(1u)) << v_n_bits) - 1u))));
39799 self->private_impl.f_n_bits = v_n_bits;
39800 if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> self->private_impl.f_n_bits) != 0u)) {
39801 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
39802 goto exit;
39804 goto exit;
39805 exit:
39806 if (a_dst && a_dst->data.ptr) {
39807 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
39809 if (a_src && a_src->data.ptr) {
39810 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
39813 return status;
39815 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3)
39816 // ‼ WUFFS MULTI-FILE SECTION -x86_bmi2
39818 // -------- func deflate.decoder.decode_huffman_fast32
39820 WUFFS_BASE__GENERATED_C_CODE
39821 static wuffs_base__status
39822 wuffs_deflate__decoder__decode_huffman_fast32(
39823 wuffs_deflate__decoder* self,
39824 wuffs_base__io_buffer* a_dst,
39825 wuffs_base__io_buffer* a_src) {
39826 wuffs_base__status status = wuffs_base__make_status(NULL);
39828 uint32_t v_bits = 0;
39829 uint32_t v_n_bits = 0;
39830 uint32_t v_table_entry = 0;
39831 uint32_t v_table_entry_n_bits = 0;
39832 uint32_t v_lmask = 0;
39833 uint32_t v_dmask = 0;
39834 uint32_t v_redir_top = 0;
39835 uint32_t v_redir_mask = 0;
39836 uint32_t v_length = 0;
39837 uint32_t v_dist_minus_1 = 0;
39838 uint32_t v_hlen = 0;
39839 uint32_t v_hdist = 0;
39840 uint32_t v_hdist_adjustment = 0;
39842 uint8_t* iop_a_dst = NULL;
39843 uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39844 uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39845 uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39846 if (a_dst && a_dst->data.ptr) {
39847 io0_a_dst = a_dst->data.ptr;
39848 io1_a_dst = io0_a_dst + a_dst->meta.wi;
39849 iop_a_dst = io1_a_dst;
39850 io2_a_dst = io0_a_dst + a_dst->data.len;
39851 if (a_dst->meta.closed) {
39852 io2_a_dst = iop_a_dst;
39855 const uint8_t* iop_a_src = NULL;
39856 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39857 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39858 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39859 if (a_src && a_src->data.ptr) {
39860 io0_a_src = a_src->data.ptr;
39861 io1_a_src = io0_a_src + a_src->meta.ri;
39862 iop_a_src = io1_a_src;
39863 io2_a_src = io0_a_src + a_src->meta.wi;
39866 if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7u)) != 0u)) {
39867 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
39868 goto exit;
39870 v_bits = self->private_impl.f_bits;
39871 v_n_bits = self->private_impl.f_n_bits;
39872 v_lmask = ((((uint32_t)(1u)) << self->private_impl.f_n_huffs_bits[0u]) - 1u);
39873 v_dmask = ((((uint32_t)(1u)) << self->private_impl.f_n_huffs_bits[1u]) - 1u);
39874 if (self->private_impl.f_transformed_history_count < (a_dst ? a_dst->meta.pos : 0u)) {
39875 status = wuffs_base__make_status(wuffs_base__error__bad_i_o_position);
39876 goto exit;
39878 v_hdist_adjustment = ((uint32_t)((self->private_impl.f_transformed_history_count - (a_dst ? a_dst->meta.pos : 0u))));
39879 label__loop__continue:;
39880 while ((((uint64_t)(io2_a_dst - iop_a_dst)) >= 266u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 12u)) {
39881 if (v_n_bits < 15u) {
39882 v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
39883 iop_a_src += 1u;
39884 v_n_bits += 8u;
39885 v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
39886 iop_a_src += 1u;
39887 v_n_bits += 8u;
39888 } else {
39890 v_table_entry = self->private_data.f_huffs[0u][(v_bits & v_lmask)];
39891 v_table_entry_n_bits = (v_table_entry & 15u);
39892 v_bits >>= v_table_entry_n_bits;
39893 v_n_bits -= v_table_entry_n_bits;
39894 if ((v_table_entry >> 31u) != 0u) {
39895 (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)((v_table_entry >> 8u)))), iop_a_dst += 1);
39896 continue;
39897 } else if ((v_table_entry >> 30u) != 0u) {
39898 } else if ((v_table_entry >> 29u) != 0u) {
39899 self->private_impl.f_end_of_block = true;
39900 break;
39901 } else if ((v_table_entry >> 28u) != 0u) {
39902 if (v_n_bits < 15u) {
39903 v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
39904 iop_a_src += 1u;
39905 v_n_bits += 8u;
39906 v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
39907 iop_a_src += 1u;
39908 v_n_bits += 8u;
39909 } else {
39911 v_redir_top = ((v_table_entry >> 8u) & 65535u);
39912 v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u);
39913 v_table_entry = self->private_data.f_huffs[0u][((v_redir_top + (v_bits & v_redir_mask)) & 1023u)];
39914 v_table_entry_n_bits = (v_table_entry & 15u);
39915 v_bits >>= v_table_entry_n_bits;
39916 v_n_bits -= v_table_entry_n_bits;
39917 if ((v_table_entry >> 31u) != 0u) {
39918 (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)((v_table_entry >> 8u)))), iop_a_dst += 1);
39919 continue;
39920 } else if ((v_table_entry >> 30u) != 0u) {
39921 } else if ((v_table_entry >> 29u) != 0u) {
39922 self->private_impl.f_end_of_block = true;
39923 break;
39924 } else if ((v_table_entry >> 28u) != 0u) {
39925 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
39926 goto exit;
39927 } else if ((v_table_entry >> 27u) != 0u) {
39928 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
39929 goto exit;
39930 } else {
39931 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
39932 goto exit;
39934 } else if ((v_table_entry >> 27u) != 0u) {
39935 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
39936 goto exit;
39937 } else {
39938 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
39939 goto exit;
39941 v_length = (((v_table_entry >> 8u) & 255u) + 3u);
39942 v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u);
39943 if (v_table_entry_n_bits > 0u) {
39944 if (v_n_bits < 15u) {
39945 v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
39946 iop_a_src += 1u;
39947 v_n_bits += 8u;
39948 v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
39949 iop_a_src += 1u;
39950 v_n_bits += 8u;
39951 } else {
39953 v_length = (((v_length + 253u + ((v_bits) & WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U32(v_table_entry_n_bits))) & 255u) + 3u);
39954 v_bits >>= v_table_entry_n_bits;
39955 v_n_bits -= v_table_entry_n_bits;
39956 } else {
39958 if (v_n_bits < 15u) {
39959 v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
39960 iop_a_src += 1u;
39961 v_n_bits += 8u;
39962 v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
39963 iop_a_src += 1u;
39964 v_n_bits += 8u;
39965 } else {
39967 v_table_entry = self->private_data.f_huffs[1u][(v_bits & v_dmask)];
39968 v_table_entry_n_bits = (v_table_entry & 15u);
39969 v_bits >>= v_table_entry_n_bits;
39970 v_n_bits -= v_table_entry_n_bits;
39971 if ((v_table_entry >> 28u) == 1u) {
39972 if (v_n_bits < 15u) {
39973 v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
39974 iop_a_src += 1u;
39975 v_n_bits += 8u;
39976 v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
39977 iop_a_src += 1u;
39978 v_n_bits += 8u;
39979 } else {
39981 v_redir_top = ((v_table_entry >> 8u) & 65535u);
39982 v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u);
39983 v_table_entry = self->private_data.f_huffs[1u][((v_redir_top + (v_bits & v_redir_mask)) & 1023u)];
39984 v_table_entry_n_bits = (v_table_entry & 15u);
39985 v_bits >>= v_table_entry_n_bits;
39986 v_n_bits -= v_table_entry_n_bits;
39987 } else {
39989 if ((v_table_entry >> 24u) != 64u) {
39990 if ((v_table_entry >> 24u) == 8u) {
39991 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
39992 goto exit;
39994 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
39995 goto exit;
39997 v_dist_minus_1 = ((v_table_entry >> 8u) & 32767u);
39998 v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u);
39999 if (v_n_bits < v_table_entry_n_bits) {
40000 v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
40001 iop_a_src += 1u;
40002 v_n_bits += 8u;
40003 v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
40004 iop_a_src += 1u;
40005 v_n_bits += 8u;
40007 v_dist_minus_1 = ((v_dist_minus_1 + ((v_bits) & WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U32(v_table_entry_n_bits))) & 32767u);
40008 v_bits >>= v_table_entry_n_bits;
40009 v_n_bits -= v_table_entry_n_bits;
40010 do {
40011 if (((uint64_t)((v_dist_minus_1 + 1u))) > ((uint64_t)(iop_a_dst - io0_a_dst))) {
40012 v_hlen = 0u;
40013 v_hdist = ((uint32_t)((((uint64_t)((v_dist_minus_1 + 1u))) - ((uint64_t)(iop_a_dst - io0_a_dst)))));
40014 if (v_length > v_hdist) {
40015 v_length -= v_hdist;
40016 v_hlen = v_hdist;
40017 } else {
40018 v_hlen = v_length;
40019 v_length = 0u;
40021 v_hdist += v_hdist_adjustment;
40022 if (self->private_impl.f_history_index < v_hdist) {
40023 status = wuffs_base__make_status(wuffs_deflate__error__bad_distance);
40024 goto exit;
40026 wuffs_private_impl__io_writer__limited_copy_u32_from_slice(
40027 &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));
40028 if (v_length == 0u) {
40029 goto label__loop__continue;
40031 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)))) {
40032 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_distance);
40033 goto exit;
40036 if ((v_dist_minus_1 + 1u) >= 8u) {
40037 wuffs_private_impl__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast(
40038 &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u));
40039 } else {
40040 wuffs_private_impl__io_writer__limited_copy_u32_from_history_fast(
40041 &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u));
40043 } while (0);
40045 while (v_n_bits >= 8u) {
40046 v_n_bits -= 8u;
40047 if (iop_a_src > io1_a_src) {
40048 iop_a_src--;
40049 } else {
40050 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_i_o);
40051 goto exit;
40054 self->private_impl.f_bits = (v_bits & ((((uint32_t)(1u)) << v_n_bits) - 1u));
40055 self->private_impl.f_n_bits = v_n_bits;
40056 if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> self->private_impl.f_n_bits) != 0u)) {
40057 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
40058 goto exit;
40060 goto exit;
40061 exit:
40062 if (a_dst && a_dst->data.ptr) {
40063 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
40065 if (a_src && a_src->data.ptr) {
40066 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
40069 return status;
40072 // -------- func deflate.decoder.decode_huffman_fast64
40074 WUFFS_BASE__GENERATED_C_CODE
40075 static wuffs_base__status
40076 wuffs_deflate__decoder__decode_huffman_fast64(
40077 wuffs_deflate__decoder* self,
40078 wuffs_base__io_buffer* a_dst,
40079 wuffs_base__io_buffer* a_src) {
40080 return (*self->private_impl.choosy_decode_huffman_fast64)(self, a_dst, a_src);
40083 WUFFS_BASE__GENERATED_C_CODE
40084 static wuffs_base__status
40085 wuffs_deflate__decoder__decode_huffman_fast64__choosy_default(
40086 wuffs_deflate__decoder* self,
40087 wuffs_base__io_buffer* a_dst,
40088 wuffs_base__io_buffer* a_src) {
40089 wuffs_base__status status = wuffs_base__make_status(NULL);
40091 uint64_t v_bits = 0;
40092 uint32_t v_n_bits = 0;
40093 uint32_t v_table_entry = 0;
40094 uint32_t v_table_entry_n_bits = 0;
40095 uint64_t v_lmask = 0;
40096 uint64_t v_dmask = 0;
40097 uint32_t v_redir_top = 0;
40098 uint32_t v_redir_mask = 0;
40099 uint32_t v_length = 0;
40100 uint32_t v_dist_minus_1 = 0;
40101 uint32_t v_hlen = 0;
40102 uint32_t v_hdist = 0;
40103 uint32_t v_hdist_adjustment = 0;
40105 uint8_t* iop_a_dst = NULL;
40106 uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40107 uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40108 uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40109 if (a_dst && a_dst->data.ptr) {
40110 io0_a_dst = a_dst->data.ptr;
40111 io1_a_dst = io0_a_dst + a_dst->meta.wi;
40112 iop_a_dst = io1_a_dst;
40113 io2_a_dst = io0_a_dst + a_dst->data.len;
40114 if (a_dst->meta.closed) {
40115 io2_a_dst = iop_a_dst;
40118 const uint8_t* iop_a_src = NULL;
40119 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40120 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40121 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40122 if (a_src && a_src->data.ptr) {
40123 io0_a_src = a_src->data.ptr;
40124 io1_a_src = io0_a_src + a_src->meta.ri;
40125 iop_a_src = io1_a_src;
40126 io2_a_src = io0_a_src + a_src->meta.wi;
40129 if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7u)) != 0u)) {
40130 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
40131 goto exit;
40133 v_bits = ((uint64_t)(self->private_impl.f_bits));
40134 v_n_bits = self->private_impl.f_n_bits;
40135 v_lmask = ((((uint64_t)(1u)) << self->private_impl.f_n_huffs_bits[0u]) - 1u);
40136 v_dmask = ((((uint64_t)(1u)) << self->private_impl.f_n_huffs_bits[1u]) - 1u);
40137 if (self->private_impl.f_transformed_history_count < (a_dst ? a_dst->meta.pos : 0u)) {
40138 status = wuffs_base__make_status(wuffs_base__error__bad_i_o_position);
40139 goto exit;
40141 v_hdist_adjustment = ((uint32_t)((self->private_impl.f_transformed_history_count - (a_dst ? a_dst->meta.pos : 0u))));
40142 label__loop__continue:;
40143 while ((((uint64_t)(io2_a_dst - iop_a_dst)) >= 266u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 8u)) {
40144 v_bits |= ((uint64_t)(wuffs_base__peek_u64le__no_bounds_check(iop_a_src) << (v_n_bits & 63u)));
40145 iop_a_src += ((63u - (v_n_bits & 63u)) >> 3u);
40146 v_n_bits |= 56u;
40147 v_table_entry = self->private_data.f_huffs[0u][(v_bits & v_lmask)];
40148 v_table_entry_n_bits = (v_table_entry & 15u);
40149 v_bits >>= v_table_entry_n_bits;
40150 v_n_bits -= v_table_entry_n_bits;
40151 if ((v_table_entry >> 31u) != 0u) {
40152 (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)((v_table_entry >> 8u)))), iop_a_dst += 1);
40153 continue;
40154 } else if ((v_table_entry >> 30u) != 0u) {
40155 } else if ((v_table_entry >> 29u) != 0u) {
40156 self->private_impl.f_end_of_block = true;
40157 break;
40158 } else if ((v_table_entry >> 28u) != 0u) {
40159 v_redir_top = ((v_table_entry >> 8u) & 65535u);
40160 v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u);
40161 v_table_entry = self->private_data.f_huffs[0u][((v_redir_top + (((uint32_t)(v_bits)) & v_redir_mask)) & 1023u)];
40162 v_table_entry_n_bits = (v_table_entry & 15u);
40163 v_bits >>= v_table_entry_n_bits;
40164 v_n_bits -= v_table_entry_n_bits;
40165 if ((v_table_entry >> 31u) != 0u) {
40166 (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)((v_table_entry >> 8u)))), iop_a_dst += 1);
40167 continue;
40168 } else if ((v_table_entry >> 30u) != 0u) {
40169 } else if ((v_table_entry >> 29u) != 0u) {
40170 self->private_impl.f_end_of_block = true;
40171 break;
40172 } else if ((v_table_entry >> 28u) != 0u) {
40173 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
40174 goto exit;
40175 } else if ((v_table_entry >> 27u) != 0u) {
40176 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
40177 goto exit;
40178 } else {
40179 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
40180 goto exit;
40182 } else if ((v_table_entry >> 27u) != 0u) {
40183 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
40184 goto exit;
40185 } else {
40186 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
40187 goto exit;
40189 v_length = (((v_table_entry >> 8u) & 255u) + 3u);
40190 v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u);
40191 if (v_table_entry_n_bits > 0u) {
40192 v_length = (((v_length + 253u + ((uint32_t)(((v_bits) & WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U64(v_table_entry_n_bits))))) & 255u) + 3u);
40193 v_bits >>= v_table_entry_n_bits;
40194 v_n_bits -= v_table_entry_n_bits;
40196 v_table_entry = self->private_data.f_huffs[1u][(v_bits & v_dmask)];
40197 v_table_entry_n_bits = (v_table_entry & 15u);
40198 v_bits >>= v_table_entry_n_bits;
40199 v_n_bits -= v_table_entry_n_bits;
40200 if ((v_table_entry >> 28u) == 1u) {
40201 v_redir_top = ((v_table_entry >> 8u) & 65535u);
40202 v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u);
40203 v_table_entry = self->private_data.f_huffs[1u][((v_redir_top + (((uint32_t)(v_bits)) & v_redir_mask)) & 1023u)];
40204 v_table_entry_n_bits = (v_table_entry & 15u);
40205 v_bits >>= v_table_entry_n_bits;
40206 v_n_bits -= v_table_entry_n_bits;
40208 if ((v_table_entry >> 24u) != 64u) {
40209 if ((v_table_entry >> 24u) == 8u) {
40210 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
40211 goto exit;
40213 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
40214 goto exit;
40216 v_dist_minus_1 = ((v_table_entry >> 8u) & 32767u);
40217 v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u);
40218 v_dist_minus_1 = ((v_dist_minus_1 + ((uint32_t)(((v_bits) & WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U64(v_table_entry_n_bits))))) & 32767u);
40219 v_bits >>= v_table_entry_n_bits;
40220 v_n_bits -= v_table_entry_n_bits;
40221 do {
40222 if (((uint64_t)((v_dist_minus_1 + 1u))) > ((uint64_t)(iop_a_dst - io0_a_dst))) {
40223 v_hlen = 0u;
40224 v_hdist = ((uint32_t)((((uint64_t)((v_dist_minus_1 + 1u))) - ((uint64_t)(iop_a_dst - io0_a_dst)))));
40225 if (v_length > v_hdist) {
40226 v_length -= v_hdist;
40227 v_hlen = v_hdist;
40228 } else {
40229 v_hlen = v_length;
40230 v_length = 0u;
40232 v_hdist += v_hdist_adjustment;
40233 if (self->private_impl.f_history_index < v_hdist) {
40234 status = wuffs_base__make_status(wuffs_deflate__error__bad_distance);
40235 goto exit;
40237 wuffs_private_impl__io_writer__limited_copy_u32_from_slice(
40238 &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));
40239 if (v_length == 0u) {
40240 goto label__loop__continue;
40242 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)))) {
40243 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_distance);
40244 goto exit;
40247 if ((v_dist_minus_1 + 1u) >= 8u) {
40248 wuffs_private_impl__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast(
40249 &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u));
40250 } else if ((v_dist_minus_1 + 1u) == 1u) {
40251 wuffs_private_impl__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast(
40252 &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u));
40253 } else {
40254 wuffs_private_impl__io_writer__limited_copy_u32_from_history_fast(
40255 &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u));
40257 } while (0);
40259 if (v_n_bits > 63u) {
40260 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
40261 goto exit;
40263 while (v_n_bits >= 8u) {
40264 v_n_bits -= 8u;
40265 if (iop_a_src > io1_a_src) {
40266 iop_a_src--;
40267 } else {
40268 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_i_o);
40269 goto exit;
40272 self->private_impl.f_bits = ((uint32_t)((v_bits & ((((uint64_t)(1u)) << v_n_bits) - 1u))));
40273 self->private_impl.f_n_bits = v_n_bits;
40274 if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> self->private_impl.f_n_bits) != 0u)) {
40275 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
40276 goto exit;
40278 goto exit;
40279 exit:
40280 if (a_dst && a_dst->data.ptr) {
40281 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
40283 if (a_src && a_src->data.ptr) {
40284 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
40287 return status;
40290 // -------- func deflate.decoder.decode_huffman_slow
40292 WUFFS_BASE__GENERATED_C_CODE
40293 static wuffs_base__status
40294 wuffs_deflate__decoder__decode_huffman_slow(
40295 wuffs_deflate__decoder* self,
40296 wuffs_base__io_buffer* a_dst,
40297 wuffs_base__io_buffer* a_src) {
40298 wuffs_base__status status = wuffs_base__make_status(NULL);
40300 uint32_t v_bits = 0;
40301 uint32_t v_n_bits = 0;
40302 uint32_t v_table_entry = 0;
40303 uint32_t v_table_entry_n_bits = 0;
40304 uint32_t v_lmask = 0;
40305 uint32_t v_dmask = 0;
40306 uint32_t v_b0 = 0;
40307 uint32_t v_redir_top = 0;
40308 uint32_t v_redir_mask = 0;
40309 uint32_t v_b1 = 0;
40310 uint32_t v_length = 0;
40311 uint32_t v_b2 = 0;
40312 uint32_t v_b3 = 0;
40313 uint32_t v_b4 = 0;
40314 uint32_t v_dist_minus_1 = 0;
40315 uint32_t v_b5 = 0;
40316 uint32_t v_n_copied = 0;
40317 uint32_t v_hlen = 0;
40318 uint32_t v_hdist = 0;
40320 uint8_t* iop_a_dst = NULL;
40321 uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40322 uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40323 uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40324 if (a_dst && a_dst->data.ptr) {
40325 io0_a_dst = a_dst->data.ptr;
40326 io1_a_dst = io0_a_dst + a_dst->meta.wi;
40327 iop_a_dst = io1_a_dst;
40328 io2_a_dst = io0_a_dst + a_dst->data.len;
40329 if (a_dst->meta.closed) {
40330 io2_a_dst = iop_a_dst;
40333 const uint8_t* iop_a_src = NULL;
40334 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40335 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40336 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40337 if (a_src && a_src->data.ptr) {
40338 io0_a_src = a_src->data.ptr;
40339 io1_a_src = io0_a_src + a_src->meta.ri;
40340 iop_a_src = io1_a_src;
40341 io2_a_src = io0_a_src + a_src->meta.wi;
40344 uint32_t coro_susp_point = self->private_impl.p_decode_huffman_slow;
40345 if (coro_susp_point) {
40346 v_bits = self->private_data.s_decode_huffman_slow.v_bits;
40347 v_n_bits = self->private_data.s_decode_huffman_slow.v_n_bits;
40348 v_table_entry_n_bits = self->private_data.s_decode_huffman_slow.v_table_entry_n_bits;
40349 v_lmask = self->private_data.s_decode_huffman_slow.v_lmask;
40350 v_dmask = self->private_data.s_decode_huffman_slow.v_dmask;
40351 v_redir_top = self->private_data.s_decode_huffman_slow.v_redir_top;
40352 v_redir_mask = self->private_data.s_decode_huffman_slow.v_redir_mask;
40353 v_length = self->private_data.s_decode_huffman_slow.v_length;
40354 v_dist_minus_1 = self->private_data.s_decode_huffman_slow.v_dist_minus_1;
40356 switch (coro_susp_point) {
40357 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
40359 if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7u)) != 0u)) {
40360 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
40361 goto exit;
40363 v_bits = self->private_impl.f_bits;
40364 v_n_bits = self->private_impl.f_n_bits;
40365 v_lmask = ((((uint32_t)(1u)) << self->private_impl.f_n_huffs_bits[0u]) - 1u);
40366 v_dmask = ((((uint32_t)(1u)) << self->private_impl.f_n_huffs_bits[1u]) - 1u);
40367 label__loop__continue:;
40368 while ( ! (self->private_impl.p_decode_huffman_slow != 0)) {
40369 while (true) {
40370 v_table_entry = self->private_data.f_huffs[0u][(v_bits & v_lmask)];
40371 v_table_entry_n_bits = (v_table_entry & 15u);
40372 if (v_n_bits >= v_table_entry_n_bits) {
40373 v_bits >>= v_table_entry_n_bits;
40374 v_n_bits -= v_table_entry_n_bits;
40375 break;
40378 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
40379 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
40380 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40381 goto suspend;
40383 uint32_t t_0 = *iop_a_src++;
40384 v_b0 = t_0;
40386 v_bits |= (v_b0 << v_n_bits);
40387 v_n_bits += 8u;
40389 if ((v_table_entry >> 31u) != 0u) {
40390 self->private_data.s_decode_huffman_slow.scratch = ((uint8_t)((v_table_entry >> 8u)));
40391 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
40392 if (iop_a_dst == io2_a_dst) {
40393 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
40394 goto suspend;
40396 *iop_a_dst++ = ((uint8_t)(self->private_data.s_decode_huffman_slow.scratch));
40397 continue;
40398 } else if ((v_table_entry >> 30u) != 0u) {
40399 } else if ((v_table_entry >> 29u) != 0u) {
40400 self->private_impl.f_end_of_block = true;
40401 break;
40402 } else if ((v_table_entry >> 28u) != 0u) {
40403 v_redir_top = ((v_table_entry >> 8u) & 65535u);
40404 v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u);
40405 while (true) {
40406 v_table_entry = self->private_data.f_huffs[0u][((v_redir_top + (v_bits & v_redir_mask)) & 1023u)];
40407 v_table_entry_n_bits = (v_table_entry & 15u);
40408 if (v_n_bits >= v_table_entry_n_bits) {
40409 v_bits >>= v_table_entry_n_bits;
40410 v_n_bits -= v_table_entry_n_bits;
40411 break;
40414 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
40415 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
40416 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40417 goto suspend;
40419 uint32_t t_1 = *iop_a_src++;
40420 v_b1 = t_1;
40422 v_bits |= (v_b1 << v_n_bits);
40423 v_n_bits += 8u;
40425 if ((v_table_entry >> 31u) != 0u) {
40426 self->private_data.s_decode_huffman_slow.scratch = ((uint8_t)((v_table_entry >> 8u)));
40427 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
40428 if (iop_a_dst == io2_a_dst) {
40429 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
40430 goto suspend;
40432 *iop_a_dst++ = ((uint8_t)(self->private_data.s_decode_huffman_slow.scratch));
40433 continue;
40434 } else if ((v_table_entry >> 30u) != 0u) {
40435 } else if ((v_table_entry >> 29u) != 0u) {
40436 self->private_impl.f_end_of_block = true;
40437 break;
40438 } else if ((v_table_entry >> 28u) != 0u) {
40439 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
40440 goto exit;
40441 } else if ((v_table_entry >> 27u) != 0u) {
40442 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
40443 goto exit;
40444 } else {
40445 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
40446 goto exit;
40448 } else if ((v_table_entry >> 27u) != 0u) {
40449 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
40450 goto exit;
40451 } else {
40452 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
40453 goto exit;
40455 v_length = (((v_table_entry >> 8u) & 255u) + 3u);
40456 v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u);
40457 if (v_table_entry_n_bits > 0u) {
40458 while (v_n_bits < v_table_entry_n_bits) {
40460 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
40461 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
40462 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40463 goto suspend;
40465 uint32_t t_2 = *iop_a_src++;
40466 v_b2 = t_2;
40468 v_bits |= (v_b2 << v_n_bits);
40469 v_n_bits += 8u;
40471 v_length = (((v_length + 253u + ((v_bits) & WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U32(v_table_entry_n_bits))) & 255u) + 3u);
40472 v_bits >>= v_table_entry_n_bits;
40473 v_n_bits -= v_table_entry_n_bits;
40475 while (true) {
40476 v_table_entry = self->private_data.f_huffs[1u][(v_bits & v_dmask)];
40477 v_table_entry_n_bits = (v_table_entry & 15u);
40478 if (v_n_bits >= v_table_entry_n_bits) {
40479 v_bits >>= v_table_entry_n_bits;
40480 v_n_bits -= v_table_entry_n_bits;
40481 break;
40484 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
40485 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
40486 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40487 goto suspend;
40489 uint32_t t_3 = *iop_a_src++;
40490 v_b3 = t_3;
40492 v_bits |= (v_b3 << v_n_bits);
40493 v_n_bits += 8u;
40495 if ((v_table_entry >> 28u) == 1u) {
40496 v_redir_top = ((v_table_entry >> 8u) & 65535u);
40497 v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u);
40498 while (true) {
40499 v_table_entry = self->private_data.f_huffs[1u][((v_redir_top + (v_bits & v_redir_mask)) & 1023u)];
40500 v_table_entry_n_bits = (v_table_entry & 15u);
40501 if (v_n_bits >= v_table_entry_n_bits) {
40502 v_bits >>= v_table_entry_n_bits;
40503 v_n_bits -= v_table_entry_n_bits;
40504 break;
40507 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
40508 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
40509 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40510 goto suspend;
40512 uint32_t t_4 = *iop_a_src++;
40513 v_b4 = t_4;
40515 v_bits |= (v_b4 << v_n_bits);
40516 v_n_bits += 8u;
40519 if ((v_table_entry >> 24u) != 64u) {
40520 if ((v_table_entry >> 24u) == 8u) {
40521 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
40522 goto exit;
40524 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
40525 goto exit;
40527 v_dist_minus_1 = ((v_table_entry >> 8u) & 32767u);
40528 v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u);
40529 if (v_table_entry_n_bits > 0u) {
40530 while (v_n_bits < v_table_entry_n_bits) {
40532 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
40533 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
40534 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40535 goto suspend;
40537 uint32_t t_5 = *iop_a_src++;
40538 v_b5 = t_5;
40540 v_bits |= (v_b5 << v_n_bits);
40541 v_n_bits += 8u;
40543 v_dist_minus_1 = ((v_dist_minus_1 + ((v_bits) & WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U32(v_table_entry_n_bits))) & 32767u);
40544 v_bits >>= v_table_entry_n_bits;
40545 v_n_bits -= v_table_entry_n_bits;
40547 while (true) {
40548 if (((uint64_t)((v_dist_minus_1 + 1u))) > ((uint64_t)(iop_a_dst - io0_a_dst))) {
40549 v_hdist = ((uint32_t)((((uint64_t)((v_dist_minus_1 + 1u))) - ((uint64_t)(iop_a_dst - io0_a_dst)))));
40550 if (v_hdist < v_length) {
40551 v_hlen = v_hdist;
40552 } else {
40553 v_hlen = v_length;
40555 v_hdist += ((uint32_t)(((uint64_t)(self->private_impl.f_transformed_history_count - (a_dst ? a_dst->meta.pos : 0u)))));
40556 if (self->private_impl.f_history_index < v_hdist) {
40557 status = wuffs_base__make_status(wuffs_deflate__error__bad_distance);
40558 goto exit;
40560 v_n_copied = wuffs_private_impl__io_writer__limited_copy_u32_from_slice(
40561 &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));
40562 if (v_n_copied < v_hlen) {
40563 v_length -= v_n_copied;
40564 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
40565 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9);
40566 continue;
40568 v_length -= v_hlen;
40569 if (v_length == 0u) {
40570 goto label__loop__continue;
40573 v_n_copied = wuffs_private_impl__io_writer__limited_copy_u32_from_history(
40574 &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u));
40575 if (v_length <= v_n_copied) {
40576 goto label__loop__continue;
40578 v_length -= v_n_copied;
40579 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
40580 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10);
40583 self->private_impl.f_bits = v_bits;
40584 self->private_impl.f_n_bits = v_n_bits;
40585 if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7u)) != 0u)) {
40586 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
40587 goto exit;
40591 self->private_impl.p_decode_huffman_slow = 0;
40592 goto exit;
40595 goto suspend;
40596 suspend:
40597 self->private_impl.p_decode_huffman_slow = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
40598 self->private_data.s_decode_huffman_slow.v_bits = v_bits;
40599 self->private_data.s_decode_huffman_slow.v_n_bits = v_n_bits;
40600 self->private_data.s_decode_huffman_slow.v_table_entry_n_bits = v_table_entry_n_bits;
40601 self->private_data.s_decode_huffman_slow.v_lmask = v_lmask;
40602 self->private_data.s_decode_huffman_slow.v_dmask = v_dmask;
40603 self->private_data.s_decode_huffman_slow.v_redir_top = v_redir_top;
40604 self->private_data.s_decode_huffman_slow.v_redir_mask = v_redir_mask;
40605 self->private_data.s_decode_huffman_slow.v_length = v_length;
40606 self->private_data.s_decode_huffman_slow.v_dist_minus_1 = v_dist_minus_1;
40608 goto exit;
40609 exit:
40610 if (a_dst && a_dst->data.ptr) {
40611 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
40613 if (a_src && a_src->data.ptr) {
40614 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
40617 return status;
40620 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__DEFLATE)
40622 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GIF)
40624 // ---------------- Status Codes Implementations
40626 const char wuffs_gif__error__bad_lzw_code[] = "#gif: bad LZW code";
40627 const char wuffs_gif__error__bad_extension_label[] = "#gif: bad extension label";
40628 const char wuffs_gif__error__bad_frame_size[] = "#gif: bad frame size";
40629 const char wuffs_gif__error__bad_graphic_control[] = "#gif: bad graphic control";
40630 const char wuffs_gif__error__bad_header[] = "#gif: bad header";
40631 const char wuffs_gif__error__bad_literal_width[] = "#gif: bad literal width";
40632 const char wuffs_gif__error__bad_palette[] = "#gif: bad palette";
40633 const char wuffs_gif__error__truncated_input[] = "#gif: truncated input";
40634 const char wuffs_gif__error__internal_error_inconsistent_i_o[] = "#gif: internal error: inconsistent I/O";
40636 // ---------------- Private Consts
40638 static const uint32_t
40639 WUFFS_GIF__INTERLACE_START[5] WUFFS_BASE__POTENTIALLY_UNUSED = {
40640 4294967295u, 1u, 2u, 4u, 0u,
40643 static const uint8_t
40644 WUFFS_GIF__INTERLACE_DELTA[5] WUFFS_BASE__POTENTIALLY_UNUSED = {
40645 1u, 2u, 4u, 8u, 8u,
40648 static const uint8_t
40649 WUFFS_GIF__INTERLACE_COUNT[5] WUFFS_BASE__POTENTIALLY_UNUSED = {
40650 0u, 1u, 2u, 4u, 8u,
40653 static const uint8_t
40654 WUFFS_GIF__ANIMEXTS1DOT0[11] WUFFS_BASE__POTENTIALLY_UNUSED = {
40655 65u, 78u, 73u, 77u, 69u, 88u, 84u, 83u,
40656 49u, 46u, 48u,
40659 static const uint8_t
40660 WUFFS_GIF__NETSCAPE2DOT0[11] WUFFS_BASE__POTENTIALLY_UNUSED = {
40661 78u, 69u, 84u, 83u, 67u, 65u, 80u, 69u,
40662 50u, 46u, 48u,
40665 static const uint8_t
40666 WUFFS_GIF__ICCRGBG1012[11] WUFFS_BASE__POTENTIALLY_UNUSED = {
40667 73u, 67u, 67u, 82u, 71u, 66u, 71u, 49u,
40668 48u, 49u, 50u,
40671 static const uint8_t
40672 WUFFS_GIF__XMPDATAXMP[11] WUFFS_BASE__POTENTIALLY_UNUSED = {
40673 88u, 77u, 80u, 32u, 68u, 97u, 116u, 97u,
40674 88u, 77u, 80u,
40677 #define WUFFS_GIF__QUIRKS_BASE 1041635328u
40679 #define WUFFS_GIF__QUIRKS_COUNT 7u
40681 // ---------------- Private Initializer Prototypes
40683 // ---------------- Private Function Prototypes
40685 WUFFS_BASE__GENERATED_C_CODE
40686 static wuffs_base__status
40687 wuffs_gif__decoder__do_decode_image_config(
40688 wuffs_gif__decoder* self,
40689 wuffs_base__image_config* a_dst,
40690 wuffs_base__io_buffer* a_src);
40692 WUFFS_BASE__GENERATED_C_CODE
40693 static wuffs_base__status
40694 wuffs_gif__decoder__do_tell_me_more(
40695 wuffs_gif__decoder* self,
40696 wuffs_base__io_buffer* a_dst,
40697 wuffs_base__more_information* a_minfo,
40698 wuffs_base__io_buffer* a_src);
40700 WUFFS_BASE__GENERATED_C_CODE
40701 static wuffs_base__status
40702 wuffs_gif__decoder__do_decode_frame_config(
40703 wuffs_gif__decoder* self,
40704 wuffs_base__frame_config* a_dst,
40705 wuffs_base__io_buffer* a_src);
40707 WUFFS_BASE__GENERATED_C_CODE
40708 static wuffs_base__status
40709 wuffs_gif__decoder__skip_frame(
40710 wuffs_gif__decoder* self,
40711 wuffs_base__io_buffer* a_src);
40713 WUFFS_BASE__GENERATED_C_CODE
40714 static wuffs_base__status
40715 wuffs_gif__decoder__do_decode_frame(
40716 wuffs_gif__decoder* self,
40717 wuffs_base__pixel_buffer* a_dst,
40718 wuffs_base__io_buffer* a_src,
40719 wuffs_base__pixel_blend a_blend,
40720 wuffs_base__slice_u8 a_workbuf,
40721 wuffs_base__decode_frame_options* a_opts);
40723 WUFFS_BASE__GENERATED_C_CODE
40724 static wuffs_base__empty_struct
40725 wuffs_gif__decoder__reset_gc(
40726 wuffs_gif__decoder* self);
40728 WUFFS_BASE__GENERATED_C_CODE
40729 static wuffs_base__status
40730 wuffs_gif__decoder__decode_up_to_id_part1(
40731 wuffs_gif__decoder* self,
40732 wuffs_base__io_buffer* a_src);
40734 WUFFS_BASE__GENERATED_C_CODE
40735 static wuffs_base__status
40736 wuffs_gif__decoder__decode_header(
40737 wuffs_gif__decoder* self,
40738 wuffs_base__io_buffer* a_src);
40740 WUFFS_BASE__GENERATED_C_CODE
40741 static wuffs_base__status
40742 wuffs_gif__decoder__decode_lsd(
40743 wuffs_gif__decoder* self,
40744 wuffs_base__io_buffer* a_src);
40746 WUFFS_BASE__GENERATED_C_CODE
40747 static wuffs_base__status
40748 wuffs_gif__decoder__decode_extension(
40749 wuffs_gif__decoder* self,
40750 wuffs_base__io_buffer* a_src);
40752 WUFFS_BASE__GENERATED_C_CODE
40753 static wuffs_base__status
40754 wuffs_gif__decoder__skip_blocks(
40755 wuffs_gif__decoder* self,
40756 wuffs_base__io_buffer* a_src);
40758 WUFFS_BASE__GENERATED_C_CODE
40759 static wuffs_base__status
40760 wuffs_gif__decoder__decode_ae(
40761 wuffs_gif__decoder* self,
40762 wuffs_base__io_buffer* a_src);
40764 WUFFS_BASE__GENERATED_C_CODE
40765 static wuffs_base__status
40766 wuffs_gif__decoder__decode_gc(
40767 wuffs_gif__decoder* self,
40768 wuffs_base__io_buffer* a_src);
40770 WUFFS_BASE__GENERATED_C_CODE
40771 static wuffs_base__status
40772 wuffs_gif__decoder__decode_id_part0(
40773 wuffs_gif__decoder* self,
40774 wuffs_base__io_buffer* a_src);
40776 WUFFS_BASE__GENERATED_C_CODE
40777 static wuffs_base__status
40778 wuffs_gif__decoder__decode_id_part1(
40779 wuffs_gif__decoder* self,
40780 wuffs_base__pixel_buffer* a_dst,
40781 wuffs_base__io_buffer* a_src,
40782 wuffs_base__pixel_blend a_blend);
40784 WUFFS_BASE__GENERATED_C_CODE
40785 static wuffs_base__status
40786 wuffs_gif__decoder__decode_id_part2(
40787 wuffs_gif__decoder* self,
40788 wuffs_base__pixel_buffer* a_dst,
40789 wuffs_base__io_buffer* a_src,
40790 wuffs_base__slice_u8 a_workbuf);
40792 WUFFS_BASE__GENERATED_C_CODE
40793 static wuffs_base__status
40794 wuffs_gif__decoder__copy_to_image_buffer(
40795 wuffs_gif__decoder* self,
40796 wuffs_base__pixel_buffer* a_pb,
40797 wuffs_base__slice_u8 a_src);
40799 WUFFS_BASE__GENERATED_C_CODE
40800 static wuffs_base__empty_struct
40801 wuffs_gif__decoder__lzw_init(
40802 wuffs_gif__decoder* self);
40804 WUFFS_BASE__GENERATED_C_CODE
40805 static wuffs_base__empty_struct
40806 wuffs_gif__decoder__lzw_read_from(
40807 wuffs_gif__decoder* self,
40808 wuffs_base__io_buffer* a_src);
40810 // ---------------- VTables
40812 const wuffs_base__image_decoder__func_ptrs
40813 wuffs_gif__decoder__func_ptrs_for__wuffs_base__image_decoder = {
40814 (wuffs_base__status(*)(void*,
40815 wuffs_base__pixel_buffer*,
40816 wuffs_base__io_buffer*,
40817 wuffs_base__pixel_blend,
40818 wuffs_base__slice_u8,
40819 wuffs_base__decode_frame_options*))(&wuffs_gif__decoder__decode_frame),
40820 (wuffs_base__status(*)(void*,
40821 wuffs_base__frame_config*,
40822 wuffs_base__io_buffer*))(&wuffs_gif__decoder__decode_frame_config),
40823 (wuffs_base__status(*)(void*,
40824 wuffs_base__image_config*,
40825 wuffs_base__io_buffer*))(&wuffs_gif__decoder__decode_image_config),
40826 (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_gif__decoder__frame_dirty_rect),
40827 (uint64_t(*)(const void*,
40828 uint32_t))(&wuffs_gif__decoder__get_quirk),
40829 (uint32_t(*)(const void*))(&wuffs_gif__decoder__num_animation_loops),
40830 (uint64_t(*)(const void*))(&wuffs_gif__decoder__num_decoded_frame_configs),
40831 (uint64_t(*)(const void*))(&wuffs_gif__decoder__num_decoded_frames),
40832 (wuffs_base__status(*)(void*,
40833 uint64_t,
40834 uint64_t))(&wuffs_gif__decoder__restart_frame),
40835 (wuffs_base__status(*)(void*,
40836 uint32_t,
40837 uint64_t))(&wuffs_gif__decoder__set_quirk),
40838 (wuffs_base__empty_struct(*)(void*,
40839 uint32_t,
40840 bool))(&wuffs_gif__decoder__set_report_metadata),
40841 (wuffs_base__status(*)(void*,
40842 wuffs_base__io_buffer*,
40843 wuffs_base__more_information*,
40844 wuffs_base__io_buffer*))(&wuffs_gif__decoder__tell_me_more),
40845 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_gif__decoder__workbuf_len),
40848 // ---------------- Initializer Implementations
40850 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
40851 wuffs_gif__decoder__initialize(
40852 wuffs_gif__decoder* self,
40853 size_t sizeof_star_self,
40854 uint64_t wuffs_version,
40855 uint32_t options){
40856 if (!self) {
40857 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
40859 if (sizeof(*self) != sizeof_star_self) {
40860 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
40862 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
40863 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
40864 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
40867 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
40868 // The whole point of this if-check is to detect an uninitialized *self.
40869 // We disable the warning on GCC. Clang-5.0 does not have this warning.
40870 #if !defined(__clang__) && defined(__GNUC__)
40871 #pragma GCC diagnostic push
40872 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
40873 #endif
40874 if (self->private_impl.magic != 0) {
40875 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
40877 #if !defined(__clang__) && defined(__GNUC__)
40878 #pragma GCC diagnostic pop
40879 #endif
40880 } else {
40881 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
40882 memset(self, 0, sizeof(*self));
40883 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
40884 } else {
40885 memset(&(self->private_impl), 0, sizeof(self->private_impl));
40889 self->private_impl.magic = WUFFS_BASE__MAGIC;
40890 self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
40891 wuffs_base__image_decoder__vtable_name;
40892 self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
40893 (const void*)(&wuffs_gif__decoder__func_ptrs_for__wuffs_base__image_decoder);
40894 return wuffs_base__make_status(NULL);
40897 wuffs_gif__decoder*
40898 wuffs_gif__decoder__alloc(void) {
40899 wuffs_gif__decoder* x =
40900 (wuffs_gif__decoder*)(calloc(1, sizeof(wuffs_gif__decoder)));
40901 if (!x) {
40902 return NULL;
40904 if (wuffs_gif__decoder__initialize(
40905 x, sizeof(wuffs_gif__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
40906 free(x);
40907 return NULL;
40909 return x;
40912 size_t
40913 sizeof__wuffs_gif__decoder(void) {
40914 return sizeof(wuffs_gif__decoder);
40917 // ---------------- Function Implementations
40919 // -------- func gif.decoder.get_quirk
40921 WUFFS_BASE__GENERATED_C_CODE
40922 WUFFS_BASE__MAYBE_STATIC uint64_t
40923 wuffs_gif__decoder__get_quirk(
40924 const wuffs_gif__decoder* self,
40925 uint32_t a_key) {
40926 if (!self) {
40927 return 0;
40929 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
40930 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
40931 return 0;
40934 uint32_t v_key = 0;
40936 if (a_key >= 1041635328u) {
40937 v_key = (a_key - 1041635328u);
40938 if (v_key < 7u) {
40939 if (self->private_impl.f_quirks[v_key]) {
40940 return 1u;
40944 return 0u;
40947 // -------- func gif.decoder.set_quirk
40949 WUFFS_BASE__GENERATED_C_CODE
40950 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
40951 wuffs_gif__decoder__set_quirk(
40952 wuffs_gif__decoder* self,
40953 uint32_t a_key,
40954 uint64_t a_value) {
40955 if (!self) {
40956 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
40958 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
40959 return wuffs_base__make_status(
40960 (self->private_impl.magic == WUFFS_BASE__DISABLED)
40961 ? wuffs_base__error__disabled_by_previous_error
40962 : wuffs_base__error__initialize_not_called);
40965 if ((self->private_impl.f_call_sequence == 0u) && (a_key >= 1041635328u)) {
40966 a_key -= 1041635328u;
40967 if (a_key < 7u) {
40968 self->private_impl.f_quirks[a_key] = (a_value > 0u);
40969 return wuffs_base__make_status(NULL);
40972 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
40975 // -------- func gif.decoder.decode_image_config
40977 WUFFS_BASE__GENERATED_C_CODE
40978 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
40979 wuffs_gif__decoder__decode_image_config(
40980 wuffs_gif__decoder* self,
40981 wuffs_base__image_config* a_dst,
40982 wuffs_base__io_buffer* a_src) {
40983 if (!self) {
40984 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
40986 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
40987 return wuffs_base__make_status(
40988 (self->private_impl.magic == WUFFS_BASE__DISABLED)
40989 ? wuffs_base__error__disabled_by_previous_error
40990 : wuffs_base__error__initialize_not_called);
40992 if (!a_src) {
40993 self->private_impl.magic = WUFFS_BASE__DISABLED;
40994 return wuffs_base__make_status(wuffs_base__error__bad_argument);
40996 if ((self->private_impl.active_coroutine != 0) &&
40997 (self->private_impl.active_coroutine != 1)) {
40998 self->private_impl.magic = WUFFS_BASE__DISABLED;
40999 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
41001 self->private_impl.active_coroutine = 0;
41002 wuffs_base__status status = wuffs_base__make_status(NULL);
41004 wuffs_base__status v_status = wuffs_base__make_status(NULL);
41006 uint32_t coro_susp_point = self->private_impl.p_decode_image_config;
41007 switch (coro_susp_point) {
41008 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
41010 while (true) {
41012 wuffs_base__status t_0 = wuffs_gif__decoder__do_decode_image_config(self, a_dst, a_src);
41013 v_status = t_0;
41015 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
41016 status = wuffs_base__make_status(wuffs_gif__error__truncated_input);
41017 goto exit;
41019 status = v_status;
41020 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
41024 self->private_impl.p_decode_image_config = 0;
41025 goto exit;
41028 goto suspend;
41029 suspend:
41030 self->private_impl.p_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
41031 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
41033 goto exit;
41034 exit:
41035 if (wuffs_base__status__is_error(&status)) {
41036 self->private_impl.magic = WUFFS_BASE__DISABLED;
41038 return status;
41041 // -------- func gif.decoder.do_decode_image_config
41043 WUFFS_BASE__GENERATED_C_CODE
41044 static wuffs_base__status
41045 wuffs_gif__decoder__do_decode_image_config(
41046 wuffs_gif__decoder* self,
41047 wuffs_base__image_config* a_dst,
41048 wuffs_base__io_buffer* a_src) {
41049 wuffs_base__status status = wuffs_base__make_status(NULL);
41051 bool v_ffio = false;
41053 uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config;
41054 switch (coro_susp_point) {
41055 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
41057 if (self->private_impl.f_call_sequence != 0u) {
41058 status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
41059 goto exit;
41060 } else if ( ! self->private_impl.f_seen_header) {
41061 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
41062 status = wuffs_gif__decoder__decode_header(self, a_src);
41063 if (status.repr) {
41064 goto suspend;
41066 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
41067 status = wuffs_gif__decoder__decode_lsd(self, a_src);
41068 if (status.repr) {
41069 goto suspend;
41071 self->private_impl.f_seen_header = true;
41073 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
41074 status = wuffs_gif__decoder__decode_up_to_id_part1(self, a_src);
41075 if (status.repr) {
41076 goto suspend;
41078 v_ffio = ! self->private_impl.f_gc_has_transparent_index;
41079 if ( ! self->private_impl.f_quirks[2u]) {
41080 v_ffio = (v_ffio &&
41081 (self->private_impl.f_frame_rect_x0 == 0u) &&
41082 (self->private_impl.f_frame_rect_y0 == 0u) &&
41083 (self->private_impl.f_frame_rect_x1 == self->private_impl.f_width) &&
41084 (self->private_impl.f_frame_rect_y1 == self->private_impl.f_height));
41085 } else if (v_ffio) {
41086 self->private_impl.f_black_color_u32_argb_premul = 4278190080u;
41088 if (self->private_impl.f_background_color_u32_argb_premul == 77u) {
41089 self->private_impl.f_background_color_u32_argb_premul = self->private_impl.f_black_color_u32_argb_premul;
41091 if (a_dst != NULL) {
41092 wuffs_base__image_config__set(
41093 a_dst,
41094 2198077448u,
41096 self->private_impl.f_width,
41097 self->private_impl.f_height,
41098 self->private_impl.f_frame_config_io_position,
41099 v_ffio);
41101 if (self->private_impl.f_call_sequence == 0u) {
41102 self->private_impl.f_call_sequence = 32u;
41105 goto ok;
41107 self->private_impl.p_do_decode_image_config = 0;
41108 goto exit;
41111 goto suspend;
41112 suspend:
41113 self->private_impl.p_do_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
41115 goto exit;
41116 exit:
41117 return status;
41120 // -------- func gif.decoder.set_report_metadata
41122 WUFFS_BASE__GENERATED_C_CODE
41123 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
41124 wuffs_gif__decoder__set_report_metadata(
41125 wuffs_gif__decoder* self,
41126 uint32_t a_fourcc,
41127 bool a_report) {
41128 if (!self) {
41129 return wuffs_base__make_empty_struct();
41131 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
41132 return wuffs_base__make_empty_struct();
41135 if (a_fourcc == 1229144912u) {
41136 self->private_impl.f_report_metadata_iccp = a_report;
41137 } else if (a_fourcc == 1481461792u) {
41138 self->private_impl.f_report_metadata_xmp = a_report;
41140 return wuffs_base__make_empty_struct();
41143 // -------- func gif.decoder.tell_me_more
41145 WUFFS_BASE__GENERATED_C_CODE
41146 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
41147 wuffs_gif__decoder__tell_me_more(
41148 wuffs_gif__decoder* self,
41149 wuffs_base__io_buffer* a_dst,
41150 wuffs_base__more_information* a_minfo,
41151 wuffs_base__io_buffer* a_src) {
41152 if (!self) {
41153 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
41155 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
41156 return wuffs_base__make_status(
41157 (self->private_impl.magic == WUFFS_BASE__DISABLED)
41158 ? wuffs_base__error__disabled_by_previous_error
41159 : wuffs_base__error__initialize_not_called);
41161 if (!a_dst || !a_src) {
41162 self->private_impl.magic = WUFFS_BASE__DISABLED;
41163 return wuffs_base__make_status(wuffs_base__error__bad_argument);
41165 if ((self->private_impl.active_coroutine != 0) &&
41166 (self->private_impl.active_coroutine != 2)) {
41167 self->private_impl.magic = WUFFS_BASE__DISABLED;
41168 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
41170 self->private_impl.active_coroutine = 0;
41171 wuffs_base__status status = wuffs_base__make_status(NULL);
41173 wuffs_base__status v_status = wuffs_base__make_status(NULL);
41175 uint32_t coro_susp_point = self->private_impl.p_tell_me_more;
41176 switch (coro_susp_point) {
41177 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
41179 while (true) {
41181 wuffs_base__status t_0 = wuffs_gif__decoder__do_tell_me_more(self, a_dst, a_minfo, a_src);
41182 v_status = t_0;
41184 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
41185 status = wuffs_base__make_status(wuffs_gif__error__truncated_input);
41186 goto exit;
41188 status = v_status;
41189 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
41193 self->private_impl.p_tell_me_more = 0;
41194 goto exit;
41197 goto suspend;
41198 suspend:
41199 self->private_impl.p_tell_me_more = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
41200 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
41202 goto exit;
41203 exit:
41204 if (wuffs_base__status__is_error(&status)) {
41205 self->private_impl.magic = WUFFS_BASE__DISABLED;
41207 return status;
41210 // -------- func gif.decoder.do_tell_me_more
41212 WUFFS_BASE__GENERATED_C_CODE
41213 static wuffs_base__status
41214 wuffs_gif__decoder__do_tell_me_more(
41215 wuffs_gif__decoder* self,
41216 wuffs_base__io_buffer* a_dst,
41217 wuffs_base__more_information* a_minfo,
41218 wuffs_base__io_buffer* a_src) {
41219 wuffs_base__status status = wuffs_base__make_status(NULL);
41221 uint64_t v_chunk_length = 0;
41223 const uint8_t* iop_a_src = NULL;
41224 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41225 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41226 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41227 if (a_src && a_src->data.ptr) {
41228 io0_a_src = a_src->data.ptr;
41229 io1_a_src = io0_a_src + a_src->meta.ri;
41230 iop_a_src = io1_a_src;
41231 io2_a_src = io0_a_src + a_src->meta.wi;
41234 uint32_t coro_susp_point = self->private_impl.p_do_tell_me_more;
41235 switch (coro_susp_point) {
41236 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
41238 if (((uint8_t)(self->private_impl.f_call_sequence & 16u)) == 0u) {
41239 status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
41240 goto exit;
41242 if (self->private_impl.f_metadata_fourcc == 0u) {
41243 status = wuffs_base__make_status(wuffs_base__error__no_more_information);
41244 goto exit;
41246 while (true) {
41247 while (true) {
41248 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) {
41249 if (a_minfo != NULL) {
41250 wuffs_base__more_information__set(a_minfo,
41253 self->private_impl.f_metadata_io_position,
41255 0u);
41257 status = wuffs_base__make_status(wuffs_base__suspension__mispositioned_read);
41258 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
41259 continue;
41261 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
41262 if (a_minfo != NULL) {
41263 wuffs_base__more_information__set(a_minfo,
41268 0u);
41270 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
41271 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
41272 continue;
41274 break;
41276 v_chunk_length = ((uint64_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src)));
41277 if (v_chunk_length <= 0u) {
41278 iop_a_src += 1u;
41279 break;
41281 if (self->private_impl.f_metadata_fourcc == 1481461792u) {
41282 v_chunk_length += 1u;
41283 } else {
41284 iop_a_src += 1u;
41286 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);
41287 if (a_minfo != NULL) {
41288 wuffs_base__more_information__set(a_minfo,
41290 self->private_impl.f_metadata_fourcc,
41292 wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))),
41293 self->private_impl.f_metadata_io_position);
41295 status = wuffs_base__make_status(wuffs_base__suspension__even_more_information);
41296 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
41298 if (a_minfo != NULL) {
41299 wuffs_base__more_information__set(a_minfo,
41301 self->private_impl.f_metadata_fourcc,
41303 self->private_impl.f_metadata_io_position,
41304 self->private_impl.f_metadata_io_position);
41306 self->private_impl.f_call_sequence &= 239u;
41307 self->private_impl.f_metadata_fourcc = 0u;
41308 self->private_impl.f_metadata_io_position = 0u;
41309 status = wuffs_base__make_status(NULL);
41310 goto ok;
41313 self->private_impl.p_do_tell_me_more = 0;
41314 goto exit;
41317 goto suspend;
41318 suspend:
41319 self->private_impl.p_do_tell_me_more = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
41321 goto exit;
41322 exit:
41323 if (a_src && a_src->data.ptr) {
41324 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
41327 return status;
41330 // -------- func gif.decoder.num_animation_loops
41332 WUFFS_BASE__GENERATED_C_CODE
41333 WUFFS_BASE__MAYBE_STATIC uint32_t
41334 wuffs_gif__decoder__num_animation_loops(
41335 const wuffs_gif__decoder* self) {
41336 if (!self) {
41337 return 0;
41339 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
41340 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
41341 return 0;
41344 if (self->private_impl.f_seen_num_animation_loops_value) {
41345 return self->private_impl.f_num_animation_loops_value;
41347 if (self->private_impl.f_num_decoded_frame_configs_value > 1u) {
41348 return 1u;
41350 return 0u;
41353 // -------- func gif.decoder.num_decoded_frame_configs
41355 WUFFS_BASE__GENERATED_C_CODE
41356 WUFFS_BASE__MAYBE_STATIC uint64_t
41357 wuffs_gif__decoder__num_decoded_frame_configs(
41358 const wuffs_gif__decoder* self) {
41359 if (!self) {
41360 return 0;
41362 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
41363 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
41364 return 0;
41367 return self->private_impl.f_num_decoded_frame_configs_value;
41370 // -------- func gif.decoder.num_decoded_frames
41372 WUFFS_BASE__GENERATED_C_CODE
41373 WUFFS_BASE__MAYBE_STATIC uint64_t
41374 wuffs_gif__decoder__num_decoded_frames(
41375 const wuffs_gif__decoder* self) {
41376 if (!self) {
41377 return 0;
41379 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
41380 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
41381 return 0;
41384 return self->private_impl.f_num_decoded_frames_value;
41387 // -------- func gif.decoder.frame_dirty_rect
41389 WUFFS_BASE__GENERATED_C_CODE
41390 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
41391 wuffs_gif__decoder__frame_dirty_rect(
41392 const wuffs_gif__decoder* self) {
41393 if (!self) {
41394 return wuffs_base__utility__empty_rect_ie_u32();
41396 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
41397 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
41398 return wuffs_base__utility__empty_rect_ie_u32();
41401 return wuffs_base__utility__make_rect_ie_u32(
41402 wuffs_base__u32__min(self->private_impl.f_frame_rect_x0, self->private_impl.f_width),
41403 wuffs_base__u32__min(self->private_impl.f_frame_rect_y0, self->private_impl.f_height),
41404 wuffs_base__u32__min(self->private_impl.f_frame_rect_x1, self->private_impl.f_width),
41405 wuffs_base__u32__min(self->private_impl.f_dirty_max_excl_y, self->private_impl.f_height));
41408 // -------- func gif.decoder.workbuf_len
41410 WUFFS_BASE__GENERATED_C_CODE
41411 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
41412 wuffs_gif__decoder__workbuf_len(
41413 const wuffs_gif__decoder* self) {
41414 if (!self) {
41415 return wuffs_base__utility__empty_range_ii_u64();
41417 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
41418 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
41419 return wuffs_base__utility__empty_range_ii_u64();
41422 return wuffs_base__utility__make_range_ii_u64(0u, 0u);
41425 // -------- func gif.decoder.restart_frame
41427 WUFFS_BASE__GENERATED_C_CODE
41428 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
41429 wuffs_gif__decoder__restart_frame(
41430 wuffs_gif__decoder* self,
41431 uint64_t a_index,
41432 uint64_t a_io_position) {
41433 if (!self) {
41434 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
41436 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
41437 return wuffs_base__make_status(
41438 (self->private_impl.magic == WUFFS_BASE__DISABLED)
41439 ? wuffs_base__error__disabled_by_previous_error
41440 : wuffs_base__error__initialize_not_called);
41443 if (self->private_impl.f_call_sequence < 32u) {
41444 return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
41445 } else if (a_io_position == 0u) {
41446 return wuffs_base__make_status(wuffs_base__error__bad_argument);
41448 self->private_impl.f_delayed_num_decoded_frames = false;
41449 self->private_impl.f_frame_config_io_position = a_io_position;
41450 self->private_impl.f_num_decoded_frame_configs_value = a_index;
41451 self->private_impl.f_num_decoded_frames_value = a_index;
41452 wuffs_gif__decoder__reset_gc(self);
41453 self->private_impl.f_call_sequence = 40u;
41454 return wuffs_base__make_status(NULL);
41457 // -------- func gif.decoder.decode_frame_config
41459 WUFFS_BASE__GENERATED_C_CODE
41460 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
41461 wuffs_gif__decoder__decode_frame_config(
41462 wuffs_gif__decoder* self,
41463 wuffs_base__frame_config* a_dst,
41464 wuffs_base__io_buffer* a_src) {
41465 if (!self) {
41466 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
41468 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
41469 return wuffs_base__make_status(
41470 (self->private_impl.magic == WUFFS_BASE__DISABLED)
41471 ? wuffs_base__error__disabled_by_previous_error
41472 : wuffs_base__error__initialize_not_called);
41474 if (!a_src) {
41475 self->private_impl.magic = WUFFS_BASE__DISABLED;
41476 return wuffs_base__make_status(wuffs_base__error__bad_argument);
41478 if ((self->private_impl.active_coroutine != 0) &&
41479 (self->private_impl.active_coroutine != 3)) {
41480 self->private_impl.magic = WUFFS_BASE__DISABLED;
41481 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
41483 self->private_impl.active_coroutine = 0;
41484 wuffs_base__status status = wuffs_base__make_status(NULL);
41486 wuffs_base__status v_status = wuffs_base__make_status(NULL);
41488 uint32_t coro_susp_point = self->private_impl.p_decode_frame_config;
41489 switch (coro_susp_point) {
41490 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
41492 while (true) {
41494 wuffs_base__status t_0 = wuffs_gif__decoder__do_decode_frame_config(self, a_dst, a_src);
41495 v_status = t_0;
41497 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
41498 status = wuffs_base__make_status(wuffs_gif__error__truncated_input);
41499 goto exit;
41501 status = v_status;
41502 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
41506 self->private_impl.p_decode_frame_config = 0;
41507 goto exit;
41510 goto suspend;
41511 suspend:
41512 self->private_impl.p_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
41513 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
41515 goto exit;
41516 exit:
41517 if (wuffs_base__status__is_error(&status)) {
41518 self->private_impl.magic = WUFFS_BASE__DISABLED;
41520 return status;
41523 // -------- func gif.decoder.do_decode_frame_config
41525 WUFFS_BASE__GENERATED_C_CODE
41526 static wuffs_base__status
41527 wuffs_gif__decoder__do_decode_frame_config(
41528 wuffs_gif__decoder* self,
41529 wuffs_base__frame_config* a_dst,
41530 wuffs_base__io_buffer* a_src) {
41531 wuffs_base__status status = wuffs_base__make_status(NULL);
41533 uint32_t v_background_color = 0;
41534 uint8_t v_flags = 0;
41536 const uint8_t* iop_a_src = NULL;
41537 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41538 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41539 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41540 if (a_src && a_src->data.ptr) {
41541 io0_a_src = a_src->data.ptr;
41542 io1_a_src = io0_a_src + a_src->meta.ri;
41543 iop_a_src = io1_a_src;
41544 io2_a_src = io0_a_src + a_src->meta.wi;
41547 uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config;
41548 if (coro_susp_point) {
41549 v_background_color = self->private_data.s_do_decode_frame_config.v_background_color;
41551 switch (coro_susp_point) {
41552 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
41554 self->private_impl.f_dirty_max_excl_y = 0u;
41555 if (((uint8_t)(self->private_impl.f_call_sequence & 16u)) != 0u) {
41556 status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
41557 goto exit;
41558 } else if (self->private_impl.f_call_sequence == 32u) {
41559 } else if (self->private_impl.f_call_sequence < 32u) {
41560 if (a_src) {
41561 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
41563 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
41564 status = wuffs_gif__decoder__do_decode_image_config(self, NULL, a_src);
41565 if (a_src) {
41566 iop_a_src = a_src->data.ptr + a_src->meta.ri;
41568 if (status.repr) {
41569 goto suspend;
41571 } else if (self->private_impl.f_call_sequence == 40u) {
41572 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)))) {
41573 status = wuffs_base__make_status(wuffs_base__error__bad_restart);
41574 goto exit;
41576 } else if (self->private_impl.f_call_sequence == 64u) {
41577 if (a_src) {
41578 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
41580 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
41581 status = wuffs_gif__decoder__skip_frame(self, a_src);
41582 if (a_src) {
41583 iop_a_src = a_src->data.ptr + a_src->meta.ri;
41585 if (status.repr) {
41586 goto suspend;
41588 if (self->private_impl.f_call_sequence >= 96u) {
41589 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
41590 goto ok;
41592 } else {
41593 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
41594 goto ok;
41596 if ((self->private_impl.f_num_decoded_frame_configs_value > 0u) || (self->private_impl.f_call_sequence == 40u)) {
41597 if (a_src) {
41598 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
41600 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
41601 status = wuffs_gif__decoder__decode_up_to_id_part1(self, a_src);
41602 if (a_src) {
41603 iop_a_src = a_src->data.ptr + a_src->meta.ri;
41605 if (status.repr) {
41606 goto suspend;
41608 if (self->private_impl.f_call_sequence >= 96u) {
41609 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
41610 goto ok;
41613 v_background_color = self->private_impl.f_black_color_u32_argb_premul;
41614 if ( ! self->private_impl.f_gc_has_transparent_index) {
41615 v_background_color = self->private_impl.f_background_color_u32_argb_premul;
41616 if (self->private_impl.f_quirks[1u] && (self->private_impl.f_num_decoded_frame_configs_value == 0u)) {
41617 while (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
41618 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
41619 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
41621 v_flags = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
41622 if (((uint8_t)(v_flags & 128u)) != 0u) {
41623 v_background_color = self->private_impl.f_black_color_u32_argb_premul;
41627 if (a_dst != NULL) {
41628 wuffs_base__frame_config__set(
41629 a_dst,
41630 wuffs_base__utility__make_rect_ie_u32(
41631 wuffs_base__u32__min(self->private_impl.f_frame_rect_x0, self->private_impl.f_width),
41632 wuffs_base__u32__min(self->private_impl.f_frame_rect_y0, self->private_impl.f_height),
41633 wuffs_base__u32__min(self->private_impl.f_frame_rect_x1, self->private_impl.f_width),
41634 wuffs_base__u32__min(self->private_impl.f_frame_rect_y1, self->private_impl.f_height)),
41635 ((wuffs_base__flicks)(self->private_impl.f_gc_duration)),
41636 self->private_impl.f_num_decoded_frame_configs_value,
41637 self->private_impl.f_frame_config_io_position,
41638 self->private_impl.f_gc_disposal,
41639 ! self->private_impl.f_gc_has_transparent_index,
41640 false,
41641 v_background_color);
41643 wuffs_private_impl__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frame_configs_value, 1u);
41644 self->private_impl.f_call_sequence = 64u;
41647 self->private_impl.p_do_decode_frame_config = 0;
41648 goto exit;
41651 goto suspend;
41652 suspend:
41653 self->private_impl.p_do_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
41654 self->private_data.s_do_decode_frame_config.v_background_color = v_background_color;
41656 goto exit;
41657 exit:
41658 if (a_src && a_src->data.ptr) {
41659 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
41662 return status;
41665 // -------- func gif.decoder.skip_frame
41667 WUFFS_BASE__GENERATED_C_CODE
41668 static wuffs_base__status
41669 wuffs_gif__decoder__skip_frame(
41670 wuffs_gif__decoder* self,
41671 wuffs_base__io_buffer* a_src) {
41672 wuffs_base__status status = wuffs_base__make_status(NULL);
41674 uint8_t v_flags = 0;
41675 uint8_t v_lw = 0;
41677 const uint8_t* iop_a_src = NULL;
41678 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41679 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41680 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41681 if (a_src && a_src->data.ptr) {
41682 io0_a_src = a_src->data.ptr;
41683 io1_a_src = io0_a_src + a_src->meta.ri;
41684 iop_a_src = io1_a_src;
41685 io2_a_src = io0_a_src + a_src->meta.wi;
41688 uint32_t coro_susp_point = self->private_impl.p_skip_frame;
41689 switch (coro_susp_point) {
41690 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
41693 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
41694 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
41695 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
41696 goto suspend;
41698 uint8_t t_0 = *iop_a_src++;
41699 v_flags = t_0;
41701 if (((uint8_t)(v_flags & 128u)) != 0u) {
41702 self->private_data.s_skip_frame.scratch = (((uint32_t)(3u)) << ((uint8_t)(1u + ((uint8_t)(v_flags & 7u)))));
41703 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
41704 if (self->private_data.s_skip_frame.scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
41705 self->private_data.s_skip_frame.scratch -= ((uint64_t)(io2_a_src - iop_a_src));
41706 iop_a_src = io2_a_src;
41707 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
41708 goto suspend;
41710 iop_a_src += self->private_data.s_skip_frame.scratch;
41713 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
41714 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
41715 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
41716 goto suspend;
41718 uint8_t t_1 = *iop_a_src++;
41719 v_lw = t_1;
41721 if (v_lw > 8u) {
41722 status = wuffs_base__make_status(wuffs_gif__error__bad_literal_width);
41723 goto exit;
41725 if (a_src) {
41726 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
41728 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
41729 status = wuffs_gif__decoder__skip_blocks(self, a_src);
41730 if (a_src) {
41731 iop_a_src = a_src->data.ptr + a_src->meta.ri;
41733 if (status.repr) {
41734 goto suspend;
41736 if (self->private_impl.f_quirks[0u]) {
41737 self->private_impl.f_delayed_num_decoded_frames = true;
41738 } else {
41739 wuffs_private_impl__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1u);
41741 wuffs_gif__decoder__reset_gc(self);
41742 self->private_impl.f_call_sequence = 32u;
41744 goto ok;
41746 self->private_impl.p_skip_frame = 0;
41747 goto exit;
41750 goto suspend;
41751 suspend:
41752 self->private_impl.p_skip_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
41754 goto exit;
41755 exit:
41756 if (a_src && a_src->data.ptr) {
41757 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
41760 return status;
41763 // -------- func gif.decoder.decode_frame
41765 WUFFS_BASE__GENERATED_C_CODE
41766 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
41767 wuffs_gif__decoder__decode_frame(
41768 wuffs_gif__decoder* self,
41769 wuffs_base__pixel_buffer* a_dst,
41770 wuffs_base__io_buffer* a_src,
41771 wuffs_base__pixel_blend a_blend,
41772 wuffs_base__slice_u8 a_workbuf,
41773 wuffs_base__decode_frame_options* a_opts) {
41774 if (!self) {
41775 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
41777 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
41778 return wuffs_base__make_status(
41779 (self->private_impl.magic == WUFFS_BASE__DISABLED)
41780 ? wuffs_base__error__disabled_by_previous_error
41781 : wuffs_base__error__initialize_not_called);
41783 if (!a_dst || !a_src) {
41784 self->private_impl.magic = WUFFS_BASE__DISABLED;
41785 return wuffs_base__make_status(wuffs_base__error__bad_argument);
41787 if ((self->private_impl.active_coroutine != 0) &&
41788 (self->private_impl.active_coroutine != 4)) {
41789 self->private_impl.magic = WUFFS_BASE__DISABLED;
41790 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
41792 self->private_impl.active_coroutine = 0;
41793 wuffs_base__status status = wuffs_base__make_status(NULL);
41795 wuffs_base__status v_status = wuffs_base__make_status(NULL);
41797 uint32_t coro_susp_point = self->private_impl.p_decode_frame;
41798 switch (coro_susp_point) {
41799 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
41801 while (true) {
41803 wuffs_base__status t_0 = wuffs_gif__decoder__do_decode_frame(self,
41804 a_dst,
41805 a_src,
41806 a_blend,
41807 a_workbuf,
41808 a_opts);
41809 v_status = t_0;
41811 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
41812 status = wuffs_base__make_status(wuffs_gif__error__truncated_input);
41813 goto exit;
41815 status = v_status;
41816 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
41820 self->private_impl.p_decode_frame = 0;
41821 goto exit;
41824 goto suspend;
41825 suspend:
41826 self->private_impl.p_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
41827 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 4 : 0;
41829 goto exit;
41830 exit:
41831 if (wuffs_base__status__is_error(&status)) {
41832 self->private_impl.magic = WUFFS_BASE__DISABLED;
41834 return status;
41837 // -------- func gif.decoder.do_decode_frame
41839 WUFFS_BASE__GENERATED_C_CODE
41840 static wuffs_base__status
41841 wuffs_gif__decoder__do_decode_frame(
41842 wuffs_gif__decoder* self,
41843 wuffs_base__pixel_buffer* a_dst,
41844 wuffs_base__io_buffer* a_src,
41845 wuffs_base__pixel_blend a_blend,
41846 wuffs_base__slice_u8 a_workbuf,
41847 wuffs_base__decode_frame_options* a_opts) {
41848 wuffs_base__status status = wuffs_base__make_status(NULL);
41850 uint32_t coro_susp_point = self->private_impl.p_do_decode_frame;
41851 switch (coro_susp_point) {
41852 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
41854 if (self->private_impl.f_call_sequence == 64u) {
41855 } else if (self->private_impl.f_call_sequence < 64u) {
41856 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
41857 status = wuffs_gif__decoder__do_decode_frame_config(self, NULL, a_src);
41858 if (status.repr) {
41859 goto suspend;
41861 } else {
41862 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
41863 goto ok;
41865 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))) {
41866 status = wuffs_base__make_status(wuffs_gif__error__bad_frame_size);
41867 goto exit;
41869 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
41870 status = wuffs_gif__decoder__decode_id_part1(self, a_dst, a_src, a_blend);
41871 if (status.repr) {
41872 goto suspend;
41874 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
41875 status = wuffs_gif__decoder__decode_id_part2(self, a_dst, a_src, a_workbuf);
41876 if (status.repr) {
41877 goto suspend;
41879 wuffs_private_impl__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1u);
41880 wuffs_gif__decoder__reset_gc(self);
41881 self->private_impl.f_call_sequence = 32u;
41884 self->private_impl.p_do_decode_frame = 0;
41885 goto exit;
41888 goto suspend;
41889 suspend:
41890 self->private_impl.p_do_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
41892 goto exit;
41893 exit:
41894 return status;
41897 // -------- func gif.decoder.reset_gc
41899 WUFFS_BASE__GENERATED_C_CODE
41900 static wuffs_base__empty_struct
41901 wuffs_gif__decoder__reset_gc(
41902 wuffs_gif__decoder* self) {
41903 self->private_impl.f_gc_has_transparent_index = false;
41904 self->private_impl.f_gc_transparent_index = 0u;
41905 self->private_impl.f_gc_disposal = 0u;
41906 self->private_impl.f_gc_duration = 0u;
41907 return wuffs_base__make_empty_struct();
41910 // -------- func gif.decoder.decode_up_to_id_part1
41912 WUFFS_BASE__GENERATED_C_CODE
41913 static wuffs_base__status
41914 wuffs_gif__decoder__decode_up_to_id_part1(
41915 wuffs_gif__decoder* self,
41916 wuffs_base__io_buffer* a_src) {
41917 wuffs_base__status status = wuffs_base__make_status(NULL);
41919 uint8_t v_block_type = 0;
41921 const uint8_t* iop_a_src = NULL;
41922 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41923 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41924 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41925 if (a_src && a_src->data.ptr) {
41926 io0_a_src = a_src->data.ptr;
41927 io1_a_src = io0_a_src + a_src->meta.ri;
41928 iop_a_src = io1_a_src;
41929 io2_a_src = io0_a_src + a_src->meta.wi;
41932 uint32_t coro_susp_point = self->private_impl.p_decode_up_to_id_part1;
41933 switch (coro_susp_point) {
41934 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
41936 if ((self->private_impl.f_frame_config_io_position == 0u) || (self->private_impl.f_num_decoded_frame_configs_value > 0u)) {
41937 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)));
41939 while (true) {
41941 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
41942 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
41943 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
41944 goto suspend;
41946 uint8_t t_0 = *iop_a_src++;
41947 v_block_type = t_0;
41949 if (v_block_type == 33u) {
41950 if (a_src) {
41951 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
41953 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
41954 status = wuffs_gif__decoder__decode_extension(self, a_src);
41955 if (a_src) {
41956 iop_a_src = a_src->data.ptr + a_src->meta.ri;
41958 if (status.repr) {
41959 goto suspend;
41961 } else if (v_block_type == 44u) {
41962 if (self->private_impl.f_delayed_num_decoded_frames) {
41963 self->private_impl.f_delayed_num_decoded_frames = false;
41964 wuffs_private_impl__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1u);
41966 if (a_src) {
41967 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
41969 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
41970 status = wuffs_gif__decoder__decode_id_part0(self, a_src);
41971 if (a_src) {
41972 iop_a_src = a_src->data.ptr + a_src->meta.ri;
41974 if (status.repr) {
41975 goto suspend;
41977 break;
41978 } else {
41979 if (self->private_impl.f_delayed_num_decoded_frames) {
41980 self->private_impl.f_delayed_num_decoded_frames = false;
41981 wuffs_private_impl__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1u);
41983 self->private_impl.f_call_sequence = 96u;
41984 break;
41988 goto ok;
41990 self->private_impl.p_decode_up_to_id_part1 = 0;
41991 goto exit;
41994 goto suspend;
41995 suspend:
41996 self->private_impl.p_decode_up_to_id_part1 = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
41998 goto exit;
41999 exit:
42000 if (a_src && a_src->data.ptr) {
42001 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
42004 return status;
42007 // -------- func gif.decoder.decode_header
42009 WUFFS_BASE__GENERATED_C_CODE
42010 static wuffs_base__status
42011 wuffs_gif__decoder__decode_header(
42012 wuffs_gif__decoder* self,
42013 wuffs_base__io_buffer* a_src) {
42014 wuffs_base__status status = wuffs_base__make_status(NULL);
42016 uint64_t v_c48 = 0;
42018 const uint8_t* iop_a_src = NULL;
42019 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42020 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42021 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42022 if (a_src && a_src->data.ptr) {
42023 io0_a_src = a_src->data.ptr;
42024 io1_a_src = io0_a_src + a_src->meta.ri;
42025 iop_a_src = io1_a_src;
42026 io2_a_src = io0_a_src + a_src->meta.wi;
42029 uint32_t coro_susp_point = self->private_impl.p_decode_header;
42030 switch (coro_susp_point) {
42031 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
42034 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
42035 uint64_t t_0;
42036 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 6)) {
42037 t_0 = ((uint64_t)(wuffs_base__peek_u48le__no_bounds_check(iop_a_src)));
42038 iop_a_src += 6;
42039 } else {
42040 self->private_data.s_decode_header.scratch = 0;
42041 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
42042 while (true) {
42043 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42044 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42045 goto suspend;
42047 uint64_t* scratch = &self->private_data.s_decode_header.scratch;
42048 uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
42049 *scratch <<= 8;
42050 *scratch >>= 8;
42051 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
42052 if (num_bits_0 == 40) {
42053 t_0 = ((uint64_t)(*scratch));
42054 break;
42056 num_bits_0 += 8u;
42057 *scratch |= ((uint64_t)(num_bits_0)) << 56;
42060 v_c48 = t_0;
42062 if ((v_c48 != 106889795225927u) && (v_c48 != 106898385160519u)) {
42063 status = wuffs_base__make_status(wuffs_gif__error__bad_header);
42064 goto exit;
42067 goto ok;
42069 self->private_impl.p_decode_header = 0;
42070 goto exit;
42073 goto suspend;
42074 suspend:
42075 self->private_impl.p_decode_header = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
42077 goto exit;
42078 exit:
42079 if (a_src && a_src->data.ptr) {
42080 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
42083 return status;
42086 // -------- func gif.decoder.decode_lsd
42088 WUFFS_BASE__GENERATED_C_CODE
42089 static wuffs_base__status
42090 wuffs_gif__decoder__decode_lsd(
42091 wuffs_gif__decoder* self,
42092 wuffs_base__io_buffer* a_src) {
42093 wuffs_base__status status = wuffs_base__make_status(NULL);
42095 uint8_t v_flags = 0;
42096 uint8_t v_background_color_index = 0;
42097 uint32_t v_num_palette_entries = 0;
42098 uint32_t v_i = 0;
42099 uint32_t v_j = 0;
42100 uint32_t v_argb = 0;
42102 const uint8_t* iop_a_src = NULL;
42103 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42104 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42105 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42106 if (a_src && a_src->data.ptr) {
42107 io0_a_src = a_src->data.ptr;
42108 io1_a_src = io0_a_src + a_src->meta.ri;
42109 iop_a_src = io1_a_src;
42110 io2_a_src = io0_a_src + a_src->meta.wi;
42113 uint32_t coro_susp_point = self->private_impl.p_decode_lsd;
42114 if (coro_susp_point) {
42115 v_flags = self->private_data.s_decode_lsd.v_flags;
42116 v_background_color_index = self->private_data.s_decode_lsd.v_background_color_index;
42117 v_num_palette_entries = self->private_data.s_decode_lsd.v_num_palette_entries;
42118 v_i = self->private_data.s_decode_lsd.v_i;
42120 switch (coro_susp_point) {
42121 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
42124 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
42125 uint32_t t_0;
42126 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
42127 t_0 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
42128 iop_a_src += 2;
42129 } else {
42130 self->private_data.s_decode_lsd.scratch = 0;
42131 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
42132 while (true) {
42133 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42134 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42135 goto suspend;
42137 uint64_t* scratch = &self->private_data.s_decode_lsd.scratch;
42138 uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
42139 *scratch <<= 8;
42140 *scratch >>= 8;
42141 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
42142 if (num_bits_0 == 8) {
42143 t_0 = ((uint32_t)(*scratch));
42144 break;
42146 num_bits_0 += 8u;
42147 *scratch |= ((uint64_t)(num_bits_0)) << 56;
42150 self->private_impl.f_width = t_0;
42153 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
42154 uint32_t t_1;
42155 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
42156 t_1 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
42157 iop_a_src += 2;
42158 } else {
42159 self->private_data.s_decode_lsd.scratch = 0;
42160 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
42161 while (true) {
42162 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42163 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42164 goto suspend;
42166 uint64_t* scratch = &self->private_data.s_decode_lsd.scratch;
42167 uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
42168 *scratch <<= 8;
42169 *scratch >>= 8;
42170 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
42171 if (num_bits_1 == 8) {
42172 t_1 = ((uint32_t)(*scratch));
42173 break;
42175 num_bits_1 += 8u;
42176 *scratch |= ((uint64_t)(num_bits_1)) << 56;
42179 self->private_impl.f_height = t_1;
42182 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
42183 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42184 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42185 goto suspend;
42187 uint8_t t_2 = *iop_a_src++;
42188 v_flags = t_2;
42191 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
42192 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42193 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42194 goto suspend;
42196 uint8_t t_3 = *iop_a_src++;
42197 v_background_color_index = t_3;
42199 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
42200 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42201 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42202 goto suspend;
42204 iop_a_src++;
42205 v_i = 0u;
42206 self->private_impl.f_has_global_palette = (((uint8_t)(v_flags & 128u)) != 0u);
42207 if (self->private_impl.f_has_global_palette) {
42208 v_num_palette_entries = (((uint32_t)(1u)) << ((uint8_t)(1u + ((uint8_t)(v_flags & 7u)))));
42209 while (v_i < v_num_palette_entries) {
42211 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
42212 uint32_t t_4;
42213 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) {
42214 t_4 = ((uint32_t)(wuffs_base__peek_u24be__no_bounds_check(iop_a_src)));
42215 iop_a_src += 3;
42216 } else {
42217 self->private_data.s_decode_lsd.scratch = 0;
42218 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
42219 while (true) {
42220 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42221 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42222 goto suspend;
42224 uint64_t* scratch = &self->private_data.s_decode_lsd.scratch;
42225 uint32_t num_bits_4 = ((uint32_t)(*scratch & 0xFFu));
42226 *scratch >>= 8;
42227 *scratch <<= 8;
42228 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_4);
42229 if (num_bits_4 == 16) {
42230 t_4 = ((uint32_t)(*scratch >> 40));
42231 break;
42233 num_bits_4 += 8u;
42234 *scratch |= ((uint64_t)(num_bits_4));
42237 v_argb = t_4;
42239 v_argb |= 4278190080u;
42240 self->private_data.f_palettes[0u][((4u * v_i) + 0u)] = ((uint8_t)((v_argb >> 0u)));
42241 self->private_data.f_palettes[0u][((4u * v_i) + 1u)] = ((uint8_t)((v_argb >> 8u)));
42242 self->private_data.f_palettes[0u][((4u * v_i) + 2u)] = ((uint8_t)((v_argb >> 16u)));
42243 self->private_data.f_palettes[0u][((4u * v_i) + 3u)] = ((uint8_t)((v_argb >> 24u)));
42244 v_i += 1u;
42246 if (self->private_impl.f_quirks[2u]) {
42247 if ((v_background_color_index != 0u) && (((uint32_t)(v_background_color_index)) < v_num_palette_entries)) {
42248 v_j = (4u * ((uint32_t)(v_background_color_index)));
42249 self->private_impl.f_background_color_u32_argb_premul = ((((uint32_t)(self->private_data.f_palettes[0u][(v_j + 0u)])) << 0u) |
42250 (((uint32_t)(self->private_data.f_palettes[0u][(v_j + 1u)])) << 8u) |
42251 (((uint32_t)(self->private_data.f_palettes[0u][(v_j + 2u)])) << 16u) |
42252 (((uint32_t)(self->private_data.f_palettes[0u][(v_j + 3u)])) << 24u));
42253 } else {
42254 self->private_impl.f_background_color_u32_argb_premul = 77u;
42258 while (v_i < 256u) {
42259 self->private_data.f_palettes[0u][((4u * v_i) + 0u)] = 0u;
42260 self->private_data.f_palettes[0u][((4u * v_i) + 1u)] = 0u;
42261 self->private_data.f_palettes[0u][((4u * v_i) + 2u)] = 0u;
42262 self->private_data.f_palettes[0u][((4u * v_i) + 3u)] = 255u;
42263 v_i += 1u;
42266 goto ok;
42268 self->private_impl.p_decode_lsd = 0;
42269 goto exit;
42272 goto suspend;
42273 suspend:
42274 self->private_impl.p_decode_lsd = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
42275 self->private_data.s_decode_lsd.v_flags = v_flags;
42276 self->private_data.s_decode_lsd.v_background_color_index = v_background_color_index;
42277 self->private_data.s_decode_lsd.v_num_palette_entries = v_num_palette_entries;
42278 self->private_data.s_decode_lsd.v_i = v_i;
42280 goto exit;
42281 exit:
42282 if (a_src && a_src->data.ptr) {
42283 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
42286 return status;
42289 // -------- func gif.decoder.decode_extension
42291 WUFFS_BASE__GENERATED_C_CODE
42292 static wuffs_base__status
42293 wuffs_gif__decoder__decode_extension(
42294 wuffs_gif__decoder* self,
42295 wuffs_base__io_buffer* a_src) {
42296 wuffs_base__status status = wuffs_base__make_status(NULL);
42298 uint8_t v_label = 0;
42300 const uint8_t* iop_a_src = NULL;
42301 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42302 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42303 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42304 if (a_src && a_src->data.ptr) {
42305 io0_a_src = a_src->data.ptr;
42306 io1_a_src = io0_a_src + a_src->meta.ri;
42307 iop_a_src = io1_a_src;
42308 io2_a_src = io0_a_src + a_src->meta.wi;
42311 uint32_t coro_susp_point = self->private_impl.p_decode_extension;
42312 switch (coro_susp_point) {
42313 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
42316 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
42317 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42318 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42319 goto suspend;
42321 uint8_t t_0 = *iop_a_src++;
42322 v_label = t_0;
42324 if (v_label == 249u) {
42325 if (a_src) {
42326 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
42328 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
42329 status = wuffs_gif__decoder__decode_gc(self, a_src);
42330 if (a_src) {
42331 iop_a_src = a_src->data.ptr + a_src->meta.ri;
42333 if (status.repr) {
42334 goto suspend;
42336 status = wuffs_base__make_status(NULL);
42337 goto ok;
42338 } else if (v_label == 255u) {
42339 if (a_src) {
42340 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
42342 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
42343 status = wuffs_gif__decoder__decode_ae(self, a_src);
42344 if (a_src) {
42345 iop_a_src = a_src->data.ptr + a_src->meta.ri;
42347 if (status.repr) {
42348 goto suspend;
42350 status = wuffs_base__make_status(NULL);
42351 goto ok;
42353 if (a_src) {
42354 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
42356 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
42357 status = wuffs_gif__decoder__skip_blocks(self, a_src);
42358 if (a_src) {
42359 iop_a_src = a_src->data.ptr + a_src->meta.ri;
42361 if (status.repr) {
42362 goto suspend;
42366 self->private_impl.p_decode_extension = 0;
42367 goto exit;
42370 goto suspend;
42371 suspend:
42372 self->private_impl.p_decode_extension = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
42374 goto exit;
42375 exit:
42376 if (a_src && a_src->data.ptr) {
42377 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
42380 return status;
42383 // -------- func gif.decoder.skip_blocks
42385 WUFFS_BASE__GENERATED_C_CODE
42386 static wuffs_base__status
42387 wuffs_gif__decoder__skip_blocks(
42388 wuffs_gif__decoder* self,
42389 wuffs_base__io_buffer* a_src) {
42390 wuffs_base__status status = wuffs_base__make_status(NULL);
42392 uint8_t v_block_size = 0;
42394 const uint8_t* iop_a_src = NULL;
42395 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42396 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42397 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42398 if (a_src && a_src->data.ptr) {
42399 io0_a_src = a_src->data.ptr;
42400 io1_a_src = io0_a_src + a_src->meta.ri;
42401 iop_a_src = io1_a_src;
42402 io2_a_src = io0_a_src + a_src->meta.wi;
42405 uint32_t coro_susp_point = self->private_impl.p_skip_blocks;
42406 switch (coro_susp_point) {
42407 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
42409 while (true) {
42411 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
42412 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42413 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42414 goto suspend;
42416 uint8_t t_0 = *iop_a_src++;
42417 v_block_size = t_0;
42419 if (v_block_size == 0u) {
42420 status = wuffs_base__make_status(NULL);
42421 goto ok;
42423 self->private_data.s_skip_blocks.scratch = ((uint32_t)(v_block_size));
42424 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
42425 if (self->private_data.s_skip_blocks.scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
42426 self->private_data.s_skip_blocks.scratch -= ((uint64_t)(io2_a_src - iop_a_src));
42427 iop_a_src = io2_a_src;
42428 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42429 goto suspend;
42431 iop_a_src += self->private_data.s_skip_blocks.scratch;
42435 self->private_impl.p_skip_blocks = 0;
42436 goto exit;
42439 goto suspend;
42440 suspend:
42441 self->private_impl.p_skip_blocks = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
42443 goto exit;
42444 exit:
42445 if (a_src && a_src->data.ptr) {
42446 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
42449 return status;
42452 // -------- func gif.decoder.decode_ae
42454 WUFFS_BASE__GENERATED_C_CODE
42455 static wuffs_base__status
42456 wuffs_gif__decoder__decode_ae(
42457 wuffs_gif__decoder* self,
42458 wuffs_base__io_buffer* a_src) {
42459 wuffs_base__status status = wuffs_base__make_status(NULL);
42461 uint8_t v_c8 = 0;
42462 uint8_t v_block_size = 0;
42463 bool v_is_animexts = false;
42464 bool v_is_netscape = false;
42465 bool v_is_iccp = false;
42466 bool v_is_xmp = false;
42468 const uint8_t* iop_a_src = NULL;
42469 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42470 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42471 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42472 if (a_src && a_src->data.ptr) {
42473 io0_a_src = a_src->data.ptr;
42474 io1_a_src = io0_a_src + a_src->meta.ri;
42475 iop_a_src = io1_a_src;
42476 io2_a_src = io0_a_src + a_src->meta.wi;
42479 uint32_t coro_susp_point = self->private_impl.p_decode_ae;
42480 if (coro_susp_point) {
42481 v_block_size = self->private_data.s_decode_ae.v_block_size;
42482 v_is_animexts = self->private_data.s_decode_ae.v_is_animexts;
42483 v_is_netscape = self->private_data.s_decode_ae.v_is_netscape;
42484 v_is_iccp = self->private_data.s_decode_ae.v_is_iccp;
42485 v_is_xmp = self->private_data.s_decode_ae.v_is_xmp;
42487 switch (coro_susp_point) {
42488 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
42490 do {
42491 if (self->private_impl.f_metadata_fourcc != 0u) {
42492 status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
42493 goto ok;
42496 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
42497 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42498 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42499 goto suspend;
42501 uint8_t t_0 = *iop_a_src++;
42502 v_block_size = t_0;
42504 if (v_block_size == 0u) {
42505 status = wuffs_base__make_status(NULL);
42506 goto ok;
42508 if (v_block_size != 11u) {
42509 self->private_data.s_decode_ae.scratch = ((uint32_t)(v_block_size));
42510 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
42511 if (self->private_data.s_decode_ae.scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
42512 self->private_data.s_decode_ae.scratch -= ((uint64_t)(io2_a_src - iop_a_src));
42513 iop_a_src = io2_a_src;
42514 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42515 goto suspend;
42517 iop_a_src += self->private_data.s_decode_ae.scratch;
42518 break;
42520 v_is_animexts = true;
42521 v_is_netscape = true;
42522 v_is_iccp = true;
42523 v_is_xmp = true;
42524 v_block_size = 0u;
42525 while (v_block_size < 11u) {
42527 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
42528 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42529 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42530 goto suspend;
42532 uint8_t t_1 = *iop_a_src++;
42533 v_c8 = t_1;
42535 v_is_animexts = (v_is_animexts && (v_c8 == WUFFS_GIF__ANIMEXTS1DOT0[v_block_size]));
42536 v_is_netscape = (v_is_netscape && (v_c8 == WUFFS_GIF__NETSCAPE2DOT0[v_block_size]));
42537 v_is_iccp = (v_is_iccp && (v_c8 == WUFFS_GIF__ICCRGBG1012[v_block_size]));
42538 v_is_xmp = (v_is_xmp && (v_c8 == WUFFS_GIF__XMPDATAXMP[v_block_size]));
42539 #if defined(__GNUC__)
42540 #pragma GCC diagnostic push
42541 #pragma GCC diagnostic ignored "-Wconversion"
42542 #endif
42543 v_block_size += 1u;
42544 #if defined(__GNUC__)
42545 #pragma GCC diagnostic pop
42546 #endif
42548 if (v_is_animexts || v_is_netscape) {
42550 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
42551 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42552 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42553 goto suspend;
42555 uint8_t t_2 = *iop_a_src++;
42556 v_block_size = t_2;
42558 if (v_block_size != 3u) {
42559 self->private_data.s_decode_ae.scratch = ((uint32_t)(v_block_size));
42560 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
42561 if (self->private_data.s_decode_ae.scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
42562 self->private_data.s_decode_ae.scratch -= ((uint64_t)(io2_a_src - iop_a_src));
42563 iop_a_src = io2_a_src;
42564 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42565 goto suspend;
42567 iop_a_src += self->private_data.s_decode_ae.scratch;
42568 break;
42571 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
42572 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42573 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42574 goto suspend;
42576 uint8_t t_3 = *iop_a_src++;
42577 v_c8 = t_3;
42579 if (v_c8 != 1u) {
42580 self->private_data.s_decode_ae.scratch = 2u;
42581 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
42582 if (self->private_data.s_decode_ae.scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
42583 self->private_data.s_decode_ae.scratch -= ((uint64_t)(io2_a_src - iop_a_src));
42584 iop_a_src = io2_a_src;
42585 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42586 goto suspend;
42588 iop_a_src += self->private_data.s_decode_ae.scratch;
42589 break;
42592 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
42593 uint32_t t_4;
42594 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
42595 t_4 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
42596 iop_a_src += 2;
42597 } else {
42598 self->private_data.s_decode_ae.scratch = 0;
42599 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
42600 while (true) {
42601 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42602 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42603 goto suspend;
42605 uint64_t* scratch = &self->private_data.s_decode_ae.scratch;
42606 uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
42607 *scratch <<= 8;
42608 *scratch >>= 8;
42609 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
42610 if (num_bits_4 == 8) {
42611 t_4 = ((uint32_t)(*scratch));
42612 break;
42614 num_bits_4 += 8u;
42615 *scratch |= ((uint64_t)(num_bits_4)) << 56;
42618 self->private_impl.f_num_animation_loops_value = t_4;
42620 self->private_impl.f_seen_num_animation_loops_value = true;
42621 if ((0u < self->private_impl.f_num_animation_loops_value) && (self->private_impl.f_num_animation_loops_value <= 65535u)) {
42622 self->private_impl.f_num_animation_loops_value += 1u;
42624 } else if (self->private_impl.f_call_sequence >= 32u) {
42625 } else if (v_is_iccp && self->private_impl.f_report_metadata_iccp) {
42626 self->private_impl.f_metadata_fourcc = 1229144912u;
42627 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)));
42628 self->private_impl.f_call_sequence = 16u;
42629 status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
42630 goto ok;
42631 } else if (v_is_xmp && self->private_impl.f_report_metadata_xmp) {
42632 self->private_impl.f_metadata_fourcc = 1481461792u;
42633 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)));
42634 self->private_impl.f_call_sequence = 16u;
42635 status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
42636 goto ok;
42638 } while (0);
42639 if (a_src) {
42640 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
42642 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
42643 status = wuffs_gif__decoder__skip_blocks(self, a_src);
42644 if (a_src) {
42645 iop_a_src = a_src->data.ptr + a_src->meta.ri;
42647 if (status.repr) {
42648 goto suspend;
42652 self->private_impl.p_decode_ae = 0;
42653 goto exit;
42656 goto suspend;
42657 suspend:
42658 self->private_impl.p_decode_ae = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
42659 self->private_data.s_decode_ae.v_block_size = v_block_size;
42660 self->private_data.s_decode_ae.v_is_animexts = v_is_animexts;
42661 self->private_data.s_decode_ae.v_is_netscape = v_is_netscape;
42662 self->private_data.s_decode_ae.v_is_iccp = v_is_iccp;
42663 self->private_data.s_decode_ae.v_is_xmp = v_is_xmp;
42665 goto exit;
42666 exit:
42667 if (a_src && a_src->data.ptr) {
42668 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
42671 return status;
42674 // -------- func gif.decoder.decode_gc
42676 WUFFS_BASE__GENERATED_C_CODE
42677 static wuffs_base__status
42678 wuffs_gif__decoder__decode_gc(
42679 wuffs_gif__decoder* self,
42680 wuffs_base__io_buffer* a_src) {
42681 wuffs_base__status status = wuffs_base__make_status(NULL);
42683 uint8_t v_c8 = 0;
42684 uint8_t v_flags = 0;
42685 uint16_t v_gc_duration_centiseconds = 0;
42687 const uint8_t* iop_a_src = NULL;
42688 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42689 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42690 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42691 if (a_src && a_src->data.ptr) {
42692 io0_a_src = a_src->data.ptr;
42693 io1_a_src = io0_a_src + a_src->meta.ri;
42694 iop_a_src = io1_a_src;
42695 io2_a_src = io0_a_src + a_src->meta.wi;
42698 uint32_t coro_susp_point = self->private_impl.p_decode_gc;
42699 switch (coro_susp_point) {
42700 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
42703 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
42704 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42705 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42706 goto suspend;
42708 uint8_t t_0 = *iop_a_src++;
42709 v_c8 = t_0;
42711 if (v_c8 != 4u) {
42712 status = wuffs_base__make_status(wuffs_gif__error__bad_graphic_control);
42713 goto exit;
42716 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
42717 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42718 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42719 goto suspend;
42721 uint8_t t_1 = *iop_a_src++;
42722 v_flags = t_1;
42724 self->private_impl.f_gc_has_transparent_index = (((uint8_t)(v_flags & 1u)) != 0u);
42725 v_flags = ((uint8_t)(((uint8_t)(v_flags >> 2u)) & 7u));
42726 if (v_flags == 2u) {
42727 self->private_impl.f_gc_disposal = 1u;
42728 } else if ((v_flags == 3u) || (v_flags == 4u)) {
42729 self->private_impl.f_gc_disposal = 2u;
42730 } else {
42731 self->private_impl.f_gc_disposal = 0u;
42734 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
42735 uint16_t t_2;
42736 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
42737 t_2 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src);
42738 iop_a_src += 2;
42739 } else {
42740 self->private_data.s_decode_gc.scratch = 0;
42741 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
42742 while (true) {
42743 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42744 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42745 goto suspend;
42747 uint64_t* scratch = &self->private_data.s_decode_gc.scratch;
42748 uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
42749 *scratch <<= 8;
42750 *scratch >>= 8;
42751 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
42752 if (num_bits_2 == 8) {
42753 t_2 = ((uint16_t)(*scratch));
42754 break;
42756 num_bits_2 += 8u;
42757 *scratch |= ((uint64_t)(num_bits_2)) << 56;
42760 v_gc_duration_centiseconds = t_2;
42762 self->private_impl.f_gc_duration = (((uint64_t)(v_gc_duration_centiseconds)) * 7056000u);
42764 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
42765 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42766 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42767 goto suspend;
42769 uint8_t t_3 = *iop_a_src++;
42770 self->private_impl.f_gc_transparent_index = t_3;
42773 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
42774 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42775 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42776 goto suspend;
42778 uint8_t t_4 = *iop_a_src++;
42779 v_c8 = t_4;
42781 if (v_c8 != 0u) {
42782 status = wuffs_base__make_status(wuffs_gif__error__bad_graphic_control);
42783 goto exit;
42786 goto ok;
42788 self->private_impl.p_decode_gc = 0;
42789 goto exit;
42792 goto suspend;
42793 suspend:
42794 self->private_impl.p_decode_gc = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
42796 goto exit;
42797 exit:
42798 if (a_src && a_src->data.ptr) {
42799 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
42802 return status;
42805 // -------- func gif.decoder.decode_id_part0
42807 WUFFS_BASE__GENERATED_C_CODE
42808 static wuffs_base__status
42809 wuffs_gif__decoder__decode_id_part0(
42810 wuffs_gif__decoder* self,
42811 wuffs_base__io_buffer* a_src) {
42812 wuffs_base__status status = wuffs_base__make_status(NULL);
42814 const uint8_t* iop_a_src = NULL;
42815 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42816 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42817 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42818 if (a_src && a_src->data.ptr) {
42819 io0_a_src = a_src->data.ptr;
42820 io1_a_src = io0_a_src + a_src->meta.ri;
42821 iop_a_src = io1_a_src;
42822 io2_a_src = io0_a_src + a_src->meta.wi;
42825 uint32_t coro_susp_point = self->private_impl.p_decode_id_part0;
42826 switch (coro_susp_point) {
42827 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
42830 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
42831 uint32_t t_0;
42832 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
42833 t_0 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
42834 iop_a_src += 2;
42835 } else {
42836 self->private_data.s_decode_id_part0.scratch = 0;
42837 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
42838 while (true) {
42839 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42840 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42841 goto suspend;
42843 uint64_t* scratch = &self->private_data.s_decode_id_part0.scratch;
42844 uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
42845 *scratch <<= 8;
42846 *scratch >>= 8;
42847 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
42848 if (num_bits_0 == 8) {
42849 t_0 = ((uint32_t)(*scratch));
42850 break;
42852 num_bits_0 += 8u;
42853 *scratch |= ((uint64_t)(num_bits_0)) << 56;
42856 self->private_impl.f_frame_rect_x0 = t_0;
42859 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
42860 uint32_t t_1;
42861 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
42862 t_1 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
42863 iop_a_src += 2;
42864 } else {
42865 self->private_data.s_decode_id_part0.scratch = 0;
42866 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
42867 while (true) {
42868 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42869 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42870 goto suspend;
42872 uint64_t* scratch = &self->private_data.s_decode_id_part0.scratch;
42873 uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
42874 *scratch <<= 8;
42875 *scratch >>= 8;
42876 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
42877 if (num_bits_1 == 8) {
42878 t_1 = ((uint32_t)(*scratch));
42879 break;
42881 num_bits_1 += 8u;
42882 *scratch |= ((uint64_t)(num_bits_1)) << 56;
42885 self->private_impl.f_frame_rect_y0 = t_1;
42888 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
42889 uint32_t t_2;
42890 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
42891 t_2 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
42892 iop_a_src += 2;
42893 } else {
42894 self->private_data.s_decode_id_part0.scratch = 0;
42895 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
42896 while (true) {
42897 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42898 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42899 goto suspend;
42901 uint64_t* scratch = &self->private_data.s_decode_id_part0.scratch;
42902 uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
42903 *scratch <<= 8;
42904 *scratch >>= 8;
42905 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
42906 if (num_bits_2 == 8) {
42907 t_2 = ((uint32_t)(*scratch));
42908 break;
42910 num_bits_2 += 8u;
42911 *scratch |= ((uint64_t)(num_bits_2)) << 56;
42914 self->private_impl.f_frame_rect_x1 = t_2;
42916 self->private_impl.f_frame_rect_x1 += self->private_impl.f_frame_rect_x0;
42918 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
42919 uint32_t t_3;
42920 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
42921 t_3 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
42922 iop_a_src += 2;
42923 } else {
42924 self->private_data.s_decode_id_part0.scratch = 0;
42925 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
42926 while (true) {
42927 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42928 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42929 goto suspend;
42931 uint64_t* scratch = &self->private_data.s_decode_id_part0.scratch;
42932 uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56));
42933 *scratch <<= 8;
42934 *scratch >>= 8;
42935 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3;
42936 if (num_bits_3 == 8) {
42937 t_3 = ((uint32_t)(*scratch));
42938 break;
42940 num_bits_3 += 8u;
42941 *scratch |= ((uint64_t)(num_bits_3)) << 56;
42944 self->private_impl.f_frame_rect_y1 = t_3;
42946 self->private_impl.f_frame_rect_y1 += self->private_impl.f_frame_rect_y0;
42947 self->private_impl.f_dst_x = self->private_impl.f_frame_rect_x0;
42948 self->private_impl.f_dst_y = self->private_impl.f_frame_rect_y0;
42949 if ((self->private_impl.f_num_decoded_frame_configs_value == 0u) && ! self->private_impl.f_quirks[4u]) {
42950 self->private_impl.f_width = wuffs_base__u32__max(self->private_impl.f_width, self->private_impl.f_frame_rect_x1);
42951 self->private_impl.f_height = wuffs_base__u32__max(self->private_impl.f_height, self->private_impl.f_frame_rect_y1);
42954 goto ok;
42956 self->private_impl.p_decode_id_part0 = 0;
42957 goto exit;
42960 goto suspend;
42961 suspend:
42962 self->private_impl.p_decode_id_part0 = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
42964 goto exit;
42965 exit:
42966 if (a_src && a_src->data.ptr) {
42967 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
42970 return status;
42973 // -------- func gif.decoder.decode_id_part1
42975 WUFFS_BASE__GENERATED_C_CODE
42976 static wuffs_base__status
42977 wuffs_gif__decoder__decode_id_part1(
42978 wuffs_gif__decoder* self,
42979 wuffs_base__pixel_buffer* a_dst,
42980 wuffs_base__io_buffer* a_src,
42981 wuffs_base__pixel_blend a_blend) {
42982 wuffs_base__status status = wuffs_base__make_status(NULL);
42984 uint8_t v_flags = 0;
42985 uint8_t v_which_palette = 0;
42986 uint32_t v_num_palette_entries = 0;
42987 uint32_t v_i = 0;
42988 uint32_t v_argb = 0;
42989 wuffs_base__status v_status = wuffs_base__make_status(NULL);
42990 uint8_t v_lw = 0;
42992 const uint8_t* iop_a_src = NULL;
42993 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42994 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42995 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42996 if (a_src && a_src->data.ptr) {
42997 io0_a_src = a_src->data.ptr;
42998 io1_a_src = io0_a_src + a_src->meta.ri;
42999 iop_a_src = io1_a_src;
43000 io2_a_src = io0_a_src + a_src->meta.wi;
43003 uint32_t coro_susp_point = self->private_impl.p_decode_id_part1;
43004 if (coro_susp_point) {
43005 v_which_palette = self->private_data.s_decode_id_part1.v_which_palette;
43006 v_num_palette_entries = self->private_data.s_decode_id_part1.v_num_palette_entries;
43007 v_i = self->private_data.s_decode_id_part1.v_i;
43009 switch (coro_susp_point) {
43010 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
43013 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
43014 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
43015 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
43016 goto suspend;
43018 uint8_t t_0 = *iop_a_src++;
43019 v_flags = t_0;
43021 if (((uint8_t)(v_flags & 64u)) != 0u) {
43022 self->private_impl.f_interlace = 4u;
43023 } else {
43024 self->private_impl.f_interlace = 0u;
43026 v_which_palette = 1u;
43027 if (((uint8_t)(v_flags & 128u)) != 0u) {
43028 v_num_palette_entries = (((uint32_t)(1u)) << ((uint8_t)(1u + ((uint8_t)(v_flags & 7u)))));
43029 v_i = 0u;
43030 while (v_i < v_num_palette_entries) {
43032 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
43033 uint32_t t_1;
43034 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) {
43035 t_1 = ((uint32_t)(wuffs_base__peek_u24be__no_bounds_check(iop_a_src)));
43036 iop_a_src += 3;
43037 } else {
43038 self->private_data.s_decode_id_part1.scratch = 0;
43039 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
43040 while (true) {
43041 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
43042 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
43043 goto suspend;
43045 uint64_t* scratch = &self->private_data.s_decode_id_part1.scratch;
43046 uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu));
43047 *scratch >>= 8;
43048 *scratch <<= 8;
43049 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
43050 if (num_bits_1 == 16) {
43051 t_1 = ((uint32_t)(*scratch >> 40));
43052 break;
43054 num_bits_1 += 8u;
43055 *scratch |= ((uint64_t)(num_bits_1));
43058 v_argb = t_1;
43060 v_argb |= 4278190080u;
43061 self->private_data.f_palettes[1u][((4u * v_i) + 0u)] = ((uint8_t)((v_argb >> 0u)));
43062 self->private_data.f_palettes[1u][((4u * v_i) + 1u)] = ((uint8_t)((v_argb >> 8u)));
43063 self->private_data.f_palettes[1u][((4u * v_i) + 2u)] = ((uint8_t)((v_argb >> 16u)));
43064 self->private_data.f_palettes[1u][((4u * v_i) + 3u)] = ((uint8_t)((v_argb >> 24u)));
43065 v_i += 1u;
43067 while (v_i < 256u) {
43068 self->private_data.f_palettes[1u][((4u * v_i) + 0u)] = 0u;
43069 self->private_data.f_palettes[1u][((4u * v_i) + 1u)] = 0u;
43070 self->private_data.f_palettes[1u][((4u * v_i) + 2u)] = 0u;
43071 self->private_data.f_palettes[1u][((4u * v_i) + 3u)] = 255u;
43072 v_i += 1u;
43074 } else if (self->private_impl.f_quirks[6u] && ! self->private_impl.f_has_global_palette) {
43075 status = wuffs_base__make_status(wuffs_gif__error__bad_palette);
43076 goto exit;
43077 } else if (self->private_impl.f_gc_has_transparent_index) {
43078 wuffs_private_impl__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));
43079 } else {
43080 v_which_palette = 0u;
43082 if (self->private_impl.f_gc_has_transparent_index) {
43083 self->private_data.f_palettes[1u][((4u * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 0u)] = 0u;
43084 self->private_data.f_palettes[1u][((4u * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 1u)] = 0u;
43085 self->private_data.f_palettes[1u][((4u * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 2u)] = 0u;
43086 self->private_data.f_palettes[1u][((4u * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 3u)] = 0u;
43088 v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
43089 wuffs_base__pixel_buffer__pixel_format(a_dst),
43090 wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)),
43091 wuffs_base__utility__make_pixel_format(2198077448u),
43092 wuffs_base__make_slice_u8(self->private_data.f_palettes[v_which_palette], 1024),
43093 a_blend);
43094 if ( ! wuffs_base__status__is_ok(&v_status)) {
43095 status = v_status;
43096 if (wuffs_base__status__is_error(&status)) {
43097 goto exit;
43098 } else if (wuffs_base__status__is_suspension(&status)) {
43099 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
43100 goto exit;
43102 goto ok;
43104 if (self->private_impl.f_ignored_but_affects_benchmarks) {
43107 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
43108 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
43109 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
43110 goto suspend;
43112 uint8_t t_2 = *iop_a_src++;
43113 v_lw = t_2;
43115 if (v_lw > 8u) {
43116 status = wuffs_base__make_status(wuffs_gif__error__bad_literal_width);
43117 goto exit;
43119 self->private_impl.f_lzw_pending_literal_width_plus_one = ((uint32_t)(((uint8_t)(1u + v_lw))));
43120 self->private_impl.f_ignored_but_affects_benchmarks = true;
43123 self->private_impl.p_decode_id_part1 = 0;
43124 goto exit;
43127 goto suspend;
43128 suspend:
43129 self->private_impl.p_decode_id_part1 = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
43130 self->private_data.s_decode_id_part1.v_which_palette = v_which_palette;
43131 self->private_data.s_decode_id_part1.v_num_palette_entries = v_num_palette_entries;
43132 self->private_data.s_decode_id_part1.v_i = v_i;
43134 goto exit;
43135 exit:
43136 if (a_src && a_src->data.ptr) {
43137 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
43140 return status;
43143 // -------- func gif.decoder.decode_id_part2
43145 WUFFS_BASE__GENERATED_C_CODE
43146 static wuffs_base__status
43147 wuffs_gif__decoder__decode_id_part2(
43148 wuffs_gif__decoder* self,
43149 wuffs_base__pixel_buffer* a_dst,
43150 wuffs_base__io_buffer* a_src,
43151 wuffs_base__slice_u8 a_workbuf) {
43152 wuffs_base__status status = wuffs_base__make_status(NULL);
43154 uint64_t v_block_size = 0;
43155 bool v_need_block_size = false;
43156 uint32_t v_n_copied = 0;
43157 uint64_t v_n_compressed = 0;
43158 wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer();
43159 wuffs_base__io_buffer* v_r = &u_r;
43160 const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43161 const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43162 const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43163 const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43164 uint64_t v_mark = 0;
43165 wuffs_base__status v_copy_status = wuffs_base__make_status(NULL);
43167 const uint8_t* iop_a_src = NULL;
43168 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43169 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43170 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43171 if (a_src && a_src->data.ptr) {
43172 io0_a_src = a_src->data.ptr;
43173 io1_a_src = io0_a_src + a_src->meta.ri;
43174 iop_a_src = io1_a_src;
43175 io2_a_src = io0_a_src + a_src->meta.wi;
43178 uint32_t coro_susp_point = self->private_impl.p_decode_id_part2;
43179 if (coro_susp_point) {
43180 v_block_size = self->private_data.s_decode_id_part2.v_block_size;
43181 v_need_block_size = self->private_data.s_decode_id_part2.v_need_block_size;
43183 switch (coro_susp_point) {
43184 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
43186 wuffs_gif__decoder__lzw_init(self);
43187 v_need_block_size = true;
43188 label__outer__continue:;
43189 while (true) {
43190 if (v_need_block_size) {
43191 v_need_block_size = false;
43193 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
43194 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
43195 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
43196 goto suspend;
43198 uint64_t t_0 = *iop_a_src++;
43199 v_block_size = t_0;
43202 if (v_block_size == 0u) {
43203 break;
43205 while (((uint64_t)(io2_a_src - iop_a_src)) == 0u) {
43206 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
43207 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
43209 if (self->private_impl.f_compressed_ri == self->private_impl.f_compressed_wi) {
43210 self->private_impl.f_compressed_ri = 0u;
43211 self->private_impl.f_compressed_wi = 0u;
43213 while (self->private_impl.f_compressed_wi <= 3841u) {
43214 v_n_compressed = wuffs_base__u64__min(v_block_size, ((uint64_t)(io2_a_src - iop_a_src)));
43215 if (v_n_compressed <= 0u) {
43216 break;
43218 v_n_copied = wuffs_private_impl__io_reader__limited_copy_u32_to_slice(
43219 &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));
43220 wuffs_private_impl__u64__sat_add_indirect(&self->private_impl.f_compressed_wi, ((uint64_t)(v_n_copied)));
43221 wuffs_private_impl__u64__sat_sub_indirect(&v_block_size, ((uint64_t)(v_n_copied)));
43222 if (v_block_size > 0u) {
43223 break;
43225 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
43226 v_need_block_size = true;
43227 break;
43229 v_block_size = ((uint64_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src)));
43230 iop_a_src += 1u;
43232 while (true) {
43233 if ((self->private_impl.f_compressed_ri > self->private_impl.f_compressed_wi) || (self->private_impl.f_compressed_wi > 4096u)) {
43234 status = wuffs_base__make_status(wuffs_gif__error__internal_error_inconsistent_i_o);
43235 goto exit;
43238 wuffs_base__io_buffer* o_0_v_r = v_r;
43239 const uint8_t* o_0_iop_v_r = iop_v_r;
43240 const uint8_t* o_0_io0_v_r = io0_v_r;
43241 const uint8_t* o_0_io1_v_r = io1_v_r;
43242 const uint8_t* o_0_io2_v_r = io2_v_r;
43243 v_r = wuffs_private_impl__io_reader__set(
43244 &u_r,
43245 &iop_v_r,
43246 &io0_v_r,
43247 &io1_v_r,
43248 &io2_v_r,
43249 wuffs_base__make_slice_u8_ij(self->private_data.f_compressed,
43250 self->private_impl.f_compressed_ri,
43251 self->private_impl.f_compressed_wi),
43252 0u);
43253 v_mark = ((uint64_t)(iop_v_r - io0_v_r));
43254 u_r.meta.ri = ((size_t)(iop_v_r - u_r.data.ptr));
43255 wuffs_gif__decoder__lzw_read_from(self, v_r);
43256 iop_v_r = u_r.data.ptr + u_r.meta.ri;
43257 wuffs_private_impl__u64__sat_add_indirect(&self->private_impl.f_compressed_ri, wuffs_private_impl__io__count_since(v_mark, ((uint64_t)(iop_v_r - io0_v_r))));
43258 v_r = o_0_v_r;
43259 iop_v_r = o_0_iop_v_r;
43260 io0_v_r = o_0_io0_v_r;
43261 io1_v_r = o_0_io1_v_r;
43262 io2_v_r = o_0_io2_v_r;
43264 if (self->private_impl.f_lzw_output_ri < self->private_impl.f_lzw_output_wi) {
43265 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,
43266 self->private_impl.f_lzw_output_ri,
43267 self->private_impl.f_lzw_output_wi));
43268 if (wuffs_base__status__is_error(&v_copy_status)) {
43269 status = v_copy_status;
43270 goto exit;
43272 self->private_impl.f_lzw_output_ri = 0u;
43273 self->private_impl.f_lzw_output_wi = 0u;
43275 if (self->private_impl.f_lzw_read_from_return_value == 0u) {
43276 self->private_impl.f_ignored_but_affects_benchmarks = false;
43277 if (v_need_block_size || (v_block_size > 0u)) {
43278 self->private_data.s_decode_id_part2.scratch = ((uint32_t)(v_block_size));
43279 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
43280 if (self->private_data.s_decode_id_part2.scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
43281 self->private_data.s_decode_id_part2.scratch -= ((uint64_t)(io2_a_src - iop_a_src));
43282 iop_a_src = io2_a_src;
43283 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
43284 goto suspend;
43286 iop_a_src += self->private_data.s_decode_id_part2.scratch;
43287 if (a_src) {
43288 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
43290 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
43291 status = wuffs_gif__decoder__skip_blocks(self, a_src);
43292 if (a_src) {
43293 iop_a_src = a_src->data.ptr + a_src->meta.ri;
43295 if (status.repr) {
43296 goto suspend;
43299 goto label__outer__break;
43300 } else if (self->private_impl.f_lzw_read_from_return_value == 1u) {
43301 continue;
43302 } else if (self->private_impl.f_lzw_read_from_return_value == 2u) {
43303 goto label__outer__continue;
43304 } 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)) {
43305 if (v_need_block_size || (v_block_size > 0u)) {
43306 self->private_data.s_decode_id_part2.scratch = ((uint32_t)(v_block_size));
43307 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
43308 if (self->private_data.s_decode_id_part2.scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
43309 self->private_data.s_decode_id_part2.scratch -= ((uint64_t)(io2_a_src - iop_a_src));
43310 iop_a_src = io2_a_src;
43311 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
43312 goto suspend;
43314 iop_a_src += self->private_data.s_decode_id_part2.scratch;
43315 if (a_src) {
43316 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
43318 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
43319 status = wuffs_gif__decoder__skip_blocks(self, a_src);
43320 if (a_src) {
43321 iop_a_src = a_src->data.ptr + a_src->meta.ri;
43323 if (status.repr) {
43324 goto suspend;
43327 goto label__outer__break;
43328 } else if (self->private_impl.f_lzw_read_from_return_value == 3u) {
43329 status = wuffs_base__make_status(wuffs_gif__error__truncated_input);
43330 goto exit;
43331 } else if (self->private_impl.f_lzw_read_from_return_value == 4u) {
43332 status = wuffs_base__make_status(wuffs_gif__error__bad_lzw_code);
43333 goto exit;
43335 status = wuffs_base__make_status(wuffs_gif__error__internal_error_inconsistent_i_o);
43336 goto exit;
43339 label__outer__break:;
43340 self->private_impl.f_compressed_ri = 0u;
43341 self->private_impl.f_compressed_wi = 0u;
43342 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)) {
43343 status = wuffs_base__make_status(wuffs_base__error__not_enough_data);
43344 goto exit;
43348 self->private_impl.p_decode_id_part2 = 0;
43349 goto exit;
43352 goto suspend;
43353 suspend:
43354 self->private_impl.p_decode_id_part2 = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
43355 self->private_data.s_decode_id_part2.v_block_size = v_block_size;
43356 self->private_data.s_decode_id_part2.v_need_block_size = v_need_block_size;
43358 goto exit;
43359 exit:
43360 if (a_src && a_src->data.ptr) {
43361 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
43364 return status;
43367 // -------- func gif.decoder.copy_to_image_buffer
43369 WUFFS_BASE__GENERATED_C_CODE
43370 static wuffs_base__status
43371 wuffs_gif__decoder__copy_to_image_buffer(
43372 wuffs_gif__decoder* self,
43373 wuffs_base__pixel_buffer* a_pb,
43374 wuffs_base__slice_u8 a_src) {
43375 wuffs_base__slice_u8 v_dst = {0};
43376 wuffs_base__slice_u8 v_src = {0};
43377 uint64_t v_width_in_bytes = 0;
43378 uint64_t v_n = 0;
43379 uint64_t v_src_ri = 0;
43380 wuffs_base__pixel_format v_pixfmt = {0};
43381 uint32_t v_bytes_per_pixel = 0;
43382 uint32_t v_bits_per_pixel = 0;
43383 wuffs_base__table_u8 v_tab = {0};
43384 uint64_t v_i = 0;
43385 uint64_t v_j = 0;
43386 uint32_t v_replicate_y0 = 0;
43387 uint32_t v_replicate_y1 = 0;
43388 wuffs_base__slice_u8 v_replicate_dst = {0};
43389 wuffs_base__slice_u8 v_replicate_src = {0};
43391 v_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_pb);
43392 v_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_pixfmt);
43393 if ((v_bits_per_pixel & 7u) != 0u) {
43394 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
43396 v_bytes_per_pixel = (v_bits_per_pixel >> 3u);
43397 v_width_in_bytes = ((uint64_t)((self->private_impl.f_width * v_bytes_per_pixel)));
43398 v_tab = wuffs_base__pixel_buffer__plane(a_pb, 0u);
43399 while (v_src_ri < ((uint64_t)(a_src.len))) {
43400 v_src = wuffs_base__slice_u8__subslice_i(a_src, v_src_ri);
43401 if (self->private_impl.f_dst_y >= self->private_impl.f_frame_rect_y1) {
43402 if (self->private_impl.f_quirks[3u]) {
43403 return wuffs_base__make_status(NULL);
43405 return wuffs_base__make_status(wuffs_base__error__too_much_data);
43407 v_dst = wuffs_private_impl__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
43408 if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
43409 v_dst = wuffs_base__slice_u8__subslice_j(v_dst, 0u);
43410 } else if (v_width_in_bytes < ((uint64_t)(v_dst.len))) {
43411 v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_width_in_bytes);
43413 v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_bytes_per_pixel)));
43414 if (v_i < ((uint64_t)(v_dst.len))) {
43415 v_j = (((uint64_t)(self->private_impl.f_frame_rect_x1)) * ((uint64_t)(v_bytes_per_pixel)));
43416 if ((v_i <= v_j) && (v_j <= ((uint64_t)(v_dst.len)))) {
43417 v_dst = wuffs_base__slice_u8__subslice_ij(v_dst, v_i, v_j);
43418 } else {
43419 v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_i);
43421 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);
43422 wuffs_private_impl__u64__sat_add_indirect(&v_src_ri, v_n);
43423 wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n)));
43424 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));
43426 if (self->private_impl.f_frame_rect_x1 <= self->private_impl.f_dst_x) {
43427 self->private_impl.f_dst_x = self->private_impl.f_frame_rect_x0;
43428 if (self->private_impl.f_interlace == 0u) {
43429 wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_dst_y, 1u);
43430 continue;
43432 if ((self->private_impl.f_num_decoded_frames_value == 0u) && ! self->private_impl.f_gc_has_transparent_index && (self->private_impl.f_interlace > 1u)) {
43433 v_replicate_src = wuffs_private_impl__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
43434 v_replicate_y0 = wuffs_base__u32__sat_add(self->private_impl.f_dst_y, 1u);
43435 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])));
43436 v_replicate_y1 = wuffs_base__u32__min(v_replicate_y1, self->private_impl.f_frame_rect_y1);
43437 while (v_replicate_y0 < v_replicate_y1) {
43438 v_replicate_dst = wuffs_private_impl__table_u8__row_u32(v_tab, v_replicate_y0);
43439 wuffs_private_impl__slice_u8__copy_from_slice(v_replicate_dst, v_replicate_src);
43440 v_replicate_y0 += 1u;
43442 self->private_impl.f_dirty_max_excl_y = wuffs_base__u32__max(self->private_impl.f_dirty_max_excl_y, v_replicate_y1);
43444 wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_dst_y, ((uint32_t)(WUFFS_GIF__INTERLACE_DELTA[self->private_impl.f_interlace])));
43445 while ((self->private_impl.f_interlace > 0u) && (self->private_impl.f_dst_y >= self->private_impl.f_frame_rect_y1)) {
43446 #if defined(__GNUC__)
43447 #pragma GCC diagnostic push
43448 #pragma GCC diagnostic ignored "-Wconversion"
43449 #endif
43450 self->private_impl.f_interlace -= 1u;
43451 #if defined(__GNUC__)
43452 #pragma GCC diagnostic pop
43453 #endif
43454 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]);
43456 continue;
43458 if (((uint64_t)(a_src.len)) == v_src_ri) {
43459 break;
43460 } else if (((uint64_t)(a_src.len)) < v_src_ri) {
43461 return wuffs_base__make_status(wuffs_gif__error__internal_error_inconsistent_i_o);
43463 v_n = ((uint64_t)((self->private_impl.f_frame_rect_x1 - self->private_impl.f_dst_x)));
43464 v_n = wuffs_base__u64__min(v_n, (((uint64_t)(a_src.len)) - v_src_ri));
43465 wuffs_private_impl__u64__sat_add_indirect(&v_src_ri, v_n);
43466 wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n)));
43467 if (self->private_impl.f_frame_rect_x1 <= self->private_impl.f_dst_x) {
43468 self->private_impl.f_dst_x = self->private_impl.f_frame_rect_x0;
43469 wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_dst_y, ((uint32_t)(WUFFS_GIF__INTERLACE_DELTA[self->private_impl.f_interlace])));
43470 while ((self->private_impl.f_interlace > 0u) && (self->private_impl.f_dst_y >= self->private_impl.f_frame_rect_y1)) {
43471 #if defined(__GNUC__)
43472 #pragma GCC diagnostic push
43473 #pragma GCC diagnostic ignored "-Wconversion"
43474 #endif
43475 self->private_impl.f_interlace -= 1u;
43476 #if defined(__GNUC__)
43477 #pragma GCC diagnostic pop
43478 #endif
43479 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]);
43481 continue;
43483 if (v_src_ri != ((uint64_t)(a_src.len))) {
43484 return wuffs_base__make_status(wuffs_gif__error__internal_error_inconsistent_i_o);
43486 break;
43488 return wuffs_base__make_status(NULL);
43491 // -------- func gif.decoder.lzw_init
43493 WUFFS_BASE__GENERATED_C_CODE
43494 static wuffs_base__empty_struct
43495 wuffs_gif__decoder__lzw_init(
43496 wuffs_gif__decoder* self) {
43497 uint32_t v_i = 0;
43499 self->private_impl.f_lzw_literal_width = 8u;
43500 if (self->private_impl.f_lzw_pending_literal_width_plus_one > 0u) {
43501 self->private_impl.f_lzw_literal_width = (self->private_impl.f_lzw_pending_literal_width_plus_one - 1u);
43503 self->private_impl.f_lzw_clear_code = (((uint32_t)(1u)) << self->private_impl.f_lzw_literal_width);
43504 self->private_impl.f_lzw_end_code = (self->private_impl.f_lzw_clear_code + 1u);
43505 self->private_impl.f_lzw_save_code = self->private_impl.f_lzw_end_code;
43506 self->private_impl.f_lzw_prev_code = self->private_impl.f_lzw_end_code;
43507 self->private_impl.f_lzw_width = (self->private_impl.f_lzw_literal_width + 1u);
43508 self->private_impl.f_lzw_bits = 0u;
43509 self->private_impl.f_lzw_n_bits = 0u;
43510 self->private_impl.f_lzw_output_ri = 0u;
43511 self->private_impl.f_lzw_output_wi = 0u;
43512 v_i = 0u;
43513 while (v_i < self->private_impl.f_lzw_clear_code) {
43514 self->private_data.f_lzw_lm1s[v_i] = 0u;
43515 self->private_data.f_lzw_suffixes[v_i][0u] = ((uint8_t)(v_i));
43516 v_i += 1u;
43518 return wuffs_base__make_empty_struct();
43521 // -------- func gif.decoder.lzw_read_from
43523 WUFFS_BASE__GENERATED_C_CODE
43524 static wuffs_base__empty_struct
43525 wuffs_gif__decoder__lzw_read_from(
43526 wuffs_gif__decoder* self,
43527 wuffs_base__io_buffer* a_src) {
43528 uint32_t v_clear_code = 0;
43529 uint32_t v_end_code = 0;
43530 uint32_t v_save_code = 0;
43531 uint32_t v_prev_code = 0;
43532 uint32_t v_width = 0;
43533 uint32_t v_bits = 0;
43534 uint32_t v_n_bits = 0;
43535 uint32_t v_output_wi = 0;
43536 uint32_t v_code = 0;
43537 uint32_t v_c = 0;
43538 uint32_t v_o = 0;
43539 uint32_t v_steps = 0;
43540 uint8_t v_first_byte = 0;
43541 uint16_t v_lm1_b = 0;
43542 uint16_t v_lm1_a = 0;
43544 const uint8_t* iop_a_src = NULL;
43545 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43546 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43547 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43548 if (a_src && a_src->data.ptr) {
43549 io0_a_src = a_src->data.ptr;
43550 io1_a_src = io0_a_src + a_src->meta.ri;
43551 iop_a_src = io1_a_src;
43552 io2_a_src = io0_a_src + a_src->meta.wi;
43555 v_clear_code = self->private_impl.f_lzw_clear_code;
43556 v_end_code = self->private_impl.f_lzw_end_code;
43557 v_save_code = self->private_impl.f_lzw_save_code;
43558 v_prev_code = self->private_impl.f_lzw_prev_code;
43559 v_width = self->private_impl.f_lzw_width;
43560 v_bits = self->private_impl.f_lzw_bits;
43561 v_n_bits = self->private_impl.f_lzw_n_bits;
43562 v_output_wi = self->private_impl.f_lzw_output_wi;
43563 while (true) {
43564 if (v_n_bits < v_width) {
43565 if (((uint64_t)(io2_a_src - iop_a_src)) >= 4u) {
43566 v_bits |= ((uint32_t)(wuffs_base__peek_u32le__no_bounds_check(iop_a_src) << v_n_bits));
43567 iop_a_src += ((31u - v_n_bits) >> 3u);
43568 v_n_bits |= 24u;
43569 } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
43570 if (a_src && a_src->meta.closed) {
43571 self->private_impl.f_lzw_read_from_return_value = 3u;
43572 } else {
43573 self->private_impl.f_lzw_read_from_return_value = 2u;
43575 break;
43576 } else {
43577 v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
43578 iop_a_src += 1u;
43579 v_n_bits += 8u;
43580 if (v_n_bits >= v_width) {
43581 } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
43582 if (a_src && a_src->meta.closed) {
43583 self->private_impl.f_lzw_read_from_return_value = 3u;
43584 } else {
43585 self->private_impl.f_lzw_read_from_return_value = 2u;
43587 break;
43588 } else {
43589 v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
43590 iop_a_src += 1u;
43591 v_n_bits += 8u;
43592 if (v_n_bits < v_width) {
43593 self->private_impl.f_lzw_read_from_return_value = 5u;
43594 break;
43599 v_code = ((v_bits) & WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U32(v_width));
43600 v_bits >>= v_width;
43601 v_n_bits -= v_width;
43602 if (v_code < v_clear_code) {
43603 self->private_data.f_lzw_output[v_output_wi] = ((uint8_t)(v_code));
43604 v_output_wi = ((v_output_wi + 1u) & 8191u);
43605 if (v_save_code <= 4095u) {
43606 v_lm1_a = ((uint16_t)(((uint16_t)(self->private_data.f_lzw_lm1s[v_prev_code] + 1u)) & 4095u));
43607 self->private_data.f_lzw_lm1s[v_save_code] = v_lm1_a;
43608 if (((uint16_t)(v_lm1_a % 8u)) != 0u) {
43609 self->private_impl.f_lzw_prefixes[v_save_code] = self->private_impl.f_lzw_prefixes[v_prev_code];
43610 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]));
43611 self->private_data.f_lzw_suffixes[v_save_code][((uint16_t)(v_lm1_a % 8u))] = ((uint8_t)(v_code));
43612 } else {
43613 self->private_impl.f_lzw_prefixes[v_save_code] = ((uint16_t)(v_prev_code));
43614 self->private_data.f_lzw_suffixes[v_save_code][0u] = ((uint8_t)(v_code));
43616 v_save_code += 1u;
43617 if (v_width < 12u) {
43618 v_width += (1u & (v_save_code >> v_width));
43620 v_prev_code = v_code;
43622 } else if (v_code <= v_end_code) {
43623 if (v_code == v_end_code) {
43624 self->private_impl.f_lzw_read_from_return_value = 0u;
43625 break;
43627 v_save_code = v_end_code;
43628 v_prev_code = v_end_code;
43629 v_width = (self->private_impl.f_lzw_literal_width + 1u);
43630 } else if (v_code <= v_save_code) {
43631 v_c = v_code;
43632 if (v_code == v_save_code) {
43633 v_c = v_prev_code;
43635 v_o = ((v_output_wi + (((uint32_t)(self->private_data.f_lzw_lm1s[v_c])) & 4294967288u)) & 8191u);
43636 v_output_wi = ((v_output_wi + 1u + ((uint32_t)(self->private_data.f_lzw_lm1s[v_c]))) & 8191u);
43637 v_steps = (((uint32_t)(self->private_data.f_lzw_lm1s[v_c])) >> 3u);
43638 while (true) {
43639 memcpy((self->private_data.f_lzw_output)+(v_o), (self->private_data.f_lzw_suffixes[v_c]), 8u);
43640 if (v_steps <= 0u) {
43641 break;
43643 v_steps -= 1u;
43644 v_o = (((uint32_t)(v_o - 8u)) & 8191u);
43645 v_c = ((uint32_t)(self->private_impl.f_lzw_prefixes[v_c]));
43647 v_first_byte = self->private_data.f_lzw_suffixes[v_c][0u];
43648 if (v_code == v_save_code) {
43649 self->private_data.f_lzw_output[v_output_wi] = v_first_byte;
43650 v_output_wi = ((v_output_wi + 1u) & 8191u);
43652 if (v_save_code <= 4095u) {
43653 v_lm1_b = ((uint16_t)(((uint16_t)(self->private_data.f_lzw_lm1s[v_prev_code] + 1u)) & 4095u));
43654 self->private_data.f_lzw_lm1s[v_save_code] = v_lm1_b;
43655 if (((uint16_t)(v_lm1_b % 8u)) != 0u) {
43656 self->private_impl.f_lzw_prefixes[v_save_code] = self->private_impl.f_lzw_prefixes[v_prev_code];
43657 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]));
43658 self->private_data.f_lzw_suffixes[v_save_code][((uint16_t)(v_lm1_b % 8u))] = v_first_byte;
43659 } else {
43660 self->private_impl.f_lzw_prefixes[v_save_code] = ((uint16_t)(v_prev_code));
43661 self->private_data.f_lzw_suffixes[v_save_code][0u] = ((uint8_t)(v_first_byte));
43663 v_save_code += 1u;
43664 if (v_width < 12u) {
43665 v_width += (1u & (v_save_code >> v_width));
43667 v_prev_code = v_code;
43669 } else {
43670 self->private_impl.f_lzw_read_from_return_value = 4u;
43671 break;
43673 if (v_output_wi > 4095u) {
43674 self->private_impl.f_lzw_read_from_return_value = 1u;
43675 break;
43678 if (self->private_impl.f_lzw_read_from_return_value != 2u) {
43679 while (v_n_bits >= 8u) {
43680 v_n_bits -= 8u;
43681 if (iop_a_src > io1_a_src) {
43682 iop_a_src--;
43683 } else {
43684 self->private_impl.f_lzw_read_from_return_value = 5u;
43685 break;
43689 self->private_impl.f_lzw_save_code = v_save_code;
43690 self->private_impl.f_lzw_prev_code = v_prev_code;
43691 self->private_impl.f_lzw_width = v_width;
43692 self->private_impl.f_lzw_bits = v_bits;
43693 self->private_impl.f_lzw_n_bits = v_n_bits;
43694 self->private_impl.f_lzw_output_wi = v_output_wi;
43695 if (a_src && a_src->data.ptr) {
43696 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
43699 return wuffs_base__make_empty_struct();
43702 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GIF)
43704 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GZIP)
43706 // ---------------- Status Codes Implementations
43708 const char wuffs_gzip__error__bad_checksum[] = "#gzip: bad checksum";
43709 const char wuffs_gzip__error__bad_compression_method[] = "#gzip: bad compression method";
43710 const char wuffs_gzip__error__bad_encoding_flags[] = "#gzip: bad encoding flags";
43711 const char wuffs_gzip__error__bad_header[] = "#gzip: bad header";
43712 const char wuffs_gzip__error__truncated_input[] = "#gzip: truncated input";
43714 // ---------------- Private Consts
43716 // ---------------- Private Initializer Prototypes
43718 // ---------------- Private Function Prototypes
43720 WUFFS_BASE__GENERATED_C_CODE
43721 static wuffs_base__status
43722 wuffs_gzip__decoder__do_transform_io(
43723 wuffs_gzip__decoder* self,
43724 wuffs_base__io_buffer* a_dst,
43725 wuffs_base__io_buffer* a_src,
43726 wuffs_base__slice_u8 a_workbuf);
43728 // ---------------- VTables
43730 const wuffs_base__io_transformer__func_ptrs
43731 wuffs_gzip__decoder__func_ptrs_for__wuffs_base__io_transformer = {
43732 (wuffs_base__optional_u63(*)(const void*))(&wuffs_gzip__decoder__dst_history_retain_length),
43733 (uint64_t(*)(const void*,
43734 uint32_t))(&wuffs_gzip__decoder__get_quirk),
43735 (wuffs_base__status(*)(void*,
43736 uint32_t,
43737 uint64_t))(&wuffs_gzip__decoder__set_quirk),
43738 (wuffs_base__status(*)(void*,
43739 wuffs_base__io_buffer*,
43740 wuffs_base__io_buffer*,
43741 wuffs_base__slice_u8))(&wuffs_gzip__decoder__transform_io),
43742 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_gzip__decoder__workbuf_len),
43745 // ---------------- Initializer Implementations
43747 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
43748 wuffs_gzip__decoder__initialize(
43749 wuffs_gzip__decoder* self,
43750 size_t sizeof_star_self,
43751 uint64_t wuffs_version,
43752 uint32_t options){
43753 if (!self) {
43754 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
43756 if (sizeof(*self) != sizeof_star_self) {
43757 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
43759 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
43760 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
43761 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
43764 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
43765 // The whole point of this if-check is to detect an uninitialized *self.
43766 // We disable the warning on GCC. Clang-5.0 does not have this warning.
43767 #if !defined(__clang__) && defined(__GNUC__)
43768 #pragma GCC diagnostic push
43769 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
43770 #endif
43771 if (self->private_impl.magic != 0) {
43772 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
43774 #if !defined(__clang__) && defined(__GNUC__)
43775 #pragma GCC diagnostic pop
43776 #endif
43777 } else {
43778 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
43779 memset(self, 0, sizeof(*self));
43780 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
43781 } else {
43782 memset(&(self->private_impl), 0, sizeof(self->private_impl));
43787 wuffs_base__status z = wuffs_crc32__ieee_hasher__initialize(
43788 &self->private_data.f_checksum, sizeof(self->private_data.f_checksum), WUFFS_VERSION, options);
43789 if (z.repr) {
43790 return z;
43794 wuffs_base__status z = wuffs_deflate__decoder__initialize(
43795 &self->private_data.f_flate, sizeof(self->private_data.f_flate), WUFFS_VERSION, options);
43796 if (z.repr) {
43797 return z;
43800 self->private_impl.magic = WUFFS_BASE__MAGIC;
43801 self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name =
43802 wuffs_base__io_transformer__vtable_name;
43803 self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers =
43804 (const void*)(&wuffs_gzip__decoder__func_ptrs_for__wuffs_base__io_transformer);
43805 return wuffs_base__make_status(NULL);
43808 wuffs_gzip__decoder*
43809 wuffs_gzip__decoder__alloc(void) {
43810 wuffs_gzip__decoder* x =
43811 (wuffs_gzip__decoder*)(calloc(1, sizeof(wuffs_gzip__decoder)));
43812 if (!x) {
43813 return NULL;
43815 if (wuffs_gzip__decoder__initialize(
43816 x, sizeof(wuffs_gzip__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
43817 free(x);
43818 return NULL;
43820 return x;
43823 size_t
43824 sizeof__wuffs_gzip__decoder(void) {
43825 return sizeof(wuffs_gzip__decoder);
43828 // ---------------- Function Implementations
43830 // -------- func gzip.decoder.get_quirk
43832 WUFFS_BASE__GENERATED_C_CODE
43833 WUFFS_BASE__MAYBE_STATIC uint64_t
43834 wuffs_gzip__decoder__get_quirk(
43835 const wuffs_gzip__decoder* self,
43836 uint32_t a_key) {
43837 if (!self) {
43838 return 0;
43840 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
43841 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
43842 return 0;
43845 if ((a_key == 1u) && self->private_impl.f_ignore_checksum) {
43846 return 1u;
43848 return 0u;
43851 // -------- func gzip.decoder.set_quirk
43853 WUFFS_BASE__GENERATED_C_CODE
43854 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
43855 wuffs_gzip__decoder__set_quirk(
43856 wuffs_gzip__decoder* self,
43857 uint32_t a_key,
43858 uint64_t a_value) {
43859 if (!self) {
43860 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
43862 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
43863 return wuffs_base__make_status(
43864 (self->private_impl.magic == WUFFS_BASE__DISABLED)
43865 ? wuffs_base__error__disabled_by_previous_error
43866 : wuffs_base__error__initialize_not_called);
43869 if (a_key == 1u) {
43870 self->private_impl.f_ignore_checksum = (a_value > 0u);
43871 return wuffs_base__make_status(NULL);
43873 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
43876 // -------- func gzip.decoder.dst_history_retain_length
43878 WUFFS_BASE__GENERATED_C_CODE
43879 WUFFS_BASE__MAYBE_STATIC wuffs_base__optional_u63
43880 wuffs_gzip__decoder__dst_history_retain_length(
43881 const wuffs_gzip__decoder* self) {
43882 if (!self) {
43883 return wuffs_base__utility__make_optional_u63(false, 0u);
43885 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
43886 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
43887 return wuffs_base__utility__make_optional_u63(false, 0u);
43890 return wuffs_base__utility__make_optional_u63(true, 0u);
43893 // -------- func gzip.decoder.workbuf_len
43895 WUFFS_BASE__GENERATED_C_CODE
43896 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
43897 wuffs_gzip__decoder__workbuf_len(
43898 const wuffs_gzip__decoder* self) {
43899 if (!self) {
43900 return wuffs_base__utility__empty_range_ii_u64();
43902 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
43903 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
43904 return wuffs_base__utility__empty_range_ii_u64();
43907 return wuffs_base__utility__make_range_ii_u64(1u, 1u);
43910 // -------- func gzip.decoder.transform_io
43912 WUFFS_BASE__GENERATED_C_CODE
43913 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
43914 wuffs_gzip__decoder__transform_io(
43915 wuffs_gzip__decoder* self,
43916 wuffs_base__io_buffer* a_dst,
43917 wuffs_base__io_buffer* a_src,
43918 wuffs_base__slice_u8 a_workbuf) {
43919 if (!self) {
43920 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
43922 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
43923 return wuffs_base__make_status(
43924 (self->private_impl.magic == WUFFS_BASE__DISABLED)
43925 ? wuffs_base__error__disabled_by_previous_error
43926 : wuffs_base__error__initialize_not_called);
43928 if (!a_dst || !a_src) {
43929 self->private_impl.magic = WUFFS_BASE__DISABLED;
43930 return wuffs_base__make_status(wuffs_base__error__bad_argument);
43932 if ((self->private_impl.active_coroutine != 0) &&
43933 (self->private_impl.active_coroutine != 1)) {
43934 self->private_impl.magic = WUFFS_BASE__DISABLED;
43935 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
43937 self->private_impl.active_coroutine = 0;
43938 wuffs_base__status status = wuffs_base__make_status(NULL);
43940 wuffs_base__status v_status = wuffs_base__make_status(NULL);
43942 uint32_t coro_susp_point = self->private_impl.p_transform_io;
43943 switch (coro_susp_point) {
43944 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
43946 while (true) {
43948 wuffs_base__status t_0 = wuffs_gzip__decoder__do_transform_io(self, a_dst, a_src, a_workbuf);
43949 v_status = t_0;
43951 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
43952 status = wuffs_base__make_status(wuffs_gzip__error__truncated_input);
43953 goto exit;
43955 status = v_status;
43956 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
43960 self->private_impl.p_transform_io = 0;
43961 goto exit;
43964 goto suspend;
43965 suspend:
43966 self->private_impl.p_transform_io = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
43967 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
43969 goto exit;
43970 exit:
43971 if (wuffs_base__status__is_error(&status)) {
43972 self->private_impl.magic = WUFFS_BASE__DISABLED;
43974 return status;
43977 // -------- func gzip.decoder.do_transform_io
43979 WUFFS_BASE__GENERATED_C_CODE
43980 static wuffs_base__status
43981 wuffs_gzip__decoder__do_transform_io(
43982 wuffs_gzip__decoder* self,
43983 wuffs_base__io_buffer* a_dst,
43984 wuffs_base__io_buffer* a_src,
43985 wuffs_base__slice_u8 a_workbuf) {
43986 wuffs_base__status status = wuffs_base__make_status(NULL);
43988 uint8_t v_c8 = 0;
43989 uint8_t v_flags = 0;
43990 uint16_t v_xlen = 0;
43991 uint64_t v_mark = 0;
43992 uint32_t v_checksum_have = 0;
43993 uint32_t v_decoded_length_have = 0;
43994 wuffs_base__status v_status = wuffs_base__make_status(NULL);
43995 uint32_t v_checksum_want = 0;
43996 uint32_t v_decoded_length_want = 0;
43998 uint8_t* iop_a_dst = NULL;
43999 uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
44000 uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
44001 uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
44002 if (a_dst && a_dst->data.ptr) {
44003 io0_a_dst = a_dst->data.ptr;
44004 io1_a_dst = io0_a_dst + a_dst->meta.wi;
44005 iop_a_dst = io1_a_dst;
44006 io2_a_dst = io0_a_dst + a_dst->data.len;
44007 if (a_dst->meta.closed) {
44008 io2_a_dst = iop_a_dst;
44011 const uint8_t* iop_a_src = NULL;
44012 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
44013 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
44014 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
44015 if (a_src && a_src->data.ptr) {
44016 io0_a_src = a_src->data.ptr;
44017 io1_a_src = io0_a_src + a_src->meta.ri;
44018 iop_a_src = io1_a_src;
44019 io2_a_src = io0_a_src + a_src->meta.wi;
44022 uint32_t coro_susp_point = self->private_impl.p_do_transform_io;
44023 if (coro_susp_point) {
44024 v_flags = self->private_data.s_do_transform_io.v_flags;
44025 v_checksum_have = self->private_data.s_do_transform_io.v_checksum_have;
44026 v_decoded_length_have = self->private_data.s_do_transform_io.v_decoded_length_have;
44027 v_checksum_want = self->private_data.s_do_transform_io.v_checksum_want;
44029 switch (coro_susp_point) {
44030 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
44033 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
44034 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
44035 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
44036 goto suspend;
44038 uint8_t t_0 = *iop_a_src++;
44039 v_c8 = t_0;
44041 if (v_c8 != 31u) {
44042 status = wuffs_base__make_status(wuffs_gzip__error__bad_header);
44043 goto exit;
44046 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
44047 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
44048 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
44049 goto suspend;
44051 uint8_t t_1 = *iop_a_src++;
44052 v_c8 = t_1;
44054 if (v_c8 != 139u) {
44055 status = wuffs_base__make_status(wuffs_gzip__error__bad_header);
44056 goto exit;
44059 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
44060 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
44061 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
44062 goto suspend;
44064 uint8_t t_2 = *iop_a_src++;
44065 v_c8 = t_2;
44067 if (v_c8 != 8u) {
44068 status = wuffs_base__make_status(wuffs_gzip__error__bad_compression_method);
44069 goto exit;
44072 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
44073 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
44074 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
44075 goto suspend;
44077 uint8_t t_3 = *iop_a_src++;
44078 v_flags = t_3;
44080 self->private_data.s_do_transform_io.scratch = 6u;
44081 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
44082 if (self->private_data.s_do_transform_io.scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
44083 self->private_data.s_do_transform_io.scratch -= ((uint64_t)(io2_a_src - iop_a_src));
44084 iop_a_src = io2_a_src;
44085 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
44086 goto suspend;
44088 iop_a_src += self->private_data.s_do_transform_io.scratch;
44089 if (((uint8_t)(v_flags & 4u)) != 0u) {
44091 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
44092 uint16_t t_4;
44093 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
44094 t_4 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src);
44095 iop_a_src += 2;
44096 } else {
44097 self->private_data.s_do_transform_io.scratch = 0;
44098 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
44099 while (true) {
44100 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
44101 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
44102 goto suspend;
44104 uint64_t* scratch = &self->private_data.s_do_transform_io.scratch;
44105 uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
44106 *scratch <<= 8;
44107 *scratch >>= 8;
44108 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
44109 if (num_bits_4 == 8) {
44110 t_4 = ((uint16_t)(*scratch));
44111 break;
44113 num_bits_4 += 8u;
44114 *scratch |= ((uint64_t)(num_bits_4)) << 56;
44117 v_xlen = t_4;
44119 self->private_data.s_do_transform_io.scratch = ((uint32_t)(v_xlen));
44120 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
44121 if (self->private_data.s_do_transform_io.scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
44122 self->private_data.s_do_transform_io.scratch -= ((uint64_t)(io2_a_src - iop_a_src));
44123 iop_a_src = io2_a_src;
44124 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
44125 goto suspend;
44127 iop_a_src += self->private_data.s_do_transform_io.scratch;
44129 if (((uint8_t)(v_flags & 8u)) != 0u) {
44130 while (true) {
44132 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
44133 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
44134 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
44135 goto suspend;
44137 uint8_t t_5 = *iop_a_src++;
44138 v_c8 = t_5;
44140 if (v_c8 == 0u) {
44141 break;
44145 if (((uint8_t)(v_flags & 16u)) != 0u) {
44146 while (true) {
44148 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
44149 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
44150 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
44151 goto suspend;
44153 uint8_t t_6 = *iop_a_src++;
44154 v_c8 = t_6;
44156 if (v_c8 == 0u) {
44157 break;
44161 if (((uint8_t)(v_flags & 2u)) != 0u) {
44162 self->private_data.s_do_transform_io.scratch = 2u;
44163 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
44164 if (self->private_data.s_do_transform_io.scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
44165 self->private_data.s_do_transform_io.scratch -= ((uint64_t)(io2_a_src - iop_a_src));
44166 iop_a_src = io2_a_src;
44167 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
44168 goto suspend;
44170 iop_a_src += self->private_data.s_do_transform_io.scratch;
44172 if (((uint8_t)(v_flags & 224u)) != 0u) {
44173 status = wuffs_base__make_status(wuffs_gzip__error__bad_encoding_flags);
44174 goto exit;
44176 while (true) {
44177 v_mark = ((uint64_t)(iop_a_dst - io0_a_dst));
44179 if (a_dst) {
44180 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
44182 if (a_src) {
44183 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
44185 wuffs_base__status t_7 = wuffs_deflate__decoder__transform_io(&self->private_data.f_flate, a_dst, a_src, a_workbuf);
44186 v_status = t_7;
44187 if (a_dst) {
44188 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
44190 if (a_src) {
44191 iop_a_src = a_src->data.ptr + a_src->meta.ri;
44194 if ( ! self->private_impl.f_ignore_checksum) {
44195 v_checksum_have = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_checksum, wuffs_private_impl__io__since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst));
44196 v_decoded_length_have += ((uint32_t)(wuffs_private_impl__io__count_since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst)))));
44198 if (wuffs_base__status__is_ok(&v_status)) {
44199 break;
44201 status = v_status;
44202 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(12);
44205 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
44206 uint32_t t_8;
44207 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
44208 t_8 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
44209 iop_a_src += 4;
44210 } else {
44211 self->private_data.s_do_transform_io.scratch = 0;
44212 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
44213 while (true) {
44214 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
44215 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
44216 goto suspend;
44218 uint64_t* scratch = &self->private_data.s_do_transform_io.scratch;
44219 uint32_t num_bits_8 = ((uint32_t)(*scratch >> 56));
44220 *scratch <<= 8;
44221 *scratch >>= 8;
44222 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_8;
44223 if (num_bits_8 == 24) {
44224 t_8 = ((uint32_t)(*scratch));
44225 break;
44227 num_bits_8 += 8u;
44228 *scratch |= ((uint64_t)(num_bits_8)) << 56;
44231 v_checksum_want = t_8;
44234 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
44235 uint32_t t_9;
44236 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
44237 t_9 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
44238 iop_a_src += 4;
44239 } else {
44240 self->private_data.s_do_transform_io.scratch = 0;
44241 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
44242 while (true) {
44243 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
44244 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
44245 goto suspend;
44247 uint64_t* scratch = &self->private_data.s_do_transform_io.scratch;
44248 uint32_t num_bits_9 = ((uint32_t)(*scratch >> 56));
44249 *scratch <<= 8;
44250 *scratch >>= 8;
44251 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_9;
44252 if (num_bits_9 == 24) {
44253 t_9 = ((uint32_t)(*scratch));
44254 break;
44256 num_bits_9 += 8u;
44257 *scratch |= ((uint64_t)(num_bits_9)) << 56;
44260 v_decoded_length_want = t_9;
44262 if ( ! self->private_impl.f_ignore_checksum && ((v_checksum_have != v_checksum_want) || (v_decoded_length_have != v_decoded_length_want))) {
44263 status = wuffs_base__make_status(wuffs_gzip__error__bad_checksum);
44264 goto exit;
44268 self->private_impl.p_do_transform_io = 0;
44269 goto exit;
44272 goto suspend;
44273 suspend:
44274 self->private_impl.p_do_transform_io = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
44275 self->private_data.s_do_transform_io.v_flags = v_flags;
44276 self->private_data.s_do_transform_io.v_checksum_have = v_checksum_have;
44277 self->private_data.s_do_transform_io.v_decoded_length_have = v_decoded_length_have;
44278 self->private_data.s_do_transform_io.v_checksum_want = v_checksum_want;
44280 goto exit;
44281 exit:
44282 if (a_dst && a_dst->data.ptr) {
44283 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
44285 if (a_src && a_src->data.ptr) {
44286 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
44289 return status;
44292 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GZIP)
44294 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JPEG)
44296 // ---------------- Status Codes Implementations
44298 const char wuffs_jpeg__error__bad_dht_marker[] = "#jpeg: bad DHT marker";
44299 const char wuffs_jpeg__error__bad_dqt_marker[] = "#jpeg: bad DQT marker";
44300 const char wuffs_jpeg__error__bad_dri_marker[] = "#jpeg: bad DRI marker";
44301 const char wuffs_jpeg__error__bad_sof_marker[] = "#jpeg: bad SOF marker";
44302 const char wuffs_jpeg__error__bad_sos_marker[] = "#jpeg: bad SOS marker";
44303 const char wuffs_jpeg__error__bad_header[] = "#jpeg: bad header";
44304 const char wuffs_jpeg__error__bad_marker[] = "#jpeg: bad marker";
44305 const char wuffs_jpeg__error__bad_scan_count[] = "#jpeg: bad scan count";
44306 const char wuffs_jpeg__error__missing_huffman_table[] = "#jpeg: missing Huffman table";
44307 const char wuffs_jpeg__error__missing_quantization_table[] = "#jpeg: missing Quantization table";
44308 const char wuffs_jpeg__error__rejected_progressive_jpeg[] = "#jpeg: rejected progressive JPEG";
44309 const char wuffs_jpeg__error__truncated_input[] = "#jpeg: truncated input";
44310 const char wuffs_jpeg__error__unsupported_arithmetic_coding[] = "#jpeg: unsupported arithmetic coding";
44311 const char wuffs_jpeg__error__unsupported_color_model[] = "#jpeg: unsupported color model";
44312 const char wuffs_jpeg__error__unsupported_fractional_sampling[] = "#jpeg: unsupported fractional sampling";
44313 const char wuffs_jpeg__error__unsupported_hierarchical_coding[] = "#jpeg: unsupported hierarchical coding";
44314 const char wuffs_jpeg__error__unsupported_implicit_height[] = "#jpeg: unsupported implicit height";
44315 const char wuffs_jpeg__error__unsupported_lossless_coding[] = "#jpeg: unsupported lossless coding";
44316 const char wuffs_jpeg__error__unsupported_marker[] = "#jpeg: unsupported marker";
44317 const char wuffs_jpeg__error__unsupported_precision_12_bits[] = "#jpeg: unsupported precision (12 bits)";
44318 const char wuffs_jpeg__error__unsupported_precision_16_bits[] = "#jpeg: unsupported precision (16 bits)";
44319 const char wuffs_jpeg__error__unsupported_precision[] = "#jpeg: unsupported precision";
44320 const char wuffs_jpeg__error__unsupported_scan_count[] = "#jpeg: unsupported scan count";
44321 const char wuffs_jpeg__error__internal_error_inconsistent_decoder_state[] = "#jpeg: internal error: inconsistent decoder state";
44323 // ---------------- Private Consts
44325 static const uint8_t
44326 WUFFS_JPEG__UNZIG[80] WUFFS_BASE__POTENTIALLY_UNUSED = {
44327 0u, 0u, 1u, 8u, 16u, 9u, 2u, 3u,
44328 10u, 17u, 24u, 32u, 25u, 18u, 11u, 4u,
44329 5u, 12u, 19u, 26u, 33u, 40u, 48u, 41u,
44330 34u, 27u, 20u, 13u, 6u, 7u, 14u, 21u,
44331 28u, 35u, 42u, 49u, 56u, 57u, 50u, 43u,
44332 36u, 29u, 22u, 15u, 23u, 30u, 37u, 44u,
44333 51u, 58u, 59u, 52u, 45u, 38u, 31u, 39u,
44334 46u, 53u, 60u, 61u, 54u, 47u, 55u, 62u,
44335 63u, 63u, 63u, 63u, 63u, 63u, 63u, 63u,
44336 63u, 63u, 63u, 63u, 63u, 63u, 63u, 63u,
44339 static const uint8_t
44340 WUFFS_JPEG__BIAS_AND_CLAMP[1024] WUFFS_BASE__POTENTIALLY_UNUSED = {
44341 128u, 129u, 130u, 131u, 132u, 133u, 134u, 135u,
44342 136u, 137u, 138u, 139u, 140u, 141u, 142u, 143u,
44343 144u, 145u, 146u, 147u, 148u, 149u, 150u, 151u,
44344 152u, 153u, 154u, 155u, 156u, 157u, 158u, 159u,
44345 160u, 161u, 162u, 163u, 164u, 165u, 166u, 167u,
44346 168u, 169u, 170u, 171u, 172u, 173u, 174u, 175u,
44347 176u, 177u, 178u, 179u, 180u, 181u, 182u, 183u,
44348 184u, 185u, 186u, 187u, 188u, 189u, 190u, 191u,
44349 192u, 193u, 194u, 195u, 196u, 197u, 198u, 199u,
44350 200u, 201u, 202u, 203u, 204u, 205u, 206u, 207u,
44351 208u, 209u, 210u, 211u, 212u, 213u, 214u, 215u,
44352 216u, 217u, 218u, 219u, 220u, 221u, 222u, 223u,
44353 224u, 225u, 226u, 227u, 228u, 229u, 230u, 231u,
44354 232u, 233u, 234u, 235u, 236u, 237u, 238u, 239u,
44355 240u, 241u, 242u, 243u, 244u, 245u, 246u, 247u,
44356 248u, 249u, 250u, 251u, 252u, 253u, 254u, 255u,
44357 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44358 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44359 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44360 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44361 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44362 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44363 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44364 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44365 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44366 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44367 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44368 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44369 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44370 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44371 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44372 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44373 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44374 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44375 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44376 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44377 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44378 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44379 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44380 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44381 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44382 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44383 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44384 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44385 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44386 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44387 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44388 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44389 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44390 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44391 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44392 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44393 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44394 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44395 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44396 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44397 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44398 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44399 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44400 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44401 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44402 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44403 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44404 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u,
44405 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44406 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44407 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44408 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44409 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44410 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44411 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44412 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44413 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44414 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44415 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44416 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44417 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44418 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44419 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44420 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44421 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44422 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44423 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44424 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44425 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44426 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44427 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44428 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44429 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44430 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44431 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44432 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44433 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44434 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44435 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44436 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44437 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44438 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44439 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44440 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44441 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44442 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44443 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44444 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44445 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44446 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44447 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44448 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44449 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44450 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44451 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44452 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
44453 0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u,
44454 8u, 9u, 10u, 11u, 12u, 13u, 14u, 15u,
44455 16u, 17u, 18u, 19u, 20u, 21u, 22u, 23u,
44456 24u, 25u, 26u, 27u, 28u, 29u, 30u, 31u,
44457 32u, 33u, 34u, 35u, 36u, 37u, 38u, 39u,
44458 40u, 41u, 42u, 43u, 44u, 45u, 46u, 47u,
44459 48u, 49u, 50u, 51u, 52u, 53u, 54u, 55u,
44460 56u, 57u, 58u, 59u, 60u, 61u, 62u, 63u,
44461 64u, 65u, 66u, 67u, 68u, 69u, 70u, 71u,
44462 72u, 73u, 74u, 75u, 76u, 77u, 78u, 79u,
44463 80u, 81u, 82u, 83u, 84u, 85u, 86u, 87u,
44464 88u, 89u, 90u, 91u, 92u, 93u, 94u, 95u,
44465 96u, 97u, 98u, 99u, 100u, 101u, 102u, 103u,
44466 104u, 105u, 106u, 107u, 108u, 109u, 110u, 111u,
44467 112u, 113u, 114u, 115u, 116u, 117u, 118u, 119u,
44468 120u, 121u, 122u, 123u, 124u, 125u, 126u, 127u,
44471 static const uint16_t
44472 WUFFS_JPEG__EXTEND[16] WUFFS_BASE__POTENTIALLY_UNUSED = {
44473 0u, 65535u, 65533u, 65529u, 65521u, 65505u, 65473u, 65409u,
44474 65281u, 65025u, 64513u, 63489u, 61441u, 57345u, 49153u, 32769u,
44477 static const uint8_t
44478 WUFFS_JPEG__DEFAULT_HUFF_TABLE_DC_LUMA[29] WUFFS_BASE__POTENTIALLY_UNUSED = {
44479 0u, 0u, 1u, 5u, 1u, 1u, 1u, 1u,
44480 1u, 1u, 0u, 0u, 0u, 0u, 0u, 0u,
44481 0u, 0u, 1u, 2u, 3u, 4u, 5u, 6u,
44482 7u, 8u, 9u, 10u, 11u,
44485 static const uint8_t
44486 WUFFS_JPEG__DEFAULT_HUFF_TABLE_DC_CHROMA[29] WUFFS_BASE__POTENTIALLY_UNUSED = {
44487 1u, 0u, 3u, 1u, 1u, 1u, 1u, 1u,
44488 1u, 1u, 1u, 1u, 0u, 0u, 0u, 0u,
44489 0u, 0u, 1u, 2u, 3u, 4u, 5u, 6u,
44490 7u, 8u, 9u, 10u, 11u,
44493 static const uint8_t
44494 WUFFS_JPEG__DEFAULT_HUFF_TABLE_AC_LUMA[179] WUFFS_BASE__POTENTIALLY_UNUSED = {
44495 16u, 0u, 2u, 1u, 3u, 3u, 2u, 4u,
44496 3u, 5u, 5u, 4u, 4u, 0u, 0u, 1u,
44497 125u, 1u, 2u, 3u, 0u, 4u, 17u, 5u,
44498 18u, 33u, 49u, 65u, 6u, 19u, 81u, 97u,
44499 7u, 34u, 113u, 20u, 50u, 129u, 145u, 161u,
44500 8u, 35u, 66u, 177u, 193u, 21u, 82u, 209u,
44501 240u, 36u, 51u, 98u, 114u, 130u, 9u, 10u,
44502 22u, 23u, 24u, 25u, 26u, 37u, 38u, 39u,
44503 40u, 41u, 42u, 52u, 53u, 54u, 55u, 56u,
44504 57u, 58u, 67u, 68u, 69u, 70u, 71u, 72u,
44505 73u, 74u, 83u, 84u, 85u, 86u, 87u, 88u,
44506 89u, 90u, 99u, 100u, 101u, 102u, 103u, 104u,
44507 105u, 106u, 115u, 116u, 117u, 118u, 119u, 120u,
44508 121u, 122u, 131u, 132u, 133u, 134u, 135u, 136u,
44509 137u, 138u, 146u, 147u, 148u, 149u, 150u, 151u,
44510 152u, 153u, 154u, 162u, 163u, 164u, 165u, 166u,
44511 167u, 168u, 169u, 170u, 178u, 179u, 180u, 181u,
44512 182u, 183u, 184u, 185u, 186u, 194u, 195u, 196u,
44513 197u, 198u, 199u, 200u, 201u, 202u, 210u, 211u,
44514 212u, 213u, 214u, 215u, 216u, 217u, 218u, 225u,
44515 226u, 227u, 228u, 229u, 230u, 231u, 232u, 233u,
44516 234u, 241u, 242u, 243u, 244u, 245u, 246u, 247u,
44517 248u, 249u, 250u,
44520 static const uint8_t
44521 WUFFS_JPEG__DEFAULT_HUFF_TABLE_AC_CHROMA[179] WUFFS_BASE__POTENTIALLY_UNUSED = {
44522 17u, 0u, 2u, 1u, 2u, 4u, 4u, 3u,
44523 4u, 7u, 5u, 4u, 4u, 0u, 1u, 2u,
44524 119u, 0u, 1u, 2u, 3u, 17u, 4u, 5u,
44525 33u, 49u, 6u, 18u, 65u, 81u, 7u, 97u,
44526 113u, 19u, 34u, 50u, 129u, 8u, 20u, 66u,
44527 145u, 161u, 177u, 193u, 9u, 35u, 51u, 82u,
44528 240u, 21u, 98u, 114u, 209u, 10u, 22u, 36u,
44529 52u, 225u, 37u, 241u, 23u, 24u, 25u, 26u,
44530 38u, 39u, 40u, 41u, 42u, 53u, 54u, 55u,
44531 56u, 57u, 58u, 67u, 68u, 69u, 70u, 71u,
44532 72u, 73u, 74u, 83u, 84u, 85u, 86u, 87u,
44533 88u, 89u, 90u, 99u, 100u, 101u, 102u, 103u,
44534 104u, 105u, 106u, 115u, 116u, 117u, 118u, 119u,
44535 120u, 121u, 122u, 130u, 131u, 132u, 133u, 134u,
44536 135u, 136u, 137u, 138u, 146u, 147u, 148u, 149u,
44537 150u, 151u, 152u, 153u, 154u, 162u, 163u, 164u,
44538 165u, 166u, 167u, 168u, 169u, 170u, 178u, 179u,
44539 180u, 181u, 182u, 183u, 184u, 185u, 186u, 194u,
44540 195u, 196u, 197u, 198u, 199u, 200u, 201u, 202u,
44541 210u, 211u, 212u, 213u, 214u, 215u, 216u, 217u,
44542 218u, 226u, 227u, 228u, 229u, 230u, 231u, 232u,
44543 233u, 234u, 242u, 243u, 244u, 245u, 246u, 247u,
44544 248u, 249u, 250u,
44547 #define WUFFS_JPEG__QUIRKS_BASE 1220532224u
44549 // ---------------- Private Initializer Prototypes
44551 // ---------------- Private Function Prototypes
44553 WUFFS_BASE__GENERATED_C_CODE
44554 static wuffs_base__empty_struct
44555 wuffs_jpeg__decoder__decode_idct(
44556 wuffs_jpeg__decoder* self,
44557 wuffs_base__slice_u8 a_dst_buffer,
44558 uint64_t a_dst_stride,
44559 uint32_t a_q);
44561 WUFFS_BASE__GENERATED_C_CODE
44562 static wuffs_base__empty_struct
44563 wuffs_jpeg__decoder__decode_idct__choosy_default(
44564 wuffs_jpeg__decoder* self,
44565 wuffs_base__slice_u8 a_dst_buffer,
44566 uint64_t a_dst_stride,
44567 uint32_t a_q);
44569 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3)
44570 WUFFS_BASE__GENERATED_C_CODE
44571 static wuffs_base__empty_struct
44572 wuffs_jpeg__decoder__decode_idct_x86_avx2(
44573 wuffs_jpeg__decoder* self,
44574 wuffs_base__slice_u8 a_dst_buffer,
44575 uint64_t a_dst_stride,
44576 uint32_t a_q);
44577 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3)
44579 WUFFS_BASE__GENERATED_C_CODE
44580 static wuffs_base__status
44581 wuffs_jpeg__decoder__do_decode_image_config(
44582 wuffs_jpeg__decoder* self,
44583 wuffs_base__image_config* a_dst,
44584 wuffs_base__io_buffer* a_src);
44586 WUFFS_BASE__GENERATED_C_CODE
44587 static wuffs_base__status
44588 wuffs_jpeg__decoder__decode_dqt(
44589 wuffs_jpeg__decoder* self,
44590 wuffs_base__io_buffer* a_src);
44592 WUFFS_BASE__GENERATED_C_CODE
44593 static wuffs_base__status
44594 wuffs_jpeg__decoder__decode_dri(
44595 wuffs_jpeg__decoder* self,
44596 wuffs_base__io_buffer* a_src);
44598 WUFFS_BASE__GENERATED_C_CODE
44599 static wuffs_base__status
44600 wuffs_jpeg__decoder__decode_appn(
44601 wuffs_jpeg__decoder* self,
44602 wuffs_base__io_buffer* a_src,
44603 uint8_t a_marker);
44605 WUFFS_BASE__GENERATED_C_CODE
44606 static wuffs_base__status
44607 wuffs_jpeg__decoder__decode_sof(
44608 wuffs_jpeg__decoder* self,
44609 wuffs_base__io_buffer* a_src);
44611 WUFFS_BASE__GENERATED_C_CODE
44612 static uint32_t
44613 wuffs_jpeg__decoder__quantize_dimension(
44614 const wuffs_jpeg__decoder* self,
44615 uint32_t a_width,
44616 uint8_t a_h,
44617 uint8_t a_max_incl_h);
44619 WUFFS_BASE__GENERATED_C_CODE
44620 static wuffs_base__status
44621 wuffs_jpeg__decoder__do_decode_frame_config(
44622 wuffs_jpeg__decoder* self,
44623 wuffs_base__frame_config* a_dst,
44624 wuffs_base__io_buffer* a_src);
44626 WUFFS_BASE__GENERATED_C_CODE
44627 static wuffs_base__status
44628 wuffs_jpeg__decoder__do_decode_frame(
44629 wuffs_jpeg__decoder* self,
44630 wuffs_base__pixel_buffer* a_dst,
44631 wuffs_base__io_buffer* a_src,
44632 wuffs_base__pixel_blend a_blend,
44633 wuffs_base__slice_u8 a_workbuf,
44634 wuffs_base__decode_frame_options* a_opts);
44636 WUFFS_BASE__GENERATED_C_CODE
44637 static wuffs_base__status
44638 wuffs_jpeg__decoder__decode_dht(
44639 wuffs_jpeg__decoder* self,
44640 wuffs_base__io_buffer* a_src);
44642 WUFFS_BASE__GENERATED_C_CODE
44643 static bool
44644 wuffs_jpeg__decoder__calculate_huff_tables(
44645 wuffs_jpeg__decoder* self,
44646 uint8_t a_tc4_th,
44647 uint32_t a_total_count);
44649 WUFFS_BASE__GENERATED_C_CODE
44650 static wuffs_base__status
44651 wuffs_jpeg__decoder__decode_sos(
44652 wuffs_jpeg__decoder* self,
44653 wuffs_base__pixel_buffer* a_dst,
44654 wuffs_base__io_buffer* a_src,
44655 wuffs_base__slice_u8 a_workbuf);
44657 WUFFS_BASE__GENERATED_C_CODE
44658 static wuffs_base__status
44659 wuffs_jpeg__decoder__prepare_scan(
44660 wuffs_jpeg__decoder* self,
44661 wuffs_base__io_buffer* a_src);
44663 WUFFS_BASE__GENERATED_C_CODE
44664 static wuffs_base__status
44665 wuffs_jpeg__decoder__use_default_huffman_table(
44666 wuffs_jpeg__decoder* self,
44667 uint8_t a_tc4_th);
44669 WUFFS_BASE__GENERATED_C_CODE
44670 static wuffs_base__empty_struct
44671 wuffs_jpeg__decoder__calculate_single_component_scan_fields(
44672 wuffs_jpeg__decoder* self);
44674 WUFFS_BASE__GENERATED_C_CODE
44675 static bool
44676 wuffs_jpeg__decoder__calculate_multiple_component_scan_fields(
44677 wuffs_jpeg__decoder* self);
44679 WUFFS_BASE__GENERATED_C_CODE
44680 static wuffs_base__empty_struct
44681 wuffs_jpeg__decoder__fill_bitstream(
44682 wuffs_jpeg__decoder* self,
44683 wuffs_base__io_buffer* a_src);
44685 WUFFS_BASE__GENERATED_C_CODE
44686 static wuffs_base__empty_struct
44687 wuffs_jpeg__decoder__load_mcu_blocks_for_single_component(
44688 wuffs_jpeg__decoder* self,
44689 uint32_t a_mx,
44690 uint32_t a_my,
44691 wuffs_base__slice_u8 a_workbuf,
44692 uint32_t a_csel);
44694 WUFFS_BASE__GENERATED_C_CODE
44695 static wuffs_base__empty_struct
44696 wuffs_jpeg__decoder__load_mcu_blocks_for_single_component__choosy_default(
44697 wuffs_jpeg__decoder* self,
44698 uint32_t a_mx,
44699 uint32_t a_my,
44700 wuffs_base__slice_u8 a_workbuf,
44701 uint32_t a_csel);
44703 WUFFS_BASE__GENERATED_C_CODE
44704 static wuffs_base__empty_struct
44705 wuffs_jpeg__decoder__load_mcu_blocks(
44706 wuffs_jpeg__decoder* self,
44707 uint32_t a_mx,
44708 uint32_t a_my,
44709 wuffs_base__slice_u8 a_workbuf);
44711 WUFFS_BASE__GENERATED_C_CODE
44712 static wuffs_base__empty_struct
44713 wuffs_jpeg__decoder__save_mcu_blocks(
44714 wuffs_jpeg__decoder* self,
44715 uint32_t a_mx,
44716 uint32_t a_my,
44717 wuffs_base__slice_u8 a_workbuf);
44719 WUFFS_BASE__GENERATED_C_CODE
44720 static wuffs_base__status
44721 wuffs_jpeg__decoder__skip_past_the_next_restart_marker(
44722 wuffs_jpeg__decoder* self,
44723 wuffs_base__io_buffer* a_src);
44725 WUFFS_BASE__GENERATED_C_CODE
44726 static wuffs_base__empty_struct
44727 wuffs_jpeg__decoder__apply_progressive_idct(
44728 wuffs_jpeg__decoder* self,
44729 wuffs_base__slice_u8 a_workbuf);
44731 WUFFS_BASE__GENERATED_C_CODE
44732 static wuffs_base__status
44733 wuffs_jpeg__decoder__swizzle_gray(
44734 wuffs_jpeg__decoder* self,
44735 wuffs_base__pixel_buffer* a_dst,
44736 wuffs_base__slice_u8 a_workbuf,
44737 uint32_t a_x0,
44738 uint32_t a_x1,
44739 uint32_t a_y0,
44740 uint32_t a_y1,
44741 uint64_t a_stride);
44743 WUFFS_BASE__GENERATED_C_CODE
44744 static wuffs_base__status
44745 wuffs_jpeg__decoder__swizzle_colorful(
44746 wuffs_jpeg__decoder* self,
44747 wuffs_base__pixel_buffer* a_dst,
44748 wuffs_base__slice_u8 a_workbuf,
44749 uint32_t a_x0,
44750 uint32_t a_x1,
44751 uint32_t a_y0,
44752 uint32_t a_y1);
44754 WUFFS_BASE__GENERATED_C_CODE
44755 static bool
44756 wuffs_jpeg__decoder__top_left_quants_has_zero(
44757 const wuffs_jpeg__decoder* self,
44758 uint32_t a_q);
44760 WUFFS_BASE__GENERATED_C_CODE
44761 static wuffs_base__empty_struct
44762 wuffs_jpeg__decoder__load_mcu_blocks_for_single_component_smooth(
44763 wuffs_jpeg__decoder* self,
44764 uint32_t a_mx,
44765 uint32_t a_my,
44766 wuffs_base__slice_u8 a_workbuf,
44767 uint32_t a_csel);
44769 WUFFS_BASE__GENERATED_C_CODE
44770 static uint32_t
44771 wuffs_jpeg__decoder__decode_mcu(
44772 wuffs_jpeg__decoder* self,
44773 wuffs_base__pixel_buffer* a_dst,
44774 wuffs_base__slice_u8 a_workbuf,
44775 uint32_t a_mx,
44776 uint32_t a_my);
44778 WUFFS_BASE__GENERATED_C_CODE
44779 static uint32_t
44780 wuffs_jpeg__decoder__decode_mcu__choosy_default(
44781 wuffs_jpeg__decoder* self,
44782 wuffs_base__pixel_buffer* a_dst,
44783 wuffs_base__slice_u8 a_workbuf,
44784 uint32_t a_mx,
44785 uint32_t a_my);
44787 WUFFS_BASE__GENERATED_C_CODE
44788 static uint32_t
44789 wuffs_jpeg__decoder__decode_mcu_progressive_ac_high_bits(
44790 wuffs_jpeg__decoder* self,
44791 wuffs_base__pixel_buffer* a_dst,
44792 wuffs_base__slice_u8 a_workbuf,
44793 uint32_t a_mx,
44794 uint32_t a_my);
44796 WUFFS_BASE__GENERATED_C_CODE
44797 static uint32_t
44798 wuffs_jpeg__decoder__decode_mcu_progressive_ac_low_bit(
44799 wuffs_jpeg__decoder* self,
44800 wuffs_base__pixel_buffer* a_dst,
44801 wuffs_base__slice_u8 a_workbuf,
44802 uint32_t a_mx,
44803 uint32_t a_my);
44805 WUFFS_BASE__GENERATED_C_CODE
44806 static uint32_t
44807 wuffs_jpeg__decoder__decode_mcu_progressive_dc_high_bits(
44808 wuffs_jpeg__decoder* self,
44809 wuffs_base__pixel_buffer* a_dst,
44810 wuffs_base__slice_u8 a_workbuf,
44811 uint32_t a_mx,
44812 uint32_t a_my);
44814 WUFFS_BASE__GENERATED_C_CODE
44815 static uint32_t
44816 wuffs_jpeg__decoder__decode_mcu_progressive_dc_low_bit(
44817 wuffs_jpeg__decoder* self,
44818 wuffs_base__pixel_buffer* a_dst,
44819 wuffs_base__slice_u8 a_workbuf,
44820 uint32_t a_mx,
44821 uint32_t a_my);
44823 // ---------------- VTables
44825 const wuffs_base__image_decoder__func_ptrs
44826 wuffs_jpeg__decoder__func_ptrs_for__wuffs_base__image_decoder = {
44827 (wuffs_base__status(*)(void*,
44828 wuffs_base__pixel_buffer*,
44829 wuffs_base__io_buffer*,
44830 wuffs_base__pixel_blend,
44831 wuffs_base__slice_u8,
44832 wuffs_base__decode_frame_options*))(&wuffs_jpeg__decoder__decode_frame),
44833 (wuffs_base__status(*)(void*,
44834 wuffs_base__frame_config*,
44835 wuffs_base__io_buffer*))(&wuffs_jpeg__decoder__decode_frame_config),
44836 (wuffs_base__status(*)(void*,
44837 wuffs_base__image_config*,
44838 wuffs_base__io_buffer*))(&wuffs_jpeg__decoder__decode_image_config),
44839 (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_jpeg__decoder__frame_dirty_rect),
44840 (uint64_t(*)(const void*,
44841 uint32_t))(&wuffs_jpeg__decoder__get_quirk),
44842 (uint32_t(*)(const void*))(&wuffs_jpeg__decoder__num_animation_loops),
44843 (uint64_t(*)(const void*))(&wuffs_jpeg__decoder__num_decoded_frame_configs),
44844 (uint64_t(*)(const void*))(&wuffs_jpeg__decoder__num_decoded_frames),
44845 (wuffs_base__status(*)(void*,
44846 uint64_t,
44847 uint64_t))(&wuffs_jpeg__decoder__restart_frame),
44848 (wuffs_base__status(*)(void*,
44849 uint32_t,
44850 uint64_t))(&wuffs_jpeg__decoder__set_quirk),
44851 (wuffs_base__empty_struct(*)(void*,
44852 uint32_t,
44853 bool))(&wuffs_jpeg__decoder__set_report_metadata),
44854 (wuffs_base__status(*)(void*,
44855 wuffs_base__io_buffer*,
44856 wuffs_base__more_information*,
44857 wuffs_base__io_buffer*))(&wuffs_jpeg__decoder__tell_me_more),
44858 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_jpeg__decoder__workbuf_len),
44861 // ---------------- Initializer Implementations
44863 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
44864 wuffs_jpeg__decoder__initialize(
44865 wuffs_jpeg__decoder* self,
44866 size_t sizeof_star_self,
44867 uint64_t wuffs_version,
44868 uint32_t options){
44869 if (!self) {
44870 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
44872 if (sizeof(*self) != sizeof_star_self) {
44873 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
44875 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
44876 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
44877 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
44880 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
44881 // The whole point of this if-check is to detect an uninitialized *self.
44882 // We disable the warning on GCC. Clang-5.0 does not have this warning.
44883 #if !defined(__clang__) && defined(__GNUC__)
44884 #pragma GCC diagnostic push
44885 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
44886 #endif
44887 if (self->private_impl.magic != 0) {
44888 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
44890 #if !defined(__clang__) && defined(__GNUC__)
44891 #pragma GCC diagnostic pop
44892 #endif
44893 } else {
44894 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
44895 memset(self, 0, sizeof(*self));
44896 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
44897 } else {
44898 memset(&(self->private_impl), 0, sizeof(self->private_impl));
44902 self->private_impl.choosy_decode_idct = &wuffs_jpeg__decoder__decode_idct__choosy_default;
44903 self->private_impl.choosy_load_mcu_blocks_for_single_component = &wuffs_jpeg__decoder__load_mcu_blocks_for_single_component__choosy_default;
44904 self->private_impl.choosy_decode_mcu = &wuffs_jpeg__decoder__decode_mcu__choosy_default;
44906 self->private_impl.magic = WUFFS_BASE__MAGIC;
44907 self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
44908 wuffs_base__image_decoder__vtable_name;
44909 self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
44910 (const void*)(&wuffs_jpeg__decoder__func_ptrs_for__wuffs_base__image_decoder);
44911 return wuffs_base__make_status(NULL);
44914 wuffs_jpeg__decoder*
44915 wuffs_jpeg__decoder__alloc(void) {
44916 wuffs_jpeg__decoder* x =
44917 (wuffs_jpeg__decoder*)(calloc(1, sizeof(wuffs_jpeg__decoder)));
44918 if (!x) {
44919 return NULL;
44921 if (wuffs_jpeg__decoder__initialize(
44922 x, sizeof(wuffs_jpeg__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
44923 free(x);
44924 return NULL;
44926 return x;
44929 size_t
44930 sizeof__wuffs_jpeg__decoder(void) {
44931 return sizeof(wuffs_jpeg__decoder);
44934 // ---------------- Function Implementations
44936 // -------- func jpeg.decoder.decode_idct
44938 WUFFS_BASE__GENERATED_C_CODE
44939 static wuffs_base__empty_struct
44940 wuffs_jpeg__decoder__decode_idct(
44941 wuffs_jpeg__decoder* self,
44942 wuffs_base__slice_u8 a_dst_buffer,
44943 uint64_t a_dst_stride,
44944 uint32_t a_q) {
44945 return (*self->private_impl.choosy_decode_idct)(self, a_dst_buffer, a_dst_stride, a_q);
44948 WUFFS_BASE__GENERATED_C_CODE
44949 static wuffs_base__empty_struct
44950 wuffs_jpeg__decoder__decode_idct__choosy_default(
44951 wuffs_jpeg__decoder* self,
44952 wuffs_base__slice_u8 a_dst_buffer,
44953 uint64_t a_dst_stride,
44954 uint32_t a_q) {
44955 uint32_t v_bq0 = 0;
44956 uint32_t v_bq2 = 0;
44957 uint32_t v_bq4 = 0;
44958 uint32_t v_bq6 = 0;
44959 uint32_t v_ca = 0;
44960 uint32_t v_cb2 = 0;
44961 uint32_t v_cb6 = 0;
44962 uint32_t v_ccp = 0;
44963 uint32_t v_ccm = 0;
44964 uint32_t v_cd0 = 0;
44965 uint32_t v_cd1 = 0;
44966 uint32_t v_cd2 = 0;
44967 uint32_t v_cd3 = 0;
44968 uint32_t v_bq1 = 0;
44969 uint32_t v_bq3 = 0;
44970 uint32_t v_bq5 = 0;
44971 uint32_t v_bq7 = 0;
44972 uint32_t v_ci51 = 0;
44973 uint32_t v_ci53 = 0;
44974 uint32_t v_ci71 = 0;
44975 uint32_t v_ci73 = 0;
44976 uint32_t v_cj = 0;
44977 uint32_t v_ck1 = 0;
44978 uint32_t v_ck3 = 0;
44979 uint32_t v_ck5 = 0;
44980 uint32_t v_ck7 = 0;
44981 uint32_t v_cl51 = 0;
44982 uint32_t v_cl73 = 0;
44983 uint32_t v_in0 = 0;
44984 uint32_t v_in2 = 0;
44985 uint32_t v_in4 = 0;
44986 uint32_t v_in6 = 0;
44987 uint32_t v_ra = 0;
44988 uint32_t v_rb2 = 0;
44989 uint32_t v_rb6 = 0;
44990 uint32_t v_rcp = 0;
44991 uint32_t v_rcm = 0;
44992 uint32_t v_rd0 = 0;
44993 uint32_t v_rd1 = 0;
44994 uint32_t v_rd2 = 0;
44995 uint32_t v_rd3 = 0;
44996 uint32_t v_in1 = 0;
44997 uint32_t v_in3 = 0;
44998 uint32_t v_in5 = 0;
44999 uint32_t v_in7 = 0;
45000 uint32_t v_ri51 = 0;
45001 uint32_t v_ri53 = 0;
45002 uint32_t v_ri71 = 0;
45003 uint32_t v_ri73 = 0;
45004 uint32_t v_rj = 0;
45005 uint32_t v_rk1 = 0;
45006 uint32_t v_rk3 = 0;
45007 uint32_t v_rk5 = 0;
45008 uint32_t v_rk7 = 0;
45009 uint32_t v_rl51 = 0;
45010 uint32_t v_rl73 = 0;
45011 uint32_t v_intermediate[64] = {0};
45013 if (8u > a_dst_stride) {
45014 return wuffs_base__make_empty_struct();
45016 if (0u == (self->private_data.f_mcu_blocks[0u][8u] |
45017 self->private_data.f_mcu_blocks[0u][16u] |
45018 self->private_data.f_mcu_blocks[0u][24u] |
45019 self->private_data.f_mcu_blocks[0u][32u] |
45020 self->private_data.f_mcu_blocks[0u][40u] |
45021 self->private_data.f_mcu_blocks[0u][48u] |
45022 self->private_data.f_mcu_blocks[0u][56u])) {
45023 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));
45024 v_intermediate[8u] = v_intermediate[0u];
45025 v_intermediate[16u] = v_intermediate[0u];
45026 v_intermediate[24u] = v_intermediate[0u];
45027 v_intermediate[32u] = v_intermediate[0u];
45028 v_intermediate[40u] = v_intermediate[0u];
45029 v_intermediate[48u] = v_intermediate[0u];
45030 v_intermediate[56u] = v_intermediate[0u];
45031 } else {
45032 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]))));
45033 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]))));
45034 v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u));
45035 v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u))));
45036 v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u))));
45037 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]))));
45038 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]))));
45039 v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u));
45040 v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u));
45041 v_cd0 = ((uint32_t)(v_ccp + v_cb2));
45042 v_cd1 = ((uint32_t)(v_ccm + v_cb6));
45043 v_cd2 = ((uint32_t)(v_ccm - v_cb6));
45044 v_cd3 = ((uint32_t)(v_ccp - v_cb2));
45045 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]))));
45046 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]))));
45047 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]))));
45048 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]))));
45049 v_ci51 = ((uint32_t)(v_bq5 + v_bq1));
45050 v_ci53 = ((uint32_t)(v_bq5 + v_bq3));
45051 v_ci71 = ((uint32_t)(v_bq7 + v_bq1));
45052 v_ci73 = ((uint32_t)(v_bq7 + v_bq3));
45053 v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u));
45054 v_ck1 = ((uint32_t)(v_bq1 * 12299u));
45055 v_ck3 = ((uint32_t)(v_bq3 * 25172u));
45056 v_ck5 = ((uint32_t)(v_bq5 * 16819u));
45057 v_ck7 = ((uint32_t)(v_bq7 * 2446u));
45058 v_ci51 *= 4294964100u;
45059 v_ci53 *= 4294946301u;
45060 v_ci71 *= 4294959923u;
45061 v_ci73 *= 4294951227u;
45062 v_cl51 = ((uint32_t)(v_ci51 + v_cj));
45063 v_cl73 = ((uint32_t)(v_ci73 + v_cj));
45064 v_ck1 += ((uint32_t)(v_ci71 + v_cl51));
45065 v_ck3 += ((uint32_t)(v_ci53 + v_cl73));
45066 v_ck5 += ((uint32_t)(v_ci53 + v_cl51));
45067 v_ck7 += ((uint32_t)(v_ci71 + v_cl73));
45068 v_intermediate[0u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u);
45069 v_intermediate[56u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u);
45070 v_intermediate[8u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u);
45071 v_intermediate[48u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u);
45072 v_intermediate[16u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u);
45073 v_intermediate[40u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u);
45074 v_intermediate[24u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u);
45075 v_intermediate[32u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u);
45077 if (0u == (self->private_data.f_mcu_blocks[0u][9u] |
45078 self->private_data.f_mcu_blocks[0u][17u] |
45079 self->private_data.f_mcu_blocks[0u][25u] |
45080 self->private_data.f_mcu_blocks[0u][33u] |
45081 self->private_data.f_mcu_blocks[0u][41u] |
45082 self->private_data.f_mcu_blocks[0u][49u] |
45083 self->private_data.f_mcu_blocks[0u][57u])) {
45084 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));
45085 v_intermediate[9u] = v_intermediate[1u];
45086 v_intermediate[17u] = v_intermediate[1u];
45087 v_intermediate[25u] = v_intermediate[1u];
45088 v_intermediate[33u] = v_intermediate[1u];
45089 v_intermediate[41u] = v_intermediate[1u];
45090 v_intermediate[49u] = v_intermediate[1u];
45091 v_intermediate[57u] = v_intermediate[1u];
45092 } else {
45093 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]))));
45094 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]))));
45095 v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u));
45096 v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u))));
45097 v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u))));
45098 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]))));
45099 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]))));
45100 v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u));
45101 v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u));
45102 v_cd0 = ((uint32_t)(v_ccp + v_cb2));
45103 v_cd1 = ((uint32_t)(v_ccm + v_cb6));
45104 v_cd2 = ((uint32_t)(v_ccm - v_cb6));
45105 v_cd3 = ((uint32_t)(v_ccp - v_cb2));
45106 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]))));
45107 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]))));
45108 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]))));
45109 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]))));
45110 v_ci51 = ((uint32_t)(v_bq5 + v_bq1));
45111 v_ci53 = ((uint32_t)(v_bq5 + v_bq3));
45112 v_ci71 = ((uint32_t)(v_bq7 + v_bq1));
45113 v_ci73 = ((uint32_t)(v_bq7 + v_bq3));
45114 v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u));
45115 v_ck1 = ((uint32_t)(v_bq1 * 12299u));
45116 v_ck3 = ((uint32_t)(v_bq3 * 25172u));
45117 v_ck5 = ((uint32_t)(v_bq5 * 16819u));
45118 v_ck7 = ((uint32_t)(v_bq7 * 2446u));
45119 v_ci51 *= 4294964100u;
45120 v_ci53 *= 4294946301u;
45121 v_ci71 *= 4294959923u;
45122 v_ci73 *= 4294951227u;
45123 v_cl51 = ((uint32_t)(v_ci51 + v_cj));
45124 v_cl73 = ((uint32_t)(v_ci73 + v_cj));
45125 v_ck1 += ((uint32_t)(v_ci71 + v_cl51));
45126 v_ck3 += ((uint32_t)(v_ci53 + v_cl73));
45127 v_ck5 += ((uint32_t)(v_ci53 + v_cl51));
45128 v_ck7 += ((uint32_t)(v_ci71 + v_cl73));
45129 v_intermediate[1u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u);
45130 v_intermediate[57u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u);
45131 v_intermediate[9u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u);
45132 v_intermediate[49u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u);
45133 v_intermediate[17u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u);
45134 v_intermediate[41u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u);
45135 v_intermediate[25u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u);
45136 v_intermediate[33u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u);
45138 if (0u == (self->private_data.f_mcu_blocks[0u][10u] |
45139 self->private_data.f_mcu_blocks[0u][18u] |
45140 self->private_data.f_mcu_blocks[0u][26u] |
45141 self->private_data.f_mcu_blocks[0u][34u] |
45142 self->private_data.f_mcu_blocks[0u][42u] |
45143 self->private_data.f_mcu_blocks[0u][50u] |
45144 self->private_data.f_mcu_blocks[0u][58u])) {
45145 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));
45146 v_intermediate[10u] = v_intermediate[2u];
45147 v_intermediate[18u] = v_intermediate[2u];
45148 v_intermediate[26u] = v_intermediate[2u];
45149 v_intermediate[34u] = v_intermediate[2u];
45150 v_intermediate[42u] = v_intermediate[2u];
45151 v_intermediate[50u] = v_intermediate[2u];
45152 v_intermediate[58u] = v_intermediate[2u];
45153 } else {
45154 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]))));
45155 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]))));
45156 v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u));
45157 v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u))));
45158 v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u))));
45159 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]))));
45160 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]))));
45161 v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u));
45162 v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u));
45163 v_cd0 = ((uint32_t)(v_ccp + v_cb2));
45164 v_cd1 = ((uint32_t)(v_ccm + v_cb6));
45165 v_cd2 = ((uint32_t)(v_ccm - v_cb6));
45166 v_cd3 = ((uint32_t)(v_ccp - v_cb2));
45167 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]))));
45168 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]))));
45169 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]))));
45170 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]))));
45171 v_ci51 = ((uint32_t)(v_bq5 + v_bq1));
45172 v_ci53 = ((uint32_t)(v_bq5 + v_bq3));
45173 v_ci71 = ((uint32_t)(v_bq7 + v_bq1));
45174 v_ci73 = ((uint32_t)(v_bq7 + v_bq3));
45175 v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u));
45176 v_ck1 = ((uint32_t)(v_bq1 * 12299u));
45177 v_ck3 = ((uint32_t)(v_bq3 * 25172u));
45178 v_ck5 = ((uint32_t)(v_bq5 * 16819u));
45179 v_ck7 = ((uint32_t)(v_bq7 * 2446u));
45180 v_ci51 *= 4294964100u;
45181 v_ci53 *= 4294946301u;
45182 v_ci71 *= 4294959923u;
45183 v_ci73 *= 4294951227u;
45184 v_cl51 = ((uint32_t)(v_ci51 + v_cj));
45185 v_cl73 = ((uint32_t)(v_ci73 + v_cj));
45186 v_ck1 += ((uint32_t)(v_ci71 + v_cl51));
45187 v_ck3 += ((uint32_t)(v_ci53 + v_cl73));
45188 v_ck5 += ((uint32_t)(v_ci53 + v_cl51));
45189 v_ck7 += ((uint32_t)(v_ci71 + v_cl73));
45190 v_intermediate[2u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u);
45191 v_intermediate[58u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u);
45192 v_intermediate[10u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u);
45193 v_intermediate[50u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u);
45194 v_intermediate[18u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u);
45195 v_intermediate[42u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u);
45196 v_intermediate[26u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u);
45197 v_intermediate[34u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u);
45199 if (0u == (self->private_data.f_mcu_blocks[0u][11u] |
45200 self->private_data.f_mcu_blocks[0u][19u] |
45201 self->private_data.f_mcu_blocks[0u][27u] |
45202 self->private_data.f_mcu_blocks[0u][35u] |
45203 self->private_data.f_mcu_blocks[0u][43u] |
45204 self->private_data.f_mcu_blocks[0u][51u] |
45205 self->private_data.f_mcu_blocks[0u][59u])) {
45206 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));
45207 v_intermediate[11u] = v_intermediate[3u];
45208 v_intermediate[19u] = v_intermediate[3u];
45209 v_intermediate[27u] = v_intermediate[3u];
45210 v_intermediate[35u] = v_intermediate[3u];
45211 v_intermediate[43u] = v_intermediate[3u];
45212 v_intermediate[51u] = v_intermediate[3u];
45213 v_intermediate[59u] = v_intermediate[3u];
45214 } else {
45215 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]))));
45216 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]))));
45217 v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u));
45218 v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u))));
45219 v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u))));
45220 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]))));
45221 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]))));
45222 v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u));
45223 v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u));
45224 v_cd0 = ((uint32_t)(v_ccp + v_cb2));
45225 v_cd1 = ((uint32_t)(v_ccm + v_cb6));
45226 v_cd2 = ((uint32_t)(v_ccm - v_cb6));
45227 v_cd3 = ((uint32_t)(v_ccp - v_cb2));
45228 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]))));
45229 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]))));
45230 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]))));
45231 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]))));
45232 v_ci51 = ((uint32_t)(v_bq5 + v_bq1));
45233 v_ci53 = ((uint32_t)(v_bq5 + v_bq3));
45234 v_ci71 = ((uint32_t)(v_bq7 + v_bq1));
45235 v_ci73 = ((uint32_t)(v_bq7 + v_bq3));
45236 v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u));
45237 v_ck1 = ((uint32_t)(v_bq1 * 12299u));
45238 v_ck3 = ((uint32_t)(v_bq3 * 25172u));
45239 v_ck5 = ((uint32_t)(v_bq5 * 16819u));
45240 v_ck7 = ((uint32_t)(v_bq7 * 2446u));
45241 v_ci51 *= 4294964100u;
45242 v_ci53 *= 4294946301u;
45243 v_ci71 *= 4294959923u;
45244 v_ci73 *= 4294951227u;
45245 v_cl51 = ((uint32_t)(v_ci51 + v_cj));
45246 v_cl73 = ((uint32_t)(v_ci73 + v_cj));
45247 v_ck1 += ((uint32_t)(v_ci71 + v_cl51));
45248 v_ck3 += ((uint32_t)(v_ci53 + v_cl73));
45249 v_ck5 += ((uint32_t)(v_ci53 + v_cl51));
45250 v_ck7 += ((uint32_t)(v_ci71 + v_cl73));
45251 v_intermediate[3u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u);
45252 v_intermediate[59u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u);
45253 v_intermediate[11u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u);
45254 v_intermediate[51u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u);
45255 v_intermediate[19u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u);
45256 v_intermediate[43u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u);
45257 v_intermediate[27u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u);
45258 v_intermediate[35u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u);
45260 if (0u == (self->private_data.f_mcu_blocks[0u][12u] |
45261 self->private_data.f_mcu_blocks[0u][20u] |
45262 self->private_data.f_mcu_blocks[0u][28u] |
45263 self->private_data.f_mcu_blocks[0u][36u] |
45264 self->private_data.f_mcu_blocks[0u][44u] |
45265 self->private_data.f_mcu_blocks[0u][52u] |
45266 self->private_data.f_mcu_blocks[0u][60u])) {
45267 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));
45268 v_intermediate[12u] = v_intermediate[4u];
45269 v_intermediate[20u] = v_intermediate[4u];
45270 v_intermediate[28u] = v_intermediate[4u];
45271 v_intermediate[36u] = v_intermediate[4u];
45272 v_intermediate[44u] = v_intermediate[4u];
45273 v_intermediate[52u] = v_intermediate[4u];
45274 v_intermediate[60u] = v_intermediate[4u];
45275 } else {
45276 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]))));
45277 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]))));
45278 v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u));
45279 v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u))));
45280 v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u))));
45281 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]))));
45282 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]))));
45283 v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u));
45284 v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u));
45285 v_cd0 = ((uint32_t)(v_ccp + v_cb2));
45286 v_cd1 = ((uint32_t)(v_ccm + v_cb6));
45287 v_cd2 = ((uint32_t)(v_ccm - v_cb6));
45288 v_cd3 = ((uint32_t)(v_ccp - v_cb2));
45289 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]))));
45290 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]))));
45291 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]))));
45292 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]))));
45293 v_ci51 = ((uint32_t)(v_bq5 + v_bq1));
45294 v_ci53 = ((uint32_t)(v_bq5 + v_bq3));
45295 v_ci71 = ((uint32_t)(v_bq7 + v_bq1));
45296 v_ci73 = ((uint32_t)(v_bq7 + v_bq3));
45297 v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u));
45298 v_ck1 = ((uint32_t)(v_bq1 * 12299u));
45299 v_ck3 = ((uint32_t)(v_bq3 * 25172u));
45300 v_ck5 = ((uint32_t)(v_bq5 * 16819u));
45301 v_ck7 = ((uint32_t)(v_bq7 * 2446u));
45302 v_ci51 *= 4294964100u;
45303 v_ci53 *= 4294946301u;
45304 v_ci71 *= 4294959923u;
45305 v_ci73 *= 4294951227u;
45306 v_cl51 = ((uint32_t)(v_ci51 + v_cj));
45307 v_cl73 = ((uint32_t)(v_ci73 + v_cj));
45308 v_ck1 += ((uint32_t)(v_ci71 + v_cl51));
45309 v_ck3 += ((uint32_t)(v_ci53 + v_cl73));
45310 v_ck5 += ((uint32_t)(v_ci53 + v_cl51));
45311 v_ck7 += ((uint32_t)(v_ci71 + v_cl73));
45312 v_intermediate[4u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u);
45313 v_intermediate[60u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u);
45314 v_intermediate[12u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u);
45315 v_intermediate[52u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u);
45316 v_intermediate[20u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u);
45317 v_intermediate[44u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u);
45318 v_intermediate[28u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u);
45319 v_intermediate[36u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u);
45321 if (0u == (self->private_data.f_mcu_blocks[0u][13u] |
45322 self->private_data.f_mcu_blocks[0u][21u] |
45323 self->private_data.f_mcu_blocks[0u][29u] |
45324 self->private_data.f_mcu_blocks[0u][37u] |
45325 self->private_data.f_mcu_blocks[0u][45u] |
45326 self->private_data.f_mcu_blocks[0u][53u] |
45327 self->private_data.f_mcu_blocks[0u][61u])) {
45328 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));
45329 v_intermediate[13u] = v_intermediate[5u];
45330 v_intermediate[21u] = v_intermediate[5u];
45331 v_intermediate[29u] = v_intermediate[5u];
45332 v_intermediate[37u] = v_intermediate[5u];
45333 v_intermediate[45u] = v_intermediate[5u];
45334 v_intermediate[53u] = v_intermediate[5u];
45335 v_intermediate[61u] = v_intermediate[5u];
45336 } else {
45337 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]))));
45338 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]))));
45339 v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u));
45340 v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u))));
45341 v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u))));
45342 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]))));
45343 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]))));
45344 v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u));
45345 v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u));
45346 v_cd0 = ((uint32_t)(v_ccp + v_cb2));
45347 v_cd1 = ((uint32_t)(v_ccm + v_cb6));
45348 v_cd2 = ((uint32_t)(v_ccm - v_cb6));
45349 v_cd3 = ((uint32_t)(v_ccp - v_cb2));
45350 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]))));
45351 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]))));
45352 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]))));
45353 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]))));
45354 v_ci51 = ((uint32_t)(v_bq5 + v_bq1));
45355 v_ci53 = ((uint32_t)(v_bq5 + v_bq3));
45356 v_ci71 = ((uint32_t)(v_bq7 + v_bq1));
45357 v_ci73 = ((uint32_t)(v_bq7 + v_bq3));
45358 v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u));
45359 v_ck1 = ((uint32_t)(v_bq1 * 12299u));
45360 v_ck3 = ((uint32_t)(v_bq3 * 25172u));
45361 v_ck5 = ((uint32_t)(v_bq5 * 16819u));
45362 v_ck7 = ((uint32_t)(v_bq7 * 2446u));
45363 v_ci51 *= 4294964100u;
45364 v_ci53 *= 4294946301u;
45365 v_ci71 *= 4294959923u;
45366 v_ci73 *= 4294951227u;
45367 v_cl51 = ((uint32_t)(v_ci51 + v_cj));
45368 v_cl73 = ((uint32_t)(v_ci73 + v_cj));
45369 v_ck1 += ((uint32_t)(v_ci71 + v_cl51));
45370 v_ck3 += ((uint32_t)(v_ci53 + v_cl73));
45371 v_ck5 += ((uint32_t)(v_ci53 + v_cl51));
45372 v_ck7 += ((uint32_t)(v_ci71 + v_cl73));
45373 v_intermediate[5u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u);
45374 v_intermediate[61u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u);
45375 v_intermediate[13u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u);
45376 v_intermediate[53u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u);
45377 v_intermediate[21u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u);
45378 v_intermediate[45u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u);
45379 v_intermediate[29u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u);
45380 v_intermediate[37u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u);
45382 if (0u == (self->private_data.f_mcu_blocks[0u][14u] |
45383 self->private_data.f_mcu_blocks[0u][22u] |
45384 self->private_data.f_mcu_blocks[0u][30u] |
45385 self->private_data.f_mcu_blocks[0u][38u] |
45386 self->private_data.f_mcu_blocks[0u][46u] |
45387 self->private_data.f_mcu_blocks[0u][54u] |
45388 self->private_data.f_mcu_blocks[0u][62u])) {
45389 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));
45390 v_intermediate[14u] = v_intermediate[6u];
45391 v_intermediate[22u] = v_intermediate[6u];
45392 v_intermediate[30u] = v_intermediate[6u];
45393 v_intermediate[38u] = v_intermediate[6u];
45394 v_intermediate[46u] = v_intermediate[6u];
45395 v_intermediate[54u] = v_intermediate[6u];
45396 v_intermediate[62u] = v_intermediate[6u];
45397 } else {
45398 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]))));
45399 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]))));
45400 v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u));
45401 v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u))));
45402 v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u))));
45403 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]))));
45404 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]))));
45405 v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u));
45406 v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u));
45407 v_cd0 = ((uint32_t)(v_ccp + v_cb2));
45408 v_cd1 = ((uint32_t)(v_ccm + v_cb6));
45409 v_cd2 = ((uint32_t)(v_ccm - v_cb6));
45410 v_cd3 = ((uint32_t)(v_ccp - v_cb2));
45411 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]))));
45412 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]))));
45413 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]))));
45414 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]))));
45415 v_ci51 = ((uint32_t)(v_bq5 + v_bq1));
45416 v_ci53 = ((uint32_t)(v_bq5 + v_bq3));
45417 v_ci71 = ((uint32_t)(v_bq7 + v_bq1));
45418 v_ci73 = ((uint32_t)(v_bq7 + v_bq3));
45419 v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u));
45420 v_ck1 = ((uint32_t)(v_bq1 * 12299u));
45421 v_ck3 = ((uint32_t)(v_bq3 * 25172u));
45422 v_ck5 = ((uint32_t)(v_bq5 * 16819u));
45423 v_ck7 = ((uint32_t)(v_bq7 * 2446u));
45424 v_ci51 *= 4294964100u;
45425 v_ci53 *= 4294946301u;
45426 v_ci71 *= 4294959923u;
45427 v_ci73 *= 4294951227u;
45428 v_cl51 = ((uint32_t)(v_ci51 + v_cj));
45429 v_cl73 = ((uint32_t)(v_ci73 + v_cj));
45430 v_ck1 += ((uint32_t)(v_ci71 + v_cl51));
45431 v_ck3 += ((uint32_t)(v_ci53 + v_cl73));
45432 v_ck5 += ((uint32_t)(v_ci53 + v_cl51));
45433 v_ck7 += ((uint32_t)(v_ci71 + v_cl73));
45434 v_intermediate[6u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u);
45435 v_intermediate[62u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u);
45436 v_intermediate[14u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u);
45437 v_intermediate[54u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u);
45438 v_intermediate[22u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u);
45439 v_intermediate[46u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u);
45440 v_intermediate[30u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u);
45441 v_intermediate[38u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u);
45443 if (0u == (self->private_data.f_mcu_blocks[0u][15u] |
45444 self->private_data.f_mcu_blocks[0u][23u] |
45445 self->private_data.f_mcu_blocks[0u][31u] |
45446 self->private_data.f_mcu_blocks[0u][39u] |
45447 self->private_data.f_mcu_blocks[0u][47u] |
45448 self->private_data.f_mcu_blocks[0u][55u] |
45449 self->private_data.f_mcu_blocks[0u][63u])) {
45450 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));
45451 v_intermediate[15u] = v_intermediate[7u];
45452 v_intermediate[23u] = v_intermediate[7u];
45453 v_intermediate[31u] = v_intermediate[7u];
45454 v_intermediate[39u] = v_intermediate[7u];
45455 v_intermediate[47u] = v_intermediate[7u];
45456 v_intermediate[55u] = v_intermediate[7u];
45457 v_intermediate[63u] = v_intermediate[7u];
45458 } else {
45459 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]))));
45460 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]))));
45461 v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u));
45462 v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u))));
45463 v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u))));
45464 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]))));
45465 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]))));
45466 v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u));
45467 v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u));
45468 v_cd0 = ((uint32_t)(v_ccp + v_cb2));
45469 v_cd1 = ((uint32_t)(v_ccm + v_cb6));
45470 v_cd2 = ((uint32_t)(v_ccm - v_cb6));
45471 v_cd3 = ((uint32_t)(v_ccp - v_cb2));
45472 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]))));
45473 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]))));
45474 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]))));
45475 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]))));
45476 v_ci51 = ((uint32_t)(v_bq5 + v_bq1));
45477 v_ci53 = ((uint32_t)(v_bq5 + v_bq3));
45478 v_ci71 = ((uint32_t)(v_bq7 + v_bq1));
45479 v_ci73 = ((uint32_t)(v_bq7 + v_bq3));
45480 v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u));
45481 v_ck1 = ((uint32_t)(v_bq1 * 12299u));
45482 v_ck3 = ((uint32_t)(v_bq3 * 25172u));
45483 v_ck5 = ((uint32_t)(v_bq5 * 16819u));
45484 v_ck7 = ((uint32_t)(v_bq7 * 2446u));
45485 v_ci51 *= 4294964100u;
45486 v_ci53 *= 4294946301u;
45487 v_ci71 *= 4294959923u;
45488 v_ci73 *= 4294951227u;
45489 v_cl51 = ((uint32_t)(v_ci51 + v_cj));
45490 v_cl73 = ((uint32_t)(v_ci73 + v_cj));
45491 v_ck1 += ((uint32_t)(v_ci71 + v_cl51));
45492 v_ck3 += ((uint32_t)(v_ci53 + v_cl73));
45493 v_ck5 += ((uint32_t)(v_ci53 + v_cl51));
45494 v_ck7 += ((uint32_t)(v_ci71 + v_cl73));
45495 v_intermediate[7u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u);
45496 v_intermediate[63u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u);
45497 v_intermediate[15u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u);
45498 v_intermediate[55u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u);
45499 v_intermediate[23u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u);
45500 v_intermediate[47u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u);
45501 v_intermediate[31u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u);
45502 v_intermediate[39u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u);
45504 if (0u == (v_intermediate[1u] |
45505 v_intermediate[2u] |
45506 v_intermediate[3u] |
45507 v_intermediate[4u] |
45508 v_intermediate[5u] |
45509 v_intermediate[6u] |
45510 v_intermediate[7u])) {
45511 if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
45512 return wuffs_base__make_empty_struct();
45514 a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[0u] + 16u)) >> 5u) & 1023u)];
45515 a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u];
45516 a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u];
45517 a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u];
45518 a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u];
45519 a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u];
45520 a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u];
45521 a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u];
45522 a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
45523 } else {
45524 v_in2 = v_intermediate[2u];
45525 v_in6 = v_intermediate[6u];
45526 v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u));
45527 v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u))));
45528 v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u))));
45529 v_in0 = v_intermediate[0u];
45530 v_in4 = v_intermediate[4u];
45531 v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u));
45532 v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u));
45533 v_rd0 = ((uint32_t)(v_rcp + v_rb2));
45534 v_rd1 = ((uint32_t)(v_rcm + v_rb6));
45535 v_rd2 = ((uint32_t)(v_rcm - v_rb6));
45536 v_rd3 = ((uint32_t)(v_rcp - v_rb2));
45537 v_in1 = v_intermediate[1u];
45538 v_in3 = v_intermediate[3u];
45539 v_in5 = v_intermediate[5u];
45540 v_in7 = v_intermediate[7u];
45541 v_ri51 = ((uint32_t)(v_in5 + v_in1));
45542 v_ri53 = ((uint32_t)(v_in5 + v_in3));
45543 v_ri71 = ((uint32_t)(v_in7 + v_in1));
45544 v_ri73 = ((uint32_t)(v_in7 + v_in3));
45545 v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u));
45546 v_rk1 = ((uint32_t)(v_in1 * 12299u));
45547 v_rk3 = ((uint32_t)(v_in3 * 25172u));
45548 v_rk5 = ((uint32_t)(v_in5 * 16819u));
45549 v_rk7 = ((uint32_t)(v_in7 * 2446u));
45550 v_ri51 *= 4294964100u;
45551 v_ri53 *= 4294946301u;
45552 v_ri71 *= 4294959923u;
45553 v_ri73 *= 4294951227u;
45554 v_rl51 = ((uint32_t)(v_ri51 + v_rj));
45555 v_rl73 = ((uint32_t)(v_ri73 + v_rj));
45556 v_rk1 += ((uint32_t)(v_ri71 + v_rl51));
45557 v_rk3 += ((uint32_t)(v_ri53 + v_rl73));
45558 v_rk5 += ((uint32_t)(v_ri53 + v_rl51));
45559 v_rk7 += ((uint32_t)(v_ri71 + v_rl73));
45560 if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
45561 return wuffs_base__make_empty_struct();
45563 a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)];
45564 a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)];
45565 a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)];
45566 a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)];
45567 a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)];
45568 a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)];
45569 a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)];
45570 a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)];
45571 a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
45573 if (0u == (v_intermediate[9u] |
45574 v_intermediate[10u] |
45575 v_intermediate[11u] |
45576 v_intermediate[12u] |
45577 v_intermediate[13u] |
45578 v_intermediate[14u] |
45579 v_intermediate[15u])) {
45580 if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
45581 return wuffs_base__make_empty_struct();
45583 a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[8u] + 16u)) >> 5u) & 1023u)];
45584 a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u];
45585 a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u];
45586 a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u];
45587 a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u];
45588 a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u];
45589 a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u];
45590 a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u];
45591 a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
45592 } else {
45593 v_in2 = v_intermediate[10u];
45594 v_in6 = v_intermediate[14u];
45595 v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u));
45596 v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u))));
45597 v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u))));
45598 v_in0 = v_intermediate[8u];
45599 v_in4 = v_intermediate[12u];
45600 v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u));
45601 v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u));
45602 v_rd0 = ((uint32_t)(v_rcp + v_rb2));
45603 v_rd1 = ((uint32_t)(v_rcm + v_rb6));
45604 v_rd2 = ((uint32_t)(v_rcm - v_rb6));
45605 v_rd3 = ((uint32_t)(v_rcp - v_rb2));
45606 v_in1 = v_intermediate[9u];
45607 v_in3 = v_intermediate[11u];
45608 v_in5 = v_intermediate[13u];
45609 v_in7 = v_intermediate[15u];
45610 v_ri51 = ((uint32_t)(v_in5 + v_in1));
45611 v_ri53 = ((uint32_t)(v_in5 + v_in3));
45612 v_ri71 = ((uint32_t)(v_in7 + v_in1));
45613 v_ri73 = ((uint32_t)(v_in7 + v_in3));
45614 v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u));
45615 v_rk1 = ((uint32_t)(v_in1 * 12299u));
45616 v_rk3 = ((uint32_t)(v_in3 * 25172u));
45617 v_rk5 = ((uint32_t)(v_in5 * 16819u));
45618 v_rk7 = ((uint32_t)(v_in7 * 2446u));
45619 v_ri51 *= 4294964100u;
45620 v_ri53 *= 4294946301u;
45621 v_ri71 *= 4294959923u;
45622 v_ri73 *= 4294951227u;
45623 v_rl51 = ((uint32_t)(v_ri51 + v_rj));
45624 v_rl73 = ((uint32_t)(v_ri73 + v_rj));
45625 v_rk1 += ((uint32_t)(v_ri71 + v_rl51));
45626 v_rk3 += ((uint32_t)(v_ri53 + v_rl73));
45627 v_rk5 += ((uint32_t)(v_ri53 + v_rl51));
45628 v_rk7 += ((uint32_t)(v_ri71 + v_rl73));
45629 if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
45630 return wuffs_base__make_empty_struct();
45632 a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)];
45633 a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)];
45634 a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)];
45635 a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)];
45636 a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)];
45637 a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)];
45638 a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)];
45639 a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)];
45640 a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
45642 if (0u == (v_intermediate[17u] |
45643 v_intermediate[18u] |
45644 v_intermediate[19u] |
45645 v_intermediate[20u] |
45646 v_intermediate[21u] |
45647 v_intermediate[22u] |
45648 v_intermediate[23u])) {
45649 if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
45650 return wuffs_base__make_empty_struct();
45652 a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[16u] + 16u)) >> 5u) & 1023u)];
45653 a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u];
45654 a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u];
45655 a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u];
45656 a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u];
45657 a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u];
45658 a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u];
45659 a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u];
45660 a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
45661 } else {
45662 v_in2 = v_intermediate[18u];
45663 v_in6 = v_intermediate[22u];
45664 v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u));
45665 v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u))));
45666 v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u))));
45667 v_in0 = v_intermediate[16u];
45668 v_in4 = v_intermediate[20u];
45669 v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u));
45670 v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u));
45671 v_rd0 = ((uint32_t)(v_rcp + v_rb2));
45672 v_rd1 = ((uint32_t)(v_rcm + v_rb6));
45673 v_rd2 = ((uint32_t)(v_rcm - v_rb6));
45674 v_rd3 = ((uint32_t)(v_rcp - v_rb2));
45675 v_in1 = v_intermediate[17u];
45676 v_in3 = v_intermediate[19u];
45677 v_in5 = v_intermediate[21u];
45678 v_in7 = v_intermediate[23u];
45679 v_ri51 = ((uint32_t)(v_in5 + v_in1));
45680 v_ri53 = ((uint32_t)(v_in5 + v_in3));
45681 v_ri71 = ((uint32_t)(v_in7 + v_in1));
45682 v_ri73 = ((uint32_t)(v_in7 + v_in3));
45683 v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u));
45684 v_rk1 = ((uint32_t)(v_in1 * 12299u));
45685 v_rk3 = ((uint32_t)(v_in3 * 25172u));
45686 v_rk5 = ((uint32_t)(v_in5 * 16819u));
45687 v_rk7 = ((uint32_t)(v_in7 * 2446u));
45688 v_ri51 *= 4294964100u;
45689 v_ri53 *= 4294946301u;
45690 v_ri71 *= 4294959923u;
45691 v_ri73 *= 4294951227u;
45692 v_rl51 = ((uint32_t)(v_ri51 + v_rj));
45693 v_rl73 = ((uint32_t)(v_ri73 + v_rj));
45694 v_rk1 += ((uint32_t)(v_ri71 + v_rl51));
45695 v_rk3 += ((uint32_t)(v_ri53 + v_rl73));
45696 v_rk5 += ((uint32_t)(v_ri53 + v_rl51));
45697 v_rk7 += ((uint32_t)(v_ri71 + v_rl73));
45698 if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
45699 return wuffs_base__make_empty_struct();
45701 a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)];
45702 a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)];
45703 a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)];
45704 a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)];
45705 a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)];
45706 a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)];
45707 a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)];
45708 a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)];
45709 a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
45711 if (0u == (v_intermediate[25u] |
45712 v_intermediate[26u] |
45713 v_intermediate[27u] |
45714 v_intermediate[28u] |
45715 v_intermediate[29u] |
45716 v_intermediate[30u] |
45717 v_intermediate[31u])) {
45718 if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
45719 return wuffs_base__make_empty_struct();
45721 a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[24u] + 16u)) >> 5u) & 1023u)];
45722 a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u];
45723 a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u];
45724 a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u];
45725 a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u];
45726 a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u];
45727 a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u];
45728 a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u];
45729 a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
45730 } else {
45731 v_in2 = v_intermediate[26u];
45732 v_in6 = v_intermediate[30u];
45733 v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u));
45734 v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u))));
45735 v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u))));
45736 v_in0 = v_intermediate[24u];
45737 v_in4 = v_intermediate[28u];
45738 v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u));
45739 v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u));
45740 v_rd0 = ((uint32_t)(v_rcp + v_rb2));
45741 v_rd1 = ((uint32_t)(v_rcm + v_rb6));
45742 v_rd2 = ((uint32_t)(v_rcm - v_rb6));
45743 v_rd3 = ((uint32_t)(v_rcp - v_rb2));
45744 v_in1 = v_intermediate[25u];
45745 v_in3 = v_intermediate[27u];
45746 v_in5 = v_intermediate[29u];
45747 v_in7 = v_intermediate[31u];
45748 v_ri51 = ((uint32_t)(v_in5 + v_in1));
45749 v_ri53 = ((uint32_t)(v_in5 + v_in3));
45750 v_ri71 = ((uint32_t)(v_in7 + v_in1));
45751 v_ri73 = ((uint32_t)(v_in7 + v_in3));
45752 v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u));
45753 v_rk1 = ((uint32_t)(v_in1 * 12299u));
45754 v_rk3 = ((uint32_t)(v_in3 * 25172u));
45755 v_rk5 = ((uint32_t)(v_in5 * 16819u));
45756 v_rk7 = ((uint32_t)(v_in7 * 2446u));
45757 v_ri51 *= 4294964100u;
45758 v_ri53 *= 4294946301u;
45759 v_ri71 *= 4294959923u;
45760 v_ri73 *= 4294951227u;
45761 v_rl51 = ((uint32_t)(v_ri51 + v_rj));
45762 v_rl73 = ((uint32_t)(v_ri73 + v_rj));
45763 v_rk1 += ((uint32_t)(v_ri71 + v_rl51));
45764 v_rk3 += ((uint32_t)(v_ri53 + v_rl73));
45765 v_rk5 += ((uint32_t)(v_ri53 + v_rl51));
45766 v_rk7 += ((uint32_t)(v_ri71 + v_rl73));
45767 if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
45768 return wuffs_base__make_empty_struct();
45770 a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)];
45771 a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)];
45772 a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)];
45773 a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)];
45774 a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)];
45775 a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)];
45776 a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)];
45777 a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)];
45778 a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
45780 if (0u == (v_intermediate[33u] |
45781 v_intermediate[34u] |
45782 v_intermediate[35u] |
45783 v_intermediate[36u] |
45784 v_intermediate[37u] |
45785 v_intermediate[38u] |
45786 v_intermediate[39u])) {
45787 if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
45788 return wuffs_base__make_empty_struct();
45790 a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[32u] + 16u)) >> 5u) & 1023u)];
45791 a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u];
45792 a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u];
45793 a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u];
45794 a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u];
45795 a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u];
45796 a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u];
45797 a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u];
45798 a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
45799 } else {
45800 v_in2 = v_intermediate[34u];
45801 v_in6 = v_intermediate[38u];
45802 v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u));
45803 v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u))));
45804 v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u))));
45805 v_in0 = v_intermediate[32u];
45806 v_in4 = v_intermediate[36u];
45807 v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u));
45808 v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u));
45809 v_rd0 = ((uint32_t)(v_rcp + v_rb2));
45810 v_rd1 = ((uint32_t)(v_rcm + v_rb6));
45811 v_rd2 = ((uint32_t)(v_rcm - v_rb6));
45812 v_rd3 = ((uint32_t)(v_rcp - v_rb2));
45813 v_in1 = v_intermediate[33u];
45814 v_in3 = v_intermediate[35u];
45815 v_in5 = v_intermediate[37u];
45816 v_in7 = v_intermediate[39u];
45817 v_ri51 = ((uint32_t)(v_in5 + v_in1));
45818 v_ri53 = ((uint32_t)(v_in5 + v_in3));
45819 v_ri71 = ((uint32_t)(v_in7 + v_in1));
45820 v_ri73 = ((uint32_t)(v_in7 + v_in3));
45821 v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u));
45822 v_rk1 = ((uint32_t)(v_in1 * 12299u));
45823 v_rk3 = ((uint32_t)(v_in3 * 25172u));
45824 v_rk5 = ((uint32_t)(v_in5 * 16819u));
45825 v_rk7 = ((uint32_t)(v_in7 * 2446u));
45826 v_ri51 *= 4294964100u;
45827 v_ri53 *= 4294946301u;
45828 v_ri71 *= 4294959923u;
45829 v_ri73 *= 4294951227u;
45830 v_rl51 = ((uint32_t)(v_ri51 + v_rj));
45831 v_rl73 = ((uint32_t)(v_ri73 + v_rj));
45832 v_rk1 += ((uint32_t)(v_ri71 + v_rl51));
45833 v_rk3 += ((uint32_t)(v_ri53 + v_rl73));
45834 v_rk5 += ((uint32_t)(v_ri53 + v_rl51));
45835 v_rk7 += ((uint32_t)(v_ri71 + v_rl73));
45836 if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
45837 return wuffs_base__make_empty_struct();
45839 a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)];
45840 a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)];
45841 a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)];
45842 a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)];
45843 a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)];
45844 a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)];
45845 a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)];
45846 a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)];
45847 a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
45849 if (0u == (v_intermediate[41u] |
45850 v_intermediate[42u] |
45851 v_intermediate[43u] |
45852 v_intermediate[44u] |
45853 v_intermediate[45u] |
45854 v_intermediate[46u] |
45855 v_intermediate[47u])) {
45856 if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
45857 return wuffs_base__make_empty_struct();
45859 a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[40u] + 16u)) >> 5u) & 1023u)];
45860 a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u];
45861 a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u];
45862 a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u];
45863 a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u];
45864 a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u];
45865 a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u];
45866 a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u];
45867 a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
45868 } else {
45869 v_in2 = v_intermediate[42u];
45870 v_in6 = v_intermediate[46u];
45871 v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u));
45872 v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u))));
45873 v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u))));
45874 v_in0 = v_intermediate[40u];
45875 v_in4 = v_intermediate[44u];
45876 v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u));
45877 v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u));
45878 v_rd0 = ((uint32_t)(v_rcp + v_rb2));
45879 v_rd1 = ((uint32_t)(v_rcm + v_rb6));
45880 v_rd2 = ((uint32_t)(v_rcm - v_rb6));
45881 v_rd3 = ((uint32_t)(v_rcp - v_rb2));
45882 v_in1 = v_intermediate[41u];
45883 v_in3 = v_intermediate[43u];
45884 v_in5 = v_intermediate[45u];
45885 v_in7 = v_intermediate[47u];
45886 v_ri51 = ((uint32_t)(v_in5 + v_in1));
45887 v_ri53 = ((uint32_t)(v_in5 + v_in3));
45888 v_ri71 = ((uint32_t)(v_in7 + v_in1));
45889 v_ri73 = ((uint32_t)(v_in7 + v_in3));
45890 v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u));
45891 v_rk1 = ((uint32_t)(v_in1 * 12299u));
45892 v_rk3 = ((uint32_t)(v_in3 * 25172u));
45893 v_rk5 = ((uint32_t)(v_in5 * 16819u));
45894 v_rk7 = ((uint32_t)(v_in7 * 2446u));
45895 v_ri51 *= 4294964100u;
45896 v_ri53 *= 4294946301u;
45897 v_ri71 *= 4294959923u;
45898 v_ri73 *= 4294951227u;
45899 v_rl51 = ((uint32_t)(v_ri51 + v_rj));
45900 v_rl73 = ((uint32_t)(v_ri73 + v_rj));
45901 v_rk1 += ((uint32_t)(v_ri71 + v_rl51));
45902 v_rk3 += ((uint32_t)(v_ri53 + v_rl73));
45903 v_rk5 += ((uint32_t)(v_ri53 + v_rl51));
45904 v_rk7 += ((uint32_t)(v_ri71 + v_rl73));
45905 if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
45906 return wuffs_base__make_empty_struct();
45908 a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)];
45909 a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)];
45910 a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)];
45911 a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)];
45912 a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)];
45913 a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)];
45914 a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)];
45915 a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)];
45916 a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
45918 if (0u == (v_intermediate[49u] |
45919 v_intermediate[50u] |
45920 v_intermediate[51u] |
45921 v_intermediate[52u] |
45922 v_intermediate[53u] |
45923 v_intermediate[54u] |
45924 v_intermediate[55u])) {
45925 if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
45926 return wuffs_base__make_empty_struct();
45928 a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[48u] + 16u)) >> 5u) & 1023u)];
45929 a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u];
45930 a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u];
45931 a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u];
45932 a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u];
45933 a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u];
45934 a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u];
45935 a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u];
45936 a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
45937 } else {
45938 v_in2 = v_intermediate[50u];
45939 v_in6 = v_intermediate[54u];
45940 v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u));
45941 v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u))));
45942 v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u))));
45943 v_in0 = v_intermediate[48u];
45944 v_in4 = v_intermediate[52u];
45945 v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u));
45946 v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u));
45947 v_rd0 = ((uint32_t)(v_rcp + v_rb2));
45948 v_rd1 = ((uint32_t)(v_rcm + v_rb6));
45949 v_rd2 = ((uint32_t)(v_rcm - v_rb6));
45950 v_rd3 = ((uint32_t)(v_rcp - v_rb2));
45951 v_in1 = v_intermediate[49u];
45952 v_in3 = v_intermediate[51u];
45953 v_in5 = v_intermediate[53u];
45954 v_in7 = v_intermediate[55u];
45955 v_ri51 = ((uint32_t)(v_in5 + v_in1));
45956 v_ri53 = ((uint32_t)(v_in5 + v_in3));
45957 v_ri71 = ((uint32_t)(v_in7 + v_in1));
45958 v_ri73 = ((uint32_t)(v_in7 + v_in3));
45959 v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u));
45960 v_rk1 = ((uint32_t)(v_in1 * 12299u));
45961 v_rk3 = ((uint32_t)(v_in3 * 25172u));
45962 v_rk5 = ((uint32_t)(v_in5 * 16819u));
45963 v_rk7 = ((uint32_t)(v_in7 * 2446u));
45964 v_ri51 *= 4294964100u;
45965 v_ri53 *= 4294946301u;
45966 v_ri71 *= 4294959923u;
45967 v_ri73 *= 4294951227u;
45968 v_rl51 = ((uint32_t)(v_ri51 + v_rj));
45969 v_rl73 = ((uint32_t)(v_ri73 + v_rj));
45970 v_rk1 += ((uint32_t)(v_ri71 + v_rl51));
45971 v_rk3 += ((uint32_t)(v_ri53 + v_rl73));
45972 v_rk5 += ((uint32_t)(v_ri53 + v_rl51));
45973 v_rk7 += ((uint32_t)(v_ri71 + v_rl73));
45974 if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
45975 return wuffs_base__make_empty_struct();
45977 a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)];
45978 a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)];
45979 a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)];
45980 a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)];
45981 a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)];
45982 a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)];
45983 a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)];
45984 a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)];
45985 a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
45987 if (0u == (v_intermediate[57u] |
45988 v_intermediate[58u] |
45989 v_intermediate[59u] |
45990 v_intermediate[60u] |
45991 v_intermediate[61u] |
45992 v_intermediate[62u] |
45993 v_intermediate[63u])) {
45994 if (8u > ((uint64_t)(a_dst_buffer.len))) {
45995 return wuffs_base__make_empty_struct();
45997 a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[56u] + 16u)) >> 5u) & 1023u)];
45998 a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u];
45999 a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u];
46000 a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u];
46001 a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u];
46002 a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u];
46003 a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u];
46004 a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u];
46005 } else {
46006 v_in2 = v_intermediate[58u];
46007 v_in6 = v_intermediate[62u];
46008 v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u));
46009 v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u))));
46010 v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u))));
46011 v_in0 = v_intermediate[56u];
46012 v_in4 = v_intermediate[60u];
46013 v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u));
46014 v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u));
46015 v_rd0 = ((uint32_t)(v_rcp + v_rb2));
46016 v_rd1 = ((uint32_t)(v_rcm + v_rb6));
46017 v_rd2 = ((uint32_t)(v_rcm - v_rb6));
46018 v_rd3 = ((uint32_t)(v_rcp - v_rb2));
46019 v_in1 = v_intermediate[57u];
46020 v_in3 = v_intermediate[59u];
46021 v_in5 = v_intermediate[61u];
46022 v_in7 = v_intermediate[63u];
46023 v_ri51 = ((uint32_t)(v_in5 + v_in1));
46024 v_ri53 = ((uint32_t)(v_in5 + v_in3));
46025 v_ri71 = ((uint32_t)(v_in7 + v_in1));
46026 v_ri73 = ((uint32_t)(v_in7 + v_in3));
46027 v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u));
46028 v_rk1 = ((uint32_t)(v_in1 * 12299u));
46029 v_rk3 = ((uint32_t)(v_in3 * 25172u));
46030 v_rk5 = ((uint32_t)(v_in5 * 16819u));
46031 v_rk7 = ((uint32_t)(v_in7 * 2446u));
46032 v_ri51 *= 4294964100u;
46033 v_ri53 *= 4294946301u;
46034 v_ri71 *= 4294959923u;
46035 v_ri73 *= 4294951227u;
46036 v_rl51 = ((uint32_t)(v_ri51 + v_rj));
46037 v_rl73 = ((uint32_t)(v_ri73 + v_rj));
46038 v_rk1 += ((uint32_t)(v_ri71 + v_rl51));
46039 v_rk3 += ((uint32_t)(v_ri53 + v_rl73));
46040 v_rk5 += ((uint32_t)(v_ri53 + v_rl51));
46041 v_rk7 += ((uint32_t)(v_ri71 + v_rl73));
46042 if (8u > ((uint64_t)(a_dst_buffer.len))) {
46043 return wuffs_base__make_empty_struct();
46045 a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)];
46046 a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)];
46047 a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)];
46048 a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)];
46049 a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)];
46050 a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)];
46051 a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)];
46052 a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)];
46054 return wuffs_base__make_empty_struct();
46057 // ‼ WUFFS MULTI-FILE SECTION +x86_avx2
46058 // -------- func jpeg.decoder.decode_idct_x86_avx2
46060 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3)
46061 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2")
46062 WUFFS_BASE__GENERATED_C_CODE
46063 static wuffs_base__empty_struct
46064 wuffs_jpeg__decoder__decode_idct_x86_avx2(
46065 wuffs_jpeg__decoder* self,
46066 wuffs_base__slice_u8 a_dst_buffer,
46067 uint64_t a_dst_stride,
46068 uint32_t a_q) {
46069 __m256i v_k_0000 = {0};
46070 __m256i v_k_8080 = {0};
46071 __m256i v_k_0000_0002 = {0};
46072 __m256i v_k_0001_FFFF = {0};
46073 __m256i v_k_0400_0000 = {0};
46074 __m256i v_k_29CF_1151_D630_1151 = {0};
46075 __m256i v_k_E333_133E_ADFD_1051 = {0};
46076 __m256i v_k_E6DC_25A1_1925_25A1 = {0};
46077 __m256i v_k_ECC1_E333_EFB0_ADFD = {0};
46078 __m128i v_az_coeffs = {0};
46079 __m256i v_az_ah00 = {0};
46080 __m256i v_az_ad00 = {0};
46081 __m256i v_az_eh00 = {0};
46082 __m256i v_az_adeh = {0};
46083 __m256i v_rows01 = {0};
46084 __m256i v_rows23 = {0};
46085 __m256i v_rows45 = {0};
46086 __m256i v_rows67 = {0};
46087 __m256i v_quants01 = {0};
46088 __m256i v_quants23 = {0};
46089 __m256i v_quants45 = {0};
46090 __m256i v_quants67 = {0};
46091 __m256i v_rows04 = {0};
46092 __m256i v_rows31 = {0};
46093 __m256i v_rows26 = {0};
46094 __m256i v_rows75 = {0};
46095 __m256i v_fp_rows62 = {0};
46096 __m256i v_fp_bq2662ad = {0};
46097 __m256i v_fp_bq2662eh = {0};
46098 __m256i v_fp_cb26ad = {0};
46099 __m256i v_fp_cb26eh = {0};
46100 __m256i v_fp_rows40pos = {0};
46101 __m256i v_fp_rows04neg = {0};
46102 __m256i v_fp_rows0pm4 = {0};
46103 __m256i v_fp_ccpmad = {0};
46104 __m256i v_fp_ccpmeh = {0};
46105 __m256i v_fp_cd01ad = {0};
46106 __m256i v_fp_cd01eh = {0};
46107 __m256i v_fp_cd32ad = {0};
46108 __m256i v_fp_cd32eh = {0};
46109 __m256i v_fp_sums7351 = {0};
46110 __m256i v_fp_sums5173 = {0};
46111 __m256i v_fp_ci73515173ad = {0};
46112 __m256i v_fp_ci73515173eh = {0};
46113 __m256i v_fp_cl7351ad = {0};
46114 __m256i v_fp_cl7351eh = {0};
46115 __m256i v_fp_rows13 = {0};
46116 __m256i v_fp_bq7153ad = {0};
46117 __m256i v_fp_bq7153eh = {0};
46118 __m256i v_fp_ck75ad = {0};
46119 __m256i v_fp_ck75eh = {0};
46120 __m256i v_fp_cl5173ad = {0};
46121 __m256i v_fp_cl5173eh = {0};
46122 __m256i v_fp_ck13ad = {0};
46123 __m256i v_fp_ck13eh = {0};
46124 __m256i v_intermediate01ad = {0};
46125 __m256i v_intermediate01eh = {0};
46126 __m256i v_intermediate01 = {0};
46127 __m256i v_intermediate32ad = {0};
46128 __m256i v_intermediate32eh = {0};
46129 __m256i v_intermediate32 = {0};
46130 __m256i v_intermediate45ad = {0};
46131 __m256i v_intermediate45eh = {0};
46132 __m256i v_intermediate45 = {0};
46133 __m256i v_intermediate76ad = {0};
46134 __m256i v_intermediate76eh = {0};
46135 __m256i v_intermediate76 = {0};
46136 __m256i v_ita0a1e0e1 = {0};
46137 __m256i v_ita2a3e2e3 = {0};
46138 __m256i v_ita4a5e4e5 = {0};
46139 __m256i v_ita6a7e6e7 = {0};
46140 __m256i v_ita0c0e0g0 = {0};
46141 __m256i v_ita1c1e1g1 = {0};
46142 __m256i v_ita4c4e4g4 = {0};
46143 __m256i v_ita5c5e5g5 = {0};
46144 __m256i v_ita0b0e0f0 = {0};
46145 __m256i v_ita4b4e4f4 = {0};
46146 __m256i v_itc0d0g0h0 = {0};
46147 __m256i v_itc4d4g4h4 = {0};
46148 __m256i v_intermediateae = {0};
46149 __m256i v_intermediatebf = {0};
46150 __m256i v_intermediatecg = {0};
46151 __m256i v_intermediatedh = {0};
46152 __m256i v_intermediatedb = {0};
46153 __m256i v_intermediatehf = {0};
46154 __m256i v_sp_cols62 = {0};
46155 __m256i v_sp_bq2662ad = {0};
46156 __m256i v_sp_bq2662eh = {0};
46157 __m256i v_sp_rb26ad = {0};
46158 __m256i v_sp_rb26eh = {0};
46159 __m256i v_sp_cols40pos = {0};
46160 __m256i v_sp_cols04neg = {0};
46161 __m256i v_sp_cols0pm4 = {0};
46162 __m256i v_sp_rcpmad = {0};
46163 __m256i v_sp_rcpmeh = {0};
46164 __m256i v_sp_rd01ad = {0};
46165 __m256i v_sp_rd01eh = {0};
46166 __m256i v_sp_rd32ad = {0};
46167 __m256i v_sp_rd32eh = {0};
46168 __m256i v_sp_sums7351 = {0};
46169 __m256i v_sp_sums5173 = {0};
46170 __m256i v_sp_ri73515173ad = {0};
46171 __m256i v_sp_ri73515173eh = {0};
46172 __m256i v_sp_rl7351ad = {0};
46173 __m256i v_sp_rl7351eh = {0};
46174 __m256i v_sp_cols13 = {0};
46175 __m256i v_sp_bq7153ad = {0};
46176 __m256i v_sp_bq7153eh = {0};
46177 __m256i v_sp_rk75ad = {0};
46178 __m256i v_sp_rk75eh = {0};
46179 __m256i v_sp_rl5173ad = {0};
46180 __m256i v_sp_rl5173eh = {0};
46181 __m256i v_sp_rk13ad = {0};
46182 __m256i v_sp_rk13eh = {0};
46183 __m256i v_final01ad = {0};
46184 __m256i v_final01eh = {0};
46185 __m256i v_final01 = {0};
46186 __m256i v_final32ad = {0};
46187 __m256i v_final32eh = {0};
46188 __m256i v_final32 = {0};
46189 __m256i v_final45ad = {0};
46190 __m256i v_final45eh = {0};
46191 __m256i v_final45 = {0};
46192 __m256i v_final76ad = {0};
46193 __m256i v_final76eh = {0};
46194 __m256i v_final76 = {0};
46195 __m256i v_fta0a1e0e1 = {0};
46196 __m256i v_fta2a3e2e3 = {0};
46197 __m256i v_fta4a5e4e5 = {0};
46198 __m256i v_fta6a7e6e7 = {0};
46199 __m256i v_fta0c0e0g0 = {0};
46200 __m256i v_fta1c1e1g1 = {0};
46201 __m256i v_fta4c4e4g4 = {0};
46202 __m256i v_fta5c5e5g5 = {0};
46203 __m256i v_fta0b0e0f0 = {0};
46204 __m256i v_ftc0d0g0h0 = {0};
46205 __m256i v_fta4b4e4f4 = {0};
46206 __m256i v_ftc4d4g4h4 = {0};
46207 __m256i v_finalae = {0};
46208 __m256i v_finalbf = {0};
46209 __m256i v_finalcg = {0};
46210 __m256i v_finaldh = {0};
46211 __m256i v_final0145 = {0};
46212 __m256i v_final2367 = {0};
46213 uint64_t v_final0 = 0;
46214 uint64_t v_final1 = 0;
46215 uint64_t v_final2 = 0;
46216 uint64_t v_final3 = 0;
46217 uint64_t v_final4 = 0;
46218 uint64_t v_final5 = 0;
46219 uint64_t v_final6 = 0;
46220 uint64_t v_final7 = 0;
46221 wuffs_base__slice_u8 v_remaining = {0};
46223 if (8u > a_dst_stride) {
46224 return wuffs_base__make_empty_struct();
46226 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));
46227 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));
46228 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));
46229 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));
46230 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));
46231 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));
46232 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));
46233 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));
46234 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));
46235 do {
46236 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)))) {
46237 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)));
46238 if (0u == ((uint64_t)(_mm_cvtsi128_si64(_mm_packs_epi16(v_az_coeffs, v_az_coeffs))))) {
46239 v_rows01 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 0u));
46240 v_quants01 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_impl.f_quant_tables[a_q] + 0u));
46241 v_rows01 = _mm256_mullo_epi16(v_rows01, v_quants01);
46242 v_az_ah00 = _mm256_slli_epi16(v_rows01, (int32_t)(2u));
46243 v_az_ad00 = _mm256_unpacklo_epi16(v_az_ah00, v_az_ah00);
46244 v_az_eh00 = _mm256_unpackhi_epi16(v_az_ah00, v_az_ah00);
46245 v_az_adeh = _mm256_inserti128_si256(v_az_ad00, _mm256_castsi256_si128(v_az_eh00), (int32_t)(1u));
46246 v_intermediateae = _mm256_shuffle_epi32(v_az_adeh, (int32_t)(0u));
46247 v_intermediatebf = _mm256_shuffle_epi32(v_az_adeh, (int32_t)(85u));
46248 v_intermediatecg = _mm256_shuffle_epi32(v_az_adeh, (int32_t)(170u));
46249 v_intermediatedh = _mm256_shuffle_epi32(v_az_adeh, (int32_t)(255u));
46250 break;
46253 v_rows01 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 0u));
46254 v_rows23 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 16u));
46255 v_rows45 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 32u));
46256 v_rows67 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 48u));
46257 v_quants01 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_impl.f_quant_tables[a_q] + 0u));
46258 v_quants23 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_impl.f_quant_tables[a_q] + 16u));
46259 v_quants45 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_impl.f_quant_tables[a_q] + 32u));
46260 v_quants67 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_impl.f_quant_tables[a_q] + 48u));
46261 v_rows01 = _mm256_mullo_epi16(v_rows01, v_quants01);
46262 v_rows23 = _mm256_mullo_epi16(v_rows23, v_quants23);
46263 v_rows45 = _mm256_mullo_epi16(v_rows45, v_quants45);
46264 v_rows67 = _mm256_mullo_epi16(v_rows67, v_quants67);
46265 v_rows04 = _mm256_permute2x128_si256(v_rows01, v_rows45, (int32_t)(32u));
46266 v_rows31 = _mm256_permute2x128_si256(v_rows23, v_rows01, (int32_t)(49u));
46267 v_rows26 = _mm256_permute2x128_si256(v_rows23, v_rows67, (int32_t)(32u));
46268 v_rows75 = _mm256_permute2x128_si256(v_rows67, v_rows45, (int32_t)(49u));
46269 v_fp_rows62 = _mm256_permute2x128_si256(v_rows26, v_rows26, (int32_t)(1u));
46270 v_fp_bq2662ad = _mm256_unpacklo_epi16(v_rows26, v_fp_rows62);
46271 v_fp_bq2662eh = _mm256_unpackhi_epi16(v_rows26, v_fp_rows62);
46272 v_fp_cb26ad = _mm256_madd_epi16(v_fp_bq2662ad, v_k_29CF_1151_D630_1151);
46273 v_fp_cb26eh = _mm256_madd_epi16(v_fp_bq2662eh, v_k_29CF_1151_D630_1151);
46274 v_fp_rows40pos = _mm256_permute2x128_si256(v_rows04, v_rows04, (int32_t)(1u));
46275 v_fp_rows04neg = _mm256_sign_epi16(v_rows04, v_k_0001_FFFF);
46276 v_fp_rows0pm4 = _mm256_add_epi16(v_fp_rows40pos, v_fp_rows04neg);
46277 v_fp_ccpmad = _mm256_srai_epi32(_mm256_unpacklo_epi16(v_k_0000, v_fp_rows0pm4), (int32_t)(3u));
46278 v_fp_ccpmeh = _mm256_srai_epi32(_mm256_unpackhi_epi16(v_k_0000, v_fp_rows0pm4), (int32_t)(3u));
46279 v_fp_cd01ad = _mm256_add_epi32(v_fp_ccpmad, v_fp_cb26ad);
46280 v_fp_cd01eh = _mm256_add_epi32(v_fp_ccpmeh, v_fp_cb26eh);
46281 v_fp_cd32ad = _mm256_sub_epi32(v_fp_ccpmad, v_fp_cb26ad);
46282 v_fp_cd32eh = _mm256_sub_epi32(v_fp_ccpmeh, v_fp_cb26eh);
46283 v_fp_sums7351 = _mm256_add_epi16(v_rows75, v_rows31);
46284 v_fp_sums5173 = _mm256_permute2x128_si256(v_fp_sums7351, v_fp_sums7351, (int32_t)(1u));
46285 v_fp_ci73515173ad = _mm256_unpacklo_epi16(v_fp_sums7351, v_fp_sums5173);
46286 v_fp_ci73515173eh = _mm256_unpackhi_epi16(v_fp_sums7351, v_fp_sums5173);
46287 v_fp_cl7351ad = _mm256_madd_epi16(v_fp_ci73515173ad, v_k_E6DC_25A1_1925_25A1);
46288 v_fp_cl7351eh = _mm256_madd_epi16(v_fp_ci73515173eh, v_k_E6DC_25A1_1925_25A1);
46289 v_fp_rows13 = _mm256_permute2x128_si256(v_rows31, v_rows31, (int32_t)(1u));
46290 v_fp_bq7153ad = _mm256_unpacklo_epi16(v_rows75, v_fp_rows13);
46291 v_fp_bq7153eh = _mm256_unpackhi_epi16(v_rows75, v_fp_rows13);
46292 v_fp_ck75ad = _mm256_add_epi32(_mm256_madd_epi16(v_fp_bq7153ad, v_k_ECC1_E333_EFB0_ADFD), v_fp_cl7351ad);
46293 v_fp_ck75eh = _mm256_add_epi32(_mm256_madd_epi16(v_fp_bq7153eh, v_k_ECC1_E333_EFB0_ADFD), v_fp_cl7351eh);
46294 v_fp_cl5173ad = _mm256_permute2x128_si256(v_fp_cl7351ad, v_fp_cl7351ad, (int32_t)(1u));
46295 v_fp_cl5173eh = _mm256_permute2x128_si256(v_fp_cl7351eh, v_fp_cl7351eh, (int32_t)(1u));
46296 v_fp_ck13ad = _mm256_add_epi32(v_fp_cl5173ad, _mm256_madd_epi16(v_fp_bq7153ad, v_k_E333_133E_ADFD_1051));
46297 v_fp_ck13eh = _mm256_add_epi32(v_fp_cl5173eh, _mm256_madd_epi16(v_fp_bq7153eh, v_k_E333_133E_ADFD_1051));
46298 v_intermediate01ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_fp_cd01ad, v_fp_ck13ad), v_k_0400_0000), (int32_t)(11u));
46299 v_intermediate01eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_fp_cd01eh, v_fp_ck13eh), v_k_0400_0000), (int32_t)(11u));
46300 v_intermediate01 = _mm256_packs_epi32(v_intermediate01ad, v_intermediate01eh);
46301 v_intermediate32ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_fp_cd32ad, v_fp_ck75ad), v_k_0400_0000), (int32_t)(11u));
46302 v_intermediate32eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_fp_cd32eh, v_fp_ck75eh), v_k_0400_0000), (int32_t)(11u));
46303 v_intermediate32 = _mm256_packs_epi32(v_intermediate32ad, v_intermediate32eh);
46304 v_intermediate45ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_fp_cd32ad, v_fp_ck75ad), v_k_0400_0000), (int32_t)(11u));
46305 v_intermediate45eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_fp_cd32eh, v_fp_ck75eh), v_k_0400_0000), (int32_t)(11u));
46306 v_intermediate45 = _mm256_packs_epi32(v_intermediate45ad, v_intermediate45eh);
46307 v_intermediate76ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_fp_cd01ad, v_fp_ck13ad), v_k_0400_0000), (int32_t)(11u));
46308 v_intermediate76eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_fp_cd01eh, v_fp_ck13eh), v_k_0400_0000), (int32_t)(11u));
46309 v_intermediate76 = _mm256_packs_epi32(v_intermediate76ad, v_intermediate76eh);
46310 v_ita0a1e0e1 = _mm256_permute4x64_epi64(v_intermediate01, (int32_t)(216u));
46311 v_ita2a3e2e3 = _mm256_permute4x64_epi64(v_intermediate32, (int32_t)(114u));
46312 v_ita4a5e4e5 = _mm256_permute4x64_epi64(v_intermediate45, (int32_t)(216u));
46313 v_ita6a7e6e7 = _mm256_permute4x64_epi64(v_intermediate76, (int32_t)(114u));
46314 v_ita0c0e0g0 = _mm256_unpacklo_epi16(v_ita0a1e0e1, v_ita2a3e2e3);
46315 v_ita1c1e1g1 = _mm256_unpackhi_epi16(v_ita0a1e0e1, v_ita2a3e2e3);
46316 v_ita4c4e4g4 = _mm256_unpacklo_epi16(v_ita4a5e4e5, v_ita6a7e6e7);
46317 v_ita5c5e5g5 = _mm256_unpackhi_epi16(v_ita4a5e4e5, v_ita6a7e6e7);
46318 v_ita0b0e0f0 = _mm256_unpacklo_epi16(v_ita0c0e0g0, v_ita1c1e1g1);
46319 v_itc0d0g0h0 = _mm256_unpackhi_epi16(v_ita0c0e0g0, v_ita1c1e1g1);
46320 v_ita4b4e4f4 = _mm256_unpacklo_epi16(v_ita4c4e4g4, v_ita5c5e5g5);
46321 v_itc4d4g4h4 = _mm256_unpackhi_epi16(v_ita4c4e4g4, v_ita5c5e5g5);
46322 v_intermediateae = _mm256_unpacklo_epi64(v_ita0b0e0f0, v_ita4b4e4f4);
46323 v_intermediatebf = _mm256_unpackhi_epi64(v_ita0b0e0f0, v_ita4b4e4f4);
46324 v_intermediatecg = _mm256_unpacklo_epi64(v_itc0d0g0h0, v_itc4d4g4h4);
46325 v_intermediatedh = _mm256_unpackhi_epi64(v_itc0d0g0h0, v_itc4d4g4h4);
46326 } while (0);
46327 v_intermediatedb = _mm256_permute2x128_si256(v_intermediatedh, v_intermediatebf, (int32_t)(32u));
46328 v_intermediatehf = _mm256_permute2x128_si256(v_intermediatedh, v_intermediatebf, (int32_t)(49u));
46329 v_sp_cols62 = _mm256_permute2x128_si256(v_intermediatecg, v_intermediatecg, (int32_t)(1u));
46330 v_sp_bq2662ad = _mm256_unpacklo_epi16(v_intermediatecg, v_sp_cols62);
46331 v_sp_bq2662eh = _mm256_unpackhi_epi16(v_intermediatecg, v_sp_cols62);
46332 v_sp_rb26ad = _mm256_madd_epi16(v_sp_bq2662ad, v_k_29CF_1151_D630_1151);
46333 v_sp_rb26eh = _mm256_madd_epi16(v_sp_bq2662eh, v_k_29CF_1151_D630_1151);
46334 v_sp_cols40pos = _mm256_permute2x128_si256(v_intermediateae, v_intermediateae, (int32_t)(1u));
46335 v_sp_cols04neg = _mm256_sign_epi16(v_intermediateae, v_k_0001_FFFF);
46336 v_sp_cols0pm4 = _mm256_add_epi16(v_sp_cols40pos, v_sp_cols04neg);
46337 v_sp_rcpmad = _mm256_srai_epi32(_mm256_unpacklo_epi16(v_k_0000, v_sp_cols0pm4), (int32_t)(3u));
46338 v_sp_rcpmeh = _mm256_srai_epi32(_mm256_unpackhi_epi16(v_k_0000, v_sp_cols0pm4), (int32_t)(3u));
46339 v_sp_rd01ad = _mm256_add_epi32(v_sp_rcpmad, v_sp_rb26ad);
46340 v_sp_rd01eh = _mm256_add_epi32(v_sp_rcpmeh, v_sp_rb26eh);
46341 v_sp_rd32ad = _mm256_sub_epi32(v_sp_rcpmad, v_sp_rb26ad);
46342 v_sp_rd32eh = _mm256_sub_epi32(v_sp_rcpmeh, v_sp_rb26eh);
46343 v_sp_sums7351 = _mm256_add_epi16(v_intermediatehf, v_intermediatedb);
46344 v_sp_sums5173 = _mm256_permute2x128_si256(v_sp_sums7351, v_sp_sums7351, (int32_t)(1u));
46345 v_sp_ri73515173ad = _mm256_unpacklo_epi16(v_sp_sums7351, v_sp_sums5173);
46346 v_sp_ri73515173eh = _mm256_unpackhi_epi16(v_sp_sums7351, v_sp_sums5173);
46347 v_sp_rl7351ad = _mm256_madd_epi16(v_sp_ri73515173ad, v_k_E6DC_25A1_1925_25A1);
46348 v_sp_rl7351eh = _mm256_madd_epi16(v_sp_ri73515173eh, v_k_E6DC_25A1_1925_25A1);
46349 v_sp_cols13 = _mm256_permute2x128_si256(v_intermediatedb, v_intermediatedb, (int32_t)(1u));
46350 v_sp_bq7153ad = _mm256_unpacklo_epi16(v_intermediatehf, v_sp_cols13);
46351 v_sp_bq7153eh = _mm256_unpackhi_epi16(v_intermediatehf, v_sp_cols13);
46352 v_sp_rk75ad = _mm256_add_epi32(_mm256_madd_epi16(v_sp_bq7153ad, v_k_ECC1_E333_EFB0_ADFD), v_sp_rl7351ad);
46353 v_sp_rk75eh = _mm256_add_epi32(_mm256_madd_epi16(v_sp_bq7153eh, v_k_ECC1_E333_EFB0_ADFD), v_sp_rl7351eh);
46354 v_sp_rl5173ad = _mm256_permute2x128_si256(v_sp_rl7351ad, v_sp_rl7351ad, (int32_t)(1u));
46355 v_sp_rl5173eh = _mm256_permute2x128_si256(v_sp_rl7351eh, v_sp_rl7351eh, (int32_t)(1u));
46356 v_sp_rk13ad = _mm256_add_epi32(v_sp_rl5173ad, _mm256_madd_epi16(v_sp_bq7153ad, v_k_E333_133E_ADFD_1051));
46357 v_sp_rk13eh = _mm256_add_epi32(v_sp_rl5173eh, _mm256_madd_epi16(v_sp_bq7153eh, v_k_E333_133E_ADFD_1051));
46358 v_final01ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_sp_rd01ad, v_sp_rk13ad), v_k_0000_0002), (int32_t)(18u));
46359 v_final01eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_sp_rd01eh, v_sp_rk13eh), v_k_0000_0002), (int32_t)(18u));
46360 v_final01 = _mm256_packs_epi32(v_final01ad, v_final01eh);
46361 v_final32ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_sp_rd32ad, v_sp_rk75ad), v_k_0000_0002), (int32_t)(18u));
46362 v_final32eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_sp_rd32eh, v_sp_rk75eh), v_k_0000_0002), (int32_t)(18u));
46363 v_final32 = _mm256_packs_epi32(v_final32ad, v_final32eh);
46364 v_final45ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_sp_rd32ad, v_sp_rk75ad), v_k_0000_0002), (int32_t)(18u));
46365 v_final45eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_sp_rd32eh, v_sp_rk75eh), v_k_0000_0002), (int32_t)(18u));
46366 v_final45 = _mm256_packs_epi32(v_final45ad, v_final45eh);
46367 v_final76ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_sp_rd01ad, v_sp_rk13ad), v_k_0000_0002), (int32_t)(18u));
46368 v_final76eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_sp_rd01eh, v_sp_rk13eh), v_k_0000_0002), (int32_t)(18u));
46369 v_final76 = _mm256_packs_epi32(v_final76ad, v_final76eh);
46370 v_fta0a1e0e1 = _mm256_permute4x64_epi64(v_final01, (int32_t)(216u));
46371 v_fta2a3e2e3 = _mm256_permute4x64_epi64(v_final32, (int32_t)(114u));
46372 v_fta4a5e4e5 = _mm256_permute4x64_epi64(v_final45, (int32_t)(216u));
46373 v_fta6a7e6e7 = _mm256_permute4x64_epi64(v_final76, (int32_t)(114u));
46374 v_fta0c0e0g0 = _mm256_unpacklo_epi16(v_fta0a1e0e1, v_fta2a3e2e3);
46375 v_fta1c1e1g1 = _mm256_unpackhi_epi16(v_fta0a1e0e1, v_fta2a3e2e3);
46376 v_fta4c4e4g4 = _mm256_unpacklo_epi16(v_fta4a5e4e5, v_fta6a7e6e7);
46377 v_fta5c5e5g5 = _mm256_unpackhi_epi16(v_fta4a5e4e5, v_fta6a7e6e7);
46378 v_fta0b0e0f0 = _mm256_unpacklo_epi16(v_fta0c0e0g0, v_fta1c1e1g1);
46379 v_ftc0d0g0h0 = _mm256_unpackhi_epi16(v_fta0c0e0g0, v_fta1c1e1g1);
46380 v_fta4b4e4f4 = _mm256_unpacklo_epi16(v_fta4c4e4g4, v_fta5c5e5g5);
46381 v_ftc4d4g4h4 = _mm256_unpackhi_epi16(v_fta4c4e4g4, v_fta5c5e5g5);
46382 v_finalae = _mm256_unpacklo_epi64(v_fta0b0e0f0, v_fta4b4e4f4);
46383 v_finalbf = _mm256_unpackhi_epi64(v_fta0b0e0f0, v_fta4b4e4f4);
46384 v_finalcg = _mm256_unpacklo_epi64(v_ftc0d0g0h0, v_ftc4d4g4h4);
46385 v_finaldh = _mm256_unpackhi_epi64(v_ftc0d0g0h0, v_ftc4d4g4h4);
46386 v_final0145 = _mm256_add_epi8(_mm256_packs_epi16(v_finalae, v_finalbf), v_k_8080);
46387 v_final2367 = _mm256_add_epi8(_mm256_packs_epi16(v_finalcg, v_finaldh), v_k_8080);
46388 v_final0 = ((uint64_t)(_mm256_extract_epi64(v_final0145, (int32_t)(0u))));
46389 v_final1 = ((uint64_t)(_mm256_extract_epi64(v_final0145, (int32_t)(1u))));
46390 v_final2 = ((uint64_t)(_mm256_extract_epi64(v_final2367, (int32_t)(0u))));
46391 v_final3 = ((uint64_t)(_mm256_extract_epi64(v_final2367, (int32_t)(1u))));
46392 v_final4 = ((uint64_t)(_mm256_extract_epi64(v_final0145, (int32_t)(2u))));
46393 v_final5 = ((uint64_t)(_mm256_extract_epi64(v_final0145, (int32_t)(3u))));
46394 v_final6 = ((uint64_t)(_mm256_extract_epi64(v_final2367, (int32_t)(2u))));
46395 v_final7 = ((uint64_t)(_mm256_extract_epi64(v_final2367, (int32_t)(3u))));
46396 if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
46397 return wuffs_base__make_empty_struct();
46399 v_remaining = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
46400 wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final0);
46401 a_dst_buffer = v_remaining;
46402 if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
46403 return wuffs_base__make_empty_struct();
46405 v_remaining = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
46406 wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final1);
46407 a_dst_buffer = v_remaining;
46408 if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
46409 return wuffs_base__make_empty_struct();
46411 v_remaining = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
46412 wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final2);
46413 a_dst_buffer = v_remaining;
46414 if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
46415 return wuffs_base__make_empty_struct();
46417 v_remaining = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
46418 wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final3);
46419 a_dst_buffer = v_remaining;
46420 if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
46421 return wuffs_base__make_empty_struct();
46423 v_remaining = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
46424 wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final4);
46425 a_dst_buffer = v_remaining;
46426 if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
46427 return wuffs_base__make_empty_struct();
46429 v_remaining = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
46430 wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final5);
46431 a_dst_buffer = v_remaining;
46432 if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
46433 return wuffs_base__make_empty_struct();
46435 v_remaining = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
46436 wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final6);
46437 a_dst_buffer = v_remaining;
46438 if (8u > ((uint64_t)(a_dst_buffer.len))) {
46439 return wuffs_base__make_empty_struct();
46441 wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final7);
46442 return wuffs_base__make_empty_struct();
46444 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3)
46445 // ‼ WUFFS MULTI-FILE SECTION -x86_avx2
46447 // -------- func jpeg.decoder.get_quirk
46449 WUFFS_BASE__GENERATED_C_CODE
46450 WUFFS_BASE__MAYBE_STATIC uint64_t
46451 wuffs_jpeg__decoder__get_quirk(
46452 const wuffs_jpeg__decoder* self,
46453 uint32_t a_key) {
46454 if (!self) {
46455 return 0;
46457 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
46458 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
46459 return 0;
46462 if (a_key == 2u) {
46463 if (self->private_impl.f_use_lower_quality) {
46464 return 18446744073709551615u;
46466 } else if (a_key == 1220532224u) {
46467 if (self->private_impl.f_reject_progressive_jpegs) {
46468 return 1u;
46471 return 0u;
46474 // -------- func jpeg.decoder.set_quirk
46476 WUFFS_BASE__GENERATED_C_CODE
46477 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
46478 wuffs_jpeg__decoder__set_quirk(
46479 wuffs_jpeg__decoder* self,
46480 uint32_t a_key,
46481 uint64_t a_value) {
46482 if (!self) {
46483 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
46485 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
46486 return wuffs_base__make_status(
46487 (self->private_impl.magic == WUFFS_BASE__DISABLED)
46488 ? wuffs_base__error__disabled_by_previous_error
46489 : wuffs_base__error__initialize_not_called);
46492 if (a_key == 2u) {
46493 self->private_impl.f_use_lower_quality = (a_value >= 9223372036854775808u);
46494 return wuffs_base__make_status(NULL);
46495 } else if (a_key == 1220532224u) {
46496 self->private_impl.f_reject_progressive_jpegs = (a_value != 0u);
46497 return wuffs_base__make_status(NULL);
46499 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
46502 // -------- func jpeg.decoder.decode_image_config
46504 WUFFS_BASE__GENERATED_C_CODE
46505 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
46506 wuffs_jpeg__decoder__decode_image_config(
46507 wuffs_jpeg__decoder* self,
46508 wuffs_base__image_config* a_dst,
46509 wuffs_base__io_buffer* a_src) {
46510 if (!self) {
46511 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
46513 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
46514 return wuffs_base__make_status(
46515 (self->private_impl.magic == WUFFS_BASE__DISABLED)
46516 ? wuffs_base__error__disabled_by_previous_error
46517 : wuffs_base__error__initialize_not_called);
46519 if (!a_src) {
46520 self->private_impl.magic = WUFFS_BASE__DISABLED;
46521 return wuffs_base__make_status(wuffs_base__error__bad_argument);
46523 if ((self->private_impl.active_coroutine != 0) &&
46524 (self->private_impl.active_coroutine != 1)) {
46525 self->private_impl.magic = WUFFS_BASE__DISABLED;
46526 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
46528 self->private_impl.active_coroutine = 0;
46529 wuffs_base__status status = wuffs_base__make_status(NULL);
46531 wuffs_base__status v_status = wuffs_base__make_status(NULL);
46533 uint32_t coro_susp_point = self->private_impl.p_decode_image_config;
46534 switch (coro_susp_point) {
46535 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
46537 while (true) {
46539 wuffs_base__status t_0 = wuffs_jpeg__decoder__do_decode_image_config(self, a_dst, a_src);
46540 v_status = t_0;
46542 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
46543 status = wuffs_base__make_status(wuffs_jpeg__error__truncated_input);
46544 goto exit;
46546 status = v_status;
46547 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
46551 self->private_impl.p_decode_image_config = 0;
46552 goto exit;
46555 goto suspend;
46556 suspend:
46557 self->private_impl.p_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
46558 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
46560 goto exit;
46561 exit:
46562 if (wuffs_base__status__is_error(&status)) {
46563 self->private_impl.magic = WUFFS_BASE__DISABLED;
46565 return status;
46568 // -------- func jpeg.decoder.do_decode_image_config
46570 WUFFS_BASE__GENERATED_C_CODE
46571 static wuffs_base__status
46572 wuffs_jpeg__decoder__do_decode_image_config(
46573 wuffs_jpeg__decoder* self,
46574 wuffs_base__image_config* a_dst,
46575 wuffs_base__io_buffer* a_src) {
46576 wuffs_base__status status = wuffs_base__make_status(NULL);
46578 uint8_t v_c8 = 0;
46579 uint8_t v_marker = 0;
46580 uint32_t v_pixfmt = 0;
46582 const uint8_t* iop_a_src = NULL;
46583 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
46584 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
46585 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
46586 if (a_src && a_src->data.ptr) {
46587 io0_a_src = a_src->data.ptr;
46588 io1_a_src = io0_a_src + a_src->meta.ri;
46589 iop_a_src = io1_a_src;
46590 io2_a_src = io0_a_src + a_src->meta.wi;
46593 uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config;
46594 if (coro_susp_point) {
46595 v_marker = self->private_data.s_do_decode_image_config.v_marker;
46597 switch (coro_susp_point) {
46598 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
46600 if (self->private_impl.f_call_sequence != 0u) {
46601 status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
46602 goto exit;
46605 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
46606 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
46607 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
46608 goto suspend;
46610 uint8_t t_0 = *iop_a_src++;
46611 v_c8 = t_0;
46613 if (v_c8 != 255u) {
46614 status = wuffs_base__make_status(wuffs_jpeg__error__bad_header);
46615 goto exit;
46618 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
46619 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
46620 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
46621 goto suspend;
46623 uint8_t t_1 = *iop_a_src++;
46624 v_c8 = t_1;
46626 if (v_c8 != 216u) {
46627 status = wuffs_base__make_status(wuffs_jpeg__error__bad_header);
46628 goto exit;
46630 while (true) {
46631 while (true) {
46633 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
46634 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
46635 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
46636 goto suspend;
46638 uint8_t t_2 = *iop_a_src++;
46639 v_c8 = t_2;
46641 if (v_c8 == 255u) {
46642 break;
46645 while (true) {
46647 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
46648 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
46649 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
46650 goto suspend;
46652 uint8_t t_3 = *iop_a_src++;
46653 v_c8 = t_3;
46655 if (v_c8 != 255u) {
46656 v_marker = v_c8;
46657 break;
46660 if (v_marker == 0u) {
46661 continue;
46662 } else if ((208u <= v_marker) && (v_marker <= 217u)) {
46663 if (v_marker <= 215u) {
46664 continue;
46666 } else {
46668 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
46669 uint32_t t_4;
46670 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
46671 t_4 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
46672 iop_a_src += 2;
46673 } else {
46674 self->private_data.s_do_decode_image_config.scratch = 0;
46675 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
46676 while (true) {
46677 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
46678 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
46679 goto suspend;
46681 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
46682 uint32_t num_bits_4 = ((uint32_t)(*scratch & 0xFFu));
46683 *scratch >>= 8;
46684 *scratch <<= 8;
46685 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_4);
46686 if (num_bits_4 == 8) {
46687 t_4 = ((uint32_t)(*scratch >> 48));
46688 break;
46690 num_bits_4 += 8u;
46691 *scratch |= ((uint64_t)(num_bits_4));
46694 self->private_impl.f_payload_length = t_4;
46696 if (self->private_impl.f_payload_length < 2u) {
46697 status = wuffs_base__make_status(wuffs_jpeg__error__bad_marker);
46698 goto exit;
46700 self->private_impl.f_payload_length -= 2u;
46702 if (v_marker < 192u) {
46703 status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker);
46704 goto exit;
46705 } else if (v_marker < 208u) {
46706 if (v_marker <= 194u) {
46707 if ((v_marker == 194u) && self->private_impl.f_reject_progressive_jpegs) {
46708 status = wuffs_base__make_status(wuffs_jpeg__error__rejected_progressive_jpeg);
46709 goto exit;
46710 } else if (self->private_impl.f_sof_marker != 0u) {
46711 status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker);
46712 goto exit;
46714 self->private_impl.f_sof_marker = v_marker;
46715 if (a_src) {
46716 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
46718 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
46719 status = wuffs_jpeg__decoder__decode_sof(self, a_src);
46720 if (a_src) {
46721 iop_a_src = a_src->data.ptr + a_src->meta.ri;
46723 if (status.repr) {
46724 goto suspend;
46726 break;
46727 } else if (v_marker == 195u) {
46728 status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_lossless_coding);
46729 goto exit;
46730 } else if (v_marker == 196u) {
46731 status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker);
46732 goto exit;
46733 } else if ((197u <= v_marker) && (v_marker <= 199u)) {
46734 status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_hierarchical_coding);
46735 goto exit;
46736 } else if (v_marker == 200u) {
46737 status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker);
46738 goto exit;
46739 } else {
46740 status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_arithmetic_coding);
46741 goto exit;
46743 } else if (v_marker < 224u) {
46744 if (v_marker < 218u) {
46745 status = wuffs_base__make_status(wuffs_jpeg__error__bad_marker);
46746 goto exit;
46747 } else if (v_marker == 218u) {
46748 status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
46749 goto exit;
46750 } else if (v_marker == 219u) {
46751 if (a_src) {
46752 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
46754 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
46755 status = wuffs_jpeg__decoder__decode_dqt(self, a_src);
46756 if (a_src) {
46757 iop_a_src = a_src->data.ptr + a_src->meta.ri;
46759 if (status.repr) {
46760 goto suspend;
46762 continue;
46763 } else if (v_marker == 221u) {
46764 if (a_src) {
46765 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
46767 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
46768 status = wuffs_jpeg__decoder__decode_dri(self, a_src);
46769 if (a_src) {
46770 iop_a_src = a_src->data.ptr + a_src->meta.ri;
46772 if (status.repr) {
46773 goto suspend;
46775 continue;
46776 } else {
46777 status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker);
46778 goto exit;
46780 } else if (v_marker < 240u) {
46781 if (a_src) {
46782 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
46784 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
46785 status = wuffs_jpeg__decoder__decode_appn(self, a_src, v_marker);
46786 if (a_src) {
46787 iop_a_src = a_src->data.ptr + a_src->meta.ri;
46789 if (status.repr) {
46790 goto suspend;
46792 continue;
46793 } else {
46794 if (v_marker == 254u) {
46795 } else {
46796 status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker);
46797 goto exit;
46800 self->private_data.s_do_decode_image_config.scratch = self->private_impl.f_payload_length;
46801 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
46802 if (self->private_data.s_do_decode_image_config.scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
46803 self->private_data.s_do_decode_image_config.scratch -= ((uint64_t)(io2_a_src - iop_a_src));
46804 iop_a_src = io2_a_src;
46805 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
46806 goto suspend;
46808 iop_a_src += self->private_data.s_do_decode_image_config.scratch;
46809 self->private_impl.f_payload_length = 0u;
46811 self->private_impl.choosy_decode_idct = (
46812 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3)
46813 wuffs_base__cpu_arch__have_x86_avx2() ? &wuffs_jpeg__decoder__decode_idct_x86_avx2 :
46814 #endif
46815 self->private_impl.choosy_decode_idct);
46816 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)));
46817 if (a_dst != NULL) {
46818 v_pixfmt = 536870920u;
46819 if (self->private_impl.f_num_components > 1u) {
46820 v_pixfmt = 2415954056u;
46822 wuffs_base__image_config__set(
46823 a_dst,
46824 v_pixfmt,
46826 self->private_impl.f_width,
46827 self->private_impl.f_height,
46828 self->private_impl.f_frame_config_io_position,
46829 true);
46831 self->private_impl.f_call_sequence = 32u;
46833 goto ok;
46835 self->private_impl.p_do_decode_image_config = 0;
46836 goto exit;
46839 goto suspend;
46840 suspend:
46841 self->private_impl.p_do_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
46842 self->private_data.s_do_decode_image_config.v_marker = v_marker;
46844 goto exit;
46845 exit:
46846 if (a_src && a_src->data.ptr) {
46847 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
46850 return status;
46853 // -------- func jpeg.decoder.decode_dqt
46855 WUFFS_BASE__GENERATED_C_CODE
46856 static wuffs_base__status
46857 wuffs_jpeg__decoder__decode_dqt(
46858 wuffs_jpeg__decoder* self,
46859 wuffs_base__io_buffer* a_src) {
46860 wuffs_base__status status = wuffs_base__make_status(NULL);
46862 uint8_t v_c8 = 0;
46863 uint8_t v_q = 0;
46864 uint32_t v_i = 0;
46866 const uint8_t* iop_a_src = NULL;
46867 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
46868 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
46869 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
46870 if (a_src && a_src->data.ptr) {
46871 io0_a_src = a_src->data.ptr;
46872 io1_a_src = io0_a_src + a_src->meta.ri;
46873 iop_a_src = io1_a_src;
46874 io2_a_src = io0_a_src + a_src->meta.wi;
46877 uint32_t coro_susp_point = self->private_impl.p_decode_dqt;
46878 if (coro_susp_point) {
46879 v_q = self->private_data.s_decode_dqt.v_q;
46880 v_i = self->private_data.s_decode_dqt.v_i;
46882 switch (coro_susp_point) {
46883 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
46885 while (self->private_impl.f_payload_length > 0u) {
46886 self->private_impl.f_payload_length -= 1u;
46888 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
46889 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
46890 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
46891 goto suspend;
46893 uint8_t t_0 = *iop_a_src++;
46894 v_c8 = t_0;
46896 if (((uint8_t)(v_c8 & 15u)) > 3u) {
46897 status = wuffs_base__make_status(wuffs_jpeg__error__bad_dqt_marker);
46898 goto exit;
46900 v_q = ((uint8_t)(v_c8 & 15u));
46901 if (((uint8_t)(v_c8 >> 4u)) == 1u) {
46902 status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_precision);
46903 goto exit;
46904 } else if ((((uint8_t)(v_c8 >> 4u)) > 1u) || (self->private_impl.f_payload_length < 64u)) {
46905 status = wuffs_base__make_status(wuffs_jpeg__error__bad_dqt_marker);
46906 goto exit;
46908 self->private_impl.f_payload_length -= 64u;
46909 v_i = 0u;
46910 while (v_i < 64u) {
46911 v_i += 1u;
46913 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
46914 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
46915 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
46916 goto suspend;
46918 uint16_t t_1 = *iop_a_src++;
46919 self->private_impl.f_quant_tables[v_q][WUFFS_JPEG__UNZIG[v_i]] = t_1;
46922 self->private_impl.f_seen_dqt[v_q] = true;
46923 if (self->private_impl.f_sof_marker == 0u) {
46924 v_i = 0u;
46925 while (v_i < 64u) {
46926 self->private_impl.f_saved_quant_tables[v_q][v_i] = self->private_impl.f_quant_tables[v_q][v_i];
46927 v_i += 1u;
46929 self->private_impl.f_saved_seen_dqt[v_q] = true;
46933 goto ok;
46935 self->private_impl.p_decode_dqt = 0;
46936 goto exit;
46939 goto suspend;
46940 suspend:
46941 self->private_impl.p_decode_dqt = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
46942 self->private_data.s_decode_dqt.v_q = v_q;
46943 self->private_data.s_decode_dqt.v_i = v_i;
46945 goto exit;
46946 exit:
46947 if (a_src && a_src->data.ptr) {
46948 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
46951 return status;
46954 // -------- func jpeg.decoder.decode_dri
46956 WUFFS_BASE__GENERATED_C_CODE
46957 static wuffs_base__status
46958 wuffs_jpeg__decoder__decode_dri(
46959 wuffs_jpeg__decoder* self,
46960 wuffs_base__io_buffer* a_src) {
46961 wuffs_base__status status = wuffs_base__make_status(NULL);
46963 const uint8_t* iop_a_src = NULL;
46964 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
46965 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
46966 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
46967 if (a_src && a_src->data.ptr) {
46968 io0_a_src = a_src->data.ptr;
46969 io1_a_src = io0_a_src + a_src->meta.ri;
46970 iop_a_src = io1_a_src;
46971 io2_a_src = io0_a_src + a_src->meta.wi;
46974 uint32_t coro_susp_point = self->private_impl.p_decode_dri;
46975 switch (coro_susp_point) {
46976 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
46978 if (self->private_impl.f_payload_length != 2u) {
46979 status = wuffs_base__make_status(wuffs_jpeg__error__bad_dri_marker);
46980 goto exit;
46982 self->private_impl.f_payload_length = 0u;
46984 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
46985 uint16_t t_0;
46986 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
46987 t_0 = wuffs_base__peek_u16be__no_bounds_check(iop_a_src);
46988 iop_a_src += 2;
46989 } else {
46990 self->private_data.s_decode_dri.scratch = 0;
46991 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
46992 while (true) {
46993 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
46994 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
46995 goto suspend;
46997 uint64_t* scratch = &self->private_data.s_decode_dri.scratch;
46998 uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu));
46999 *scratch >>= 8;
47000 *scratch <<= 8;
47001 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
47002 if (num_bits_0 == 8) {
47003 t_0 = ((uint16_t)(*scratch >> 48));
47004 break;
47006 num_bits_0 += 8u;
47007 *scratch |= ((uint64_t)(num_bits_0));
47010 self->private_impl.f_restart_interval = t_0;
47012 if (self->private_impl.f_sof_marker == 0u) {
47013 self->private_impl.f_saved_restart_interval = self->private_impl.f_restart_interval;
47016 goto ok;
47018 self->private_impl.p_decode_dri = 0;
47019 goto exit;
47022 goto suspend;
47023 suspend:
47024 self->private_impl.p_decode_dri = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
47026 goto exit;
47027 exit:
47028 if (a_src && a_src->data.ptr) {
47029 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
47032 return status;
47035 // -------- func jpeg.decoder.decode_appn
47037 WUFFS_BASE__GENERATED_C_CODE
47038 static wuffs_base__status
47039 wuffs_jpeg__decoder__decode_appn(
47040 wuffs_jpeg__decoder* self,
47041 wuffs_base__io_buffer* a_src,
47042 uint8_t a_marker) {
47043 wuffs_base__status status = wuffs_base__make_status(NULL);
47045 uint8_t v_c8 = 0;
47046 uint32_t v_c32 = 0;
47048 const uint8_t* iop_a_src = NULL;
47049 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
47050 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
47051 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
47052 if (a_src && a_src->data.ptr) {
47053 io0_a_src = a_src->data.ptr;
47054 io1_a_src = io0_a_src + a_src->meta.ri;
47055 iop_a_src = io1_a_src;
47056 io2_a_src = io0_a_src + a_src->meta.wi;
47059 uint32_t coro_susp_point = self->private_impl.p_decode_appn;
47060 switch (coro_susp_point) {
47061 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
47063 do {
47064 if (a_marker == 224u) {
47065 if (self->private_impl.f_payload_length >= 5u) {
47066 self->private_impl.f_payload_length -= 5u;
47068 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
47069 uint32_t t_0;
47070 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
47071 t_0 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
47072 iop_a_src += 4;
47073 } else {
47074 self->private_data.s_decode_appn.scratch = 0;
47075 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
47076 while (true) {
47077 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
47078 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
47079 goto suspend;
47081 uint64_t* scratch = &self->private_data.s_decode_appn.scratch;
47082 uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
47083 *scratch <<= 8;
47084 *scratch >>= 8;
47085 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
47086 if (num_bits_0 == 24) {
47087 t_0 = ((uint32_t)(*scratch));
47088 break;
47090 num_bits_0 += 8u;
47091 *scratch |= ((uint64_t)(num_bits_0)) << 56;
47094 v_c32 = t_0;
47096 if (v_c32 != 1179207242u) {
47097 self->private_impl.f_payload_length = (65535u & (self->private_impl.f_payload_length + 1u));
47098 break;
47101 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
47102 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
47103 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
47104 goto suspend;
47106 uint8_t t_1 = *iop_a_src++;
47107 v_c8 = t_1;
47109 self->private_impl.f_is_jfif = (v_c8 == 0u);
47111 } else if (a_marker == 238u) {
47112 if (self->private_impl.f_payload_length >= 12u) {
47113 self->private_impl.f_payload_length -= 12u;
47115 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
47116 uint32_t t_2;
47117 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
47118 t_2 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
47119 iop_a_src += 4;
47120 } else {
47121 self->private_data.s_decode_appn.scratch = 0;
47122 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
47123 while (true) {
47124 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
47125 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
47126 goto suspend;
47128 uint64_t* scratch = &self->private_data.s_decode_appn.scratch;
47129 uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
47130 *scratch <<= 8;
47131 *scratch >>= 8;
47132 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
47133 if (num_bits_2 == 24) {
47134 t_2 = ((uint32_t)(*scratch));
47135 break;
47137 num_bits_2 += 8u;
47138 *scratch |= ((uint64_t)(num_bits_2)) << 56;
47141 v_c32 = t_2;
47143 if (v_c32 != 1651467329u) {
47144 self->private_impl.f_payload_length = (65535u & (self->private_impl.f_payload_length + 8u));
47145 break;
47148 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
47149 uint32_t t_3;
47150 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
47151 t_3 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
47152 iop_a_src += 4;
47153 } else {
47154 self->private_data.s_decode_appn.scratch = 0;
47155 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
47156 while (true) {
47157 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
47158 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
47159 goto suspend;
47161 uint64_t* scratch = &self->private_data.s_decode_appn.scratch;
47162 uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56));
47163 *scratch <<= 8;
47164 *scratch >>= 8;
47165 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3;
47166 if (num_bits_3 == 24) {
47167 t_3 = ((uint32_t)(*scratch));
47168 break;
47170 num_bits_3 += 8u;
47171 *scratch |= ((uint64_t)(num_bits_3)) << 56;
47174 v_c32 = t_3;
47176 if ((255u & v_c32) != 101u) {
47177 self->private_impl.f_payload_length = (65535u & (self->private_impl.f_payload_length + 4u));
47178 break;
47181 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
47182 uint32_t t_4;
47183 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
47184 t_4 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
47185 iop_a_src += 4;
47186 } else {
47187 self->private_data.s_decode_appn.scratch = 0;
47188 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
47189 while (true) {
47190 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
47191 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
47192 goto suspend;
47194 uint64_t* scratch = &self->private_data.s_decode_appn.scratch;
47195 uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
47196 *scratch <<= 8;
47197 *scratch >>= 8;
47198 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
47199 if (num_bits_4 == 24) {
47200 t_4 = ((uint32_t)(*scratch));
47201 break;
47203 num_bits_4 += 8u;
47204 *scratch |= ((uint64_t)(num_bits_4)) << 56;
47207 v_c32 = t_4;
47209 if ((v_c32 >> 24u) == 0u) {
47210 self->private_impl.f_is_adobe = 1u;
47211 } else {
47212 self->private_impl.f_is_adobe = 2u;
47216 } while (0);
47217 self->private_data.s_decode_appn.scratch = self->private_impl.f_payload_length;
47218 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
47219 if (self->private_data.s_decode_appn.scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
47220 self->private_data.s_decode_appn.scratch -= ((uint64_t)(io2_a_src - iop_a_src));
47221 iop_a_src = io2_a_src;
47222 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
47223 goto suspend;
47225 iop_a_src += self->private_data.s_decode_appn.scratch;
47226 self->private_impl.f_payload_length = 0u;
47228 goto ok;
47230 self->private_impl.p_decode_appn = 0;
47231 goto exit;
47234 goto suspend;
47235 suspend:
47236 self->private_impl.p_decode_appn = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
47238 goto exit;
47239 exit:
47240 if (a_src && a_src->data.ptr) {
47241 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
47244 return status;
47247 // -------- func jpeg.decoder.decode_sof
47249 WUFFS_BASE__GENERATED_C_CODE
47250 static wuffs_base__status
47251 wuffs_jpeg__decoder__decode_sof(
47252 wuffs_jpeg__decoder* self,
47253 wuffs_base__io_buffer* a_src) {
47254 wuffs_base__status status = wuffs_base__make_status(NULL);
47256 uint8_t v_c8 = 0;
47257 uint8_t v_comp_h = 0;
47258 uint8_t v_comp_v = 0;
47259 uint32_t v_i = 0;
47260 uint32_t v_j = 0;
47261 bool v_has_h24 = false;
47262 bool v_has_h3 = false;
47263 bool v_has_v24 = false;
47264 bool v_has_v3 = false;
47265 uint32_t v_upper_bound = 0;
47266 uint64_t v_wh0 = 0;
47267 uint64_t v_wh1 = 0;
47268 uint64_t v_wh2 = 0;
47269 uint64_t v_wh3 = 0;
47270 uint64_t v_progressive = 0;
47272 const uint8_t* iop_a_src = NULL;
47273 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
47274 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
47275 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
47276 if (a_src && a_src->data.ptr) {
47277 io0_a_src = a_src->data.ptr;
47278 io1_a_src = io0_a_src + a_src->meta.ri;
47279 iop_a_src = io1_a_src;
47280 io2_a_src = io0_a_src + a_src->meta.wi;
47283 uint32_t coro_susp_point = self->private_impl.p_decode_sof;
47284 if (coro_susp_point) {
47285 v_i = self->private_data.s_decode_sof.v_i;
47287 switch (coro_susp_point) {
47288 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
47290 if (self->private_impl.f_payload_length < 6u) {
47291 status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker);
47292 goto exit;
47294 self->private_impl.f_payload_length -= 6u;
47296 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
47297 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
47298 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
47299 goto suspend;
47301 uint8_t t_0 = *iop_a_src++;
47302 v_c8 = t_0;
47304 if (v_c8 == 8u) {
47305 } else if (v_c8 == 12u) {
47306 status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_precision_12_bits);
47307 goto exit;
47308 } else if (v_c8 == 16u) {
47309 status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_precision_16_bits);
47310 goto exit;
47311 } else {
47312 status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_precision);
47313 goto exit;
47316 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
47317 uint32_t t_1;
47318 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
47319 t_1 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
47320 iop_a_src += 2;
47321 } else {
47322 self->private_data.s_decode_sof.scratch = 0;
47323 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
47324 while (true) {
47325 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
47326 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
47327 goto suspend;
47329 uint64_t* scratch = &self->private_data.s_decode_sof.scratch;
47330 uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu));
47331 *scratch >>= 8;
47332 *scratch <<= 8;
47333 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
47334 if (num_bits_1 == 8) {
47335 t_1 = ((uint32_t)(*scratch >> 48));
47336 break;
47338 num_bits_1 += 8u;
47339 *scratch |= ((uint64_t)(num_bits_1));
47342 self->private_impl.f_height = t_1;
47344 if (self->private_impl.f_height == 0u) {
47345 status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_implicit_height);
47346 goto exit;
47349 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
47350 uint32_t t_2;
47351 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
47352 t_2 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
47353 iop_a_src += 2;
47354 } else {
47355 self->private_data.s_decode_sof.scratch = 0;
47356 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
47357 while (true) {
47358 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
47359 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
47360 goto suspend;
47362 uint64_t* scratch = &self->private_data.s_decode_sof.scratch;
47363 uint32_t num_bits_2 = ((uint32_t)(*scratch & 0xFFu));
47364 *scratch >>= 8;
47365 *scratch <<= 8;
47366 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_2);
47367 if (num_bits_2 == 8) {
47368 t_2 = ((uint32_t)(*scratch >> 48));
47369 break;
47371 num_bits_2 += 8u;
47372 *scratch |= ((uint64_t)(num_bits_2));
47375 self->private_impl.f_width = t_2;
47377 if (self->private_impl.f_width == 0u) {
47378 status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension);
47379 goto exit;
47382 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
47383 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
47384 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
47385 goto suspend;
47387 uint8_t t_3 = *iop_a_src++;
47388 v_c8 = t_3;
47390 if ((v_c8 == 0u) || (v_c8 > 4u)) {
47391 status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker);
47392 goto exit;
47393 } else if (v_c8 == 2u) {
47394 status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_color_model);
47395 goto exit;
47397 self->private_impl.f_num_components = ((uint32_t)(v_c8));
47398 if (self->private_impl.f_payload_length != (3u * self->private_impl.f_num_components)) {
47399 status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker);
47400 goto exit;
47402 self->private_impl.f_payload_length = 0u;
47403 v_i = 0u;
47404 while (v_i < self->private_impl.f_num_components) {
47406 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
47407 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
47408 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
47409 goto suspend;
47411 uint8_t t_4 = *iop_a_src++;
47412 self->private_impl.f_components_c[v_i] = t_4;
47415 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
47416 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
47417 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
47418 goto suspend;
47420 uint8_t t_5 = *iop_a_src++;
47421 v_c8 = t_5;
47423 v_comp_h = ((uint8_t)(v_c8 >> 4u));
47424 v_comp_v = ((uint8_t)(v_c8 & 15u));
47425 if ((v_comp_h == 0u) ||
47426 (v_comp_h > 4u) ||
47427 (v_comp_v == 0u) ||
47428 (v_comp_v > 4u)) {
47429 status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker);
47430 goto exit;
47432 self->private_impl.f_components_h[v_i] = v_comp_h;
47433 if (self->private_impl.f_max_incl_components_h < self->private_impl.f_components_h[v_i]) {
47434 self->private_impl.f_max_incl_components_h = self->private_impl.f_components_h[v_i];
47436 self->private_impl.f_components_v[v_i] = v_comp_v;
47437 if (self->private_impl.f_max_incl_components_v < self->private_impl.f_components_v[v_i]) {
47438 self->private_impl.f_max_incl_components_v = self->private_impl.f_components_v[v_i];
47441 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
47442 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
47443 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
47444 goto suspend;
47446 uint8_t t_6 = *iop_a_src++;
47447 v_c8 = t_6;
47449 if (v_c8 >= 4u) {
47450 status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker);
47451 goto exit;
47453 self->private_impl.f_components_tq[v_i] = v_c8;
47454 v_j = 0u;
47455 while (v_j < v_i) {
47456 if (self->private_impl.f_components_c[v_j] == self->private_impl.f_components_c[v_i]) {
47457 status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker);
47458 goto exit;
47460 v_j += 1u;
47462 v_i += 1u;
47464 if (self->private_impl.f_num_components == 1u) {
47465 self->private_impl.f_max_incl_components_h = 1u;
47466 self->private_impl.f_max_incl_components_v = 1u;
47467 self->private_impl.f_components_h[0u] = 1u;
47468 self->private_impl.f_components_v[0u] = 1u;
47469 } else {
47470 v_has_h24 = false;
47471 v_has_h3 = false;
47472 v_has_v24 = false;
47473 v_has_v3 = false;
47474 v_i = 0u;
47475 while (v_i < self->private_impl.f_num_components) {
47476 v_has_h24 = (v_has_h24 || (self->private_impl.f_components_h[v_i] == 2u) || (self->private_impl.f_components_h[v_i] == 4u));
47477 v_has_h3 = (v_has_h3 || (self->private_impl.f_components_h[v_i] == 3u));
47478 v_has_v24 = (v_has_v24 || (self->private_impl.f_components_v[v_i] == 2u) || (self->private_impl.f_components_v[v_i] == 4u));
47479 v_has_v3 = (v_has_v3 || (self->private_impl.f_components_v[v_i] == 3u));
47480 v_i += 1u;
47482 if ((v_has_h24 && v_has_h3) || (v_has_v24 && v_has_v3)) {
47483 status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_fractional_sampling);
47484 goto exit;
47486 if (self->private_impl.f_num_components == 4u) {
47487 self->private_impl.f_is_rgb_or_cmyk = (self->private_impl.f_is_adobe < 2u);
47488 } else {
47489 if (self->private_impl.f_is_jfif) {
47490 self->private_impl.f_is_rgb_or_cmyk = false;
47491 } else if (self->private_impl.f_is_adobe > 0u) {
47492 self->private_impl.f_is_rgb_or_cmyk = (self->private_impl.f_is_adobe == 1u);
47493 } else {
47494 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));
47498 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);
47499 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);
47500 v_upper_bound = 65544u;
47501 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]))));
47502 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]))));
47503 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]))));
47504 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]))));
47505 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]))));
47506 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]))));
47507 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]))));
47508 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]))));
47509 v_wh0 = (((uint64_t)(self->private_impl.f_components_workbuf_widths[0u])) * ((uint64_t)(self->private_impl.f_components_workbuf_heights[0u])));
47510 v_wh1 = (((uint64_t)(self->private_impl.f_components_workbuf_widths[1u])) * ((uint64_t)(self->private_impl.f_components_workbuf_heights[1u])));
47511 v_wh2 = (((uint64_t)(self->private_impl.f_components_workbuf_widths[2u])) * ((uint64_t)(self->private_impl.f_components_workbuf_heights[2u])));
47512 v_wh3 = (((uint64_t)(self->private_impl.f_components_workbuf_widths[3u])) * ((uint64_t)(self->private_impl.f_components_workbuf_heights[3u])));
47513 v_progressive = 0u;
47514 if (self->private_impl.f_sof_marker >= 194u) {
47515 v_progressive = 2u;
47516 v_i = 0u;
47517 while (v_i < 4u) {
47518 v_j = 0u;
47519 while (v_j < 10u) {
47520 self->private_impl.f_block_smoothing_lowest_scan_al[v_i][v_j] = 16u;
47521 v_j += 1u;
47523 v_i += 1u;
47526 self->private_impl.f_components_workbuf_offsets[0u] = 0u;
47527 self->private_impl.f_components_workbuf_offsets[1u] = (self->private_impl.f_components_workbuf_offsets[0u] + v_wh0);
47528 self->private_impl.f_components_workbuf_offsets[2u] = (self->private_impl.f_components_workbuf_offsets[1u] + v_wh1);
47529 self->private_impl.f_components_workbuf_offsets[3u] = (self->private_impl.f_components_workbuf_offsets[2u] + v_wh2);
47530 self->private_impl.f_components_workbuf_offsets[4u] = (self->private_impl.f_components_workbuf_offsets[3u] + v_wh3);
47531 self->private_impl.f_components_workbuf_offsets[5u] = (self->private_impl.f_components_workbuf_offsets[4u] + (v_wh0 * v_progressive));
47532 self->private_impl.f_components_workbuf_offsets[6u] = (self->private_impl.f_components_workbuf_offsets[5u] + (v_wh1 * v_progressive));
47533 self->private_impl.f_components_workbuf_offsets[7u] = (self->private_impl.f_components_workbuf_offsets[6u] + (v_wh2 * v_progressive));
47534 self->private_impl.f_components_workbuf_offsets[8u] = (self->private_impl.f_components_workbuf_offsets[7u] + (v_wh3 * v_progressive));
47536 goto ok;
47538 self->private_impl.p_decode_sof = 0;
47539 goto exit;
47542 goto suspend;
47543 suspend:
47544 self->private_impl.p_decode_sof = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
47545 self->private_data.s_decode_sof.v_i = v_i;
47547 goto exit;
47548 exit:
47549 if (a_src && a_src->data.ptr) {
47550 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
47553 return status;
47556 // -------- func jpeg.decoder.quantize_dimension
47558 WUFFS_BASE__GENERATED_C_CODE
47559 static uint32_t
47560 wuffs_jpeg__decoder__quantize_dimension(
47561 const wuffs_jpeg__decoder* self,
47562 uint32_t a_width,
47563 uint8_t a_h,
47564 uint8_t a_max_incl_h) {
47565 uint32_t v_ratio = 0;
47567 v_ratio = 0u;
47568 if (a_h > 0u) {
47569 v_ratio = ((uint32_t)(((uint8_t)(a_max_incl_h / a_h))));
47571 if (v_ratio == 1u) {
47572 return ((a_width + 7u) / 8u);
47573 } else if (v_ratio == 2u) {
47574 return ((a_width + 15u) / 16u);
47575 } else if (v_ratio == 3u) {
47576 return ((a_width + 23u) / 24u);
47578 return ((a_width + 31u) / 32u);
47581 // -------- func jpeg.decoder.decode_frame_config
47583 WUFFS_BASE__GENERATED_C_CODE
47584 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
47585 wuffs_jpeg__decoder__decode_frame_config(
47586 wuffs_jpeg__decoder* self,
47587 wuffs_base__frame_config* a_dst,
47588 wuffs_base__io_buffer* a_src) {
47589 if (!self) {
47590 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
47592 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
47593 return wuffs_base__make_status(
47594 (self->private_impl.magic == WUFFS_BASE__DISABLED)
47595 ? wuffs_base__error__disabled_by_previous_error
47596 : wuffs_base__error__initialize_not_called);
47598 if (!a_src) {
47599 self->private_impl.magic = WUFFS_BASE__DISABLED;
47600 return wuffs_base__make_status(wuffs_base__error__bad_argument);
47602 if ((self->private_impl.active_coroutine != 0) &&
47603 (self->private_impl.active_coroutine != 2)) {
47604 self->private_impl.magic = WUFFS_BASE__DISABLED;
47605 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
47607 self->private_impl.active_coroutine = 0;
47608 wuffs_base__status status = wuffs_base__make_status(NULL);
47610 wuffs_base__status v_status = wuffs_base__make_status(NULL);
47612 uint32_t coro_susp_point = self->private_impl.p_decode_frame_config;
47613 switch (coro_susp_point) {
47614 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
47616 while (true) {
47618 wuffs_base__status t_0 = wuffs_jpeg__decoder__do_decode_frame_config(self, a_dst, a_src);
47619 v_status = t_0;
47621 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
47622 status = wuffs_base__make_status(wuffs_jpeg__error__truncated_input);
47623 goto exit;
47625 status = v_status;
47626 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
47630 self->private_impl.p_decode_frame_config = 0;
47631 goto exit;
47634 goto suspend;
47635 suspend:
47636 self->private_impl.p_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
47637 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
47639 goto exit;
47640 exit:
47641 if (wuffs_base__status__is_error(&status)) {
47642 self->private_impl.magic = WUFFS_BASE__DISABLED;
47644 return status;
47647 // -------- func jpeg.decoder.do_decode_frame_config
47649 WUFFS_BASE__GENERATED_C_CODE
47650 static wuffs_base__status
47651 wuffs_jpeg__decoder__do_decode_frame_config(
47652 wuffs_jpeg__decoder* self,
47653 wuffs_base__frame_config* a_dst,
47654 wuffs_base__io_buffer* a_src) {
47655 wuffs_base__status status = wuffs_base__make_status(NULL);
47657 const uint8_t* iop_a_src = NULL;
47658 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
47659 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
47660 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
47661 if (a_src && a_src->data.ptr) {
47662 io0_a_src = a_src->data.ptr;
47663 io1_a_src = io0_a_src + a_src->meta.ri;
47664 iop_a_src = io1_a_src;
47665 io2_a_src = io0_a_src + a_src->meta.wi;
47668 uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config;
47669 switch (coro_susp_point) {
47670 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
47672 if (self->private_impl.f_call_sequence == 32u) {
47673 } else if (self->private_impl.f_call_sequence < 32u) {
47674 if (a_src) {
47675 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
47677 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
47678 status = wuffs_jpeg__decoder__do_decode_image_config(self, NULL, a_src);
47679 if (a_src) {
47680 iop_a_src = a_src->data.ptr + a_src->meta.ri;
47682 if (status.repr) {
47683 goto suspend;
47685 } else if (self->private_impl.f_call_sequence == 40u) {
47686 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)))) {
47687 status = wuffs_base__make_status(wuffs_base__error__bad_restart);
47688 goto exit;
47690 } else if (self->private_impl.f_call_sequence == 64u) {
47691 self->private_impl.f_call_sequence = 96u;
47692 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
47693 goto ok;
47694 } else {
47695 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
47696 goto ok;
47698 if (a_dst != NULL) {
47699 wuffs_base__frame_config__set(
47700 a_dst,
47701 wuffs_base__utility__make_rect_ie_u32(
47704 self->private_impl.f_width,
47705 self->private_impl.f_height),
47706 ((wuffs_base__flicks)(0u)),
47708 self->private_impl.f_frame_config_io_position,
47710 true,
47711 false,
47712 4278190080u);
47714 self->private_impl.f_call_sequence = 64u;
47717 self->private_impl.p_do_decode_frame_config = 0;
47718 goto exit;
47721 goto suspend;
47722 suspend:
47723 self->private_impl.p_do_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
47725 goto exit;
47726 exit:
47727 if (a_src && a_src->data.ptr) {
47728 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
47731 return status;
47734 // -------- func jpeg.decoder.decode_frame
47736 WUFFS_BASE__GENERATED_C_CODE
47737 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
47738 wuffs_jpeg__decoder__decode_frame(
47739 wuffs_jpeg__decoder* self,
47740 wuffs_base__pixel_buffer* a_dst,
47741 wuffs_base__io_buffer* a_src,
47742 wuffs_base__pixel_blend a_blend,
47743 wuffs_base__slice_u8 a_workbuf,
47744 wuffs_base__decode_frame_options* a_opts) {
47745 if (!self) {
47746 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
47748 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
47749 return wuffs_base__make_status(
47750 (self->private_impl.magic == WUFFS_BASE__DISABLED)
47751 ? wuffs_base__error__disabled_by_previous_error
47752 : wuffs_base__error__initialize_not_called);
47754 if (!a_dst || !a_src) {
47755 self->private_impl.magic = WUFFS_BASE__DISABLED;
47756 return wuffs_base__make_status(wuffs_base__error__bad_argument);
47758 if ((self->private_impl.active_coroutine != 0) &&
47759 (self->private_impl.active_coroutine != 3)) {
47760 self->private_impl.magic = WUFFS_BASE__DISABLED;
47761 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
47763 self->private_impl.active_coroutine = 0;
47764 wuffs_base__status status = wuffs_base__make_status(NULL);
47766 wuffs_base__status v_ddf_status = wuffs_base__make_status(NULL);
47767 wuffs_base__status v_swizzle_status = wuffs_base__make_status(NULL);
47768 uint32_t v_scan_count = 0;
47770 uint32_t coro_susp_point = self->private_impl.p_decode_frame;
47771 switch (coro_susp_point) {
47772 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
47774 while (true) {
47775 v_scan_count = self->private_impl.f_scan_count;
47777 wuffs_base__status t_0 = wuffs_jpeg__decoder__do_decode_frame(self,
47778 a_dst,
47779 a_src,
47780 a_blend,
47781 a_workbuf,
47782 a_opts);
47783 v_ddf_status = t_0;
47785 if ((v_ddf_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
47786 v_ddf_status = wuffs_base__make_status(wuffs_jpeg__error__truncated_input);
47788 if ( ! self->private_impl.f_swizzle_immediately && (wuffs_base__status__is_error(&v_ddf_status) || (v_scan_count < self->private_impl.f_scan_count))) {
47789 if (self->private_impl.f_sof_marker >= 194u) {
47790 wuffs_jpeg__decoder__apply_progressive_idct(self, a_workbuf);
47792 if (self->private_impl.f_num_components == 1u) {
47793 v_swizzle_status = wuffs_jpeg__decoder__swizzle_gray(self,
47794 a_dst,
47795 a_workbuf,
47797 4294967295u,
47799 4294967295u,
47800 ((uint64_t)(self->private_impl.f_components_workbuf_widths[0u])));
47801 } else {
47802 v_swizzle_status = wuffs_jpeg__decoder__swizzle_colorful(self,
47803 a_dst,
47804 a_workbuf,
47806 4294967295u,
47808 4294967295u);
47810 if (wuffs_base__status__is_error(&v_ddf_status)) {
47811 status = v_ddf_status;
47812 goto exit;
47813 } else if (wuffs_base__status__is_error(&v_swizzle_status)) {
47814 status = v_swizzle_status;
47815 goto exit;
47818 status = v_ddf_status;
47819 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
47823 self->private_impl.p_decode_frame = 0;
47824 goto exit;
47827 goto suspend;
47828 suspend:
47829 self->private_impl.p_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
47830 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
47832 goto exit;
47833 exit:
47834 if (wuffs_base__status__is_error(&status)) {
47835 self->private_impl.magic = WUFFS_BASE__DISABLED;
47837 return status;
47840 // -------- func jpeg.decoder.do_decode_frame
47842 WUFFS_BASE__GENERATED_C_CODE
47843 static wuffs_base__status
47844 wuffs_jpeg__decoder__do_decode_frame(
47845 wuffs_jpeg__decoder* self,
47846 wuffs_base__pixel_buffer* a_dst,
47847 wuffs_base__io_buffer* a_src,
47848 wuffs_base__pixel_blend a_blend,
47849 wuffs_base__slice_u8 a_workbuf,
47850 wuffs_base__decode_frame_options* a_opts) {
47851 wuffs_base__status status = wuffs_base__make_status(NULL);
47853 uint32_t v_pixfmt = 0;
47854 wuffs_base__status v_status = wuffs_base__make_status(NULL);
47855 uint8_t v_c8 = 0;
47856 uint8_t v_marker = 0;
47858 const uint8_t* iop_a_src = NULL;
47859 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
47860 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
47861 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
47862 if (a_src && a_src->data.ptr) {
47863 io0_a_src = a_src->data.ptr;
47864 io1_a_src = io0_a_src + a_src->meta.ri;
47865 iop_a_src = io1_a_src;
47866 io2_a_src = io0_a_src + a_src->meta.wi;
47869 uint32_t coro_susp_point = self->private_impl.p_do_decode_frame;
47870 if (coro_susp_point) {
47871 v_marker = self->private_data.s_do_decode_frame.v_marker;
47873 switch (coro_susp_point) {
47874 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
47876 if (self->private_impl.f_call_sequence == 64u) {
47877 } else if (self->private_impl.f_call_sequence < 64u) {
47878 if (a_src) {
47879 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
47881 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
47882 status = wuffs_jpeg__decoder__do_decode_frame_config(self, NULL, a_src);
47883 if (a_src) {
47884 iop_a_src = a_src->data.ptr + a_src->meta.ri;
47886 if (status.repr) {
47887 goto suspend;
47889 } else {
47890 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
47891 goto ok;
47893 v_pixfmt = 536870920u;
47894 if (self->private_impl.f_num_components > 1u) {
47895 v_pixfmt = 2415954056u;
47897 v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
47898 wuffs_base__pixel_buffer__pixel_format(a_dst),
47899 wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)),
47900 wuffs_base__utility__make_pixel_format(v_pixfmt),
47901 wuffs_base__utility__empty_slice_u8(),
47902 a_blend);
47903 if ( ! wuffs_base__status__is_ok(&v_status)) {
47904 status = v_status;
47905 if (wuffs_base__status__is_error(&status)) {
47906 goto exit;
47907 } else if (wuffs_base__status__is_suspension(&status)) {
47908 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
47909 goto exit;
47911 goto ok;
47913 self->private_impl.f_swizzle_immediately = false;
47914 if (self->private_impl.f_components_workbuf_offsets[8u] > ((uint64_t)(a_workbuf.len))) {
47915 if (self->private_impl.f_sof_marker >= 194u) {
47916 status = wuffs_base__make_status(wuffs_base__error__bad_workbuf_length);
47917 goto exit;
47919 self->private_impl.f_swizzle_immediately = self->private_impl.f_use_lower_quality;
47920 self->private_impl.f_swizzle_immediately_status = wuffs_base__make_status(NULL);
47921 } else if (self->private_impl.f_components_workbuf_offsets[4u] < self->private_impl.f_components_workbuf_offsets[8u]) {
47922 wuffs_private_impl__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);
47924 if (self->private_impl.f_components_workbuf_offsets[4u] <= ((uint64_t)(a_workbuf.len))) {
47925 wuffs_private_impl__bulk_memset(a_workbuf.ptr, self->private_impl.f_components_workbuf_offsets[4u], 128u);
47927 while (true) {
47928 while (true) {
47930 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
47931 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
47932 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
47933 goto suspend;
47935 uint8_t t_0 = *iop_a_src++;
47936 v_c8 = t_0;
47938 if (v_c8 == 255u) {
47939 break;
47942 while (true) {
47944 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
47945 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
47946 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
47947 goto suspend;
47949 uint8_t t_1 = *iop_a_src++;
47950 v_c8 = t_1;
47952 if (v_c8 != 255u) {
47953 v_marker = v_c8;
47954 break;
47957 if (v_marker == 0u) {
47958 continue;
47959 } else if ((208u <= v_marker) && (v_marker <= 217u)) {
47960 if (v_marker <= 215u) {
47961 continue;
47963 } else {
47965 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
47966 uint32_t t_2;
47967 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
47968 t_2 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
47969 iop_a_src += 2;
47970 } else {
47971 self->private_data.s_do_decode_frame.scratch = 0;
47972 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
47973 while (true) {
47974 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
47975 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
47976 goto suspend;
47978 uint64_t* scratch = &self->private_data.s_do_decode_frame.scratch;
47979 uint32_t num_bits_2 = ((uint32_t)(*scratch & 0xFFu));
47980 *scratch >>= 8;
47981 *scratch <<= 8;
47982 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_2);
47983 if (num_bits_2 == 8) {
47984 t_2 = ((uint32_t)(*scratch >> 48));
47985 break;
47987 num_bits_2 += 8u;
47988 *scratch |= ((uint64_t)(num_bits_2));
47991 self->private_impl.f_payload_length = t_2;
47993 if (self->private_impl.f_payload_length < 2u) {
47994 status = wuffs_base__make_status(wuffs_jpeg__error__bad_marker);
47995 goto exit;
47997 self->private_impl.f_payload_length -= 2u;
47999 if (v_marker < 192u) {
48000 status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker);
48001 goto exit;
48002 } else if (v_marker < 208u) {
48003 if (v_marker == 196u) {
48004 if (a_src) {
48005 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
48007 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
48008 status = wuffs_jpeg__decoder__decode_dht(self, a_src);
48009 if (a_src) {
48010 iop_a_src = a_src->data.ptr + a_src->meta.ri;
48012 if (status.repr) {
48013 goto suspend;
48015 continue;
48016 } else if (v_marker == 200u) {
48017 status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker);
48018 goto exit;
48020 status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker);
48021 goto exit;
48022 } else if (v_marker < 224u) {
48023 if (v_marker < 217u) {
48024 status = wuffs_base__make_status(wuffs_jpeg__error__bad_marker);
48025 goto exit;
48026 } else if (v_marker == 217u) {
48027 break;
48028 } else if (v_marker == 218u) {
48029 if (a_src) {
48030 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
48032 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
48033 status = wuffs_jpeg__decoder__decode_sos(self, a_dst, a_src, a_workbuf);
48034 if (a_src) {
48035 iop_a_src = a_src->data.ptr + a_src->meta.ri;
48037 if (status.repr) {
48038 goto suspend;
48040 continue;
48041 } else if (v_marker == 219u) {
48042 if (a_src) {
48043 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
48045 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
48046 status = wuffs_jpeg__decoder__decode_dqt(self, a_src);
48047 if (a_src) {
48048 iop_a_src = a_src->data.ptr + a_src->meta.ri;
48050 if (status.repr) {
48051 goto suspend;
48053 continue;
48054 } else if (v_marker == 221u) {
48055 if (a_src) {
48056 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
48058 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
48059 status = wuffs_jpeg__decoder__decode_dri(self, a_src);
48060 if (a_src) {
48061 iop_a_src = a_src->data.ptr + a_src->meta.ri;
48063 if (status.repr) {
48064 goto suspend;
48066 continue;
48067 } else {
48068 status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker);
48069 goto exit;
48071 } else if (v_marker < 240u) {
48072 } else {
48073 if (v_marker == 254u) {
48074 } else {
48075 status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker);
48076 goto exit;
48079 self->private_data.s_do_decode_frame.scratch = self->private_impl.f_payload_length;
48080 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
48081 if (self->private_data.s_do_decode_frame.scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
48082 self->private_data.s_do_decode_frame.scratch -= ((uint64_t)(io2_a_src - iop_a_src));
48083 iop_a_src = io2_a_src;
48084 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
48085 goto suspend;
48087 iop_a_src += self->private_data.s_do_decode_frame.scratch;
48088 self->private_impl.f_payload_length = 0u;
48090 self->private_impl.f_call_sequence = 96u;
48093 self->private_impl.p_do_decode_frame = 0;
48094 goto exit;
48097 goto suspend;
48098 suspend:
48099 self->private_impl.p_do_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
48100 self->private_data.s_do_decode_frame.v_marker = v_marker;
48102 goto exit;
48103 exit:
48104 if (a_src && a_src->data.ptr) {
48105 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
48108 return status;
48111 // -------- func jpeg.decoder.decode_dht
48113 WUFFS_BASE__GENERATED_C_CODE
48114 static wuffs_base__status
48115 wuffs_jpeg__decoder__decode_dht(
48116 wuffs_jpeg__decoder* self,
48117 wuffs_base__io_buffer* a_src) {
48118 wuffs_base__status status = wuffs_base__make_status(NULL);
48120 uint8_t v_c8 = 0;
48121 uint8_t v_tc = 0;
48122 uint8_t v_th = 0;
48123 uint8_t v_tc4_th = 0;
48124 uint32_t v_working_total_count = 0;
48125 uint32_t v_total_count = 0;
48126 uint32_t v_i = 0;
48127 bool v_failed = false;
48129 const uint8_t* iop_a_src = NULL;
48130 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48131 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48132 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48133 if (a_src && a_src->data.ptr) {
48134 io0_a_src = a_src->data.ptr;
48135 io1_a_src = io0_a_src + a_src->meta.ri;
48136 iop_a_src = io1_a_src;
48137 io2_a_src = io0_a_src + a_src->meta.wi;
48140 uint32_t coro_susp_point = self->private_impl.p_decode_dht;
48141 if (coro_susp_point) {
48142 v_tc4_th = self->private_data.s_decode_dht.v_tc4_th;
48143 v_total_count = self->private_data.s_decode_dht.v_total_count;
48144 v_i = self->private_data.s_decode_dht.v_i;
48146 switch (coro_susp_point) {
48147 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
48149 if (self->private_impl.f_sof_marker == 0u) {
48150 status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker);
48151 goto exit;
48153 while (self->private_impl.f_payload_length > 0u) {
48154 if (self->private_impl.f_payload_length < 17u) {
48155 status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker);
48156 goto exit;
48158 self->private_impl.f_payload_length -= 17u;
48160 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
48161 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
48162 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
48163 goto suspend;
48165 uint8_t t_0 = *iop_a_src++;
48166 v_c8 = t_0;
48168 if ((((uint8_t)(v_c8 >> 4u)) > 1u) || (((uint8_t)(v_c8 & 15u)) > 3u)) {
48169 status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker);
48170 goto exit;
48172 v_tc = ((uint8_t)(v_c8 >> 4u));
48173 v_th = ((uint8_t)(v_c8 & 15u));
48174 v_tc4_th = ((uint8_t)(((uint8_t)(((uint8_t)(v_tc * 4u)) | v_th))));
48175 if ((self->private_impl.f_sof_marker == 192u) && (((uint8_t)(v_tc4_th & 3u)) > 1u)) {
48176 status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker);
48177 goto exit;
48179 v_i = 0u;
48180 while (v_i < 16u) {
48182 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
48183 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
48184 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
48185 goto suspend;
48187 uint8_t t_1 = *iop_a_src++;
48188 self->private_data.f_dht_temp_counts[v_i] = t_1;
48190 v_i += 1u;
48192 v_working_total_count = 0u;
48193 v_i = 0u;
48194 while (v_i < 16u) {
48195 v_working_total_count = ((v_working_total_count + ((uint32_t)(self->private_data.f_dht_temp_counts[v_i]))) & 65535u);
48196 v_i += 1u;
48198 if ((v_working_total_count <= 0u) || (256u < v_working_total_count)) {
48199 status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker);
48200 goto exit;
48202 v_total_count = v_working_total_count;
48203 if (self->private_impl.f_payload_length < v_total_count) {
48204 status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker);
48205 goto exit;
48207 self->private_impl.f_payload_length -= v_total_count;
48208 v_i = 0u;
48209 while (v_i < v_total_count) {
48211 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
48212 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
48213 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
48214 goto suspend;
48216 uint8_t t_2 = *iop_a_src++;
48217 self->private_impl.f_huff_tables_symbols[v_tc4_th][v_i] = t_2;
48219 v_i += 1u;
48221 while (v_i < 256u) {
48222 self->private_impl.f_huff_tables_symbols[v_tc4_th][v_i] = 0u;
48223 v_i += 1u;
48225 if (((uint8_t)(v_tc4_th & 4u)) == 0u) {
48226 v_i = 0u;
48227 while (v_i < v_total_count) {
48228 if (self->private_impl.f_huff_tables_symbols[v_tc4_th][v_i] > 15u) {
48229 status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker);
48230 goto exit;
48232 v_i += 1u;
48235 v_failed = wuffs_jpeg__decoder__calculate_huff_tables(self, v_tc4_th, v_total_count);
48236 if (v_failed) {
48237 status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker);
48238 goto exit;
48240 self->private_impl.f_seen_dht[v_tc4_th] = true;
48243 goto ok;
48245 self->private_impl.p_decode_dht = 0;
48246 goto exit;
48249 goto suspend;
48250 suspend:
48251 self->private_impl.p_decode_dht = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
48252 self->private_data.s_decode_dht.v_tc4_th = v_tc4_th;
48253 self->private_data.s_decode_dht.v_total_count = v_total_count;
48254 self->private_data.s_decode_dht.v_i = v_i;
48256 goto exit;
48257 exit:
48258 if (a_src && a_src->data.ptr) {
48259 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
48262 return status;
48265 // -------- func jpeg.decoder.calculate_huff_tables
48267 WUFFS_BASE__GENERATED_C_CODE
48268 static bool
48269 wuffs_jpeg__decoder__calculate_huff_tables(
48270 wuffs_jpeg__decoder* self,
48271 uint8_t a_tc4_th,
48272 uint32_t a_total_count) {
48273 uint32_t v_i = 0;
48274 uint8_t v_j = 0;
48275 uint8_t v_k = 0;
48276 uint32_t v_bit_length_minus_one = 0;
48277 uint8_t v_bit_length = 0;
48278 uint32_t v_bit_string = 0;
48279 uint32_t v_slow = 0;
48280 uint8_t v_prefix = 0;
48281 uint16_t v_fast = 0;
48282 uint32_t v_reps = 0;
48284 v_i = 0u;
48285 v_k = 0u;
48286 v_bit_length_minus_one = 0u;
48287 while (v_i < a_total_count) {
48288 while (v_k >= self->private_data.f_dht_temp_counts[v_bit_length_minus_one]) {
48289 v_k = 0u;
48290 v_bit_length_minus_one = ((v_bit_length_minus_one + 1u) & 15u);
48292 #if defined(__GNUC__)
48293 #pragma GCC diagnostic push
48294 #pragma GCC diagnostic ignored "-Wconversion"
48295 #endif
48296 v_k += 1u;
48297 #if defined(__GNUC__)
48298 #pragma GCC diagnostic pop
48299 #endif
48300 self->private_data.f_dht_temp_bit_lengths[v_i] = ((uint8_t)((v_bit_length_minus_one + 1u)));
48301 v_i += 1u;
48303 v_bit_length = 0u;
48304 v_bit_string = 0u;
48305 v_i = 0u;
48306 while (v_i < a_total_count) {
48307 while (v_bit_length < self->private_data.f_dht_temp_bit_lengths[v_i]) {
48308 if (v_bit_length >= 16u) {
48309 return true;
48311 #if defined(__GNUC__)
48312 #pragma GCC diagnostic push
48313 #pragma GCC diagnostic ignored "-Wconversion"
48314 #endif
48315 v_bit_length += 1u;
48316 #if defined(__GNUC__)
48317 #pragma GCC diagnostic pop
48318 #endif
48319 v_bit_string <<= 1u;
48321 self->private_data.f_dht_temp_bit_strings[v_i] = ((uint16_t)(v_bit_string));
48322 v_bit_string += 1u;
48323 if ((v_bit_string >> v_bit_length) > 0u) {
48324 return true;
48326 v_i += 1u;
48328 v_k = 0u;
48329 v_bit_length_minus_one = 0u;
48330 while (true) {
48331 if (self->private_data.f_dht_temp_counts[v_bit_length_minus_one] == 0u) {
48332 self->private_impl.f_huff_tables_slow[a_tc4_th][v_bit_length_minus_one] = 0u;
48333 } else {
48334 v_slow = (255u & ((uint32_t)(((uint32_t)(v_k)) - ((uint32_t)(self->private_data.f_dht_temp_bit_strings[v_k])))));
48335 #if defined(__GNUC__)
48336 #pragma GCC diagnostic push
48337 #pragma GCC diagnostic ignored "-Wconversion"
48338 #endif
48339 v_k += self->private_data.f_dht_temp_counts[v_bit_length_minus_one];
48340 #if defined(__GNUC__)
48341 #pragma GCC diagnostic pop
48342 #endif
48343 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));
48345 v_bit_length_minus_one = ((v_bit_length_minus_one + 1u) & 15u);
48346 if (v_bit_length_minus_one == 0u) {
48347 break;
48350 v_i = 0u;
48351 while (v_i < 256u) {
48352 self->private_impl.f_huff_tables_fast[a_tc4_th][v_i] = 65535u;
48353 v_i += 1u;
48355 v_j = 0u;
48356 v_bit_length_minus_one = 0u;
48357 while (v_bit_length_minus_one < 8u) {
48358 v_k = 0u;
48359 while (v_k < self->private_data.f_dht_temp_counts[v_bit_length_minus_one]) {
48360 v_prefix = ((uint8_t)((((uint32_t)(self->private_data.f_dht_temp_bit_strings[v_j])) << (7u - v_bit_length_minus_one))));
48361 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])))));
48362 v_reps = (((uint32_t)(1u)) << (7u - v_bit_length_minus_one));
48363 while (v_reps > 0u) {
48364 self->private_impl.f_huff_tables_fast[a_tc4_th][v_prefix] = v_fast;
48365 #if defined(__GNUC__)
48366 #pragma GCC diagnostic push
48367 #pragma GCC diagnostic ignored "-Wconversion"
48368 #endif
48369 v_prefix += 1u;
48370 #if defined(__GNUC__)
48371 #pragma GCC diagnostic pop
48372 #endif
48373 v_reps -= 1u;
48375 #if defined(__GNUC__)
48376 #pragma GCC diagnostic push
48377 #pragma GCC diagnostic ignored "-Wconversion"
48378 #endif
48379 v_k += 1u;
48380 v_j += 1u;
48381 #if defined(__GNUC__)
48382 #pragma GCC diagnostic pop
48383 #endif
48385 v_bit_length_minus_one += 1u;
48387 return false;
48390 // -------- func jpeg.decoder.decode_sos
48392 WUFFS_BASE__GENERATED_C_CODE
48393 static wuffs_base__status
48394 wuffs_jpeg__decoder__decode_sos(
48395 wuffs_jpeg__decoder* self,
48396 wuffs_base__pixel_buffer* a_dst,
48397 wuffs_base__io_buffer* a_src,
48398 wuffs_base__slice_u8 a_workbuf) {
48399 wuffs_base__status status = wuffs_base__make_status(NULL);
48401 uint32_t v_my = 0;
48402 uint32_t v_mx = 0;
48403 uint32_t v_decode_mcu_result = 0;
48404 uint32_t v_bitstream_length = 0;
48406 uint32_t coro_susp_point = self->private_impl.p_decode_sos;
48407 if (coro_susp_point) {
48408 v_my = self->private_data.s_decode_sos.v_my;
48409 v_mx = self->private_data.s_decode_sos.v_mx;
48411 switch (coro_susp_point) {
48412 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
48414 if (self->private_impl.f_scan_count >= 32u) {
48415 status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_scan_count);
48416 goto exit;
48417 } else if ((self->private_impl.f_scan_count > 0u) && ! self->private_impl.f_expect_multiple_scans) {
48418 status = wuffs_base__make_status(wuffs_jpeg__error__bad_scan_count);
48419 goto exit;
48421 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
48422 status = wuffs_jpeg__decoder__prepare_scan(self, a_src);
48423 if (status.repr) {
48424 goto suspend;
48426 self->private_impl.f_next_restart_marker = 0u;
48427 self->private_impl.f_mcu_previous_dc_values[0u] = 0u;
48428 self->private_impl.f_mcu_previous_dc_values[1u] = 0u;
48429 self->private_impl.f_mcu_previous_dc_values[2u] = 0u;
48430 self->private_impl.f_mcu_previous_dc_values[3u] = 0u;
48431 self->private_impl.f_restarts_remaining = self->private_impl.f_restart_interval;
48432 self->private_impl.f_eob_run = 0u;
48433 self->private_impl.f_bitstream_bits = 0u;
48434 self->private_impl.f_bitstream_n_bits = 0u;
48435 self->private_impl.f_bitstream_ri = 0u;
48436 self->private_impl.f_bitstream_wi = 0u;
48437 self->private_impl.f_bitstream_padding = 12345u;
48438 wuffs_jpeg__decoder__fill_bitstream(self, a_src);
48439 v_my = 0u;
48440 while (v_my < self->private_impl.f_scan_height_in_mcus) {
48441 v_mx = 0u;
48442 while (v_mx < self->private_impl.f_scan_width_in_mcus) {
48443 self->private_impl.f_mcu_current_block = 0u;
48444 self->private_impl.f_mcu_zig_index = ((uint32_t)(self->private_impl.f_scan_ss));
48445 if (self->private_impl.f_sof_marker >= 194u) {
48446 wuffs_jpeg__decoder__load_mcu_blocks(self, v_mx, v_my, a_workbuf);
48448 while (true) {
48449 v_decode_mcu_result = wuffs_jpeg__decoder__decode_mcu(self,
48450 a_dst,
48451 a_workbuf,
48452 v_mx,
48453 v_my);
48454 if (v_decode_mcu_result == 0u) {
48455 break;
48456 } else if (v_decode_mcu_result == 1u) {
48457 } else if (v_decode_mcu_result == 2u) {
48458 status = wuffs_base__make_status(wuffs_jpeg__error__internal_error_inconsistent_decoder_state);
48459 goto exit;
48460 } else {
48461 status = self->private_impl.f_swizzle_immediately_status;
48462 if (wuffs_base__status__is_error(&status)) {
48463 goto exit;
48464 } else if (wuffs_base__status__is_suspension(&status)) {
48465 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
48466 goto exit;
48468 goto ok;
48470 while (true) {
48471 v_bitstream_length = ((uint32_t)(self->private_impl.f_bitstream_wi - self->private_impl.f_bitstream_ri));
48472 wuffs_jpeg__decoder__fill_bitstream(self, a_src);
48473 if (v_bitstream_length < ((uint32_t)(self->private_impl.f_bitstream_wi - self->private_impl.f_bitstream_ri))) {
48474 break;
48475 } else if (self->private_impl.f_bitstream_padding == 0u) {
48476 status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
48477 goto exit;
48478 } else if ((a_src && a_src->meta.closed) && ! self->private_impl.f_bitstream_is_closed) {
48479 if (self->private_impl.f_bitstream_wi < 1024u) {
48480 wuffs_private_impl__bulk_memset(&self->private_data.f_bitstream_buffer[self->private_impl.f_bitstream_wi], 264u, 0u);
48481 self->private_impl.f_bitstream_wi += 264u;
48482 self->private_impl.f_bitstream_is_closed = true;
48484 break;
48486 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
48487 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
48490 if (self->private_impl.f_sof_marker >= 194u) {
48491 wuffs_jpeg__decoder__save_mcu_blocks(self, v_mx, v_my, a_workbuf);
48493 if (self->private_impl.f_restarts_remaining > 0u) {
48494 #if defined(__GNUC__)
48495 #pragma GCC diagnostic push
48496 #pragma GCC diagnostic ignored "-Wconversion"
48497 #endif
48498 self->private_impl.f_restarts_remaining -= 1u;
48499 #if defined(__GNUC__)
48500 #pragma GCC diagnostic pop
48501 #endif
48502 if (self->private_impl.f_restarts_remaining == 0u) {
48503 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
48504 status = wuffs_jpeg__decoder__skip_past_the_next_restart_marker(self, a_src);
48505 if (status.repr) {
48506 goto suspend;
48508 self->private_impl.f_mcu_previous_dc_values[0u] = 0u;
48509 self->private_impl.f_mcu_previous_dc_values[1u] = 0u;
48510 self->private_impl.f_mcu_previous_dc_values[2u] = 0u;
48511 self->private_impl.f_mcu_previous_dc_values[3u] = 0u;
48512 self->private_impl.f_restarts_remaining = self->private_impl.f_restart_interval;
48513 self->private_impl.f_eob_run = 0u;
48514 self->private_impl.f_bitstream_bits = 0u;
48515 self->private_impl.f_bitstream_n_bits = 0u;
48516 self->private_impl.f_bitstream_ri = 0u;
48517 self->private_impl.f_bitstream_wi = 0u;
48518 self->private_impl.f_bitstream_padding = 12345u;
48521 v_mx += 1u;
48523 v_my += 1u;
48525 wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_scan_count, 1u);
48528 self->private_impl.p_decode_sos = 0;
48529 goto exit;
48532 goto suspend;
48533 suspend:
48534 self->private_impl.p_decode_sos = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
48535 self->private_data.s_decode_sos.v_my = v_my;
48536 self->private_data.s_decode_sos.v_mx = v_mx;
48538 goto exit;
48539 exit:
48540 return status;
48543 // -------- func jpeg.decoder.prepare_scan
48545 WUFFS_BASE__GENERATED_C_CODE
48546 static wuffs_base__status
48547 wuffs_jpeg__decoder__prepare_scan(
48548 wuffs_jpeg__decoder* self,
48549 wuffs_base__io_buffer* a_src) {
48550 wuffs_base__status status = wuffs_base__make_status(NULL);
48552 uint8_t v_c8 = 0;
48553 uint32_t v_i = 0;
48554 uint32_t v_j = 0;
48555 uint32_t v_j_max_incl = 0;
48556 bool v_failed = false;
48558 const uint8_t* iop_a_src = NULL;
48559 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48560 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48561 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48562 if (a_src && a_src->data.ptr) {
48563 io0_a_src = a_src->data.ptr;
48564 io1_a_src = io0_a_src + a_src->meta.ri;
48565 iop_a_src = io1_a_src;
48566 io2_a_src = io0_a_src + a_src->meta.wi;
48569 uint32_t coro_susp_point = self->private_impl.p_prepare_scan;
48570 if (coro_susp_point) {
48571 v_i = self->private_data.s_prepare_scan.v_i;
48573 switch (coro_susp_point) {
48574 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
48576 if ((self->private_impl.f_payload_length < 6u) || (self->private_impl.f_payload_length > 12u)) {
48577 status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
48578 goto exit;
48581 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
48582 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
48583 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
48584 goto suspend;
48586 uint8_t t_0 = *iop_a_src++;
48587 v_c8 = t_0;
48589 if ((v_c8 < 1u) || (v_c8 > 4u)) {
48590 status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
48591 goto exit;
48593 self->private_impl.f_scan_num_components = ((uint32_t)(v_c8));
48594 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)))) {
48595 status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
48596 goto exit;
48598 self->private_impl.f_payload_length = 0u;
48599 v_i = 0u;
48600 while (v_i < self->private_impl.f_scan_num_components) {
48602 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
48603 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
48604 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
48605 goto suspend;
48607 uint8_t t_1 = *iop_a_src++;
48608 v_c8 = t_1;
48610 v_j = 0u;
48611 while (true) {
48612 if (v_j >= self->private_impl.f_num_components) {
48613 status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
48614 goto exit;
48616 if (v_c8 == self->private_impl.f_components_c[v_j]) {
48617 if ( ! self->private_impl.f_seen_dqt[self->private_impl.f_components_tq[v_j]]) {
48618 status = wuffs_base__make_status(wuffs_jpeg__error__missing_quantization_table);
48619 goto exit;
48621 self->private_impl.f_scan_comps_cselector[v_i] = ((uint8_t)(v_j));
48622 break;
48624 v_j += 1u;
48626 v_j = 0u;
48627 while (v_j < v_i) {
48628 if (self->private_impl.f_scan_comps_cselector[v_i] == self->private_impl.f_scan_comps_cselector[v_j]) {
48629 status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
48630 goto exit;
48632 v_j += 1u;
48635 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
48636 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
48637 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
48638 goto suspend;
48640 uint8_t t_2 = *iop_a_src++;
48641 v_c8 = t_2;
48643 if ((((uint8_t)(v_c8 >> 4u)) > 3u) || (((uint8_t)(v_c8 & 15u)) > 3u)) {
48644 status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
48645 goto exit;
48647 self->private_impl.f_scan_comps_td[v_i] = ((uint8_t)(v_c8 >> 4u));
48648 self->private_impl.f_scan_comps_ta[v_i] = ((uint8_t)(v_c8 & 15u));
48649 if (self->private_impl.f_sof_marker == 192u) {
48650 if ((self->private_impl.f_scan_comps_td[v_i] > 1u) || (self->private_impl.f_scan_comps_ta[v_i] > 1u)) {
48651 status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
48652 goto exit;
48655 v_i += 1u;
48657 if (self->private_impl.f_scan_count == 0u) {
48658 self->private_impl.f_expect_multiple_scans = ((self->private_impl.f_sof_marker >= 194u) || (self->private_impl.f_scan_num_components < self->private_impl.f_num_components));
48660 if (self->private_impl.f_sof_marker < 194u) {
48661 self->private_data.s_prepare_scan.scratch = 3u;
48662 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
48663 if (self->private_data.s_prepare_scan.scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
48664 self->private_data.s_prepare_scan.scratch -= ((uint64_t)(io2_a_src - iop_a_src));
48665 iop_a_src = io2_a_src;
48666 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
48667 goto suspend;
48669 iop_a_src += self->private_data.s_prepare_scan.scratch;
48670 self->private_impl.f_scan_ss = 0u;
48671 self->private_impl.f_scan_se = 63u;
48672 self->private_impl.f_scan_ah = 0u;
48673 self->private_impl.f_scan_al = 0u;
48674 } else {
48676 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
48677 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
48678 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
48679 goto suspend;
48681 uint8_t t_3 = *iop_a_src++;
48682 v_c8 = t_3;
48684 if (v_c8 > 63u) {
48685 status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
48686 goto exit;
48688 self->private_impl.f_scan_ss = v_c8;
48690 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
48691 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
48692 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
48693 goto suspend;
48695 uint8_t t_4 = *iop_a_src++;
48696 v_c8 = t_4;
48698 if ((v_c8 > 63u) || (v_c8 < self->private_impl.f_scan_ss)) {
48699 status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
48700 goto exit;
48702 self->private_impl.f_scan_se = v_c8;
48704 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
48705 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
48706 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
48707 goto suspend;
48709 uint8_t t_5 = *iop_a_src++;
48710 v_c8 = t_5;
48712 if ((((uint8_t)(v_c8 >> 4u)) > 14u) || (((uint8_t)(v_c8 & 15u)) > 13u)) {
48713 status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
48714 goto exit;
48716 self->private_impl.f_scan_ah = ((uint8_t)(v_c8 >> 4u));
48717 self->private_impl.f_scan_al = ((uint8_t)(v_c8 & 15u));
48718 if (self->private_impl.f_scan_ah > 0u) {
48719 if (((uint8_t)(self->private_impl.f_scan_ah - 1u)) != self->private_impl.f_scan_al) {
48720 status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
48721 goto exit;
48724 if (self->private_impl.f_scan_ss == 0u) {
48725 if (self->private_impl.f_scan_se != 0u) {
48726 status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
48727 goto exit;
48728 } else if (self->private_impl.f_scan_ah == 0u) {
48729 self->private_impl.choosy_decode_mcu = (
48730 &wuffs_jpeg__decoder__decode_mcu_progressive_dc_high_bits);
48731 } else {
48732 self->private_impl.choosy_decode_mcu = (
48733 &wuffs_jpeg__decoder__decode_mcu_progressive_dc_low_bit);
48735 } else {
48736 if (self->private_impl.f_scan_num_components != 1u) {
48737 status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
48738 goto exit;
48739 } else if (self->private_impl.f_scan_ah == 0u) {
48740 self->private_impl.choosy_decode_mcu = (
48741 &wuffs_jpeg__decoder__decode_mcu_progressive_ac_high_bits);
48742 } else {
48743 self->private_impl.choosy_decode_mcu = (
48744 &wuffs_jpeg__decoder__decode_mcu_progressive_ac_low_bit);
48748 v_i = 0u;
48749 while (v_i < self->private_impl.f_scan_num_components) {
48750 if ((self->private_impl.f_scan_ss == 0u) && ! self->private_impl.f_seen_dht[((uint8_t)(0u | self->private_impl.f_scan_comps_td[v_i]))]) {
48751 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
48752 status = wuffs_jpeg__decoder__use_default_huffman_table(self, ((uint8_t)(0u | self->private_impl.f_scan_comps_td[v_i])));
48753 if (status.repr) {
48754 goto suspend;
48757 if ((self->private_impl.f_scan_se != 0u) && ! self->private_impl.f_seen_dht[((uint8_t)(4u | self->private_impl.f_scan_comps_ta[v_i]))]) {
48758 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
48759 status = wuffs_jpeg__decoder__use_default_huffman_table(self, ((uint8_t)(4u | self->private_impl.f_scan_comps_ta[v_i])));
48760 if (status.repr) {
48761 goto suspend;
48764 v_j = ((uint32_t)(self->private_impl.f_scan_ss));
48765 v_j_max_incl = ((uint32_t)(wuffs_base__u8__min(self->private_impl.f_scan_se, 9u)));
48766 while (v_j <= v_j_max_incl) {
48767 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;
48768 v_j += 1u;
48770 v_i += 1u;
48772 if (self->private_impl.f_scan_num_components == 1u) {
48773 wuffs_jpeg__decoder__calculate_single_component_scan_fields(self);
48774 } else {
48775 v_failed = wuffs_jpeg__decoder__calculate_multiple_component_scan_fields(self);
48776 if (v_failed) {
48777 status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
48778 goto exit;
48782 goto ok;
48784 self->private_impl.p_prepare_scan = 0;
48785 goto exit;
48788 goto suspend;
48789 suspend:
48790 self->private_impl.p_prepare_scan = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
48791 self->private_data.s_prepare_scan.v_i = v_i;
48793 goto exit;
48794 exit:
48795 if (a_src && a_src->data.ptr) {
48796 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
48799 return status;
48802 // -------- func jpeg.decoder.use_default_huffman_table
48804 WUFFS_BASE__GENERATED_C_CODE
48805 static wuffs_base__status
48806 wuffs_jpeg__decoder__use_default_huffman_table(
48807 wuffs_jpeg__decoder* self,
48808 uint8_t a_tc4_th) {
48809 wuffs_base__status status = wuffs_base__make_status(NULL);
48811 wuffs_base__slice_u8 v_data = {0};
48812 wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer();
48813 wuffs_base__io_buffer* v_r = &u_r;
48814 const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48815 const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48816 const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48817 const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48818 wuffs_base__status v_status = wuffs_base__make_status(NULL);
48820 if (a_tc4_th == 0u) {
48821 v_data = wuffs_base__make_slice_u8(wuffs_base__strip_const_from_u8_ptr(WUFFS_JPEG__DEFAULT_HUFF_TABLE_DC_LUMA), 29);
48822 } else if (a_tc4_th == 1u) {
48823 v_data = wuffs_base__make_slice_u8(wuffs_base__strip_const_from_u8_ptr(WUFFS_JPEG__DEFAULT_HUFF_TABLE_DC_CHROMA), 29);
48824 } else if (a_tc4_th == 4u) {
48825 v_data = wuffs_base__make_slice_u8(wuffs_base__strip_const_from_u8_ptr(WUFFS_JPEG__DEFAULT_HUFF_TABLE_AC_LUMA), 179);
48826 } else if (a_tc4_th == 5u) {
48827 v_data = wuffs_base__make_slice_u8(wuffs_base__strip_const_from_u8_ptr(WUFFS_JPEG__DEFAULT_HUFF_TABLE_AC_CHROMA), 179);
48828 } else {
48829 status = wuffs_base__make_status(wuffs_jpeg__error__missing_huffman_table);
48830 goto exit;
48833 wuffs_base__io_buffer* o_0_v_r = v_r;
48834 const uint8_t* o_0_iop_v_r = iop_v_r;
48835 const uint8_t* o_0_io0_v_r = io0_v_r;
48836 const uint8_t* o_0_io1_v_r = io1_v_r;
48837 const uint8_t* o_0_io2_v_r = io2_v_r;
48838 v_r = wuffs_private_impl__io_reader__set(
48839 &u_r,
48840 &iop_v_r,
48841 &io0_v_r,
48842 &io1_v_r,
48843 &io2_v_r,
48844 v_data,
48845 0u);
48846 self->private_impl.f_payload_length = ((uint32_t)((((uint64_t)(v_data.len)) & 65535u)));
48848 wuffs_base__status t_0 = wuffs_jpeg__decoder__decode_dht(self, v_r);
48849 v_status = t_0;
48851 v_r = o_0_v_r;
48852 iop_v_r = o_0_iop_v_r;
48853 io0_v_r = o_0_io0_v_r;
48854 io1_v_r = o_0_io1_v_r;
48855 io2_v_r = o_0_io2_v_r;
48857 status = v_status;
48858 if (wuffs_base__status__is_error(&status)) {
48859 goto exit;
48860 } else if (wuffs_base__status__is_suspension(&status)) {
48861 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
48862 goto exit;
48864 goto ok;
48867 goto exit;
48868 exit:
48869 return status;
48872 // -------- func jpeg.decoder.calculate_single_component_scan_fields
48874 WUFFS_BASE__GENERATED_C_CODE
48875 static wuffs_base__empty_struct
48876 wuffs_jpeg__decoder__calculate_single_component_scan_fields(
48877 wuffs_jpeg__decoder* self) {
48878 uint8_t v_csel = 0;
48880 self->private_impl.f_scan_comps_bx_offset[0u] = 0u;
48881 self->private_impl.f_scan_comps_by_offset[0u] = 0u;
48882 self->private_impl.f_mcu_num_blocks = 1u;
48883 self->private_impl.f_mcu_blocks_sselector[0u] = 0u;
48884 v_csel = self->private_impl.f_scan_comps_cselector[0u];
48885 self->private_impl.f_mcu_blocks_offset[0u] = self->private_impl.f_components_workbuf_offsets[v_csel];
48886 self->private_impl.f_mcu_blocks_mx_mul[0u] = 8u;
48887 self->private_impl.f_mcu_blocks_my_mul[0u] = (8u * self->private_impl.f_components_workbuf_widths[v_csel]);
48888 self->private_impl.f_mcu_blocks_dc_hselector[0u] = ((uint8_t)(0u | self->private_impl.f_scan_comps_td[0u]));
48889 self->private_impl.f_mcu_blocks_ac_hselector[0u] = ((uint8_t)(4u | self->private_impl.f_scan_comps_ta[0u]));
48890 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);
48891 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);
48892 return wuffs_base__make_empty_struct();
48895 // -------- func jpeg.decoder.calculate_multiple_component_scan_fields
48897 WUFFS_BASE__GENERATED_C_CODE
48898 static bool
48899 wuffs_jpeg__decoder__calculate_multiple_component_scan_fields(
48900 wuffs_jpeg__decoder* self) {
48901 uint32_t v_i = 0;
48902 uint32_t v_h = 0;
48903 uint32_t v_v = 0;
48904 uint32_t v_hv = 0;
48905 uint32_t v_total_hv = 0;
48906 uint32_t v_b = 0;
48907 uint32_t v_bx_offset = 0;
48908 uint32_t v_by_offset = 0;
48909 uint32_t v_sibo = 0;
48910 uint8_t v_ssel = 0;
48911 uint8_t v_csel = 0;
48913 v_total_hv = 0u;
48914 v_i = 0u;
48915 v_b = 0u;
48916 v_bx_offset = 0u;
48917 v_by_offset = 0u;
48918 while (v_i < self->private_impl.f_scan_num_components) {
48919 v_h = ((uint32_t)(self->private_impl.f_components_h[self->private_impl.f_scan_comps_cselector[v_i]]));
48920 v_v = ((uint32_t)(self->private_impl.f_components_v[self->private_impl.f_scan_comps_cselector[v_i]]));
48921 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]])));
48922 self->private_impl.f_swizzle_immediately_c_offsets[v_i] = ((uint32_t)(64u * v_total_hv));
48923 v_total_hv += v_hv;
48924 while (v_hv > 0u) {
48925 self->private_impl.f_scan_comps_bx_offset[(v_b & 15u)] = ((uint8_t)((v_bx_offset & 3u)));
48926 self->private_impl.f_scan_comps_by_offset[(v_b & 15u)] = ((uint8_t)((v_by_offset & 3u)));
48927 self->private_impl.f_mcu_blocks_sselector[(v_b & 15u)] = ((uint8_t)(v_i));
48928 v_b += 1u;
48929 v_bx_offset += 1u;
48930 if (v_bx_offset == v_h) {
48931 v_bx_offset = 0u;
48932 v_by_offset += 1u;
48933 if (v_by_offset == v_v) {
48934 v_by_offset = 0u;
48937 v_hv -= 1u;
48939 v_i += 1u;
48941 if (v_total_hv > 10u) {
48942 return true;
48944 self->private_impl.f_mcu_num_blocks = v_total_hv;
48945 self->private_impl.f_swizzle_immediately_c_offsets[self->private_impl.f_scan_num_components] = ((uint32_t)(64u * v_total_hv));
48946 v_b = 0u;
48947 while (v_b < self->private_impl.f_mcu_num_blocks) {
48948 v_ssel = self->private_impl.f_mcu_blocks_sselector[v_b];
48949 v_csel = self->private_impl.f_scan_comps_cselector[v_ssel];
48950 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]))));
48951 self->private_impl.f_mcu_blocks_mx_mul[v_b] = (8u * ((uint32_t)(self->private_impl.f_components_h[v_csel])));
48952 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]);
48953 self->private_impl.f_mcu_blocks_dc_hselector[v_b] = ((uint8_t)(0u | self->private_impl.f_scan_comps_td[v_ssel]));
48954 self->private_impl.f_mcu_blocks_ac_hselector[v_b] = ((uint8_t)(4u | self->private_impl.f_scan_comps_ta[v_ssel]));
48955 v_sibo = ((uint32_t)(self->private_impl.f_swizzle_immediately_c_offsets[v_csel] + ((8u * ((uint32_t)(self->private_impl.f_scan_comps_bx_offset[v_b]))) + (64u * ((uint32_t)(self->private_impl.f_scan_comps_by_offset[v_b])) * ((uint32_t)(self->private_impl.f_components_h[v_csel]))))));
48956 self->private_impl.f_swizzle_immediately_b_offsets[v_b] = wuffs_base__u32__min(v_sibo, 576u);
48957 v_b += 1u;
48959 self->private_impl.f_scan_width_in_mcus = self->private_impl.f_width_in_mcus;
48960 self->private_impl.f_scan_height_in_mcus = self->private_impl.f_height_in_mcus;
48961 return false;
48964 // -------- func jpeg.decoder.fill_bitstream
48966 WUFFS_BASE__GENERATED_C_CODE
48967 static wuffs_base__empty_struct
48968 wuffs_jpeg__decoder__fill_bitstream(
48969 wuffs_jpeg__decoder* self,
48970 wuffs_base__io_buffer* a_src) {
48971 uint32_t v_wi = 0;
48972 uint8_t v_c8 = 0;
48973 uint32_t v_new_wi = 0;
48975 const uint8_t* iop_a_src = NULL;
48976 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48977 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48978 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48979 if (a_src && a_src->data.ptr) {
48980 io0_a_src = a_src->data.ptr;
48981 io1_a_src = io0_a_src + a_src->meta.ri;
48982 iop_a_src = io1_a_src;
48983 io2_a_src = io0_a_src + a_src->meta.wi;
48986 if (self->private_impl.f_bitstream_ri <= 0u) {
48987 } else if (self->private_impl.f_bitstream_ri >= self->private_impl.f_bitstream_wi) {
48988 self->private_impl.f_bitstream_ri = 0u;
48989 self->private_impl.f_bitstream_wi = 0u;
48990 } else {
48991 v_wi = (self->private_impl.f_bitstream_wi - self->private_impl.f_bitstream_ri);
48992 wuffs_private_impl__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,
48993 self->private_impl.f_bitstream_ri,
48994 self->private_impl.f_bitstream_wi));
48995 self->private_impl.f_bitstream_ri = 0u;
48996 self->private_impl.f_bitstream_wi = v_wi;
48998 v_wi = self->private_impl.f_bitstream_wi;
48999 while ((v_wi < 2048u) && (((uint64_t)(io2_a_src - iop_a_src)) > 0u)) {
49000 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
49001 if (v_c8 < 255u) {
49002 self->private_data.f_bitstream_buffer[v_wi] = v_c8;
49003 v_wi += 1u;
49004 iop_a_src += 1u;
49005 continue;
49006 } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 1u) {
49007 break;
49008 } else if (((uint16_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src) >> 8u)) > 0u) {
49009 break;
49010 } else {
49011 self->private_data.f_bitstream_buffer[v_wi] = 255u;
49012 v_wi += 1u;
49013 iop_a_src += 2u;
49016 if (((uint64_t)(io2_a_src - iop_a_src)) > 1u) {
49017 if ((wuffs_base__peek_u8be__no_bounds_check(iop_a_src) >= 255u) && (((uint16_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src) >> 8u)) > 0u)) {
49018 v_new_wi = (wuffs_base__u32__min(v_wi, 1784u) + 264u);
49019 v_new_wi = wuffs_base__u32__min(v_new_wi, (v_wi + self->private_impl.f_bitstream_padding));
49020 if (v_wi < v_new_wi) {
49021 wuffs_private_impl__u32__sat_sub_indirect(&self->private_impl.f_bitstream_padding, (v_new_wi - v_wi));
49022 wuffs_private_impl__bulk_memset(&self->private_data.f_bitstream_buffer[v_wi], (v_new_wi - v_wi), 0u);
49023 v_wi = v_new_wi;
49027 self->private_impl.f_bitstream_wi = v_wi;
49028 if (a_src && a_src->data.ptr) {
49029 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
49032 return wuffs_base__make_empty_struct();
49035 // -------- func jpeg.decoder.load_mcu_blocks_for_single_component
49037 WUFFS_BASE__GENERATED_C_CODE
49038 static wuffs_base__empty_struct
49039 wuffs_jpeg__decoder__load_mcu_blocks_for_single_component(
49040 wuffs_jpeg__decoder* self,
49041 uint32_t a_mx,
49042 uint32_t a_my,
49043 wuffs_base__slice_u8 a_workbuf,
49044 uint32_t a_csel) {
49045 return (*self->private_impl.choosy_load_mcu_blocks_for_single_component)(self, a_mx, a_my, a_workbuf, a_csel);
49048 WUFFS_BASE__GENERATED_C_CODE
49049 static wuffs_base__empty_struct
49050 wuffs_jpeg__decoder__load_mcu_blocks_for_single_component__choosy_default(
49051 wuffs_jpeg__decoder* self,
49052 uint32_t a_mx,
49053 uint32_t a_my,
49054 wuffs_base__slice_u8 a_workbuf,
49055 uint32_t a_csel) {
49056 uint64_t v_stride16 = 0;
49057 uint64_t v_offset = 0;
49059 v_stride16 = ((uint64_t)((self->private_impl.f_components_workbuf_widths[a_csel] * 16u)));
49060 v_offset = (self->private_impl.f_components_workbuf_offsets[(a_csel | 4u)] + (((uint64_t)(a_mx)) * 128u) + (((uint64_t)(a_my)) * v_stride16));
49061 if (v_offset <= ((uint64_t)(a_workbuf.len))) {
49062 wuffs_private_impl__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));
49064 return wuffs_base__make_empty_struct();
49067 // -------- func jpeg.decoder.load_mcu_blocks
49069 WUFFS_BASE__GENERATED_C_CODE
49070 static wuffs_base__empty_struct
49071 wuffs_jpeg__decoder__load_mcu_blocks(
49072 wuffs_jpeg__decoder* self,
49073 uint32_t a_mx,
49074 uint32_t a_my,
49075 wuffs_base__slice_u8 a_workbuf) {
49076 uint32_t v_b = 0;
49077 uint8_t v_csel = 0;
49078 uint64_t v_h = 0;
49079 uint64_t v_v = 0;
49080 uint64_t v_stride16 = 0;
49081 uint64_t v_offset = 0;
49083 v_h = 1u;
49084 v_v = 1u;
49085 v_b = 0u;
49086 while (v_b < self->private_impl.f_mcu_num_blocks) {
49087 v_csel = self->private_impl.f_scan_comps_cselector[self->private_impl.f_mcu_blocks_sselector[v_b]];
49088 if (self->private_impl.f_scan_num_components > 1u) {
49089 v_h = ((uint64_t)(self->private_impl.f_components_h[v_csel]));
49090 v_v = ((uint64_t)(self->private_impl.f_components_v[v_csel]));
49092 v_stride16 = ((uint64_t)((self->private_impl.f_components_workbuf_widths[v_csel] * 16u)));
49093 v_offset = (self->private_impl.f_components_workbuf_offsets[((uint8_t)(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));
49094 if (v_offset <= ((uint64_t)(a_workbuf.len))) {
49095 wuffs_private_impl__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));
49097 v_b += 1u;
49099 return wuffs_base__make_empty_struct();
49102 // -------- func jpeg.decoder.save_mcu_blocks
49104 WUFFS_BASE__GENERATED_C_CODE
49105 static wuffs_base__empty_struct
49106 wuffs_jpeg__decoder__save_mcu_blocks(
49107 wuffs_jpeg__decoder* self,
49108 uint32_t a_mx,
49109 uint32_t a_my,
49110 wuffs_base__slice_u8 a_workbuf) {
49111 uint32_t v_b = 0;
49112 uint8_t v_csel = 0;
49113 uint64_t v_h = 0;
49114 uint64_t v_v = 0;
49115 uint64_t v_stride16 = 0;
49116 uint64_t v_offset = 0;
49118 v_h = 1u;
49119 v_v = 1u;
49120 v_b = 0u;
49121 while (v_b < self->private_impl.f_mcu_num_blocks) {
49122 v_csel = self->private_impl.f_scan_comps_cselector[self->private_impl.f_mcu_blocks_sselector[v_b]];
49123 if (self->private_impl.f_scan_num_components > 1u) {
49124 v_h = ((uint64_t)(self->private_impl.f_components_h[v_csel]));
49125 v_v = ((uint64_t)(self->private_impl.f_components_v[v_csel]));
49127 v_stride16 = ((uint64_t)((self->private_impl.f_components_workbuf_widths[v_csel] * 16u)));
49128 v_offset = (self->private_impl.f_components_workbuf_offsets[((uint8_t)(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));
49129 if (v_offset <= ((uint64_t)(a_workbuf.len))) {
49130 wuffs_private_impl__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));
49132 v_b += 1u;
49134 return wuffs_base__make_empty_struct();
49137 // -------- func jpeg.decoder.skip_past_the_next_restart_marker
49139 WUFFS_BASE__GENERATED_C_CODE
49140 static wuffs_base__status
49141 wuffs_jpeg__decoder__skip_past_the_next_restart_marker(
49142 wuffs_jpeg__decoder* self,
49143 wuffs_base__io_buffer* a_src) {
49144 wuffs_base__status status = wuffs_base__make_status(NULL);
49146 uint8_t v_c8 = 0;
49148 const uint8_t* iop_a_src = NULL;
49149 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
49150 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
49151 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
49152 if (a_src && a_src->data.ptr) {
49153 io0_a_src = a_src->data.ptr;
49154 io1_a_src = io0_a_src + a_src->meta.ri;
49155 iop_a_src = io1_a_src;
49156 io2_a_src = io0_a_src + a_src->meta.wi;
49159 uint32_t coro_susp_point = self->private_impl.p_skip_past_the_next_restart_marker;
49160 switch (coro_susp_point) {
49161 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
49163 while (true) {
49164 if (((uint64_t)(io2_a_src - iop_a_src)) < 2u) {
49165 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
49166 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
49167 continue;
49168 } else if (wuffs_base__peek_u8be__no_bounds_check(iop_a_src) < 255u) {
49169 iop_a_src += 1u;
49170 continue;
49172 v_c8 = ((uint8_t)(((uint16_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src) >> 8u))));
49173 if (v_c8 < 192u) {
49174 iop_a_src += 2u;
49175 continue;
49176 } else if ((v_c8 < 208u) || (215u < v_c8)) {
49177 break;
49179 v_c8 &= 7u;
49180 if ((self->private_impl.f_next_restart_marker == ((uint8_t)(((uint8_t)(v_c8 + 1u)) & 7u))) || (self->private_impl.f_next_restart_marker == ((uint8_t)(((uint8_t)(v_c8 + 2u)) & 7u)))) {
49181 break;
49182 } else if ((self->private_impl.f_next_restart_marker == ((uint8_t)(((uint8_t)(v_c8 + 7u)) & 7u))) || (self->private_impl.f_next_restart_marker == ((uint8_t)(((uint8_t)(v_c8 + 6u)) & 7u)))) {
49183 iop_a_src += 2u;
49184 continue;
49185 } else {
49186 iop_a_src += 2u;
49187 break;
49190 self->private_impl.f_next_restart_marker = ((uint8_t)(((uint8_t)(self->private_impl.f_next_restart_marker + 1u)) & 7u));
49193 self->private_impl.p_skip_past_the_next_restart_marker = 0;
49194 goto exit;
49197 goto suspend;
49198 suspend:
49199 self->private_impl.p_skip_past_the_next_restart_marker = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
49201 goto exit;
49202 exit:
49203 if (a_src && a_src->data.ptr) {
49204 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
49207 return status;
49210 // -------- func jpeg.decoder.apply_progressive_idct
49212 WUFFS_BASE__GENERATED_C_CODE
49213 static wuffs_base__empty_struct
49214 wuffs_jpeg__decoder__apply_progressive_idct(
49215 wuffs_jpeg__decoder* self,
49216 wuffs_base__slice_u8 a_workbuf) {
49217 uint32_t v_csel = 0;
49218 bool v_block_smoothing_applicable = false;
49219 uint32_t v_scan_width_in_mcus = 0;
49220 uint32_t v_scan_height_in_mcus = 0;
49221 uint32_t v_mcu_blocks_mx_mul_0 = 0;
49222 uint32_t v_mcu_blocks_my_mul_0 = 0;
49223 uint32_t v_my = 0;
49224 uint32_t v_mx = 0;
49225 uint64_t v_stride = 0;
49226 uint64_t v_offset = 0;
49227 uint8_t v_stashed_mcu_blocks_0[128] = {0};
49229 wuffs_private_impl__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));
49230 v_block_smoothing_applicable = true;
49231 v_csel = 0u;
49232 while (v_csel < self->private_impl.f_num_components) {
49233 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])))) {
49234 v_block_smoothing_applicable = false;
49236 v_csel += 1u;
49238 v_csel = 0u;
49239 while (v_csel < self->private_impl.f_num_components) {
49240 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);
49241 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);
49242 v_mcu_blocks_mx_mul_0 = 8u;
49243 v_mcu_blocks_my_mul_0 = (8u * self->private_impl.f_components_workbuf_widths[v_csel]);
49244 if (v_block_smoothing_applicable && (0u != (self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][1u] |
49245 self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][2u] |
49246 self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][3u] |
49247 self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][4u] |
49248 self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][5u] |
49249 self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][6u] |
49250 self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][8u] |
49251 self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][8u] |
49252 self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][9u]))) {
49253 self->private_impl.choosy_load_mcu_blocks_for_single_component = (
49254 &wuffs_jpeg__decoder__load_mcu_blocks_for_single_component_smooth);
49255 self->private_impl.f_block_smoothing_mx_max_incl = wuffs_base__u32__sat_sub(v_scan_width_in_mcus, 1u);
49256 self->private_impl.f_block_smoothing_my_max_incl = wuffs_base__u32__sat_sub(v_scan_height_in_mcus, 1u);
49257 } else {
49258 self->private_impl.choosy_load_mcu_blocks_for_single_component = (
49259 &wuffs_jpeg__decoder__load_mcu_blocks_for_single_component__choosy_default);
49261 v_my = 0u;
49262 while (v_my < v_scan_height_in_mcus) {
49263 v_mx = 0u;
49264 while (v_mx < v_scan_width_in_mcus) {
49265 wuffs_jpeg__decoder__load_mcu_blocks_for_single_component(self,
49266 v_mx,
49267 v_my,
49268 a_workbuf,
49269 v_csel);
49270 v_stride = ((uint64_t)(self->private_impl.f_components_workbuf_widths[v_csel]));
49271 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))));
49272 if (v_offset <= ((uint64_t)(a_workbuf.len))) {
49273 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])));
49275 v_mx += 1u;
49277 v_my += 1u;
49279 v_csel += 1u;
49281 wuffs_private_impl__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));
49282 return wuffs_base__make_empty_struct();
49285 // -------- func jpeg.decoder.swizzle_gray
49287 WUFFS_BASE__GENERATED_C_CODE
49288 static wuffs_base__status
49289 wuffs_jpeg__decoder__swizzle_gray(
49290 wuffs_jpeg__decoder* self,
49291 wuffs_base__pixel_buffer* a_dst,
49292 wuffs_base__slice_u8 a_workbuf,
49293 uint32_t a_x0,
49294 uint32_t a_x1,
49295 uint32_t a_y0,
49296 uint32_t a_y1,
49297 uint64_t a_stride) {
49298 wuffs_base__pixel_format v_dst_pixfmt = {0};
49299 uint32_t v_dst_bits_per_pixel = 0;
49300 uint32_t v_dst_bytes_per_pixel = 0;
49301 uint64_t v_x0 = 0;
49302 uint64_t v_x1 = 0;
49303 wuffs_base__table_u8 v_tab = {0};
49304 wuffs_base__slice_u8 v_dst = {0};
49305 uint32_t v_y = 0;
49306 uint32_t v_y1 = 0;
49308 v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
49309 v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
49310 if ((v_dst_bits_per_pixel & 7u) != 0u) {
49311 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
49313 v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u);
49314 v_x0 = ((uint64_t)((v_dst_bytes_per_pixel * wuffs_base__u32__min(a_x0, self->private_impl.f_width))));
49315 v_x1 = ((uint64_t)((v_dst_bytes_per_pixel * wuffs_base__u32__min(a_x1, self->private_impl.f_width))));
49316 v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
49317 v_y = a_y0;
49318 v_y1 = wuffs_base__u32__min(a_y1, self->private_impl.f_height);
49319 while (v_y < v_y1) {
49320 v_dst = wuffs_private_impl__table_u8__row_u32(v_tab, v_y);
49321 if (v_x1 < ((uint64_t)(v_dst.len))) {
49322 v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_x1);
49324 if (v_x0 < ((uint64_t)(v_dst.len))) {
49325 v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_x0);
49326 } else {
49327 v_dst = wuffs_base__utility__empty_slice_u8();
49329 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);
49330 if (a_stride <= ((uint64_t)(a_workbuf.len))) {
49331 a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, a_stride);
49332 } else {
49333 a_workbuf = wuffs_base__utility__empty_slice_u8();
49335 v_y += 1u;
49337 return wuffs_base__make_status(NULL);
49340 // -------- func jpeg.decoder.swizzle_colorful
49342 WUFFS_BASE__GENERATED_C_CODE
49343 static wuffs_base__status
49344 wuffs_jpeg__decoder__swizzle_colorful(
49345 wuffs_jpeg__decoder* self,
49346 wuffs_base__pixel_buffer* a_dst,
49347 wuffs_base__slice_u8 a_workbuf,
49348 uint32_t a_x0,
49349 uint32_t a_x1,
49350 uint32_t a_y0,
49351 uint32_t a_y1) {
49352 uint64_t v_i = 0;
49353 uint64_t v_j = 0;
49354 wuffs_base__slice_u8 v_src0 = {0};
49355 wuffs_base__slice_u8 v_src1 = {0};
49356 wuffs_base__slice_u8 v_src2 = {0};
49357 wuffs_base__slice_u8 v_src3 = {0};
49358 uint32_t v_width0 = 0;
49359 uint32_t v_width1 = 0;
49360 uint32_t v_width2 = 0;
49361 uint32_t v_width3 = 0;
49362 uint32_t v_height0 = 0;
49363 uint32_t v_height1 = 0;
49364 uint32_t v_height2 = 0;
49365 uint32_t v_height3 = 0;
49366 wuffs_base__status v_status = wuffs_base__make_status(NULL);
49368 if (self->private_impl.f_swizzle_immediately) {
49369 v_i = ((uint64_t)(self->private_impl.f_swizzle_immediately_c_offsets[0u]));
49370 v_j = ((uint64_t)(self->private_impl.f_swizzle_immediately_c_offsets[1u]));
49371 if ((v_i <= v_j) && (v_j <= 640u)) {
49372 v_src0 = wuffs_base__make_slice_u8_ij(self->private_data.f_swizzle_immediately_buffer, v_i, v_j);
49373 v_width0 = (8u * ((uint32_t)(self->private_impl.f_components_h[0u])));
49374 v_height0 = (8u * ((uint32_t)(self->private_impl.f_components_v[0u])));
49376 v_i = ((uint64_t)(self->private_impl.f_swizzle_immediately_c_offsets[1u]));
49377 v_j = ((uint64_t)(self->private_impl.f_swizzle_immediately_c_offsets[2u]));
49378 if ((v_i <= v_j) && (v_j <= 640u)) {
49379 v_src1 = wuffs_base__make_slice_u8_ij(self->private_data.f_swizzle_immediately_buffer, v_i, v_j);
49380 v_width1 = (8u * ((uint32_t)(self->private_impl.f_components_h[1u])));
49381 v_height1 = (8u * ((uint32_t)(self->private_impl.f_components_v[1u])));
49383 v_i = ((uint64_t)(self->private_impl.f_swizzle_immediately_c_offsets[2u]));
49384 v_j = ((uint64_t)(self->private_impl.f_swizzle_immediately_c_offsets[3u]));
49385 if ((v_i <= v_j) && (v_j <= 640u)) {
49386 v_src2 = wuffs_base__make_slice_u8_ij(self->private_data.f_swizzle_immediately_buffer, v_i, v_j);
49387 v_width2 = (8u * ((uint32_t)(self->private_impl.f_components_h[2u])));
49388 v_height2 = (8u * ((uint32_t)(self->private_impl.f_components_v[2u])));
49390 v_i = ((uint64_t)(self->private_impl.f_swizzle_immediately_c_offsets[3u]));
49391 v_j = ((uint64_t)(self->private_impl.f_swizzle_immediately_c_offsets[4u]));
49392 if ((v_i <= v_j) && (v_j <= 640u)) {
49393 v_src3 = wuffs_base__make_slice_u8_ij(self->private_data.f_swizzle_immediately_buffer, v_i, v_j);
49394 v_width3 = (8u * ((uint32_t)(self->private_impl.f_components_h[3u])));
49395 v_height3 = (8u * ((uint32_t)(self->private_impl.f_components_v[3u])));
49397 } else {
49398 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)))) {
49399 v_src0 = wuffs_base__slice_u8__subslice_ij(a_workbuf,
49400 self->private_impl.f_components_workbuf_offsets[0u],
49401 self->private_impl.f_components_workbuf_offsets[1u]);
49402 v_width0 = self->private_impl.f_components_workbuf_widths[0u];
49403 v_height0 = self->private_impl.f_components_workbuf_heights[0u];
49405 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)))) {
49406 v_src1 = wuffs_base__slice_u8__subslice_ij(a_workbuf,
49407 self->private_impl.f_components_workbuf_offsets[1u],
49408 self->private_impl.f_components_workbuf_offsets[2u]);
49409 v_width1 = self->private_impl.f_components_workbuf_widths[1u];
49410 v_height1 = self->private_impl.f_components_workbuf_heights[1u];
49412 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)))) {
49413 v_src2 = wuffs_base__slice_u8__subslice_ij(a_workbuf,
49414 self->private_impl.f_components_workbuf_offsets[2u],
49415 self->private_impl.f_components_workbuf_offsets[3u]);
49416 v_width2 = self->private_impl.f_components_workbuf_widths[2u];
49417 v_height2 = self->private_impl.f_components_workbuf_heights[2u];
49419 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)))) {
49420 v_src3 = wuffs_base__slice_u8__subslice_ij(a_workbuf,
49421 self->private_impl.f_components_workbuf_offsets[3u],
49422 self->private_impl.f_components_workbuf_offsets[4u]);
49423 v_width3 = self->private_impl.f_components_workbuf_widths[3u];
49424 v_height3 = self->private_impl.f_components_workbuf_heights[3u];
49427 v_status = wuffs_base__pixel_swizzler__swizzle_ycck(&self->private_impl.f_swizzler,
49428 a_dst,
49429 wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)),
49430 (a_x0 & 65535u),
49431 wuffs_base__u32__min(a_x1, self->private_impl.f_width),
49432 (a_y0 & 65535u),
49433 wuffs_base__u32__min(a_y1, self->private_impl.f_height),
49434 v_src0,
49435 v_src1,
49436 v_src2,
49437 v_src3,
49438 v_width0,
49439 v_width1,
49440 v_width2,
49441 v_width3,
49442 v_height0,
49443 v_height1,
49444 v_height2,
49445 v_height3,
49446 v_width0,
49447 v_width1,
49448 v_width2,
49449 v_width3,
49450 self->private_impl.f_components_h[0u],
49451 self->private_impl.f_components_h[1u],
49452 self->private_impl.f_components_h[2u],
49453 self->private_impl.f_components_h[3u],
49454 self->private_impl.f_components_v[0u],
49455 self->private_impl.f_components_v[1u],
49456 self->private_impl.f_components_v[2u],
49457 self->private_impl.f_components_v[3u],
49458 self->private_impl.f_is_rgb_or_cmyk,
49459 ! self->private_impl.f_use_lower_quality,
49460 wuffs_base__make_slice_u8(self->private_data.f_swizzle_ycck_scratch_buffer_2k, 2048));
49461 return wuffs_private_impl__status__ensure_not_a_suspension(v_status);
49464 // -------- func jpeg.decoder.frame_dirty_rect
49466 WUFFS_BASE__GENERATED_C_CODE
49467 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
49468 wuffs_jpeg__decoder__frame_dirty_rect(
49469 const wuffs_jpeg__decoder* self) {
49470 if (!self) {
49471 return wuffs_base__utility__empty_rect_ie_u32();
49473 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
49474 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
49475 return wuffs_base__utility__empty_rect_ie_u32();
49478 return wuffs_base__utility__make_rect_ie_u32(
49481 self->private_impl.f_width,
49482 self->private_impl.f_height);
49485 // -------- func jpeg.decoder.num_animation_loops
49487 WUFFS_BASE__GENERATED_C_CODE
49488 WUFFS_BASE__MAYBE_STATIC uint32_t
49489 wuffs_jpeg__decoder__num_animation_loops(
49490 const wuffs_jpeg__decoder* self) {
49491 if (!self) {
49492 return 0;
49494 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
49495 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
49496 return 0;
49499 return 0u;
49502 // -------- func jpeg.decoder.num_decoded_frame_configs
49504 WUFFS_BASE__GENERATED_C_CODE
49505 WUFFS_BASE__MAYBE_STATIC uint64_t
49506 wuffs_jpeg__decoder__num_decoded_frame_configs(
49507 const wuffs_jpeg__decoder* self) {
49508 if (!self) {
49509 return 0;
49511 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
49512 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
49513 return 0;
49516 if (self->private_impl.f_call_sequence > 32u) {
49517 return 1u;
49519 return 0u;
49522 // -------- func jpeg.decoder.num_decoded_frames
49524 WUFFS_BASE__GENERATED_C_CODE
49525 WUFFS_BASE__MAYBE_STATIC uint64_t
49526 wuffs_jpeg__decoder__num_decoded_frames(
49527 const wuffs_jpeg__decoder* self) {
49528 if (!self) {
49529 return 0;
49531 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
49532 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
49533 return 0;
49536 if (self->private_impl.f_call_sequence > 64u) {
49537 return 1u;
49539 return 0u;
49542 // -------- func jpeg.decoder.restart_frame
49544 WUFFS_BASE__GENERATED_C_CODE
49545 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
49546 wuffs_jpeg__decoder__restart_frame(
49547 wuffs_jpeg__decoder* self,
49548 uint64_t a_index,
49549 uint64_t a_io_position) {
49550 if (!self) {
49551 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
49553 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
49554 return wuffs_base__make_status(
49555 (self->private_impl.magic == WUFFS_BASE__DISABLED)
49556 ? wuffs_base__error__disabled_by_previous_error
49557 : wuffs_base__error__initialize_not_called);
49560 uint32_t v_i = 0;
49561 uint32_t v_j = 0;
49563 if (self->private_impl.f_call_sequence < 32u) {
49564 return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
49566 if (a_index != 0u) {
49567 return wuffs_base__make_status(wuffs_base__error__bad_argument);
49569 self->private_impl.f_call_sequence = 40u;
49570 self->private_impl.f_bitstream_is_closed = false;
49571 self->private_impl.f_expect_multiple_scans = false;
49572 self->private_impl.f_frame_config_io_position = a_io_position;
49573 self->private_impl.f_scan_count = 0u;
49574 self->private_impl.f_restart_interval = self->private_impl.f_saved_restart_interval;
49575 v_i = 0u;
49576 while (v_i < 4u) {
49577 self->private_impl.f_seen_dqt[v_i] = self->private_impl.f_saved_seen_dqt[v_i];
49578 v_j = 0u;
49579 while (v_j < 64u) {
49580 self->private_impl.f_quant_tables[v_i][v_j] = self->private_impl.f_saved_quant_tables[v_i][v_j];
49581 v_j += 1u;
49583 v_i += 1u;
49585 v_i = 0u;
49586 while (v_i < 4u) {
49587 v_j = 0u;
49588 while (v_j < 10u) {
49589 self->private_impl.f_block_smoothing_lowest_scan_al[v_i][v_j] = 16u;
49590 v_j += 1u;
49592 v_i += 1u;
49594 v_i = 0u;
49595 while (v_i < 8u) {
49596 self->private_impl.f_seen_dht[v_i] = false;
49597 v_i += 1u;
49599 return wuffs_base__make_status(NULL);
49602 // -------- func jpeg.decoder.set_report_metadata
49604 WUFFS_BASE__GENERATED_C_CODE
49605 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
49606 wuffs_jpeg__decoder__set_report_metadata(
49607 wuffs_jpeg__decoder* self,
49608 uint32_t a_fourcc,
49609 bool a_report) {
49610 return wuffs_base__make_empty_struct();
49613 // -------- func jpeg.decoder.tell_me_more
49615 WUFFS_BASE__GENERATED_C_CODE
49616 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
49617 wuffs_jpeg__decoder__tell_me_more(
49618 wuffs_jpeg__decoder* self,
49619 wuffs_base__io_buffer* a_dst,
49620 wuffs_base__more_information* a_minfo,
49621 wuffs_base__io_buffer* a_src) {
49622 if (!self) {
49623 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
49625 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
49626 return wuffs_base__make_status(
49627 (self->private_impl.magic == WUFFS_BASE__DISABLED)
49628 ? wuffs_base__error__disabled_by_previous_error
49629 : wuffs_base__error__initialize_not_called);
49631 if (!a_dst || !a_src) {
49632 self->private_impl.magic = WUFFS_BASE__DISABLED;
49633 return wuffs_base__make_status(wuffs_base__error__bad_argument);
49635 if ((self->private_impl.active_coroutine != 0) &&
49636 (self->private_impl.active_coroutine != 4)) {
49637 self->private_impl.magic = WUFFS_BASE__DISABLED;
49638 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
49640 self->private_impl.active_coroutine = 0;
49641 wuffs_base__status status = wuffs_base__make_status(NULL);
49643 status = wuffs_base__make_status(wuffs_base__error__no_more_information);
49644 goto exit;
49646 goto ok;
49648 goto exit;
49649 exit:
49650 if (wuffs_base__status__is_error(&status)) {
49651 self->private_impl.magic = WUFFS_BASE__DISABLED;
49653 return status;
49656 // -------- func jpeg.decoder.workbuf_len
49658 WUFFS_BASE__GENERATED_C_CODE
49659 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
49660 wuffs_jpeg__decoder__workbuf_len(
49661 const wuffs_jpeg__decoder* self) {
49662 if (!self) {
49663 return wuffs_base__utility__empty_range_ii_u64();
49665 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
49666 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
49667 return wuffs_base__utility__empty_range_ii_u64();
49670 if (self->private_impl.f_use_lower_quality && (self->private_impl.f_sof_marker < 194u)) {
49671 return wuffs_base__utility__make_range_ii_u64(0u, self->private_impl.f_components_workbuf_offsets[8u]);
49673 return wuffs_base__utility__make_range_ii_u64(self->private_impl.f_components_workbuf_offsets[8u], self->private_impl.f_components_workbuf_offsets[8u]);
49676 // -------- func jpeg.decoder.top_left_quants_has_zero
49678 WUFFS_BASE__GENERATED_C_CODE
49679 static bool
49680 wuffs_jpeg__decoder__top_left_quants_has_zero(
49681 const wuffs_jpeg__decoder* self,
49682 uint32_t a_q) {
49683 return ((self->private_impl.f_quant_tables[a_q][0u] == 0u) ||
49684 (self->private_impl.f_quant_tables[a_q][1u] == 0u) ||
49685 (self->private_impl.f_quant_tables[a_q][2u] == 0u) ||
49686 (self->private_impl.f_quant_tables[a_q][3u] == 0u) ||
49687 (self->private_impl.f_quant_tables[a_q][8u] == 0u) ||
49688 (self->private_impl.f_quant_tables[a_q][9u] == 0u) ||
49689 (self->private_impl.f_quant_tables[a_q][10u] == 0u) ||
49690 (self->private_impl.f_quant_tables[a_q][16u] == 0u) ||
49691 (self->private_impl.f_quant_tables[a_q][17u] == 0u) ||
49692 (self->private_impl.f_quant_tables[a_q][24u] == 0u));
49695 // -------- func jpeg.decoder.load_mcu_blocks_for_single_component_smooth
49697 WUFFS_BASE__GENERATED_C_CODE
49698 static wuffs_base__empty_struct
49699 wuffs_jpeg__decoder__load_mcu_blocks_for_single_component_smooth(
49700 wuffs_jpeg__decoder* self,
49701 uint32_t a_mx,
49702 uint32_t a_my,
49703 wuffs_base__slice_u8 a_workbuf,
49704 uint32_t a_csel) {
49705 uint64_t v_stride16 = 0;
49706 uint64_t v_offset = 0;
49707 uint32_t v_dx = 0;
49708 uint32_t v_dy = 0;
49709 uint32_t v_mx = 0;
49710 uint32_t v_my = 0;
49711 uint8_t v_q = 0;
49712 uint32_t v_q_00 = 0;
49713 uint32_t v_q_xy = 0;
49714 uint8_t v_al = 0;
49715 uint32_t v_scratch = 0;
49716 uint32_t v_limit = 0;
49718 v_stride16 = ((uint64_t)((self->private_impl.f_components_workbuf_widths[a_csel] * 16u)));
49719 v_offset = (self->private_impl.f_components_workbuf_offsets[(a_csel | 4u)] + (((uint64_t)(a_mx)) * 128u) + (((uint64_t)(a_my)) * v_stride16));
49720 if (v_offset <= ((uint64_t)(a_workbuf.len))) {
49721 wuffs_private_impl__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));
49723 v_dy = 0u;
49724 while (v_dy < 5u) {
49725 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));
49726 v_dx = 0u;
49727 while (v_dx < 5u) {
49728 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));
49729 v_offset = (self->private_impl.f_components_workbuf_offsets[(a_csel | 4u)] + (((uint64_t)(v_mx)) * 128u) + (((uint64_t)(v_my)) * v_stride16));
49730 if (v_offset <= ((uint64_t)(a_workbuf.len))) {
49731 wuffs_private_impl__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));
49733 v_dx += 1u;
49735 v_dy += 1u;
49737 v_q = self->private_impl.f_components_tq[a_csel];
49738 v_q_00 = ((uint32_t)(self->private_impl.f_quant_tables[v_q][0u]));
49739 if (v_q_00 <= 0u) {
49740 return wuffs_base__make_empty_struct();
49742 if (0u != (16u &
49743 self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][1u] &
49744 self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][2u] &
49745 self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][3u] &
49746 self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][4u] &
49747 self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][5u] &
49748 self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][6u] &
49749 self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][7u] &
49750 self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][8u] &
49751 self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][9u])) {
49752 v_scratch = 0u;
49753 v_scratch += ((uint32_t)(4294967294u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
49754 v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
49755 v_scratch += ((uint32_t)(4294967288u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
49756 v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
49757 v_scratch += ((uint32_t)(4294967294u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
49758 v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
49759 v_scratch += ((uint32_t)(6u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
49760 v_scratch += ((uint32_t)(42u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
49761 v_scratch += ((uint32_t)(6u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
49762 v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
49763 v_scratch += ((uint32_t)(4294967288u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
49764 v_scratch += ((uint32_t)(42u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
49765 v_scratch += ((uint32_t)(152u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
49766 v_scratch += ((uint32_t)(42u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
49767 v_scratch += ((uint32_t)(4294967288u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
49768 v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
49769 v_scratch += ((uint32_t)(6u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
49770 v_scratch += ((uint32_t)(42u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
49771 v_scratch += ((uint32_t)(6u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
49772 v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
49773 v_scratch += ((uint32_t)(4294967294u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
49774 v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
49775 v_scratch += ((uint32_t)(4294967288u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
49776 v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
49777 v_scratch += ((uint32_t)(4294967294u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
49778 if (v_scratch < 2147483648u) {
49779 v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + 128u)) / 256u)));
49780 } else {
49781 v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + 128u)) / 256u)));
49783 self->private_data.f_mcu_blocks[0u][0u] = ((uint16_t)(v_scratch));
49784 v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][1u]));
49785 if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][1u] == 0u)) {
49786 v_scratch = 0u;
49787 v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
49788 v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
49789 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
49790 v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
49791 v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
49792 v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
49793 v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
49794 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
49795 v_scratch += ((uint32_t)(4294967283u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
49796 v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
49797 v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
49798 v_scratch += ((uint32_t)(38u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
49799 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
49800 v_scratch += ((uint32_t)(4294967258u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
49801 v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
49802 v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
49803 v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
49804 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
49805 v_scratch += ((uint32_t)(4294967283u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
49806 v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
49807 v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
49808 v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
49809 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
49810 v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
49811 v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
49812 v_scratch *= v_q_00;
49813 if (v_scratch < 2147483648u) {
49814 v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
49815 } else {
49816 v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
49818 self->private_data.f_mcu_blocks[0u][1u] = ((uint16_t)(v_scratch));
49820 v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][2u]));
49821 if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][2u] == 0u)) {
49822 v_scratch = 0u;
49823 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
49824 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
49825 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
49826 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
49827 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
49828 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
49829 v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
49830 v_scratch += ((uint32_t)(4294967291u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
49831 v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
49832 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
49833 v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
49834 v_scratch += ((uint32_t)(7u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
49835 v_scratch += ((uint32_t)(4294967282u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
49836 v_scratch += ((uint32_t)(7u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
49837 v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
49838 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
49839 v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
49840 v_scratch += ((uint32_t)(4294967291u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
49841 v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
49842 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
49843 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
49844 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
49845 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
49846 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
49847 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
49848 v_scratch *= v_q_00;
49849 if (v_scratch < 2147483648u) {
49850 v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
49851 } else {
49852 v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
49854 self->private_data.f_mcu_blocks[0u][2u] = ((uint16_t)(v_scratch));
49856 v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][3u]));
49857 if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][3u] == 0u)) {
49858 v_scratch = 0u;
49859 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
49860 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
49861 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
49862 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
49863 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
49864 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
49865 v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
49866 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
49867 v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
49868 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
49869 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
49870 v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
49871 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
49872 v_scratch += ((uint32_t)(4294967294u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
49873 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
49874 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
49875 v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
49876 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
49877 v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
49878 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
49879 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
49880 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
49881 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
49882 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
49883 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
49884 v_scratch *= v_q_00;
49885 if (v_scratch < 2147483648u) {
49886 v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
49887 } else {
49888 v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
49890 self->private_data.f_mcu_blocks[0u][3u] = ((uint16_t)(v_scratch));
49892 v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][8u]));
49893 if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][8u] == 0u)) {
49894 v_scratch = 0u;
49895 v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
49896 v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
49897 v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
49898 v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
49899 v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
49900 v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
49901 v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
49902 v_scratch += ((uint32_t)(38u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
49903 v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
49904 v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
49905 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
49906 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
49907 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
49908 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
49909 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
49910 v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
49911 v_scratch += ((uint32_t)(4294967283u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
49912 v_scratch += ((uint32_t)(4294967258u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
49913 v_scratch += ((uint32_t)(4294967283u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
49914 v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
49915 v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
49916 v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
49917 v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
49918 v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
49919 v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
49920 v_scratch *= v_q_00;
49921 if (v_scratch < 2147483648u) {
49922 v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
49923 } else {
49924 v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
49926 self->private_data.f_mcu_blocks[0u][8u] = ((uint16_t)(v_scratch));
49928 v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][9u]));
49929 if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][9u] == 0u)) {
49930 v_scratch = 0u;
49931 v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
49932 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
49933 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
49934 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
49935 v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
49936 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
49937 v_scratch += ((uint32_t)(9u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
49938 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
49939 v_scratch += ((uint32_t)(4294967287u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
49940 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
49941 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
49942 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
49943 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
49944 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
49945 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
49946 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
49947 v_scratch += ((uint32_t)(4294967287u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
49948 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
49949 v_scratch += ((uint32_t)(9u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
49950 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
49951 v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
49952 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
49953 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
49954 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
49955 v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
49956 v_scratch *= v_q_00;
49957 if (v_scratch < 2147483648u) {
49958 v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
49959 } else {
49960 v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
49962 self->private_data.f_mcu_blocks[0u][9u] = ((uint16_t)(v_scratch));
49964 v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][10u]));
49965 if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][10u] == 0u)) {
49966 v_scratch = 0u;
49967 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
49968 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
49969 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
49970 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
49971 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
49972 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
49973 v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
49974 v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
49975 v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
49976 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
49977 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
49978 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
49979 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
49980 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
49981 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
49982 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
49983 v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
49984 v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
49985 v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
49986 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
49987 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
49988 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
49989 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
49990 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
49991 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
49992 v_scratch *= v_q_00;
49993 if (v_scratch < 2147483648u) {
49994 v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
49995 } else {
49996 v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
49998 self->private_data.f_mcu_blocks[0u][10u] = ((uint16_t)(v_scratch));
50000 v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][16u]));
50001 if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][16u] == 0u)) {
50002 v_scratch = 0u;
50003 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
50004 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
50005 v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
50006 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
50007 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
50008 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
50009 v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
50010 v_scratch += ((uint32_t)(7u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
50011 v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
50012 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
50013 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
50014 v_scratch += ((uint32_t)(4294967291u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
50015 v_scratch += ((uint32_t)(4294967282u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
50016 v_scratch += ((uint32_t)(4294967291u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
50017 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
50018 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
50019 v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
50020 v_scratch += ((uint32_t)(7u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
50021 v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
50022 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
50023 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
50024 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
50025 v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
50026 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
50027 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
50028 v_scratch *= v_q_00;
50029 if (v_scratch < 2147483648u) {
50030 v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
50031 } else {
50032 v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
50034 self->private_data.f_mcu_blocks[0u][16u] = ((uint16_t)(v_scratch));
50036 v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][17u]));
50037 if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][17u] == 0u)) {
50038 v_scratch = 0u;
50039 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
50040 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
50041 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
50042 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
50043 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
50044 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
50045 v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
50046 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
50047 v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
50048 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
50049 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
50050 v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
50051 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
50052 v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
50053 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
50054 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
50055 v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
50056 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
50057 v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
50058 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
50059 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
50060 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
50061 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
50062 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
50063 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
50064 v_scratch *= v_q_00;
50065 if (v_scratch < 2147483648u) {
50066 v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
50067 } else {
50068 v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
50070 self->private_data.f_mcu_blocks[0u][17u] = ((uint16_t)(v_scratch));
50072 v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][24u]));
50073 if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][24u] == 0u)) {
50074 v_scratch = 0u;
50075 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
50076 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
50077 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
50078 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
50079 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
50080 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
50081 v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
50082 v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
50083 v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
50084 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
50085 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
50086 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
50087 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
50088 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
50089 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
50090 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
50091 v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
50092 v_scratch += ((uint32_t)(4294967294u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
50093 v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
50094 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
50095 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
50096 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
50097 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
50098 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
50099 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
50100 v_scratch *= v_q_00;
50101 if (v_scratch < 2147483648u) {
50102 v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
50103 } else {
50104 v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
50106 self->private_data.f_mcu_blocks[0u][24u] = ((uint16_t)(v_scratch));
50108 } else {
50109 v_al = self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][1u];
50110 v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][1u]));
50111 if ((v_al > 0u) && (v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][1u] == 0u)) {
50112 v_limit = ((((uint32_t)(1u)) << v_al) - 1u);
50113 v_scratch = 0u;
50114 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
50115 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
50116 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
50117 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
50118 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
50119 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
50120 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
50121 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
50122 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
50123 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
50124 v_scratch += ((uint32_t)(4294967289u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
50125 v_scratch += ((uint32_t)(50u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
50126 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
50127 v_scratch += ((uint32_t)(4294967246u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
50128 v_scratch += ((uint32_t)(7u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
50129 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
50130 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
50131 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
50132 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
50133 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
50134 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
50135 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
50136 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
50137 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
50138 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
50139 v_scratch *= v_q_00;
50140 if (v_scratch < 2147483648u) {
50141 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)))));
50142 } else {
50143 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)))));
50145 self->private_data.f_mcu_blocks[0u][1u] = ((uint16_t)(v_scratch));
50147 v_al = self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][5u];
50148 v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][2u]));
50149 if ((v_al > 0u) && (v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][2u] == 0u)) {
50150 v_limit = ((((uint32_t)(1u)) << v_al) - 1u);
50151 v_scratch = 0u;
50152 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
50153 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
50154 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
50155 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
50156 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
50157 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
50158 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
50159 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
50160 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
50161 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
50162 v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
50163 v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
50164 v_scratch += ((uint32_t)(4294967272u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
50165 v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
50166 v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
50167 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
50168 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
50169 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
50170 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
50171 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
50172 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
50173 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
50174 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
50175 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
50176 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
50177 v_scratch *= v_q_00;
50178 if (v_scratch < 2147483648u) {
50179 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)))));
50180 } else {
50181 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)))));
50183 self->private_data.f_mcu_blocks[0u][2u] = ((uint16_t)(v_scratch));
50185 v_al = self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][2u];
50186 v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][8u]));
50187 if ((v_al > 0u) && (v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][8u] == 0u)) {
50188 v_limit = ((((uint32_t)(1u)) << v_al) - 1u);
50189 v_scratch = 0u;
50190 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
50191 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
50192 v_scratch += ((uint32_t)(4294967289u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
50193 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
50194 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
50195 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
50196 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
50197 v_scratch += ((uint32_t)(50u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
50198 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
50199 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
50200 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
50201 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
50202 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
50203 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
50204 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
50205 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
50206 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
50207 v_scratch += ((uint32_t)(4294967246u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
50208 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
50209 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
50210 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
50211 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
50212 v_scratch += ((uint32_t)(7u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
50213 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
50214 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
50215 v_scratch *= v_q_00;
50216 if (v_scratch < 2147483648u) {
50217 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)))));
50218 } else {
50219 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)))));
50221 self->private_data.f_mcu_blocks[0u][8u] = ((uint16_t)(v_scratch));
50223 v_al = self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][4u];
50224 v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][9u]));
50225 if ((v_al > 0u) && (v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][9u] == 0u)) {
50226 v_limit = ((((uint32_t)(1u)) << v_al) - 1u);
50227 v_scratch = 0u;
50228 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
50229 v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
50230 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
50231 v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
50232 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
50233 v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
50234 v_scratch += ((uint32_t)(10u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
50235 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
50236 v_scratch += ((uint32_t)(4294967286u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
50237 v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
50238 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
50239 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
50240 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
50241 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
50242 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
50243 v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
50244 v_scratch += ((uint32_t)(4294967286u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
50245 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
50246 v_scratch += ((uint32_t)(10u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
50247 v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
50248 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
50249 v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
50250 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
50251 v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
50252 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
50253 v_scratch *= v_q_00;
50254 if (v_scratch < 2147483648u) {
50255 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)))));
50256 } else {
50257 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)))));
50259 self->private_data.f_mcu_blocks[0u][9u] = ((uint16_t)(v_scratch));
50261 v_al = self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][3u];
50262 v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][16u]));
50263 if ((v_al > 0u) && (v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][16u] == 0u)) {
50264 v_limit = ((((uint32_t)(1u)) << v_al) - 1u);
50265 v_scratch = 0u;
50266 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
50267 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
50268 v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
50269 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
50270 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
50271 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
50272 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
50273 v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
50274 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
50275 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
50276 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
50277 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
50278 v_scratch += ((uint32_t)(4294967272u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
50279 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
50280 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
50281 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
50282 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
50283 v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
50284 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
50285 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
50286 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
50287 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
50288 v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
50289 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
50290 v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
50291 v_scratch *= v_q_00;
50292 if (v_scratch < 2147483648u) {
50293 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)))));
50294 } else {
50295 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)))));
50297 self->private_data.f_mcu_blocks[0u][16u] = ((uint16_t)(v_scratch));
50300 return wuffs_base__make_empty_struct();
50303 // -------- func jpeg.decoder.decode_mcu
50305 WUFFS_BASE__GENERATED_C_CODE
50306 static uint32_t
50307 wuffs_jpeg__decoder__decode_mcu(
50308 wuffs_jpeg__decoder* self,
50309 wuffs_base__pixel_buffer* a_dst,
50310 wuffs_base__slice_u8 a_workbuf,
50311 uint32_t a_mx,
50312 uint32_t a_my) {
50313 return (*self->private_impl.choosy_decode_mcu)(self, a_dst, a_workbuf, a_mx, a_my);
50316 WUFFS_BASE__GENERATED_C_CODE
50317 static uint32_t
50318 wuffs_jpeg__decoder__decode_mcu__choosy_default(
50319 wuffs_jpeg__decoder* self,
50320 wuffs_base__pixel_buffer* a_dst,
50321 wuffs_base__slice_u8 a_workbuf,
50322 uint32_t a_mx,
50323 uint32_t a_my) {
50324 uint32_t v_ret = 0;
50325 uint64_t v_bits = 0;
50326 uint32_t v_n_bits = 0;
50327 uint8_t v_csel = 0;
50328 wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer();
50329 wuffs_base__io_buffer* v_r = &u_r;
50330 const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
50331 const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
50332 const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
50333 const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
50334 uint32_t v_pos = 0;
50335 uint8_t v_dc_h = 0;
50336 uint32_t v_dc_symbol = 0;
50337 uint32_t v_dc_ht_fast = 0;
50338 uint32_t v_dc_bl = 0;
50339 uint32_t v_dc_code = 0;
50340 uint32_t v_dc_blm1 = 0;
50341 uint32_t v_dc_ht_slow = 0;
50342 uint16_t v_dc_value = 0;
50343 uint16_t v_dc_extend = 0;
50344 const uint16_t* v_ac_huff_table_fast = NULL;
50345 uint8_t v_ac_h = 0;
50346 uint32_t v_ac_symbol = 0;
50347 uint32_t v_ac_ht_fast = 0;
50348 uint32_t v_ac_bl = 0;
50349 uint32_t v_ac_code = 0;
50350 uint32_t v_ac_blm1 = 0;
50351 uint32_t v_ac_ht_slow = 0;
50352 uint16_t v_ac_value = 0;
50353 uint16_t v_ac_extend = 0;
50354 uint32_t v_ac_rrrr = 0;
50355 uint32_t v_ac_ssss = 0;
50356 uint32_t v_z = 0;
50357 uint32_t v_mcb = 0;
50358 uint64_t v_stride = 0;
50359 uint64_t v_offset = 0;
50361 v_bits = self->private_impl.f_bitstream_bits;
50362 v_n_bits = self->private_impl.f_bitstream_n_bits;
50363 if (self->private_impl.f_bitstream_ri > self->private_impl.f_bitstream_wi) {
50364 return 2u;
50367 wuffs_base__io_buffer* o_0_v_r = v_r;
50368 const uint8_t* o_0_iop_v_r = iop_v_r;
50369 const uint8_t* o_0_io0_v_r = io0_v_r;
50370 const uint8_t* o_0_io1_v_r = io1_v_r;
50371 const uint8_t* o_0_io2_v_r = io2_v_r;
50372 v_r = wuffs_private_impl__io_reader__set(
50373 &u_r,
50374 &iop_v_r,
50375 &io0_v_r,
50376 &io1_v_r,
50377 &io2_v_r,
50378 wuffs_base__make_slice_u8_ij(self->private_data.f_bitstream_buffer,
50379 self->private_impl.f_bitstream_ri,
50380 self->private_impl.f_bitstream_wi),
50381 ((uint64_t)(self->private_impl.f_bitstream_ri)));
50382 do {
50383 while (self->private_impl.f_mcu_current_block < self->private_impl.f_mcu_num_blocks) {
50384 while (self->private_impl.f_mcu_zig_index <= 0u) {
50385 wuffs_private_impl__bulk_memset(&self->private_data.f_mcu_blocks[0], 1u * (size_t)128u, 0u);
50386 if (((uint64_t)(io2_v_r - iop_v_r)) < 264u) {
50387 v_ret = 1u;
50388 goto label__goto_done__break;
50390 v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u));
50391 iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u);
50392 v_n_bits |= 56u;
50393 v_dc_h = self->private_impl.f_mcu_blocks_dc_hselector[self->private_impl.f_mcu_current_block];
50394 v_dc_ht_fast = ((uint32_t)(self->private_impl.f_huff_tables_fast[v_dc_h][(v_bits >> 56u)]));
50395 v_dc_bl = (v_dc_ht_fast >> 8u);
50396 if (v_n_bits >= v_dc_bl) {
50397 v_dc_symbol = (15u & v_dc_ht_fast);
50398 v_dc_extend = WUFFS_JPEG__EXTEND[v_dc_symbol];
50399 v_bits <<= (v_dc_bl & 63u);
50400 v_n_bits -= v_dc_bl;
50401 } else {
50402 v_dc_code = ((uint32_t)((v_bits >> 55u)));
50403 v_dc_blm1 = 8u;
50404 v_bits <<= 9u;
50405 v_n_bits -= 9u;
50406 while (true) {
50407 v_dc_ht_slow = self->private_impl.f_huff_tables_slow[v_dc_h][v_dc_blm1];
50408 if (v_dc_code < (v_dc_ht_slow >> 8u)) {
50409 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)))])));
50410 v_dc_extend = WUFFS_JPEG__EXTEND[v_dc_symbol];
50411 break;
50413 v_dc_code = (((uint32_t)(v_dc_code << 1u)) | ((uint32_t)((v_bits >> 63u))));
50414 v_bits <<= 1u;
50415 v_n_bits -= 1u;
50416 v_dc_blm1 = ((v_dc_blm1 + 1u) & 15u);
50417 if (v_dc_blm1 == 0u) {
50418 v_dc_symbol = 0u;
50419 v_dc_extend = WUFFS_JPEG__EXTEND[v_dc_symbol];
50420 break;
50424 v_dc_value = ((uint16_t)(((v_bits >> 32u) >> (32u - v_dc_symbol))));
50425 #if defined(__GNUC__)
50426 #pragma GCC diagnostic push
50427 #pragma GCC diagnostic ignored "-Wconversion"
50428 #endif
50429 v_dc_value += ((uint16_t)(v_dc_extend & ((uint16_t)(((uint16_t)(wuffs_base__utility__sign_extend_rshift_u64(v_bits, 63u))) ^ 65535u))));
50430 #if defined(__GNUC__)
50431 #pragma GCC diagnostic pop
50432 #endif
50433 v_bits <<= v_dc_symbol;
50434 v_n_bits -= v_dc_symbol;
50435 v_csel = self->private_impl.f_scan_comps_cselector[self->private_impl.f_mcu_blocks_sselector[self->private_impl.f_mcu_current_block]];
50436 #if defined(__GNUC__)
50437 #pragma GCC diagnostic push
50438 #pragma GCC diagnostic ignored "-Wconversion"
50439 #endif
50440 self->private_impl.f_mcu_previous_dc_values[v_csel] += v_dc_value;
50441 #if defined(__GNUC__)
50442 #pragma GCC diagnostic pop
50443 #endif
50444 self->private_data.f_mcu_blocks[0u][0u] = self->private_impl.f_mcu_previous_dc_values[v_csel];
50445 self->private_impl.f_mcu_zig_index = 1u;
50446 break;
50448 if (((uint64_t)(io2_v_r - iop_v_r)) < 264u) {
50449 v_ret = 1u;
50450 goto label__goto_done__break;
50452 if (v_n_bits < 16u) {
50453 v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u));
50455 v_z = 1u;
50456 self->private_impl.f_mcu_zig_index = 0u;
50457 v_ac_h = self->private_impl.f_mcu_blocks_ac_hselector[self->private_impl.f_mcu_current_block];
50458 v_ac_huff_table_fast = &self->private_impl.f_huff_tables_fast[v_ac_h][0u];
50459 while (v_z < 64u) {
50460 v_ac_ht_fast = ((uint32_t)(v_ac_huff_table_fast[(v_bits >> 56u)]));
50461 if (((uint64_t)(io2_v_r - iop_v_r)) < 8u) {
50462 v_ret = 2u;
50463 goto label__goto_done__break;
50465 v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u));
50466 iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u);
50467 v_n_bits |= 56u;
50468 v_ac_bl = (v_ac_ht_fast >> 8u);
50469 if (v_n_bits >= v_ac_bl) {
50470 v_ac_symbol = (255u & v_ac_ht_fast);
50471 v_bits <<= (v_ac_bl & 63u);
50472 v_n_bits -= v_ac_bl;
50473 } else {
50474 v_ac_code = ((uint32_t)((v_bits >> 55u)));
50475 v_ac_blm1 = 8u;
50476 v_bits <<= 9u;
50477 v_n_bits -= 9u;
50478 while (true) {
50479 v_ac_ht_slow = self->private_impl.f_huff_tables_slow[v_ac_h][v_ac_blm1];
50480 if (v_ac_code < (v_ac_ht_slow >> 8u)) {
50481 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)))]));
50482 break;
50484 v_ac_code = (((uint32_t)(v_ac_code << 1u)) | ((uint32_t)((v_bits >> 63u))));
50485 v_bits <<= 1u;
50486 v_n_bits -= 1u;
50487 v_ac_blm1 = ((v_ac_blm1 + 1u) & 15u);
50488 if (v_ac_blm1 == 0u) {
50489 v_ac_symbol = 0u;
50490 break;
50494 v_ac_rrrr = (v_ac_symbol >> 4u);
50495 v_z += (v_ac_rrrr + 1u);
50496 v_ac_ssss = (v_ac_symbol & 15u);
50497 v_ac_extend = WUFFS_JPEG__EXTEND[v_ac_ssss];
50498 if (v_ac_ssss > 0u) {
50499 v_ac_value = ((uint16_t)((v_bits >> (64u - v_ac_ssss))));
50500 #if defined(__GNUC__)
50501 #pragma GCC diagnostic push
50502 #pragma GCC diagnostic ignored "-Wconversion"
50503 #endif
50504 v_ac_value += ((uint16_t)(v_ac_extend & ((uint16_t)(((uint16_t)(wuffs_base__utility__sign_extend_rshift_u64(v_bits, 63u))) ^ 65535u))));
50505 #if defined(__GNUC__)
50506 #pragma GCC diagnostic pop
50507 #endif
50508 v_bits <<= v_ac_ssss;
50509 v_n_bits -= v_ac_ssss;
50510 self->private_data.f_mcu_blocks[0u][WUFFS_JPEG__UNZIG[v_z]] = v_ac_value;
50511 } else if (v_ac_rrrr < 15u) {
50512 break;
50515 v_mcb = self->private_impl.f_mcu_current_block;
50516 self->private_impl.f_mcu_current_block += 1u;
50517 if (self->private_impl.f_test_only_interrupt_decode_mcu) {
50518 goto label__goto_done__break;
50520 if ( ! self->private_impl.f_swizzle_immediately) {
50521 v_csel = self->private_impl.f_scan_comps_cselector[self->private_impl.f_mcu_blocks_sselector[v_mcb]];
50522 v_stride = ((uint64_t)(self->private_impl.f_components_workbuf_widths[v_csel]));
50523 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))));
50524 if (v_offset <= ((uint64_t)(a_workbuf.len))) {
50525 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])));
50527 } else if (self->private_impl.f_num_components == 1u) {
50528 wuffs_jpeg__decoder__decode_idct(self, wuffs_base__make_slice_u8(self->private_data.f_swizzle_immediately_buffer, 64), 8u, ((uint32_t)(self->private_impl.f_components_tq[v_csel])));
50529 self->private_impl.f_swizzle_immediately_status = wuffs_jpeg__decoder__swizzle_gray(self,
50530 a_dst,
50531 wuffs_base__make_slice_u8(self->private_data.f_swizzle_immediately_buffer, 64),
50532 ((a_mx + 0u) * 8u),
50533 ((a_mx + 1u) * 8u),
50534 ((a_my + 0u) * 8u),
50535 ((a_my + 1u) * 8u),
50536 8u);
50537 if ( ! wuffs_base__status__is_ok(&self->private_impl.f_swizzle_immediately_status)) {
50538 v_ret = 3u;
50539 goto label__goto_done__break;
50541 break;
50542 } else {
50543 v_csel = self->private_impl.f_scan_comps_cselector[self->private_impl.f_mcu_blocks_sselector[v_mcb]];
50544 v_stride = (8u * ((uint64_t)(self->private_impl.f_components_h[v_csel])));
50545 wuffs_jpeg__decoder__decode_idct(self, wuffs_base__make_slice_u8_ij(self->private_data.f_swizzle_immediately_buffer, self->private_impl.f_swizzle_immediately_b_offsets[v_mcb], 640), v_stride, ((uint32_t)(self->private_impl.f_components_tq[v_csel])));
50546 if (self->private_impl.f_mcu_current_block < self->private_impl.f_mcu_num_blocks) {
50547 continue;
50549 self->private_impl.f_swizzle_immediately_status = wuffs_jpeg__decoder__swizzle_colorful(self,
50550 a_dst,
50551 wuffs_base__utility__empty_slice_u8(),
50552 ((a_mx + 0u) * 8u * ((uint32_t)(self->private_impl.f_max_incl_components_h))),
50553 ((a_mx + 1u) * 8u * ((uint32_t)(self->private_impl.f_max_incl_components_h))),
50554 ((a_my + 0u) * 8u * ((uint32_t)(self->private_impl.f_max_incl_components_v))),
50555 ((a_my + 1u) * 8u * ((uint32_t)(self->private_impl.f_max_incl_components_v))));
50556 if ( ! wuffs_base__status__is_ok(&self->private_impl.f_swizzle_immediately_status)) {
50557 v_ret = 3u;
50558 goto label__goto_done__break;
50560 break;
50563 self->private_impl.f_mcu_current_block = 0u;
50564 } while (0);
50565 label__goto_done__break:;
50566 v_pos = ((uint32_t)(wuffs_base__u64__sat_add((v_r ? v_r->meta.pos : 0), ((uint64_t)(iop_v_r - io0_v_r)))));
50567 if (v_pos > self->private_impl.f_bitstream_wi) {
50568 v_ret = 2u;
50569 } else {
50570 self->private_impl.f_bitstream_ri = v_pos;
50572 v_r = o_0_v_r;
50573 iop_v_r = o_0_iop_v_r;
50574 io0_v_r = o_0_io0_v_r;
50575 io1_v_r = o_0_io1_v_r;
50576 io2_v_r = o_0_io2_v_r;
50578 self->private_impl.f_bitstream_bits = v_bits;
50579 self->private_impl.f_bitstream_n_bits = v_n_bits;
50580 return v_ret;
50583 // -------- func jpeg.decoder.decode_mcu_progressive_ac_high_bits
50585 WUFFS_BASE__GENERATED_C_CODE
50586 static uint32_t
50587 wuffs_jpeg__decoder__decode_mcu_progressive_ac_high_bits(
50588 wuffs_jpeg__decoder* self,
50589 wuffs_base__pixel_buffer* a_dst,
50590 wuffs_base__slice_u8 a_workbuf,
50591 uint32_t a_mx,
50592 uint32_t a_my) {
50593 uint32_t v_ret = 0;
50594 uint64_t v_bits = 0;
50595 uint32_t v_n_bits = 0;
50596 wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer();
50597 wuffs_base__io_buffer* v_r = &u_r;
50598 const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
50599 const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
50600 const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
50601 const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
50602 uint32_t v_pos = 0;
50603 const uint16_t* v_ac_huff_table_fast = NULL;
50604 uint8_t v_ac_h = 0;
50605 uint32_t v_ac_symbol = 0;
50606 uint32_t v_ac_ht_fast = 0;
50607 uint32_t v_ac_bl = 0;
50608 uint32_t v_ac_code = 0;
50609 uint32_t v_ac_blm1 = 0;
50610 uint32_t v_ac_ht_slow = 0;
50611 uint16_t v_ac_value = 0;
50612 uint16_t v_ac_extend = 0;
50613 uint32_t v_ac_rrrr = 0;
50614 uint32_t v_ac_ssss = 0;
50615 uint32_t v_z = 0;
50617 if (self->private_impl.f_eob_run > 0u) {
50618 #if defined(__GNUC__)
50619 #pragma GCC diagnostic push
50620 #pragma GCC diagnostic ignored "-Wconversion"
50621 #endif
50622 self->private_impl.f_eob_run -= 1u;
50623 #if defined(__GNUC__)
50624 #pragma GCC diagnostic pop
50625 #endif
50626 return 0u;
50628 v_bits = self->private_impl.f_bitstream_bits;
50629 v_n_bits = self->private_impl.f_bitstream_n_bits;
50630 if (self->private_impl.f_bitstream_ri > self->private_impl.f_bitstream_wi) {
50631 return 2u;
50634 wuffs_base__io_buffer* o_0_v_r = v_r;
50635 const uint8_t* o_0_iop_v_r = iop_v_r;
50636 const uint8_t* o_0_io0_v_r = io0_v_r;
50637 const uint8_t* o_0_io1_v_r = io1_v_r;
50638 const uint8_t* o_0_io2_v_r = io2_v_r;
50639 v_r = wuffs_private_impl__io_reader__set(
50640 &u_r,
50641 &iop_v_r,
50642 &io0_v_r,
50643 &io1_v_r,
50644 &io2_v_r,
50645 wuffs_base__make_slice_u8_ij(self->private_data.f_bitstream_buffer,
50646 self->private_impl.f_bitstream_ri,
50647 self->private_impl.f_bitstream_wi),
50648 ((uint64_t)(self->private_impl.f_bitstream_ri)));
50649 do {
50650 do {
50651 if (((uint64_t)(io2_v_r - iop_v_r)) < 264u) {
50652 v_ret = 1u;
50653 goto label__goto_done__break;
50655 if (v_n_bits < 16u) {
50656 v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u));
50658 v_z = self->private_impl.f_mcu_zig_index;
50659 self->private_impl.f_mcu_zig_index = 0u;
50660 v_ac_h = self->private_impl.f_mcu_blocks_ac_hselector[0u];
50661 v_ac_huff_table_fast = &self->private_impl.f_huff_tables_fast[v_ac_h][0u];
50662 while (v_z <= ((uint32_t)(self->private_impl.f_scan_se))) {
50663 v_ac_ht_fast = ((uint32_t)(v_ac_huff_table_fast[(v_bits >> 56u)]));
50664 if (((uint64_t)(io2_v_r - iop_v_r)) < 8u) {
50665 v_ret = 2u;
50666 goto label__goto_done__break;
50668 v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u));
50669 iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u);
50670 v_n_bits |= 56u;
50671 v_ac_bl = (v_ac_ht_fast >> 8u);
50672 if (v_n_bits >= v_ac_bl) {
50673 v_ac_symbol = (255u & v_ac_ht_fast);
50674 v_bits <<= (v_ac_bl & 63u);
50675 v_n_bits -= v_ac_bl;
50676 } else {
50677 v_ac_code = ((uint32_t)((v_bits >> 55u)));
50678 v_ac_blm1 = 8u;
50679 v_bits <<= 9u;
50680 v_n_bits -= 9u;
50681 while (true) {
50682 v_ac_ht_slow = self->private_impl.f_huff_tables_slow[v_ac_h][v_ac_blm1];
50683 if (v_ac_code < (v_ac_ht_slow >> 8u)) {
50684 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)))]));
50685 break;
50687 v_ac_code = (((uint32_t)(v_ac_code << 1u)) | ((uint32_t)((v_bits >> 63u))));
50688 v_bits <<= 1u;
50689 v_n_bits -= 1u;
50690 v_ac_blm1 = ((v_ac_blm1 + 1u) & 15u);
50691 if (v_ac_blm1 == 0u) {
50692 v_ac_symbol = 0u;
50693 break;
50697 v_ac_rrrr = (v_ac_symbol >> 4u);
50698 v_z += (v_ac_rrrr + 1u);
50699 v_ac_ssss = (v_ac_symbol & 15u);
50700 v_ac_extend = WUFFS_JPEG__EXTEND[v_ac_ssss];
50701 if (v_ac_ssss > 0u) {
50702 v_ac_value = ((uint16_t)((v_bits >> (64u - v_ac_ssss))));
50703 #if defined(__GNUC__)
50704 #pragma GCC diagnostic push
50705 #pragma GCC diagnostic ignored "-Wconversion"
50706 #endif
50707 v_ac_value += ((uint16_t)(v_ac_extend & ((uint16_t)(((uint16_t)(wuffs_base__utility__sign_extend_rshift_u64(v_bits, 63u))) ^ 65535u))));
50708 #if defined(__GNUC__)
50709 #pragma GCC diagnostic pop
50710 #endif
50711 v_bits <<= v_ac_ssss;
50712 v_n_bits -= v_ac_ssss;
50713 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))));
50714 } else if (v_ac_rrrr < 15u) {
50715 self->private_impl.f_eob_run = ((uint16_t)(((uint16_t)(((uint16_t)(((uint16_t)(1u)) << v_ac_rrrr)) - 1u))));
50716 if (v_ac_rrrr > 0u) {
50717 #if defined(__GNUC__)
50718 #pragma GCC diagnostic push
50719 #pragma GCC diagnostic ignored "-Wconversion"
50720 #endif
50721 self->private_impl.f_eob_run += ((uint16_t)((v_bits >> (64u - v_ac_rrrr))));
50722 #if defined(__GNUC__)
50723 #pragma GCC diagnostic pop
50724 #endif
50725 v_bits <<= v_ac_rrrr;
50726 v_n_bits -= v_ac_rrrr;
50728 break;
50731 } while (0);
50732 } while (0);
50733 label__goto_done__break:;
50734 v_pos = ((uint32_t)(wuffs_base__u64__sat_add((v_r ? v_r->meta.pos : 0), ((uint64_t)(iop_v_r - io0_v_r)))));
50735 if (v_pos > self->private_impl.f_bitstream_wi) {
50736 v_ret = 2u;
50737 } else {
50738 self->private_impl.f_bitstream_ri = v_pos;
50740 v_r = o_0_v_r;
50741 iop_v_r = o_0_iop_v_r;
50742 io0_v_r = o_0_io0_v_r;
50743 io1_v_r = o_0_io1_v_r;
50744 io2_v_r = o_0_io2_v_r;
50746 self->private_impl.f_bitstream_bits = v_bits;
50747 self->private_impl.f_bitstream_n_bits = v_n_bits;
50748 return v_ret;
50751 // -------- func jpeg.decoder.decode_mcu_progressive_ac_low_bit
50753 WUFFS_BASE__GENERATED_C_CODE
50754 static uint32_t
50755 wuffs_jpeg__decoder__decode_mcu_progressive_ac_low_bit(
50756 wuffs_jpeg__decoder* self,
50757 wuffs_base__pixel_buffer* a_dst,
50758 wuffs_base__slice_u8 a_workbuf,
50759 uint32_t a_mx,
50760 uint32_t a_my) {
50761 uint32_t v_ret = 0;
50762 uint64_t v_bits = 0;
50763 uint32_t v_n_bits = 0;
50764 uint16_t v_one_lshift_scan_al = 0;
50765 wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer();
50766 wuffs_base__io_buffer* v_r = &u_r;
50767 const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
50768 const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
50769 const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
50770 const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
50771 uint32_t v_pos = 0;
50772 const uint16_t* v_ac_huff_table_fast = NULL;
50773 uint8_t v_ac_h = 0;
50774 uint32_t v_ac_symbol = 0;
50775 uint32_t v_ac_ht_fast = 0;
50776 uint32_t v_ac_bl = 0;
50777 uint32_t v_ac_code = 0;
50778 uint32_t v_ac_blm1 = 0;
50779 uint32_t v_ac_ht_slow = 0;
50780 uint16_t v_ac_value = 0;
50781 uint32_t v_ac_rrrr = 0;
50782 uint32_t v_ac_ssss = 0;
50783 uint8_t v_unzig = 0;
50784 bool v_bit = false;
50786 v_bits = self->private_impl.f_bitstream_bits;
50787 v_n_bits = self->private_impl.f_bitstream_n_bits;
50788 v_one_lshift_scan_al = ((uint16_t)(((uint16_t)(1u)) << self->private_impl.f_scan_al));
50789 if (self->private_impl.f_bitstream_ri > self->private_impl.f_bitstream_wi) {
50790 return 2u;
50793 wuffs_base__io_buffer* o_0_v_r = v_r;
50794 const uint8_t* o_0_iop_v_r = iop_v_r;
50795 const uint8_t* o_0_io0_v_r = io0_v_r;
50796 const uint8_t* o_0_io1_v_r = io1_v_r;
50797 const uint8_t* o_0_io2_v_r = io2_v_r;
50798 v_r = wuffs_private_impl__io_reader__set(
50799 &u_r,
50800 &iop_v_r,
50801 &io0_v_r,
50802 &io1_v_r,
50803 &io2_v_r,
50804 wuffs_base__make_slice_u8_ij(self->private_data.f_bitstream_buffer,
50805 self->private_impl.f_bitstream_ri,
50806 self->private_impl.f_bitstream_wi),
50807 ((uint64_t)(self->private_impl.f_bitstream_ri)));
50808 do {
50809 do {
50810 if (((uint64_t)(io2_v_r - iop_v_r)) < 264u) {
50811 v_ret = 1u;
50812 goto label__goto_done__break;
50814 while (true) {
50815 if (self->private_impl.f_eob_run > 0u) {
50816 break;
50818 v_ac_h = self->private_impl.f_mcu_blocks_ac_hselector[0u];
50819 v_ac_huff_table_fast = &self->private_impl.f_huff_tables_fast[v_ac_h][0u];
50820 while (true) {
50821 if (((uint64_t)(io2_v_r - iop_v_r)) < 8u) {
50822 v_ret = 2u;
50823 goto label__goto_done__break;
50825 v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u));
50826 iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u);
50827 v_n_bits |= 56u;
50828 v_ac_ht_fast = ((uint32_t)(v_ac_huff_table_fast[(v_bits >> 56u)]));
50829 v_ac_bl = (v_ac_ht_fast >> 8u);
50830 if (v_n_bits >= v_ac_bl) {
50831 v_ac_symbol = (255u & v_ac_ht_fast);
50832 v_bits <<= (v_ac_bl & 63u);
50833 v_n_bits -= v_ac_bl;
50834 } else {
50835 v_ac_code = ((uint32_t)((v_bits >> 55u)));
50836 v_ac_blm1 = 8u;
50837 v_bits <<= 9u;
50838 v_n_bits -= 9u;
50839 while (true) {
50840 v_ac_ht_slow = self->private_impl.f_huff_tables_slow[v_ac_h][v_ac_blm1];
50841 if (v_ac_code < (v_ac_ht_slow >> 8u)) {
50842 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)))]));
50843 break;
50845 v_ac_code = (((uint32_t)(v_ac_code << 1u)) | ((uint32_t)((v_bits >> 63u))));
50846 v_bits <<= 1u;
50847 v_n_bits -= 1u;
50848 v_ac_blm1 = ((v_ac_blm1 + 1u) & 15u);
50849 if (v_ac_blm1 == 0u) {
50850 v_ac_symbol = 0u;
50851 break;
50855 v_ac_rrrr = (v_ac_symbol >> 4u);
50856 v_ac_ssss = (v_ac_symbol & 15u);
50857 v_ac_value = 0u;
50858 if (v_ac_ssss > 0u) {
50859 v_ac_value = ((uint16_t)(((uint16_t)(1u)) << self->private_impl.f_scan_al));
50860 if ((v_bits >> 63u) == 0u) {
50861 v_ac_value = ((uint16_t)(((uint16_t)(65535u)) << self->private_impl.f_scan_al));
50863 v_bits <<= 1u;
50864 v_n_bits -= 1u;
50865 } else if (v_ac_rrrr < 15u) {
50866 self->private_impl.f_eob_run = ((uint16_t)(((uint16_t)(1u)) << v_ac_rrrr));
50867 if (v_ac_rrrr > 0u) {
50868 #if defined(__GNUC__)
50869 #pragma GCC diagnostic push
50870 #pragma GCC diagnostic ignored "-Wconversion"
50871 #endif
50872 self->private_impl.f_eob_run += ((uint16_t)((v_bits >> (64u - v_ac_rrrr))));
50873 #if defined(__GNUC__)
50874 #pragma GCC diagnostic pop
50875 #endif
50876 v_bits <<= v_ac_rrrr;
50877 v_n_bits -= v_ac_rrrr;
50879 goto label__goto_do_eob__break;
50881 while (true) {
50882 v_unzig = WUFFS_JPEG__UNZIG[(1u + self->private_impl.f_mcu_zig_index)];
50883 if (self->private_data.f_mcu_blocks[0u][v_unzig] != 0u) {
50884 if (v_n_bits == 0u) {
50885 if (((uint64_t)(io2_v_r - iop_v_r)) < 8u) {
50886 v_ret = 2u;
50887 goto label__goto_done__break;
50889 v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u));
50890 iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u);
50891 v_n_bits |= 56u;
50893 v_bit = ((v_bits >> 63u) > 0u);
50894 v_bits <<= 1u;
50895 v_n_bits -= 1u;
50896 if (v_bit) {
50897 if (self->private_data.f_mcu_blocks[0u][v_unzig] < 32768u) {
50898 #if defined(__GNUC__)
50899 #pragma GCC diagnostic push
50900 #pragma GCC diagnostic ignored "-Wconversion"
50901 #endif
50902 self->private_data.f_mcu_blocks[0u][v_unzig] += v_one_lshift_scan_al;
50903 #if defined(__GNUC__)
50904 #pragma GCC diagnostic pop
50905 #endif
50906 } else {
50907 #if defined(__GNUC__)
50908 #pragma GCC diagnostic push
50909 #pragma GCC diagnostic ignored "-Wconversion"
50910 #endif
50911 self->private_data.f_mcu_blocks[0u][v_unzig] -= v_one_lshift_scan_al;
50912 #if defined(__GNUC__)
50913 #pragma GCC diagnostic pop
50914 #endif
50917 } else if (v_ac_rrrr <= 0u) {
50918 break;
50919 } else {
50920 v_ac_rrrr -= 1u;
50922 if (self->private_impl.f_mcu_zig_index >= ((uint32_t)(self->private_impl.f_scan_se))) {
50923 break;
50925 self->private_impl.f_mcu_zig_index += 1u;
50927 if (v_ac_value != 0u) {
50928 self->private_data.f_mcu_blocks[0u][WUFFS_JPEG__UNZIG[(1u + self->private_impl.f_mcu_zig_index)]] = v_ac_value;
50930 if (self->private_impl.f_mcu_zig_index >= ((uint32_t)(self->private_impl.f_scan_se))) {
50931 break;
50933 self->private_impl.f_mcu_zig_index += 1u;
50935 goto label__block__break;
50937 label__goto_do_eob__break:;
50938 if (self->private_impl.f_eob_run <= 0u) {
50939 v_ret = 2u;
50940 goto label__goto_done__break;
50942 while (true) {
50943 v_unzig = WUFFS_JPEG__UNZIG[(1u + self->private_impl.f_mcu_zig_index)];
50944 if (self->private_data.f_mcu_blocks[0u][v_unzig] != 0u) {
50945 if (v_n_bits == 0u) {
50946 if (((uint64_t)(io2_v_r - iop_v_r)) < 8u) {
50947 v_ret = 2u;
50948 goto label__goto_done__break;
50950 v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u));
50951 iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u);
50952 v_n_bits |= 56u;
50954 v_bit = ((v_bits >> 63u) > 0u);
50955 v_bits <<= 1u;
50956 v_n_bits -= 1u;
50957 if (v_bit) {
50958 if (self->private_data.f_mcu_blocks[0u][v_unzig] < 32768u) {
50959 #if defined(__GNUC__)
50960 #pragma GCC diagnostic push
50961 #pragma GCC diagnostic ignored "-Wconversion"
50962 #endif
50963 self->private_data.f_mcu_blocks[0u][v_unzig] += v_one_lshift_scan_al;
50964 #if defined(__GNUC__)
50965 #pragma GCC diagnostic pop
50966 #endif
50967 } else {
50968 #if defined(__GNUC__)
50969 #pragma GCC diagnostic push
50970 #pragma GCC diagnostic ignored "-Wconversion"
50971 #endif
50972 self->private_data.f_mcu_blocks[0u][v_unzig] -= v_one_lshift_scan_al;
50973 #if defined(__GNUC__)
50974 #pragma GCC diagnostic pop
50975 #endif
50979 if (self->private_impl.f_mcu_zig_index >= ((uint32_t)(self->private_impl.f_scan_se))) {
50980 break;
50982 self->private_impl.f_mcu_zig_index += 1u;
50984 #if defined(__GNUC__)
50985 #pragma GCC diagnostic push
50986 #pragma GCC diagnostic ignored "-Wconversion"
50987 #endif
50988 self->private_impl.f_eob_run -= 1u;
50989 #if defined(__GNUC__)
50990 #pragma GCC diagnostic pop
50991 #endif
50992 } while (0);
50993 label__block__break:;
50994 } while (0);
50995 label__goto_done__break:;
50996 v_pos = ((uint32_t)(wuffs_base__u64__sat_add((v_r ? v_r->meta.pos : 0), ((uint64_t)(iop_v_r - io0_v_r)))));
50997 if (v_pos > self->private_impl.f_bitstream_wi) {
50998 v_ret = 2u;
50999 } else {
51000 self->private_impl.f_bitstream_ri = v_pos;
51002 v_r = o_0_v_r;
51003 iop_v_r = o_0_iop_v_r;
51004 io0_v_r = o_0_io0_v_r;
51005 io1_v_r = o_0_io1_v_r;
51006 io2_v_r = o_0_io2_v_r;
51008 self->private_impl.f_bitstream_bits = v_bits;
51009 self->private_impl.f_bitstream_n_bits = v_n_bits;
51010 return v_ret;
51013 // -------- func jpeg.decoder.decode_mcu_progressive_dc_high_bits
51015 WUFFS_BASE__GENERATED_C_CODE
51016 static uint32_t
51017 wuffs_jpeg__decoder__decode_mcu_progressive_dc_high_bits(
51018 wuffs_jpeg__decoder* self,
51019 wuffs_base__pixel_buffer* a_dst,
51020 wuffs_base__slice_u8 a_workbuf,
51021 uint32_t a_mx,
51022 uint32_t a_my) {
51023 uint32_t v_ret = 0;
51024 uint64_t v_bits = 0;
51025 uint32_t v_n_bits = 0;
51026 uint8_t v_csel = 0;
51027 wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer();
51028 wuffs_base__io_buffer* v_r = &u_r;
51029 const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
51030 const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
51031 const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
51032 const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
51033 uint32_t v_pos = 0;
51034 uint8_t v_dc_h = 0;
51035 uint32_t v_dc_symbol = 0;
51036 uint32_t v_dc_ht_fast = 0;
51037 uint32_t v_dc_bl = 0;
51038 uint32_t v_dc_code = 0;
51039 uint32_t v_dc_blm1 = 0;
51040 uint32_t v_dc_ht_slow = 0;
51041 uint16_t v_dc_value = 0;
51042 uint16_t v_dc_extend = 0;
51044 v_bits = self->private_impl.f_bitstream_bits;
51045 v_n_bits = self->private_impl.f_bitstream_n_bits;
51046 if (self->private_impl.f_bitstream_ri > self->private_impl.f_bitstream_wi) {
51047 return 2u;
51050 wuffs_base__io_buffer* o_0_v_r = v_r;
51051 const uint8_t* o_0_iop_v_r = iop_v_r;
51052 const uint8_t* o_0_io0_v_r = io0_v_r;
51053 const uint8_t* o_0_io1_v_r = io1_v_r;
51054 const uint8_t* o_0_io2_v_r = io2_v_r;
51055 v_r = wuffs_private_impl__io_reader__set(
51056 &u_r,
51057 &iop_v_r,
51058 &io0_v_r,
51059 &io1_v_r,
51060 &io2_v_r,
51061 wuffs_base__make_slice_u8_ij(self->private_data.f_bitstream_buffer,
51062 self->private_impl.f_bitstream_ri,
51063 self->private_impl.f_bitstream_wi),
51064 ((uint64_t)(self->private_impl.f_bitstream_ri)));
51065 do {
51066 while (self->private_impl.f_mcu_current_block < self->private_impl.f_mcu_num_blocks) {
51067 if (((uint64_t)(io2_v_r - iop_v_r)) < 264u) {
51068 v_ret = 1u;
51069 goto label__goto_done__break;
51071 do {
51072 if (((uint64_t)(io2_v_r - iop_v_r)) < 8u) {
51073 v_ret = 2u;
51074 goto label__goto_done__break;
51076 v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u));
51077 iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u);
51078 v_n_bits |= 56u;
51079 v_dc_h = self->private_impl.f_mcu_blocks_dc_hselector[self->private_impl.f_mcu_current_block];
51080 v_dc_ht_fast = ((uint32_t)(self->private_impl.f_huff_tables_fast[v_dc_h][(v_bits >> 56u)]));
51081 v_dc_bl = (v_dc_ht_fast >> 8u);
51082 if (v_n_bits >= v_dc_bl) {
51083 v_dc_symbol = (15u & v_dc_ht_fast);
51084 v_dc_extend = WUFFS_JPEG__EXTEND[v_dc_symbol];
51085 v_bits <<= (v_dc_bl & 63u);
51086 v_n_bits -= v_dc_bl;
51087 } else {
51088 v_dc_code = ((uint32_t)((v_bits >> 55u)));
51089 v_dc_blm1 = 8u;
51090 v_bits <<= 9u;
51091 v_n_bits -= 9u;
51092 while (true) {
51093 v_dc_ht_slow = self->private_impl.f_huff_tables_slow[v_dc_h][v_dc_blm1];
51094 if (v_dc_code < (v_dc_ht_slow >> 8u)) {
51095 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)))])));
51096 v_dc_extend = WUFFS_JPEG__EXTEND[v_dc_symbol];
51097 break;
51099 v_dc_code = (((uint32_t)(v_dc_code << 1u)) | ((uint32_t)((v_bits >> 63u))));
51100 v_bits <<= 1u;
51101 v_n_bits -= 1u;
51102 v_dc_blm1 = ((v_dc_blm1 + 1u) & 15u);
51103 if (v_dc_blm1 == 0u) {
51104 v_dc_symbol = 0u;
51105 v_dc_extend = WUFFS_JPEG__EXTEND[v_dc_symbol];
51106 break;
51110 v_dc_value = ((uint16_t)(((v_bits >> 32u) >> (32u - v_dc_symbol))));
51111 #if defined(__GNUC__)
51112 #pragma GCC diagnostic push
51113 #pragma GCC diagnostic ignored "-Wconversion"
51114 #endif
51115 v_dc_value += ((uint16_t)(v_dc_extend & ((uint16_t)(((uint16_t)(wuffs_base__utility__sign_extend_rshift_u64(v_bits, 63u))) ^ 65535u))));
51116 #if defined(__GNUC__)
51117 #pragma GCC diagnostic pop
51118 #endif
51119 v_bits <<= v_dc_symbol;
51120 v_n_bits -= v_dc_symbol;
51121 v_csel = self->private_impl.f_scan_comps_cselector[self->private_impl.f_mcu_blocks_sselector[self->private_impl.f_mcu_current_block]];
51122 #if defined(__GNUC__)
51123 #pragma GCC diagnostic push
51124 #pragma GCC diagnostic ignored "-Wconversion"
51125 #endif
51126 self->private_impl.f_mcu_previous_dc_values[v_csel] += v_dc_value;
51127 #if defined(__GNUC__)
51128 #pragma GCC diagnostic pop
51129 #endif
51130 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));
51131 } while (0);
51132 self->private_impl.f_mcu_current_block += 1u;
51134 self->private_impl.f_mcu_current_block = 0u;
51135 } while (0);
51136 label__goto_done__break:;
51137 v_pos = ((uint32_t)(wuffs_base__u64__sat_add((v_r ? v_r->meta.pos : 0), ((uint64_t)(iop_v_r - io0_v_r)))));
51138 if (v_pos > self->private_impl.f_bitstream_wi) {
51139 v_ret = 2u;
51140 } else {
51141 self->private_impl.f_bitstream_ri = v_pos;
51143 v_r = o_0_v_r;
51144 iop_v_r = o_0_iop_v_r;
51145 io0_v_r = o_0_io0_v_r;
51146 io1_v_r = o_0_io1_v_r;
51147 io2_v_r = o_0_io2_v_r;
51149 self->private_impl.f_bitstream_bits = v_bits;
51150 self->private_impl.f_bitstream_n_bits = v_n_bits;
51151 return v_ret;
51154 // -------- func jpeg.decoder.decode_mcu_progressive_dc_low_bit
51156 WUFFS_BASE__GENERATED_C_CODE
51157 static uint32_t
51158 wuffs_jpeg__decoder__decode_mcu_progressive_dc_low_bit(
51159 wuffs_jpeg__decoder* self,
51160 wuffs_base__pixel_buffer* a_dst,
51161 wuffs_base__slice_u8 a_workbuf,
51162 uint32_t a_mx,
51163 uint32_t a_my) {
51164 uint32_t v_ret = 0;
51165 uint64_t v_bits = 0;
51166 uint32_t v_n_bits = 0;
51167 uint16_t v_one_lshift_scan_al = 0;
51168 wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer();
51169 wuffs_base__io_buffer* v_r = &u_r;
51170 const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
51171 const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
51172 const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
51173 const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
51174 uint32_t v_pos = 0;
51176 v_bits = self->private_impl.f_bitstream_bits;
51177 v_n_bits = self->private_impl.f_bitstream_n_bits;
51178 v_one_lshift_scan_al = ((uint16_t)(((uint16_t)(1u)) << self->private_impl.f_scan_al));
51179 if (self->private_impl.f_bitstream_ri > self->private_impl.f_bitstream_wi) {
51180 return 2u;
51183 wuffs_base__io_buffer* o_0_v_r = v_r;
51184 const uint8_t* o_0_iop_v_r = iop_v_r;
51185 const uint8_t* o_0_io0_v_r = io0_v_r;
51186 const uint8_t* o_0_io1_v_r = io1_v_r;
51187 const uint8_t* o_0_io2_v_r = io2_v_r;
51188 v_r = wuffs_private_impl__io_reader__set(
51189 &u_r,
51190 &iop_v_r,
51191 &io0_v_r,
51192 &io1_v_r,
51193 &io2_v_r,
51194 wuffs_base__make_slice_u8_ij(self->private_data.f_bitstream_buffer,
51195 self->private_impl.f_bitstream_ri,
51196 self->private_impl.f_bitstream_wi),
51197 ((uint64_t)(self->private_impl.f_bitstream_ri)));
51198 do {
51199 while (self->private_impl.f_mcu_current_block < self->private_impl.f_mcu_num_blocks) {
51200 if (((uint64_t)(io2_v_r - iop_v_r)) < 264u) {
51201 v_ret = 1u;
51202 goto label__goto_done__break;
51204 do {
51205 if (((uint64_t)(io2_v_r - iop_v_r)) < 8u) {
51206 v_ret = 2u;
51207 goto label__goto_done__break;
51209 v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u));
51210 iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u);
51211 v_n_bits |= 56u;
51212 if ((v_bits >> 63u) != 0u) {
51213 self->private_data.f_mcu_blocks[self->private_impl.f_mcu_current_block][0u] |= v_one_lshift_scan_al;
51215 v_bits <<= 1u;
51216 v_n_bits -= 1u;
51217 } while (0);
51218 self->private_impl.f_mcu_current_block += 1u;
51220 self->private_impl.f_mcu_current_block = 0u;
51221 } while (0);
51222 label__goto_done__break:;
51223 v_pos = ((uint32_t)(wuffs_base__u64__sat_add((v_r ? v_r->meta.pos : 0), ((uint64_t)(iop_v_r - io0_v_r)))));
51224 if (v_pos > self->private_impl.f_bitstream_wi) {
51225 v_ret = 2u;
51226 } else {
51227 self->private_impl.f_bitstream_ri = v_pos;
51229 v_r = o_0_v_r;
51230 iop_v_r = o_0_iop_v_r;
51231 io0_v_r = o_0_io0_v_r;
51232 io1_v_r = o_0_io1_v_r;
51233 io2_v_r = o_0_io2_v_r;
51235 self->private_impl.f_bitstream_bits = v_bits;
51236 self->private_impl.f_bitstream_n_bits = v_n_bits;
51237 return v_ret;
51240 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JPEG)
51242 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JSON)
51244 // ---------------- Status Codes Implementations
51246 const char wuffs_json__error__bad_c0_control_code[] = "#json: bad C0 control code";
51247 const char wuffs_json__error__bad_utf_8[] = "#json: bad UTF-8";
51248 const char wuffs_json__error__bad_backslash_escape[] = "#json: bad backslash-escape";
51249 const char wuffs_json__error__bad_input[] = "#json: bad input";
51250 const char wuffs_json__error__bad_new_line_in_a_string[] = "#json: bad new-line in a string";
51251 const char wuffs_json__error__bad_quirk_combination[] = "#json: bad quirk combination";
51252 const char wuffs_json__error__unsupported_number_length[] = "#json: unsupported number length";
51253 const char wuffs_json__error__unsupported_recursion_depth[] = "#json: unsupported recursion depth";
51254 const char wuffs_json__error__internal_error_inconsistent_i_o[] = "#json: internal error: inconsistent I/O";
51256 // ---------------- Private Consts
51258 #define WUFFS_JSON__DECODER_NUMBER_LENGTH_MAX_INCL 99u
51260 static const uint8_t
51261 WUFFS_JSON__LUT_BACKSLASHES[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
51262 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51263 0u, 0u, 3u, 0u, 0u, 0u, 0u, 0u,
51264 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51265 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51266 0u, 0u, 162u, 0u, 0u, 0u, 0u, 5u,
51267 0u, 0u, 0u, 0u, 0u, 0u, 0u, 175u,
51268 7u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51269 0u, 0u, 0u, 0u, 0u, 0u, 0u, 4u,
51270 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51271 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51272 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51273 0u, 0u, 0u, 0u, 220u, 0u, 0u, 0u,
51274 0u, 1u, 136u, 0u, 0u, 2u, 140u, 0u,
51275 0u, 0u, 0u, 0u, 0u, 0u, 138u, 0u,
51276 0u, 0u, 141u, 0u, 137u, 0u, 6u, 0u,
51277 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51278 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51279 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51280 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51281 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51282 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51283 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51284 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51285 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51286 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51287 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51288 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51289 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51290 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51291 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51292 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51293 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51296 static const uint8_t
51297 WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_QUIRKS[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
51298 0u, 1u, 3u, 4u, 5u, 6u, 7u, 10u,
51301 static const uint8_t
51302 WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_CHARS[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
51303 0u, 7u, 27u, 10u, 63u, 39u, 11u, 0u,
51306 static const uint8_t
51307 WUFFS_JSON__LUT_CHARS[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
51308 128u, 129u, 130u, 131u, 132u, 133u, 134u, 135u,
51309 136u, 137u, 138u, 139u, 140u, 141u, 142u, 143u,
51310 144u, 145u, 146u, 147u, 148u, 149u, 150u, 151u,
51311 152u, 153u, 154u, 155u, 156u, 157u, 158u, 159u,
51312 0u, 0u, 1u, 0u, 0u, 0u, 0u, 0u,
51313 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51314 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51315 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51316 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51317 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51318 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51319 0u, 0u, 0u, 0u, 2u, 0u, 0u, 0u,
51320 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51321 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51322 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51323 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51324 16u, 16u, 16u, 16u, 16u, 16u, 16u, 16u,
51325 16u, 16u, 16u, 16u, 16u, 16u, 16u, 16u,
51326 16u, 16u, 16u, 16u, 16u, 16u, 16u, 16u,
51327 16u, 16u, 16u, 16u, 16u, 16u, 16u, 16u,
51328 16u, 16u, 16u, 16u, 16u, 16u, 16u, 16u,
51329 16u, 16u, 16u, 16u, 16u, 16u, 16u, 16u,
51330 16u, 16u, 16u, 16u, 16u, 16u, 16u, 16u,
51331 16u, 16u, 16u, 16u, 16u, 16u, 16u, 16u,
51332 32u, 32u, 3u, 3u, 3u, 3u, 3u, 3u,
51333 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u,
51334 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u,
51335 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u,
51336 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u,
51337 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u,
51338 5u, 5u, 5u, 5u, 5u, 32u, 32u, 32u,
51339 32u, 32u, 32u, 32u, 32u, 32u, 32u, 32u,
51342 #define WUFFS_JSON__CLASS_WHITESPACE 0u
51344 #define WUFFS_JSON__CLASS_STRING 1u
51346 #define WUFFS_JSON__CLASS_COMMA 2u
51348 #define WUFFS_JSON__CLASS_COLON 3u
51350 #define WUFFS_JSON__CLASS_NUMBER 4u
51352 #define WUFFS_JSON__CLASS_OPEN_CURLY_BRACE 5u
51354 #define WUFFS_JSON__CLASS_CLOSE_CURLY_BRACE 6u
51356 #define WUFFS_JSON__CLASS_OPEN_SQUARE_BRACKET 7u
51358 #define WUFFS_JSON__CLASS_CLOSE_SQUARE_BRACKET 8u
51360 #define WUFFS_JSON__CLASS_FALSE 9u
51362 #define WUFFS_JSON__CLASS_TRUE 10u
51364 #define WUFFS_JSON__CLASS_NULL_NAN_INF 11u
51366 #define WUFFS_JSON__CLASS_COMMENT 12u
51368 #define WUFFS_JSON__EXPECT_VALUE 7858u
51370 #define WUFFS_JSON__EXPECT_NON_STRING_VALUE 7856u
51372 #define WUFFS_JSON__EXPECT_STRING 4098u
51374 #define WUFFS_JSON__EXPECT_COMMA 4100u
51376 #define WUFFS_JSON__EXPECT_COLON 4104u
51378 #define WUFFS_JSON__EXPECT_NUMBER 4112u
51380 #define WUFFS_JSON__EXPECT_CLOSE_CURLY_BRACE 4160u
51382 #define WUFFS_JSON__EXPECT_CLOSE_SQUARE_BRACKET 4352u
51384 static const uint8_t
51385 WUFFS_JSON__LUT_CLASSES[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
51386 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u,
51387 15u, 0u, 0u, 15u, 15u, 0u, 15u, 15u,
51388 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u,
51389 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u,
51390 0u, 15u, 1u, 15u, 15u, 15u, 15u, 15u,
51391 15u, 15u, 15u, 11u, 2u, 4u, 15u, 12u,
51392 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u,
51393 4u, 4u, 3u, 15u, 15u, 15u, 15u, 15u,
51394 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u,
51395 15u, 11u, 15u, 15u, 15u, 15u, 11u, 15u,
51396 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u,
51397 15u, 15u, 15u, 7u, 15u, 8u, 15u, 15u,
51398 15u, 15u, 15u, 15u, 15u, 15u, 9u, 15u,
51399 15u, 11u, 15u, 15u, 15u, 15u, 11u, 15u,
51400 15u, 15u, 15u, 15u, 10u, 15u, 15u, 15u,
51401 15u, 15u, 15u, 5u, 15u, 6u, 15u, 15u,
51402 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u,
51403 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u,
51404 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u,
51405 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u,
51406 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u,
51407 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u,
51408 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u,
51409 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u,
51410 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u,
51411 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u,
51412 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u,
51413 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u,
51414 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u,
51415 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u,
51416 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u,
51417 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u,
51420 static const uint8_t
51421 WUFFS_JSON__LUT_DECIMAL_DIGITS[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
51422 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51423 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51424 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51425 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51426 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51427 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51428 128u, 129u, 130u, 131u, 132u, 133u, 134u, 135u,
51429 136u, 137u, 0u, 0u, 0u, 0u, 0u, 0u,
51430 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51431 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51432 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51433 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51434 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51435 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51436 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51437 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51438 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51439 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51440 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51441 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51442 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51443 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51444 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51445 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51446 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51447 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51448 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51449 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51450 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51451 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51452 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51453 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51456 static const uint8_t
51457 WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
51458 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51459 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51460 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51461 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51462 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51463 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51464 128u, 129u, 130u, 131u, 132u, 133u, 134u, 135u,
51465 136u, 137u, 0u, 0u, 0u, 0u, 0u, 0u,
51466 0u, 138u, 139u, 140u, 141u, 142u, 143u, 0u,
51467 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51468 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51469 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51470 0u, 138u, 139u, 140u, 141u, 142u, 143u, 0u,
51471 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51472 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51473 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51474 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51475 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51476 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51477 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51478 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51479 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51480 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51481 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51482 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51483 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51484 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51485 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51486 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51487 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51488 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51489 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
51492 #define WUFFS_JSON__QUIRKS_BASE 1225364480u
51494 #define WUFFS_JSON__QUIRKS_COUNT 21u
51496 // ---------------- Private Initializer Prototypes
51498 // ---------------- Private Function Prototypes
51500 WUFFS_BASE__GENERATED_C_CODE
51501 static uint32_t
51502 wuffs_json__decoder__decode_number(
51503 wuffs_json__decoder* self,
51504 wuffs_base__io_buffer* a_src);
51506 WUFFS_BASE__GENERATED_C_CODE
51507 static uint32_t
51508 wuffs_json__decoder__decode_digits(
51509 wuffs_json__decoder* self,
51510 wuffs_base__io_buffer* a_src,
51511 uint32_t a_n);
51513 WUFFS_BASE__GENERATED_C_CODE
51514 static wuffs_base__status
51515 wuffs_json__decoder__decode_leading(
51516 wuffs_json__decoder* self,
51517 wuffs_base__token_buffer* a_dst,
51518 wuffs_base__io_buffer* a_src);
51520 WUFFS_BASE__GENERATED_C_CODE
51521 static wuffs_base__status
51522 wuffs_json__decoder__decode_comment(
51523 wuffs_json__decoder* self,
51524 wuffs_base__token_buffer* a_dst,
51525 wuffs_base__io_buffer* a_src);
51527 WUFFS_BASE__GENERATED_C_CODE
51528 static wuffs_base__status
51529 wuffs_json__decoder__decode_inf_nan(
51530 wuffs_json__decoder* self,
51531 wuffs_base__token_buffer* a_dst,
51532 wuffs_base__io_buffer* a_src);
51534 WUFFS_BASE__GENERATED_C_CODE
51535 static wuffs_base__status
51536 wuffs_json__decoder__decode_trailer(
51537 wuffs_json__decoder* self,
51538 wuffs_base__token_buffer* a_dst,
51539 wuffs_base__io_buffer* a_src);
51541 // ---------------- VTables
51543 const wuffs_base__token_decoder__func_ptrs
51544 wuffs_json__decoder__func_ptrs_for__wuffs_base__token_decoder = {
51545 (wuffs_base__status(*)(void*,
51546 wuffs_base__token_buffer*,
51547 wuffs_base__io_buffer*,
51548 wuffs_base__slice_u8))(&wuffs_json__decoder__decode_tokens),
51549 (uint64_t(*)(const void*,
51550 uint32_t))(&wuffs_json__decoder__get_quirk),
51551 (wuffs_base__status(*)(void*,
51552 uint32_t,
51553 uint64_t))(&wuffs_json__decoder__set_quirk),
51554 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_json__decoder__workbuf_len),
51557 // ---------------- Initializer Implementations
51559 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
51560 wuffs_json__decoder__initialize(
51561 wuffs_json__decoder* self,
51562 size_t sizeof_star_self,
51563 uint64_t wuffs_version,
51564 uint32_t options){
51565 if (!self) {
51566 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
51568 if (sizeof(*self) != sizeof_star_self) {
51569 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
51571 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
51572 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
51573 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
51576 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
51577 // The whole point of this if-check is to detect an uninitialized *self.
51578 // We disable the warning on GCC. Clang-5.0 does not have this warning.
51579 #if !defined(__clang__) && defined(__GNUC__)
51580 #pragma GCC diagnostic push
51581 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
51582 #endif
51583 if (self->private_impl.magic != 0) {
51584 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
51586 #if !defined(__clang__) && defined(__GNUC__)
51587 #pragma GCC diagnostic pop
51588 #endif
51589 } else {
51590 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
51591 memset(self, 0, sizeof(*self));
51592 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
51593 } else {
51594 memset(&(self->private_impl), 0, sizeof(self->private_impl));
51598 self->private_impl.magic = WUFFS_BASE__MAGIC;
51599 self->private_impl.vtable_for__wuffs_base__token_decoder.vtable_name =
51600 wuffs_base__token_decoder__vtable_name;
51601 self->private_impl.vtable_for__wuffs_base__token_decoder.function_pointers =
51602 (const void*)(&wuffs_json__decoder__func_ptrs_for__wuffs_base__token_decoder);
51603 return wuffs_base__make_status(NULL);
51606 wuffs_json__decoder*
51607 wuffs_json__decoder__alloc(void) {
51608 wuffs_json__decoder* x =
51609 (wuffs_json__decoder*)(calloc(1, sizeof(wuffs_json__decoder)));
51610 if (!x) {
51611 return NULL;
51613 if (wuffs_json__decoder__initialize(
51614 x, sizeof(wuffs_json__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
51615 free(x);
51616 return NULL;
51618 return x;
51621 size_t
51622 sizeof__wuffs_json__decoder(void) {
51623 return sizeof(wuffs_json__decoder);
51626 // ---------------- Function Implementations
51628 // -------- func json.decoder.get_quirk
51630 WUFFS_BASE__GENERATED_C_CODE
51631 WUFFS_BASE__MAYBE_STATIC uint64_t
51632 wuffs_json__decoder__get_quirk(
51633 const wuffs_json__decoder* self,
51634 uint32_t a_key) {
51635 if (!self) {
51636 return 0;
51638 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
51639 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
51640 return 0;
51643 uint32_t v_key = 0;
51645 if (a_key >= 1225364480u) {
51646 v_key = (a_key - 1225364480u);
51647 if (v_key < 21u) {
51648 if (self->private_impl.f_quirks[v_key]) {
51649 return 1u;
51653 return 0u;
51656 // -------- func json.decoder.set_quirk
51658 WUFFS_BASE__GENERATED_C_CODE
51659 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
51660 wuffs_json__decoder__set_quirk(
51661 wuffs_json__decoder* self,
51662 uint32_t a_key,
51663 uint64_t a_value) {
51664 if (!self) {
51665 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
51667 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
51668 return wuffs_base__make_status(
51669 (self->private_impl.magic == WUFFS_BASE__DISABLED)
51670 ? wuffs_base__error__disabled_by_previous_error
51671 : wuffs_base__error__initialize_not_called);
51674 if (a_key >= 1225364480u) {
51675 a_key -= 1225364480u;
51676 if (a_key < 21u) {
51677 self->private_impl.f_quirks[a_key] = (a_value > 0u);
51678 return wuffs_base__make_status(NULL);
51681 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
51684 // -------- func json.decoder.workbuf_len
51686 WUFFS_BASE__GENERATED_C_CODE
51687 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
51688 wuffs_json__decoder__workbuf_len(
51689 const wuffs_json__decoder* self) {
51690 if (!self) {
51691 return wuffs_base__utility__empty_range_ii_u64();
51693 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
51694 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
51695 return wuffs_base__utility__empty_range_ii_u64();
51698 return wuffs_base__utility__empty_range_ii_u64();
51701 // -------- func json.decoder.decode_tokens
51703 WUFFS_BASE__GENERATED_C_CODE
51704 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
51705 wuffs_json__decoder__decode_tokens(
51706 wuffs_json__decoder* self,
51707 wuffs_base__token_buffer* a_dst,
51708 wuffs_base__io_buffer* a_src,
51709 wuffs_base__slice_u8 a_workbuf) {
51710 if (!self) {
51711 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
51713 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
51714 return wuffs_base__make_status(
51715 (self->private_impl.magic == WUFFS_BASE__DISABLED)
51716 ? wuffs_base__error__disabled_by_previous_error
51717 : wuffs_base__error__initialize_not_called);
51719 if (!a_dst || !a_src) {
51720 self->private_impl.magic = WUFFS_BASE__DISABLED;
51721 return wuffs_base__make_status(wuffs_base__error__bad_argument);
51723 if ((self->private_impl.active_coroutine != 0) &&
51724 (self->private_impl.active_coroutine != 1)) {
51725 self->private_impl.magic = WUFFS_BASE__DISABLED;
51726 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
51728 self->private_impl.active_coroutine = 0;
51729 wuffs_base__status status = wuffs_base__make_status(NULL);
51731 uint32_t v_vminor = 0;
51732 uint32_t v_number_length = 0;
51733 uint32_t v_number_status = 0;
51734 uint32_t v_string_length = 0;
51735 uint32_t v_whitespace_length = 0;
51736 uint32_t v_depth = 0;
51737 uint32_t v_stack_byte = 0;
51738 uint32_t v_stack_bit = 0;
51739 uint32_t v_match = 0;
51740 uint32_t v_c32 = 0;
51741 uint8_t v_c8 = 0;
51742 uint8_t v_backslash = 0;
51743 uint8_t v_char = 0;
51744 uint8_t v_class = 0;
51745 uint32_t v_multi_byte_utf8 = 0;
51746 uint8_t v_backslash_x_ok = 0;
51747 uint8_t v_backslash_x_value = 0;
51748 uint32_t v_backslash_x_string = 0;
51749 uint8_t v_uni4_ok = 0;
51750 uint64_t v_uni4_string = 0;
51751 uint32_t v_uni4_value = 0;
51752 uint32_t v_uni4_high_surrogate = 0;
51753 uint8_t v_uni8_ok = 0;
51754 uint64_t v_uni8_string = 0;
51755 uint32_t v_uni8_value = 0;
51756 uint32_t v_expect = 0;
51757 uint32_t v_expect_after_value = 0;
51759 wuffs_base__token* iop_a_dst = NULL;
51760 wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
51761 wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
51762 wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
51763 if (a_dst && a_dst->data.ptr) {
51764 io0_a_dst = a_dst->data.ptr;
51765 io1_a_dst = io0_a_dst + a_dst->meta.wi;
51766 iop_a_dst = io1_a_dst;
51767 io2_a_dst = io0_a_dst + a_dst->data.len;
51768 if (a_dst->meta.closed) {
51769 io2_a_dst = iop_a_dst;
51772 const uint8_t* iop_a_src = NULL;
51773 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
51774 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
51775 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
51776 if (a_src && a_src->data.ptr) {
51777 io0_a_src = a_src->data.ptr;
51778 io1_a_src = io0_a_src + a_src->meta.ri;
51779 iop_a_src = io1_a_src;
51780 io2_a_src = io0_a_src + a_src->meta.wi;
51783 uint32_t coro_susp_point = self->private_impl.p_decode_tokens;
51784 if (coro_susp_point) {
51785 v_depth = self->private_data.s_decode_tokens.v_depth;
51786 v_expect = self->private_data.s_decode_tokens.v_expect;
51787 v_expect_after_value = self->private_data.s_decode_tokens.v_expect_after_value;
51789 switch (coro_susp_point) {
51790 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
51792 if (self->private_impl.f_end_of_data) {
51793 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
51794 goto ok;
51796 if (self->private_impl.f_quirks[18u]) {
51797 if (self->private_impl.f_quirks[11u] || self->private_impl.f_quirks[12u] || self->private_impl.f_quirks[17u]) {
51798 status = wuffs_base__make_status(wuffs_json__error__bad_quirk_combination);
51799 goto exit;
51802 if (self->private_impl.f_quirks[15u] || self->private_impl.f_quirks[16u]) {
51803 if (a_dst) {
51804 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
51806 if (a_src) {
51807 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
51809 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
51810 status = wuffs_json__decoder__decode_leading(self, a_dst, a_src);
51811 if (a_dst) {
51812 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
51814 if (a_src) {
51815 iop_a_src = a_src->data.ptr + a_src->meta.ri;
51817 if (status.repr) {
51818 goto suspend;
51821 v_expect = 7858u;
51822 label__outer__continue:;
51823 while (true) {
51824 while (true) {
51825 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
51826 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
51827 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
51828 goto label__outer__continue;
51830 v_whitespace_length = 0u;
51831 v_c8 = 0u;
51832 v_class = 0u;
51833 while (true) {
51834 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
51835 if (v_whitespace_length > 0u) {
51836 *iop_a_dst++ = wuffs_base__make_token(
51837 (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
51838 (((uint64_t)(v_whitespace_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
51839 v_whitespace_length = 0u;
51841 if (a_src && a_src->meta.closed) {
51842 status = wuffs_base__make_status(wuffs_json__error__bad_input);
51843 goto exit;
51845 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
51846 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
51847 goto label__outer__continue;
51849 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
51850 v_class = WUFFS_JSON__LUT_CLASSES[v_c8];
51851 if (v_class != 0u) {
51852 break;
51854 iop_a_src += 1u;
51855 if (v_whitespace_length >= 65534u) {
51856 *iop_a_dst++ = wuffs_base__make_token(
51857 (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
51858 (((uint64_t)(65535u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
51859 v_whitespace_length = 0u;
51860 goto label__outer__continue;
51862 v_whitespace_length += 1u;
51864 if (v_whitespace_length > 0u) {
51865 *iop_a_dst++ = wuffs_base__make_token(
51866 (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
51867 (((uint64_t)(v_whitespace_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
51868 v_whitespace_length = 0u;
51869 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
51870 goto label__outer__continue;
51873 if (0u == (v_expect & (((uint32_t)(1u)) << v_class))) {
51874 status = wuffs_base__make_status(wuffs_json__error__bad_input);
51875 goto exit;
51877 if (v_class == 1u) {
51878 *iop_a_dst++ = wuffs_base__make_token(
51879 (((uint64_t)(4194579u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
51880 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
51881 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
51882 iop_a_src += 1u;
51883 label__string_loop_outer__continue:;
51884 while (true) {
51885 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
51886 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
51887 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
51888 continue;
51890 v_string_length = 0u;
51891 while (true) {
51892 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
51893 if (v_string_length > 0u) {
51894 *iop_a_dst++ = wuffs_base__make_token(
51895 (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
51896 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
51897 (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
51898 v_string_length = 0u;
51900 if (a_src && a_src->meta.closed) {
51901 status = wuffs_base__make_status(wuffs_json__error__bad_input);
51902 goto exit;
51904 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
51905 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
51906 goto label__string_loop_outer__continue;
51908 while (((uint64_t)(io2_a_src - iop_a_src)) > 4u) {
51909 v_c32 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
51910 if (0u != (WUFFS_JSON__LUT_CHARS[(255u & (v_c32 >> 0u))] |
51911 WUFFS_JSON__LUT_CHARS[(255u & (v_c32 >> 8u))] |
51912 WUFFS_JSON__LUT_CHARS[(255u & (v_c32 >> 16u))] |
51913 WUFFS_JSON__LUT_CHARS[(255u & (v_c32 >> 24u))])) {
51914 break;
51916 iop_a_src += 4u;
51917 if (v_string_length > 65527u) {
51918 *iop_a_dst++ = wuffs_base__make_token(
51919 (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
51920 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
51921 (((uint64_t)((v_string_length + 4u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
51922 v_string_length = 0u;
51923 goto label__string_loop_outer__continue;
51925 v_string_length += 4u;
51927 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
51928 v_char = WUFFS_JSON__LUT_CHARS[v_c8];
51929 if (v_char == 0u) {
51930 iop_a_src += 1u;
51931 if (v_string_length >= 65531u) {
51932 *iop_a_dst++ = wuffs_base__make_token(
51933 (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
51934 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
51935 (((uint64_t)(65532u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
51936 v_string_length = 0u;
51937 goto label__string_loop_outer__continue;
51939 v_string_length += 1u;
51940 continue;
51941 } else if (v_char == 1u) {
51942 if (v_string_length != 0u) {
51943 *iop_a_dst++ = wuffs_base__make_token(
51944 (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
51945 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
51946 (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
51947 v_string_length = 0u;
51949 goto label__string_loop_outer__break;
51950 } else if (v_char == 2u) {
51951 if (v_string_length > 0u) {
51952 *iop_a_dst++ = wuffs_base__make_token(
51953 (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
51954 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
51955 (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
51956 v_string_length = 0u;
51957 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
51958 goto label__string_loop_outer__continue;
51961 if (((uint64_t)(io2_a_src - iop_a_src)) < 2u) {
51962 if (a_src && a_src->meta.closed) {
51963 status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
51964 goto exit;
51966 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
51967 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
51968 goto label__string_loop_outer__continue;
51970 v_c8 = ((uint8_t)(((uint16_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src) >> 8u))));
51971 v_backslash = WUFFS_JSON__LUT_BACKSLASHES[v_c8];
51972 if (((uint8_t)(v_backslash & 128u)) != 0u) {
51973 iop_a_src += 2u;
51974 *iop_a_dst++ = wuffs_base__make_token(
51975 (((uint64_t)((6291456u | ((uint32_t)(((uint8_t)(v_backslash & 127u))))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
51976 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
51977 (((uint64_t)(2u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
51978 goto label__string_loop_outer__continue;
51979 } else if (v_backslash != 0u) {
51980 if (self->private_impl.f_quirks[WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_QUIRKS[((uint8_t)(v_backslash & 7u))]]) {
51981 iop_a_src += 2u;
51982 *iop_a_dst++ = wuffs_base__make_token(
51983 (((uint64_t)((6291456u | ((uint32_t)(WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_CHARS[((uint8_t)(v_backslash & 7u))]))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
51984 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
51985 (((uint64_t)(2u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
51986 goto label__string_loop_outer__continue;
51988 } else if (v_c8 == 117u) {
51989 if (((uint64_t)(io2_a_src - iop_a_src)) < 6u) {
51990 if (a_src && a_src->meta.closed) {
51991 status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
51992 goto exit;
51994 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
51995 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7);
51996 goto label__string_loop_outer__continue;
51998 v_uni4_string = (((uint64_t)(wuffs_base__peek_u48le__no_bounds_check(iop_a_src))) >> 16u);
51999 v_uni4_value = 0u;
52000 v_uni4_ok = 128u;
52001 v_c8 = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 0u))];
52002 v_uni4_ok &= v_c8;
52003 v_uni4_value |= (((uint32_t)(((uint8_t)(v_c8 & 15u)))) << 12u);
52004 v_c8 = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 8u))];
52005 v_uni4_ok &= v_c8;
52006 v_uni4_value |= (((uint32_t)(((uint8_t)(v_c8 & 15u)))) << 8u);
52007 v_c8 = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 16u))];
52008 v_uni4_ok &= v_c8;
52009 v_uni4_value |= (((uint32_t)(((uint8_t)(v_c8 & 15u)))) << 4u);
52010 v_c8 = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 24u))];
52011 v_uni4_ok &= v_c8;
52012 v_uni4_value |= (((uint32_t)(((uint8_t)(v_c8 & 15u)))) << 0u);
52013 if (v_uni4_ok == 0u) {
52014 } else if ((v_uni4_value < 55296u) || (57343u < v_uni4_value)) {
52015 iop_a_src += 6u;
52016 *iop_a_dst++ = wuffs_base__make_token(
52017 (((uint64_t)((6291456u | v_uni4_value))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
52018 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
52019 (((uint64_t)(6u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
52020 goto label__string_loop_outer__continue;
52021 } else if (v_uni4_value >= 56320u) {
52022 } else {
52023 if (((uint64_t)(io2_a_src - iop_a_src)) < 12u) {
52024 if (a_src && a_src->meta.closed) {
52025 if (self->private_impl.f_quirks[20u]) {
52026 iop_a_src += 6u;
52027 *iop_a_dst++ = wuffs_base__make_token(
52028 (((uint64_t)(6356989u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
52029 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
52030 (((uint64_t)(6u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
52031 goto label__string_loop_outer__continue;
52033 status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
52034 goto exit;
52036 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
52037 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8);
52038 goto label__string_loop_outer__continue;
52040 v_uni4_string = (wuffs_base__peek_u64le__no_bounds_check(iop_a_src + 4u) >> 16u);
52041 if (((255u & (v_uni4_string >> 0u)) != 92u) || ((255u & (v_uni4_string >> 8u)) != 117u)) {
52042 v_uni4_high_surrogate = 0u;
52043 v_uni4_value = 0u;
52044 v_uni4_ok = 0u;
52045 } else {
52046 v_uni4_high_surrogate = (65536u + ((v_uni4_value - 55296u) << 10u));
52047 v_uni4_value = 0u;
52048 v_uni4_ok = 128u;
52049 v_uni4_string >>= 16u;
52050 v_c8 = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 0u))];
52051 v_uni4_ok &= v_c8;
52052 v_uni4_value |= (((uint32_t)(((uint8_t)(v_c8 & 15u)))) << 12u);
52053 v_c8 = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 8u))];
52054 v_uni4_ok &= v_c8;
52055 v_uni4_value |= (((uint32_t)(((uint8_t)(v_c8 & 15u)))) << 8u);
52056 v_c8 = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 16u))];
52057 v_uni4_ok &= v_c8;
52058 v_uni4_value |= (((uint32_t)(((uint8_t)(v_c8 & 15u)))) << 4u);
52059 v_c8 = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 24u))];
52060 v_uni4_ok &= v_c8;
52061 v_uni4_value |= (((uint32_t)(((uint8_t)(v_c8 & 15u)))) << 0u);
52063 if ((v_uni4_ok != 0u) && (56320u <= v_uni4_value) && (v_uni4_value <= 57343u)) {
52064 v_uni4_value -= 56320u;
52065 iop_a_src += 12u;
52066 *iop_a_dst++ = wuffs_base__make_token(
52067 (((uint64_t)((6291456u | v_uni4_high_surrogate | v_uni4_value))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
52068 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
52069 (((uint64_t)(12u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
52070 goto label__string_loop_outer__continue;
52073 if (self->private_impl.f_quirks[20u]) {
52074 if (((uint64_t)(io2_a_src - iop_a_src)) < 6u) {
52075 status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o);
52076 goto exit;
52078 iop_a_src += 6u;
52079 *iop_a_dst++ = wuffs_base__make_token(
52080 (((uint64_t)(6356989u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
52081 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
52082 (((uint64_t)(6u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
52083 goto label__string_loop_outer__continue;
52085 } else if ((v_c8 == 85u) && self->private_impl.f_quirks[2u]) {
52086 if (((uint64_t)(io2_a_src - iop_a_src)) < 10u) {
52087 if (a_src && a_src->meta.closed) {
52088 status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
52089 goto exit;
52091 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
52092 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9);
52093 goto label__string_loop_outer__continue;
52095 v_uni8_string = wuffs_base__peek_u64le__no_bounds_check(iop_a_src + 2u);
52096 v_uni8_value = 0u;
52097 v_uni8_ok = 128u;
52098 v_c8 = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 0u))];
52099 v_uni8_ok &= v_c8;
52100 v_uni8_value |= (((uint32_t)(((uint8_t)(v_c8 & 15u)))) << 28u);
52101 v_c8 = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 8u))];
52102 v_uni8_ok &= v_c8;
52103 v_uni8_value |= (((uint32_t)(((uint8_t)(v_c8 & 15u)))) << 24u);
52104 v_c8 = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 16u))];
52105 v_uni8_ok &= v_c8;
52106 v_uni8_value |= (((uint32_t)(((uint8_t)(v_c8 & 15u)))) << 20u);
52107 v_c8 = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 24u))];
52108 v_uni8_ok &= v_c8;
52109 v_uni8_value |= (((uint32_t)(((uint8_t)(v_c8 & 15u)))) << 16u);
52110 v_c8 = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 32u))];
52111 v_uni8_ok &= v_c8;
52112 v_uni8_value |= (((uint32_t)(((uint8_t)(v_c8 & 15u)))) << 12u);
52113 v_c8 = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 40u))];
52114 v_uni8_ok &= v_c8;
52115 v_uni8_value |= (((uint32_t)(((uint8_t)(v_c8 & 15u)))) << 8u);
52116 v_c8 = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 48u))];
52117 v_uni8_ok &= v_c8;
52118 v_uni8_value |= (((uint32_t)(((uint8_t)(v_c8 & 15u)))) << 4u);
52119 v_c8 = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 56u))];
52120 v_uni8_ok &= v_c8;
52121 v_uni8_value |= (((uint32_t)(((uint8_t)(v_c8 & 15u)))) << 0u);
52122 if (v_uni8_ok == 0u) {
52123 } else if ((v_uni8_value < 55296u) || ((57343u < v_uni8_value) && (v_uni8_value <= 1114111u))) {
52124 iop_a_src += 10u;
52125 *iop_a_dst++ = wuffs_base__make_token(
52126 (((uint64_t)((6291456u | (v_uni8_value & 2097151u)))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
52127 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
52128 (((uint64_t)(10u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
52129 goto label__string_loop_outer__continue;
52130 } else if (self->private_impl.f_quirks[20u]) {
52131 iop_a_src += 10u;
52132 *iop_a_dst++ = wuffs_base__make_token(
52133 (((uint64_t)(6356989u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
52134 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
52135 (((uint64_t)(10u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
52136 goto label__string_loop_outer__continue;
52138 } else if ((v_c8 == 120u) && self->private_impl.f_quirks[9u]) {
52139 if (((uint64_t)(io2_a_src - iop_a_src)) < 4u) {
52140 if (a_src && a_src->meta.closed) {
52141 status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
52142 goto exit;
52144 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
52145 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10);
52146 goto label__string_loop_outer__continue;
52148 v_backslash_x_string = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
52149 v_backslash_x_ok = 128u;
52150 v_c8 = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_backslash_x_string >> 16u))];
52151 v_backslash_x_ok &= v_c8;
52152 v_backslash_x_value = ((uint8_t)(((uint8_t)(((uint8_t)(v_c8 & 15u)) << 4u))));
52153 v_c8 = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_backslash_x_string >> 24u))];
52154 v_backslash_x_ok &= v_c8;
52155 v_backslash_x_value = ((uint8_t)(((uint8_t)(v_backslash_x_value | ((uint8_t)(v_c8 & 15u))))));
52156 if ((v_backslash_x_ok == 0u) || ((v_backslash_x_string & 65535u) != 30812u)) {
52157 status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
52158 goto exit;
52160 iop_a_src += 4u;
52161 *iop_a_dst++ = wuffs_base__make_token(
52162 (((uint64_t)((6291456u | ((uint32_t)(v_backslash_x_value))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
52163 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
52164 (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
52165 goto label__string_loop_outer__continue;
52167 status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
52168 goto exit;
52169 } else if (v_char == 3u) {
52170 if (((uint64_t)(io2_a_src - iop_a_src)) < 2u) {
52171 if (v_string_length > 0u) {
52172 *iop_a_dst++ = wuffs_base__make_token(
52173 (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
52174 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
52175 (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
52176 v_string_length = 0u;
52177 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
52178 goto label__string_loop_outer__continue;
52181 if (a_src && a_src->meta.closed) {
52182 if (self->private_impl.f_quirks[20u]) {
52183 *iop_a_dst++ = wuffs_base__make_token(
52184 (((uint64_t)(6356989u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
52185 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
52186 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
52187 iop_a_src += 1u;
52188 goto label__string_loop_outer__continue;
52190 status = wuffs_base__make_status(wuffs_json__error__bad_utf_8);
52191 goto exit;
52193 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
52194 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(11);
52195 goto label__string_loop_outer__continue;
52197 v_multi_byte_utf8 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
52198 if ((v_multi_byte_utf8 & 49152u) == 32768u) {
52199 v_multi_byte_utf8 = ((1984u & ((uint32_t)(v_multi_byte_utf8 << 6u))) | (63u & (v_multi_byte_utf8 >> 8u)));
52200 iop_a_src += 2u;
52201 if (v_string_length >= 65528u) {
52202 *iop_a_dst++ = wuffs_base__make_token(
52203 (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
52204 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
52205 (((uint64_t)((v_string_length + 2u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
52206 v_string_length = 0u;
52207 goto label__string_loop_outer__continue;
52209 v_string_length += 2u;
52210 continue;
52212 } else if (v_char == 4u) {
52213 if (((uint64_t)(io2_a_src - iop_a_src)) < 3u) {
52214 if (v_string_length > 0u) {
52215 *iop_a_dst++ = wuffs_base__make_token(
52216 (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
52217 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
52218 (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
52219 v_string_length = 0u;
52220 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
52221 goto label__string_loop_outer__continue;
52224 if (a_src && a_src->meta.closed) {
52225 if (self->private_impl.f_quirks[20u]) {
52226 *iop_a_dst++ = wuffs_base__make_token(
52227 (((uint64_t)(6356989u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
52228 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
52229 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
52230 iop_a_src += 1u;
52231 goto label__string_loop_outer__continue;
52233 status = wuffs_base__make_status(wuffs_json__error__bad_utf_8);
52234 goto exit;
52236 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
52237 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(12);
52238 goto label__string_loop_outer__continue;
52240 v_multi_byte_utf8 = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src)));
52241 if ((v_multi_byte_utf8 & 12632064u) == 8421376u) {
52242 v_multi_byte_utf8 = ((61440u & ((uint32_t)(v_multi_byte_utf8 << 12u))) | (4032u & (v_multi_byte_utf8 >> 2u)) | (63u & (v_multi_byte_utf8 >> 16u)));
52243 if ((2047u < v_multi_byte_utf8) && ((v_multi_byte_utf8 < 55296u) || (57343u < v_multi_byte_utf8))) {
52244 iop_a_src += 3u;
52245 if (v_string_length >= 65528u) {
52246 *iop_a_dst++ = wuffs_base__make_token(
52247 (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
52248 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
52249 (((uint64_t)((v_string_length + 3u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
52250 v_string_length = 0u;
52251 goto label__string_loop_outer__continue;
52253 v_string_length += 3u;
52254 continue;
52257 } else if (v_char == 5u) {
52258 if (((uint64_t)(io2_a_src - iop_a_src)) < 4u) {
52259 if (v_string_length > 0u) {
52260 *iop_a_dst++ = wuffs_base__make_token(
52261 (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
52262 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
52263 (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
52264 v_string_length = 0u;
52265 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
52266 goto label__string_loop_outer__continue;
52269 if (a_src && a_src->meta.closed) {
52270 if (self->private_impl.f_quirks[20u]) {
52271 *iop_a_dst++ = wuffs_base__make_token(
52272 (((uint64_t)(6356989u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
52273 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
52274 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
52275 iop_a_src += 1u;
52276 goto label__string_loop_outer__continue;
52278 status = wuffs_base__make_status(wuffs_json__error__bad_utf_8);
52279 goto exit;
52281 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
52282 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(13);
52283 goto label__string_loop_outer__continue;
52285 v_multi_byte_utf8 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
52286 if ((v_multi_byte_utf8 & 3233857536u) == 2155905024u) {
52287 v_multi_byte_utf8 = ((1835008u & ((uint32_t)(v_multi_byte_utf8 << 18u))) |
52288 (258048u & ((uint32_t)(v_multi_byte_utf8 << 4u))) |
52289 (4032u & (v_multi_byte_utf8 >> 10u)) |
52290 (63u & (v_multi_byte_utf8 >> 24u)));
52291 if ((65535u < v_multi_byte_utf8) && (v_multi_byte_utf8 <= 1114111u)) {
52292 iop_a_src += 4u;
52293 if (v_string_length >= 65528u) {
52294 *iop_a_dst++ = wuffs_base__make_token(
52295 (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
52296 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
52297 (((uint64_t)((v_string_length + 4u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
52298 v_string_length = 0u;
52299 goto label__string_loop_outer__continue;
52301 v_string_length += 4u;
52302 continue;
52306 if (v_string_length > 0u) {
52307 *iop_a_dst++ = wuffs_base__make_token(
52308 (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
52309 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
52310 (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
52311 v_string_length = 0u;
52312 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
52313 goto label__string_loop_outer__continue;
52316 if (((uint8_t)(v_char & 128u)) != 0u) {
52317 if (self->private_impl.f_quirks[0u]) {
52318 *iop_a_dst++ = wuffs_base__make_token(
52319 (((uint64_t)((6291456u | ((uint32_t)(((uint8_t)(v_char & 127u))))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
52320 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
52321 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
52322 iop_a_src += 1u;
52323 goto label__string_loop_outer__continue;
52325 if (v_char == 138u) {
52326 status = wuffs_base__make_status(wuffs_json__error__bad_new_line_in_a_string);
52327 goto exit;
52329 status = wuffs_base__make_status(wuffs_json__error__bad_c0_control_code);
52330 goto exit;
52332 if (self->private_impl.f_quirks[20u]) {
52333 *iop_a_dst++ = wuffs_base__make_token(
52334 (((uint64_t)(6356989u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
52335 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
52336 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
52337 iop_a_src += 1u;
52338 goto label__string_loop_outer__continue;
52340 status = wuffs_base__make_status(wuffs_json__error__bad_utf_8);
52341 goto exit;
52344 label__string_loop_outer__break:;
52345 while (true) {
52346 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
52347 if (a_src && a_src->meta.closed) {
52348 status = wuffs_base__make_status(wuffs_json__error__bad_input);
52349 goto exit;
52351 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
52352 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(14);
52353 continue;
52355 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
52356 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
52357 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(15);
52358 continue;
52360 iop_a_src += 1u;
52361 *iop_a_dst++ = wuffs_base__make_token(
52362 (((uint64_t)(4194579u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
52363 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
52364 break;
52366 if (0u == (v_expect & (((uint32_t)(1u)) << 4u))) {
52367 v_expect = 4104u;
52368 goto label__outer__continue;
52370 break;
52371 } else if (v_class == 2u) {
52372 iop_a_src += 1u;
52373 *iop_a_dst++ = wuffs_base__make_token(
52374 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
52375 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
52376 if (0u == (v_expect & (((uint32_t)(1u)) << 8u))) {
52377 if (self->private_impl.f_quirks[13u]) {
52378 v_expect = 4162u;
52379 } else {
52380 v_expect = 4098u;
52382 } else {
52383 if (self->private_impl.f_quirks[13u]) {
52384 v_expect = 8114u;
52385 } else {
52386 v_expect = 7858u;
52389 goto label__outer__continue;
52390 } else if (v_class == 3u) {
52391 iop_a_src += 1u;
52392 *iop_a_dst++ = wuffs_base__make_token(
52393 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
52394 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
52395 v_expect = 7858u;
52396 goto label__outer__continue;
52397 } else if (v_class == 4u) {
52398 while (true) {
52399 if (a_src) {
52400 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
52402 v_number_length = wuffs_json__decoder__decode_number(self, a_src);
52403 if (a_src) {
52404 iop_a_src = a_src->data.ptr + a_src->meta.ri;
52406 v_number_status = (v_number_length >> 8u);
52407 v_vminor = 10486787u;
52408 if ((v_number_length & 128u) != 0u) {
52409 v_vminor = 10486785u;
52411 v_number_length = (v_number_length & 127u);
52412 if (v_number_status == 0u) {
52413 *iop_a_dst++ = wuffs_base__make_token(
52414 (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
52415 (((uint64_t)(v_number_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
52416 break;
52418 while (v_number_length > 0u) {
52419 v_number_length -= 1u;
52420 if (iop_a_src > io1_a_src) {
52421 iop_a_src--;
52422 } else {
52423 status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o);
52424 goto exit;
52427 if (v_number_status == 1u) {
52428 if (self->private_impl.f_quirks[14u]) {
52429 if (a_dst) {
52430 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
52432 if (a_src) {
52433 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
52435 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
52436 status = wuffs_json__decoder__decode_inf_nan(self, a_dst, a_src);
52437 if (a_dst) {
52438 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
52440 if (a_src) {
52441 iop_a_src = a_src->data.ptr + a_src->meta.ri;
52443 if (status.repr) {
52444 goto suspend;
52446 break;
52448 status = wuffs_base__make_status(wuffs_json__error__bad_input);
52449 goto exit;
52450 } else if (v_number_status == 2u) {
52451 status = wuffs_base__make_status(wuffs_json__error__unsupported_number_length);
52452 goto exit;
52453 } else {
52454 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
52455 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(17);
52456 while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
52457 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
52458 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(18);
52462 break;
52463 } else if (v_class == 5u) {
52464 v_vminor = 2113553u;
52465 if (v_depth == 0u) {
52466 } else if (0u != (v_expect_after_value & (((uint32_t)(1u)) << 6u))) {
52467 v_vminor = 2113601u;
52468 } else {
52469 v_vminor = 2113569u;
52471 if (v_depth >= 1024u) {
52472 status = wuffs_base__make_status(wuffs_json__error__unsupported_recursion_depth);
52473 goto exit;
52475 v_stack_byte = (v_depth / 32u);
52476 v_stack_bit = (v_depth & 31u);
52477 self->private_data.f_stack[v_stack_byte] |= (((uint32_t)(1u)) << v_stack_bit);
52478 v_depth += 1u;
52479 iop_a_src += 1u;
52480 *iop_a_dst++ = wuffs_base__make_token(
52481 (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
52482 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
52483 v_expect = 4162u;
52484 v_expect_after_value = 4164u;
52485 goto label__outer__continue;
52486 } else if (v_class == 6u) {
52487 iop_a_src += 1u;
52488 if (v_depth <= 1u) {
52489 *iop_a_dst++ = wuffs_base__make_token(
52490 (((uint64_t)(2101314u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
52491 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
52492 goto label__outer__break;
52494 v_depth -= 1u;
52495 v_stack_byte = ((v_depth - 1u) / 32u);
52496 v_stack_bit = ((v_depth - 1u) & 31u);
52497 if (0u == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1u)) << v_stack_bit))) {
52498 *iop_a_dst++ = wuffs_base__make_token(
52499 (((uint64_t)(2105410u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
52500 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
52501 v_expect = 4356u;
52502 v_expect_after_value = 4356u;
52503 } else {
52504 *iop_a_dst++ = wuffs_base__make_token(
52505 (((uint64_t)(2113602u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
52506 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
52507 v_expect = 4164u;
52508 v_expect_after_value = 4164u;
52510 goto label__outer__continue;
52511 } else if (v_class == 7u) {
52512 v_vminor = 2105361u;
52513 if (v_depth == 0u) {
52514 } else if (0u != (v_expect_after_value & (((uint32_t)(1u)) << 6u))) {
52515 v_vminor = 2105409u;
52516 } else {
52517 v_vminor = 2105377u;
52519 if (v_depth >= 1024u) {
52520 status = wuffs_base__make_status(wuffs_json__error__unsupported_recursion_depth);
52521 goto exit;
52523 v_stack_byte = (v_depth / 32u);
52524 v_stack_bit = (v_depth & 31u);
52525 self->private_data.f_stack[v_stack_byte] &= (4294967295u ^ (((uint32_t)(1u)) << v_stack_bit));
52526 v_depth += 1u;
52527 iop_a_src += 1u;
52528 *iop_a_dst++ = wuffs_base__make_token(
52529 (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
52530 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
52531 v_expect = 8114u;
52532 v_expect_after_value = 4356u;
52533 goto label__outer__continue;
52534 } else if (v_class == 8u) {
52535 iop_a_src += 1u;
52536 if (v_depth <= 1u) {
52537 *iop_a_dst++ = wuffs_base__make_token(
52538 (((uint64_t)(2101282u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
52539 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
52540 goto label__outer__break;
52542 v_depth -= 1u;
52543 v_stack_byte = ((v_depth - 1u) / 32u);
52544 v_stack_bit = ((v_depth - 1u) & 31u);
52545 if (0u == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1u)) << v_stack_bit))) {
52546 *iop_a_dst++ = wuffs_base__make_token(
52547 (((uint64_t)(2105378u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
52548 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
52549 v_expect = 4356u;
52550 v_expect_after_value = 4356u;
52551 } else {
52552 *iop_a_dst++ = wuffs_base__make_token(
52553 (((uint64_t)(2113570u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
52554 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
52555 v_expect = 4164u;
52556 v_expect_after_value = 4164u;
52558 goto label__outer__continue;
52559 } else if (v_class == 9u) {
52560 v_match = wuffs_private_impl__io_reader__match7(iop_a_src, io2_a_src, a_src, 111546413966853u);
52561 if (v_match == 0u) {
52562 *iop_a_dst++ = wuffs_base__make_token(
52563 (((uint64_t)(8388612u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
52564 (((uint64_t)(5u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
52565 if (((uint64_t)(io2_a_src - iop_a_src)) < 5u) {
52566 status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o);
52567 goto exit;
52569 iop_a_src += 5u;
52570 break;
52571 } else if (v_match == 1u) {
52572 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
52573 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(19);
52574 goto label__outer__continue;
52576 } else if (v_class == 10u) {
52577 v_match = wuffs_private_impl__io_reader__match7(iop_a_src, io2_a_src, a_src, 435762131972u);
52578 if (v_match == 0u) {
52579 *iop_a_dst++ = wuffs_base__make_token(
52580 (((uint64_t)(8388616u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
52581 (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
52582 if (((uint64_t)(io2_a_src - iop_a_src)) < 4u) {
52583 status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o);
52584 goto exit;
52586 iop_a_src += 4u;
52587 break;
52588 } else if (v_match == 1u) {
52589 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
52590 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(20);
52591 goto label__outer__continue;
52593 } else if (v_class == 11u) {
52594 v_match = wuffs_private_impl__io_reader__match7(iop_a_src, io2_a_src, a_src, 465676103172u);
52595 if (v_match == 0u) {
52596 *iop_a_dst++ = wuffs_base__make_token(
52597 (((uint64_t)(8388610u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
52598 (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
52599 if (((uint64_t)(io2_a_src - iop_a_src)) < 4u) {
52600 status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o);
52601 goto exit;
52603 iop_a_src += 4u;
52604 break;
52605 } else if (v_match == 1u) {
52606 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
52607 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(21);
52608 goto label__outer__continue;
52610 if (self->private_impl.f_quirks[14u]) {
52611 if (a_dst) {
52612 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
52614 if (a_src) {
52615 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
52617 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(22);
52618 status = wuffs_json__decoder__decode_inf_nan(self, a_dst, a_src);
52619 if (a_dst) {
52620 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
52622 if (a_src) {
52623 iop_a_src = a_src->data.ptr + a_src->meta.ri;
52625 if (status.repr) {
52626 goto suspend;
52628 break;
52630 } else if (v_class == 12u) {
52631 if (self->private_impl.f_quirks[11u] || self->private_impl.f_quirks[12u]) {
52632 if (a_dst) {
52633 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
52635 if (a_src) {
52636 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
52638 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(23);
52639 status = wuffs_json__decoder__decode_comment(self, a_dst, a_src);
52640 if (a_dst) {
52641 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
52643 if (a_src) {
52644 iop_a_src = a_src->data.ptr + a_src->meta.ri;
52646 if (status.repr) {
52647 goto suspend;
52649 if (self->private_impl.f_comment_type > 0u) {
52650 goto label__outer__continue;
52654 status = wuffs_base__make_status(wuffs_json__error__bad_input);
52655 goto exit;
52657 if (v_depth == 0u) {
52658 break;
52660 v_expect = v_expect_after_value;
52662 label__outer__break:;
52663 if (self->private_impl.f_quirks[17u] || self->private_impl.f_quirks[18u]) {
52664 if (a_dst) {
52665 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
52667 if (a_src) {
52668 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
52670 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(24);
52671 status = wuffs_json__decoder__decode_trailer(self, a_dst, a_src);
52672 if (a_dst) {
52673 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
52675 if (a_src) {
52676 iop_a_src = a_src->data.ptr + a_src->meta.ri;
52678 if (status.repr) {
52679 goto suspend;
52682 self->private_impl.f_end_of_data = true;
52685 self->private_impl.p_decode_tokens = 0;
52686 goto exit;
52689 goto suspend;
52690 suspend:
52691 self->private_impl.p_decode_tokens = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
52692 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
52693 self->private_data.s_decode_tokens.v_depth = v_depth;
52694 self->private_data.s_decode_tokens.v_expect = v_expect;
52695 self->private_data.s_decode_tokens.v_expect_after_value = v_expect_after_value;
52697 goto exit;
52698 exit:
52699 if (a_dst && a_dst->data.ptr) {
52700 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
52702 if (a_src && a_src->data.ptr) {
52703 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
52706 if (wuffs_base__status__is_error(&status)) {
52707 self->private_impl.magic = WUFFS_BASE__DISABLED;
52709 return status;
52712 // -------- func json.decoder.decode_number
52714 WUFFS_BASE__GENERATED_C_CODE
52715 static uint32_t
52716 wuffs_json__decoder__decode_number(
52717 wuffs_json__decoder* self,
52718 wuffs_base__io_buffer* a_src) {
52719 uint8_t v_c8 = 0;
52720 uint32_t v_n = 0;
52721 uint32_t v_floating_point = 0;
52723 const uint8_t* iop_a_src = NULL;
52724 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
52725 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
52726 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
52727 if (a_src && a_src->data.ptr) {
52728 io0_a_src = a_src->data.ptr;
52729 io1_a_src = io0_a_src + a_src->meta.ri;
52730 iop_a_src = io1_a_src;
52731 io2_a_src = io0_a_src + a_src->meta.wi;
52734 do {
52735 v_n = 0u;
52736 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
52737 if ( ! (a_src && a_src->meta.closed)) {
52738 v_n |= 768u;
52740 break;
52742 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
52743 if (v_c8 != 45u) {
52744 } else {
52745 v_n += 1u;
52746 iop_a_src += 1u;
52747 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
52748 if ( ! (a_src && a_src->meta.closed)) {
52749 v_n |= 768u;
52751 v_n |= 256u;
52752 break;
52754 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
52756 if (v_c8 == 48u) {
52757 v_n += 1u;
52758 iop_a_src += 1u;
52759 } else {
52760 if (a_src) {
52761 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
52763 v_n = wuffs_json__decoder__decode_digits(self, a_src, v_n);
52764 if (a_src) {
52765 iop_a_src = a_src->data.ptr + a_src->meta.ri;
52767 if (v_n > 99u) {
52768 break;
52771 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
52772 if ( ! (a_src && a_src->meta.closed)) {
52773 v_n |= 768u;
52775 break;
52777 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
52778 if (v_c8 != 46u) {
52779 } else {
52780 if (v_n >= 99u) {
52781 v_n |= 512u;
52782 break;
52784 v_n += 1u;
52785 iop_a_src += 1u;
52786 v_floating_point = 128u;
52787 if (a_src) {
52788 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
52790 v_n = wuffs_json__decoder__decode_digits(self, a_src, v_n);
52791 if (a_src) {
52792 iop_a_src = a_src->data.ptr + a_src->meta.ri;
52794 if (v_n > 99u) {
52795 break;
52797 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
52798 if ( ! (a_src && a_src->meta.closed)) {
52799 v_n |= 768u;
52801 break;
52803 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
52805 if ((v_c8 != 69u) && (v_c8 != 101u)) {
52806 break;
52808 if (v_n >= 99u) {
52809 v_n |= 512u;
52810 break;
52812 v_n += 1u;
52813 iop_a_src += 1u;
52814 v_floating_point = 128u;
52815 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
52816 if ( ! (a_src && a_src->meta.closed)) {
52817 v_n |= 768u;
52819 v_n |= 256u;
52820 break;
52822 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
52823 if ((v_c8 != 43u) && (v_c8 != 45u)) {
52824 } else {
52825 if (v_n >= 99u) {
52826 v_n |= 512u;
52827 break;
52829 v_n += 1u;
52830 iop_a_src += 1u;
52832 if (a_src) {
52833 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
52835 v_n = wuffs_json__decoder__decode_digits(self, a_src, v_n);
52836 if (a_src) {
52837 iop_a_src = a_src->data.ptr + a_src->meta.ri;
52839 } while (0);
52840 if (a_src && a_src->data.ptr) {
52841 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
52843 return (v_n | v_floating_point);
52846 // -------- func json.decoder.decode_digits
52848 WUFFS_BASE__GENERATED_C_CODE
52849 static uint32_t
52850 wuffs_json__decoder__decode_digits(
52851 wuffs_json__decoder* self,
52852 wuffs_base__io_buffer* a_src,
52853 uint32_t a_n) {
52854 uint8_t v_c8 = 0;
52855 uint32_t v_n = 0;
52857 const uint8_t* iop_a_src = NULL;
52858 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
52859 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
52860 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
52861 if (a_src && a_src->data.ptr) {
52862 io0_a_src = a_src->data.ptr;
52863 io1_a_src = io0_a_src + a_src->meta.ri;
52864 iop_a_src = io1_a_src;
52865 io2_a_src = io0_a_src + a_src->meta.wi;
52868 v_n = a_n;
52869 while (true) {
52870 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
52871 if ( ! (a_src && a_src->meta.closed)) {
52872 v_n |= 768u;
52874 break;
52876 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
52877 if (0u == WUFFS_JSON__LUT_DECIMAL_DIGITS[v_c8]) {
52878 break;
52880 if (v_n >= 99u) {
52881 v_n |= 512u;
52882 break;
52884 v_n += 1u;
52885 iop_a_src += 1u;
52887 if (v_n == a_n) {
52888 v_n |= 256u;
52890 if (a_src && a_src->data.ptr) {
52891 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
52893 return v_n;
52896 // -------- func json.decoder.decode_leading
52898 WUFFS_BASE__GENERATED_C_CODE
52899 static wuffs_base__status
52900 wuffs_json__decoder__decode_leading(
52901 wuffs_json__decoder* self,
52902 wuffs_base__token_buffer* a_dst,
52903 wuffs_base__io_buffer* a_src) {
52904 wuffs_base__status status = wuffs_base__make_status(NULL);
52906 uint8_t v_c8 = 0;
52907 uint32_t v_u = 0;
52909 wuffs_base__token* iop_a_dst = NULL;
52910 wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
52911 wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
52912 wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
52913 if (a_dst && a_dst->data.ptr) {
52914 io0_a_dst = a_dst->data.ptr;
52915 io1_a_dst = io0_a_dst + a_dst->meta.wi;
52916 iop_a_dst = io1_a_dst;
52917 io2_a_dst = io0_a_dst + a_dst->data.len;
52918 if (a_dst->meta.closed) {
52919 io2_a_dst = iop_a_dst;
52922 const uint8_t* iop_a_src = NULL;
52923 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
52924 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
52925 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
52926 if (a_src && a_src->data.ptr) {
52927 io0_a_src = a_src->data.ptr;
52928 io1_a_src = io0_a_src + a_src->meta.ri;
52929 iop_a_src = io1_a_src;
52930 io2_a_src = io0_a_src + a_src->meta.wi;
52933 uint32_t coro_susp_point = self->private_impl.p_decode_leading;
52934 switch (coro_susp_point) {
52935 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
52937 self->private_impl.f_allow_leading_ars = self->private_impl.f_quirks[15u];
52938 self->private_impl.f_allow_leading_ubom = self->private_impl.f_quirks[16u];
52939 while (self->private_impl.f_allow_leading_ars || self->private_impl.f_allow_leading_ubom) {
52940 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
52941 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
52942 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
52943 continue;
52945 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
52946 if (a_src && a_src->meta.closed) {
52947 break;
52949 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
52950 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
52951 continue;
52953 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
52954 if ((v_c8 == 30u) && self->private_impl.f_allow_leading_ars) {
52955 self->private_impl.f_allow_leading_ars = false;
52956 iop_a_src += 1u;
52957 *iop_a_dst++ = wuffs_base__make_token(
52958 (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
52959 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
52960 continue;
52961 } else if ((v_c8 == 239u) && self->private_impl.f_allow_leading_ubom) {
52962 if (((uint64_t)(io2_a_src - iop_a_src)) < 3u) {
52963 if (a_src && a_src->meta.closed) {
52964 break;
52966 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
52967 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
52968 continue;
52970 v_u = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src)));
52971 if (v_u == 12565487u) {
52972 self->private_impl.f_allow_leading_ubom = false;
52973 iop_a_src += 3u;
52974 *iop_a_dst++ = wuffs_base__make_token(
52975 (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
52976 (((uint64_t)(3u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
52977 continue;
52980 break;
52984 self->private_impl.p_decode_leading = 0;
52985 goto exit;
52988 goto suspend;
52989 suspend:
52990 self->private_impl.p_decode_leading = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
52992 goto exit;
52993 exit:
52994 if (a_dst && a_dst->data.ptr) {
52995 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
52997 if (a_src && a_src->data.ptr) {
52998 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
53001 return status;
53004 // -------- func json.decoder.decode_comment
53006 WUFFS_BASE__GENERATED_C_CODE
53007 static wuffs_base__status
53008 wuffs_json__decoder__decode_comment(
53009 wuffs_json__decoder* self,
53010 wuffs_base__token_buffer* a_dst,
53011 wuffs_base__io_buffer* a_src) {
53012 wuffs_base__status status = wuffs_base__make_status(NULL);
53014 uint8_t v_c8 = 0;
53015 uint16_t v_c16 = 0;
53016 uint32_t v_length = 0;
53018 wuffs_base__token* iop_a_dst = NULL;
53019 wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
53020 wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
53021 wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
53022 if (a_dst && a_dst->data.ptr) {
53023 io0_a_dst = a_dst->data.ptr;
53024 io1_a_dst = io0_a_dst + a_dst->meta.wi;
53025 iop_a_dst = io1_a_dst;
53026 io2_a_dst = io0_a_dst + a_dst->data.len;
53027 if (a_dst->meta.closed) {
53028 io2_a_dst = iop_a_dst;
53031 const uint8_t* iop_a_src = NULL;
53032 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
53033 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
53034 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
53035 if (a_src && a_src->data.ptr) {
53036 io0_a_src = a_src->data.ptr;
53037 io1_a_src = io0_a_src + a_src->meta.ri;
53038 iop_a_src = io1_a_src;
53039 io2_a_src = io0_a_src + a_src->meta.wi;
53042 uint32_t coro_susp_point = self->private_impl.p_decode_comment;
53043 switch (coro_susp_point) {
53044 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
53046 self->private_impl.f_comment_type = 0u;
53047 while ((((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) || (((uint64_t)(io2_a_src - iop_a_src)) <= 1u)) {
53048 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
53049 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
53050 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
53051 continue;
53053 if (a_src && a_src->meta.closed) {
53054 status = wuffs_base__make_status(NULL);
53055 goto ok;
53057 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
53058 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
53060 v_c16 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src);
53061 if ((v_c16 == 10799u) && self->private_impl.f_quirks[11u]) {
53062 iop_a_src += 2u;
53063 v_length = 2u;
53064 while (true) {
53065 if (((uint64_t)(io2_a_src - iop_a_src)) <= 1u) {
53066 if (v_length > 0u) {
53067 *iop_a_dst++ = wuffs_base__make_token(
53068 (((uint64_t)(2u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
53069 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
53070 (((uint64_t)(v_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
53072 if (a_src && a_src->meta.closed) {
53073 status = wuffs_base__make_status(wuffs_json__error__bad_input);
53074 goto exit;
53076 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
53077 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
53078 while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
53079 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
53080 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
53082 v_length = 0u;
53083 continue;
53085 v_c16 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src);
53086 if (v_c16 == 12074u) {
53087 iop_a_src += 2u;
53088 *iop_a_dst++ = wuffs_base__make_token(
53089 (((uint64_t)(2u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
53090 (((uint64_t)((v_length + 2u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
53091 self->private_impl.f_comment_type = 1u;
53092 status = wuffs_base__make_status(NULL);
53093 goto ok;
53095 iop_a_src += 1u;
53096 if (v_length >= 65533u) {
53097 *iop_a_dst++ = wuffs_base__make_token(
53098 (((uint64_t)(2u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
53099 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
53100 (((uint64_t)((v_length + 1u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
53101 while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
53102 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
53103 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
53105 v_length = 0u;
53106 continue;
53108 v_length += 1u;
53110 } else if ((v_c16 == 12079u) && self->private_impl.f_quirks[12u]) {
53111 iop_a_src += 2u;
53112 v_length = 2u;
53113 while (true) {
53114 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
53115 if (a_src && a_src->meta.closed) {
53116 *iop_a_dst++ = wuffs_base__make_token(
53117 (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
53118 (((uint64_t)(v_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
53119 self->private_impl.f_comment_type = 2u;
53120 status = wuffs_base__make_status(NULL);
53121 goto ok;
53122 } else if (v_length > 0u) {
53123 *iop_a_dst++ = wuffs_base__make_token(
53124 (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
53125 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
53126 (((uint64_t)(v_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
53128 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
53129 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
53130 while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
53131 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
53132 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7);
53134 v_length = 0u;
53135 continue;
53137 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
53138 if (v_c8 == 10u) {
53139 *iop_a_dst++ = wuffs_base__make_token(
53140 (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
53141 (((uint64_t)(v_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
53142 self->private_impl.f_comment_type = 2u;
53143 status = wuffs_base__make_status(NULL);
53144 goto ok;
53146 iop_a_src += 1u;
53147 if (v_length >= 65533u) {
53148 *iop_a_dst++ = wuffs_base__make_token(
53149 (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
53150 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
53151 (((uint64_t)((v_length + 1u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
53152 while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
53153 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
53154 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8);
53156 v_length = 0u;
53157 continue;
53159 v_length += 1u;
53164 self->private_impl.p_decode_comment = 0;
53165 goto exit;
53168 goto suspend;
53169 suspend:
53170 self->private_impl.p_decode_comment = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
53172 goto exit;
53173 exit:
53174 if (a_dst && a_dst->data.ptr) {
53175 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
53177 if (a_src && a_src->data.ptr) {
53178 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
53181 return status;
53184 // -------- func json.decoder.decode_inf_nan
53186 WUFFS_BASE__GENERATED_C_CODE
53187 static wuffs_base__status
53188 wuffs_json__decoder__decode_inf_nan(
53189 wuffs_json__decoder* self,
53190 wuffs_base__token_buffer* a_dst,
53191 wuffs_base__io_buffer* a_src) {
53192 wuffs_base__status status = wuffs_base__make_status(NULL);
53194 uint32_t v_c32 = 0;
53195 uint32_t v_neg = 0;
53197 wuffs_base__token* iop_a_dst = NULL;
53198 wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
53199 wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
53200 wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
53201 if (a_dst && a_dst->data.ptr) {
53202 io0_a_dst = a_dst->data.ptr;
53203 io1_a_dst = io0_a_dst + a_dst->meta.wi;
53204 iop_a_dst = io1_a_dst;
53205 io2_a_dst = io0_a_dst + a_dst->data.len;
53206 if (a_dst->meta.closed) {
53207 io2_a_dst = iop_a_dst;
53210 const uint8_t* iop_a_src = NULL;
53211 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
53212 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
53213 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
53214 if (a_src && a_src->data.ptr) {
53215 io0_a_src = a_src->data.ptr;
53216 io1_a_src = io0_a_src + a_src->meta.ri;
53217 iop_a_src = io1_a_src;
53218 io2_a_src = io0_a_src + a_src->meta.wi;
53221 uint32_t coro_susp_point = self->private_impl.p_decode_inf_nan;
53222 switch (coro_susp_point) {
53223 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
53225 while (true) {
53226 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
53227 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
53228 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
53229 continue;
53231 if (((uint64_t)(io2_a_src - iop_a_src)) <= 2u) {
53232 if (a_src && a_src->meta.closed) {
53233 status = wuffs_base__make_status(wuffs_json__error__bad_input);
53234 goto exit;
53236 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
53237 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
53238 continue;
53240 v_c32 = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src)));
53241 if ((v_c32 | 2105376u) == 6712937u) {
53242 if (((uint64_t)(io2_a_src - iop_a_src)) > 7u) {
53243 if ((wuffs_base__peek_u64le__no_bounds_check(iop_a_src) | 2314885530818453536u) == 8751735898823356009u) {
53244 *iop_a_dst++ = wuffs_base__make_token(
53245 (((uint64_t)(10485792u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
53246 (((uint64_t)(8u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
53247 iop_a_src += 8u;
53248 status = wuffs_base__make_status(NULL);
53249 goto ok;
53251 } else if ( ! (a_src && a_src->meta.closed)) {
53252 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
53253 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
53254 continue;
53256 *iop_a_dst++ = wuffs_base__make_token(
53257 (((uint64_t)(10485792u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
53258 (((uint64_t)(3u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
53259 iop_a_src += 3u;
53260 status = wuffs_base__make_status(NULL);
53261 goto ok;
53262 } else if ((v_c32 | 2105376u) == 7233902u) {
53263 *iop_a_dst++ = wuffs_base__make_token(
53264 (((uint64_t)(10485888u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
53265 (((uint64_t)(3u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
53266 iop_a_src += 3u;
53267 status = wuffs_base__make_status(NULL);
53268 goto ok;
53269 } else if ((v_c32 & 255u) == 43u) {
53270 v_neg = 0u;
53271 } else if ((v_c32 & 255u) == 45u) {
53272 v_neg = 1u;
53273 } else {
53274 status = wuffs_base__make_status(wuffs_json__error__bad_input);
53275 goto exit;
53277 if (((uint64_t)(io2_a_src - iop_a_src)) <= 3u) {
53278 if (a_src && a_src->meta.closed) {
53279 status = wuffs_base__make_status(wuffs_json__error__bad_input);
53280 goto exit;
53282 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
53283 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
53284 continue;
53286 v_c32 = (wuffs_base__peek_u32le__no_bounds_check(iop_a_src) >> 8u);
53287 if ((v_c32 | 2105376u) == 6712937u) {
53288 if (((uint64_t)(io2_a_src - iop_a_src)) > 8u) {
53289 if ((wuffs_base__peek_u64le__no_bounds_check(iop_a_src + 1u) | 2314885530818453536u) == 8751735898823356009u) {
53290 *iop_a_dst++ = wuffs_base__make_token(
53291 (((uint64_t)((10485760u | (((uint32_t)(32u)) >> v_neg)))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
53292 (((uint64_t)(9u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
53293 iop_a_src += 9u;
53294 status = wuffs_base__make_status(NULL);
53295 goto ok;
53297 } else if ( ! (a_src && a_src->meta.closed)) {
53298 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
53299 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
53300 continue;
53302 *iop_a_dst++ = wuffs_base__make_token(
53303 (((uint64_t)((10485760u | (((uint32_t)(32u)) >> v_neg)))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
53304 (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
53305 iop_a_src += 4u;
53306 status = wuffs_base__make_status(NULL);
53307 goto ok;
53308 } else if ((v_c32 | 2105376u) == 7233902u) {
53309 *iop_a_dst++ = wuffs_base__make_token(
53310 (((uint64_t)((10485760u | (((uint32_t)(128u)) >> v_neg)))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
53311 (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
53312 iop_a_src += 4u;
53313 status = wuffs_base__make_status(NULL);
53314 goto ok;
53316 status = wuffs_base__make_status(wuffs_json__error__bad_input);
53317 goto exit;
53321 self->private_impl.p_decode_inf_nan = 0;
53322 goto exit;
53325 goto suspend;
53326 suspend:
53327 self->private_impl.p_decode_inf_nan = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
53329 goto exit;
53330 exit:
53331 if (a_dst && a_dst->data.ptr) {
53332 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
53334 if (a_src && a_src->data.ptr) {
53335 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
53338 return status;
53341 // -------- func json.decoder.decode_trailer
53343 WUFFS_BASE__GENERATED_C_CODE
53344 static wuffs_base__status
53345 wuffs_json__decoder__decode_trailer(
53346 wuffs_json__decoder* self,
53347 wuffs_base__token_buffer* a_dst,
53348 wuffs_base__io_buffer* a_src) {
53349 wuffs_base__status status = wuffs_base__make_status(NULL);
53351 uint8_t v_c8 = 0;
53352 uint32_t v_whitespace_length = 0;
53354 wuffs_base__token* iop_a_dst = NULL;
53355 wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
53356 wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
53357 wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
53358 if (a_dst && a_dst->data.ptr) {
53359 io0_a_dst = a_dst->data.ptr;
53360 io1_a_dst = io0_a_dst + a_dst->meta.wi;
53361 iop_a_dst = io1_a_dst;
53362 io2_a_dst = io0_a_dst + a_dst->data.len;
53363 if (a_dst->meta.closed) {
53364 io2_a_dst = iop_a_dst;
53367 const uint8_t* iop_a_src = NULL;
53368 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
53369 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
53370 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
53371 if (a_src && a_src->data.ptr) {
53372 io0_a_src = a_src->data.ptr;
53373 io1_a_src = io0_a_src + a_src->meta.ri;
53374 iop_a_src = io1_a_src;
53375 io2_a_src = io0_a_src + a_src->meta.wi;
53378 uint32_t coro_susp_point = self->private_impl.p_decode_trailer;
53379 switch (coro_susp_point) {
53380 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
53382 if (self->private_impl.f_quirks[18u]) {
53383 self->private_impl.f_trailer_stop = 10u;
53384 } else {
53385 self->private_impl.f_trailer_stop = 0u;
53387 label__outer__continue:;
53388 while (true) {
53389 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
53390 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
53391 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
53392 continue;
53394 v_whitespace_length = 0u;
53395 while (true) {
53396 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
53397 if (v_whitespace_length > 0u) {
53398 *iop_a_dst++ = wuffs_base__make_token(
53399 (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
53400 (((uint64_t)(v_whitespace_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
53402 if (a_src && a_src->meta.closed) {
53403 goto label__outer__break;
53405 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
53406 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
53407 goto label__outer__continue;
53409 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
53410 if (WUFFS_JSON__LUT_CLASSES[v_c8] != 0u) {
53411 if (v_whitespace_length > 0u) {
53412 *iop_a_dst++ = wuffs_base__make_token(
53413 (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
53414 (((uint64_t)(v_whitespace_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
53416 if (self->private_impl.f_trailer_stop > 0u) {
53417 status = wuffs_base__make_status(wuffs_json__error__bad_input);
53418 goto exit;
53420 if (a_dst) {
53421 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
53423 if (a_src) {
53424 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
53426 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
53427 status = wuffs_json__decoder__decode_comment(self, a_dst, a_src);
53428 if (a_dst) {
53429 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
53431 if (a_src) {
53432 iop_a_src = a_src->data.ptr + a_src->meta.ri;
53434 if (status.repr) {
53435 goto suspend;
53437 if (self->private_impl.f_comment_type > 0u) {
53438 goto label__outer__continue;
53440 status = wuffs_base__make_status(NULL);
53441 goto ok;
53443 iop_a_src += 1u;
53444 if ((v_whitespace_length >= 65534u) || (v_c8 == self->private_impl.f_trailer_stop)) {
53445 *iop_a_dst++ = wuffs_base__make_token(
53446 (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
53447 (((uint64_t)((v_whitespace_length + 1u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
53448 if (v_c8 == self->private_impl.f_trailer_stop) {
53449 status = wuffs_base__make_status(NULL);
53450 goto ok;
53452 goto label__outer__continue;
53454 v_whitespace_length += 1u;
53457 label__outer__break:;
53460 self->private_impl.p_decode_trailer = 0;
53461 goto exit;
53464 goto suspend;
53465 suspend:
53466 self->private_impl.p_decode_trailer = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
53468 goto exit;
53469 exit:
53470 if (a_dst && a_dst->data.ptr) {
53471 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
53473 if (a_src && a_src->data.ptr) {
53474 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
53477 return status;
53480 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JSON)
53482 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZMA)
53484 // ---------------- Status Codes Implementations
53486 const char wuffs_lzma__error__bad_lzma2_header[] = "#lzma: bad LZMA2 header";
53487 const char wuffs_lzma__error__bad_bitstream_trailer[] = "#lzma: bad bitstream trailer";
53488 const char wuffs_lzma__error__bad_code[] = "#lzma: bad code";
53489 const char wuffs_lzma__error__bad_decoded_length[] = "#lzma: bad decoded length";
53490 const char wuffs_lzma__error__bad_distance[] = "#lzma: bad distance";
53491 const char wuffs_lzma__error__bad_header[] = "#lzma: bad header";
53492 const char wuffs_lzma__error__truncated_input[] = "#lzma: truncated input";
53493 const char wuffs_lzma__error__unsupported_decoded_length[] = "#lzma: unsupported decoded length";
53494 const char wuffs_lzma__error__unsupported_properties[] = "#lzma: unsupported properties";
53495 const char wuffs_lzma__error__internal_error_inconsistent_i_o[] = "#lzma: internal error: inconsistent I/O";
53496 const char wuffs_lzma__error__internal_error_inconsistent_dictionary_state[] = "#lzma: internal error: inconsistent dictionary state";
53498 // ---------------- Private Consts
53500 static const uint8_t
53501 WUFFS_LZMA__STATE_TRANSITION_LITERAL[12] WUFFS_BASE__POTENTIALLY_UNUSED = {
53502 0u, 0u, 0u, 0u, 1u, 2u, 3u, 4u,
53503 5u, 6u, 4u, 5u,
53506 static const uint8_t
53507 WUFFS_LZMA__STATE_TRANSITION_MATCH[12] WUFFS_BASE__POTENTIALLY_UNUSED = {
53508 7u, 7u, 7u, 7u, 7u, 7u, 7u, 10u,
53509 10u, 10u, 10u, 10u,
53512 static const uint8_t
53513 WUFFS_LZMA__STATE_TRANSITION_LONGREP[12] WUFFS_BASE__POTENTIALLY_UNUSED = {
53514 8u, 8u, 8u, 8u, 8u, 8u, 8u, 11u,
53515 11u, 11u, 11u, 11u,
53518 static const uint8_t
53519 WUFFS_LZMA__STATE_TRANSITION_SHORTREP[12] WUFFS_BASE__POTENTIALLY_UNUSED = {
53520 9u, 9u, 9u, 9u, 9u, 9u, 9u, 11u,
53521 11u, 11u, 11u, 11u,
53524 static const uint8_t
53525 WUFFS_LZMA__CLAMP_NO_MORE_THAN_3[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
53526 0u, 1u, 2u, 3u, 3u, 3u, 3u, 3u,
53529 #define WUFFS_LZMA__QUIRKS_BASE 1348001792u
53531 // ---------------- Private Initializer Prototypes
53533 // ---------------- Private Function Prototypes
53535 WUFFS_BASE__GENERATED_C_CODE
53536 static wuffs_base__status
53537 wuffs_lzma__decoder__decode_bitstream_fast(
53538 wuffs_lzma__decoder* self,
53539 wuffs_base__io_buffer* a_dst,
53540 wuffs_base__io_buffer* a_src,
53541 wuffs_base__slice_u8 a_workbuf);
53543 WUFFS_BASE__GENERATED_C_CODE
53544 static wuffs_base__status
53545 wuffs_lzma__decoder__decode_bitstream_slow(
53546 wuffs_lzma__decoder* self,
53547 wuffs_base__io_buffer* a_dst,
53548 wuffs_base__io_buffer* a_src,
53549 wuffs_base__slice_u8 a_workbuf);
53551 WUFFS_BASE__GENERATED_C_CODE
53552 static wuffs_base__status
53553 wuffs_lzma__decoder__add_history(
53554 wuffs_lzma__decoder* self,
53555 wuffs_base__slice_u8 a_hist,
53556 wuffs_base__slice_u8 a_workbuf);
53558 WUFFS_BASE__GENERATED_C_CODE
53559 static wuffs_base__status
53560 wuffs_lzma__decoder__do_transform_io(
53561 wuffs_lzma__decoder* self,
53562 wuffs_base__io_buffer* a_dst,
53563 wuffs_base__io_buffer* a_src,
53564 wuffs_base__slice_u8 a_workbuf);
53566 WUFFS_BASE__GENERATED_C_CODE
53567 static wuffs_base__status
53568 wuffs_lzma__decoder__decode_bitstream(
53569 wuffs_lzma__decoder* self,
53570 wuffs_base__io_buffer* a_dst,
53571 wuffs_base__io_buffer* a_src,
53572 wuffs_base__slice_u8 a_workbuf);
53574 WUFFS_BASE__GENERATED_C_CODE
53575 static wuffs_base__status
53576 wuffs_lzma__decoder__update_stashed_bytes(
53577 wuffs_lzma__decoder* self,
53578 wuffs_base__io_buffer* a_dst,
53579 wuffs_base__slice_u8 a_workbuf);
53581 WUFFS_BASE__GENERATED_C_CODE
53582 static wuffs_base__status
53583 wuffs_lzma__decoder__decode_optional_end_of_stream(
53584 wuffs_lzma__decoder* self,
53585 wuffs_base__io_buffer* a_src,
53586 wuffs_base__slice_u8 a_workbuf);
53588 WUFFS_BASE__GENERATED_C_CODE
53589 static wuffs_base__empty_struct
53590 wuffs_lzma__decoder__initialize_dict(
53591 wuffs_lzma__decoder* self);
53593 WUFFS_BASE__GENERATED_C_CODE
53594 static wuffs_base__empty_struct
53595 wuffs_lzma__decoder__initialize_probs(
53596 wuffs_lzma__decoder* self);
53598 // ---------------- VTables
53600 const wuffs_base__io_transformer__func_ptrs
53601 wuffs_lzma__decoder__func_ptrs_for__wuffs_base__io_transformer = {
53602 (wuffs_base__optional_u63(*)(const void*))(&wuffs_lzma__decoder__dst_history_retain_length),
53603 (uint64_t(*)(const void*,
53604 uint32_t))(&wuffs_lzma__decoder__get_quirk),
53605 (wuffs_base__status(*)(void*,
53606 uint32_t,
53607 uint64_t))(&wuffs_lzma__decoder__set_quirk),
53608 (wuffs_base__status(*)(void*,
53609 wuffs_base__io_buffer*,
53610 wuffs_base__io_buffer*,
53611 wuffs_base__slice_u8))(&wuffs_lzma__decoder__transform_io),
53612 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_lzma__decoder__workbuf_len),
53615 // ---------------- Initializer Implementations
53617 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
53618 wuffs_lzma__decoder__initialize(
53619 wuffs_lzma__decoder* self,
53620 size_t sizeof_star_self,
53621 uint64_t wuffs_version,
53622 uint32_t options){
53623 if (!self) {
53624 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
53626 if (sizeof(*self) != sizeof_star_self) {
53627 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
53629 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
53630 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
53631 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
53634 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
53635 // The whole point of this if-check is to detect an uninitialized *self.
53636 // We disable the warning on GCC. Clang-5.0 does not have this warning.
53637 #if !defined(__clang__) && defined(__GNUC__)
53638 #pragma GCC diagnostic push
53639 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
53640 #endif
53641 if (self->private_impl.magic != 0) {
53642 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
53644 #if !defined(__clang__) && defined(__GNUC__)
53645 #pragma GCC diagnostic pop
53646 #endif
53647 } else {
53648 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
53649 memset(self, 0, sizeof(*self));
53650 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
53651 } else {
53652 memset(&(self->private_impl), 0, sizeof(self->private_impl));
53656 self->private_impl.magic = WUFFS_BASE__MAGIC;
53657 self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name =
53658 wuffs_base__io_transformer__vtable_name;
53659 self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers =
53660 (const void*)(&wuffs_lzma__decoder__func_ptrs_for__wuffs_base__io_transformer);
53661 return wuffs_base__make_status(NULL);
53664 wuffs_lzma__decoder*
53665 wuffs_lzma__decoder__alloc(void) {
53666 wuffs_lzma__decoder* x =
53667 (wuffs_lzma__decoder*)(calloc(1, sizeof(wuffs_lzma__decoder)));
53668 if (!x) {
53669 return NULL;
53671 if (wuffs_lzma__decoder__initialize(
53672 x, sizeof(wuffs_lzma__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
53673 free(x);
53674 return NULL;
53676 return x;
53679 size_t
53680 sizeof__wuffs_lzma__decoder(void) {
53681 return sizeof(wuffs_lzma__decoder);
53684 // ---------------- Function Implementations
53686 // -------- func lzma.decoder.decode_bitstream_fast
53688 WUFFS_BASE__GENERATED_C_CODE
53689 static wuffs_base__status
53690 wuffs_lzma__decoder__decode_bitstream_fast(
53691 wuffs_lzma__decoder* self,
53692 wuffs_base__io_buffer* a_dst,
53693 wuffs_base__io_buffer* a_src,
53694 wuffs_base__slice_u8 a_workbuf) {
53695 wuffs_base__status status = wuffs_base__make_status(NULL);
53697 uint8_t v_c8 = 0;
53698 uint32_t v_bits = 0;
53699 uint32_t v_range = 0;
53700 uint32_t v_state = 0;
53701 uint32_t v_rep0 = 0;
53702 uint32_t v_rep1 = 0;
53703 uint32_t v_rep2 = 0;
53704 uint32_t v_rep3 = 0;
53705 uint32_t v_reptmp = 0;
53706 uint32_t v_rep = 0;
53707 uint64_t v_pos = 0;
53708 uint64_t v_pos_end = 0;
53709 uint32_t v_lc = 0;
53710 uint64_t v_lp_mask = 0;
53711 uint64_t v_pb_mask = 0;
53712 uint32_t v_prob = 0;
53713 uint32_t v_threshold = 0;
53714 uint32_t v_tree_node = 0;
53715 uint8_t v_prev_byte = 0;
53716 uint32_t v_match_byte = 0;
53717 uint32_t v_match_cusp = 0;
53718 uint32_t v_len_state = 0;
53719 uint32_t v_slot = 0;
53720 uint32_t v_len = 0;
53721 uint32_t v_lanl_offset = 0;
53722 uint32_t v_lanl_old_offset = 0;
53723 uint32_t v_lanl_index = 0;
53724 uint32_t v_num_extra_bits = 0;
53725 uint32_t v_dist_extra_bits = 0;
53726 uint32_t v_high_bit_was_on = 0;
53727 uint32_t v_i = 0;
53728 uint32_t v_index_ao00 = 0;
53729 uint32_t v_index_ao41 = 0;
53730 uint32_t v_index_lit = 0;
53731 uint32_t v_index_len = 0;
53732 uint32_t v_index_small_dist_base = 0;
53733 uint32_t v_index_small_dist_extra = 0;
53734 uint32_t v_index_small_dist = 0;
53735 uint32_t v_index_large_dist = 0;
53736 uint32_t v_dist = 0;
53737 uint32_t v_adj_dist = 0;
53738 uint64_t v_wb_index = 0;
53740 uint8_t* iop_a_dst = NULL;
53741 uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
53742 uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
53743 uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
53744 if (a_dst && a_dst->data.ptr) {
53745 io0_a_dst = a_dst->data.ptr;
53746 io1_a_dst = io0_a_dst + a_dst->meta.wi;
53747 iop_a_dst = io1_a_dst;
53748 io2_a_dst = io0_a_dst + a_dst->data.len;
53749 if (a_dst->meta.closed) {
53750 io2_a_dst = iop_a_dst;
53753 const uint8_t* iop_a_src = NULL;
53754 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
53755 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
53756 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
53757 if (a_src && a_src->data.ptr) {
53758 io0_a_src = a_src->data.ptr;
53759 io1_a_src = io0_a_src + a_src->meta.ri;
53760 iop_a_src = io1_a_src;
53761 io2_a_src = io0_a_src + a_src->meta.wi;
53764 v_prev_byte = self->private_impl.f_stashed_bytes[0u];
53765 v_match_byte = ((uint32_t)(self->private_impl.f_stashed_bytes[1u]));
53766 v_bits = self->private_impl.f_stashed_bits;
53767 v_range = self->private_impl.f_stashed_range;
53768 v_state = self->private_impl.f_stashed_state;
53769 v_rep0 = self->private_impl.f_stashed_rep0;
53770 v_rep1 = self->private_impl.f_stashed_rep1;
53771 v_rep2 = self->private_impl.f_stashed_rep2;
53772 v_rep3 = self->private_impl.f_stashed_rep3;
53773 v_pos = self->private_impl.f_stashed_pos;
53774 v_pos_end = self->private_impl.f_stashed_pos_end;
53775 v_lc = self->private_impl.f_lc;
53776 v_lp_mask = ((((uint64_t)(1u)) << self->private_impl.f_lp) - 1u);
53777 v_pb_mask = ((((uint64_t)(1u)) << self->private_impl.f_pb) - 1u);
53778 while ((((uint64_t)(io2_a_dst - iop_a_dst)) >= 282u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 48u)) {
53779 if (v_pos >= v_pos_end) {
53780 self->private_impl.f_end_of_chunk = true;
53781 break;
53783 v_index_ao00 = ((v_state << 4u) | ((uint32_t)((v_pos & v_pb_mask))));
53784 v_prob = ((uint32_t)(self->private_data.f_probs_ao00[v_index_ao00]));
53785 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
53786 if (v_bits < v_threshold) {
53787 v_range = v_threshold;
53788 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
53789 self->private_data.f_probs_ao00[v_index_ao00] = ((uint16_t)(v_prob));
53790 if ((v_range >> 24u) == 0u) {
53791 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
53792 iop_a_src += 1u;
53793 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
53794 v_range <<= 8u;
53796 v_index_lit = (15u & ((((uint32_t)((v_pos & v_lp_mask))) << v_lc) | (((uint32_t)(v_prev_byte)) >> (8u - v_lc))));
53797 v_lanl_offset = 0u;
53798 if (v_state >= 7u) {
53799 v_lanl_offset = 256u;
53801 v_tree_node = 1u;
53802 while (v_tree_node < 256u) {
53803 v_match_byte <<= 1u;
53804 v_lanl_old_offset = v_lanl_offset;
53805 v_lanl_offset &= v_match_byte;
53806 v_lanl_index = (v_lanl_offset + v_lanl_old_offset + v_tree_node);
53807 v_prob = ((uint32_t)(self->private_data.f_probs_lit[v_index_lit][v_lanl_index]));
53808 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
53809 if (v_bits < v_threshold) {
53810 v_lanl_offset = ((v_lanl_offset ^ v_lanl_old_offset) & 256u);
53811 v_range = v_threshold;
53812 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
53813 self->private_data.f_probs_lit[v_index_lit][v_lanl_index] = ((uint16_t)(v_prob));
53814 v_tree_node = (v_tree_node << 1u);
53815 } else {
53816 v_bits -= v_threshold;
53817 v_range -= v_threshold;
53818 v_prob -= (v_prob >> 5u);
53819 self->private_data.f_probs_lit[v_index_lit][v_lanl_index] = ((uint16_t)(v_prob));
53820 v_tree_node = ((v_tree_node << 1u) | 1u);
53822 if ((v_range >> 24u) == 0u) {
53823 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
53824 status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_i_o);
53825 goto exit;
53827 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
53828 iop_a_src += 1u;
53829 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
53830 v_range <<= 8u;
53833 v_prev_byte = ((uint8_t)(v_tree_node));
53834 (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, v_prev_byte), iop_a_dst += 1);
53835 v_pos += 1u;
53836 v_state = ((uint32_t)(WUFFS_LZMA__STATE_TRANSITION_LITERAL[v_state]));
53837 continue;
53839 v_bits -= v_threshold;
53840 v_range -= v_threshold;
53841 v_prob -= (v_prob >> 5u);
53842 self->private_data.f_probs_ao00[v_index_ao00] = ((uint16_t)(v_prob));
53843 if ((v_range >> 24u) == 0u) {
53844 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
53845 iop_a_src += 1u;
53846 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
53847 v_range <<= 8u;
53848 } else {
53850 do {
53851 v_prob = ((uint32_t)(self->private_data.f_probs_ao20[v_state]));
53852 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
53853 if (v_bits < v_threshold) {
53854 v_range = v_threshold;
53855 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
53856 self->private_data.f_probs_ao20[v_state] = ((uint16_t)(v_prob));
53857 if ((v_range >> 24u) == 0u) {
53858 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
53859 iop_a_src += 1u;
53860 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
53861 v_range <<= 8u;
53862 } else {
53864 do {
53865 v_prob = ((uint32_t)(self->private_data.f_probs_match_len_low[0u][0u]));
53866 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
53867 if (v_bits < v_threshold) {
53868 v_range = v_threshold;
53869 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
53870 self->private_data.f_probs_match_len_low[0u][0u] = ((uint16_t)(v_prob));
53871 if ((v_range >> 24u) == 0u) {
53872 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
53873 iop_a_src += 1u;
53874 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
53875 v_range <<= 8u;
53877 v_index_len = ((uint32_t)((v_pos & v_pb_mask)));
53878 v_tree_node = 1u;
53879 while (v_tree_node < 8u) {
53880 v_prob = ((uint32_t)(self->private_data.f_probs_match_len_low[v_index_len][v_tree_node]));
53881 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
53882 if (v_bits < v_threshold) {
53883 v_range = v_threshold;
53884 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
53885 self->private_data.f_probs_match_len_low[v_index_len][v_tree_node] = ((uint16_t)(v_prob));
53886 v_tree_node = (v_tree_node << 1u);
53887 } else {
53888 v_bits -= v_threshold;
53889 v_range -= v_threshold;
53890 v_prob -= (v_prob >> 5u);
53891 self->private_data.f_probs_match_len_low[v_index_len][v_tree_node] = ((uint16_t)(v_prob));
53892 v_tree_node = ((v_tree_node << 1u) | 1u);
53894 if ((v_range >> 24u) == 0u) {
53895 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
53896 status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_i_o);
53897 goto exit;
53899 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
53900 iop_a_src += 1u;
53901 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
53902 v_range <<= 8u;
53905 v_len_state = ((uint32_t)(WUFFS_LZMA__CLAMP_NO_MORE_THAN_3[(v_tree_node & 7u)]));
53906 v_len = ((v_tree_node & 7u) + 2u);
53907 break;
53909 v_bits -= v_threshold;
53910 v_range -= v_threshold;
53911 v_prob -= (v_prob >> 5u);
53912 self->private_data.f_probs_match_len_low[0u][0u] = ((uint16_t)(v_prob));
53913 if ((v_range >> 24u) == 0u) {
53914 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
53915 status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_i_o);
53916 goto exit;
53918 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
53919 iop_a_src += 1u;
53920 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
53921 v_range <<= 8u;
53923 v_prob = ((uint32_t)(self->private_data.f_probs_match_len_mid[0u][0u]));
53924 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
53925 if (v_bits < v_threshold) {
53926 v_range = v_threshold;
53927 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
53928 self->private_data.f_probs_match_len_mid[0u][0u] = ((uint16_t)(v_prob));
53929 if ((v_range >> 24u) == 0u) {
53930 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
53931 status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_i_o);
53932 goto exit;
53934 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
53935 iop_a_src += 1u;
53936 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
53937 v_range <<= 8u;
53939 v_index_len = ((uint32_t)((v_pos & v_pb_mask)));
53940 v_tree_node = 1u;
53941 while (v_tree_node < 8u) {
53942 v_prob = ((uint32_t)(self->private_data.f_probs_match_len_mid[v_index_len][v_tree_node]));
53943 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
53944 if (v_bits < v_threshold) {
53945 v_range = v_threshold;
53946 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
53947 self->private_data.f_probs_match_len_mid[v_index_len][v_tree_node] = ((uint16_t)(v_prob));
53948 v_tree_node = (v_tree_node << 1u);
53949 } else {
53950 v_bits -= v_threshold;
53951 v_range -= v_threshold;
53952 v_prob -= (v_prob >> 5u);
53953 self->private_data.f_probs_match_len_mid[v_index_len][v_tree_node] = ((uint16_t)(v_prob));
53954 v_tree_node = ((v_tree_node << 1u) | 1u);
53956 if ((v_range >> 24u) == 0u) {
53957 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
53958 status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_i_o);
53959 goto exit;
53961 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
53962 iop_a_src += 1u;
53963 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
53964 v_range <<= 8u;
53967 v_len = ((v_tree_node & 7u) + 10u);
53968 v_len_state = 3u;
53969 break;
53971 v_bits -= v_threshold;
53972 v_range -= v_threshold;
53973 v_prob -= (v_prob >> 5u);
53974 self->private_data.f_probs_match_len_mid[0u][0u] = ((uint16_t)(v_prob));
53975 if ((v_range >> 24u) == 0u) {
53976 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
53977 status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_i_o);
53978 goto exit;
53980 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
53981 iop_a_src += 1u;
53982 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
53983 v_range <<= 8u;
53985 v_tree_node = 1u;
53986 while (v_tree_node < 256u) {
53987 v_prob = ((uint32_t)(self->private_data.f_probs_match_len_high[0u][v_tree_node]));
53988 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
53989 if (v_bits < v_threshold) {
53990 v_range = v_threshold;
53991 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
53992 self->private_data.f_probs_match_len_high[0u][v_tree_node] = ((uint16_t)(v_prob));
53993 v_tree_node = (v_tree_node << 1u);
53994 } else {
53995 v_bits -= v_threshold;
53996 v_range -= v_threshold;
53997 v_prob -= (v_prob >> 5u);
53998 self->private_data.f_probs_match_len_high[0u][v_tree_node] = ((uint16_t)(v_prob));
53999 v_tree_node = ((v_tree_node << 1u) | 1u);
54001 if ((v_range >> 24u) == 0u) {
54002 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
54003 status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_i_o);
54004 goto exit;
54006 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
54007 iop_a_src += 1u;
54008 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
54009 v_range <<= 8u;
54012 v_len = ((v_tree_node & 255u) + 18u);
54013 v_len_state = 3u;
54014 } while (0);
54015 v_slot = 1u;
54016 while (v_slot < 64u) {
54017 v_prob = ((uint32_t)(self->private_data.f_probs_slot[v_len_state][v_slot]));
54018 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
54019 if (v_bits < v_threshold) {
54020 v_range = v_threshold;
54021 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
54022 self->private_data.f_probs_slot[v_len_state][v_slot] = ((uint16_t)(v_prob));
54023 v_slot = (v_slot << 1u);
54024 } else {
54025 v_bits -= v_threshold;
54026 v_range -= v_threshold;
54027 v_prob -= (v_prob >> 5u);
54028 self->private_data.f_probs_slot[v_len_state][v_slot] = ((uint16_t)(v_prob));
54029 v_slot = ((v_slot << 1u) | 1u);
54031 if ((v_range >> 24u) == 0u) {
54032 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
54033 status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_i_o);
54034 goto exit;
54036 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
54037 iop_a_src += 1u;
54038 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
54039 v_range <<= 8u;
54042 v_slot &= 63u;
54043 v_rep = v_slot;
54044 if (v_slot < 4u) {
54045 } else if (v_slot < 14u) {
54046 v_num_extra_bits = ((v_slot >> 1u) - 1u);
54047 v_rep = ((2u | (v_slot & 1u)) << v_num_extra_bits);
54048 v_index_small_dist_base = ((uint32_t)(v_rep - v_slot));
54049 v_index_small_dist_extra = 1u;
54050 v_dist_extra_bits = 0u;
54051 v_i = 0u;
54052 while (v_i < v_num_extra_bits) {
54053 v_index_small_dist = (((uint32_t)(v_index_small_dist_base + v_index_small_dist_extra)) & 127u);
54054 v_prob = ((uint32_t)(self->private_data.f_probs_small_dist[v_index_small_dist]));
54055 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
54056 if (v_bits < v_threshold) {
54057 v_range = v_threshold;
54058 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
54059 self->private_data.f_probs_small_dist[v_index_small_dist] = ((uint16_t)(v_prob));
54060 v_index_small_dist_extra = ((uint32_t)(v_index_small_dist_extra << 1u));
54061 v_i += 1u;
54062 } else {
54063 v_bits -= v_threshold;
54064 v_range -= v_threshold;
54065 v_prob -= (v_prob >> 5u);
54066 self->private_data.f_probs_small_dist[v_index_small_dist] = ((uint16_t)(v_prob));
54067 v_index_small_dist_extra = (((uint32_t)(v_index_small_dist_extra << 1u)) | 1u);
54068 v_dist_extra_bits |= (((uint32_t)(1u)) << v_i);
54069 v_i += 1u;
54071 if ((v_range >> 24u) == 0u) {
54072 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
54073 status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_i_o);
54074 goto exit;
54076 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
54077 iop_a_src += 1u;
54078 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
54079 v_range <<= 8u;
54082 v_rep += v_dist_extra_bits;
54083 } else {
54084 v_num_extra_bits = ((v_slot >> 1u) - 1u);
54085 v_rep = ((2u | (v_slot & 1u)) << v_num_extra_bits);
54086 v_dist_extra_bits = 0u;
54087 while (true) {
54088 v_range >>= 1u;
54089 v_bits -= v_range;
54090 v_high_bit_was_on = ((uint32_t)(0u - (v_bits >> 31u)));
54091 v_bits += (v_range & v_high_bit_was_on);
54092 v_dist_extra_bits = (((uint32_t)(v_dist_extra_bits << 1u)) | (((uint32_t)(v_high_bit_was_on + 1u)) & 1u));
54093 if ((v_range >> 24u) == 0u) {
54094 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
54095 status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_i_o);
54096 goto exit;
54098 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
54099 iop_a_src += 1u;
54100 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
54101 v_range <<= 8u;
54103 v_num_extra_bits -= 1u;
54104 if (v_num_extra_bits <= 4u) {
54105 break;
54108 v_dist_extra_bits <<= 4u;
54109 v_index_large_dist = 1u;
54110 while (true) {
54111 v_prob = ((uint32_t)(self->private_data.f_probs_large_dist[v_index_large_dist]));
54112 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
54113 if (v_bits < v_threshold) {
54114 v_range = v_threshold;
54115 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
54116 self->private_data.f_probs_large_dist[v_index_large_dist] = ((uint16_t)(v_prob));
54117 v_index_large_dist = (15u & ((uint32_t)(v_index_large_dist << 1u)));
54118 } else {
54119 v_bits -= v_threshold;
54120 v_range -= v_threshold;
54121 v_prob -= (v_prob >> 5u);
54122 self->private_data.f_probs_large_dist[v_index_large_dist] = ((uint16_t)(v_prob));
54123 v_index_large_dist = (15u & (((uint32_t)(v_index_large_dist << 1u)) | 1u));
54124 v_dist_extra_bits |= (((uint32_t)(1u)) << (4u - v_num_extra_bits));
54126 if ((v_range >> 24u) == 0u) {
54127 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
54128 status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_i_o);
54129 goto exit;
54131 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
54132 iop_a_src += 1u;
54133 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
54134 v_range <<= 8u;
54136 v_num_extra_bits -= 1u;
54137 if (v_num_extra_bits <= 0u) {
54138 break;
54141 v_rep += v_dist_extra_bits;
54143 if (v_rep >= 4294967295u) {
54144 self->private_impl.f_end_of_chunk = true;
54145 goto label__outer__break;
54147 v_rep3 = v_rep2;
54148 v_rep2 = v_rep1;
54149 v_rep1 = v_rep0;
54150 v_rep0 = v_rep;
54151 v_state = ((uint32_t)(WUFFS_LZMA__STATE_TRANSITION_MATCH[v_state]));
54152 break;
54154 v_bits -= v_threshold;
54155 v_range -= v_threshold;
54156 v_prob -= (v_prob >> 5u);
54157 self->private_data.f_probs_ao20[v_state] = ((uint16_t)(v_prob));
54158 if ((v_range >> 24u) == 0u) {
54159 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
54160 iop_a_src += 1u;
54161 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
54162 v_range <<= 8u;
54163 } else {
54165 v_prob = ((uint32_t)(self->private_data.f_probs_ao40[v_state]));
54166 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
54167 if (v_bits < v_threshold) {
54168 v_range = v_threshold;
54169 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
54170 self->private_data.f_probs_ao40[v_state] = ((uint16_t)(v_prob));
54171 if ((v_range >> 24u) == 0u) {
54172 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
54173 iop_a_src += 1u;
54174 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
54175 v_range <<= 8u;
54176 } else {
54178 v_index_ao41 = ((v_state << 4u) | ((uint32_t)((v_pos & v_pb_mask))));
54179 v_prob = ((uint32_t)(self->private_data.f_probs_ao41[v_index_ao41]));
54180 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
54181 if (v_bits < v_threshold) {
54182 v_range = v_threshold;
54183 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
54184 self->private_data.f_probs_ao41[v_index_ao41] = ((uint16_t)(v_prob));
54185 if ((v_range >> 24u) == 0u) {
54186 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
54187 iop_a_src += 1u;
54188 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
54189 v_range <<= 8u;
54191 v_len = 1u;
54192 v_state = ((uint32_t)(WUFFS_LZMA__STATE_TRANSITION_SHORTREP[v_state]));
54193 break;
54195 v_bits -= v_threshold;
54196 v_range -= v_threshold;
54197 v_prob -= (v_prob >> 5u);
54198 self->private_data.f_probs_ao41[v_index_ao41] = ((uint16_t)(v_prob));
54199 if ((v_range >> 24u) == 0u) {
54200 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
54201 iop_a_src += 1u;
54202 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
54203 v_range <<= 8u;
54205 } else {
54206 v_bits -= v_threshold;
54207 v_range -= v_threshold;
54208 v_prob -= (v_prob >> 5u);
54209 self->private_data.f_probs_ao40[v_state] = ((uint16_t)(v_prob));
54210 if ((v_range >> 24u) == 0u) {
54211 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
54212 iop_a_src += 1u;
54213 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
54214 v_range <<= 8u;
54215 } else {
54217 v_prob = ((uint32_t)(self->private_data.f_probs_ao60[v_state]));
54218 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
54219 if (v_bits < v_threshold) {
54220 v_range = v_threshold;
54221 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
54222 self->private_data.f_probs_ao60[v_state] = ((uint16_t)(v_prob));
54223 if ((v_range >> 24u) == 0u) {
54224 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
54225 iop_a_src += 1u;
54226 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
54227 v_range <<= 8u;
54229 v_reptmp = v_rep1;
54230 v_rep1 = v_rep0;
54231 v_rep0 = v_reptmp;
54232 } else {
54233 v_bits -= v_threshold;
54234 v_range -= v_threshold;
54235 v_prob -= (v_prob >> 5u);
54236 self->private_data.f_probs_ao60[v_state] = ((uint16_t)(v_prob));
54237 if ((v_range >> 24u) == 0u) {
54238 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
54239 iop_a_src += 1u;
54240 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
54241 v_range <<= 8u;
54242 } else {
54244 v_prob = ((uint32_t)(self->private_data.f_probs_ao63[v_state]));
54245 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
54246 if (v_bits < v_threshold) {
54247 v_range = v_threshold;
54248 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
54249 self->private_data.f_probs_ao63[v_state] = ((uint16_t)(v_prob));
54250 if ((v_range >> 24u) == 0u) {
54251 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
54252 iop_a_src += 1u;
54253 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
54254 v_range <<= 8u;
54256 v_reptmp = v_rep2;
54257 v_rep2 = v_rep1;
54258 v_rep1 = v_rep0;
54259 v_rep0 = v_reptmp;
54260 } else {
54261 v_bits -= v_threshold;
54262 v_range -= v_threshold;
54263 v_prob -= (v_prob >> 5u);
54264 self->private_data.f_probs_ao63[v_state] = ((uint16_t)(v_prob));
54265 if ((v_range >> 24u) == 0u) {
54266 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
54267 iop_a_src += 1u;
54268 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
54269 v_range <<= 8u;
54271 v_reptmp = v_rep3;
54272 v_rep3 = v_rep2;
54273 v_rep2 = v_rep1;
54274 v_rep1 = v_rep0;
54275 v_rep0 = v_reptmp;
54279 do {
54280 v_prob = ((uint32_t)(self->private_data.f_probs_longrep_len_low[0u][0u]));
54281 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
54282 if (v_bits < v_threshold) {
54283 v_range = v_threshold;
54284 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
54285 self->private_data.f_probs_longrep_len_low[0u][0u] = ((uint16_t)(v_prob));
54286 if ((v_range >> 24u) == 0u) {
54287 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
54288 status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_i_o);
54289 goto exit;
54291 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
54292 iop_a_src += 1u;
54293 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
54294 v_range <<= 8u;
54296 v_index_len = ((uint32_t)((v_pos & v_pb_mask)));
54297 v_tree_node = 1u;
54298 while (v_tree_node < 8u) {
54299 v_prob = ((uint32_t)(self->private_data.f_probs_longrep_len_low[v_index_len][v_tree_node]));
54300 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
54301 if (v_bits < v_threshold) {
54302 v_range = v_threshold;
54303 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
54304 self->private_data.f_probs_longrep_len_low[v_index_len][v_tree_node] = ((uint16_t)(v_prob));
54305 v_tree_node = (v_tree_node << 1u);
54306 } else {
54307 v_bits -= v_threshold;
54308 v_range -= v_threshold;
54309 v_prob -= (v_prob >> 5u);
54310 self->private_data.f_probs_longrep_len_low[v_index_len][v_tree_node] = ((uint16_t)(v_prob));
54311 v_tree_node = ((v_tree_node << 1u) | 1u);
54313 if ((v_range >> 24u) == 0u) {
54314 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
54315 status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_i_o);
54316 goto exit;
54318 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
54319 iop_a_src += 1u;
54320 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
54321 v_range <<= 8u;
54324 v_len = ((v_tree_node & 7u) + 2u);
54325 v_state = ((uint32_t)(WUFFS_LZMA__STATE_TRANSITION_LONGREP[v_state]));
54326 break;
54328 v_bits -= v_threshold;
54329 v_range -= v_threshold;
54330 v_prob -= (v_prob >> 5u);
54331 self->private_data.f_probs_longrep_len_low[0u][0u] = ((uint16_t)(v_prob));
54332 if ((v_range >> 24u) == 0u) {
54333 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
54334 status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_i_o);
54335 goto exit;
54337 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
54338 iop_a_src += 1u;
54339 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
54340 v_range <<= 8u;
54342 v_prob = ((uint32_t)(self->private_data.f_probs_longrep_len_mid[0u][0u]));
54343 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
54344 if (v_bits < v_threshold) {
54345 v_range = v_threshold;
54346 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
54347 self->private_data.f_probs_longrep_len_mid[0u][0u] = ((uint16_t)(v_prob));
54348 if ((v_range >> 24u) == 0u) {
54349 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
54350 status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_i_o);
54351 goto exit;
54353 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
54354 iop_a_src += 1u;
54355 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
54356 v_range <<= 8u;
54358 v_index_len = ((uint32_t)((v_pos & v_pb_mask)));
54359 v_tree_node = 1u;
54360 while (v_tree_node < 8u) {
54361 v_prob = ((uint32_t)(self->private_data.f_probs_longrep_len_mid[v_index_len][v_tree_node]));
54362 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
54363 if (v_bits < v_threshold) {
54364 v_range = v_threshold;
54365 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
54366 self->private_data.f_probs_longrep_len_mid[v_index_len][v_tree_node] = ((uint16_t)(v_prob));
54367 v_tree_node = (v_tree_node << 1u);
54368 } else {
54369 v_bits -= v_threshold;
54370 v_range -= v_threshold;
54371 v_prob -= (v_prob >> 5u);
54372 self->private_data.f_probs_longrep_len_mid[v_index_len][v_tree_node] = ((uint16_t)(v_prob));
54373 v_tree_node = ((v_tree_node << 1u) | 1u);
54375 if ((v_range >> 24u) == 0u) {
54376 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
54377 status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_i_o);
54378 goto exit;
54380 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
54381 iop_a_src += 1u;
54382 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
54383 v_range <<= 8u;
54386 v_len = ((v_tree_node & 7u) + 10u);
54387 v_state = ((uint32_t)(WUFFS_LZMA__STATE_TRANSITION_LONGREP[v_state]));
54388 break;
54390 v_bits -= v_threshold;
54391 v_range -= v_threshold;
54392 v_prob -= (v_prob >> 5u);
54393 self->private_data.f_probs_longrep_len_mid[0u][0u] = ((uint16_t)(v_prob));
54394 if ((v_range >> 24u) == 0u) {
54395 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
54396 status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_i_o);
54397 goto exit;
54399 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
54400 iop_a_src += 1u;
54401 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
54402 v_range <<= 8u;
54404 v_tree_node = 1u;
54405 while (v_tree_node < 256u) {
54406 v_prob = ((uint32_t)(self->private_data.f_probs_longrep_len_high[0u][v_tree_node]));
54407 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
54408 if (v_bits < v_threshold) {
54409 v_range = v_threshold;
54410 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
54411 self->private_data.f_probs_longrep_len_high[0u][v_tree_node] = ((uint16_t)(v_prob));
54412 v_tree_node = (v_tree_node << 1u);
54413 } else {
54414 v_bits -= v_threshold;
54415 v_range -= v_threshold;
54416 v_prob -= (v_prob >> 5u);
54417 self->private_data.f_probs_longrep_len_high[0u][v_tree_node] = ((uint16_t)(v_prob));
54418 v_tree_node = ((v_tree_node << 1u) | 1u);
54420 if ((v_range >> 24u) == 0u) {
54421 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
54422 status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_i_o);
54423 goto exit;
54425 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
54426 iop_a_src += 1u;
54427 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
54428 v_range <<= 8u;
54431 v_len = ((v_tree_node & 255u) + 18u);
54432 v_state = ((uint32_t)(WUFFS_LZMA__STATE_TRANSITION_LONGREP[v_state]));
54433 } while (0);
54434 } while (0);
54435 v_dist = (v_rep0 + 1u);
54436 if ((((uint64_t)(v_dist)) > v_pos) || (((uint64_t)(v_dist)) > ((uint64_t)(self->private_impl.f_dict_size)))) {
54437 status = wuffs_base__make_status(wuffs_lzma__error__bad_distance);
54438 goto exit;
54440 v_pos += ((uint64_t)(v_len));
54441 if (((uint64_t)(v_dist)) > ((uint64_t)(iop_a_dst - io0_a_dst))) {
54442 v_adj_dist = ((uint32_t)((((uint64_t)(v_dist)) - ((uint64_t)(iop_a_dst - io0_a_dst)))));
54443 if (v_adj_dist > self->private_impl.f_dict_seen) {
54444 status = wuffs_base__make_status(wuffs_lzma__error__bad_distance);
54445 goto exit;
54447 v_wb_index = ((uint64_t)(((uint64_t)(self->private_impl.f_dict_workbuf_index)) - ((uint64_t)(v_adj_dist))));
54448 while (v_wb_index >= 9223372036854775808u) {
54449 v_wb_index += ((uint64_t)(self->private_impl.f_dict_size));
54451 if (v_wb_index >= ((uint64_t)(a_workbuf.len))) {
54452 status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_dictionary_state);
54453 goto exit;
54455 if (v_len < v_adj_dist) {
54456 wuffs_private_impl__io_writer__limited_copy_u32_from_slice(
54457 &iop_a_dst, io2_a_dst,(v_len + 1u), wuffs_base__slice_u8__subslice_i(a_workbuf, v_wb_index));
54458 if ( ! (iop_a_dst > io1_a_dst)) {
54459 status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_dictionary_state);
54460 goto exit;
54462 v_match_byte = ((uint32_t)(iop_a_dst[-1]));
54463 iop_a_dst--;
54464 if ( ! (iop_a_dst > io1_a_dst)) {
54465 status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_dictionary_state);
54466 goto exit;
54468 v_prev_byte = iop_a_dst[-1];
54469 continue;
54470 } else if (v_len == v_adj_dist) {
54471 wuffs_private_impl__io_writer__limited_copy_u32_from_slice(
54472 &iop_a_dst, io2_a_dst,v_len, wuffs_base__slice_u8__subslice_i(a_workbuf, v_wb_index));
54473 wuffs_private_impl__io_writer__limited_copy_u32_from_history(
54474 &iop_a_dst, io0_a_dst, io2_a_dst, 1u, v_dist);
54475 if ( ! (iop_a_dst > io1_a_dst)) {
54476 status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_dictionary_state);
54477 goto exit;
54479 v_match_byte = ((uint32_t)(iop_a_dst[-1]));
54480 iop_a_dst--;
54481 if ( ! (iop_a_dst > io1_a_dst)) {
54482 status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_dictionary_state);
54483 goto exit;
54485 v_prev_byte = iop_a_dst[-1];
54486 continue;
54488 wuffs_private_impl__io_writer__limited_copy_u32_from_slice(
54489 &iop_a_dst, io2_a_dst,v_adj_dist, wuffs_base__slice_u8__subslice_i(a_workbuf, v_wb_index));
54490 v_len -= v_adj_dist;
54491 if ((((uint64_t)(v_len)) > ((uint64_t)(io2_a_dst - iop_a_dst))) || (((uint64_t)((v_len + 8u))) > ((uint64_t)(io2_a_dst - iop_a_dst))) || (((uint64_t)(v_dist)) > ((uint64_t)(iop_a_dst - io0_a_dst)))) {
54492 status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_dictionary_state);
54493 goto exit;
54496 if (v_dist >= 8u) {
54497 v_match_cusp = wuffs_private_impl__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast_return_cusp(
54498 &iop_a_dst, io0_a_dst, io2_a_dst, v_len, v_dist);
54499 v_match_byte = (v_match_cusp >> 8u);
54500 v_prev_byte = ((uint8_t)(v_match_cusp));
54501 } else {
54502 v_match_cusp = wuffs_private_impl__io_writer__limited_copy_u32_from_history_fast_return_cusp(
54503 &iop_a_dst, io0_a_dst, io2_a_dst, v_len, v_dist);
54504 v_match_byte = (v_match_cusp >> 8u);
54505 v_prev_byte = ((uint8_t)(v_match_cusp));
54508 label__outer__break:;
54509 self->private_impl.f_stashed_bytes[0u] = v_prev_byte;
54510 self->private_impl.f_stashed_bytes[1u] = ((uint8_t)(v_match_byte));
54511 self->private_impl.f_stashed_bits = v_bits;
54512 self->private_impl.f_stashed_range = v_range;
54513 self->private_impl.f_stashed_state = v_state;
54514 self->private_impl.f_stashed_rep0 = v_rep0;
54515 self->private_impl.f_stashed_rep1 = v_rep1;
54516 self->private_impl.f_stashed_rep2 = v_rep2;
54517 self->private_impl.f_stashed_rep3 = v_rep3;
54518 self->private_impl.f_stashed_pos = v_pos;
54519 self->private_impl.f_stashed_pos_end = v_pos_end;
54520 goto exit;
54521 exit:
54522 if (a_dst && a_dst->data.ptr) {
54523 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
54525 if (a_src && a_src->data.ptr) {
54526 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
54529 return status;
54532 // -------- func lzma.decoder.decode_bitstream_slow
54534 WUFFS_BASE__GENERATED_C_CODE
54535 static wuffs_base__status
54536 wuffs_lzma__decoder__decode_bitstream_slow(
54537 wuffs_lzma__decoder* self,
54538 wuffs_base__io_buffer* a_dst,
54539 wuffs_base__io_buffer* a_src,
54540 wuffs_base__slice_u8 a_workbuf) {
54541 wuffs_base__status status = wuffs_base__make_status(NULL);
54543 uint8_t v_c8 = 0;
54544 uint32_t v_bits = 0;
54545 uint32_t v_range = 0;
54546 uint32_t v_state = 0;
54547 uint32_t v_rep0 = 0;
54548 uint32_t v_rep1 = 0;
54549 uint32_t v_rep2 = 0;
54550 uint32_t v_rep3 = 0;
54551 uint32_t v_reptmp = 0;
54552 uint32_t v_rep = 0;
54553 uint64_t v_pos = 0;
54554 uint64_t v_pos_end = 0;
54555 uint32_t v_lc = 0;
54556 uint64_t v_lp_mask = 0;
54557 uint64_t v_pb_mask = 0;
54558 uint32_t v_prob = 0;
54559 uint32_t v_threshold = 0;
54560 uint32_t v_tree_node = 0;
54561 uint8_t v_prev_byte = 0;
54562 uint32_t v_match_byte = 0;
54563 uint32_t v_match_cusp = 0;
54564 uint32_t v_len_state = 0;
54565 uint32_t v_slot = 0;
54566 uint32_t v_len = 0;
54567 uint32_t v_lanl_offset = 0;
54568 uint32_t v_lanl_old_offset = 0;
54569 uint32_t v_lanl_index = 0;
54570 uint32_t v_num_extra_bits = 0;
54571 uint32_t v_dist_extra_bits = 0;
54572 uint32_t v_high_bit_was_on = 0;
54573 uint32_t v_i = 0;
54574 uint32_t v_index_ao00 = 0;
54575 uint32_t v_index_ao41 = 0;
54576 uint32_t v_index_lit = 0;
54577 uint32_t v_index_len = 0;
54578 uint32_t v_index_small_dist_base = 0;
54579 uint32_t v_index_small_dist_extra = 0;
54580 uint32_t v_index_small_dist = 0;
54581 uint32_t v_index_large_dist = 0;
54582 uint32_t v_dist = 0;
54583 uint32_t v_adj_dist = 0;
54584 uint64_t v_wb_index = 0;
54586 uint8_t* iop_a_dst = NULL;
54587 uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
54588 uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
54589 uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
54590 if (a_dst && a_dst->data.ptr) {
54591 io0_a_dst = a_dst->data.ptr;
54592 io1_a_dst = io0_a_dst + a_dst->meta.wi;
54593 iop_a_dst = io1_a_dst;
54594 io2_a_dst = io0_a_dst + a_dst->data.len;
54595 if (a_dst->meta.closed) {
54596 io2_a_dst = iop_a_dst;
54599 const uint8_t* iop_a_src = NULL;
54600 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
54601 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
54602 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
54603 if (a_src && a_src->data.ptr) {
54604 io0_a_src = a_src->data.ptr;
54605 io1_a_src = io0_a_src + a_src->meta.ri;
54606 iop_a_src = io1_a_src;
54607 io2_a_src = io0_a_src + a_src->meta.wi;
54610 uint32_t coro_susp_point = self->private_impl.p_decode_bitstream_slow;
54611 if (coro_susp_point) {
54612 v_bits = self->private_data.s_decode_bitstream_slow.v_bits;
54613 v_range = self->private_data.s_decode_bitstream_slow.v_range;
54614 v_state = self->private_data.s_decode_bitstream_slow.v_state;
54615 v_rep0 = self->private_data.s_decode_bitstream_slow.v_rep0;
54616 v_rep1 = self->private_data.s_decode_bitstream_slow.v_rep1;
54617 v_rep2 = self->private_data.s_decode_bitstream_slow.v_rep2;
54618 v_rep3 = self->private_data.s_decode_bitstream_slow.v_rep3;
54619 v_rep = self->private_data.s_decode_bitstream_slow.v_rep;
54620 v_pos = self->private_data.s_decode_bitstream_slow.v_pos;
54621 v_pos_end = self->private_data.s_decode_bitstream_slow.v_pos_end;
54622 v_lc = self->private_data.s_decode_bitstream_slow.v_lc;
54623 v_lp_mask = self->private_data.s_decode_bitstream_slow.v_lp_mask;
54624 v_pb_mask = self->private_data.s_decode_bitstream_slow.v_pb_mask;
54625 v_tree_node = self->private_data.s_decode_bitstream_slow.v_tree_node;
54626 v_prev_byte = self->private_data.s_decode_bitstream_slow.v_prev_byte;
54627 v_match_byte = self->private_data.s_decode_bitstream_slow.v_match_byte;
54628 v_len_state = self->private_data.s_decode_bitstream_slow.v_len_state;
54629 v_slot = self->private_data.s_decode_bitstream_slow.v_slot;
54630 v_len = self->private_data.s_decode_bitstream_slow.v_len;
54631 v_lanl_offset = self->private_data.s_decode_bitstream_slow.v_lanl_offset;
54632 v_num_extra_bits = self->private_data.s_decode_bitstream_slow.v_num_extra_bits;
54633 v_dist_extra_bits = self->private_data.s_decode_bitstream_slow.v_dist_extra_bits;
54634 v_i = self->private_data.s_decode_bitstream_slow.v_i;
54635 v_index_lit = self->private_data.s_decode_bitstream_slow.v_index_lit;
54636 v_index_len = self->private_data.s_decode_bitstream_slow.v_index_len;
54637 v_index_small_dist_base = self->private_data.s_decode_bitstream_slow.v_index_small_dist_base;
54638 v_index_small_dist_extra = self->private_data.s_decode_bitstream_slow.v_index_small_dist_extra;
54639 v_index_large_dist = self->private_data.s_decode_bitstream_slow.v_index_large_dist;
54640 v_dist = self->private_data.s_decode_bitstream_slow.v_dist;
54642 switch (coro_susp_point) {
54643 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
54645 v_prev_byte = self->private_impl.f_stashed_bytes[0u];
54646 v_match_byte = ((uint32_t)(self->private_impl.f_stashed_bytes[1u]));
54647 v_bits = self->private_impl.f_stashed_bits;
54648 v_range = self->private_impl.f_stashed_range;
54649 v_state = self->private_impl.f_stashed_state;
54650 v_rep0 = self->private_impl.f_stashed_rep0;
54651 v_rep1 = self->private_impl.f_stashed_rep1;
54652 v_rep2 = self->private_impl.f_stashed_rep2;
54653 v_rep3 = self->private_impl.f_stashed_rep3;
54654 v_pos = self->private_impl.f_stashed_pos;
54655 v_pos_end = self->private_impl.f_stashed_pos_end;
54656 v_lc = self->private_impl.f_lc;
54657 v_lp_mask = ((((uint64_t)(1u)) << self->private_impl.f_lp) - 1u);
54658 v_pb_mask = ((((uint64_t)(1u)) << self->private_impl.f_pb) - 1u);
54659 while ( ! (self->private_impl.p_decode_bitstream_slow != 0)) {
54660 if (v_pos >= v_pos_end) {
54661 self->private_impl.f_end_of_chunk = true;
54662 break;
54664 v_index_ao00 = ((v_state << 4u) | ((uint32_t)((v_pos & v_pb_mask))));
54665 v_prob = ((uint32_t)(self->private_data.f_probs_ao00[v_index_ao00]));
54666 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
54667 if (v_bits < v_threshold) {
54668 v_range = v_threshold;
54669 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
54670 self->private_data.f_probs_ao00[v_index_ao00] = ((uint16_t)(v_prob));
54671 if ((v_range >> 24u) == 0u) {
54673 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
54674 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
54675 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
54676 goto suspend;
54678 uint8_t t_0 = *iop_a_src++;
54679 v_c8 = t_0;
54681 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
54682 v_range <<= 8u;
54684 v_index_lit = (15u & ((((uint32_t)((v_pos & v_lp_mask))) << v_lc) | (((uint32_t)(v_prev_byte)) >> (8u - v_lc))));
54685 if (v_state >= 7u) {
54686 v_lanl_offset = 256u;
54687 v_tree_node = 1u;
54688 while (v_tree_node < 256u) {
54689 v_match_byte <<= 1u;
54690 v_lanl_old_offset = v_lanl_offset;
54691 v_lanl_offset &= v_match_byte;
54692 v_lanl_index = (v_lanl_offset + v_lanl_old_offset + v_tree_node);
54693 v_prob = ((uint32_t)(self->private_data.f_probs_lit[v_index_lit][v_lanl_index]));
54694 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
54695 if (v_bits < v_threshold) {
54696 v_lanl_offset = ((v_lanl_offset ^ v_lanl_old_offset) & 256u);
54697 v_range = v_threshold;
54698 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
54699 self->private_data.f_probs_lit[v_index_lit][v_lanl_index] = ((uint16_t)(v_prob));
54700 v_tree_node = (v_tree_node << 1u);
54701 } else {
54702 v_bits -= v_threshold;
54703 v_range -= v_threshold;
54704 v_prob -= (v_prob >> 5u);
54705 self->private_data.f_probs_lit[v_index_lit][v_lanl_index] = ((uint16_t)(v_prob));
54706 v_tree_node = ((v_tree_node << 1u) | 1u);
54708 if ((v_range >> 24u) == 0u) {
54710 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
54711 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
54712 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
54713 goto suspend;
54715 uint8_t t_1 = *iop_a_src++;
54716 v_c8 = t_1;
54718 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
54719 v_range <<= 8u;
54722 } else {
54723 v_tree_node = 1u;
54724 while (v_tree_node < 256u) {
54725 v_prob = ((uint32_t)(self->private_data.f_probs_lit[v_index_lit][v_tree_node]));
54726 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
54727 if (v_bits < v_threshold) {
54728 v_range = v_threshold;
54729 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
54730 self->private_data.f_probs_lit[v_index_lit][v_tree_node] = ((uint16_t)(v_prob));
54731 v_tree_node = (v_tree_node << 1u);
54732 } else {
54733 v_bits -= v_threshold;
54734 v_range -= v_threshold;
54735 v_prob -= (v_prob >> 5u);
54736 self->private_data.f_probs_lit[v_index_lit][v_tree_node] = ((uint16_t)(v_prob));
54737 v_tree_node = ((v_tree_node << 1u) | 1u);
54739 if ((v_range >> 24u) == 0u) {
54741 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
54742 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
54743 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
54744 goto suspend;
54746 uint8_t t_2 = *iop_a_src++;
54747 v_c8 = t_2;
54749 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
54750 v_range <<= 8u;
54754 v_prev_byte = ((uint8_t)(v_tree_node));
54755 self->private_data.s_decode_bitstream_slow.scratch = v_prev_byte;
54756 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
54757 if (iop_a_dst == io2_a_dst) {
54758 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
54759 goto suspend;
54761 *iop_a_dst++ = ((uint8_t)(self->private_data.s_decode_bitstream_slow.scratch));
54762 v_pos += 1u;
54763 v_state = ((uint32_t)(WUFFS_LZMA__STATE_TRANSITION_LITERAL[v_state]));
54764 continue;
54766 v_bits -= v_threshold;
54767 v_range -= v_threshold;
54768 v_prob -= (v_prob >> 5u);
54769 self->private_data.f_probs_ao00[v_index_ao00] = ((uint16_t)(v_prob));
54770 if ((v_range >> 24u) == 0u) {
54772 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
54773 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
54774 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
54775 goto suspend;
54777 uint8_t t_3 = *iop_a_src++;
54778 v_c8 = t_3;
54780 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
54781 v_range <<= 8u;
54783 do {
54784 v_prob = ((uint32_t)(self->private_data.f_probs_ao20[v_state]));
54785 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
54786 if (v_bits < v_threshold) {
54787 v_range = v_threshold;
54788 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
54789 self->private_data.f_probs_ao20[v_state] = ((uint16_t)(v_prob));
54790 if ((v_range >> 24u) == 0u) {
54792 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
54793 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
54794 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
54795 goto suspend;
54797 uint8_t t_4 = *iop_a_src++;
54798 v_c8 = t_4;
54800 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
54801 v_range <<= 8u;
54803 do {
54804 v_prob = ((uint32_t)(self->private_data.f_probs_match_len_low[0u][0u]));
54805 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
54806 if (v_bits < v_threshold) {
54807 v_range = v_threshold;
54808 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
54809 self->private_data.f_probs_match_len_low[0u][0u] = ((uint16_t)(v_prob));
54810 if ((v_range >> 24u) == 0u) {
54812 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
54813 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
54814 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
54815 goto suspend;
54817 uint8_t t_5 = *iop_a_src++;
54818 v_c8 = t_5;
54820 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
54821 v_range <<= 8u;
54823 v_index_len = ((uint32_t)((v_pos & v_pb_mask)));
54824 v_tree_node = 1u;
54825 while (v_tree_node < 8u) {
54826 v_prob = ((uint32_t)(self->private_data.f_probs_match_len_low[v_index_len][v_tree_node]));
54827 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
54828 if (v_bits < v_threshold) {
54829 v_range = v_threshold;
54830 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
54831 self->private_data.f_probs_match_len_low[v_index_len][v_tree_node] = ((uint16_t)(v_prob));
54832 v_tree_node = (v_tree_node << 1u);
54833 } else {
54834 v_bits -= v_threshold;
54835 v_range -= v_threshold;
54836 v_prob -= (v_prob >> 5u);
54837 self->private_data.f_probs_match_len_low[v_index_len][v_tree_node] = ((uint16_t)(v_prob));
54838 v_tree_node = ((v_tree_node << 1u) | 1u);
54840 if ((v_range >> 24u) == 0u) {
54842 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
54843 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
54844 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
54845 goto suspend;
54847 uint8_t t_6 = *iop_a_src++;
54848 v_c8 = t_6;
54850 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
54851 v_range <<= 8u;
54854 v_len_state = ((uint32_t)(WUFFS_LZMA__CLAMP_NO_MORE_THAN_3[(v_tree_node & 7u)]));
54855 v_len = ((v_tree_node & 7u) + 2u);
54856 break;
54858 v_bits -= v_threshold;
54859 v_range -= v_threshold;
54860 v_prob -= (v_prob >> 5u);
54861 self->private_data.f_probs_match_len_low[0u][0u] = ((uint16_t)(v_prob));
54862 if ((v_range >> 24u) == 0u) {
54864 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
54865 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
54866 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
54867 goto suspend;
54869 uint8_t t_7 = *iop_a_src++;
54870 v_c8 = t_7;
54872 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
54873 v_range <<= 8u;
54875 v_prob = ((uint32_t)(self->private_data.f_probs_match_len_mid[0u][0u]));
54876 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
54877 if (v_bits < v_threshold) {
54878 v_range = v_threshold;
54879 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
54880 self->private_data.f_probs_match_len_mid[0u][0u] = ((uint16_t)(v_prob));
54881 if ((v_range >> 24u) == 0u) {
54883 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
54884 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
54885 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
54886 goto suspend;
54888 uint8_t t_8 = *iop_a_src++;
54889 v_c8 = t_8;
54891 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
54892 v_range <<= 8u;
54894 v_index_len = ((uint32_t)((v_pos & v_pb_mask)));
54895 v_tree_node = 1u;
54896 while (v_tree_node < 8u) {
54897 v_prob = ((uint32_t)(self->private_data.f_probs_match_len_mid[v_index_len][v_tree_node]));
54898 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
54899 if (v_bits < v_threshold) {
54900 v_range = v_threshold;
54901 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
54902 self->private_data.f_probs_match_len_mid[v_index_len][v_tree_node] = ((uint16_t)(v_prob));
54903 v_tree_node = (v_tree_node << 1u);
54904 } else {
54905 v_bits -= v_threshold;
54906 v_range -= v_threshold;
54907 v_prob -= (v_prob >> 5u);
54908 self->private_data.f_probs_match_len_mid[v_index_len][v_tree_node] = ((uint16_t)(v_prob));
54909 v_tree_node = ((v_tree_node << 1u) | 1u);
54911 if ((v_range >> 24u) == 0u) {
54913 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
54914 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
54915 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
54916 goto suspend;
54918 uint8_t t_9 = *iop_a_src++;
54919 v_c8 = t_9;
54921 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
54922 v_range <<= 8u;
54925 v_len = ((v_tree_node & 7u) + 10u);
54926 v_len_state = 3u;
54927 break;
54929 v_bits -= v_threshold;
54930 v_range -= v_threshold;
54931 v_prob -= (v_prob >> 5u);
54932 self->private_data.f_probs_match_len_mid[0u][0u] = ((uint16_t)(v_prob));
54933 if ((v_range >> 24u) == 0u) {
54935 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
54936 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
54937 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
54938 goto suspend;
54940 uint8_t t_10 = *iop_a_src++;
54941 v_c8 = t_10;
54943 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
54944 v_range <<= 8u;
54946 v_tree_node = 1u;
54947 while (v_tree_node < 256u) {
54948 v_prob = ((uint32_t)(self->private_data.f_probs_match_len_high[0u][v_tree_node]));
54949 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
54950 if (v_bits < v_threshold) {
54951 v_range = v_threshold;
54952 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
54953 self->private_data.f_probs_match_len_high[0u][v_tree_node] = ((uint16_t)(v_prob));
54954 v_tree_node = (v_tree_node << 1u);
54955 } else {
54956 v_bits -= v_threshold;
54957 v_range -= v_threshold;
54958 v_prob -= (v_prob >> 5u);
54959 self->private_data.f_probs_match_len_high[0u][v_tree_node] = ((uint16_t)(v_prob));
54960 v_tree_node = ((v_tree_node << 1u) | 1u);
54962 if ((v_range >> 24u) == 0u) {
54964 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
54965 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
54966 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
54967 goto suspend;
54969 uint8_t t_11 = *iop_a_src++;
54970 v_c8 = t_11;
54972 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
54973 v_range <<= 8u;
54976 v_len = ((v_tree_node & 255u) + 18u);
54977 v_len_state = 3u;
54978 } while (0);
54979 v_slot = 1u;
54980 while (v_slot < 64u) {
54981 v_prob = ((uint32_t)(self->private_data.f_probs_slot[v_len_state][v_slot]));
54982 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
54983 if (v_bits < v_threshold) {
54984 v_range = v_threshold;
54985 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
54986 self->private_data.f_probs_slot[v_len_state][v_slot] = ((uint16_t)(v_prob));
54987 v_slot = (v_slot << 1u);
54988 } else {
54989 v_bits -= v_threshold;
54990 v_range -= v_threshold;
54991 v_prob -= (v_prob >> 5u);
54992 self->private_data.f_probs_slot[v_len_state][v_slot] = ((uint16_t)(v_prob));
54993 v_slot = ((v_slot << 1u) | 1u);
54995 if ((v_range >> 24u) == 0u) {
54997 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
54998 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
54999 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
55000 goto suspend;
55002 uint8_t t_12 = *iop_a_src++;
55003 v_c8 = t_12;
55005 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
55006 v_range <<= 8u;
55009 v_slot &= 63u;
55010 v_rep = v_slot;
55011 if (v_slot < 4u) {
55012 } else if (v_slot < 14u) {
55013 v_num_extra_bits = ((v_slot >> 1u) - 1u);
55014 v_rep = ((2u | (v_slot & 1u)) << v_num_extra_bits);
55015 v_index_small_dist_base = ((uint32_t)(v_rep - v_slot));
55016 v_index_small_dist_extra = 1u;
55017 v_dist_extra_bits = 0u;
55018 v_i = 0u;
55019 while (v_i < v_num_extra_bits) {
55020 v_index_small_dist = (((uint32_t)(v_index_small_dist_base + v_index_small_dist_extra)) & 127u);
55021 v_prob = ((uint32_t)(self->private_data.f_probs_small_dist[v_index_small_dist]));
55022 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
55023 if (v_bits < v_threshold) {
55024 v_range = v_threshold;
55025 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
55026 self->private_data.f_probs_small_dist[v_index_small_dist] = ((uint16_t)(v_prob));
55027 v_index_small_dist_extra = ((uint32_t)(v_index_small_dist_extra << 1u));
55028 v_i += 1u;
55029 } else {
55030 v_bits -= v_threshold;
55031 v_range -= v_threshold;
55032 v_prob -= (v_prob >> 5u);
55033 self->private_data.f_probs_small_dist[v_index_small_dist] = ((uint16_t)(v_prob));
55034 v_index_small_dist_extra = (((uint32_t)(v_index_small_dist_extra << 1u)) | 1u);
55035 v_dist_extra_bits |= (((uint32_t)(1u)) << v_i);
55036 v_i += 1u;
55038 if ((v_range >> 24u) == 0u) {
55040 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
55041 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
55042 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
55043 goto suspend;
55045 uint8_t t_13 = *iop_a_src++;
55046 v_c8 = t_13;
55048 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
55049 v_range <<= 8u;
55052 v_rep += v_dist_extra_bits;
55053 } else {
55054 v_num_extra_bits = ((v_slot >> 1u) - 1u);
55055 v_rep = ((2u | (v_slot & 1u)) << v_num_extra_bits);
55056 v_dist_extra_bits = 0u;
55057 while (true) {
55058 v_range >>= 1u;
55059 v_bits -= v_range;
55060 v_high_bit_was_on = ((uint32_t)(0u - (v_bits >> 31u)));
55061 v_bits += (v_range & v_high_bit_was_on);
55062 v_dist_extra_bits = (((uint32_t)(v_dist_extra_bits << 1u)) | (((uint32_t)(v_high_bit_was_on + 1u)) & 1u));
55063 if ((v_range >> 24u) == 0u) {
55065 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
55066 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
55067 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
55068 goto suspend;
55070 uint8_t t_14 = *iop_a_src++;
55071 v_c8 = t_14;
55073 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
55074 v_range <<= 8u;
55076 v_num_extra_bits -= 1u;
55077 if (v_num_extra_bits <= 4u) {
55078 break;
55081 v_dist_extra_bits <<= 4u;
55082 v_index_large_dist = 1u;
55083 while (true) {
55084 v_prob = ((uint32_t)(self->private_data.f_probs_large_dist[v_index_large_dist]));
55085 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
55086 if (v_bits < v_threshold) {
55087 v_range = v_threshold;
55088 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
55089 self->private_data.f_probs_large_dist[v_index_large_dist] = ((uint16_t)(v_prob));
55090 v_index_large_dist = (15u & ((uint32_t)(v_index_large_dist << 1u)));
55091 } else {
55092 v_bits -= v_threshold;
55093 v_range -= v_threshold;
55094 v_prob -= (v_prob >> 5u);
55095 self->private_data.f_probs_large_dist[v_index_large_dist] = ((uint16_t)(v_prob));
55096 v_index_large_dist = (15u & (((uint32_t)(v_index_large_dist << 1u)) | 1u));
55097 v_dist_extra_bits |= (((uint32_t)(1u)) << (4u - v_num_extra_bits));
55099 if ((v_range >> 24u) == 0u) {
55101 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(17);
55102 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
55103 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
55104 goto suspend;
55106 uint8_t t_15 = *iop_a_src++;
55107 v_c8 = t_15;
55109 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
55110 v_range <<= 8u;
55112 v_num_extra_bits -= 1u;
55113 if (v_num_extra_bits <= 0u) {
55114 break;
55117 v_rep += v_dist_extra_bits;
55119 if (v_rep >= 4294967295u) {
55120 self->private_impl.f_end_of_chunk = true;
55121 goto label__outer__break;
55123 v_rep3 = v_rep2;
55124 v_rep2 = v_rep1;
55125 v_rep1 = v_rep0;
55126 v_rep0 = v_rep;
55127 v_state = ((uint32_t)(WUFFS_LZMA__STATE_TRANSITION_MATCH[v_state]));
55128 break;
55130 v_bits -= v_threshold;
55131 v_range -= v_threshold;
55132 v_prob -= (v_prob >> 5u);
55133 self->private_data.f_probs_ao20[v_state] = ((uint16_t)(v_prob));
55134 if ((v_range >> 24u) == 0u) {
55136 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(18);
55137 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
55138 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
55139 goto suspend;
55141 uint8_t t_16 = *iop_a_src++;
55142 v_c8 = t_16;
55144 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
55145 v_range <<= 8u;
55147 v_prob = ((uint32_t)(self->private_data.f_probs_ao40[v_state]));
55148 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
55149 if (v_bits < v_threshold) {
55150 v_range = v_threshold;
55151 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
55152 self->private_data.f_probs_ao40[v_state] = ((uint16_t)(v_prob));
55153 if ((v_range >> 24u) == 0u) {
55155 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(19);
55156 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
55157 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
55158 goto suspend;
55160 uint8_t t_17 = *iop_a_src++;
55161 v_c8 = t_17;
55163 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
55164 v_range <<= 8u;
55166 v_index_ao41 = ((v_state << 4u) | ((uint32_t)((v_pos & v_pb_mask))));
55167 v_prob = ((uint32_t)(self->private_data.f_probs_ao41[v_index_ao41]));
55168 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
55169 if (v_bits < v_threshold) {
55170 v_range = v_threshold;
55171 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
55172 self->private_data.f_probs_ao41[v_index_ao41] = ((uint16_t)(v_prob));
55173 if ((v_range >> 24u) == 0u) {
55175 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(20);
55176 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
55177 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
55178 goto suspend;
55180 uint8_t t_18 = *iop_a_src++;
55181 v_c8 = t_18;
55183 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
55184 v_range <<= 8u;
55186 v_len = 1u;
55187 v_state = ((uint32_t)(WUFFS_LZMA__STATE_TRANSITION_SHORTREP[v_state]));
55188 break;
55190 v_bits -= v_threshold;
55191 v_range -= v_threshold;
55192 v_prob -= (v_prob >> 5u);
55193 self->private_data.f_probs_ao41[v_index_ao41] = ((uint16_t)(v_prob));
55194 if ((v_range >> 24u) == 0u) {
55196 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(21);
55197 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
55198 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
55199 goto suspend;
55201 uint8_t t_19 = *iop_a_src++;
55202 v_c8 = t_19;
55204 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
55205 v_range <<= 8u;
55207 } else {
55208 v_bits -= v_threshold;
55209 v_range -= v_threshold;
55210 v_prob -= (v_prob >> 5u);
55211 self->private_data.f_probs_ao40[v_state] = ((uint16_t)(v_prob));
55212 if ((v_range >> 24u) == 0u) {
55214 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(22);
55215 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
55216 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
55217 goto suspend;
55219 uint8_t t_20 = *iop_a_src++;
55220 v_c8 = t_20;
55222 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
55223 v_range <<= 8u;
55225 v_prob = ((uint32_t)(self->private_data.f_probs_ao60[v_state]));
55226 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
55227 if (v_bits < v_threshold) {
55228 v_range = v_threshold;
55229 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
55230 self->private_data.f_probs_ao60[v_state] = ((uint16_t)(v_prob));
55231 if ((v_range >> 24u) == 0u) {
55233 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(23);
55234 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
55235 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
55236 goto suspend;
55238 uint8_t t_21 = *iop_a_src++;
55239 v_c8 = t_21;
55241 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
55242 v_range <<= 8u;
55244 v_reptmp = v_rep1;
55245 v_rep1 = v_rep0;
55246 v_rep0 = v_reptmp;
55247 } else {
55248 v_bits -= v_threshold;
55249 v_range -= v_threshold;
55250 v_prob -= (v_prob >> 5u);
55251 self->private_data.f_probs_ao60[v_state] = ((uint16_t)(v_prob));
55252 if ((v_range >> 24u) == 0u) {
55254 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(24);
55255 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
55256 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
55257 goto suspend;
55259 uint8_t t_22 = *iop_a_src++;
55260 v_c8 = t_22;
55262 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
55263 v_range <<= 8u;
55265 v_prob = ((uint32_t)(self->private_data.f_probs_ao63[v_state]));
55266 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
55267 if (v_bits < v_threshold) {
55268 v_range = v_threshold;
55269 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
55270 self->private_data.f_probs_ao63[v_state] = ((uint16_t)(v_prob));
55271 if ((v_range >> 24u) == 0u) {
55273 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(25);
55274 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
55275 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
55276 goto suspend;
55278 uint8_t t_23 = *iop_a_src++;
55279 v_c8 = t_23;
55281 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
55282 v_range <<= 8u;
55284 v_reptmp = v_rep2;
55285 v_rep2 = v_rep1;
55286 v_rep1 = v_rep0;
55287 v_rep0 = v_reptmp;
55288 } else {
55289 v_bits -= v_threshold;
55290 v_range -= v_threshold;
55291 v_prob -= (v_prob >> 5u);
55292 self->private_data.f_probs_ao63[v_state] = ((uint16_t)(v_prob));
55293 if ((v_range >> 24u) == 0u) {
55295 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(26);
55296 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
55297 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
55298 goto suspend;
55300 uint8_t t_24 = *iop_a_src++;
55301 v_c8 = t_24;
55303 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
55304 v_range <<= 8u;
55306 v_reptmp = v_rep3;
55307 v_rep3 = v_rep2;
55308 v_rep2 = v_rep1;
55309 v_rep1 = v_rep0;
55310 v_rep0 = v_reptmp;
55314 do {
55315 v_prob = ((uint32_t)(self->private_data.f_probs_longrep_len_low[0u][0u]));
55316 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
55317 if (v_bits < v_threshold) {
55318 v_range = v_threshold;
55319 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
55320 self->private_data.f_probs_longrep_len_low[0u][0u] = ((uint16_t)(v_prob));
55321 if ((v_range >> 24u) == 0u) {
55323 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(27);
55324 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
55325 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
55326 goto suspend;
55328 uint8_t t_25 = *iop_a_src++;
55329 v_c8 = t_25;
55331 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
55332 v_range <<= 8u;
55334 v_index_len = ((uint32_t)((v_pos & v_pb_mask)));
55335 v_tree_node = 1u;
55336 while (v_tree_node < 8u) {
55337 v_prob = ((uint32_t)(self->private_data.f_probs_longrep_len_low[v_index_len][v_tree_node]));
55338 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
55339 if (v_bits < v_threshold) {
55340 v_range = v_threshold;
55341 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
55342 self->private_data.f_probs_longrep_len_low[v_index_len][v_tree_node] = ((uint16_t)(v_prob));
55343 v_tree_node = (v_tree_node << 1u);
55344 } else {
55345 v_bits -= v_threshold;
55346 v_range -= v_threshold;
55347 v_prob -= (v_prob >> 5u);
55348 self->private_data.f_probs_longrep_len_low[v_index_len][v_tree_node] = ((uint16_t)(v_prob));
55349 v_tree_node = ((v_tree_node << 1u) | 1u);
55351 if ((v_range >> 24u) == 0u) {
55353 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(28);
55354 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
55355 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
55356 goto suspend;
55358 uint8_t t_26 = *iop_a_src++;
55359 v_c8 = t_26;
55361 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
55362 v_range <<= 8u;
55365 v_len = ((v_tree_node & 7u) + 2u);
55366 v_state = ((uint32_t)(WUFFS_LZMA__STATE_TRANSITION_LONGREP[v_state]));
55367 break;
55369 v_bits -= v_threshold;
55370 v_range -= v_threshold;
55371 v_prob -= (v_prob >> 5u);
55372 self->private_data.f_probs_longrep_len_low[0u][0u] = ((uint16_t)(v_prob));
55373 if ((v_range >> 24u) == 0u) {
55375 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(29);
55376 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
55377 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
55378 goto suspend;
55380 uint8_t t_27 = *iop_a_src++;
55381 v_c8 = t_27;
55383 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
55384 v_range <<= 8u;
55386 v_prob = ((uint32_t)(self->private_data.f_probs_longrep_len_mid[0u][0u]));
55387 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
55388 if (v_bits < v_threshold) {
55389 v_range = v_threshold;
55390 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
55391 self->private_data.f_probs_longrep_len_mid[0u][0u] = ((uint16_t)(v_prob));
55392 if ((v_range >> 24u) == 0u) {
55394 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(30);
55395 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
55396 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
55397 goto suspend;
55399 uint8_t t_28 = *iop_a_src++;
55400 v_c8 = t_28;
55402 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
55403 v_range <<= 8u;
55405 v_index_len = ((uint32_t)((v_pos & v_pb_mask)));
55406 v_tree_node = 1u;
55407 while (v_tree_node < 8u) {
55408 v_prob = ((uint32_t)(self->private_data.f_probs_longrep_len_mid[v_index_len][v_tree_node]));
55409 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
55410 if (v_bits < v_threshold) {
55411 v_range = v_threshold;
55412 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
55413 self->private_data.f_probs_longrep_len_mid[v_index_len][v_tree_node] = ((uint16_t)(v_prob));
55414 v_tree_node = (v_tree_node << 1u);
55415 } else {
55416 v_bits -= v_threshold;
55417 v_range -= v_threshold;
55418 v_prob -= (v_prob >> 5u);
55419 self->private_data.f_probs_longrep_len_mid[v_index_len][v_tree_node] = ((uint16_t)(v_prob));
55420 v_tree_node = ((v_tree_node << 1u) | 1u);
55422 if ((v_range >> 24u) == 0u) {
55424 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(31);
55425 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
55426 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
55427 goto suspend;
55429 uint8_t t_29 = *iop_a_src++;
55430 v_c8 = t_29;
55432 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
55433 v_range <<= 8u;
55436 v_len = ((v_tree_node & 7u) + 10u);
55437 v_state = ((uint32_t)(WUFFS_LZMA__STATE_TRANSITION_LONGREP[v_state]));
55438 break;
55440 v_bits -= v_threshold;
55441 v_range -= v_threshold;
55442 v_prob -= (v_prob >> 5u);
55443 self->private_data.f_probs_longrep_len_mid[0u][0u] = ((uint16_t)(v_prob));
55444 if ((v_range >> 24u) == 0u) {
55446 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(32);
55447 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
55448 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
55449 goto suspend;
55451 uint8_t t_30 = *iop_a_src++;
55452 v_c8 = t_30;
55454 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
55455 v_range <<= 8u;
55457 v_tree_node = 1u;
55458 while (v_tree_node < 256u) {
55459 v_prob = ((uint32_t)(self->private_data.f_probs_longrep_len_high[0u][v_tree_node]));
55460 v_threshold = ((uint32_t)((v_range >> 11u) * v_prob));
55461 if (v_bits < v_threshold) {
55462 v_range = v_threshold;
55463 v_prob += (((uint32_t)(2048u - v_prob)) >> 5u);
55464 self->private_data.f_probs_longrep_len_high[0u][v_tree_node] = ((uint16_t)(v_prob));
55465 v_tree_node = (v_tree_node << 1u);
55466 } else {
55467 v_bits -= v_threshold;
55468 v_range -= v_threshold;
55469 v_prob -= (v_prob >> 5u);
55470 self->private_data.f_probs_longrep_len_high[0u][v_tree_node] = ((uint16_t)(v_prob));
55471 v_tree_node = ((v_tree_node << 1u) | 1u);
55473 if ((v_range >> 24u) == 0u) {
55475 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(33);
55476 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
55477 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
55478 goto suspend;
55480 uint8_t t_31 = *iop_a_src++;
55481 v_c8 = t_31;
55483 v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8)));
55484 v_range <<= 8u;
55487 v_len = ((v_tree_node & 255u) + 18u);
55488 v_state = ((uint32_t)(WUFFS_LZMA__STATE_TRANSITION_LONGREP[v_state]));
55489 } while (0);
55490 } while (0);
55491 v_dist = (v_rep0 + 1u);
55492 if ((((uint64_t)(v_dist)) > v_pos) || (((uint64_t)(v_dist)) > ((uint64_t)(self->private_impl.f_dict_size)))) {
55493 status = wuffs_base__make_status(wuffs_lzma__error__bad_distance);
55494 goto exit;
55496 v_pos += ((uint64_t)(v_len));
55497 while (274u > ((uint64_t)(io2_a_dst - iop_a_dst))) {
55498 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
55499 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(34);
55501 if (((uint64_t)(v_dist)) > ((uint64_t)(iop_a_dst - io0_a_dst))) {
55502 v_adj_dist = ((uint32_t)((((uint64_t)(v_dist)) - ((uint64_t)(iop_a_dst - io0_a_dst)))));
55503 if (v_adj_dist > self->private_impl.f_dict_seen) {
55504 status = wuffs_base__make_status(wuffs_lzma__error__bad_distance);
55505 goto exit;
55507 v_wb_index = ((uint64_t)(((uint64_t)(self->private_impl.f_dict_workbuf_index)) - ((uint64_t)(v_adj_dist))));
55508 while (v_wb_index >= 9223372036854775808u) {
55509 v_wb_index += ((uint64_t)(self->private_impl.f_dict_size));
55511 if (v_wb_index >= ((uint64_t)(a_workbuf.len))) {
55512 status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_dictionary_state);
55513 goto exit;
55515 if (v_len < v_adj_dist) {
55516 wuffs_private_impl__io_writer__limited_copy_u32_from_slice(
55517 &iop_a_dst, io2_a_dst,(v_len + 1u), wuffs_base__slice_u8__subslice_i(a_workbuf, v_wb_index));
55518 if ( ! (iop_a_dst > io1_a_dst)) {
55519 status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_dictionary_state);
55520 goto exit;
55522 v_match_byte = ((uint32_t)(iop_a_dst[-1]));
55523 iop_a_dst--;
55524 if ( ! (iop_a_dst > io1_a_dst)) {
55525 status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_dictionary_state);
55526 goto exit;
55528 v_prev_byte = iop_a_dst[-1];
55529 continue;
55530 } else if (v_len == v_adj_dist) {
55531 wuffs_private_impl__io_writer__limited_copy_u32_from_slice(
55532 &iop_a_dst, io2_a_dst,v_len, wuffs_base__slice_u8__subslice_i(a_workbuf, v_wb_index));
55533 wuffs_private_impl__io_writer__limited_copy_u32_from_history(
55534 &iop_a_dst, io0_a_dst, io2_a_dst, 1u, v_dist);
55535 if ( ! (iop_a_dst > io1_a_dst)) {
55536 status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_dictionary_state);
55537 goto exit;
55539 v_match_byte = ((uint32_t)(iop_a_dst[-1]));
55540 iop_a_dst--;
55541 if ( ! (iop_a_dst > io1_a_dst)) {
55542 status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_dictionary_state);
55543 goto exit;
55545 v_prev_byte = iop_a_dst[-1];
55546 continue;
55548 wuffs_private_impl__io_writer__limited_copy_u32_from_slice(
55549 &iop_a_dst, io2_a_dst,v_adj_dist, wuffs_base__slice_u8__subslice_i(a_workbuf, v_wb_index));
55550 v_len -= v_adj_dist;
55551 if ((((uint64_t)(v_len)) > ((uint64_t)(io2_a_dst - iop_a_dst))) || (((uint64_t)(v_dist)) > ((uint64_t)(iop_a_dst - io0_a_dst)))) {
55552 status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_dictionary_state);
55553 goto exit;
55556 v_match_cusp = wuffs_private_impl__io_writer__limited_copy_u32_from_history_fast_return_cusp(
55557 &iop_a_dst, io0_a_dst, io2_a_dst, v_len, v_dist);
55558 v_match_byte = (v_match_cusp >> 8u);
55559 v_prev_byte = ((uint8_t)(v_match_cusp));
55561 label__outer__break:;
55562 self->private_impl.f_stashed_bytes[0u] = v_prev_byte;
55563 self->private_impl.f_stashed_bytes[1u] = ((uint8_t)(v_match_byte));
55564 self->private_impl.f_stashed_bits = v_bits;
55565 self->private_impl.f_stashed_range = v_range;
55566 self->private_impl.f_stashed_state = v_state;
55567 self->private_impl.f_stashed_rep0 = v_rep0;
55568 self->private_impl.f_stashed_rep1 = v_rep1;
55569 self->private_impl.f_stashed_rep2 = v_rep2;
55570 self->private_impl.f_stashed_rep3 = v_rep3;
55571 self->private_impl.f_stashed_pos = v_pos;
55572 self->private_impl.f_stashed_pos_end = v_pos_end;
55575 self->private_impl.p_decode_bitstream_slow = 0;
55576 goto exit;
55579 goto suspend;
55580 suspend:
55581 self->private_impl.p_decode_bitstream_slow = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
55582 self->private_data.s_decode_bitstream_slow.v_bits = v_bits;
55583 self->private_data.s_decode_bitstream_slow.v_range = v_range;
55584 self->private_data.s_decode_bitstream_slow.v_state = v_state;
55585 self->private_data.s_decode_bitstream_slow.v_rep0 = v_rep0;
55586 self->private_data.s_decode_bitstream_slow.v_rep1 = v_rep1;
55587 self->private_data.s_decode_bitstream_slow.v_rep2 = v_rep2;
55588 self->private_data.s_decode_bitstream_slow.v_rep3 = v_rep3;
55589 self->private_data.s_decode_bitstream_slow.v_rep = v_rep;
55590 self->private_data.s_decode_bitstream_slow.v_pos = v_pos;
55591 self->private_data.s_decode_bitstream_slow.v_pos_end = v_pos_end;
55592 self->private_data.s_decode_bitstream_slow.v_lc = v_lc;
55593 self->private_data.s_decode_bitstream_slow.v_lp_mask = v_lp_mask;
55594 self->private_data.s_decode_bitstream_slow.v_pb_mask = v_pb_mask;
55595 self->private_data.s_decode_bitstream_slow.v_tree_node = v_tree_node;
55596 self->private_data.s_decode_bitstream_slow.v_prev_byte = v_prev_byte;
55597 self->private_data.s_decode_bitstream_slow.v_match_byte = v_match_byte;
55598 self->private_data.s_decode_bitstream_slow.v_len_state = v_len_state;
55599 self->private_data.s_decode_bitstream_slow.v_slot = v_slot;
55600 self->private_data.s_decode_bitstream_slow.v_len = v_len;
55601 self->private_data.s_decode_bitstream_slow.v_lanl_offset = v_lanl_offset;
55602 self->private_data.s_decode_bitstream_slow.v_num_extra_bits = v_num_extra_bits;
55603 self->private_data.s_decode_bitstream_slow.v_dist_extra_bits = v_dist_extra_bits;
55604 self->private_data.s_decode_bitstream_slow.v_i = v_i;
55605 self->private_data.s_decode_bitstream_slow.v_index_lit = v_index_lit;
55606 self->private_data.s_decode_bitstream_slow.v_index_len = v_index_len;
55607 self->private_data.s_decode_bitstream_slow.v_index_small_dist_base = v_index_small_dist_base;
55608 self->private_data.s_decode_bitstream_slow.v_index_small_dist_extra = v_index_small_dist_extra;
55609 self->private_data.s_decode_bitstream_slow.v_index_large_dist = v_index_large_dist;
55610 self->private_data.s_decode_bitstream_slow.v_dist = v_dist;
55612 goto exit;
55613 exit:
55614 if (a_dst && a_dst->data.ptr) {
55615 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
55617 if (a_src && a_src->data.ptr) {
55618 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
55621 return status;
55624 // -------- func lzma.decoder.add_history
55626 WUFFS_BASE__GENERATED_C_CODE
55627 static wuffs_base__status
55628 wuffs_lzma__decoder__add_history(
55629 wuffs_lzma__decoder* self,
55630 wuffs_base__slice_u8 a_hist,
55631 wuffs_base__slice_u8 a_workbuf) {
55632 uint64_t v_dict_workbuf_index = 0;
55633 uint64_t v_dict_size = 0;
55634 uint64_t v_hist_length = 0;
55635 wuffs_base__slice_u8 v_s = {0};
55636 uint64_t v_n_copied = 0;
55637 uint64_t v_n = 0;
55639 v_dict_workbuf_index = ((uint64_t)(self->private_impl.f_dict_workbuf_index));
55640 v_dict_size = ((uint64_t)(self->private_impl.f_dict_size));
55641 if (((uint64_t)(a_hist.len)) == 0u) {
55642 return wuffs_base__make_status(NULL);
55644 if (((uint64_t)(a_workbuf.len)) < (v_dict_size + 273u)) {
55645 return wuffs_base__make_status(wuffs_base__error__bad_workbuf_length);
55647 v_hist_length = ((uint64_t)(a_hist.len));
55648 if (v_hist_length > 4294967295u) {
55649 self->private_impl.f_dict_seen = 4294967295u;
55650 } else {
55651 wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_dict_seen, ((uint32_t)(v_hist_length)));
55653 v_s = a_hist;
55654 if (((uint64_t)(v_s.len)) >= v_dict_size) {
55655 v_s = wuffs_private_impl__slice_u8__suffix(v_s, v_dict_size);
55656 wuffs_private_impl__slice_u8__copy_from_slice(a_workbuf, v_s);
55657 self->private_impl.f_dict_workbuf_index = 0u;
55658 } else if (v_dict_workbuf_index > v_dict_size) {
55659 return wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_dictionary_state);
55660 } else {
55661 v_n_copied = wuffs_private_impl__slice_u8__copy_from_slice(wuffs_base__slice_u8__subslice_ij(a_workbuf, v_dict_workbuf_index, v_dict_size), v_s);
55662 if (v_n_copied < ((uint64_t)(v_s.len))) {
55663 v_n = wuffs_private_impl__slice_u8__copy_from_slice(a_workbuf, wuffs_base__slice_u8__subslice_i(v_s, v_n_copied));
55664 self->private_impl.f_dict_workbuf_index = ((uint32_t)(v_n));
55665 } else {
55666 v_n = ((uint64_t)(v_dict_workbuf_index + v_n_copied));
55667 if (v_n < v_dict_size) {
55668 self->private_impl.f_dict_workbuf_index = ((uint32_t)(v_n));
55669 } else {
55670 self->private_impl.f_dict_workbuf_index = 0u;
55674 if ((273u > v_dict_size) || (v_dict_size > ((uint64_t)(a_workbuf.len)))) {
55675 return wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_dictionary_state);
55677 wuffs_private_impl__slice_u8__copy_from_slice(wuffs_base__slice_u8__subslice_i(a_workbuf, v_dict_size), wuffs_base__slice_u8__subslice_j(a_workbuf, 273u));
55678 return wuffs_base__make_status(NULL);
55681 // -------- func lzma.decoder.get_quirk
55683 WUFFS_BASE__GENERATED_C_CODE
55684 WUFFS_BASE__MAYBE_STATIC uint64_t
55685 wuffs_lzma__decoder__get_quirk(
55686 const wuffs_lzma__decoder* self,
55687 uint32_t a_key) {
55688 if (!self) {
55689 return 0;
55691 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
55692 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
55693 return 0;
55696 if (a_key == 1348001792u) {
55697 if (self->private_impl.f_allow_non_zero_initial_byte) {
55698 return 1u;
55700 } else if (a_key == 1348001793u) {
55701 return ((uint64_t)(self->private_impl.f_format_extension));
55703 return 0u;
55706 // -------- func lzma.decoder.set_quirk
55708 WUFFS_BASE__GENERATED_C_CODE
55709 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
55710 wuffs_lzma__decoder__set_quirk(
55711 wuffs_lzma__decoder* self,
55712 uint32_t a_key,
55713 uint64_t a_value) {
55714 if (!self) {
55715 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
55717 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
55718 return wuffs_base__make_status(
55719 (self->private_impl.magic == WUFFS_BASE__DISABLED)
55720 ? wuffs_base__error__disabled_by_previous_error
55721 : wuffs_base__error__initialize_not_called);
55724 uint32_t v_v = 0;
55725 uint32_t v_n = 0;
55727 if (a_key == 1348001792u) {
55728 self->private_impl.f_allow_non_zero_initial_byte = (a_value > 0u);
55729 } else if (a_key == 1348001793u) {
55730 if (a_value == 0u) {
55731 self->private_impl.f_format_extension = 0u;
55732 return wuffs_base__make_status(NULL);
55733 } else if ((a_value & 255u) == 1u) {
55734 if ((a_value >> 8u) <= 255u) {
55735 self->private_impl.f_format_extension = ((uint32_t)(a_value));
55736 v_v = (self->private_impl.f_format_extension >> 8u);
55737 v_n = (((uint32_t)(1u)) << (v_v & 31u));
55738 wuffs_private_impl__u32__sat_sub_indirect(&v_n, ((v_n >> 4u) * ((v_v >> 5u) & 7u)));
55739 if ((v_n < 4096u) || (536870912u < v_n)) {
55740 return wuffs_base__make_status(wuffs_base__error__bad_argument);
55742 self->private_impl.f_dict_size = v_n;
55743 return wuffs_base__make_status(NULL);
55745 } else if ((a_value & 255u) == 2u) {
55746 if ((a_value >> 8u) <= 40u) {
55747 self->private_impl.f_format_extension = ((uint32_t)(a_value));
55748 v_v = (self->private_impl.f_format_extension >> 8u);
55749 if (v_v < 40u) {
55750 self->private_impl.f_dict_size = ((2u | (v_v & 1u)) << ((v_v >> 1u) + 11u));
55751 } else {
55752 self->private_impl.f_dict_size = 4294967295u;
55754 return wuffs_base__make_status(NULL);
55757 return wuffs_base__make_status(wuffs_base__error__bad_argument);
55759 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
55762 // -------- func lzma.decoder.dst_history_retain_length
55764 WUFFS_BASE__GENERATED_C_CODE
55765 WUFFS_BASE__MAYBE_STATIC wuffs_base__optional_u63
55766 wuffs_lzma__decoder__dst_history_retain_length(
55767 const wuffs_lzma__decoder* self) {
55768 if (!self) {
55769 return wuffs_base__utility__make_optional_u63(false, 0u);
55771 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
55772 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
55773 return wuffs_base__utility__make_optional_u63(false, 0u);
55776 return wuffs_base__utility__make_optional_u63(true, 0u);
55779 // -------- func lzma.decoder.workbuf_len
55781 WUFFS_BASE__GENERATED_C_CODE
55782 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
55783 wuffs_lzma__decoder__workbuf_len(
55784 const wuffs_lzma__decoder* self) {
55785 if (!self) {
55786 return wuffs_base__utility__empty_range_ii_u64();
55788 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
55789 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
55790 return wuffs_base__utility__empty_range_ii_u64();
55793 uint64_t v_m = 0;
55795 if (self->private_impl.f_dict_size == 0u) {
55796 return wuffs_base__utility__make_range_ii_u64(0u, 0u);
55798 v_m = (((uint64_t)(self->private_impl.f_dict_size)) + 273u);
55799 return wuffs_base__utility__make_range_ii_u64(v_m, v_m);
55802 // -------- func lzma.decoder.transform_io
55804 WUFFS_BASE__GENERATED_C_CODE
55805 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
55806 wuffs_lzma__decoder__transform_io(
55807 wuffs_lzma__decoder* self,
55808 wuffs_base__io_buffer* a_dst,
55809 wuffs_base__io_buffer* a_src,
55810 wuffs_base__slice_u8 a_workbuf) {
55811 if (!self) {
55812 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
55814 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
55815 return wuffs_base__make_status(
55816 (self->private_impl.magic == WUFFS_BASE__DISABLED)
55817 ? wuffs_base__error__disabled_by_previous_error
55818 : wuffs_base__error__initialize_not_called);
55820 if (!a_dst || !a_src) {
55821 self->private_impl.magic = WUFFS_BASE__DISABLED;
55822 return wuffs_base__make_status(wuffs_base__error__bad_argument);
55824 if ((self->private_impl.active_coroutine != 0) &&
55825 (self->private_impl.active_coroutine != 1)) {
55826 self->private_impl.magic = WUFFS_BASE__DISABLED;
55827 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
55829 self->private_impl.active_coroutine = 0;
55830 wuffs_base__status status = wuffs_base__make_status(NULL);
55832 uint64_t v_mark = 0;
55833 wuffs_base__status v_dti_status = wuffs_base__make_status(NULL);
55834 wuffs_base__status v_ah_status = wuffs_base__make_status(NULL);
55836 uint8_t* iop_a_dst = NULL;
55837 uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
55838 uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
55839 uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
55840 if (a_dst && a_dst->data.ptr) {
55841 io0_a_dst = a_dst->data.ptr;
55842 io1_a_dst = io0_a_dst + a_dst->meta.wi;
55843 iop_a_dst = io1_a_dst;
55844 io2_a_dst = io0_a_dst + a_dst->data.len;
55845 if (a_dst->meta.closed) {
55846 io2_a_dst = iop_a_dst;
55850 uint32_t coro_susp_point = self->private_impl.p_transform_io;
55851 switch (coro_susp_point) {
55852 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
55854 while (true) {
55855 v_mark = ((uint64_t)(iop_a_dst - io0_a_dst));
55857 if (a_dst) {
55858 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
55860 wuffs_base__status t_0 = wuffs_lzma__decoder__do_transform_io(self, a_dst, a_src, a_workbuf);
55861 v_dti_status = t_0;
55862 if (a_dst) {
55863 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
55866 if ( ! wuffs_base__status__is_suspension(&v_dti_status)) {
55867 status = v_dti_status;
55868 if (wuffs_base__status__is_error(&status)) {
55869 goto exit;
55870 } else if (wuffs_base__status__is_suspension(&status)) {
55871 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
55872 goto exit;
55874 goto ok;
55875 } else if ((v_dti_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
55876 status = wuffs_base__make_status(wuffs_lzma__error__truncated_input);
55877 goto exit;
55879 v_ah_status = wuffs_lzma__decoder__add_history(self, wuffs_private_impl__io__since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst), a_workbuf);
55880 if (wuffs_base__status__is_error(&v_ah_status)) {
55881 status = v_ah_status;
55882 goto exit;
55884 status = v_dti_status;
55885 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
55889 self->private_impl.p_transform_io = 0;
55890 goto exit;
55893 goto suspend;
55894 suspend:
55895 self->private_impl.p_transform_io = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
55896 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
55898 goto exit;
55899 exit:
55900 if (a_dst && a_dst->data.ptr) {
55901 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
55904 if (wuffs_base__status__is_error(&status)) {
55905 self->private_impl.magic = WUFFS_BASE__DISABLED;
55907 return status;
55910 // -------- func lzma.decoder.do_transform_io
55912 WUFFS_BASE__GENERATED_C_CODE
55913 static wuffs_base__status
55914 wuffs_lzma__decoder__do_transform_io(
55915 wuffs_lzma__decoder* self,
55916 wuffs_base__io_buffer* a_dst,
55917 wuffs_base__io_buffer* a_src,
55918 wuffs_base__slice_u8 a_workbuf) {
55919 wuffs_base__status status = wuffs_base__make_status(NULL);
55921 uint8_t v_header_byte = 0;
55922 uint8_t v_c8 = 0;
55923 uint32_t v_c32 = 0;
55924 uint8_t v_prop_byte = 0;
55925 uint32_t v_lc = 0;
55926 uint32_t v_lp = 0;
55927 uint32_t v_pb = 0;
55928 uint32_t v_length = 0;
55929 uint32_t v_n_copied = 0;
55930 uint64_t v_smark = 0;
55931 wuffs_base__status v_status = wuffs_base__make_status(NULL);
55933 uint8_t* iop_a_dst = NULL;
55934 uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
55935 uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
55936 uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
55937 if (a_dst && a_dst->data.ptr) {
55938 io0_a_dst = a_dst->data.ptr;
55939 io1_a_dst = io0_a_dst + a_dst->meta.wi;
55940 iop_a_dst = io1_a_dst;
55941 io2_a_dst = io0_a_dst + a_dst->data.len;
55942 if (a_dst->meta.closed) {
55943 io2_a_dst = iop_a_dst;
55946 const uint8_t* iop_a_src = NULL;
55947 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
55948 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
55949 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
55950 if (a_src && a_src->data.ptr) {
55951 io0_a_src = a_src->data.ptr;
55952 io1_a_src = io0_a_src + a_src->meta.ri;
55953 iop_a_src = io1_a_src;
55954 io2_a_src = io0_a_src + a_src->meta.wi;
55957 uint32_t coro_susp_point = self->private_impl.p_do_transform_io;
55958 if (coro_susp_point) {
55959 v_header_byte = self->private_data.s_do_transform_io.v_header_byte;
55960 v_length = self->private_data.s_do_transform_io.v_length;
55962 switch (coro_susp_point) {
55963 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
55965 self->private_impl.f_lzma2_need_prob_reset = true;
55966 self->private_impl.f_lzma2_need_properties = true;
55967 self->private_impl.f_lzma2_need_dict_reset = true;
55968 while (true) {
55969 if ((self->private_impl.f_format_extension & 255u) == 0u) {
55971 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
55972 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
55973 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
55974 goto suspend;
55976 uint8_t t_0 = *iop_a_src++;
55977 v_prop_byte = t_0;
55979 if (v_prop_byte >= 225u) {
55980 status = wuffs_base__make_status(wuffs_lzma__error__bad_header);
55981 goto exit;
55983 v_lc = ((uint32_t)(((uint8_t)(v_prop_byte % 9u))));
55984 #if defined(__GNUC__)
55985 #pragma GCC diagnostic push
55986 #pragma GCC diagnostic ignored "-Wconversion"
55987 #endif
55988 v_prop_byte /= 9u;
55989 #if defined(__GNUC__)
55990 #pragma GCC diagnostic pop
55991 #endif
55992 v_lp = ((uint32_t)(((uint8_t)(v_prop_byte % 5u))));
55993 v_pb = ((uint32_t)(((uint8_t)(v_prop_byte / 5u))));
55994 if ((v_lc + v_lp) > 4u) {
55995 status = wuffs_base__make_status(wuffs_lzma__error__unsupported_properties);
55996 goto exit;
55998 self->private_impl.f_lc = wuffs_base__u32__min(v_lc, 4u);
55999 self->private_impl.f_lp = v_lp;
56000 self->private_impl.f_pb = v_pb;
56002 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
56003 uint32_t t_1;
56004 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
56005 t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
56006 iop_a_src += 4;
56007 } else {
56008 self->private_data.s_do_transform_io.scratch = 0;
56009 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
56010 while (true) {
56011 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
56012 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
56013 goto suspend;
56015 uint64_t* scratch = &self->private_data.s_do_transform_io.scratch;
56016 uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
56017 *scratch <<= 8;
56018 *scratch >>= 8;
56019 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
56020 if (num_bits_1 == 24) {
56021 t_1 = ((uint32_t)(*scratch));
56022 break;
56024 num_bits_1 += 8u;
56025 *scratch |= ((uint64_t)(num_bits_1)) << 56;
56028 v_c32 = t_1;
56030 self->private_impl.f_dict_size = wuffs_base__u32__max(v_c32, 4096u);
56032 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
56033 uint64_t t_2;
56034 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 8)) {
56035 t_2 = wuffs_base__peek_u64le__no_bounds_check(iop_a_src);
56036 iop_a_src += 8;
56037 } else {
56038 self->private_data.s_do_transform_io.scratch = 0;
56039 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
56040 while (true) {
56041 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
56042 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
56043 goto suspend;
56045 uint64_t* scratch = &self->private_data.s_do_transform_io.scratch;
56046 uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
56047 *scratch <<= 8;
56048 *scratch >>= 8;
56049 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
56050 if (num_bits_2 == 56) {
56051 t_2 = ((uint64_t)(*scratch));
56052 break;
56054 num_bits_2 += 8u;
56055 *scratch |= ((uint64_t)(num_bits_2)) << 56;
56058 self->private_impl.f_decoded_length = t_2;
56060 if ((self->private_impl.f_decoded_length >= 9223372036854775808u) && (self->private_impl.f_decoded_length != 18446744073709551615u)) {
56061 status = wuffs_base__make_status(wuffs_lzma__error__unsupported_decoded_length);
56062 goto exit;
56064 wuffs_lzma__decoder__initialize_probs(self);
56065 } else if ((self->private_impl.f_format_extension & 255u) == 1u) {
56066 self->private_impl.f_lc = 3u;
56067 self->private_impl.f_lp = 0u;
56068 self->private_impl.f_pb = 2u;
56069 self->private_impl.f_decoded_length = 18446744073709551615u;
56070 wuffs_lzma__decoder__initialize_probs(self);
56071 } else {
56072 while (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
56073 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
56074 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
56076 if (wuffs_base__peek_u8be__no_bounds_check(iop_a_src) == 0u) {
56077 iop_a_src += 1u;
56078 break;
56081 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
56082 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
56083 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
56084 goto suspend;
56086 uint8_t t_3 = *iop_a_src++;
56087 v_header_byte = t_3;
56089 if (v_header_byte < 128u) {
56090 if (v_header_byte < 2u) {
56091 self->private_impl.f_lzma2_need_prob_reset = true;
56092 self->private_impl.f_lzma2_need_properties = true;
56093 self->private_impl.f_lzma2_need_dict_reset = false;
56094 wuffs_lzma__decoder__initialize_dict(self);
56095 } else if ((v_header_byte > 2u) || self->private_impl.f_lzma2_need_dict_reset) {
56096 status = wuffs_base__make_status(wuffs_lzma__error__bad_lzma2_header);
56097 goto exit;
56099 self->private_impl.f_prev_lzma2_chunk_was_uncompressed = true;
56101 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
56102 uint32_t t_4;
56103 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
56104 t_4 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
56105 iop_a_src += 2;
56106 } else {
56107 self->private_data.s_do_transform_io.scratch = 0;
56108 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
56109 while (true) {
56110 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
56111 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
56112 goto suspend;
56114 uint64_t* scratch = &self->private_data.s_do_transform_io.scratch;
56115 uint32_t num_bits_4 = ((uint32_t)(*scratch & 0xFFu));
56116 *scratch >>= 8;
56117 *scratch <<= 8;
56118 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_4);
56119 if (num_bits_4 == 8) {
56120 t_4 = ((uint32_t)(*scratch >> 48));
56121 break;
56123 num_bits_4 += 8u;
56124 *scratch |= ((uint64_t)(num_bits_4));
56127 v_c32 = t_4;
56129 v_length = (1u + v_c32);
56130 while (true) {
56131 v_n_copied = wuffs_private_impl__io_writer__limited_copy_u32_from_reader(
56132 &iop_a_dst, io2_a_dst,v_length, &iop_a_src, io2_a_src);
56133 wuffs_private_impl__u64__sat_add_indirect(&self->private_impl.f_stashed_pos, ((uint64_t)(v_n_copied)));
56134 if (v_length <= v_n_copied) {
56135 break;
56137 v_length -= v_n_copied;
56138 if (((uint64_t)(io2_a_dst - iop_a_dst)) == 0u) {
56139 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
56140 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10);
56141 } else {
56142 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
56143 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(11);
56146 continue;
56148 self->private_impl.f_decoded_length = ((uint64_t)(v_header_byte));
56150 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
56151 uint32_t t_5;
56152 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
56153 t_5 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
56154 iop_a_src += 2;
56155 } else {
56156 self->private_data.s_do_transform_io.scratch = 0;
56157 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
56158 while (true) {
56159 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
56160 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
56161 goto suspend;
56163 uint64_t* scratch = &self->private_data.s_do_transform_io.scratch;
56164 uint32_t num_bits_5 = ((uint32_t)(*scratch & 0xFFu));
56165 *scratch >>= 8;
56166 *scratch <<= 8;
56167 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_5);
56168 if (num_bits_5 == 8) {
56169 t_5 = ((uint32_t)(*scratch >> 48));
56170 break;
56172 num_bits_5 += 8u;
56173 *scratch |= ((uint64_t)(num_bits_5));
56176 v_c32 = t_5;
56178 self->private_impl.f_decoded_length = (((self->private_impl.f_decoded_length & 31u) << 16u) + ((uint64_t)((1u + v_c32))));
56180 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
56181 uint32_t t_6;
56182 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
56183 t_6 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
56184 iop_a_src += 2;
56185 } else {
56186 self->private_data.s_do_transform_io.scratch = 0;
56187 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
56188 while (true) {
56189 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
56190 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
56191 goto suspend;
56193 uint64_t* scratch = &self->private_data.s_do_transform_io.scratch;
56194 uint32_t num_bits_6 = ((uint32_t)(*scratch & 0xFFu));
56195 *scratch >>= 8;
56196 *scratch <<= 8;
56197 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_6);
56198 if (num_bits_6 == 8) {
56199 t_6 = ((uint32_t)(*scratch >> 48));
56200 break;
56202 num_bits_6 += 8u;
56203 *scratch |= ((uint64_t)(num_bits_6));
56206 v_c32 = t_6;
56208 self->private_impl.f_lzma2_encoded_length_want = ((uint64_t)((1u + v_c32)));
56209 if (v_header_byte >= 160u) {
56210 wuffs_lzma__decoder__initialize_probs(self);
56211 self->private_impl.f_lzma2_need_prob_reset = false;
56213 if (v_header_byte >= 192u) {
56215 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
56216 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
56217 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
56218 goto suspend;
56220 uint8_t t_7 = *iop_a_src++;
56221 v_prop_byte = t_7;
56223 if (v_prop_byte >= 225u) {
56224 status = wuffs_base__make_status(wuffs_lzma__error__bad_lzma2_header);
56225 goto exit;
56227 v_lc = ((uint32_t)(((uint8_t)(v_prop_byte % 9u))));
56228 #if defined(__GNUC__)
56229 #pragma GCC diagnostic push
56230 #pragma GCC diagnostic ignored "-Wconversion"
56231 #endif
56232 v_prop_byte /= 9u;
56233 #if defined(__GNUC__)
56234 #pragma GCC diagnostic pop
56235 #endif
56236 v_lp = ((uint32_t)(((uint8_t)(v_prop_byte % 5u))));
56237 v_pb = ((uint32_t)(((uint8_t)(v_prop_byte / 5u))));
56238 if ((v_lc + v_lp) > 4u) {
56239 status = wuffs_base__make_status(wuffs_lzma__error__bad_lzma2_header);
56240 goto exit;
56242 self->private_impl.f_lc = wuffs_base__u32__min(v_lc, 4u);
56243 self->private_impl.f_lp = v_lp;
56244 self->private_impl.f_pb = v_pb;
56245 self->private_impl.f_lzma2_need_properties = false;
56247 if (v_header_byte >= 224u) {
56248 self->private_impl.f_lzma2_need_dict_reset = false;
56249 wuffs_lzma__decoder__initialize_dict(self);
56250 } else if (self->private_impl.f_prev_lzma2_chunk_was_uncompressed) {
56251 if (a_dst) {
56252 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
56254 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(17);
56255 status = wuffs_lzma__decoder__update_stashed_bytes(self, a_dst, a_workbuf);
56256 if (a_dst) {
56257 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
56259 if (status.repr) {
56260 goto suspend;
56263 self->private_impl.f_prev_lzma2_chunk_was_uncompressed = false;
56264 if (self->private_impl.f_lzma2_need_prob_reset || self->private_impl.f_lzma2_need_properties || self->private_impl.f_lzma2_need_dict_reset) {
56265 status = wuffs_base__make_status(wuffs_lzma__error__bad_lzma2_header);
56266 goto exit;
56270 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(18);
56271 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
56272 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
56273 goto suspend;
56275 uint8_t t_8 = *iop_a_src++;
56276 v_c8 = t_8;
56278 if ((v_c8 != 0u) && ! self->private_impl.f_allow_non_zero_initial_byte) {
56279 status = wuffs_base__make_status(wuffs_lzma__error__bad_code);
56280 goto exit;
56283 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(19);
56284 uint32_t t_9;
56285 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
56286 t_9 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
56287 iop_a_src += 4;
56288 } else {
56289 self->private_data.s_do_transform_io.scratch = 0;
56290 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(20);
56291 while (true) {
56292 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
56293 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
56294 goto suspend;
56296 uint64_t* scratch = &self->private_data.s_do_transform_io.scratch;
56297 uint32_t num_bits_9 = ((uint32_t)(*scratch & 0xFFu));
56298 *scratch >>= 8;
56299 *scratch <<= 8;
56300 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_9);
56301 if (num_bits_9 == 24) {
56302 t_9 = ((uint32_t)(*scratch >> 32));
56303 break;
56305 num_bits_9 += 8u;
56306 *scratch |= ((uint64_t)(num_bits_9));
56309 self->private_impl.f_stashed_bits = t_9;
56311 if (self->private_impl.f_stashed_bits == 4294967295u) {
56312 status = wuffs_base__make_status(wuffs_lzma__error__bad_code);
56313 goto exit;
56315 self->private_impl.f_stashed_range = 4294967295u;
56316 self->private_impl.f_stashed_pos_end = wuffs_base__u64__sat_add(self->private_impl.f_stashed_pos, self->private_impl.f_decoded_length);
56317 if ((self->private_impl.f_stashed_pos_end == 18446744073709551615u) && (self->private_impl.f_decoded_length != 18446744073709551615u)) {
56318 status = wuffs_base__make_status(wuffs_lzma__error__unsupported_decoded_length);
56319 goto exit;
56321 self->private_impl.f_lzma2_encoded_length_have = 5u;
56322 while (((uint64_t)(a_workbuf.len)) < (((uint64_t)(self->private_impl.f_dict_size)) + 273u)) {
56323 status = wuffs_base__make_status(wuffs_base__suspension__short_workbuf);
56324 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(21);
56326 while (true) {
56327 v_smark = ((uint64_t)(iop_a_src - io0_a_src));
56329 if (a_dst) {
56330 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
56332 if (a_src) {
56333 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
56335 wuffs_base__status t_10 = wuffs_lzma__decoder__decode_bitstream(self, a_dst, a_src, a_workbuf);
56336 v_status = t_10;
56337 if (a_dst) {
56338 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
56340 if (a_src) {
56341 iop_a_src = a_src->data.ptr + a_src->meta.ri;
56344 wuffs_private_impl__u64__sat_add_indirect(&self->private_impl.f_lzma2_encoded_length_have, wuffs_private_impl__io__count_since(v_smark, ((uint64_t)(iop_a_src - io0_a_src))));
56345 if (wuffs_base__status__is_ok(&v_status)) {
56346 break;
56348 status = v_status;
56349 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(22);
56351 if (self->private_impl.f_decoded_length == 18446744073709551615u) {
56352 if (self->private_impl.f_stashed_bits != 0u) {
56353 status = wuffs_base__make_status(wuffs_lzma__error__bad_bitstream_trailer);
56354 goto exit;
56356 } else if (self->private_impl.f_stashed_pos != self->private_impl.f_stashed_pos_end) {
56357 status = wuffs_base__make_status(wuffs_lzma__error__bad_decoded_length);
56358 goto exit;
56359 } else if (self->private_impl.f_stashed_bits != 0u) {
56360 if (a_src) {
56361 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
56363 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(23);
56364 status = wuffs_lzma__decoder__decode_optional_end_of_stream(self, a_src, a_workbuf);
56365 if (a_src) {
56366 iop_a_src = a_src->data.ptr + a_src->meta.ri;
56368 if (status.repr) {
56369 goto suspend;
56371 if (self->private_impl.f_stashed_bits != 0u) {
56372 status = wuffs_base__make_status(wuffs_lzma__error__bad_bitstream_trailer);
56373 goto exit;
56376 if ((self->private_impl.f_format_extension & 255u) < 2u) {
56377 break;
56378 } else if (self->private_impl.f_lzma2_encoded_length_have != self->private_impl.f_lzma2_encoded_length_want) {
56379 status = wuffs_base__make_status(wuffs_lzma__error__bad_lzma2_header);
56380 goto exit;
56385 self->private_impl.p_do_transform_io = 0;
56386 goto exit;
56389 goto suspend;
56390 suspend:
56391 self->private_impl.p_do_transform_io = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
56392 self->private_data.s_do_transform_io.v_header_byte = v_header_byte;
56393 self->private_data.s_do_transform_io.v_length = v_length;
56395 goto exit;
56396 exit:
56397 if (a_dst && a_dst->data.ptr) {
56398 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
56400 if (a_src && a_src->data.ptr) {
56401 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
56404 return status;
56407 // -------- func lzma.decoder.decode_bitstream
56409 WUFFS_BASE__GENERATED_C_CODE
56410 static wuffs_base__status
56411 wuffs_lzma__decoder__decode_bitstream(
56412 wuffs_lzma__decoder* self,
56413 wuffs_base__io_buffer* a_dst,
56414 wuffs_base__io_buffer* a_src,
56415 wuffs_base__slice_u8 a_workbuf) {
56416 wuffs_base__status status = wuffs_base__make_status(NULL);
56418 wuffs_base__status v_status = wuffs_base__make_status(NULL);
56420 uint32_t coro_susp_point = self->private_impl.p_decode_bitstream;
56421 switch (coro_susp_point) {
56422 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
56424 self->private_impl.f_end_of_chunk = false;
56425 while (true) {
56426 v_status = wuffs_lzma__decoder__decode_bitstream_fast(self, a_dst, a_src, a_workbuf);
56427 if (wuffs_base__status__is_error(&v_status)) {
56428 status = v_status;
56429 goto exit;
56431 if (self->private_impl.f_end_of_chunk) {
56432 break;
56434 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
56435 status = wuffs_lzma__decoder__decode_bitstream_slow(self, a_dst, a_src, a_workbuf);
56436 if (status.repr) {
56437 goto suspend;
56439 if (self->private_impl.f_end_of_chunk) {
56440 break;
56444 goto ok;
56446 self->private_impl.p_decode_bitstream = 0;
56447 goto exit;
56450 goto suspend;
56451 suspend:
56452 self->private_impl.p_decode_bitstream = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
56454 goto exit;
56455 exit:
56456 return status;
56459 // -------- func lzma.decoder.update_stashed_bytes
56461 WUFFS_BASE__GENERATED_C_CODE
56462 static wuffs_base__status
56463 wuffs_lzma__decoder__update_stashed_bytes(
56464 wuffs_lzma__decoder* self,
56465 wuffs_base__io_buffer* a_dst,
56466 wuffs_base__slice_u8 a_workbuf) {
56467 wuffs_base__status status = wuffs_base__make_status(NULL);
56469 uint32_t v_dist = 0;
56470 uint32_t v_which = 0;
56471 uint32_t v_adj_dist = 0;
56472 uint64_t v_wb_index = 0;
56474 uint8_t* iop_a_dst = NULL;
56475 uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
56476 uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
56477 uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
56478 if (a_dst && a_dst->data.ptr) {
56479 io0_a_dst = a_dst->data.ptr;
56480 io1_a_dst = io0_a_dst + a_dst->meta.wi;
56481 iop_a_dst = io1_a_dst;
56482 io2_a_dst = io0_a_dst + a_dst->data.len;
56483 if (a_dst->meta.closed) {
56484 io2_a_dst = iop_a_dst;
56488 uint32_t coro_susp_point = self->private_impl.p_update_stashed_bytes;
56489 switch (coro_susp_point) {
56490 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
56492 while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
56493 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
56494 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
56496 v_dist = 1u;
56497 v_which = 0u;
56498 while (v_which < 2u) {
56499 if (((uint64_t)(v_dist)) <= ((uint64_t)(iop_a_dst - io0_a_dst))) {
56500 wuffs_private_impl__io_writer__limited_copy_u32_from_history(
56501 &iop_a_dst, io0_a_dst, io2_a_dst, 1u, v_dist);
56502 if ( ! (iop_a_dst > io1_a_dst)) {
56503 status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_dictionary_state);
56504 goto exit;
56506 self->private_impl.f_stashed_bytes[v_which] = iop_a_dst[-1];
56507 iop_a_dst--;
56508 } else {
56509 v_adj_dist = ((uint32_t)((((uint64_t)(v_dist)) - ((uint64_t)(iop_a_dst - io0_a_dst)))));
56510 v_wb_index = ((uint64_t)(((uint64_t)(self->private_impl.f_dict_workbuf_index)) - ((uint64_t)(v_adj_dist))));
56511 while (v_wb_index >= 9223372036854775808u) {
56512 v_wb_index += ((uint64_t)(self->private_impl.f_dict_size));
56514 if (v_wb_index >= ((uint64_t)(a_workbuf.len))) {
56515 status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_dictionary_state);
56516 goto exit;
56518 self->private_impl.f_stashed_bytes[v_which] = a_workbuf.ptr[v_wb_index];
56520 v_dist = (1u + self->private_impl.f_stashed_rep0);
56521 v_which += 1u;
56525 self->private_impl.p_update_stashed_bytes = 0;
56526 goto exit;
56529 goto suspend;
56530 suspend:
56531 self->private_impl.p_update_stashed_bytes = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
56533 goto exit;
56534 exit:
56535 if (a_dst && a_dst->data.ptr) {
56536 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
56539 return status;
56542 // -------- func lzma.decoder.decode_optional_end_of_stream
56544 WUFFS_BASE__GENERATED_C_CODE
56545 static wuffs_base__status
56546 wuffs_lzma__decoder__decode_optional_end_of_stream(
56547 wuffs_lzma__decoder* self,
56548 wuffs_base__io_buffer* a_src,
56549 wuffs_base__slice_u8 a_workbuf) {
56550 wuffs_base__status status = wuffs_base__make_status(NULL);
56552 wuffs_base__io_buffer u_w = wuffs_base__empty_io_buffer();
56553 wuffs_base__io_buffer* v_w = &u_w;
56554 uint8_t* iop_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
56555 uint8_t* io0_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
56556 uint8_t* io1_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
56557 uint8_t* io2_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
56558 wuffs_base__status v_status = wuffs_base__make_status(NULL);
56560 uint32_t coro_susp_point = self->private_impl.p_decode_optional_end_of_stream;
56561 switch (coro_susp_point) {
56562 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
56564 self->private_impl.f_stashed_pos_end = 18446744073709551615u;
56565 while (true) {
56567 wuffs_base__io_buffer* o_0_v_w = v_w;
56568 uint8_t* o_0_iop_v_w = iop_v_w;
56569 uint8_t* o_0_io0_v_w = io0_v_w;
56570 uint8_t* o_0_io1_v_w = io1_v_w;
56571 uint8_t* o_0_io2_v_w = io2_v_w;
56572 v_w = wuffs_private_impl__io_writer__set(
56573 &u_w,
56574 &iop_v_w,
56575 &io0_v_w,
56576 &io1_v_w,
56577 &io2_v_w,
56578 wuffs_base__utility__empty_slice_u8(),
56579 0u);
56581 wuffs_base__status t_0 = wuffs_lzma__decoder__decode_bitstream_slow(self, v_w, a_src, a_workbuf);
56582 v_status = t_0;
56584 v_w = o_0_v_w;
56585 iop_v_w = o_0_iop_v_w;
56586 io0_v_w = o_0_io0_v_w;
56587 io1_v_w = o_0_io1_v_w;
56588 io2_v_w = o_0_io2_v_w;
56590 if (wuffs_base__status__is_ok(&v_status)) {
56591 break;
56592 } else if (v_status.repr == wuffs_base__suspension__short_write) {
56593 status = wuffs_base__make_status(wuffs_lzma__error__bad_bitstream_trailer);
56594 goto exit;
56596 status = v_status;
56597 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
56599 self->private_impl.f_stashed_pos_end = self->private_impl.f_stashed_pos;
56602 self->private_impl.p_decode_optional_end_of_stream = 0;
56603 goto exit;
56606 goto suspend;
56607 suspend:
56608 self->private_impl.p_decode_optional_end_of_stream = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
56610 goto exit;
56611 exit:
56612 return status;
56615 // -------- func lzma.decoder.initialize_dict
56617 WUFFS_BASE__GENERATED_C_CODE
56618 static wuffs_base__empty_struct
56619 wuffs_lzma__decoder__initialize_dict(
56620 wuffs_lzma__decoder* self) {
56621 self->private_impl.f_dict_workbuf_index = 0u;
56622 self->private_impl.f_dict_seen = 0u;
56623 self->private_impl.f_stashed_bytes[0u] = 0u;
56624 self->private_impl.f_stashed_bytes[1u] = 0u;
56625 self->private_impl.f_stashed_pos = 0u;
56626 return wuffs_base__make_empty_struct();
56629 // -------- func lzma.decoder.initialize_probs
56631 WUFFS_BASE__GENERATED_C_CODE
56632 static wuffs_base__empty_struct
56633 wuffs_lzma__decoder__initialize_probs(
56634 wuffs_lzma__decoder* self) {
56635 uint32_t v_i = 0;
56636 uint32_t v_j = 0;
56638 v_i = 0u;
56639 while (v_i < 192u) {
56640 self->private_data.f_probs_ao00[v_i] = 1024u;
56641 v_i += 1u;
56643 v_i = 0u;
56644 while (v_i < 12u) {
56645 self->private_data.f_probs_ao20[v_i] = 1024u;
56646 v_i += 1u;
56648 v_i = 0u;
56649 while (v_i < 12u) {
56650 self->private_data.f_probs_ao40[v_i] = 1024u;
56651 v_i += 1u;
56653 v_i = 0u;
56654 while (v_i < 192u) {
56655 self->private_data.f_probs_ao41[v_i] = 1024u;
56656 v_i += 1u;
56658 v_i = 0u;
56659 while (v_i < 12u) {
56660 self->private_data.f_probs_ao60[v_i] = 1024u;
56661 v_i += 1u;
56663 v_i = 0u;
56664 while (v_i < 12u) {
56665 self->private_data.f_probs_ao63[v_i] = 1024u;
56666 v_i += 1u;
56668 v_i = 0u;
56669 while (v_i < 16u) {
56670 v_j = 0u;
56671 while (v_j < 8u) {
56672 self->private_data.f_probs_match_len_low[v_i][v_j] = 1024u;
56673 v_j += 1u;
56675 v_i += 1u;
56677 v_i = 0u;
56678 while (v_i < 16u) {
56679 v_j = 0u;
56680 while (v_j < 8u) {
56681 self->private_data.f_probs_match_len_mid[v_i][v_j] = 1024u;
56682 v_j += 1u;
56684 v_i += 1u;
56686 v_i = 0u;
56687 while (v_i < 256u) {
56688 self->private_data.f_probs_match_len_high[0u][v_i] = 1024u;
56689 v_i += 1u;
56691 v_i = 0u;
56692 while (v_i < 16u) {
56693 v_j = 0u;
56694 while (v_j < 8u) {
56695 self->private_data.f_probs_longrep_len_low[v_i][v_j] = 1024u;
56696 v_j += 1u;
56698 v_i += 1u;
56700 v_i = 0u;
56701 while (v_i < 16u) {
56702 v_j = 0u;
56703 while (v_j < 8u) {
56704 self->private_data.f_probs_longrep_len_mid[v_i][v_j] = 1024u;
56705 v_j += 1u;
56707 v_i += 1u;
56709 v_i = 0u;
56710 while (v_i < 256u) {
56711 self->private_data.f_probs_longrep_len_high[0u][v_i] = 1024u;
56712 v_i += 1u;
56714 v_i = 0u;
56715 while (v_i < 4u) {
56716 v_j = 0u;
56717 while (v_j < 64u) {
56718 self->private_data.f_probs_slot[v_i][v_j] = 1024u;
56719 v_j += 1u;
56721 v_i += 1u;
56723 v_i = 0u;
56724 while (v_i < 128u) {
56725 self->private_data.f_probs_small_dist[v_i] = 1024u;
56726 v_i += 1u;
56728 v_i = 0u;
56729 while (v_i < 16u) {
56730 self->private_data.f_probs_large_dist[v_i] = 1024u;
56731 v_i += 1u;
56733 v_i = 0u;
56734 while (v_i < 16u) {
56735 v_j = 0u;
56736 while (v_j < 768u) {
56737 self->private_data.f_probs_lit[v_i][v_j] = 1024u;
56738 v_j += 1u;
56740 v_i += 1u;
56742 self->private_impl.f_stashed_state = 0u;
56743 self->private_impl.f_stashed_rep0 = 0u;
56744 self->private_impl.f_stashed_rep1 = 0u;
56745 self->private_impl.f_stashed_rep2 = 0u;
56746 self->private_impl.f_stashed_rep3 = 0u;
56747 return wuffs_base__make_empty_struct();
56750 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZMA)
56752 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZIP)
56754 // ---------------- Status Codes Implementations
56756 const char wuffs_lzip__error__bad_checksum[] = "#lzip: bad checksum";
56757 const char wuffs_lzip__error__bad_footer[] = "#lzip: bad footer";
56758 const char wuffs_lzip__error__bad_header[] = "#lzip: bad header";
56759 const char wuffs_lzip__error__truncated_input[] = "#lzip: truncated input";
56761 // ---------------- Private Consts
56763 // ---------------- Private Initializer Prototypes
56765 // ---------------- Private Function Prototypes
56767 WUFFS_BASE__GENERATED_C_CODE
56768 static wuffs_base__status
56769 wuffs_lzip__decoder__do_transform_io(
56770 wuffs_lzip__decoder* self,
56771 wuffs_base__io_buffer* a_dst,
56772 wuffs_base__io_buffer* a_src,
56773 wuffs_base__slice_u8 a_workbuf);
56775 // ---------------- VTables
56777 const wuffs_base__io_transformer__func_ptrs
56778 wuffs_lzip__decoder__func_ptrs_for__wuffs_base__io_transformer = {
56779 (wuffs_base__optional_u63(*)(const void*))(&wuffs_lzip__decoder__dst_history_retain_length),
56780 (uint64_t(*)(const void*,
56781 uint32_t))(&wuffs_lzip__decoder__get_quirk),
56782 (wuffs_base__status(*)(void*,
56783 uint32_t,
56784 uint64_t))(&wuffs_lzip__decoder__set_quirk),
56785 (wuffs_base__status(*)(void*,
56786 wuffs_base__io_buffer*,
56787 wuffs_base__io_buffer*,
56788 wuffs_base__slice_u8))(&wuffs_lzip__decoder__transform_io),
56789 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_lzip__decoder__workbuf_len),
56792 // ---------------- Initializer Implementations
56794 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
56795 wuffs_lzip__decoder__initialize(
56796 wuffs_lzip__decoder* self,
56797 size_t sizeof_star_self,
56798 uint64_t wuffs_version,
56799 uint32_t options){
56800 if (!self) {
56801 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
56803 if (sizeof(*self) != sizeof_star_self) {
56804 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
56806 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
56807 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
56808 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
56811 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
56812 // The whole point of this if-check is to detect an uninitialized *self.
56813 // We disable the warning on GCC. Clang-5.0 does not have this warning.
56814 #if !defined(__clang__) && defined(__GNUC__)
56815 #pragma GCC diagnostic push
56816 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
56817 #endif
56818 if (self->private_impl.magic != 0) {
56819 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
56821 #if !defined(__clang__) && defined(__GNUC__)
56822 #pragma GCC diagnostic pop
56823 #endif
56824 } else {
56825 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
56826 memset(self, 0, sizeof(*self));
56827 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
56828 } else {
56829 memset(&(self->private_impl), 0, sizeof(self->private_impl));
56834 wuffs_base__status z = wuffs_crc32__ieee_hasher__initialize(
56835 &self->private_data.f_crc32, sizeof(self->private_data.f_crc32), WUFFS_VERSION, options);
56836 if (z.repr) {
56837 return z;
56841 wuffs_base__status z = wuffs_lzma__decoder__initialize(
56842 &self->private_data.f_lzma, sizeof(self->private_data.f_lzma), WUFFS_VERSION, options);
56843 if (z.repr) {
56844 return z;
56847 self->private_impl.magic = WUFFS_BASE__MAGIC;
56848 self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name =
56849 wuffs_base__io_transformer__vtable_name;
56850 self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers =
56851 (const void*)(&wuffs_lzip__decoder__func_ptrs_for__wuffs_base__io_transformer);
56852 return wuffs_base__make_status(NULL);
56855 wuffs_lzip__decoder*
56856 wuffs_lzip__decoder__alloc(void) {
56857 wuffs_lzip__decoder* x =
56858 (wuffs_lzip__decoder*)(calloc(1, sizeof(wuffs_lzip__decoder)));
56859 if (!x) {
56860 return NULL;
56862 if (wuffs_lzip__decoder__initialize(
56863 x, sizeof(wuffs_lzip__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
56864 free(x);
56865 return NULL;
56867 return x;
56870 size_t
56871 sizeof__wuffs_lzip__decoder(void) {
56872 return sizeof(wuffs_lzip__decoder);
56875 // ---------------- Function Implementations
56877 // -------- func lzip.decoder.get_quirk
56879 WUFFS_BASE__GENERATED_C_CODE
56880 WUFFS_BASE__MAYBE_STATIC uint64_t
56881 wuffs_lzip__decoder__get_quirk(
56882 const wuffs_lzip__decoder* self,
56883 uint32_t a_key) {
56884 if (!self) {
56885 return 0;
56887 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
56888 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
56889 return 0;
56892 if ((a_key == 1u) && self->private_impl.f_ignore_checksum) {
56893 return 1u;
56895 return 0u;
56898 // -------- func lzip.decoder.set_quirk
56900 WUFFS_BASE__GENERATED_C_CODE
56901 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
56902 wuffs_lzip__decoder__set_quirk(
56903 wuffs_lzip__decoder* self,
56904 uint32_t a_key,
56905 uint64_t a_value) {
56906 if (!self) {
56907 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
56909 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
56910 return wuffs_base__make_status(
56911 (self->private_impl.magic == WUFFS_BASE__DISABLED)
56912 ? wuffs_base__error__disabled_by_previous_error
56913 : wuffs_base__error__initialize_not_called);
56916 if (a_key == 1u) {
56917 self->private_impl.f_ignore_checksum = (a_value > 0u);
56918 return wuffs_base__make_status(NULL);
56920 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
56923 // -------- func lzip.decoder.dst_history_retain_length
56925 WUFFS_BASE__GENERATED_C_CODE
56926 WUFFS_BASE__MAYBE_STATIC wuffs_base__optional_u63
56927 wuffs_lzip__decoder__dst_history_retain_length(
56928 const wuffs_lzip__decoder* self) {
56929 if (!self) {
56930 return wuffs_base__utility__make_optional_u63(false, 0u);
56932 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
56933 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
56934 return wuffs_base__utility__make_optional_u63(false, 0u);
56937 return wuffs_lzma__decoder__dst_history_retain_length(&self->private_data.f_lzma);
56940 // -------- func lzip.decoder.workbuf_len
56942 WUFFS_BASE__GENERATED_C_CODE
56943 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
56944 wuffs_lzip__decoder__workbuf_len(
56945 const wuffs_lzip__decoder* self) {
56946 if (!self) {
56947 return wuffs_base__utility__empty_range_ii_u64();
56949 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
56950 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
56951 return wuffs_base__utility__empty_range_ii_u64();
56954 return wuffs_lzma__decoder__workbuf_len(&self->private_data.f_lzma);
56957 // -------- func lzip.decoder.transform_io
56959 WUFFS_BASE__GENERATED_C_CODE
56960 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
56961 wuffs_lzip__decoder__transform_io(
56962 wuffs_lzip__decoder* self,
56963 wuffs_base__io_buffer* a_dst,
56964 wuffs_base__io_buffer* a_src,
56965 wuffs_base__slice_u8 a_workbuf) {
56966 if (!self) {
56967 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
56969 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
56970 return wuffs_base__make_status(
56971 (self->private_impl.magic == WUFFS_BASE__DISABLED)
56972 ? wuffs_base__error__disabled_by_previous_error
56973 : wuffs_base__error__initialize_not_called);
56975 if (!a_dst || !a_src) {
56976 self->private_impl.magic = WUFFS_BASE__DISABLED;
56977 return wuffs_base__make_status(wuffs_base__error__bad_argument);
56979 if ((self->private_impl.active_coroutine != 0) &&
56980 (self->private_impl.active_coroutine != 1)) {
56981 self->private_impl.magic = WUFFS_BASE__DISABLED;
56982 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
56984 self->private_impl.active_coroutine = 0;
56985 wuffs_base__status status = wuffs_base__make_status(NULL);
56987 wuffs_base__status v_status = wuffs_base__make_status(NULL);
56989 uint32_t coro_susp_point = self->private_impl.p_transform_io;
56990 switch (coro_susp_point) {
56991 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
56993 while (true) {
56995 wuffs_base__status t_0 = wuffs_lzip__decoder__do_transform_io(self, a_dst, a_src, a_workbuf);
56996 v_status = t_0;
56998 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
56999 status = wuffs_base__make_status(wuffs_lzip__error__truncated_input);
57000 goto exit;
57002 status = v_status;
57003 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
57007 self->private_impl.p_transform_io = 0;
57008 goto exit;
57011 goto suspend;
57012 suspend:
57013 self->private_impl.p_transform_io = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
57014 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
57016 goto exit;
57017 exit:
57018 if (wuffs_base__status__is_error(&status)) {
57019 self->private_impl.magic = WUFFS_BASE__DISABLED;
57021 return status;
57024 // -------- func lzip.decoder.do_transform_io
57026 WUFFS_BASE__GENERATED_C_CODE
57027 static wuffs_base__status
57028 wuffs_lzip__decoder__do_transform_io(
57029 wuffs_lzip__decoder* self,
57030 wuffs_base__io_buffer* a_dst,
57031 wuffs_base__io_buffer* a_src,
57032 wuffs_base__slice_u8 a_workbuf) {
57033 wuffs_base__status status = wuffs_base__make_status(NULL);
57035 uint8_t v_c8 = 0;
57036 uint32_t v_c32 = 0;
57037 uint64_t v_c64 = 0;
57038 uint64_t v_dmark = 0;
57039 uint64_t v_smark = 0;
57040 wuffs_base__status v_status = wuffs_base__make_status(NULL);
57041 uint32_t v_checksum_want = 0;
57042 uint32_t v_checksum_have = 0;
57043 uint64_t v_size_want = 0;
57045 uint8_t* iop_a_dst = NULL;
57046 uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
57047 uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
57048 uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
57049 if (a_dst && a_dst->data.ptr) {
57050 io0_a_dst = a_dst->data.ptr;
57051 io1_a_dst = io0_a_dst + a_dst->meta.wi;
57052 iop_a_dst = io1_a_dst;
57053 io2_a_dst = io0_a_dst + a_dst->data.len;
57054 if (a_dst->meta.closed) {
57055 io2_a_dst = iop_a_dst;
57058 const uint8_t* iop_a_src = NULL;
57059 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
57060 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
57061 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
57062 if (a_src && a_src->data.ptr) {
57063 io0_a_src = a_src->data.ptr;
57064 io1_a_src = io0_a_src + a_src->meta.ri;
57065 iop_a_src = io1_a_src;
57066 io2_a_src = io0_a_src + a_src->meta.wi;
57069 uint32_t coro_susp_point = self->private_impl.p_do_transform_io;
57070 switch (coro_susp_point) {
57071 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
57073 while (true) {
57075 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
57076 uint64_t t_0;
57077 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 5)) {
57078 t_0 = ((uint64_t)(wuffs_base__peek_u40le__no_bounds_check(iop_a_src)));
57079 iop_a_src += 5;
57080 } else {
57081 self->private_data.s_do_transform_io.scratch = 0;
57082 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
57083 while (true) {
57084 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
57085 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
57086 goto suspend;
57088 uint64_t* scratch = &self->private_data.s_do_transform_io.scratch;
57089 uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
57090 *scratch <<= 8;
57091 *scratch >>= 8;
57092 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
57093 if (num_bits_0 == 32) {
57094 t_0 = ((uint64_t)(*scratch));
57095 break;
57097 num_bits_0 += 8u;
57098 *scratch |= ((uint64_t)(num_bits_0)) << 56;
57101 v_c64 = t_0;
57103 if (v_c64 != 5641951820u) {
57104 status = wuffs_base__make_status(wuffs_lzip__error__bad_header);
57105 goto exit;
57108 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
57109 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
57110 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
57111 goto suspend;
57113 uint8_t t_1 = *iop_a_src++;
57114 v_c8 = t_1;
57116 v_status = wuffs_lzma__decoder__set_quirk(&self->private_data.f_lzma, 1348001793u, (1u | (((uint64_t)(v_c8)) << 8u)));
57117 if ( ! wuffs_base__status__is_ok(&v_status)) {
57118 if (v_status.repr == wuffs_base__error__bad_argument) {
57119 status = wuffs_base__make_status(wuffs_lzip__error__bad_header);
57120 goto exit;
57122 status = v_status;
57123 if (wuffs_base__status__is_error(&status)) {
57124 goto exit;
57125 } else if (wuffs_base__status__is_suspension(&status)) {
57126 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
57127 goto exit;
57129 goto ok;
57131 self->private_impl.f_ssize_have = 0u;
57132 self->private_impl.f_dsize_have = 0u;
57133 wuffs_lzma__decoder__set_quirk(&self->private_data.f_lzma, 1348001792u, 1u);
57134 while (true) {
57135 v_dmark = ((uint64_t)(iop_a_dst - io0_a_dst));
57136 v_smark = ((uint64_t)(iop_a_src - io0_a_src));
57138 if (a_dst) {
57139 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
57141 if (a_src) {
57142 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
57144 wuffs_base__status t_2 = wuffs_lzma__decoder__transform_io(&self->private_data.f_lzma, a_dst, a_src, a_workbuf);
57145 v_status = t_2;
57146 if (a_dst) {
57147 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
57149 if (a_src) {
57150 iop_a_src = a_src->data.ptr + a_src->meta.ri;
57153 self->private_impl.f_ssize_have += wuffs_private_impl__io__count_since(v_smark, ((uint64_t)(iop_a_src - io0_a_src)));
57154 self->private_impl.f_dsize_have += wuffs_private_impl__io__count_since(v_dmark, ((uint64_t)(iop_a_dst - io0_a_dst)));
57155 if ( ! self->private_impl.f_ignore_checksum) {
57156 wuffs_crc32__ieee_hasher__update(&self->private_data.f_crc32, wuffs_private_impl__io__since(v_dmark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst));
57158 if (wuffs_base__status__is_ok(&v_status)) {
57159 break;
57161 status = v_status;
57162 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
57165 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
57166 uint32_t t_3;
57167 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
57168 t_3 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
57169 iop_a_src += 4;
57170 } else {
57171 self->private_data.s_do_transform_io.scratch = 0;
57172 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
57173 while (true) {
57174 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
57175 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
57176 goto suspend;
57178 uint64_t* scratch = &self->private_data.s_do_transform_io.scratch;
57179 uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56));
57180 *scratch <<= 8;
57181 *scratch >>= 8;
57182 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3;
57183 if (num_bits_3 == 24) {
57184 t_3 = ((uint32_t)(*scratch));
57185 break;
57187 num_bits_3 += 8u;
57188 *scratch |= ((uint64_t)(num_bits_3)) << 56;
57191 v_checksum_want = t_3;
57193 if ( ! self->private_impl.f_ignore_checksum) {
57194 v_checksum_have = wuffs_crc32__ieee_hasher__checksum_u32(&self->private_data.f_crc32);
57195 if (v_checksum_have != v_checksum_want) {
57196 status = wuffs_base__make_status(wuffs_lzip__error__bad_checksum);
57197 goto exit;
57201 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
57202 uint64_t t_4;
57203 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 8)) {
57204 t_4 = wuffs_base__peek_u64le__no_bounds_check(iop_a_src);
57205 iop_a_src += 8;
57206 } else {
57207 self->private_data.s_do_transform_io.scratch = 0;
57208 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
57209 while (true) {
57210 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
57211 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
57212 goto suspend;
57214 uint64_t* scratch = &self->private_data.s_do_transform_io.scratch;
57215 uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
57216 *scratch <<= 8;
57217 *scratch >>= 8;
57218 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
57219 if (num_bits_4 == 56) {
57220 t_4 = ((uint64_t)(*scratch));
57221 break;
57223 num_bits_4 += 8u;
57224 *scratch |= ((uint64_t)(num_bits_4)) << 56;
57227 v_size_want = t_4;
57229 if (self->private_impl.f_dsize_have != v_size_want) {
57230 status = wuffs_base__make_status(wuffs_lzip__error__bad_footer);
57231 goto exit;
57234 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
57235 uint64_t t_5;
57236 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 8)) {
57237 t_5 = wuffs_base__peek_u64le__no_bounds_check(iop_a_src);
57238 iop_a_src += 8;
57239 } else {
57240 self->private_data.s_do_transform_io.scratch = 0;
57241 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
57242 while (true) {
57243 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
57244 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
57245 goto suspend;
57247 uint64_t* scratch = &self->private_data.s_do_transform_io.scratch;
57248 uint32_t num_bits_5 = ((uint32_t)(*scratch >> 56));
57249 *scratch <<= 8;
57250 *scratch >>= 8;
57251 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_5;
57252 if (num_bits_5 == 56) {
57253 t_5 = ((uint64_t)(*scratch));
57254 break;
57256 num_bits_5 += 8u;
57257 *scratch |= ((uint64_t)(num_bits_5)) << 56;
57260 v_size_want = t_5;
57262 if ((v_size_want < 26u) || (2251799813685248u < v_size_want)) {
57263 status = wuffs_base__make_status(wuffs_lzip__error__bad_footer);
57264 goto exit;
57265 } else if (self->private_impl.f_ssize_have != (v_size_want - 26u)) {
57266 status = wuffs_base__make_status(wuffs_lzip__error__bad_footer);
57267 goto exit;
57269 while (((uint64_t)(io2_a_src - iop_a_src)) < 4u) {
57270 if (a_src && a_src->meta.closed) {
57271 goto label__outer__break;
57273 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
57274 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(11);
57276 v_c32 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
57277 if (v_c32 != 1346984524u) {
57278 break;
57280 wuffs_private_impl__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32,
57281 sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
57282 wuffs_private_impl__ignore_status(wuffs_lzma__decoder__initialize(&self->private_data.f_lzma,
57283 sizeof (wuffs_lzma__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
57285 label__outer__break:;
57288 self->private_impl.p_do_transform_io = 0;
57289 goto exit;
57292 goto suspend;
57293 suspend:
57294 self->private_impl.p_do_transform_io = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
57296 goto exit;
57297 exit:
57298 if (a_dst && a_dst->data.ptr) {
57299 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
57301 if (a_src && a_src->data.ptr) {
57302 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
57305 return status;
57308 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZIP)
57310 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZW)
57312 // ---------------- Status Codes Implementations
57314 const char wuffs_lzw__error__bad_code[] = "#lzw: bad code";
57315 const char wuffs_lzw__error__truncated_input[] = "#lzw: truncated input";
57316 const char wuffs_lzw__error__internal_error_inconsistent_i_o[] = "#lzw: internal error: inconsistent I/O";
57318 // ---------------- Private Consts
57320 #define WUFFS_LZW__QUIRKS_BASE 1348378624u
57322 // ---------------- Private Initializer Prototypes
57324 // ---------------- Private Function Prototypes
57326 WUFFS_BASE__GENERATED_C_CODE
57327 static wuffs_base__empty_struct
57328 wuffs_lzw__decoder__read_from(
57329 wuffs_lzw__decoder* self,
57330 wuffs_base__io_buffer* a_src);
57332 WUFFS_BASE__GENERATED_C_CODE
57333 static wuffs_base__status
57334 wuffs_lzw__decoder__write_to(
57335 wuffs_lzw__decoder* self,
57336 wuffs_base__io_buffer* a_dst);
57338 // ---------------- VTables
57340 const wuffs_base__io_transformer__func_ptrs
57341 wuffs_lzw__decoder__func_ptrs_for__wuffs_base__io_transformer = {
57342 (wuffs_base__optional_u63(*)(const void*))(&wuffs_lzw__decoder__dst_history_retain_length),
57343 (uint64_t(*)(const void*,
57344 uint32_t))(&wuffs_lzw__decoder__get_quirk),
57345 (wuffs_base__status(*)(void*,
57346 uint32_t,
57347 uint64_t))(&wuffs_lzw__decoder__set_quirk),
57348 (wuffs_base__status(*)(void*,
57349 wuffs_base__io_buffer*,
57350 wuffs_base__io_buffer*,
57351 wuffs_base__slice_u8))(&wuffs_lzw__decoder__transform_io),
57352 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_lzw__decoder__workbuf_len),
57355 // ---------------- Initializer Implementations
57357 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
57358 wuffs_lzw__decoder__initialize(
57359 wuffs_lzw__decoder* self,
57360 size_t sizeof_star_self,
57361 uint64_t wuffs_version,
57362 uint32_t options){
57363 if (!self) {
57364 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
57366 if (sizeof(*self) != sizeof_star_self) {
57367 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
57369 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
57370 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
57371 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
57374 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
57375 // The whole point of this if-check is to detect an uninitialized *self.
57376 // We disable the warning on GCC. Clang-5.0 does not have this warning.
57377 #if !defined(__clang__) && defined(__GNUC__)
57378 #pragma GCC diagnostic push
57379 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
57380 #endif
57381 if (self->private_impl.magic != 0) {
57382 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
57384 #if !defined(__clang__) && defined(__GNUC__)
57385 #pragma GCC diagnostic pop
57386 #endif
57387 } else {
57388 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
57389 memset(self, 0, sizeof(*self));
57390 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
57391 } else {
57392 memset(&(self->private_impl), 0, sizeof(self->private_impl));
57396 self->private_impl.magic = WUFFS_BASE__MAGIC;
57397 self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name =
57398 wuffs_base__io_transformer__vtable_name;
57399 self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers =
57400 (const void*)(&wuffs_lzw__decoder__func_ptrs_for__wuffs_base__io_transformer);
57401 return wuffs_base__make_status(NULL);
57404 wuffs_lzw__decoder*
57405 wuffs_lzw__decoder__alloc(void) {
57406 wuffs_lzw__decoder* x =
57407 (wuffs_lzw__decoder*)(calloc(1, sizeof(wuffs_lzw__decoder)));
57408 if (!x) {
57409 return NULL;
57411 if (wuffs_lzw__decoder__initialize(
57412 x, sizeof(wuffs_lzw__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
57413 free(x);
57414 return NULL;
57416 return x;
57419 size_t
57420 sizeof__wuffs_lzw__decoder(void) {
57421 return sizeof(wuffs_lzw__decoder);
57424 // ---------------- Function Implementations
57426 // -------- func lzw.decoder.get_quirk
57428 WUFFS_BASE__GENERATED_C_CODE
57429 WUFFS_BASE__MAYBE_STATIC uint64_t
57430 wuffs_lzw__decoder__get_quirk(
57431 const wuffs_lzw__decoder* self,
57432 uint32_t a_key) {
57433 if (!self) {
57434 return 0;
57436 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
57437 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
57438 return 0;
57441 if (a_key == 1348378624u) {
57442 return ((uint64_t)(self->private_impl.f_pending_literal_width_plus_one));
57444 return 0u;
57447 // -------- func lzw.decoder.set_quirk
57449 WUFFS_BASE__GENERATED_C_CODE
57450 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
57451 wuffs_lzw__decoder__set_quirk(
57452 wuffs_lzw__decoder* self,
57453 uint32_t a_key,
57454 uint64_t a_value) {
57455 if (!self) {
57456 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
57458 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
57459 return wuffs_base__make_status(
57460 (self->private_impl.magic == WUFFS_BASE__DISABLED)
57461 ? wuffs_base__error__disabled_by_previous_error
57462 : wuffs_base__error__initialize_not_called);
57465 if (a_key == 1348378624u) {
57466 if (a_value > 9u) {
57467 return wuffs_base__make_status(wuffs_base__error__bad_argument);
57469 self->private_impl.f_pending_literal_width_plus_one = ((uint32_t)(a_value));
57470 return wuffs_base__make_status(NULL);
57472 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
57475 // -------- func lzw.decoder.dst_history_retain_length
57477 WUFFS_BASE__GENERATED_C_CODE
57478 WUFFS_BASE__MAYBE_STATIC wuffs_base__optional_u63
57479 wuffs_lzw__decoder__dst_history_retain_length(
57480 const wuffs_lzw__decoder* self) {
57481 if (!self) {
57482 return wuffs_base__utility__make_optional_u63(false, 0u);
57484 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
57485 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
57486 return wuffs_base__utility__make_optional_u63(false, 0u);
57489 return wuffs_base__utility__make_optional_u63(true, 0u);
57492 // -------- func lzw.decoder.workbuf_len
57494 WUFFS_BASE__GENERATED_C_CODE
57495 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
57496 wuffs_lzw__decoder__workbuf_len(
57497 const wuffs_lzw__decoder* self) {
57498 if (!self) {
57499 return wuffs_base__utility__empty_range_ii_u64();
57501 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
57502 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
57503 return wuffs_base__utility__empty_range_ii_u64();
57506 return wuffs_base__utility__make_range_ii_u64(0u, 0u);
57509 // -------- func lzw.decoder.transform_io
57511 WUFFS_BASE__GENERATED_C_CODE
57512 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
57513 wuffs_lzw__decoder__transform_io(
57514 wuffs_lzw__decoder* self,
57515 wuffs_base__io_buffer* a_dst,
57516 wuffs_base__io_buffer* a_src,
57517 wuffs_base__slice_u8 a_workbuf) {
57518 if (!self) {
57519 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
57521 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
57522 return wuffs_base__make_status(
57523 (self->private_impl.magic == WUFFS_BASE__DISABLED)
57524 ? wuffs_base__error__disabled_by_previous_error
57525 : wuffs_base__error__initialize_not_called);
57527 if (!a_dst || !a_src) {
57528 self->private_impl.magic = WUFFS_BASE__DISABLED;
57529 return wuffs_base__make_status(wuffs_base__error__bad_argument);
57531 if ((self->private_impl.active_coroutine != 0) &&
57532 (self->private_impl.active_coroutine != 1)) {
57533 self->private_impl.magic = WUFFS_BASE__DISABLED;
57534 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
57536 self->private_impl.active_coroutine = 0;
57537 wuffs_base__status status = wuffs_base__make_status(NULL);
57539 uint32_t v_i = 0;
57541 uint32_t coro_susp_point = self->private_impl.p_transform_io;
57542 switch (coro_susp_point) {
57543 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
57545 self->private_impl.f_literal_width = 8u;
57546 if (self->private_impl.f_pending_literal_width_plus_one > 0u) {
57547 self->private_impl.f_literal_width = (self->private_impl.f_pending_literal_width_plus_one - 1u);
57549 self->private_impl.f_clear_code = (((uint32_t)(1u)) << self->private_impl.f_literal_width);
57550 self->private_impl.f_end_code = (self->private_impl.f_clear_code + 1u);
57551 self->private_impl.f_save_code = self->private_impl.f_end_code;
57552 self->private_impl.f_prev_code = self->private_impl.f_end_code;
57553 self->private_impl.f_width = (self->private_impl.f_literal_width + 1u);
57554 self->private_impl.f_bits = 0u;
57555 self->private_impl.f_n_bits = 0u;
57556 self->private_impl.f_output_ri = 0u;
57557 self->private_impl.f_output_wi = 0u;
57558 v_i = 0u;
57559 while (v_i < self->private_impl.f_clear_code) {
57560 self->private_data.f_lm1s[v_i] = 0u;
57561 self->private_data.f_suffixes[v_i][0u] = ((uint8_t)(v_i));
57562 v_i += 1u;
57564 while (true) {
57565 wuffs_lzw__decoder__read_from(self, a_src);
57566 if (self->private_impl.f_output_wi > 0u) {
57567 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
57568 status = wuffs_lzw__decoder__write_to(self, a_dst);
57569 if (status.repr) {
57570 goto suspend;
57573 if (self->private_impl.f_read_from_return_value == 0u) {
57574 break;
57575 } else if (self->private_impl.f_read_from_return_value == 1u) {
57576 continue;
57577 } else if (self->private_impl.f_read_from_return_value == 2u) {
57578 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
57579 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
57580 } else if (self->private_impl.f_read_from_return_value == 3u) {
57581 status = wuffs_base__make_status(wuffs_lzw__error__truncated_input);
57582 goto exit;
57583 } else if (self->private_impl.f_read_from_return_value == 4u) {
57584 status = wuffs_base__make_status(wuffs_lzw__error__bad_code);
57585 goto exit;
57586 } else {
57587 status = wuffs_base__make_status(wuffs_lzw__error__internal_error_inconsistent_i_o);
57588 goto exit;
57593 self->private_impl.p_transform_io = 0;
57594 goto exit;
57597 goto suspend;
57598 suspend:
57599 self->private_impl.p_transform_io = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
57600 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
57602 goto exit;
57603 exit:
57604 if (wuffs_base__status__is_error(&status)) {
57605 self->private_impl.magic = WUFFS_BASE__DISABLED;
57607 return status;
57610 // -------- func lzw.decoder.read_from
57612 WUFFS_BASE__GENERATED_C_CODE
57613 static wuffs_base__empty_struct
57614 wuffs_lzw__decoder__read_from(
57615 wuffs_lzw__decoder* self,
57616 wuffs_base__io_buffer* a_src) {
57617 uint32_t v_clear_code = 0;
57618 uint32_t v_end_code = 0;
57619 uint32_t v_save_code = 0;
57620 uint32_t v_prev_code = 0;
57621 uint32_t v_width = 0;
57622 uint32_t v_bits = 0;
57623 uint32_t v_n_bits = 0;
57624 uint32_t v_output_wi = 0;
57625 uint32_t v_code = 0;
57626 uint32_t v_c = 0;
57627 uint32_t v_o = 0;
57628 uint32_t v_steps = 0;
57629 uint8_t v_first_byte = 0;
57630 uint16_t v_lm1_b = 0;
57631 uint16_t v_lm1_a = 0;
57633 const uint8_t* iop_a_src = NULL;
57634 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
57635 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
57636 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
57637 if (a_src && a_src->data.ptr) {
57638 io0_a_src = a_src->data.ptr;
57639 io1_a_src = io0_a_src + a_src->meta.ri;
57640 iop_a_src = io1_a_src;
57641 io2_a_src = io0_a_src + a_src->meta.wi;
57644 v_clear_code = self->private_impl.f_clear_code;
57645 v_end_code = self->private_impl.f_end_code;
57646 v_save_code = self->private_impl.f_save_code;
57647 v_prev_code = self->private_impl.f_prev_code;
57648 v_width = self->private_impl.f_width;
57649 v_bits = self->private_impl.f_bits;
57650 v_n_bits = self->private_impl.f_n_bits;
57651 v_output_wi = self->private_impl.f_output_wi;
57652 while (true) {
57653 if (v_n_bits < v_width) {
57654 if (((uint64_t)(io2_a_src - iop_a_src)) >= 4u) {
57655 v_bits |= ((uint32_t)(wuffs_base__peek_u32le__no_bounds_check(iop_a_src) << v_n_bits));
57656 iop_a_src += ((31u - v_n_bits) >> 3u);
57657 v_n_bits |= 24u;
57658 } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
57659 if (a_src && a_src->meta.closed) {
57660 self->private_impl.f_read_from_return_value = 3u;
57661 } else {
57662 self->private_impl.f_read_from_return_value = 2u;
57664 break;
57665 } else {
57666 v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
57667 iop_a_src += 1u;
57668 v_n_bits += 8u;
57669 if (v_n_bits >= v_width) {
57670 } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
57671 if (a_src && a_src->meta.closed) {
57672 self->private_impl.f_read_from_return_value = 3u;
57673 } else {
57674 self->private_impl.f_read_from_return_value = 2u;
57676 break;
57677 } else {
57678 v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
57679 iop_a_src += 1u;
57680 v_n_bits += 8u;
57681 if (v_n_bits < v_width) {
57682 self->private_impl.f_read_from_return_value = 5u;
57683 break;
57688 v_code = ((v_bits) & WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U32(v_width));
57689 v_bits >>= v_width;
57690 v_n_bits -= v_width;
57691 if (v_code < v_clear_code) {
57692 self->private_data.f_output[v_output_wi] = ((uint8_t)(v_code));
57693 v_output_wi = ((v_output_wi + 1u) & 8191u);
57694 if (v_save_code <= 4095u) {
57695 v_lm1_a = ((uint16_t)(((uint16_t)(self->private_data.f_lm1s[v_prev_code] + 1u)) & 4095u));
57696 self->private_data.f_lm1s[v_save_code] = v_lm1_a;
57697 if (((uint16_t)(v_lm1_a % 8u)) != 0u) {
57698 self->private_impl.f_prefixes[v_save_code] = self->private_impl.f_prefixes[v_prev_code];
57699 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]));
57700 self->private_data.f_suffixes[v_save_code][((uint16_t)(v_lm1_a % 8u))] = ((uint8_t)(v_code));
57701 } else {
57702 self->private_impl.f_prefixes[v_save_code] = ((uint16_t)(v_prev_code));
57703 self->private_data.f_suffixes[v_save_code][0u] = ((uint8_t)(v_code));
57705 v_save_code += 1u;
57706 if (v_width < 12u) {
57707 v_width += (1u & (v_save_code >> v_width));
57709 v_prev_code = v_code;
57711 } else if (v_code <= v_end_code) {
57712 if (v_code == v_end_code) {
57713 self->private_impl.f_read_from_return_value = 0u;
57714 break;
57716 v_save_code = v_end_code;
57717 v_prev_code = v_end_code;
57718 v_width = (self->private_impl.f_literal_width + 1u);
57719 } else if (v_code <= v_save_code) {
57720 v_c = v_code;
57721 if (v_code == v_save_code) {
57722 v_c = v_prev_code;
57724 v_o = ((v_output_wi + (((uint32_t)(self->private_data.f_lm1s[v_c])) & 4294967288u)) & 8191u);
57725 v_output_wi = ((v_output_wi + 1u + ((uint32_t)(self->private_data.f_lm1s[v_c]))) & 8191u);
57726 v_steps = (((uint32_t)(self->private_data.f_lm1s[v_c])) >> 3u);
57727 while (true) {
57728 memcpy((self->private_data.f_output)+(v_o), (self->private_data.f_suffixes[v_c]), 8u);
57729 if (v_steps <= 0u) {
57730 break;
57732 v_steps -= 1u;
57733 v_o = (((uint32_t)(v_o - 8u)) & 8191u);
57734 v_c = ((uint32_t)(self->private_impl.f_prefixes[v_c]));
57736 v_first_byte = self->private_data.f_suffixes[v_c][0u];
57737 if (v_code == v_save_code) {
57738 self->private_data.f_output[v_output_wi] = v_first_byte;
57739 v_output_wi = ((v_output_wi + 1u) & 8191u);
57741 if (v_save_code <= 4095u) {
57742 v_lm1_b = ((uint16_t)(((uint16_t)(self->private_data.f_lm1s[v_prev_code] + 1u)) & 4095u));
57743 self->private_data.f_lm1s[v_save_code] = v_lm1_b;
57744 if (((uint16_t)(v_lm1_b % 8u)) != 0u) {
57745 self->private_impl.f_prefixes[v_save_code] = self->private_impl.f_prefixes[v_prev_code];
57746 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]));
57747 self->private_data.f_suffixes[v_save_code][((uint16_t)(v_lm1_b % 8u))] = v_first_byte;
57748 } else {
57749 self->private_impl.f_prefixes[v_save_code] = ((uint16_t)(v_prev_code));
57750 self->private_data.f_suffixes[v_save_code][0u] = ((uint8_t)(v_first_byte));
57752 v_save_code += 1u;
57753 if (v_width < 12u) {
57754 v_width += (1u & (v_save_code >> v_width));
57756 v_prev_code = v_code;
57758 } else {
57759 self->private_impl.f_read_from_return_value = 4u;
57760 break;
57762 if (v_output_wi > 4095u) {
57763 self->private_impl.f_read_from_return_value = 1u;
57764 break;
57767 if (self->private_impl.f_read_from_return_value != 2u) {
57768 while (v_n_bits >= 8u) {
57769 v_n_bits -= 8u;
57770 if (iop_a_src > io1_a_src) {
57771 iop_a_src--;
57772 } else {
57773 self->private_impl.f_read_from_return_value = 5u;
57774 break;
57778 self->private_impl.f_save_code = v_save_code;
57779 self->private_impl.f_prev_code = v_prev_code;
57780 self->private_impl.f_width = v_width;
57781 self->private_impl.f_bits = v_bits;
57782 self->private_impl.f_n_bits = v_n_bits;
57783 self->private_impl.f_output_wi = v_output_wi;
57784 if (a_src && a_src->data.ptr) {
57785 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
57788 return wuffs_base__make_empty_struct();
57791 // -------- func lzw.decoder.write_to
57793 WUFFS_BASE__GENERATED_C_CODE
57794 static wuffs_base__status
57795 wuffs_lzw__decoder__write_to(
57796 wuffs_lzw__decoder* self,
57797 wuffs_base__io_buffer* a_dst) {
57798 wuffs_base__status status = wuffs_base__make_status(NULL);
57800 wuffs_base__slice_u8 v_s = {0};
57801 uint64_t v_n = 0;
57803 uint8_t* iop_a_dst = NULL;
57804 uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
57805 uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
57806 uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
57807 if (a_dst && a_dst->data.ptr) {
57808 io0_a_dst = a_dst->data.ptr;
57809 io1_a_dst = io0_a_dst + a_dst->meta.wi;
57810 iop_a_dst = io1_a_dst;
57811 io2_a_dst = io0_a_dst + a_dst->data.len;
57812 if (a_dst->meta.closed) {
57813 io2_a_dst = iop_a_dst;
57817 uint32_t coro_susp_point = self->private_impl.p_write_to;
57818 switch (coro_susp_point) {
57819 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
57821 while (self->private_impl.f_output_wi > 0u) {
57822 if (self->private_impl.f_output_ri > self->private_impl.f_output_wi) {
57823 status = wuffs_base__make_status(wuffs_lzw__error__internal_error_inconsistent_i_o);
57824 goto exit;
57826 v_s = wuffs_base__make_slice_u8_ij(self->private_data.f_output,
57827 self->private_impl.f_output_ri,
57828 self->private_impl.f_output_wi);
57829 v_n = wuffs_private_impl__io_writer__copy_from_slice(&iop_a_dst, io2_a_dst,v_s);
57830 if (v_n == ((uint64_t)(v_s.len))) {
57831 self->private_impl.f_output_ri = 0u;
57832 self->private_impl.f_output_wi = 0u;
57833 status = wuffs_base__make_status(NULL);
57834 goto ok;
57836 self->private_impl.f_output_ri = (((uint32_t)(self->private_impl.f_output_ri + ((uint32_t)(v_n)))) & 8191u);
57837 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
57838 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
57842 self->private_impl.p_write_to = 0;
57843 goto exit;
57846 goto suspend;
57847 suspend:
57848 self->private_impl.p_write_to = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
57850 goto exit;
57851 exit:
57852 if (a_dst && a_dst->data.ptr) {
57853 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
57856 return status;
57859 // -------- func lzw.decoder.flush
57861 WUFFS_BASE__GENERATED_C_CODE
57862 WUFFS_BASE__MAYBE_STATIC wuffs_base__slice_u8
57863 wuffs_lzw__decoder__flush(
57864 wuffs_lzw__decoder* self) {
57865 if (!self) {
57866 return wuffs_base__empty_slice_u8();
57868 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
57869 return wuffs_base__empty_slice_u8();
57872 uint32_t v_ri = 0;
57873 uint32_t v_wi = 0;
57875 v_ri = self->private_impl.f_output_ri;
57876 v_wi = self->private_impl.f_output_wi;
57877 self->private_impl.f_output_ri = 0u;
57878 self->private_impl.f_output_wi = 0u;
57879 if (v_ri <= v_wi) {
57880 return wuffs_base__make_slice_u8_ij(self->private_data.f_output, v_ri, v_wi);
57882 return wuffs_base__make_slice_u8(self->private_data.f_output, 0);
57885 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZW)
57887 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NETPBM)
57889 // ---------------- Status Codes Implementations
57891 const char wuffs_netpbm__error__bad_header[] = "#netpbm: bad header";
57892 const char wuffs_netpbm__error__truncated_input[] = "#netpbm: truncated input";
57893 const char wuffs_netpbm__error__unsupported_netpbm_file[] = "#netpbm: unsupported Netpbm file";
57894 const char wuffs_netpbm__note__internal_note_short_read[] = "@netpbm: internal note: short read";
57896 // ---------------- Private Consts
57898 // ---------------- Private Initializer Prototypes
57900 // ---------------- Private Function Prototypes
57902 WUFFS_BASE__GENERATED_C_CODE
57903 static wuffs_base__status
57904 wuffs_netpbm__decoder__do_decode_image_config(
57905 wuffs_netpbm__decoder* self,
57906 wuffs_base__image_config* a_dst,
57907 wuffs_base__io_buffer* a_src);
57909 WUFFS_BASE__GENERATED_C_CODE
57910 static wuffs_base__status
57911 wuffs_netpbm__decoder__do_decode_frame_config(
57912 wuffs_netpbm__decoder* self,
57913 wuffs_base__frame_config* a_dst,
57914 wuffs_base__io_buffer* a_src);
57916 WUFFS_BASE__GENERATED_C_CODE
57917 static wuffs_base__status
57918 wuffs_netpbm__decoder__do_decode_frame(
57919 wuffs_netpbm__decoder* self,
57920 wuffs_base__pixel_buffer* a_dst,
57921 wuffs_base__io_buffer* a_src,
57922 wuffs_base__pixel_blend a_blend,
57923 wuffs_base__slice_u8 a_workbuf,
57924 wuffs_base__decode_frame_options* a_opts);
57926 WUFFS_BASE__GENERATED_C_CODE
57927 static wuffs_base__status
57928 wuffs_netpbm__decoder__swizzle(
57929 wuffs_netpbm__decoder* self,
57930 wuffs_base__pixel_buffer* a_dst,
57931 wuffs_base__io_buffer* a_src);
57933 // ---------------- VTables
57935 const wuffs_base__image_decoder__func_ptrs
57936 wuffs_netpbm__decoder__func_ptrs_for__wuffs_base__image_decoder = {
57937 (wuffs_base__status(*)(void*,
57938 wuffs_base__pixel_buffer*,
57939 wuffs_base__io_buffer*,
57940 wuffs_base__pixel_blend,
57941 wuffs_base__slice_u8,
57942 wuffs_base__decode_frame_options*))(&wuffs_netpbm__decoder__decode_frame),
57943 (wuffs_base__status(*)(void*,
57944 wuffs_base__frame_config*,
57945 wuffs_base__io_buffer*))(&wuffs_netpbm__decoder__decode_frame_config),
57946 (wuffs_base__status(*)(void*,
57947 wuffs_base__image_config*,
57948 wuffs_base__io_buffer*))(&wuffs_netpbm__decoder__decode_image_config),
57949 (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_netpbm__decoder__frame_dirty_rect),
57950 (uint64_t(*)(const void*,
57951 uint32_t))(&wuffs_netpbm__decoder__get_quirk),
57952 (uint32_t(*)(const void*))(&wuffs_netpbm__decoder__num_animation_loops),
57953 (uint64_t(*)(const void*))(&wuffs_netpbm__decoder__num_decoded_frame_configs),
57954 (uint64_t(*)(const void*))(&wuffs_netpbm__decoder__num_decoded_frames),
57955 (wuffs_base__status(*)(void*,
57956 uint64_t,
57957 uint64_t))(&wuffs_netpbm__decoder__restart_frame),
57958 (wuffs_base__status(*)(void*,
57959 uint32_t,
57960 uint64_t))(&wuffs_netpbm__decoder__set_quirk),
57961 (wuffs_base__empty_struct(*)(void*,
57962 uint32_t,
57963 bool))(&wuffs_netpbm__decoder__set_report_metadata),
57964 (wuffs_base__status(*)(void*,
57965 wuffs_base__io_buffer*,
57966 wuffs_base__more_information*,
57967 wuffs_base__io_buffer*))(&wuffs_netpbm__decoder__tell_me_more),
57968 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_netpbm__decoder__workbuf_len),
57971 // ---------------- Initializer Implementations
57973 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
57974 wuffs_netpbm__decoder__initialize(
57975 wuffs_netpbm__decoder* self,
57976 size_t sizeof_star_self,
57977 uint64_t wuffs_version,
57978 uint32_t options){
57979 if (!self) {
57980 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
57982 if (sizeof(*self) != sizeof_star_self) {
57983 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
57985 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
57986 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
57987 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
57990 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
57991 // The whole point of this if-check is to detect an uninitialized *self.
57992 // We disable the warning on GCC. Clang-5.0 does not have this warning.
57993 #if !defined(__clang__) && defined(__GNUC__)
57994 #pragma GCC diagnostic push
57995 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
57996 #endif
57997 if (self->private_impl.magic != 0) {
57998 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
58000 #if !defined(__clang__) && defined(__GNUC__)
58001 #pragma GCC diagnostic pop
58002 #endif
58003 } else {
58004 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
58005 memset(self, 0, sizeof(*self));
58006 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
58007 } else {
58008 memset(&(self->private_impl), 0, sizeof(self->private_impl));
58012 self->private_impl.magic = WUFFS_BASE__MAGIC;
58013 self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
58014 wuffs_base__image_decoder__vtable_name;
58015 self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
58016 (const void*)(&wuffs_netpbm__decoder__func_ptrs_for__wuffs_base__image_decoder);
58017 return wuffs_base__make_status(NULL);
58020 wuffs_netpbm__decoder*
58021 wuffs_netpbm__decoder__alloc(void) {
58022 wuffs_netpbm__decoder* x =
58023 (wuffs_netpbm__decoder*)(calloc(1, sizeof(wuffs_netpbm__decoder)));
58024 if (!x) {
58025 return NULL;
58027 if (wuffs_netpbm__decoder__initialize(
58028 x, sizeof(wuffs_netpbm__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
58029 free(x);
58030 return NULL;
58032 return x;
58035 size_t
58036 sizeof__wuffs_netpbm__decoder(void) {
58037 return sizeof(wuffs_netpbm__decoder);
58040 // ---------------- Function Implementations
58042 // -------- func netpbm.decoder.get_quirk
58044 WUFFS_BASE__GENERATED_C_CODE
58045 WUFFS_BASE__MAYBE_STATIC uint64_t
58046 wuffs_netpbm__decoder__get_quirk(
58047 const wuffs_netpbm__decoder* self,
58048 uint32_t a_key) {
58049 if (!self) {
58050 return 0;
58052 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
58053 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
58054 return 0;
58057 return 0u;
58060 // -------- func netpbm.decoder.set_quirk
58062 WUFFS_BASE__GENERATED_C_CODE
58063 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
58064 wuffs_netpbm__decoder__set_quirk(
58065 wuffs_netpbm__decoder* self,
58066 uint32_t a_key,
58067 uint64_t a_value) {
58068 if (!self) {
58069 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
58071 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
58072 return wuffs_base__make_status(
58073 (self->private_impl.magic == WUFFS_BASE__DISABLED)
58074 ? wuffs_base__error__disabled_by_previous_error
58075 : wuffs_base__error__initialize_not_called);
58078 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
58081 // -------- func netpbm.decoder.decode_image_config
58083 WUFFS_BASE__GENERATED_C_CODE
58084 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
58085 wuffs_netpbm__decoder__decode_image_config(
58086 wuffs_netpbm__decoder* self,
58087 wuffs_base__image_config* a_dst,
58088 wuffs_base__io_buffer* a_src) {
58089 if (!self) {
58090 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
58092 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
58093 return wuffs_base__make_status(
58094 (self->private_impl.magic == WUFFS_BASE__DISABLED)
58095 ? wuffs_base__error__disabled_by_previous_error
58096 : wuffs_base__error__initialize_not_called);
58098 if (!a_src) {
58099 self->private_impl.magic = WUFFS_BASE__DISABLED;
58100 return wuffs_base__make_status(wuffs_base__error__bad_argument);
58102 if ((self->private_impl.active_coroutine != 0) &&
58103 (self->private_impl.active_coroutine != 1)) {
58104 self->private_impl.magic = WUFFS_BASE__DISABLED;
58105 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
58107 self->private_impl.active_coroutine = 0;
58108 wuffs_base__status status = wuffs_base__make_status(NULL);
58110 wuffs_base__status v_status = wuffs_base__make_status(NULL);
58112 uint32_t coro_susp_point = self->private_impl.p_decode_image_config;
58113 switch (coro_susp_point) {
58114 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
58116 while (true) {
58118 wuffs_base__status t_0 = wuffs_netpbm__decoder__do_decode_image_config(self, a_dst, a_src);
58119 v_status = t_0;
58121 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
58122 status = wuffs_base__make_status(wuffs_netpbm__error__truncated_input);
58123 goto exit;
58125 status = v_status;
58126 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
58130 self->private_impl.p_decode_image_config = 0;
58131 goto exit;
58134 goto suspend;
58135 suspend:
58136 self->private_impl.p_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
58137 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
58139 goto exit;
58140 exit:
58141 if (wuffs_base__status__is_error(&status)) {
58142 self->private_impl.magic = WUFFS_BASE__DISABLED;
58144 return status;
58147 // -------- func netpbm.decoder.do_decode_image_config
58149 WUFFS_BASE__GENERATED_C_CODE
58150 static wuffs_base__status
58151 wuffs_netpbm__decoder__do_decode_image_config(
58152 wuffs_netpbm__decoder* self,
58153 wuffs_base__image_config* a_dst,
58154 wuffs_base__io_buffer* a_src) {
58155 wuffs_base__status status = wuffs_base__make_status(NULL);
58157 uint8_t v_c8 = 0;
58158 uint32_t v_n = 0;
58160 const uint8_t* iop_a_src = NULL;
58161 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
58162 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
58163 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
58164 if (a_src && a_src->data.ptr) {
58165 io0_a_src = a_src->data.ptr;
58166 io1_a_src = io0_a_src + a_src->meta.ri;
58167 iop_a_src = io1_a_src;
58168 io2_a_src = io0_a_src + a_src->meta.wi;
58171 uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config;
58172 switch (coro_susp_point) {
58173 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
58175 if (self->private_impl.f_call_sequence != 0u) {
58176 status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
58177 goto exit;
58180 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
58181 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
58182 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
58183 goto suspend;
58185 uint8_t t_0 = *iop_a_src++;
58186 v_c8 = t_0;
58188 if (v_c8 != 80u) {
58189 status = wuffs_base__make_status(wuffs_netpbm__error__bad_header);
58190 goto exit;
58193 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
58194 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
58195 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
58196 goto suspend;
58198 uint8_t t_1 = *iop_a_src++;
58199 v_c8 = t_1;
58201 if ((v_c8 < 49u) || (55u < v_c8)) {
58202 status = wuffs_base__make_status(wuffs_netpbm__error__bad_header);
58203 goto exit;
58204 } else if (v_c8 == 53u) {
58205 self->private_impl.f_pixfmt = 536870920u;
58206 } else if (v_c8 == 54u) {
58207 self->private_impl.f_pixfmt = 2684356744u;
58208 } else {
58209 status = wuffs_base__make_status(wuffs_netpbm__error__unsupported_netpbm_file);
58210 goto exit;
58213 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
58214 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
58215 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
58216 goto suspend;
58218 uint8_t t_2 = *iop_a_src++;
58219 v_c8 = t_2;
58221 if (v_c8 != 10u) {
58222 status = wuffs_base__make_status(wuffs_netpbm__error__bad_header);
58223 goto exit;
58225 while (true) {
58227 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
58228 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
58229 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
58230 goto suspend;
58232 uint8_t t_3 = *iop_a_src++;
58233 v_c8 = t_3;
58235 if ((v_c8 == 32u) || (v_c8 == 9u)) {
58236 continue;
58237 } else if (v_c8 == 35u) {
58238 while (true) {
58240 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
58241 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
58242 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
58243 goto suspend;
58245 uint8_t t_4 = *iop_a_src++;
58246 v_c8 = t_4;
58248 if (v_c8 == 10u) {
58249 break;
58252 continue;
58253 } else if ((v_c8 < 48u) || (57u < v_c8)) {
58254 status = wuffs_base__make_status(wuffs_netpbm__error__bad_header);
58255 goto exit;
58257 self->private_impl.f_width = ((uint32_t)(((uint8_t)(v_c8 - 48u))));
58258 break;
58260 while (true) {
58262 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
58263 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
58264 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
58265 goto suspend;
58267 uint8_t t_5 = *iop_a_src++;
58268 v_c8 = t_5;
58270 if ((v_c8 == 32u) || (v_c8 == 9u)) {
58271 break;
58272 } else if ((v_c8 < 48u) || (57u < v_c8)) {
58273 status = wuffs_base__make_status(wuffs_netpbm__error__bad_header);
58274 goto exit;
58276 v_n = ((10u * self->private_impl.f_width) + ((uint32_t)(((uint8_t)(v_c8 - 48u)))));
58277 if (v_n > 16777215u) {
58278 status = wuffs_base__make_status(wuffs_netpbm__error__unsupported_netpbm_file);
58279 goto exit;
58281 self->private_impl.f_width = v_n;
58283 while (true) {
58285 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
58286 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
58287 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
58288 goto suspend;
58290 uint8_t t_6 = *iop_a_src++;
58291 v_c8 = t_6;
58293 if ((v_c8 == 32u) || (v_c8 == 9u)) {
58294 continue;
58295 } else if (v_c8 == 35u) {
58296 while (true) {
58298 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
58299 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
58300 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
58301 goto suspend;
58303 uint8_t t_7 = *iop_a_src++;
58304 v_c8 = t_7;
58306 if (v_c8 == 10u) {
58307 break;
58310 continue;
58311 } else if ((v_c8 < 48u) || (57u < v_c8)) {
58312 status = wuffs_base__make_status(wuffs_netpbm__error__bad_header);
58313 goto exit;
58315 self->private_impl.f_height = ((uint32_t)(((uint8_t)(v_c8 - 48u))));
58316 break;
58318 while (true) {
58320 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
58321 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
58322 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
58323 goto suspend;
58325 uint8_t t_8 = *iop_a_src++;
58326 v_c8 = t_8;
58328 if ((v_c8 == 32u) || (v_c8 == 9u) || (v_c8 == 13u)) {
58329 continue;
58330 } else if (v_c8 == 10u) {
58331 break;
58332 } else if ((v_c8 < 48u) || (57u < v_c8)) {
58333 status = wuffs_base__make_status(wuffs_netpbm__error__bad_header);
58334 goto exit;
58336 v_n = ((10u * self->private_impl.f_height) + ((uint32_t)(((uint8_t)(v_c8 - 48u)))));
58337 if (v_n > 16777215u) {
58338 status = wuffs_base__make_status(wuffs_netpbm__error__unsupported_netpbm_file);
58339 goto exit;
58341 self->private_impl.f_height = v_n;
58343 while (true) {
58345 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
58346 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
58347 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
58348 goto suspend;
58350 uint8_t t_9 = *iop_a_src++;
58351 v_c8 = t_9;
58353 if ((v_c8 == 32u) || (v_c8 == 9u)) {
58354 continue;
58355 } else if (v_c8 == 35u) {
58356 while (true) {
58358 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
58359 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
58360 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
58361 goto suspend;
58363 uint8_t t_10 = *iop_a_src++;
58364 v_c8 = t_10;
58366 if (v_c8 == 10u) {
58367 break;
58370 continue;
58371 } else if ((v_c8 < 48u) || (57u < v_c8)) {
58372 status = wuffs_base__make_status(wuffs_netpbm__error__bad_header);
58373 goto exit;
58375 self->private_impl.f_max_value = ((uint32_t)(((uint8_t)(v_c8 - 48u))));
58376 break;
58378 while (true) {
58380 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
58381 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
58382 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
58383 goto suspend;
58385 uint8_t t_11 = *iop_a_src++;
58386 v_c8 = t_11;
58388 if ((v_c8 == 32u) || (v_c8 == 9u) || (v_c8 == 13u)) {
58389 continue;
58390 } else if (v_c8 == 10u) {
58391 break;
58392 } else if ((v_c8 < 48u) || (57u < v_c8)) {
58393 status = wuffs_base__make_status(wuffs_netpbm__error__bad_header);
58394 goto exit;
58396 v_n = ((10u * self->private_impl.f_max_value) + ((uint32_t)(((uint8_t)(v_c8 - 48u)))));
58397 if (v_n > 16777215u) {
58398 status = wuffs_base__make_status(wuffs_netpbm__error__unsupported_netpbm_file);
58399 goto exit;
58401 self->private_impl.f_max_value = v_n;
58403 if (self->private_impl.f_max_value != 255u) {
58404 status = wuffs_base__make_status(wuffs_netpbm__error__unsupported_netpbm_file);
58405 goto exit;
58407 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)));
58408 if (a_dst != NULL) {
58409 wuffs_base__image_config__set(
58410 a_dst,
58411 self->private_impl.f_pixfmt,
58413 self->private_impl.f_width,
58414 self->private_impl.f_height,
58415 self->private_impl.f_frame_config_io_position,
58416 false);
58418 self->private_impl.f_call_sequence = 32u;
58420 goto ok;
58422 self->private_impl.p_do_decode_image_config = 0;
58423 goto exit;
58426 goto suspend;
58427 suspend:
58428 self->private_impl.p_do_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
58430 goto exit;
58431 exit:
58432 if (a_src && a_src->data.ptr) {
58433 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
58436 return status;
58439 // -------- func netpbm.decoder.decode_frame_config
58441 WUFFS_BASE__GENERATED_C_CODE
58442 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
58443 wuffs_netpbm__decoder__decode_frame_config(
58444 wuffs_netpbm__decoder* self,
58445 wuffs_base__frame_config* a_dst,
58446 wuffs_base__io_buffer* a_src) {
58447 if (!self) {
58448 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
58450 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
58451 return wuffs_base__make_status(
58452 (self->private_impl.magic == WUFFS_BASE__DISABLED)
58453 ? wuffs_base__error__disabled_by_previous_error
58454 : wuffs_base__error__initialize_not_called);
58456 if (!a_src) {
58457 self->private_impl.magic = WUFFS_BASE__DISABLED;
58458 return wuffs_base__make_status(wuffs_base__error__bad_argument);
58460 if ((self->private_impl.active_coroutine != 0) &&
58461 (self->private_impl.active_coroutine != 2)) {
58462 self->private_impl.magic = WUFFS_BASE__DISABLED;
58463 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
58465 self->private_impl.active_coroutine = 0;
58466 wuffs_base__status status = wuffs_base__make_status(NULL);
58468 wuffs_base__status v_status = wuffs_base__make_status(NULL);
58470 uint32_t coro_susp_point = self->private_impl.p_decode_frame_config;
58471 switch (coro_susp_point) {
58472 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
58474 while (true) {
58476 wuffs_base__status t_0 = wuffs_netpbm__decoder__do_decode_frame_config(self, a_dst, a_src);
58477 v_status = t_0;
58479 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
58480 status = wuffs_base__make_status(wuffs_netpbm__error__truncated_input);
58481 goto exit;
58483 status = v_status;
58484 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
58488 self->private_impl.p_decode_frame_config = 0;
58489 goto exit;
58492 goto suspend;
58493 suspend:
58494 self->private_impl.p_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
58495 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
58497 goto exit;
58498 exit:
58499 if (wuffs_base__status__is_error(&status)) {
58500 self->private_impl.magic = WUFFS_BASE__DISABLED;
58502 return status;
58505 // -------- func netpbm.decoder.do_decode_frame_config
58507 WUFFS_BASE__GENERATED_C_CODE
58508 static wuffs_base__status
58509 wuffs_netpbm__decoder__do_decode_frame_config(
58510 wuffs_netpbm__decoder* self,
58511 wuffs_base__frame_config* a_dst,
58512 wuffs_base__io_buffer* a_src) {
58513 wuffs_base__status status = wuffs_base__make_status(NULL);
58515 const uint8_t* iop_a_src = NULL;
58516 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
58517 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
58518 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
58519 if (a_src && a_src->data.ptr) {
58520 io0_a_src = a_src->data.ptr;
58521 io1_a_src = io0_a_src + a_src->meta.ri;
58522 iop_a_src = io1_a_src;
58523 io2_a_src = io0_a_src + a_src->meta.wi;
58526 uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config;
58527 switch (coro_susp_point) {
58528 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
58530 if (self->private_impl.f_call_sequence == 32u) {
58531 } else if (self->private_impl.f_call_sequence < 32u) {
58532 if (a_src) {
58533 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
58535 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
58536 status = wuffs_netpbm__decoder__do_decode_image_config(self, NULL, a_src);
58537 if (a_src) {
58538 iop_a_src = a_src->data.ptr + a_src->meta.ri;
58540 if (status.repr) {
58541 goto suspend;
58543 } else if (self->private_impl.f_call_sequence == 40u) {
58544 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)))) {
58545 status = wuffs_base__make_status(wuffs_base__error__bad_restart);
58546 goto exit;
58548 } else if (self->private_impl.f_call_sequence == 64u) {
58549 self->private_impl.f_call_sequence = 96u;
58550 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
58551 goto ok;
58552 } else {
58553 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
58554 goto ok;
58556 if (a_dst != NULL) {
58557 wuffs_base__frame_config__set(
58558 a_dst,
58559 wuffs_base__utility__make_rect_ie_u32(
58562 self->private_impl.f_width,
58563 self->private_impl.f_height),
58564 ((wuffs_base__flicks)(0u)),
58566 self->private_impl.f_frame_config_io_position,
58568 false,
58569 false,
58570 0u);
58572 self->private_impl.f_call_sequence = 64u;
58575 self->private_impl.p_do_decode_frame_config = 0;
58576 goto exit;
58579 goto suspend;
58580 suspend:
58581 self->private_impl.p_do_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
58583 goto exit;
58584 exit:
58585 if (a_src && a_src->data.ptr) {
58586 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
58589 return status;
58592 // -------- func netpbm.decoder.decode_frame
58594 WUFFS_BASE__GENERATED_C_CODE
58595 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
58596 wuffs_netpbm__decoder__decode_frame(
58597 wuffs_netpbm__decoder* self,
58598 wuffs_base__pixel_buffer* a_dst,
58599 wuffs_base__io_buffer* a_src,
58600 wuffs_base__pixel_blend a_blend,
58601 wuffs_base__slice_u8 a_workbuf,
58602 wuffs_base__decode_frame_options* a_opts) {
58603 if (!self) {
58604 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
58606 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
58607 return wuffs_base__make_status(
58608 (self->private_impl.magic == WUFFS_BASE__DISABLED)
58609 ? wuffs_base__error__disabled_by_previous_error
58610 : wuffs_base__error__initialize_not_called);
58612 if (!a_dst || !a_src) {
58613 self->private_impl.magic = WUFFS_BASE__DISABLED;
58614 return wuffs_base__make_status(wuffs_base__error__bad_argument);
58616 if ((self->private_impl.active_coroutine != 0) &&
58617 (self->private_impl.active_coroutine != 3)) {
58618 self->private_impl.magic = WUFFS_BASE__DISABLED;
58619 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
58621 self->private_impl.active_coroutine = 0;
58622 wuffs_base__status status = wuffs_base__make_status(NULL);
58624 wuffs_base__status v_status = wuffs_base__make_status(NULL);
58626 uint32_t coro_susp_point = self->private_impl.p_decode_frame;
58627 switch (coro_susp_point) {
58628 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
58630 while (true) {
58632 wuffs_base__status t_0 = wuffs_netpbm__decoder__do_decode_frame(self,
58633 a_dst,
58634 a_src,
58635 a_blend,
58636 a_workbuf,
58637 a_opts);
58638 v_status = t_0;
58640 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
58641 status = wuffs_base__make_status(wuffs_netpbm__error__truncated_input);
58642 goto exit;
58644 status = v_status;
58645 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
58649 self->private_impl.p_decode_frame = 0;
58650 goto exit;
58653 goto suspend;
58654 suspend:
58655 self->private_impl.p_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
58656 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
58658 goto exit;
58659 exit:
58660 if (wuffs_base__status__is_error(&status)) {
58661 self->private_impl.magic = WUFFS_BASE__DISABLED;
58663 return status;
58666 // -------- func netpbm.decoder.do_decode_frame
58668 WUFFS_BASE__GENERATED_C_CODE
58669 static wuffs_base__status
58670 wuffs_netpbm__decoder__do_decode_frame(
58671 wuffs_netpbm__decoder* self,
58672 wuffs_base__pixel_buffer* a_dst,
58673 wuffs_base__io_buffer* a_src,
58674 wuffs_base__pixel_blend a_blend,
58675 wuffs_base__slice_u8 a_workbuf,
58676 wuffs_base__decode_frame_options* a_opts) {
58677 wuffs_base__status status = wuffs_base__make_status(NULL);
58679 wuffs_base__status v_status = wuffs_base__make_status(NULL);
58681 uint32_t coro_susp_point = self->private_impl.p_do_decode_frame;
58682 switch (coro_susp_point) {
58683 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
58685 if (self->private_impl.f_call_sequence == 64u) {
58686 } else if (self->private_impl.f_call_sequence < 64u) {
58687 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
58688 status = wuffs_netpbm__decoder__do_decode_frame_config(self, NULL, a_src);
58689 if (status.repr) {
58690 goto suspend;
58692 } else {
58693 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
58694 goto ok;
58696 self->private_impl.f_dst_x = 0u;
58697 self->private_impl.f_dst_y = 0u;
58698 v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
58699 wuffs_base__pixel_buffer__pixel_format(a_dst),
58700 wuffs_base__pixel_buffer__palette(a_dst),
58701 wuffs_base__utility__make_pixel_format(self->private_impl.f_pixfmt),
58702 wuffs_base__utility__empty_slice_u8(),
58703 a_blend);
58704 if ( ! wuffs_base__status__is_ok(&v_status)) {
58705 status = v_status;
58706 if (wuffs_base__status__is_error(&status)) {
58707 goto exit;
58708 } else if (wuffs_base__status__is_suspension(&status)) {
58709 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
58710 goto exit;
58712 goto ok;
58714 while (true) {
58715 v_status = wuffs_netpbm__decoder__swizzle(self, a_dst, a_src);
58716 if (wuffs_base__status__is_ok(&v_status)) {
58717 break;
58718 } else if (v_status.repr != wuffs_netpbm__note__internal_note_short_read) {
58719 status = v_status;
58720 if (wuffs_base__status__is_error(&status)) {
58721 goto exit;
58722 } else if (wuffs_base__status__is_suspension(&status)) {
58723 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
58724 goto exit;
58726 goto ok;
58728 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
58729 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
58731 self->private_impl.f_call_sequence = 96u;
58734 self->private_impl.p_do_decode_frame = 0;
58735 goto exit;
58738 goto suspend;
58739 suspend:
58740 self->private_impl.p_do_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
58742 goto exit;
58743 exit:
58744 return status;
58747 // -------- func netpbm.decoder.swizzle
58749 WUFFS_BASE__GENERATED_C_CODE
58750 static wuffs_base__status
58751 wuffs_netpbm__decoder__swizzle(
58752 wuffs_netpbm__decoder* self,
58753 wuffs_base__pixel_buffer* a_dst,
58754 wuffs_base__io_buffer* a_src) {
58755 wuffs_base__status status = wuffs_base__make_status(NULL);
58757 wuffs_base__pixel_format v_dst_pixfmt = {0};
58758 uint32_t v_dst_bits_per_pixel = 0;
58759 uint32_t v_dst_bytes_per_pixel = 0;
58760 uint64_t v_dst_bytes_per_row = 0;
58761 uint32_t v_src_bytes_per_pixel = 0;
58762 wuffs_base__table_u8 v_tab = {0};
58763 wuffs_base__slice_u8 v_dst = {0};
58764 uint64_t v_i = 0;
58765 uint64_t v_j = 0;
58766 uint64_t v_n = 0;
58768 const uint8_t* iop_a_src = NULL;
58769 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
58770 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
58771 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
58772 if (a_src && a_src->data.ptr) {
58773 io0_a_src = a_src->data.ptr;
58774 io1_a_src = io0_a_src + a_src->meta.ri;
58775 iop_a_src = io1_a_src;
58776 io2_a_src = io0_a_src + a_src->meta.wi;
58779 v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
58780 v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
58781 if ((v_dst_bits_per_pixel & 7u) != 0u) {
58782 status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
58783 goto exit;
58785 v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u);
58786 v_dst_bytes_per_row = ((uint64_t)((self->private_impl.f_width * v_dst_bytes_per_pixel)));
58787 v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
58788 while (true) {
58789 if (self->private_impl.f_dst_x == self->private_impl.f_width) {
58790 self->private_impl.f_dst_x = 0u;
58791 self->private_impl.f_dst_y += 1u;
58792 if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
58793 break;
58796 v_dst = wuffs_private_impl__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
58797 if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) {
58798 v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row);
58800 v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_dst_bytes_per_pixel)));
58801 if (v_i >= ((uint64_t)(v_dst.len))) {
58802 v_src_bytes_per_pixel = 1u;
58803 if (self->private_impl.f_pixfmt == 2684356744u) {
58804 v_src_bytes_per_pixel = 3u;
58806 v_n = (((uint64_t)(io2_a_src - iop_a_src)) / ((uint64_t)(v_src_bytes_per_pixel)));
58807 v_n = wuffs_base__u64__min(v_n, ((uint64_t)(((uint32_t)(self->private_impl.f_width - self->private_impl.f_dst_x)))));
58808 v_j = v_n;
58809 while (v_j >= 8u) {
58810 if (((uint64_t)(io2_a_src - iop_a_src)) >= ((uint64_t)((v_src_bytes_per_pixel * 8u)))) {
58811 iop_a_src += (v_src_bytes_per_pixel * 8u);
58813 v_j -= 8u;
58815 while (v_j > 0u) {
58816 if (((uint64_t)(io2_a_src - iop_a_src)) >= ((uint64_t)((v_src_bytes_per_pixel * 1u)))) {
58817 iop_a_src += (v_src_bytes_per_pixel * 1u);
58819 v_j -= 1u;
58821 } else {
58822 v_n = wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(
58823 &self->private_impl.f_swizzler,
58824 wuffs_base__slice_u8__subslice_i(v_dst, v_i),
58825 wuffs_base__pixel_buffer__palette(a_dst),
58826 &iop_a_src,
58827 io2_a_src);
58829 if (v_n == 0u) {
58830 status = wuffs_base__make_status(wuffs_netpbm__note__internal_note_short_read);
58831 goto ok;
58833 wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n)));
58835 status = wuffs_base__make_status(NULL);
58836 goto ok;
58839 goto exit;
58840 exit:
58841 if (a_src && a_src->data.ptr) {
58842 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
58845 return status;
58848 // -------- func netpbm.decoder.frame_dirty_rect
58850 WUFFS_BASE__GENERATED_C_CODE
58851 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
58852 wuffs_netpbm__decoder__frame_dirty_rect(
58853 const wuffs_netpbm__decoder* self) {
58854 if (!self) {
58855 return wuffs_base__utility__empty_rect_ie_u32();
58857 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
58858 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
58859 return wuffs_base__utility__empty_rect_ie_u32();
58862 return wuffs_base__utility__make_rect_ie_u32(
58865 self->private_impl.f_width,
58866 self->private_impl.f_height);
58869 // -------- func netpbm.decoder.num_animation_loops
58871 WUFFS_BASE__GENERATED_C_CODE
58872 WUFFS_BASE__MAYBE_STATIC uint32_t
58873 wuffs_netpbm__decoder__num_animation_loops(
58874 const wuffs_netpbm__decoder* self) {
58875 if (!self) {
58876 return 0;
58878 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
58879 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
58880 return 0;
58883 return 0u;
58886 // -------- func netpbm.decoder.num_decoded_frame_configs
58888 WUFFS_BASE__GENERATED_C_CODE
58889 WUFFS_BASE__MAYBE_STATIC uint64_t
58890 wuffs_netpbm__decoder__num_decoded_frame_configs(
58891 const wuffs_netpbm__decoder* self) {
58892 if (!self) {
58893 return 0;
58895 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
58896 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
58897 return 0;
58900 if (self->private_impl.f_call_sequence > 32u) {
58901 return 1u;
58903 return 0u;
58906 // -------- func netpbm.decoder.num_decoded_frames
58908 WUFFS_BASE__GENERATED_C_CODE
58909 WUFFS_BASE__MAYBE_STATIC uint64_t
58910 wuffs_netpbm__decoder__num_decoded_frames(
58911 const wuffs_netpbm__decoder* self) {
58912 if (!self) {
58913 return 0;
58915 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
58916 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
58917 return 0;
58920 if (self->private_impl.f_call_sequence > 64u) {
58921 return 1u;
58923 return 0u;
58926 // -------- func netpbm.decoder.restart_frame
58928 WUFFS_BASE__GENERATED_C_CODE
58929 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
58930 wuffs_netpbm__decoder__restart_frame(
58931 wuffs_netpbm__decoder* self,
58932 uint64_t a_index,
58933 uint64_t a_io_position) {
58934 if (!self) {
58935 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
58937 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
58938 return wuffs_base__make_status(
58939 (self->private_impl.magic == WUFFS_BASE__DISABLED)
58940 ? wuffs_base__error__disabled_by_previous_error
58941 : wuffs_base__error__initialize_not_called);
58944 if (self->private_impl.f_call_sequence < 32u) {
58945 return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
58947 if ((a_index != 0u) || (a_io_position != self->private_impl.f_frame_config_io_position)) {
58948 return wuffs_base__make_status(wuffs_base__error__bad_argument);
58950 self->private_impl.f_call_sequence = 40u;
58951 return wuffs_base__make_status(NULL);
58954 // -------- func netpbm.decoder.set_report_metadata
58956 WUFFS_BASE__GENERATED_C_CODE
58957 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
58958 wuffs_netpbm__decoder__set_report_metadata(
58959 wuffs_netpbm__decoder* self,
58960 uint32_t a_fourcc,
58961 bool a_report) {
58962 return wuffs_base__make_empty_struct();
58965 // -------- func netpbm.decoder.tell_me_more
58967 WUFFS_BASE__GENERATED_C_CODE
58968 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
58969 wuffs_netpbm__decoder__tell_me_more(
58970 wuffs_netpbm__decoder* self,
58971 wuffs_base__io_buffer* a_dst,
58972 wuffs_base__more_information* a_minfo,
58973 wuffs_base__io_buffer* a_src) {
58974 if (!self) {
58975 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
58977 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
58978 return wuffs_base__make_status(
58979 (self->private_impl.magic == WUFFS_BASE__DISABLED)
58980 ? wuffs_base__error__disabled_by_previous_error
58981 : wuffs_base__error__initialize_not_called);
58983 if (!a_dst || !a_src) {
58984 self->private_impl.magic = WUFFS_BASE__DISABLED;
58985 return wuffs_base__make_status(wuffs_base__error__bad_argument);
58987 if ((self->private_impl.active_coroutine != 0) &&
58988 (self->private_impl.active_coroutine != 4)) {
58989 self->private_impl.magic = WUFFS_BASE__DISABLED;
58990 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
58992 self->private_impl.active_coroutine = 0;
58993 wuffs_base__status status = wuffs_base__make_status(NULL);
58995 status = wuffs_base__make_status(wuffs_base__error__no_more_information);
58996 goto exit;
58998 goto ok;
59000 goto exit;
59001 exit:
59002 if (wuffs_base__status__is_error(&status)) {
59003 self->private_impl.magic = WUFFS_BASE__DISABLED;
59005 return status;
59008 // -------- func netpbm.decoder.workbuf_len
59010 WUFFS_BASE__GENERATED_C_CODE
59011 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
59012 wuffs_netpbm__decoder__workbuf_len(
59013 const wuffs_netpbm__decoder* self) {
59014 if (!self) {
59015 return wuffs_base__utility__empty_range_ii_u64();
59017 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
59018 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
59019 return wuffs_base__utility__empty_range_ii_u64();
59022 return wuffs_base__utility__make_range_ii_u64(0u, 0u);
59025 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NETPBM)
59027 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NIE)
59029 // ---------------- Status Codes Implementations
59031 const char wuffs_nie__error__bad_header[] = "#nie: bad header";
59032 const char wuffs_nie__error__truncated_input[] = "#nie: truncated input";
59033 const char wuffs_nie__error__unsupported_nie_file[] = "#nie: unsupported NIE file";
59034 const char wuffs_nie__note__internal_note_short_read[] = "@nie: internal note: short read";
59036 // ---------------- Private Consts
59038 // ---------------- Private Initializer Prototypes
59040 // ---------------- Private Function Prototypes
59042 WUFFS_BASE__GENERATED_C_CODE
59043 static wuffs_base__status
59044 wuffs_nie__decoder__do_decode_image_config(
59045 wuffs_nie__decoder* self,
59046 wuffs_base__image_config* a_dst,
59047 wuffs_base__io_buffer* a_src);
59049 WUFFS_BASE__GENERATED_C_CODE
59050 static wuffs_base__status
59051 wuffs_nie__decoder__do_decode_frame_config(
59052 wuffs_nie__decoder* self,
59053 wuffs_base__frame_config* a_dst,
59054 wuffs_base__io_buffer* a_src);
59056 WUFFS_BASE__GENERATED_C_CODE
59057 static wuffs_base__status
59058 wuffs_nie__decoder__do_decode_frame(
59059 wuffs_nie__decoder* self,
59060 wuffs_base__pixel_buffer* a_dst,
59061 wuffs_base__io_buffer* a_src,
59062 wuffs_base__pixel_blend a_blend,
59063 wuffs_base__slice_u8 a_workbuf,
59064 wuffs_base__decode_frame_options* a_opts);
59066 WUFFS_BASE__GENERATED_C_CODE
59067 static wuffs_base__status
59068 wuffs_nie__decoder__swizzle(
59069 wuffs_nie__decoder* self,
59070 wuffs_base__pixel_buffer* a_dst,
59071 wuffs_base__io_buffer* a_src);
59073 // ---------------- VTables
59075 const wuffs_base__image_decoder__func_ptrs
59076 wuffs_nie__decoder__func_ptrs_for__wuffs_base__image_decoder = {
59077 (wuffs_base__status(*)(void*,
59078 wuffs_base__pixel_buffer*,
59079 wuffs_base__io_buffer*,
59080 wuffs_base__pixel_blend,
59081 wuffs_base__slice_u8,
59082 wuffs_base__decode_frame_options*))(&wuffs_nie__decoder__decode_frame),
59083 (wuffs_base__status(*)(void*,
59084 wuffs_base__frame_config*,
59085 wuffs_base__io_buffer*))(&wuffs_nie__decoder__decode_frame_config),
59086 (wuffs_base__status(*)(void*,
59087 wuffs_base__image_config*,
59088 wuffs_base__io_buffer*))(&wuffs_nie__decoder__decode_image_config),
59089 (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_nie__decoder__frame_dirty_rect),
59090 (uint64_t(*)(const void*,
59091 uint32_t))(&wuffs_nie__decoder__get_quirk),
59092 (uint32_t(*)(const void*))(&wuffs_nie__decoder__num_animation_loops),
59093 (uint64_t(*)(const void*))(&wuffs_nie__decoder__num_decoded_frame_configs),
59094 (uint64_t(*)(const void*))(&wuffs_nie__decoder__num_decoded_frames),
59095 (wuffs_base__status(*)(void*,
59096 uint64_t,
59097 uint64_t))(&wuffs_nie__decoder__restart_frame),
59098 (wuffs_base__status(*)(void*,
59099 uint32_t,
59100 uint64_t))(&wuffs_nie__decoder__set_quirk),
59101 (wuffs_base__empty_struct(*)(void*,
59102 uint32_t,
59103 bool))(&wuffs_nie__decoder__set_report_metadata),
59104 (wuffs_base__status(*)(void*,
59105 wuffs_base__io_buffer*,
59106 wuffs_base__more_information*,
59107 wuffs_base__io_buffer*))(&wuffs_nie__decoder__tell_me_more),
59108 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_nie__decoder__workbuf_len),
59111 // ---------------- Initializer Implementations
59113 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
59114 wuffs_nie__decoder__initialize(
59115 wuffs_nie__decoder* self,
59116 size_t sizeof_star_self,
59117 uint64_t wuffs_version,
59118 uint32_t options){
59119 if (!self) {
59120 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
59122 if (sizeof(*self) != sizeof_star_self) {
59123 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
59125 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
59126 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
59127 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
59130 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
59131 // The whole point of this if-check is to detect an uninitialized *self.
59132 // We disable the warning on GCC. Clang-5.0 does not have this warning.
59133 #if !defined(__clang__) && defined(__GNUC__)
59134 #pragma GCC diagnostic push
59135 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
59136 #endif
59137 if (self->private_impl.magic != 0) {
59138 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
59140 #if !defined(__clang__) && defined(__GNUC__)
59141 #pragma GCC diagnostic pop
59142 #endif
59143 } else {
59144 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
59145 memset(self, 0, sizeof(*self));
59146 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
59147 } else {
59148 memset(&(self->private_impl), 0, sizeof(self->private_impl));
59152 self->private_impl.magic = WUFFS_BASE__MAGIC;
59153 self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
59154 wuffs_base__image_decoder__vtable_name;
59155 self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
59156 (const void*)(&wuffs_nie__decoder__func_ptrs_for__wuffs_base__image_decoder);
59157 return wuffs_base__make_status(NULL);
59160 wuffs_nie__decoder*
59161 wuffs_nie__decoder__alloc(void) {
59162 wuffs_nie__decoder* x =
59163 (wuffs_nie__decoder*)(calloc(1, sizeof(wuffs_nie__decoder)));
59164 if (!x) {
59165 return NULL;
59167 if (wuffs_nie__decoder__initialize(
59168 x, sizeof(wuffs_nie__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
59169 free(x);
59170 return NULL;
59172 return x;
59175 size_t
59176 sizeof__wuffs_nie__decoder(void) {
59177 return sizeof(wuffs_nie__decoder);
59180 // ---------------- Function Implementations
59182 // -------- func nie.decoder.get_quirk
59184 WUFFS_BASE__GENERATED_C_CODE
59185 WUFFS_BASE__MAYBE_STATIC uint64_t
59186 wuffs_nie__decoder__get_quirk(
59187 const wuffs_nie__decoder* self,
59188 uint32_t a_key) {
59189 if (!self) {
59190 return 0;
59192 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
59193 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
59194 return 0;
59197 return 0u;
59200 // -------- func nie.decoder.set_quirk
59202 WUFFS_BASE__GENERATED_C_CODE
59203 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
59204 wuffs_nie__decoder__set_quirk(
59205 wuffs_nie__decoder* self,
59206 uint32_t a_key,
59207 uint64_t a_value) {
59208 if (!self) {
59209 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
59211 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
59212 return wuffs_base__make_status(
59213 (self->private_impl.magic == WUFFS_BASE__DISABLED)
59214 ? wuffs_base__error__disabled_by_previous_error
59215 : wuffs_base__error__initialize_not_called);
59218 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
59221 // -------- func nie.decoder.decode_image_config
59223 WUFFS_BASE__GENERATED_C_CODE
59224 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
59225 wuffs_nie__decoder__decode_image_config(
59226 wuffs_nie__decoder* self,
59227 wuffs_base__image_config* a_dst,
59228 wuffs_base__io_buffer* a_src) {
59229 if (!self) {
59230 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
59232 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
59233 return wuffs_base__make_status(
59234 (self->private_impl.magic == WUFFS_BASE__DISABLED)
59235 ? wuffs_base__error__disabled_by_previous_error
59236 : wuffs_base__error__initialize_not_called);
59238 if (!a_src) {
59239 self->private_impl.magic = WUFFS_BASE__DISABLED;
59240 return wuffs_base__make_status(wuffs_base__error__bad_argument);
59242 if ((self->private_impl.active_coroutine != 0) &&
59243 (self->private_impl.active_coroutine != 1)) {
59244 self->private_impl.magic = WUFFS_BASE__DISABLED;
59245 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
59247 self->private_impl.active_coroutine = 0;
59248 wuffs_base__status status = wuffs_base__make_status(NULL);
59250 wuffs_base__status v_status = wuffs_base__make_status(NULL);
59252 uint32_t coro_susp_point = self->private_impl.p_decode_image_config;
59253 switch (coro_susp_point) {
59254 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
59256 while (true) {
59258 wuffs_base__status t_0 = wuffs_nie__decoder__do_decode_image_config(self, a_dst, a_src);
59259 v_status = t_0;
59261 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
59262 status = wuffs_base__make_status(wuffs_nie__error__truncated_input);
59263 goto exit;
59265 status = v_status;
59266 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
59270 self->private_impl.p_decode_image_config = 0;
59271 goto exit;
59274 goto suspend;
59275 suspend:
59276 self->private_impl.p_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
59277 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
59279 goto exit;
59280 exit:
59281 if (wuffs_base__status__is_error(&status)) {
59282 self->private_impl.magic = WUFFS_BASE__DISABLED;
59284 return status;
59287 // -------- func nie.decoder.do_decode_image_config
59289 WUFFS_BASE__GENERATED_C_CODE
59290 static wuffs_base__status
59291 wuffs_nie__decoder__do_decode_image_config(
59292 wuffs_nie__decoder* self,
59293 wuffs_base__image_config* a_dst,
59294 wuffs_base__io_buffer* a_src) {
59295 wuffs_base__status status = wuffs_base__make_status(NULL);
59297 uint32_t v_a = 0;
59299 const uint8_t* iop_a_src = NULL;
59300 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
59301 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
59302 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
59303 if (a_src && a_src->data.ptr) {
59304 io0_a_src = a_src->data.ptr;
59305 io1_a_src = io0_a_src + a_src->meta.ri;
59306 iop_a_src = io1_a_src;
59307 io2_a_src = io0_a_src + a_src->meta.wi;
59310 uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config;
59311 switch (coro_susp_point) {
59312 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
59314 if (self->private_impl.f_call_sequence != 0u) {
59315 status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
59316 goto exit;
59319 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
59320 uint32_t t_0;
59321 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
59322 t_0 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
59323 iop_a_src += 4;
59324 } else {
59325 self->private_data.s_do_decode_image_config.scratch = 0;
59326 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
59327 while (true) {
59328 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
59329 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
59330 goto suspend;
59332 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
59333 uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
59334 *scratch <<= 8;
59335 *scratch >>= 8;
59336 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
59337 if (num_bits_0 == 24) {
59338 t_0 = ((uint32_t)(*scratch));
59339 break;
59341 num_bits_0 += 8u;
59342 *scratch |= ((uint64_t)(num_bits_0)) << 56;
59345 v_a = t_0;
59347 if (v_a != 1169146734u) {
59348 status = wuffs_base__make_status(wuffs_nie__error__bad_header);
59349 goto exit;
59352 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
59353 uint32_t t_1;
59354 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
59355 t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
59356 iop_a_src += 4;
59357 } else {
59358 self->private_data.s_do_decode_image_config.scratch = 0;
59359 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
59360 while (true) {
59361 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
59362 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
59363 goto suspend;
59365 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
59366 uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
59367 *scratch <<= 8;
59368 *scratch >>= 8;
59369 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
59370 if (num_bits_1 == 24) {
59371 t_1 = ((uint32_t)(*scratch));
59372 break;
59374 num_bits_1 += 8u;
59375 *scratch |= ((uint64_t)(num_bits_1)) << 56;
59378 v_a = t_1;
59380 if (v_a == 879649535u) {
59381 self->private_impl.f_pixfmt = 2164295816u;
59382 } else if (v_a == 946758399u) {
59383 self->private_impl.f_pixfmt = 2164308923u;
59384 } else if (v_a == 879780607u) {
59385 status = wuffs_base__make_status(wuffs_nie__error__unsupported_nie_file);
59386 goto exit;
59387 } else if (v_a == 946889471u) {
59388 status = wuffs_base__make_status(wuffs_nie__error__unsupported_nie_file);
59389 goto exit;
59390 } else {
59391 status = wuffs_base__make_status(wuffs_nie__error__bad_header);
59392 goto exit;
59395 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
59396 uint32_t t_2;
59397 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
59398 t_2 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
59399 iop_a_src += 4;
59400 } else {
59401 self->private_data.s_do_decode_image_config.scratch = 0;
59402 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
59403 while (true) {
59404 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
59405 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
59406 goto suspend;
59408 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
59409 uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
59410 *scratch <<= 8;
59411 *scratch >>= 8;
59412 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
59413 if (num_bits_2 == 24) {
59414 t_2 = ((uint32_t)(*scratch));
59415 break;
59417 num_bits_2 += 8u;
59418 *scratch |= ((uint64_t)(num_bits_2)) << 56;
59421 v_a = t_2;
59423 if (v_a > 2147483647u) {
59424 status = wuffs_base__make_status(wuffs_nie__error__bad_header);
59425 goto exit;
59426 } else if (v_a > 16777215u) {
59427 status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension);
59428 goto exit;
59430 self->private_impl.f_width = v_a;
59432 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
59433 uint32_t t_3;
59434 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
59435 t_3 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
59436 iop_a_src += 4;
59437 } else {
59438 self->private_data.s_do_decode_image_config.scratch = 0;
59439 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
59440 while (true) {
59441 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
59442 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
59443 goto suspend;
59445 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
59446 uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56));
59447 *scratch <<= 8;
59448 *scratch >>= 8;
59449 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3;
59450 if (num_bits_3 == 24) {
59451 t_3 = ((uint32_t)(*scratch));
59452 break;
59454 num_bits_3 += 8u;
59455 *scratch |= ((uint64_t)(num_bits_3)) << 56;
59458 v_a = t_3;
59460 if (v_a > 2147483647u) {
59461 status = wuffs_base__make_status(wuffs_nie__error__bad_header);
59462 goto exit;
59463 } else if (v_a > 16777215u) {
59464 status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension);
59465 goto exit;
59467 self->private_impl.f_height = v_a;
59468 if (a_dst != NULL) {
59469 wuffs_base__image_config__set(
59470 a_dst,
59471 self->private_impl.f_pixfmt,
59473 self->private_impl.f_width,
59474 self->private_impl.f_height,
59475 16u,
59476 false);
59478 self->private_impl.f_call_sequence = 32u;
59480 goto ok;
59482 self->private_impl.p_do_decode_image_config = 0;
59483 goto exit;
59486 goto suspend;
59487 suspend:
59488 self->private_impl.p_do_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
59490 goto exit;
59491 exit:
59492 if (a_src && a_src->data.ptr) {
59493 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
59496 return status;
59499 // -------- func nie.decoder.decode_frame_config
59501 WUFFS_BASE__GENERATED_C_CODE
59502 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
59503 wuffs_nie__decoder__decode_frame_config(
59504 wuffs_nie__decoder* self,
59505 wuffs_base__frame_config* a_dst,
59506 wuffs_base__io_buffer* a_src) {
59507 if (!self) {
59508 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
59510 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
59511 return wuffs_base__make_status(
59512 (self->private_impl.magic == WUFFS_BASE__DISABLED)
59513 ? wuffs_base__error__disabled_by_previous_error
59514 : wuffs_base__error__initialize_not_called);
59516 if (!a_src) {
59517 self->private_impl.magic = WUFFS_BASE__DISABLED;
59518 return wuffs_base__make_status(wuffs_base__error__bad_argument);
59520 if ((self->private_impl.active_coroutine != 0) &&
59521 (self->private_impl.active_coroutine != 2)) {
59522 self->private_impl.magic = WUFFS_BASE__DISABLED;
59523 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
59525 self->private_impl.active_coroutine = 0;
59526 wuffs_base__status status = wuffs_base__make_status(NULL);
59528 wuffs_base__status v_status = wuffs_base__make_status(NULL);
59530 uint32_t coro_susp_point = self->private_impl.p_decode_frame_config;
59531 switch (coro_susp_point) {
59532 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
59534 while (true) {
59536 wuffs_base__status t_0 = wuffs_nie__decoder__do_decode_frame_config(self, a_dst, a_src);
59537 v_status = t_0;
59539 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
59540 status = wuffs_base__make_status(wuffs_nie__error__truncated_input);
59541 goto exit;
59543 status = v_status;
59544 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
59548 self->private_impl.p_decode_frame_config = 0;
59549 goto exit;
59552 goto suspend;
59553 suspend:
59554 self->private_impl.p_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
59555 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
59557 goto exit;
59558 exit:
59559 if (wuffs_base__status__is_error(&status)) {
59560 self->private_impl.magic = WUFFS_BASE__DISABLED;
59562 return status;
59565 // -------- func nie.decoder.do_decode_frame_config
59567 WUFFS_BASE__GENERATED_C_CODE
59568 static wuffs_base__status
59569 wuffs_nie__decoder__do_decode_frame_config(
59570 wuffs_nie__decoder* self,
59571 wuffs_base__frame_config* a_dst,
59572 wuffs_base__io_buffer* a_src) {
59573 wuffs_base__status status = wuffs_base__make_status(NULL);
59575 const uint8_t* iop_a_src = NULL;
59576 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
59577 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
59578 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
59579 if (a_src && a_src->data.ptr) {
59580 io0_a_src = a_src->data.ptr;
59581 io1_a_src = io0_a_src + a_src->meta.ri;
59582 iop_a_src = io1_a_src;
59583 io2_a_src = io0_a_src + a_src->meta.wi;
59586 uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config;
59587 switch (coro_susp_point) {
59588 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
59590 if (self->private_impl.f_call_sequence == 32u) {
59591 } else if (self->private_impl.f_call_sequence < 32u) {
59592 if (a_src) {
59593 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
59595 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
59596 status = wuffs_nie__decoder__do_decode_image_config(self, NULL, a_src);
59597 if (a_src) {
59598 iop_a_src = a_src->data.ptr + a_src->meta.ri;
59600 if (status.repr) {
59601 goto suspend;
59603 } else if (self->private_impl.f_call_sequence == 40u) {
59604 if (16u != wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)))) {
59605 status = wuffs_base__make_status(wuffs_base__error__bad_restart);
59606 goto exit;
59608 } else if (self->private_impl.f_call_sequence == 64u) {
59609 self->private_impl.f_call_sequence = 96u;
59610 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
59611 goto ok;
59612 } else {
59613 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
59614 goto ok;
59616 if (a_dst != NULL) {
59617 wuffs_base__frame_config__set(
59618 a_dst,
59619 wuffs_base__utility__make_rect_ie_u32(
59622 self->private_impl.f_width,
59623 self->private_impl.f_height),
59624 ((wuffs_base__flicks)(0u)),
59626 16u,
59628 false,
59629 false,
59630 0u);
59632 self->private_impl.f_call_sequence = 64u;
59635 self->private_impl.p_do_decode_frame_config = 0;
59636 goto exit;
59639 goto suspend;
59640 suspend:
59641 self->private_impl.p_do_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
59643 goto exit;
59644 exit:
59645 if (a_src && a_src->data.ptr) {
59646 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
59649 return status;
59652 // -------- func nie.decoder.decode_frame
59654 WUFFS_BASE__GENERATED_C_CODE
59655 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
59656 wuffs_nie__decoder__decode_frame(
59657 wuffs_nie__decoder* self,
59658 wuffs_base__pixel_buffer* a_dst,
59659 wuffs_base__io_buffer* a_src,
59660 wuffs_base__pixel_blend a_blend,
59661 wuffs_base__slice_u8 a_workbuf,
59662 wuffs_base__decode_frame_options* a_opts) {
59663 if (!self) {
59664 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
59666 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
59667 return wuffs_base__make_status(
59668 (self->private_impl.magic == WUFFS_BASE__DISABLED)
59669 ? wuffs_base__error__disabled_by_previous_error
59670 : wuffs_base__error__initialize_not_called);
59672 if (!a_dst || !a_src) {
59673 self->private_impl.magic = WUFFS_BASE__DISABLED;
59674 return wuffs_base__make_status(wuffs_base__error__bad_argument);
59676 if ((self->private_impl.active_coroutine != 0) &&
59677 (self->private_impl.active_coroutine != 3)) {
59678 self->private_impl.magic = WUFFS_BASE__DISABLED;
59679 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
59681 self->private_impl.active_coroutine = 0;
59682 wuffs_base__status status = wuffs_base__make_status(NULL);
59684 wuffs_base__status v_status = wuffs_base__make_status(NULL);
59686 uint32_t coro_susp_point = self->private_impl.p_decode_frame;
59687 switch (coro_susp_point) {
59688 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
59690 while (true) {
59692 wuffs_base__status t_0 = wuffs_nie__decoder__do_decode_frame(self,
59693 a_dst,
59694 a_src,
59695 a_blend,
59696 a_workbuf,
59697 a_opts);
59698 v_status = t_0;
59700 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
59701 status = wuffs_base__make_status(wuffs_nie__error__truncated_input);
59702 goto exit;
59704 status = v_status;
59705 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
59709 self->private_impl.p_decode_frame = 0;
59710 goto exit;
59713 goto suspend;
59714 suspend:
59715 self->private_impl.p_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
59716 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
59718 goto exit;
59719 exit:
59720 if (wuffs_base__status__is_error(&status)) {
59721 self->private_impl.magic = WUFFS_BASE__DISABLED;
59723 return status;
59726 // -------- func nie.decoder.do_decode_frame
59728 WUFFS_BASE__GENERATED_C_CODE
59729 static wuffs_base__status
59730 wuffs_nie__decoder__do_decode_frame(
59731 wuffs_nie__decoder* self,
59732 wuffs_base__pixel_buffer* a_dst,
59733 wuffs_base__io_buffer* a_src,
59734 wuffs_base__pixel_blend a_blend,
59735 wuffs_base__slice_u8 a_workbuf,
59736 wuffs_base__decode_frame_options* a_opts) {
59737 wuffs_base__status status = wuffs_base__make_status(NULL);
59739 wuffs_base__status v_status = wuffs_base__make_status(NULL);
59741 uint32_t coro_susp_point = self->private_impl.p_do_decode_frame;
59742 switch (coro_susp_point) {
59743 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
59745 if (self->private_impl.f_call_sequence == 64u) {
59746 } else if (self->private_impl.f_call_sequence < 64u) {
59747 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
59748 status = wuffs_nie__decoder__do_decode_frame_config(self, NULL, a_src);
59749 if (status.repr) {
59750 goto suspend;
59752 } else {
59753 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
59754 goto ok;
59756 self->private_impl.f_dst_x = 0u;
59757 self->private_impl.f_dst_y = 0u;
59758 v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
59759 wuffs_base__pixel_buffer__pixel_format(a_dst),
59760 wuffs_base__pixel_buffer__palette(a_dst),
59761 wuffs_base__utility__make_pixel_format(self->private_impl.f_pixfmt),
59762 wuffs_base__utility__empty_slice_u8(),
59763 a_blend);
59764 if ( ! wuffs_base__status__is_ok(&v_status)) {
59765 status = v_status;
59766 if (wuffs_base__status__is_error(&status)) {
59767 goto exit;
59768 } else if (wuffs_base__status__is_suspension(&status)) {
59769 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
59770 goto exit;
59772 goto ok;
59774 while (true) {
59775 v_status = wuffs_nie__decoder__swizzle(self, a_dst, a_src);
59776 if (wuffs_base__status__is_ok(&v_status)) {
59777 break;
59778 } else if (v_status.repr != wuffs_nie__note__internal_note_short_read) {
59779 status = v_status;
59780 if (wuffs_base__status__is_error(&status)) {
59781 goto exit;
59782 } else if (wuffs_base__status__is_suspension(&status)) {
59783 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
59784 goto exit;
59786 goto ok;
59788 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
59789 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
59791 self->private_impl.f_call_sequence = 96u;
59794 self->private_impl.p_do_decode_frame = 0;
59795 goto exit;
59798 goto suspend;
59799 suspend:
59800 self->private_impl.p_do_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
59802 goto exit;
59803 exit:
59804 return status;
59807 // -------- func nie.decoder.swizzle
59809 WUFFS_BASE__GENERATED_C_CODE
59810 static wuffs_base__status
59811 wuffs_nie__decoder__swizzle(
59812 wuffs_nie__decoder* self,
59813 wuffs_base__pixel_buffer* a_dst,
59814 wuffs_base__io_buffer* a_src) {
59815 wuffs_base__status status = wuffs_base__make_status(NULL);
59817 wuffs_base__pixel_format v_dst_pixfmt = {0};
59818 uint32_t v_dst_bits_per_pixel = 0;
59819 uint32_t v_dst_bytes_per_pixel = 0;
59820 uint64_t v_dst_bytes_per_row = 0;
59821 uint32_t v_src_bytes_per_pixel = 0;
59822 wuffs_base__table_u8 v_tab = {0};
59823 wuffs_base__slice_u8 v_dst = {0};
59824 uint64_t v_i = 0;
59825 uint64_t v_j = 0;
59826 uint64_t v_n = 0;
59828 const uint8_t* iop_a_src = NULL;
59829 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
59830 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
59831 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
59832 if (a_src && a_src->data.ptr) {
59833 io0_a_src = a_src->data.ptr;
59834 io1_a_src = io0_a_src + a_src->meta.ri;
59835 iop_a_src = io1_a_src;
59836 io2_a_src = io0_a_src + a_src->meta.wi;
59839 v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
59840 v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
59841 if ((v_dst_bits_per_pixel & 7u) != 0u) {
59842 status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
59843 goto exit;
59845 v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u);
59846 v_dst_bytes_per_row = ((uint64_t)((self->private_impl.f_width * v_dst_bytes_per_pixel)));
59847 v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
59848 while (true) {
59849 if (self->private_impl.f_dst_x == self->private_impl.f_width) {
59850 self->private_impl.f_dst_x = 0u;
59851 self->private_impl.f_dst_y += 1u;
59852 if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
59853 break;
59856 v_dst = wuffs_private_impl__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
59857 if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) {
59858 v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row);
59860 v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_dst_bytes_per_pixel)));
59861 if (v_i >= ((uint64_t)(v_dst.len))) {
59862 v_src_bytes_per_pixel = 4u;
59863 if (self->private_impl.f_pixfmt == 2164308923u) {
59864 v_src_bytes_per_pixel = 8u;
59866 v_n = (((uint64_t)(io2_a_src - iop_a_src)) / ((uint64_t)(v_src_bytes_per_pixel)));
59867 v_n = wuffs_base__u64__min(v_n, ((uint64_t)(((uint32_t)(self->private_impl.f_width - self->private_impl.f_dst_x)))));
59868 v_j = v_n;
59869 while (v_j >= 8u) {
59870 if (((uint64_t)(io2_a_src - iop_a_src)) >= ((uint64_t)((v_src_bytes_per_pixel * 8u)))) {
59871 iop_a_src += (v_src_bytes_per_pixel * 8u);
59873 v_j -= 8u;
59875 while (v_j > 0u) {
59876 if (((uint64_t)(io2_a_src - iop_a_src)) >= ((uint64_t)((v_src_bytes_per_pixel * 1u)))) {
59877 iop_a_src += (v_src_bytes_per_pixel * 1u);
59879 v_j -= 1u;
59881 } else {
59882 v_n = wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(
59883 &self->private_impl.f_swizzler,
59884 wuffs_base__slice_u8__subslice_i(v_dst, v_i),
59885 wuffs_base__pixel_buffer__palette(a_dst),
59886 &iop_a_src,
59887 io2_a_src);
59889 if (v_n == 0u) {
59890 status = wuffs_base__make_status(wuffs_nie__note__internal_note_short_read);
59891 goto ok;
59893 wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n)));
59895 status = wuffs_base__make_status(NULL);
59896 goto ok;
59899 goto exit;
59900 exit:
59901 if (a_src && a_src->data.ptr) {
59902 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
59905 return status;
59908 // -------- func nie.decoder.frame_dirty_rect
59910 WUFFS_BASE__GENERATED_C_CODE
59911 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
59912 wuffs_nie__decoder__frame_dirty_rect(
59913 const wuffs_nie__decoder* self) {
59914 if (!self) {
59915 return wuffs_base__utility__empty_rect_ie_u32();
59917 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
59918 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
59919 return wuffs_base__utility__empty_rect_ie_u32();
59922 return wuffs_base__utility__make_rect_ie_u32(
59925 self->private_impl.f_width,
59926 self->private_impl.f_height);
59929 // -------- func nie.decoder.num_animation_loops
59931 WUFFS_BASE__GENERATED_C_CODE
59932 WUFFS_BASE__MAYBE_STATIC uint32_t
59933 wuffs_nie__decoder__num_animation_loops(
59934 const wuffs_nie__decoder* self) {
59935 if (!self) {
59936 return 0;
59938 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
59939 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
59940 return 0;
59943 return 0u;
59946 // -------- func nie.decoder.num_decoded_frame_configs
59948 WUFFS_BASE__GENERATED_C_CODE
59949 WUFFS_BASE__MAYBE_STATIC uint64_t
59950 wuffs_nie__decoder__num_decoded_frame_configs(
59951 const wuffs_nie__decoder* self) {
59952 if (!self) {
59953 return 0;
59955 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
59956 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
59957 return 0;
59960 if (self->private_impl.f_call_sequence > 32u) {
59961 return 1u;
59963 return 0u;
59966 // -------- func nie.decoder.num_decoded_frames
59968 WUFFS_BASE__GENERATED_C_CODE
59969 WUFFS_BASE__MAYBE_STATIC uint64_t
59970 wuffs_nie__decoder__num_decoded_frames(
59971 const wuffs_nie__decoder* self) {
59972 if (!self) {
59973 return 0;
59975 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
59976 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
59977 return 0;
59980 if (self->private_impl.f_call_sequence > 64u) {
59981 return 1u;
59983 return 0u;
59986 // -------- func nie.decoder.restart_frame
59988 WUFFS_BASE__GENERATED_C_CODE
59989 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
59990 wuffs_nie__decoder__restart_frame(
59991 wuffs_nie__decoder* self,
59992 uint64_t a_index,
59993 uint64_t a_io_position) {
59994 if (!self) {
59995 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
59997 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
59998 return wuffs_base__make_status(
59999 (self->private_impl.magic == WUFFS_BASE__DISABLED)
60000 ? wuffs_base__error__disabled_by_previous_error
60001 : wuffs_base__error__initialize_not_called);
60004 if (self->private_impl.f_call_sequence < 32u) {
60005 return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
60007 if ((a_index != 0u) || (a_io_position != 16u)) {
60008 return wuffs_base__make_status(wuffs_base__error__bad_argument);
60010 self->private_impl.f_call_sequence = 40u;
60011 return wuffs_base__make_status(NULL);
60014 // -------- func nie.decoder.set_report_metadata
60016 WUFFS_BASE__GENERATED_C_CODE
60017 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
60018 wuffs_nie__decoder__set_report_metadata(
60019 wuffs_nie__decoder* self,
60020 uint32_t a_fourcc,
60021 bool a_report) {
60022 return wuffs_base__make_empty_struct();
60025 // -------- func nie.decoder.tell_me_more
60027 WUFFS_BASE__GENERATED_C_CODE
60028 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
60029 wuffs_nie__decoder__tell_me_more(
60030 wuffs_nie__decoder* self,
60031 wuffs_base__io_buffer* a_dst,
60032 wuffs_base__more_information* a_minfo,
60033 wuffs_base__io_buffer* a_src) {
60034 if (!self) {
60035 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
60037 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
60038 return wuffs_base__make_status(
60039 (self->private_impl.magic == WUFFS_BASE__DISABLED)
60040 ? wuffs_base__error__disabled_by_previous_error
60041 : wuffs_base__error__initialize_not_called);
60043 if (!a_dst || !a_src) {
60044 self->private_impl.magic = WUFFS_BASE__DISABLED;
60045 return wuffs_base__make_status(wuffs_base__error__bad_argument);
60047 if ((self->private_impl.active_coroutine != 0) &&
60048 (self->private_impl.active_coroutine != 4)) {
60049 self->private_impl.magic = WUFFS_BASE__DISABLED;
60050 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
60052 self->private_impl.active_coroutine = 0;
60053 wuffs_base__status status = wuffs_base__make_status(NULL);
60055 status = wuffs_base__make_status(wuffs_base__error__no_more_information);
60056 goto exit;
60058 goto ok;
60060 goto exit;
60061 exit:
60062 if (wuffs_base__status__is_error(&status)) {
60063 self->private_impl.magic = WUFFS_BASE__DISABLED;
60065 return status;
60068 // -------- func nie.decoder.workbuf_len
60070 WUFFS_BASE__GENERATED_C_CODE
60071 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
60072 wuffs_nie__decoder__workbuf_len(
60073 const wuffs_nie__decoder* self) {
60074 if (!self) {
60075 return wuffs_base__utility__empty_range_ii_u64();
60077 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
60078 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
60079 return wuffs_base__utility__empty_range_ii_u64();
60082 return wuffs_base__utility__make_range_ii_u64(0u, 0u);
60085 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NIE)
60087 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ZLIB)
60089 // ---------------- Status Codes Implementations
60091 const char wuffs_zlib__note__dictionary_required[] = "@zlib: dictionary required";
60092 const char wuffs_zlib__error__bad_checksum[] = "#zlib: bad checksum";
60093 const char wuffs_zlib__error__bad_compression_method[] = "#zlib: bad compression method";
60094 const char wuffs_zlib__error__bad_compression_window_size[] = "#zlib: bad compression window size";
60095 const char wuffs_zlib__error__bad_parity_check[] = "#zlib: bad parity check";
60096 const char wuffs_zlib__error__incorrect_dictionary[] = "#zlib: incorrect dictionary";
60097 const char wuffs_zlib__error__truncated_input[] = "#zlib: truncated input";
60099 // ---------------- Private Consts
60101 #define WUFFS_ZLIB__QUIRKS_BASE 2113790976u
60103 #define WUFFS_ZLIB__QUIRKS_COUNT 1u
60105 // ---------------- Private Initializer Prototypes
60107 // ---------------- Private Function Prototypes
60109 WUFFS_BASE__GENERATED_C_CODE
60110 static wuffs_base__status
60111 wuffs_zlib__decoder__do_transform_io(
60112 wuffs_zlib__decoder* self,
60113 wuffs_base__io_buffer* a_dst,
60114 wuffs_base__io_buffer* a_src,
60115 wuffs_base__slice_u8 a_workbuf);
60117 // ---------------- VTables
60119 const wuffs_base__io_transformer__func_ptrs
60120 wuffs_zlib__decoder__func_ptrs_for__wuffs_base__io_transformer = {
60121 (wuffs_base__optional_u63(*)(const void*))(&wuffs_zlib__decoder__dst_history_retain_length),
60122 (uint64_t(*)(const void*,
60123 uint32_t))(&wuffs_zlib__decoder__get_quirk),
60124 (wuffs_base__status(*)(void*,
60125 uint32_t,
60126 uint64_t))(&wuffs_zlib__decoder__set_quirk),
60127 (wuffs_base__status(*)(void*,
60128 wuffs_base__io_buffer*,
60129 wuffs_base__io_buffer*,
60130 wuffs_base__slice_u8))(&wuffs_zlib__decoder__transform_io),
60131 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_zlib__decoder__workbuf_len),
60134 // ---------------- Initializer Implementations
60136 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
60137 wuffs_zlib__decoder__initialize(
60138 wuffs_zlib__decoder* self,
60139 size_t sizeof_star_self,
60140 uint64_t wuffs_version,
60141 uint32_t options){
60142 if (!self) {
60143 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
60145 if (sizeof(*self) != sizeof_star_self) {
60146 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
60148 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
60149 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
60150 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
60153 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
60154 // The whole point of this if-check is to detect an uninitialized *self.
60155 // We disable the warning on GCC. Clang-5.0 does not have this warning.
60156 #if !defined(__clang__) && defined(__GNUC__)
60157 #pragma GCC diagnostic push
60158 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
60159 #endif
60160 if (self->private_impl.magic != 0) {
60161 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
60163 #if !defined(__clang__) && defined(__GNUC__)
60164 #pragma GCC diagnostic pop
60165 #endif
60166 } else {
60167 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
60168 memset(self, 0, sizeof(*self));
60169 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
60170 } else {
60171 memset(&(self->private_impl), 0, sizeof(self->private_impl));
60176 wuffs_base__status z = wuffs_adler32__hasher__initialize(
60177 &self->private_data.f_checksum, sizeof(self->private_data.f_checksum), WUFFS_VERSION, options);
60178 if (z.repr) {
60179 return z;
60183 wuffs_base__status z = wuffs_adler32__hasher__initialize(
60184 &self->private_data.f_dict_id_hasher, sizeof(self->private_data.f_dict_id_hasher), WUFFS_VERSION, options);
60185 if (z.repr) {
60186 return z;
60190 wuffs_base__status z = wuffs_deflate__decoder__initialize(
60191 &self->private_data.f_flate, sizeof(self->private_data.f_flate), WUFFS_VERSION, options);
60192 if (z.repr) {
60193 return z;
60196 self->private_impl.magic = WUFFS_BASE__MAGIC;
60197 self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name =
60198 wuffs_base__io_transformer__vtable_name;
60199 self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers =
60200 (const void*)(&wuffs_zlib__decoder__func_ptrs_for__wuffs_base__io_transformer);
60201 return wuffs_base__make_status(NULL);
60204 wuffs_zlib__decoder*
60205 wuffs_zlib__decoder__alloc(void) {
60206 wuffs_zlib__decoder* x =
60207 (wuffs_zlib__decoder*)(calloc(1, sizeof(wuffs_zlib__decoder)));
60208 if (!x) {
60209 return NULL;
60211 if (wuffs_zlib__decoder__initialize(
60212 x, sizeof(wuffs_zlib__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
60213 free(x);
60214 return NULL;
60216 return x;
60219 size_t
60220 sizeof__wuffs_zlib__decoder(void) {
60221 return sizeof(wuffs_zlib__decoder);
60224 // ---------------- Function Implementations
60226 // -------- func zlib.decoder.dictionary_id
60228 WUFFS_BASE__GENERATED_C_CODE
60229 WUFFS_BASE__MAYBE_STATIC uint32_t
60230 wuffs_zlib__decoder__dictionary_id(
60231 const wuffs_zlib__decoder* self) {
60232 if (!self) {
60233 return 0;
60235 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
60236 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
60237 return 0;
60240 return self->private_impl.f_dict_id_want;
60243 // -------- func zlib.decoder.add_dictionary
60245 WUFFS_BASE__GENERATED_C_CODE
60246 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
60247 wuffs_zlib__decoder__add_dictionary(
60248 wuffs_zlib__decoder* self,
60249 wuffs_base__slice_u8 a_dict) {
60250 if (!self) {
60251 return wuffs_base__make_empty_struct();
60253 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
60254 return wuffs_base__make_empty_struct();
60257 if (self->private_impl.f_header_complete) {
60258 self->private_impl.f_bad_call_sequence = true;
60259 } else {
60260 self->private_impl.f_dict_id_have = wuffs_adler32__hasher__update_u32(&self->private_data.f_dict_id_hasher, a_dict);
60261 wuffs_deflate__decoder__add_history(&self->private_data.f_flate, a_dict);
60263 self->private_impl.f_got_dictionary = true;
60264 return wuffs_base__make_empty_struct();
60267 // -------- func zlib.decoder.get_quirk
60269 WUFFS_BASE__GENERATED_C_CODE
60270 WUFFS_BASE__MAYBE_STATIC uint64_t
60271 wuffs_zlib__decoder__get_quirk(
60272 const wuffs_zlib__decoder* self,
60273 uint32_t a_key) {
60274 if (!self) {
60275 return 0;
60277 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
60278 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
60279 return 0;
60282 uint32_t v_key = 0;
60284 if ((a_key == 1u) && self->private_impl.f_ignore_checksum) {
60285 return 1u;
60286 } else if (a_key >= 2113790976u) {
60287 v_key = (a_key - 2113790976u);
60288 if (v_key < 1u) {
60289 if (self->private_impl.f_quirks[v_key]) {
60290 return 1u;
60294 return 0u;
60297 // -------- func zlib.decoder.set_quirk
60299 WUFFS_BASE__GENERATED_C_CODE
60300 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
60301 wuffs_zlib__decoder__set_quirk(
60302 wuffs_zlib__decoder* self,
60303 uint32_t a_key,
60304 uint64_t a_value) {
60305 if (!self) {
60306 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
60308 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
60309 return wuffs_base__make_status(
60310 (self->private_impl.magic == WUFFS_BASE__DISABLED)
60311 ? wuffs_base__error__disabled_by_previous_error
60312 : wuffs_base__error__initialize_not_called);
60315 if (self->private_impl.f_header_complete) {
60316 self->private_impl.f_bad_call_sequence = true;
60317 return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
60318 } else if (a_key == 1u) {
60319 self->private_impl.f_ignore_checksum = (a_value > 0u);
60320 return wuffs_base__make_status(NULL);
60321 } else if (a_key >= 2113790976u) {
60322 a_key -= 2113790976u;
60323 if (a_key < 1u) {
60324 self->private_impl.f_quirks[a_key] = (a_value > 0u);
60325 return wuffs_base__make_status(NULL);
60328 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
60331 // -------- func zlib.decoder.dst_history_retain_length
60333 WUFFS_BASE__GENERATED_C_CODE
60334 WUFFS_BASE__MAYBE_STATIC wuffs_base__optional_u63
60335 wuffs_zlib__decoder__dst_history_retain_length(
60336 const wuffs_zlib__decoder* self) {
60337 if (!self) {
60338 return wuffs_base__utility__make_optional_u63(false, 0u);
60340 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
60341 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
60342 return wuffs_base__utility__make_optional_u63(false, 0u);
60345 return wuffs_base__utility__make_optional_u63(true, 0u);
60348 // -------- func zlib.decoder.workbuf_len
60350 WUFFS_BASE__GENERATED_C_CODE
60351 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
60352 wuffs_zlib__decoder__workbuf_len(
60353 const wuffs_zlib__decoder* self) {
60354 if (!self) {
60355 return wuffs_base__utility__empty_range_ii_u64();
60357 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
60358 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
60359 return wuffs_base__utility__empty_range_ii_u64();
60362 return wuffs_base__utility__make_range_ii_u64(1u, 1u);
60365 // -------- func zlib.decoder.transform_io
60367 WUFFS_BASE__GENERATED_C_CODE
60368 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
60369 wuffs_zlib__decoder__transform_io(
60370 wuffs_zlib__decoder* self,
60371 wuffs_base__io_buffer* a_dst,
60372 wuffs_base__io_buffer* a_src,
60373 wuffs_base__slice_u8 a_workbuf) {
60374 if (!self) {
60375 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
60377 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
60378 return wuffs_base__make_status(
60379 (self->private_impl.magic == WUFFS_BASE__DISABLED)
60380 ? wuffs_base__error__disabled_by_previous_error
60381 : wuffs_base__error__initialize_not_called);
60383 if (!a_dst || !a_src) {
60384 self->private_impl.magic = WUFFS_BASE__DISABLED;
60385 return wuffs_base__make_status(wuffs_base__error__bad_argument);
60387 if ((self->private_impl.active_coroutine != 0) &&
60388 (self->private_impl.active_coroutine != 1)) {
60389 self->private_impl.magic = WUFFS_BASE__DISABLED;
60390 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
60392 self->private_impl.active_coroutine = 0;
60393 wuffs_base__status status = wuffs_base__make_status(NULL);
60395 wuffs_base__status v_status = wuffs_base__make_status(NULL);
60397 uint32_t coro_susp_point = self->private_impl.p_transform_io;
60398 switch (coro_susp_point) {
60399 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
60401 while (true) {
60403 wuffs_base__status t_0 = wuffs_zlib__decoder__do_transform_io(self, a_dst, a_src, a_workbuf);
60404 v_status = t_0;
60406 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
60407 status = wuffs_base__make_status(wuffs_zlib__error__truncated_input);
60408 goto exit;
60410 status = v_status;
60411 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
60415 self->private_impl.p_transform_io = 0;
60416 goto exit;
60419 goto suspend;
60420 suspend:
60421 self->private_impl.p_transform_io = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
60422 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
60424 goto exit;
60425 exit:
60426 if (wuffs_base__status__is_error(&status)) {
60427 self->private_impl.magic = WUFFS_BASE__DISABLED;
60429 return status;
60432 // -------- func zlib.decoder.do_transform_io
60434 WUFFS_BASE__GENERATED_C_CODE
60435 static wuffs_base__status
60436 wuffs_zlib__decoder__do_transform_io(
60437 wuffs_zlib__decoder* self,
60438 wuffs_base__io_buffer* a_dst,
60439 wuffs_base__io_buffer* a_src,
60440 wuffs_base__slice_u8 a_workbuf) {
60441 wuffs_base__status status = wuffs_base__make_status(NULL);
60443 uint16_t v_x = 0;
60444 uint32_t v_checksum_have = 0;
60445 wuffs_base__status v_status = wuffs_base__make_status(NULL);
60446 uint32_t v_checksum_want = 0;
60447 uint64_t v_mark = 0;
60449 uint8_t* iop_a_dst = NULL;
60450 uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
60451 uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
60452 uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
60453 if (a_dst && a_dst->data.ptr) {
60454 io0_a_dst = a_dst->data.ptr;
60455 io1_a_dst = io0_a_dst + a_dst->meta.wi;
60456 iop_a_dst = io1_a_dst;
60457 io2_a_dst = io0_a_dst + a_dst->data.len;
60458 if (a_dst->meta.closed) {
60459 io2_a_dst = iop_a_dst;
60462 const uint8_t* iop_a_src = NULL;
60463 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
60464 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
60465 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
60466 if (a_src && a_src->data.ptr) {
60467 io0_a_src = a_src->data.ptr;
60468 io1_a_src = io0_a_src + a_src->meta.ri;
60469 iop_a_src = io1_a_src;
60470 io2_a_src = io0_a_src + a_src->meta.wi;
60473 uint32_t coro_susp_point = self->private_impl.p_do_transform_io;
60474 if (coro_susp_point) {
60475 v_checksum_have = self->private_data.s_do_transform_io.v_checksum_have;
60477 switch (coro_susp_point) {
60478 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
60480 if (self->private_impl.f_bad_call_sequence) {
60481 status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
60482 goto exit;
60483 } else if (self->private_impl.f_quirks[0u]) {
60484 } else if ( ! self->private_impl.f_want_dictionary) {
60486 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
60487 uint16_t t_0;
60488 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
60489 t_0 = wuffs_base__peek_u16be__no_bounds_check(iop_a_src);
60490 iop_a_src += 2;
60491 } else {
60492 self->private_data.s_do_transform_io.scratch = 0;
60493 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
60494 while (true) {
60495 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
60496 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
60497 goto suspend;
60499 uint64_t* scratch = &self->private_data.s_do_transform_io.scratch;
60500 uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu));
60501 *scratch >>= 8;
60502 *scratch <<= 8;
60503 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
60504 if (num_bits_0 == 8) {
60505 t_0 = ((uint16_t)(*scratch >> 48));
60506 break;
60508 num_bits_0 += 8u;
60509 *scratch |= ((uint64_t)(num_bits_0));
60512 v_x = t_0;
60514 if (((uint16_t)(((uint16_t)(v_x >> 8u)) & 15u)) != 8u) {
60515 status = wuffs_base__make_status(wuffs_zlib__error__bad_compression_method);
60516 goto exit;
60518 if (((uint16_t)(v_x >> 12u)) > 7u) {
60519 status = wuffs_base__make_status(wuffs_zlib__error__bad_compression_window_size);
60520 goto exit;
60522 if (((uint16_t)(v_x % 31u)) != 0u) {
60523 status = wuffs_base__make_status(wuffs_zlib__error__bad_parity_check);
60524 goto exit;
60526 self->private_impl.f_want_dictionary = (((uint16_t)(v_x & 32u)) != 0u);
60527 if (self->private_impl.f_want_dictionary) {
60528 self->private_impl.f_dict_id_have = 1u;
60530 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
60531 uint32_t t_1;
60532 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
60533 t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
60534 iop_a_src += 4;
60535 } else {
60536 self->private_data.s_do_transform_io.scratch = 0;
60537 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
60538 while (true) {
60539 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
60540 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
60541 goto suspend;
60543 uint64_t* scratch = &self->private_data.s_do_transform_io.scratch;
60544 uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu));
60545 *scratch >>= 8;
60546 *scratch <<= 8;
60547 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
60548 if (num_bits_1 == 24) {
60549 t_1 = ((uint32_t)(*scratch >> 32));
60550 break;
60552 num_bits_1 += 8u;
60553 *scratch |= ((uint64_t)(num_bits_1));
60556 self->private_impl.f_dict_id_want = t_1;
60558 status = wuffs_base__make_status(wuffs_zlib__note__dictionary_required);
60559 goto ok;
60560 } else if (self->private_impl.f_got_dictionary) {
60561 status = wuffs_base__make_status(wuffs_zlib__error__incorrect_dictionary);
60562 goto exit;
60564 } else if (self->private_impl.f_dict_id_have != self->private_impl.f_dict_id_want) {
60565 if (self->private_impl.f_got_dictionary) {
60566 status = wuffs_base__make_status(wuffs_zlib__error__incorrect_dictionary);
60567 goto exit;
60569 status = wuffs_base__make_status(wuffs_zlib__note__dictionary_required);
60570 goto ok;
60572 self->private_impl.f_header_complete = true;
60573 while (true) {
60574 v_mark = ((uint64_t)(iop_a_dst - io0_a_dst));
60576 if (a_dst) {
60577 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
60579 if (a_src) {
60580 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
60582 wuffs_base__status t_2 = wuffs_deflate__decoder__transform_io(&self->private_data.f_flate, a_dst, a_src, a_workbuf);
60583 v_status = t_2;
60584 if (a_dst) {
60585 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
60587 if (a_src) {
60588 iop_a_src = a_src->data.ptr + a_src->meta.ri;
60591 if ( ! self->private_impl.f_ignore_checksum && ! self->private_impl.f_quirks[0u]) {
60592 v_checksum_have = wuffs_adler32__hasher__update_u32(&self->private_data.f_checksum, wuffs_private_impl__io__since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst));
60594 if (wuffs_base__status__is_ok(&v_status)) {
60595 break;
60597 status = v_status;
60598 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
60600 if ( ! self->private_impl.f_quirks[0u]) {
60602 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
60603 uint32_t t_3;
60604 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
60605 t_3 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
60606 iop_a_src += 4;
60607 } else {
60608 self->private_data.s_do_transform_io.scratch = 0;
60609 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
60610 while (true) {
60611 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
60612 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
60613 goto suspend;
60615 uint64_t* scratch = &self->private_data.s_do_transform_io.scratch;
60616 uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFFu));
60617 *scratch >>= 8;
60618 *scratch <<= 8;
60619 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3);
60620 if (num_bits_3 == 24) {
60621 t_3 = ((uint32_t)(*scratch >> 32));
60622 break;
60624 num_bits_3 += 8u;
60625 *scratch |= ((uint64_t)(num_bits_3));
60628 v_checksum_want = t_3;
60630 if ( ! self->private_impl.f_ignore_checksum && (v_checksum_have != v_checksum_want)) {
60631 status = wuffs_base__make_status(wuffs_zlib__error__bad_checksum);
60632 goto exit;
60637 self->private_impl.p_do_transform_io = 0;
60638 goto exit;
60641 goto suspend;
60642 suspend:
60643 self->private_impl.p_do_transform_io = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
60644 self->private_data.s_do_transform_io.v_checksum_have = v_checksum_have;
60646 goto exit;
60647 exit:
60648 if (a_dst && a_dst->data.ptr) {
60649 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
60651 if (a_src && a_src->data.ptr) {
60652 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
60655 return status;
60658 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ZLIB)
60660 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__PNG)
60662 // ---------------- Status Codes Implementations
60664 const char wuffs_png__error__bad_animation_sequence_number[] = "#png: bad animation sequence number";
60665 const char wuffs_png__error__bad_checksum[] = "#png: bad checksum";
60666 const char wuffs_png__error__bad_chunk[] = "#png: bad chunk";
60667 const char wuffs_png__error__bad_filter[] = "#png: bad filter";
60668 const char wuffs_png__error__bad_header[] = "#png: bad header";
60669 const char wuffs_png__error__bad_text_chunk_not_latin_1[] = "#png: bad text chunk (not Latin-1)";
60670 const char wuffs_png__error__missing_palette[] = "#png: missing palette";
60671 const char wuffs_png__error__truncated_input[] = "#png: truncated input";
60672 const char wuffs_png__error__unsupported_cgbi_extension[] = "#png: unsupported CgBI extension";
60673 const char wuffs_png__error__unsupported_png_compression_method[] = "#png: unsupported PNG compression method";
60674 const char wuffs_png__error__unsupported_png_file[] = "#png: unsupported PNG file";
60675 const char wuffs_png__error__internal_error_inconsistent_i_o[] = "#png: internal error: inconsistent I/O";
60676 const char wuffs_png__error__internal_error_inconsistent_chunk_type[] = "#png: internal error: inconsistent chunk type";
60677 const char wuffs_png__error__internal_error_inconsistent_workbuf_length[] = "#png: internal error: inconsistent workbuf length";
60678 const char wuffs_png__error__internal_error_zlib_decoder_did_not_exhaust_its_input[] = "#png: internal error: zlib decoder did not exhaust its input";
60680 // ---------------- Private Consts
60682 #define WUFFS_PNG__ANCILLARY_BIT 32u
60684 static const uint8_t
60685 WUFFS_PNG__INTERLACING[8][6] WUFFS_BASE__POTENTIALLY_UNUSED = {
60687 0u, 0u, 0u, 0u, 0u, 0u,
60688 }, {
60689 3u, 7u, 0u, 3u, 7u, 0u,
60690 }, {
60691 3u, 3u, 4u, 3u, 7u, 0u,
60692 }, {
60693 2u, 3u, 0u, 3u, 3u, 4u,
60694 }, {
60695 2u, 1u, 2u, 2u, 3u, 0u,
60696 }, {
60697 1u, 1u, 0u, 2u, 1u, 2u,
60698 }, {
60699 1u, 0u, 1u, 1u, 1u, 0u,
60700 }, {
60701 0u, 0u, 0u, 1u, 0u, 1u,
60705 static const uint8_t
60706 WUFFS_PNG__LOW_BIT_DEPTH_MULTIPLIERS[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
60707 0u, 255u, 85u, 0u, 17u, 0u, 0u, 0u,
60710 static const uint8_t
60711 WUFFS_PNG__LOW_BIT_DEPTH_NUM_PACKS[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
60712 0u, 8u, 4u, 0u, 2u, 0u, 0u, 0u,
60715 static const uint8_t
60716 WUFFS_PNG__NUM_CHANNELS[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
60717 1u, 0u, 3u, 1u, 2u, 0u, 4u, 0u,
60720 static const uint16_t
60721 WUFFS_PNG__LATIN_1[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
60722 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
60723 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
60724 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
60725 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
60726 32u, 33u, 34u, 35u, 36u, 37u, 38u, 39u,
60727 40u, 41u, 42u, 43u, 44u, 45u, 46u, 47u,
60728 48u, 49u, 50u, 51u, 52u, 53u, 54u, 55u,
60729 56u, 57u, 58u, 59u, 60u, 61u, 62u, 63u,
60730 64u, 65u, 66u, 67u, 68u, 69u, 70u, 71u,
60731 72u, 73u, 74u, 75u, 76u, 77u, 78u, 79u,
60732 80u, 81u, 82u, 83u, 84u, 85u, 86u, 87u,
60733 88u, 89u, 90u, 91u, 92u, 93u, 94u, 95u,
60734 96u, 97u, 98u, 99u, 100u, 101u, 102u, 103u,
60735 104u, 105u, 106u, 107u, 108u, 109u, 110u, 111u,
60736 112u, 113u, 114u, 115u, 116u, 117u, 118u, 119u,
60737 120u, 121u, 122u, 123u, 124u, 125u, 126u, 0u,
60738 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
60739 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
60740 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
60741 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
60742 0u, 41410u, 41666u, 41922u, 42178u, 42434u, 42690u, 42946u,
60743 43202u, 43458u, 43714u, 43970u, 44226u, 44482u, 44738u, 44994u,
60744 45250u, 45506u, 45762u, 46018u, 46274u, 46530u, 46786u, 47042u,
60745 47298u, 47554u, 47810u, 48066u, 48322u, 48578u, 48834u, 49090u,
60746 32963u, 33219u, 33475u, 33731u, 33987u, 34243u, 34499u, 34755u,
60747 35011u, 35267u, 35523u, 35779u, 36035u, 36291u, 36547u, 36803u,
60748 37059u, 37315u, 37571u, 37827u, 38083u, 38339u, 38595u, 38851u,
60749 39107u, 39363u, 39619u, 39875u, 40131u, 40387u, 40643u, 40899u,
60750 41155u, 41411u, 41667u, 41923u, 42179u, 42435u, 42691u, 42947u,
60751 43203u, 43459u, 43715u, 43971u, 44227u, 44483u, 44739u, 44995u,
60752 45251u, 45507u, 45763u, 46019u, 46275u, 46531u, 46787u, 47043u,
60753 47299u, 47555u, 47811u, 48067u, 48323u, 48579u, 48835u, 49091u,
60756 // ---------------- Private Initializer Prototypes
60758 // ---------------- Private Function Prototypes
60760 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON)
60761 WUFFS_BASE__GENERATED_C_CODE
60762 static wuffs_base__empty_struct
60763 wuffs_png__decoder__filter_1_distance_4_arm_neon(
60764 wuffs_png__decoder* self,
60765 wuffs_base__slice_u8 a_curr);
60766 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON)
60768 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON)
60769 WUFFS_BASE__GENERATED_C_CODE
60770 static wuffs_base__empty_struct
60771 wuffs_png__decoder__filter_3_distance_4_arm_neon(
60772 wuffs_png__decoder* self,
60773 wuffs_base__slice_u8 a_curr,
60774 wuffs_base__slice_u8 a_prev);
60775 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON)
60777 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON)
60778 WUFFS_BASE__GENERATED_C_CODE
60779 static wuffs_base__empty_struct
60780 wuffs_png__decoder__filter_4_distance_3_arm_neon(
60781 wuffs_png__decoder* self,
60782 wuffs_base__slice_u8 a_curr,
60783 wuffs_base__slice_u8 a_prev);
60784 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON)
60786 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON)
60787 WUFFS_BASE__GENERATED_C_CODE
60788 static wuffs_base__empty_struct
60789 wuffs_png__decoder__filter_4_distance_4_arm_neon(
60790 wuffs_png__decoder* self,
60791 wuffs_base__slice_u8 a_curr,
60792 wuffs_base__slice_u8 a_prev);
60793 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON)
60795 WUFFS_BASE__GENERATED_C_CODE
60796 static wuffs_base__empty_struct
60797 wuffs_png__decoder__filter_1(
60798 wuffs_png__decoder* self,
60799 wuffs_base__slice_u8 a_curr);
60801 WUFFS_BASE__GENERATED_C_CODE
60802 static wuffs_base__empty_struct
60803 wuffs_png__decoder__filter_1__choosy_default(
60804 wuffs_png__decoder* self,
60805 wuffs_base__slice_u8 a_curr);
60807 WUFFS_BASE__GENERATED_C_CODE
60808 static wuffs_base__empty_struct
60809 wuffs_png__decoder__filter_1_distance_3_fallback(
60810 wuffs_png__decoder* self,
60811 wuffs_base__slice_u8 a_curr);
60813 WUFFS_BASE__GENERATED_C_CODE
60814 static wuffs_base__empty_struct
60815 wuffs_png__decoder__filter_1_distance_4_fallback(
60816 wuffs_png__decoder* self,
60817 wuffs_base__slice_u8 a_curr);
60819 WUFFS_BASE__GENERATED_C_CODE
60820 static wuffs_base__empty_struct
60821 wuffs_png__decoder__filter_2(
60822 wuffs_png__decoder* self,
60823 wuffs_base__slice_u8 a_curr,
60824 wuffs_base__slice_u8 a_prev);
60826 WUFFS_BASE__GENERATED_C_CODE
60827 static wuffs_base__empty_struct
60828 wuffs_png__decoder__filter_3(
60829 wuffs_png__decoder* self,
60830 wuffs_base__slice_u8 a_curr,
60831 wuffs_base__slice_u8 a_prev);
60833 WUFFS_BASE__GENERATED_C_CODE
60834 static wuffs_base__empty_struct
60835 wuffs_png__decoder__filter_3__choosy_default(
60836 wuffs_png__decoder* self,
60837 wuffs_base__slice_u8 a_curr,
60838 wuffs_base__slice_u8 a_prev);
60840 WUFFS_BASE__GENERATED_C_CODE
60841 static wuffs_base__empty_struct
60842 wuffs_png__decoder__filter_3_distance_3_fallback(
60843 wuffs_png__decoder* self,
60844 wuffs_base__slice_u8 a_curr,
60845 wuffs_base__slice_u8 a_prev);
60847 WUFFS_BASE__GENERATED_C_CODE
60848 static wuffs_base__empty_struct
60849 wuffs_png__decoder__filter_3_distance_4_fallback(
60850 wuffs_png__decoder* self,
60851 wuffs_base__slice_u8 a_curr,
60852 wuffs_base__slice_u8 a_prev);
60854 WUFFS_BASE__GENERATED_C_CODE
60855 static wuffs_base__empty_struct
60856 wuffs_png__decoder__filter_4(
60857 wuffs_png__decoder* self,
60858 wuffs_base__slice_u8 a_curr,
60859 wuffs_base__slice_u8 a_prev);
60861 WUFFS_BASE__GENERATED_C_CODE
60862 static wuffs_base__empty_struct
60863 wuffs_png__decoder__filter_4__choosy_default(
60864 wuffs_png__decoder* self,
60865 wuffs_base__slice_u8 a_curr,
60866 wuffs_base__slice_u8 a_prev);
60868 WUFFS_BASE__GENERATED_C_CODE
60869 static wuffs_base__empty_struct
60870 wuffs_png__decoder__filter_4_distance_3_fallback(
60871 wuffs_png__decoder* self,
60872 wuffs_base__slice_u8 a_curr,
60873 wuffs_base__slice_u8 a_prev);
60875 WUFFS_BASE__GENERATED_C_CODE
60876 static wuffs_base__empty_struct
60877 wuffs_png__decoder__filter_4_distance_4_fallback(
60878 wuffs_png__decoder* self,
60879 wuffs_base__slice_u8 a_curr,
60880 wuffs_base__slice_u8 a_prev);
60882 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
60883 WUFFS_BASE__GENERATED_C_CODE
60884 static wuffs_base__empty_struct
60885 wuffs_png__decoder__filter_1_distance_4_x86_sse42(
60886 wuffs_png__decoder* self,
60887 wuffs_base__slice_u8 a_curr);
60888 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
60890 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
60891 WUFFS_BASE__GENERATED_C_CODE
60892 static wuffs_base__empty_struct
60893 wuffs_png__decoder__filter_3_distance_4_x86_sse42(
60894 wuffs_png__decoder* self,
60895 wuffs_base__slice_u8 a_curr,
60896 wuffs_base__slice_u8 a_prev);
60897 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
60899 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
60900 WUFFS_BASE__GENERATED_C_CODE
60901 static wuffs_base__empty_struct
60902 wuffs_png__decoder__filter_4_distance_3_x86_sse42(
60903 wuffs_png__decoder* self,
60904 wuffs_base__slice_u8 a_curr,
60905 wuffs_base__slice_u8 a_prev);
60906 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
60908 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
60909 WUFFS_BASE__GENERATED_C_CODE
60910 static wuffs_base__empty_struct
60911 wuffs_png__decoder__filter_4_distance_4_x86_sse42(
60912 wuffs_png__decoder* self,
60913 wuffs_base__slice_u8 a_curr,
60914 wuffs_base__slice_u8 a_prev);
60915 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
60917 WUFFS_BASE__GENERATED_C_CODE
60918 static wuffs_base__status
60919 wuffs_png__decoder__do_decode_image_config(
60920 wuffs_png__decoder* self,
60921 wuffs_base__image_config* a_dst,
60922 wuffs_base__io_buffer* a_src);
60924 WUFFS_BASE__GENERATED_C_CODE
60925 static wuffs_base__status
60926 wuffs_png__decoder__decode_ihdr(
60927 wuffs_png__decoder* self,
60928 wuffs_base__io_buffer* a_src);
60930 WUFFS_BASE__GENERATED_C_CODE
60931 static wuffs_base__empty_struct
60932 wuffs_png__decoder__assign_filter_distance(
60933 wuffs_png__decoder* self);
60935 WUFFS_BASE__GENERATED_C_CODE
60936 static uint64_t
60937 wuffs_png__decoder__calculate_bytes_per_row(
60938 const wuffs_png__decoder* self,
60939 uint32_t a_width);
60941 WUFFS_BASE__GENERATED_C_CODE
60942 static wuffs_base__empty_struct
60943 wuffs_png__decoder__choose_filter_implementations(
60944 wuffs_png__decoder* self);
60946 WUFFS_BASE__GENERATED_C_CODE
60947 static wuffs_base__status
60948 wuffs_png__decoder__decode_other_chunk(
60949 wuffs_png__decoder* self,
60950 wuffs_base__io_buffer* a_src,
60951 bool a_framy);
60953 WUFFS_BASE__GENERATED_C_CODE
60954 static wuffs_base__status
60955 wuffs_png__decoder__decode_actl(
60956 wuffs_png__decoder* self,
60957 wuffs_base__io_buffer* a_src);
60959 WUFFS_BASE__GENERATED_C_CODE
60960 static wuffs_base__status
60961 wuffs_png__decoder__decode_chrm(
60962 wuffs_png__decoder* self,
60963 wuffs_base__io_buffer* a_src);
60965 WUFFS_BASE__GENERATED_C_CODE
60966 static wuffs_base__status
60967 wuffs_png__decoder__decode_exif(
60968 wuffs_png__decoder* self,
60969 wuffs_base__io_buffer* a_src);
60971 WUFFS_BASE__GENERATED_C_CODE
60972 static wuffs_base__status
60973 wuffs_png__decoder__decode_fctl(
60974 wuffs_png__decoder* self,
60975 wuffs_base__io_buffer* a_src);
60977 WUFFS_BASE__GENERATED_C_CODE
60978 static wuffs_base__status
60979 wuffs_png__decoder__decode_gama(
60980 wuffs_png__decoder* self,
60981 wuffs_base__io_buffer* a_src);
60983 WUFFS_BASE__GENERATED_C_CODE
60984 static wuffs_base__status
60985 wuffs_png__decoder__decode_iccp(
60986 wuffs_png__decoder* self,
60987 wuffs_base__io_buffer* a_src);
60989 WUFFS_BASE__GENERATED_C_CODE
60990 static wuffs_base__status
60991 wuffs_png__decoder__decode_plte(
60992 wuffs_png__decoder* self,
60993 wuffs_base__io_buffer* a_src);
60995 WUFFS_BASE__GENERATED_C_CODE
60996 static wuffs_base__status
60997 wuffs_png__decoder__decode_srgb(
60998 wuffs_png__decoder* self,
60999 wuffs_base__io_buffer* a_src);
61001 WUFFS_BASE__GENERATED_C_CODE
61002 static wuffs_base__status
61003 wuffs_png__decoder__decode_trns(
61004 wuffs_png__decoder* self,
61005 wuffs_base__io_buffer* a_src);
61007 WUFFS_BASE__GENERATED_C_CODE
61008 static wuffs_base__status
61009 wuffs_png__decoder__do_decode_frame_config(
61010 wuffs_png__decoder* self,
61011 wuffs_base__frame_config* a_dst,
61012 wuffs_base__io_buffer* a_src);
61014 WUFFS_BASE__GENERATED_C_CODE
61015 static wuffs_base__status
61016 wuffs_png__decoder__skip_frame(
61017 wuffs_png__decoder* self,
61018 wuffs_base__io_buffer* a_src);
61020 WUFFS_BASE__GENERATED_C_CODE
61021 static wuffs_base__status
61022 wuffs_png__decoder__do_decode_frame(
61023 wuffs_png__decoder* self,
61024 wuffs_base__pixel_buffer* a_dst,
61025 wuffs_base__io_buffer* a_src,
61026 wuffs_base__pixel_blend a_blend,
61027 wuffs_base__slice_u8 a_workbuf,
61028 wuffs_base__decode_frame_options* a_opts);
61030 WUFFS_BASE__GENERATED_C_CODE
61031 static wuffs_base__status
61032 wuffs_png__decoder__decode_pass(
61033 wuffs_png__decoder* self,
61034 wuffs_base__io_buffer* a_src,
61035 wuffs_base__slice_u8 a_workbuf);
61037 WUFFS_BASE__GENERATED_C_CODE
61038 static wuffs_base__status
61039 wuffs_png__decoder__do_tell_me_more(
61040 wuffs_png__decoder* self,
61041 wuffs_base__io_buffer* a_dst,
61042 wuffs_base__more_information* a_minfo,
61043 wuffs_base__io_buffer* a_src);
61045 WUFFS_BASE__GENERATED_C_CODE
61046 static wuffs_base__status
61047 wuffs_png__decoder__filter_and_swizzle(
61048 wuffs_png__decoder* self,
61049 wuffs_base__pixel_buffer* a_dst,
61050 wuffs_base__slice_u8 a_workbuf);
61052 WUFFS_BASE__GENERATED_C_CODE
61053 static wuffs_base__status
61054 wuffs_png__decoder__filter_and_swizzle__choosy_default(
61055 wuffs_png__decoder* self,
61056 wuffs_base__pixel_buffer* a_dst,
61057 wuffs_base__slice_u8 a_workbuf);
61059 WUFFS_BASE__GENERATED_C_CODE
61060 static wuffs_base__status
61061 wuffs_png__decoder__filter_and_swizzle_tricky(
61062 wuffs_png__decoder* self,
61063 wuffs_base__pixel_buffer* a_dst,
61064 wuffs_base__slice_u8 a_workbuf);
61066 // ---------------- VTables
61068 const wuffs_base__image_decoder__func_ptrs
61069 wuffs_png__decoder__func_ptrs_for__wuffs_base__image_decoder = {
61070 (wuffs_base__status(*)(void*,
61071 wuffs_base__pixel_buffer*,
61072 wuffs_base__io_buffer*,
61073 wuffs_base__pixel_blend,
61074 wuffs_base__slice_u8,
61075 wuffs_base__decode_frame_options*))(&wuffs_png__decoder__decode_frame),
61076 (wuffs_base__status(*)(void*,
61077 wuffs_base__frame_config*,
61078 wuffs_base__io_buffer*))(&wuffs_png__decoder__decode_frame_config),
61079 (wuffs_base__status(*)(void*,
61080 wuffs_base__image_config*,
61081 wuffs_base__io_buffer*))(&wuffs_png__decoder__decode_image_config),
61082 (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_png__decoder__frame_dirty_rect),
61083 (uint64_t(*)(const void*,
61084 uint32_t))(&wuffs_png__decoder__get_quirk),
61085 (uint32_t(*)(const void*))(&wuffs_png__decoder__num_animation_loops),
61086 (uint64_t(*)(const void*))(&wuffs_png__decoder__num_decoded_frame_configs),
61087 (uint64_t(*)(const void*))(&wuffs_png__decoder__num_decoded_frames),
61088 (wuffs_base__status(*)(void*,
61089 uint64_t,
61090 uint64_t))(&wuffs_png__decoder__restart_frame),
61091 (wuffs_base__status(*)(void*,
61092 uint32_t,
61093 uint64_t))(&wuffs_png__decoder__set_quirk),
61094 (wuffs_base__empty_struct(*)(void*,
61095 uint32_t,
61096 bool))(&wuffs_png__decoder__set_report_metadata),
61097 (wuffs_base__status(*)(void*,
61098 wuffs_base__io_buffer*,
61099 wuffs_base__more_information*,
61100 wuffs_base__io_buffer*))(&wuffs_png__decoder__tell_me_more),
61101 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_png__decoder__workbuf_len),
61104 // ---------------- Initializer Implementations
61106 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
61107 wuffs_png__decoder__initialize(
61108 wuffs_png__decoder* self,
61109 size_t sizeof_star_self,
61110 uint64_t wuffs_version,
61111 uint32_t options){
61112 if (!self) {
61113 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
61115 if (sizeof(*self) != sizeof_star_self) {
61116 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
61118 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
61119 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
61120 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
61123 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
61124 // The whole point of this if-check is to detect an uninitialized *self.
61125 // We disable the warning on GCC. Clang-5.0 does not have this warning.
61126 #if !defined(__clang__) && defined(__GNUC__)
61127 #pragma GCC diagnostic push
61128 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
61129 #endif
61130 if (self->private_impl.magic != 0) {
61131 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
61133 #if !defined(__clang__) && defined(__GNUC__)
61134 #pragma GCC diagnostic pop
61135 #endif
61136 } else {
61137 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
61138 memset(self, 0, sizeof(*self));
61139 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
61140 } else {
61141 memset(&(self->private_impl), 0, sizeof(self->private_impl));
61145 self->private_impl.choosy_filter_1 = &wuffs_png__decoder__filter_1__choosy_default;
61146 self->private_impl.choosy_filter_3 = &wuffs_png__decoder__filter_3__choosy_default;
61147 self->private_impl.choosy_filter_4 = &wuffs_png__decoder__filter_4__choosy_default;
61148 self->private_impl.choosy_filter_and_swizzle = &wuffs_png__decoder__filter_and_swizzle__choosy_default;
61151 wuffs_base__status z = wuffs_crc32__ieee_hasher__initialize(
61152 &self->private_data.f_crc32, sizeof(self->private_data.f_crc32), WUFFS_VERSION, options);
61153 if (z.repr) {
61154 return z;
61158 wuffs_base__status z = wuffs_zlib__decoder__initialize(
61159 &self->private_data.f_zlib, sizeof(self->private_data.f_zlib), WUFFS_VERSION, options);
61160 if (z.repr) {
61161 return z;
61164 self->private_impl.magic = WUFFS_BASE__MAGIC;
61165 self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
61166 wuffs_base__image_decoder__vtable_name;
61167 self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
61168 (const void*)(&wuffs_png__decoder__func_ptrs_for__wuffs_base__image_decoder);
61169 return wuffs_base__make_status(NULL);
61172 wuffs_png__decoder*
61173 wuffs_png__decoder__alloc(void) {
61174 wuffs_png__decoder* x =
61175 (wuffs_png__decoder*)(calloc(1, sizeof(wuffs_png__decoder)));
61176 if (!x) {
61177 return NULL;
61179 if (wuffs_png__decoder__initialize(
61180 x, sizeof(wuffs_png__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
61181 free(x);
61182 return NULL;
61184 return x;
61187 size_t
61188 sizeof__wuffs_png__decoder(void) {
61189 return sizeof(wuffs_png__decoder);
61192 // ---------------- Function Implementations
61194 // ‼ WUFFS MULTI-FILE SECTION +arm_neon
61195 // -------- func png.decoder.filter_1_distance_4_arm_neon
61197 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON)
61198 WUFFS_BASE__GENERATED_C_CODE
61199 static wuffs_base__empty_struct
61200 wuffs_png__decoder__filter_1_distance_4_arm_neon(
61201 wuffs_png__decoder* self,
61202 wuffs_base__slice_u8 a_curr) {
61203 wuffs_base__slice_u8 v_curr = {0};
61204 uint8x8_t v_fa = {0};
61205 uint8x8_t v_fx = {0};
61208 wuffs_base__slice_u8 i_slice_curr = a_curr;
61209 v_curr.ptr = i_slice_curr.ptr;
61210 v_curr.len = 4;
61211 const uint8_t* i_end0_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8));
61212 while (v_curr.ptr < i_end0_curr) {
61213 v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
61214 v_fx = vadd_u8(v_fx, v_fa);
61215 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
61216 v_fa = v_fx;
61217 v_curr.ptr += 4;
61218 v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
61219 v_fx = vadd_u8(v_fx, v_fa);
61220 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
61221 v_fa = v_fx;
61222 v_curr.ptr += 4;
61224 v_curr.len = 4;
61225 const uint8_t* i_end1_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4));
61226 while (v_curr.ptr < i_end1_curr) {
61227 v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
61228 v_fx = vadd_u8(v_fx, v_fa);
61229 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
61230 v_fa = v_fx;
61231 v_curr.ptr += 4;
61233 v_curr.len = 0;
61235 return wuffs_base__make_empty_struct();
61237 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON)
61238 // ‼ WUFFS MULTI-FILE SECTION -arm_neon
61240 // ‼ WUFFS MULTI-FILE SECTION +arm_neon
61241 // -------- func png.decoder.filter_3_distance_4_arm_neon
61243 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON)
61244 WUFFS_BASE__GENERATED_C_CODE
61245 static wuffs_base__empty_struct
61246 wuffs_png__decoder__filter_3_distance_4_arm_neon(
61247 wuffs_png__decoder* self,
61248 wuffs_base__slice_u8 a_curr,
61249 wuffs_base__slice_u8 a_prev) {
61250 wuffs_base__slice_u8 v_curr = {0};
61251 wuffs_base__slice_u8 v_prev = {0};
61252 uint8x8_t v_fa = {0};
61253 uint8x8_t v_fb = {0};
61254 uint8x8_t v_fx = {0};
61256 if (((uint64_t)(a_prev.len)) == 0u) {
61258 wuffs_base__slice_u8 i_slice_curr = a_curr;
61259 v_curr.ptr = i_slice_curr.ptr;
61260 v_curr.len = 4;
61261 const uint8_t* i_end0_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8));
61262 while (v_curr.ptr < i_end0_curr) {
61263 v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
61264 v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb));
61265 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
61266 v_fa = v_fx;
61267 v_curr.ptr += 4;
61268 v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
61269 v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb));
61270 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
61271 v_fa = v_fx;
61272 v_curr.ptr += 4;
61274 v_curr.len = 4;
61275 const uint8_t* i_end1_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4));
61276 while (v_curr.ptr < i_end1_curr) {
61277 v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
61278 v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb));
61279 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
61280 v_fa = v_fx;
61281 v_curr.ptr += 4;
61283 v_curr.len = 0;
61285 } else {
61287 wuffs_base__slice_u8 i_slice_curr = a_curr;
61288 v_curr.ptr = i_slice_curr.ptr;
61289 wuffs_base__slice_u8 i_slice_prev = a_prev;
61290 v_prev.ptr = i_slice_prev.ptr;
61291 i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
61292 v_curr.len = 4;
61293 v_prev.len = 4;
61294 const uint8_t* i_end0_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8));
61295 while (v_curr.ptr < i_end0_curr) {
61296 v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
61297 v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
61298 v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb));
61299 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
61300 v_fa = v_fx;
61301 v_curr.ptr += 4;
61302 v_prev.ptr += 4;
61303 v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
61304 v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
61305 v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb));
61306 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
61307 v_fa = v_fx;
61308 v_curr.ptr += 4;
61309 v_prev.ptr += 4;
61311 v_curr.len = 4;
61312 v_prev.len = 4;
61313 const uint8_t* i_end1_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4));
61314 while (v_curr.ptr < i_end1_curr) {
61315 v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
61316 v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
61317 v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb));
61318 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
61319 v_fa = v_fx;
61320 v_curr.ptr += 4;
61321 v_prev.ptr += 4;
61323 v_curr.len = 0;
61324 v_prev.len = 0;
61327 return wuffs_base__make_empty_struct();
61329 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON)
61330 // ‼ WUFFS MULTI-FILE SECTION -arm_neon
61332 // ‼ WUFFS MULTI-FILE SECTION +arm_neon
61333 // -------- func png.decoder.filter_4_distance_3_arm_neon
61335 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON)
61336 WUFFS_BASE__GENERATED_C_CODE
61337 static wuffs_base__empty_struct
61338 wuffs_png__decoder__filter_4_distance_3_arm_neon(
61339 wuffs_png__decoder* self,
61340 wuffs_base__slice_u8 a_curr,
61341 wuffs_base__slice_u8 a_prev) {
61342 wuffs_base__slice_u8 v_curr = {0};
61343 wuffs_base__slice_u8 v_prev = {0};
61344 uint8x8_t v_fa = {0};
61345 uint8x8_t v_fb = {0};
61346 uint8x8_t v_fc = {0};
61347 uint8x8_t v_fx = {0};
61348 uint16x8_t v_fafb = {0};
61349 uint16x8_t v_fcfc = {0};
61350 uint16x8_t v_pa = {0};
61351 uint16x8_t v_pb = {0};
61352 uint16x8_t v_pc = {0};
61353 uint16x8_t v_cmpab = {0};
61354 uint16x8_t v_cmpac = {0};
61355 uint8x8_t v_picka = {0};
61356 uint8x8_t v_pickb = {0};
61359 wuffs_base__slice_u8 i_slice_curr = a_curr;
61360 v_curr.ptr = i_slice_curr.ptr;
61361 wuffs_base__slice_u8 i_slice_prev = a_prev;
61362 v_prev.ptr = i_slice_prev.ptr;
61363 i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
61364 v_curr.len = 4;
61365 v_prev.len = 4;
61366 const uint8_t* i_end0_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, wuffs_private_impl__iterate_total_advance((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)), 7, 6));
61367 while (v_curr.ptr < i_end0_curr) {
61368 v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
61369 v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
61370 v_fafb = vaddl_u8(v_fa, v_fb);
61371 v_fcfc = vaddl_u8(v_fc, v_fc);
61372 v_pa = vabdl_u8(v_fb, v_fc);
61373 v_pb = vabdl_u8(v_fa, v_fc);
61374 v_pc = vabdq_u16(v_fafb, v_fcfc);
61375 v_cmpab = vcleq_u16(v_pa, v_pb);
61376 v_cmpac = vcleq_u16(v_pa, v_pc);
61377 v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
61378 v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
61379 v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
61380 wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
61381 v_fc = v_fb;
61382 v_fa = v_fx;
61383 v_curr.ptr += 3;
61384 v_prev.ptr += 3;
61385 v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
61386 v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
61387 v_fafb = vaddl_u8(v_fa, v_fb);
61388 v_fcfc = vaddl_u8(v_fc, v_fc);
61389 v_pa = vabdl_u8(v_fb, v_fc);
61390 v_pb = vabdl_u8(v_fa, v_fc);
61391 v_pc = vabdq_u16(v_fafb, v_fcfc);
61392 v_cmpab = vcleq_u16(v_pa, v_pb);
61393 v_cmpac = vcleq_u16(v_pa, v_pc);
61394 v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
61395 v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
61396 v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
61397 wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
61398 v_fc = v_fb;
61399 v_fa = v_fx;
61400 v_curr.ptr += 3;
61401 v_prev.ptr += 3;
61403 v_curr.len = 4;
61404 v_prev.len = 4;
61405 const uint8_t* i_end1_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, wuffs_private_impl__iterate_total_advance((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)), 4, 3));
61406 while (v_curr.ptr < i_end1_curr) {
61407 v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
61408 v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
61409 v_fafb = vaddl_u8(v_fa, v_fb);
61410 v_fcfc = vaddl_u8(v_fc, v_fc);
61411 v_pa = vabdl_u8(v_fb, v_fc);
61412 v_pb = vabdl_u8(v_fa, v_fc);
61413 v_pc = vabdq_u16(v_fafb, v_fcfc);
61414 v_cmpab = vcleq_u16(v_pa, v_pb);
61415 v_cmpac = vcleq_u16(v_pa, v_pc);
61416 v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
61417 v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
61418 v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
61419 wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
61420 v_fc = v_fb;
61421 v_fa = v_fx;
61422 v_curr.ptr += 3;
61423 v_prev.ptr += 3;
61425 v_curr.len = 3;
61426 v_prev.len = 3;
61427 const uint8_t* i_end2_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3));
61428 while (v_curr.ptr < i_end2_curr) {
61429 v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u24le__no_bounds_check(v_prev.ptr)));
61430 v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u24le__no_bounds_check(v_curr.ptr)));
61431 v_fafb = vaddl_u8(v_fa, v_fb);
61432 v_fcfc = vaddl_u8(v_fc, v_fc);
61433 v_pa = vabdl_u8(v_fb, v_fc);
61434 v_pb = vabdl_u8(v_fa, v_fc);
61435 v_pc = vabdq_u16(v_fafb, v_fcfc);
61436 v_cmpab = vcleq_u16(v_pa, v_pb);
61437 v_cmpac = vcleq_u16(v_pa, v_pc);
61438 v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
61439 v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
61440 v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
61441 wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
61442 v_curr.ptr += 3;
61443 v_prev.ptr += 3;
61445 v_curr.len = 0;
61446 v_prev.len = 0;
61448 return wuffs_base__make_empty_struct();
61450 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON)
61451 // ‼ WUFFS MULTI-FILE SECTION -arm_neon
61453 // ‼ WUFFS MULTI-FILE SECTION +arm_neon
61454 // -------- func png.decoder.filter_4_distance_4_arm_neon
61456 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON)
61457 WUFFS_BASE__GENERATED_C_CODE
61458 static wuffs_base__empty_struct
61459 wuffs_png__decoder__filter_4_distance_4_arm_neon(
61460 wuffs_png__decoder* self,
61461 wuffs_base__slice_u8 a_curr,
61462 wuffs_base__slice_u8 a_prev) {
61463 wuffs_base__slice_u8 v_curr = {0};
61464 wuffs_base__slice_u8 v_prev = {0};
61465 uint8x8_t v_fa = {0};
61466 uint8x8_t v_fb = {0};
61467 uint8x8_t v_fc = {0};
61468 uint8x8_t v_fx = {0};
61469 uint16x8_t v_fafb = {0};
61470 uint16x8_t v_fcfc = {0};
61471 uint16x8_t v_pa = {0};
61472 uint16x8_t v_pb = {0};
61473 uint16x8_t v_pc = {0};
61474 uint16x8_t v_cmpab = {0};
61475 uint16x8_t v_cmpac = {0};
61476 uint8x8_t v_picka = {0};
61477 uint8x8_t v_pickb = {0};
61480 wuffs_base__slice_u8 i_slice_curr = a_curr;
61481 v_curr.ptr = i_slice_curr.ptr;
61482 wuffs_base__slice_u8 i_slice_prev = a_prev;
61483 v_prev.ptr = i_slice_prev.ptr;
61484 i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
61485 v_curr.len = 4;
61486 v_prev.len = 4;
61487 const uint8_t* i_end0_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8));
61488 while (v_curr.ptr < i_end0_curr) {
61489 v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
61490 v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
61491 v_fafb = vaddl_u8(v_fa, v_fb);
61492 v_fcfc = vaddl_u8(v_fc, v_fc);
61493 v_pa = vabdl_u8(v_fb, v_fc);
61494 v_pb = vabdl_u8(v_fa, v_fc);
61495 v_pc = vabdq_u16(v_fafb, v_fcfc);
61496 v_cmpab = vcleq_u16(v_pa, v_pb);
61497 v_cmpac = vcleq_u16(v_pa, v_pc);
61498 v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
61499 v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
61500 v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
61501 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
61502 v_fc = v_fb;
61503 v_fa = v_fx;
61504 v_curr.ptr += 4;
61505 v_prev.ptr += 4;
61506 v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
61507 v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
61508 v_fafb = vaddl_u8(v_fa, v_fb);
61509 v_fcfc = vaddl_u8(v_fc, v_fc);
61510 v_pa = vabdl_u8(v_fb, v_fc);
61511 v_pb = vabdl_u8(v_fa, v_fc);
61512 v_pc = vabdq_u16(v_fafb, v_fcfc);
61513 v_cmpab = vcleq_u16(v_pa, v_pb);
61514 v_cmpac = vcleq_u16(v_pa, v_pc);
61515 v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
61516 v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
61517 v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
61518 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
61519 v_fc = v_fb;
61520 v_fa = v_fx;
61521 v_curr.ptr += 4;
61522 v_prev.ptr += 4;
61524 v_curr.len = 4;
61525 v_prev.len = 4;
61526 const uint8_t* i_end1_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4));
61527 while (v_curr.ptr < i_end1_curr) {
61528 v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
61529 v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
61530 v_fafb = vaddl_u8(v_fa, v_fb);
61531 v_fcfc = vaddl_u8(v_fc, v_fc);
61532 v_pa = vabdl_u8(v_fb, v_fc);
61533 v_pb = vabdl_u8(v_fa, v_fc);
61534 v_pc = vabdq_u16(v_fafb, v_fcfc);
61535 v_cmpab = vcleq_u16(v_pa, v_pb);
61536 v_cmpac = vcleq_u16(v_pa, v_pc);
61537 v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
61538 v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
61539 v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
61540 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
61541 v_fc = v_fb;
61542 v_fa = v_fx;
61543 v_curr.ptr += 4;
61544 v_prev.ptr += 4;
61546 v_curr.len = 0;
61547 v_prev.len = 0;
61549 return wuffs_base__make_empty_struct();
61551 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON)
61552 // ‼ WUFFS MULTI-FILE SECTION -arm_neon
61554 // -------- func png.decoder.filter_1
61556 WUFFS_BASE__GENERATED_C_CODE
61557 static wuffs_base__empty_struct
61558 wuffs_png__decoder__filter_1(
61559 wuffs_png__decoder* self,
61560 wuffs_base__slice_u8 a_curr) {
61561 return (*self->private_impl.choosy_filter_1)(self, a_curr);
61564 WUFFS_BASE__GENERATED_C_CODE
61565 static wuffs_base__empty_struct
61566 wuffs_png__decoder__filter_1__choosy_default(
61567 wuffs_png__decoder* self,
61568 wuffs_base__slice_u8 a_curr) {
61569 uint64_t v_filter_distance = 0;
61570 uint8_t v_fa = 0;
61571 uint64_t v_i_start = 0;
61572 uint64_t v_i = 0;
61574 v_filter_distance = ((uint64_t)(self->private_impl.f_filter_distance));
61575 v_i_start = 0u;
61576 while (v_i_start < v_filter_distance) {
61577 v_fa = 0u;
61578 v_i = v_i_start;
61579 while (v_i < ((uint64_t)(a_curr.len))) {
61580 a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + v_fa));
61581 v_fa = a_curr.ptr[v_i];
61582 v_i += v_filter_distance;
61584 v_i_start += 1u;
61586 return wuffs_base__make_empty_struct();
61589 // -------- func png.decoder.filter_1_distance_3_fallback
61591 WUFFS_BASE__GENERATED_C_CODE
61592 static wuffs_base__empty_struct
61593 wuffs_png__decoder__filter_1_distance_3_fallback(
61594 wuffs_png__decoder* self,
61595 wuffs_base__slice_u8 a_curr) {
61596 wuffs_base__slice_u8 v_curr = {0};
61597 uint8_t v_fa0 = 0;
61598 uint8_t v_fa1 = 0;
61599 uint8_t v_fa2 = 0;
61602 wuffs_base__slice_u8 i_slice_curr = a_curr;
61603 v_curr.ptr = i_slice_curr.ptr;
61604 v_curr.len = 3;
61605 const uint8_t* i_end0_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 6) * 6));
61606 while (v_curr.ptr < i_end0_curr) {
61607 v_fa0 = ((uint8_t)(v_fa0 + v_curr.ptr[0u]));
61608 v_curr.ptr[0u] = v_fa0;
61609 v_fa1 = ((uint8_t)(v_fa1 + v_curr.ptr[1u]));
61610 v_curr.ptr[1u] = v_fa1;
61611 v_fa2 = ((uint8_t)(v_fa2 + v_curr.ptr[2u]));
61612 v_curr.ptr[2u] = v_fa2;
61613 v_curr.ptr += 3;
61614 v_fa0 = ((uint8_t)(v_fa0 + v_curr.ptr[0u]));
61615 v_curr.ptr[0u] = v_fa0;
61616 v_fa1 = ((uint8_t)(v_fa1 + v_curr.ptr[1u]));
61617 v_curr.ptr[1u] = v_fa1;
61618 v_fa2 = ((uint8_t)(v_fa2 + v_curr.ptr[2u]));
61619 v_curr.ptr[2u] = v_fa2;
61620 v_curr.ptr += 3;
61622 v_curr.len = 3;
61623 const uint8_t* i_end1_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3));
61624 while (v_curr.ptr < i_end1_curr) {
61625 v_fa0 = ((uint8_t)(v_fa0 + v_curr.ptr[0u]));
61626 v_curr.ptr[0u] = v_fa0;
61627 v_fa1 = ((uint8_t)(v_fa1 + v_curr.ptr[1u]));
61628 v_curr.ptr[1u] = v_fa1;
61629 v_fa2 = ((uint8_t)(v_fa2 + v_curr.ptr[2u]));
61630 v_curr.ptr[2u] = v_fa2;
61631 v_curr.ptr += 3;
61633 v_curr.len = 0;
61635 return wuffs_base__make_empty_struct();
61638 // -------- func png.decoder.filter_1_distance_4_fallback
61640 WUFFS_BASE__GENERATED_C_CODE
61641 static wuffs_base__empty_struct
61642 wuffs_png__decoder__filter_1_distance_4_fallback(
61643 wuffs_png__decoder* self,
61644 wuffs_base__slice_u8 a_curr) {
61645 wuffs_base__slice_u8 v_curr = {0};
61646 uint8_t v_fa0 = 0;
61647 uint8_t v_fa1 = 0;
61648 uint8_t v_fa2 = 0;
61649 uint8_t v_fa3 = 0;
61652 wuffs_base__slice_u8 i_slice_curr = a_curr;
61653 v_curr.ptr = i_slice_curr.ptr;
61654 v_curr.len = 4;
61655 const uint8_t* i_end0_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4));
61656 while (v_curr.ptr < i_end0_curr) {
61657 v_fa0 = ((uint8_t)(v_fa0 + v_curr.ptr[0u]));
61658 v_curr.ptr[0u] = v_fa0;
61659 v_fa1 = ((uint8_t)(v_fa1 + v_curr.ptr[1u]));
61660 v_curr.ptr[1u] = v_fa1;
61661 v_fa2 = ((uint8_t)(v_fa2 + v_curr.ptr[2u]));
61662 v_curr.ptr[2u] = v_fa2;
61663 v_fa3 = ((uint8_t)(v_fa3 + v_curr.ptr[3u]));
61664 v_curr.ptr[3u] = v_fa3;
61665 v_curr.ptr += 4;
61667 v_curr.len = 0;
61669 return wuffs_base__make_empty_struct();
61672 // -------- func png.decoder.filter_2
61674 WUFFS_BASE__GENERATED_C_CODE
61675 static wuffs_base__empty_struct
61676 wuffs_png__decoder__filter_2(
61677 wuffs_png__decoder* self,
61678 wuffs_base__slice_u8 a_curr,
61679 wuffs_base__slice_u8 a_prev) {
61680 uint64_t v_n = 0;
61681 uint64_t v_i = 0;
61683 v_n = wuffs_base__u64__min(((uint64_t)(a_curr.len)), ((uint64_t)(a_prev.len)));
61684 v_i = 0u;
61685 while (v_i < v_n) {
61686 a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + a_prev.ptr[v_i]));
61687 v_i += 1u;
61689 return wuffs_base__make_empty_struct();
61692 // -------- func png.decoder.filter_3
61694 WUFFS_BASE__GENERATED_C_CODE
61695 static wuffs_base__empty_struct
61696 wuffs_png__decoder__filter_3(
61697 wuffs_png__decoder* self,
61698 wuffs_base__slice_u8 a_curr,
61699 wuffs_base__slice_u8 a_prev) {
61700 return (*self->private_impl.choosy_filter_3)(self, a_curr, a_prev);
61703 WUFFS_BASE__GENERATED_C_CODE
61704 static wuffs_base__empty_struct
61705 wuffs_png__decoder__filter_3__choosy_default(
61706 wuffs_png__decoder* self,
61707 wuffs_base__slice_u8 a_curr,
61708 wuffs_base__slice_u8 a_prev) {
61709 uint64_t v_filter_distance = 0;
61710 uint64_t v_n = 0;
61711 uint64_t v_i = 0;
61713 v_filter_distance = ((uint64_t)(self->private_impl.f_filter_distance));
61714 if (((uint64_t)(a_prev.len)) == 0u) {
61715 v_i = v_filter_distance;
61716 while (v_i < ((uint64_t)(a_curr.len))) {
61717 a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + ((uint8_t)(a_curr.ptr[(v_i - v_filter_distance)] / 2u))));
61718 v_i += 1u;
61720 } else {
61721 v_n = wuffs_base__u64__min(((uint64_t)(a_curr.len)), ((uint64_t)(a_prev.len)));
61722 v_i = 0u;
61723 while ((v_i < v_n) && (v_i < v_filter_distance)) {
61724 a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + ((uint8_t)(a_prev.ptr[v_i] / 2u))));
61725 v_i += 1u;
61727 v_i = v_filter_distance;
61728 while (v_i < v_n) {
61729 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)))));
61730 v_i += 1u;
61733 return wuffs_base__make_empty_struct();
61736 // -------- func png.decoder.filter_3_distance_3_fallback
61738 WUFFS_BASE__GENERATED_C_CODE
61739 static wuffs_base__empty_struct
61740 wuffs_png__decoder__filter_3_distance_3_fallback(
61741 wuffs_png__decoder* self,
61742 wuffs_base__slice_u8 a_curr,
61743 wuffs_base__slice_u8 a_prev) {
61744 wuffs_base__slice_u8 v_curr = {0};
61745 wuffs_base__slice_u8 v_prev = {0};
61746 uint8_t v_fa0 = 0;
61747 uint8_t v_fa1 = 0;
61748 uint8_t v_fa2 = 0;
61750 if (((uint64_t)(a_prev.len)) == 0u) {
61752 wuffs_base__slice_u8 i_slice_curr = a_curr;
61753 v_curr.ptr = i_slice_curr.ptr;
61754 v_curr.len = 3;
61755 const uint8_t* i_end0_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 6) * 6));
61756 while (v_curr.ptr < i_end0_curr) {
61757 v_fa0 = ((uint8_t)(((uint8_t)(v_fa0 / 2u)) + v_curr.ptr[0u]));
61758 v_curr.ptr[0u] = v_fa0;
61759 v_fa1 = ((uint8_t)(((uint8_t)(v_fa1 / 2u)) + v_curr.ptr[1u]));
61760 v_curr.ptr[1u] = v_fa1;
61761 v_fa2 = ((uint8_t)(((uint8_t)(v_fa2 / 2u)) + v_curr.ptr[2u]));
61762 v_curr.ptr[2u] = v_fa2;
61763 v_curr.ptr += 3;
61764 v_fa0 = ((uint8_t)(((uint8_t)(v_fa0 / 2u)) + v_curr.ptr[0u]));
61765 v_curr.ptr[0u] = v_fa0;
61766 v_fa1 = ((uint8_t)(((uint8_t)(v_fa1 / 2u)) + v_curr.ptr[1u]));
61767 v_curr.ptr[1u] = v_fa1;
61768 v_fa2 = ((uint8_t)(((uint8_t)(v_fa2 / 2u)) + v_curr.ptr[2u]));
61769 v_curr.ptr[2u] = v_fa2;
61770 v_curr.ptr += 3;
61772 v_curr.len = 3;
61773 const uint8_t* i_end1_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3));
61774 while (v_curr.ptr < i_end1_curr) {
61775 v_fa0 = ((uint8_t)(((uint8_t)(v_fa0 / 2u)) + v_curr.ptr[0u]));
61776 v_curr.ptr[0u] = v_fa0;
61777 v_fa1 = ((uint8_t)(((uint8_t)(v_fa1 / 2u)) + v_curr.ptr[1u]));
61778 v_curr.ptr[1u] = v_fa1;
61779 v_fa2 = ((uint8_t)(((uint8_t)(v_fa2 / 2u)) + v_curr.ptr[2u]));
61780 v_curr.ptr[2u] = v_fa2;
61781 v_curr.ptr += 3;
61783 v_curr.len = 0;
61785 } else {
61787 wuffs_base__slice_u8 i_slice_curr = a_curr;
61788 v_curr.ptr = i_slice_curr.ptr;
61789 wuffs_base__slice_u8 i_slice_prev = a_prev;
61790 v_prev.ptr = i_slice_prev.ptr;
61791 i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
61792 v_curr.len = 3;
61793 v_prev.len = 3;
61794 const uint8_t* i_end0_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 6) * 6));
61795 while (v_curr.ptr < i_end0_curr) {
61796 v_fa0 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa0)) + ((uint32_t)(v_prev.ptr[0u]))) / 2u))) + v_curr.ptr[0u]));
61797 v_curr.ptr[0u] = v_fa0;
61798 v_fa1 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa1)) + ((uint32_t)(v_prev.ptr[1u]))) / 2u))) + v_curr.ptr[1u]));
61799 v_curr.ptr[1u] = v_fa1;
61800 v_fa2 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa2)) + ((uint32_t)(v_prev.ptr[2u]))) / 2u))) + v_curr.ptr[2u]));
61801 v_curr.ptr[2u] = v_fa2;
61802 v_curr.ptr += 3;
61803 v_prev.ptr += 3;
61804 v_fa0 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa0)) + ((uint32_t)(v_prev.ptr[0u]))) / 2u))) + v_curr.ptr[0u]));
61805 v_curr.ptr[0u] = v_fa0;
61806 v_fa1 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa1)) + ((uint32_t)(v_prev.ptr[1u]))) / 2u))) + v_curr.ptr[1u]));
61807 v_curr.ptr[1u] = v_fa1;
61808 v_fa2 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa2)) + ((uint32_t)(v_prev.ptr[2u]))) / 2u))) + v_curr.ptr[2u]));
61809 v_curr.ptr[2u] = v_fa2;
61810 v_curr.ptr += 3;
61811 v_prev.ptr += 3;
61813 v_curr.len = 3;
61814 v_prev.len = 3;
61815 const uint8_t* i_end1_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3));
61816 while (v_curr.ptr < i_end1_curr) {
61817 v_fa0 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa0)) + ((uint32_t)(v_prev.ptr[0u]))) / 2u))) + v_curr.ptr[0u]));
61818 v_curr.ptr[0u] = v_fa0;
61819 v_fa1 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa1)) + ((uint32_t)(v_prev.ptr[1u]))) / 2u))) + v_curr.ptr[1u]));
61820 v_curr.ptr[1u] = v_fa1;
61821 v_fa2 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa2)) + ((uint32_t)(v_prev.ptr[2u]))) / 2u))) + v_curr.ptr[2u]));
61822 v_curr.ptr[2u] = v_fa2;
61823 v_curr.ptr += 3;
61824 v_prev.ptr += 3;
61826 v_curr.len = 0;
61827 v_prev.len = 0;
61830 return wuffs_base__make_empty_struct();
61833 // -------- func png.decoder.filter_3_distance_4_fallback
61835 WUFFS_BASE__GENERATED_C_CODE
61836 static wuffs_base__empty_struct
61837 wuffs_png__decoder__filter_3_distance_4_fallback(
61838 wuffs_png__decoder* self,
61839 wuffs_base__slice_u8 a_curr,
61840 wuffs_base__slice_u8 a_prev) {
61841 wuffs_base__slice_u8 v_curr = {0};
61842 wuffs_base__slice_u8 v_prev = {0};
61843 uint8_t v_fa0 = 0;
61844 uint8_t v_fa1 = 0;
61845 uint8_t v_fa2 = 0;
61846 uint8_t v_fa3 = 0;
61848 if (((uint64_t)(a_prev.len)) == 0u) {
61850 wuffs_base__slice_u8 i_slice_curr = a_curr;
61851 v_curr.ptr = i_slice_curr.ptr;
61852 v_curr.len = 4;
61853 const uint8_t* i_end0_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4));
61854 while (v_curr.ptr < i_end0_curr) {
61855 v_fa0 = ((uint8_t)(((uint8_t)(v_fa0 / 2u)) + v_curr.ptr[0u]));
61856 v_curr.ptr[0u] = v_fa0;
61857 v_fa1 = ((uint8_t)(((uint8_t)(v_fa1 / 2u)) + v_curr.ptr[1u]));
61858 v_curr.ptr[1u] = v_fa1;
61859 v_fa2 = ((uint8_t)(((uint8_t)(v_fa2 / 2u)) + v_curr.ptr[2u]));
61860 v_curr.ptr[2u] = v_fa2;
61861 v_fa3 = ((uint8_t)(((uint8_t)(v_fa3 / 2u)) + v_curr.ptr[3u]));
61862 v_curr.ptr[3u] = v_fa3;
61863 v_curr.ptr += 4;
61865 v_curr.len = 0;
61867 } else {
61869 wuffs_base__slice_u8 i_slice_curr = a_curr;
61870 v_curr.ptr = i_slice_curr.ptr;
61871 wuffs_base__slice_u8 i_slice_prev = a_prev;
61872 v_prev.ptr = i_slice_prev.ptr;
61873 i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
61874 v_curr.len = 4;
61875 v_prev.len = 4;
61876 const uint8_t* i_end0_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4));
61877 while (v_curr.ptr < i_end0_curr) {
61878 v_fa0 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa0)) + ((uint32_t)(v_prev.ptr[0u]))) / 2u))) + v_curr.ptr[0u]));
61879 v_curr.ptr[0u] = v_fa0;
61880 v_fa1 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa1)) + ((uint32_t)(v_prev.ptr[1u]))) / 2u))) + v_curr.ptr[1u]));
61881 v_curr.ptr[1u] = v_fa1;
61882 v_fa2 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa2)) + ((uint32_t)(v_prev.ptr[2u]))) / 2u))) + v_curr.ptr[2u]));
61883 v_curr.ptr[2u] = v_fa2;
61884 v_fa3 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa3)) + ((uint32_t)(v_prev.ptr[3u]))) / 2u))) + v_curr.ptr[3u]));
61885 v_curr.ptr[3u] = v_fa3;
61886 v_curr.ptr += 4;
61887 v_prev.ptr += 4;
61889 v_curr.len = 0;
61890 v_prev.len = 0;
61893 return wuffs_base__make_empty_struct();
61896 // -------- func png.decoder.filter_4
61898 WUFFS_BASE__GENERATED_C_CODE
61899 static wuffs_base__empty_struct
61900 wuffs_png__decoder__filter_4(
61901 wuffs_png__decoder* self,
61902 wuffs_base__slice_u8 a_curr,
61903 wuffs_base__slice_u8 a_prev) {
61904 return (*self->private_impl.choosy_filter_4)(self, a_curr, a_prev);
61907 WUFFS_BASE__GENERATED_C_CODE
61908 static wuffs_base__empty_struct
61909 wuffs_png__decoder__filter_4__choosy_default(
61910 wuffs_png__decoder* self,
61911 wuffs_base__slice_u8 a_curr,
61912 wuffs_base__slice_u8 a_prev) {
61913 uint64_t v_filter_distance = 0;
61914 uint64_t v_n = 0;
61915 uint64_t v_i = 0;
61916 uint32_t v_fa = 0;
61917 uint32_t v_fb = 0;
61918 uint32_t v_fc = 0;
61919 uint32_t v_pp = 0;
61920 uint32_t v_pa = 0;
61921 uint32_t v_pb = 0;
61922 uint32_t v_pc = 0;
61924 v_filter_distance = ((uint64_t)(self->private_impl.f_filter_distance));
61925 v_n = wuffs_base__u64__min(((uint64_t)(a_curr.len)), ((uint64_t)(a_prev.len)));
61926 v_i = 0u;
61927 while ((v_i < v_n) && (v_i < v_filter_distance)) {
61928 a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + a_prev.ptr[v_i]));
61929 v_i += 1u;
61931 v_i = v_filter_distance;
61932 while (v_i < v_n) {
61933 v_fa = ((uint32_t)(a_curr.ptr[(v_i - v_filter_distance)]));
61934 v_fb = ((uint32_t)(a_prev.ptr[v_i]));
61935 v_fc = ((uint32_t)(a_prev.ptr[(v_i - v_filter_distance)]));
61936 v_pp = ((uint32_t)(((uint32_t)(v_fa + v_fb)) - v_fc));
61937 v_pa = ((uint32_t)(v_pp - v_fa));
61938 if (v_pa >= 2147483648u) {
61939 v_pa = ((uint32_t)(0u - v_pa));
61941 v_pb = ((uint32_t)(v_pp - v_fb));
61942 if (v_pb >= 2147483648u) {
61943 v_pb = ((uint32_t)(0u - v_pb));
61945 v_pc = ((uint32_t)(v_pp - v_fc));
61946 if (v_pc >= 2147483648u) {
61947 v_pc = ((uint32_t)(0u - v_pc));
61949 if ((v_pa <= v_pb) && (v_pa <= v_pc)) {
61950 } else if (v_pb <= v_pc) {
61951 v_fa = v_fb;
61952 } else {
61953 v_fa = v_fc;
61955 a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + ((uint8_t)(v_fa))));
61956 v_i += 1u;
61958 return wuffs_base__make_empty_struct();
61961 // -------- func png.decoder.filter_4_distance_3_fallback
61963 WUFFS_BASE__GENERATED_C_CODE
61964 static wuffs_base__empty_struct
61965 wuffs_png__decoder__filter_4_distance_3_fallback(
61966 wuffs_png__decoder* self,
61967 wuffs_base__slice_u8 a_curr,
61968 wuffs_base__slice_u8 a_prev) {
61969 wuffs_base__slice_u8 v_curr = {0};
61970 wuffs_base__slice_u8 v_prev = {0};
61971 uint32_t v_fa0 = 0;
61972 uint32_t v_fa1 = 0;
61973 uint32_t v_fa2 = 0;
61974 uint32_t v_fb0 = 0;
61975 uint32_t v_fb1 = 0;
61976 uint32_t v_fb2 = 0;
61977 uint32_t v_fc0 = 0;
61978 uint32_t v_fc1 = 0;
61979 uint32_t v_fc2 = 0;
61980 uint32_t v_pp0 = 0;
61981 uint32_t v_pp1 = 0;
61982 uint32_t v_pp2 = 0;
61983 uint32_t v_pa0 = 0;
61984 uint32_t v_pa1 = 0;
61985 uint32_t v_pa2 = 0;
61986 uint32_t v_pb0 = 0;
61987 uint32_t v_pb1 = 0;
61988 uint32_t v_pb2 = 0;
61989 uint32_t v_pc0 = 0;
61990 uint32_t v_pc1 = 0;
61991 uint32_t v_pc2 = 0;
61994 wuffs_base__slice_u8 i_slice_curr = a_curr;
61995 v_curr.ptr = i_slice_curr.ptr;
61996 wuffs_base__slice_u8 i_slice_prev = a_prev;
61997 v_prev.ptr = i_slice_prev.ptr;
61998 i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
61999 v_curr.len = 3;
62000 v_prev.len = 3;
62001 const uint8_t* i_end0_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3));
62002 while (v_curr.ptr < i_end0_curr) {
62003 v_fb0 = ((uint32_t)(v_prev.ptr[0u]));
62004 v_pp0 = ((uint32_t)(((uint32_t)(v_fa0 + v_fb0)) - v_fc0));
62005 v_pa0 = ((uint32_t)(v_pp0 - v_fa0));
62006 if (v_pa0 >= 2147483648u) {
62007 v_pa0 = ((uint32_t)(0u - v_pa0));
62009 v_pb0 = ((uint32_t)(v_pp0 - v_fb0));
62010 if (v_pb0 >= 2147483648u) {
62011 v_pb0 = ((uint32_t)(0u - v_pb0));
62013 v_pc0 = ((uint32_t)(v_pp0 - v_fc0));
62014 if (v_pc0 >= 2147483648u) {
62015 v_pc0 = ((uint32_t)(0u - v_pc0));
62017 if ((v_pa0 <= v_pb0) && (v_pa0 <= v_pc0)) {
62018 } else if (v_pb0 <= v_pc0) {
62019 v_fa0 = v_fb0;
62020 } else {
62021 v_fa0 = v_fc0;
62023 v_curr.ptr[0u] = ((uint8_t)(v_curr.ptr[0u] + ((uint8_t)(v_fa0))));
62024 v_fa0 = ((uint32_t)(v_curr.ptr[0u]));
62025 v_fc0 = v_fb0;
62026 v_fb1 = ((uint32_t)(v_prev.ptr[1u]));
62027 v_pp1 = ((uint32_t)(((uint32_t)(v_fa1 + v_fb1)) - v_fc1));
62028 v_pa1 = ((uint32_t)(v_pp1 - v_fa1));
62029 if (v_pa1 >= 2147483648u) {
62030 v_pa1 = ((uint32_t)(0u - v_pa1));
62032 v_pb1 = ((uint32_t)(v_pp1 - v_fb1));
62033 if (v_pb1 >= 2147483648u) {
62034 v_pb1 = ((uint32_t)(0u - v_pb1));
62036 v_pc1 = ((uint32_t)(v_pp1 - v_fc1));
62037 if (v_pc1 >= 2147483648u) {
62038 v_pc1 = ((uint32_t)(0u - v_pc1));
62040 if ((v_pa1 <= v_pb1) && (v_pa1 <= v_pc1)) {
62041 } else if (v_pb1 <= v_pc1) {
62042 v_fa1 = v_fb1;
62043 } else {
62044 v_fa1 = v_fc1;
62046 v_curr.ptr[1u] = ((uint8_t)(v_curr.ptr[1u] + ((uint8_t)(v_fa1))));
62047 v_fa1 = ((uint32_t)(v_curr.ptr[1u]));
62048 v_fc1 = v_fb1;
62049 v_fb2 = ((uint32_t)(v_prev.ptr[2u]));
62050 v_pp2 = ((uint32_t)(((uint32_t)(v_fa2 + v_fb2)) - v_fc2));
62051 v_pa2 = ((uint32_t)(v_pp2 - v_fa2));
62052 if (v_pa2 >= 2147483648u) {
62053 v_pa2 = ((uint32_t)(0u - v_pa2));
62055 v_pb2 = ((uint32_t)(v_pp2 - v_fb2));
62056 if (v_pb2 >= 2147483648u) {
62057 v_pb2 = ((uint32_t)(0u - v_pb2));
62059 v_pc2 = ((uint32_t)(v_pp2 - v_fc2));
62060 if (v_pc2 >= 2147483648u) {
62061 v_pc2 = ((uint32_t)(0u - v_pc2));
62063 if ((v_pa2 <= v_pb2) && (v_pa2 <= v_pc2)) {
62064 } else if (v_pb2 <= v_pc2) {
62065 v_fa2 = v_fb2;
62066 } else {
62067 v_fa2 = v_fc2;
62069 v_curr.ptr[2u] = ((uint8_t)(v_curr.ptr[2u] + ((uint8_t)(v_fa2))));
62070 v_fa2 = ((uint32_t)(v_curr.ptr[2u]));
62071 v_fc2 = v_fb2;
62072 v_curr.ptr += 3;
62073 v_prev.ptr += 3;
62075 v_curr.len = 0;
62076 v_prev.len = 0;
62078 return wuffs_base__make_empty_struct();
62081 // -------- func png.decoder.filter_4_distance_4_fallback
62083 WUFFS_BASE__GENERATED_C_CODE
62084 static wuffs_base__empty_struct
62085 wuffs_png__decoder__filter_4_distance_4_fallback(
62086 wuffs_png__decoder* self,
62087 wuffs_base__slice_u8 a_curr,
62088 wuffs_base__slice_u8 a_prev) {
62089 wuffs_base__slice_u8 v_curr = {0};
62090 wuffs_base__slice_u8 v_prev = {0};
62091 uint32_t v_fa0 = 0;
62092 uint32_t v_fa1 = 0;
62093 uint32_t v_fa2 = 0;
62094 uint32_t v_fa3 = 0;
62095 uint32_t v_fb0 = 0;
62096 uint32_t v_fb1 = 0;
62097 uint32_t v_fb2 = 0;
62098 uint32_t v_fb3 = 0;
62099 uint32_t v_fc0 = 0;
62100 uint32_t v_fc1 = 0;
62101 uint32_t v_fc2 = 0;
62102 uint32_t v_fc3 = 0;
62103 uint32_t v_pp0 = 0;
62104 uint32_t v_pp1 = 0;
62105 uint32_t v_pp2 = 0;
62106 uint32_t v_pp3 = 0;
62107 uint32_t v_pa0 = 0;
62108 uint32_t v_pa1 = 0;
62109 uint32_t v_pa2 = 0;
62110 uint32_t v_pa3 = 0;
62111 uint32_t v_pb0 = 0;
62112 uint32_t v_pb1 = 0;
62113 uint32_t v_pb2 = 0;
62114 uint32_t v_pb3 = 0;
62115 uint32_t v_pc0 = 0;
62116 uint32_t v_pc1 = 0;
62117 uint32_t v_pc2 = 0;
62118 uint32_t v_pc3 = 0;
62121 wuffs_base__slice_u8 i_slice_curr = a_curr;
62122 v_curr.ptr = i_slice_curr.ptr;
62123 wuffs_base__slice_u8 i_slice_prev = a_prev;
62124 v_prev.ptr = i_slice_prev.ptr;
62125 i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
62126 v_curr.len = 4;
62127 v_prev.len = 4;
62128 const uint8_t* i_end0_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4));
62129 while (v_curr.ptr < i_end0_curr) {
62130 v_fb0 = ((uint32_t)(v_prev.ptr[0u]));
62131 v_pp0 = ((uint32_t)(((uint32_t)(v_fa0 + v_fb0)) - v_fc0));
62132 v_pa0 = ((uint32_t)(v_pp0 - v_fa0));
62133 if (v_pa0 >= 2147483648u) {
62134 v_pa0 = ((uint32_t)(0u - v_pa0));
62136 v_pb0 = ((uint32_t)(v_pp0 - v_fb0));
62137 if (v_pb0 >= 2147483648u) {
62138 v_pb0 = ((uint32_t)(0u - v_pb0));
62140 v_pc0 = ((uint32_t)(v_pp0 - v_fc0));
62141 if (v_pc0 >= 2147483648u) {
62142 v_pc0 = ((uint32_t)(0u - v_pc0));
62144 if ((v_pa0 <= v_pb0) && (v_pa0 <= v_pc0)) {
62145 } else if (v_pb0 <= v_pc0) {
62146 v_fa0 = v_fb0;
62147 } else {
62148 v_fa0 = v_fc0;
62150 v_curr.ptr[0u] = ((uint8_t)(v_curr.ptr[0u] + ((uint8_t)(v_fa0))));
62151 v_fa0 = ((uint32_t)(v_curr.ptr[0u]));
62152 v_fc0 = v_fb0;
62153 v_fb1 = ((uint32_t)(v_prev.ptr[1u]));
62154 v_pp1 = ((uint32_t)(((uint32_t)(v_fa1 + v_fb1)) - v_fc1));
62155 v_pa1 = ((uint32_t)(v_pp1 - v_fa1));
62156 if (v_pa1 >= 2147483648u) {
62157 v_pa1 = ((uint32_t)(0u - v_pa1));
62159 v_pb1 = ((uint32_t)(v_pp1 - v_fb1));
62160 if (v_pb1 >= 2147483648u) {
62161 v_pb1 = ((uint32_t)(0u - v_pb1));
62163 v_pc1 = ((uint32_t)(v_pp1 - v_fc1));
62164 if (v_pc1 >= 2147483648u) {
62165 v_pc1 = ((uint32_t)(0u - v_pc1));
62167 if ((v_pa1 <= v_pb1) && (v_pa1 <= v_pc1)) {
62168 } else if (v_pb1 <= v_pc1) {
62169 v_fa1 = v_fb1;
62170 } else {
62171 v_fa1 = v_fc1;
62173 v_curr.ptr[1u] = ((uint8_t)(v_curr.ptr[1u] + ((uint8_t)(v_fa1))));
62174 v_fa1 = ((uint32_t)(v_curr.ptr[1u]));
62175 v_fc1 = v_fb1;
62176 v_fb2 = ((uint32_t)(v_prev.ptr[2u]));
62177 v_pp2 = ((uint32_t)(((uint32_t)(v_fa2 + v_fb2)) - v_fc2));
62178 v_pa2 = ((uint32_t)(v_pp2 - v_fa2));
62179 if (v_pa2 >= 2147483648u) {
62180 v_pa2 = ((uint32_t)(0u - v_pa2));
62182 v_pb2 = ((uint32_t)(v_pp2 - v_fb2));
62183 if (v_pb2 >= 2147483648u) {
62184 v_pb2 = ((uint32_t)(0u - v_pb2));
62186 v_pc2 = ((uint32_t)(v_pp2 - v_fc2));
62187 if (v_pc2 >= 2147483648u) {
62188 v_pc2 = ((uint32_t)(0u - v_pc2));
62190 if ((v_pa2 <= v_pb2) && (v_pa2 <= v_pc2)) {
62191 } else if (v_pb2 <= v_pc2) {
62192 v_fa2 = v_fb2;
62193 } else {
62194 v_fa2 = v_fc2;
62196 v_curr.ptr[2u] = ((uint8_t)(v_curr.ptr[2u] + ((uint8_t)(v_fa2))));
62197 v_fa2 = ((uint32_t)(v_curr.ptr[2u]));
62198 v_fc2 = v_fb2;
62199 v_fb3 = ((uint32_t)(v_prev.ptr[3u]));
62200 v_pp3 = ((uint32_t)(((uint32_t)(v_fa3 + v_fb3)) - v_fc3));
62201 v_pa3 = ((uint32_t)(v_pp3 - v_fa3));
62202 if (v_pa3 >= 2147483648u) {
62203 v_pa3 = ((uint32_t)(0u - v_pa3));
62205 v_pb3 = ((uint32_t)(v_pp3 - v_fb3));
62206 if (v_pb3 >= 2147483648u) {
62207 v_pb3 = ((uint32_t)(0u - v_pb3));
62209 v_pc3 = ((uint32_t)(v_pp3 - v_fc3));
62210 if (v_pc3 >= 2147483648u) {
62211 v_pc3 = ((uint32_t)(0u - v_pc3));
62213 if ((v_pa3 <= v_pb3) && (v_pa3 <= v_pc3)) {
62214 } else if (v_pb3 <= v_pc3) {
62215 v_fa3 = v_fb3;
62216 } else {
62217 v_fa3 = v_fc3;
62219 v_curr.ptr[3u] = ((uint8_t)(v_curr.ptr[3u] + ((uint8_t)(v_fa3))));
62220 v_fa3 = ((uint32_t)(v_curr.ptr[3u]));
62221 v_fc3 = v_fb3;
62222 v_curr.ptr += 4;
62223 v_prev.ptr += 4;
62225 v_curr.len = 0;
62226 v_prev.len = 0;
62228 return wuffs_base__make_empty_struct();
62231 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
62232 // -------- func png.decoder.filter_1_distance_4_x86_sse42
62234 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
62235 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
62236 WUFFS_BASE__GENERATED_C_CODE
62237 static wuffs_base__empty_struct
62238 wuffs_png__decoder__filter_1_distance_4_x86_sse42(
62239 wuffs_png__decoder* self,
62240 wuffs_base__slice_u8 a_curr) {
62241 wuffs_base__slice_u8 v_curr = {0};
62242 __m128i v_x128 = {0};
62243 __m128i v_a128 = {0};
62246 wuffs_base__slice_u8 i_slice_curr = a_curr;
62247 v_curr.ptr = i_slice_curr.ptr;
62248 v_curr.len = 4;
62249 const uint8_t* i_end0_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8));
62250 while (v_curr.ptr < i_end0_curr) {
62251 v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
62252 v_x128 = _mm_add_epi8(v_x128, v_a128);
62253 v_a128 = v_x128;
62254 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
62255 v_curr.ptr += 4;
62256 v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
62257 v_x128 = _mm_add_epi8(v_x128, v_a128);
62258 v_a128 = v_x128;
62259 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
62260 v_curr.ptr += 4;
62262 v_curr.len = 4;
62263 const uint8_t* i_end1_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4));
62264 while (v_curr.ptr < i_end1_curr) {
62265 v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
62266 v_x128 = _mm_add_epi8(v_x128, v_a128);
62267 v_a128 = v_x128;
62268 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
62269 v_curr.ptr += 4;
62271 v_curr.len = 0;
62273 return wuffs_base__make_empty_struct();
62275 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
62276 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
62278 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
62279 // -------- func png.decoder.filter_3_distance_4_x86_sse42
62281 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
62282 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
62283 WUFFS_BASE__GENERATED_C_CODE
62284 static wuffs_base__empty_struct
62285 wuffs_png__decoder__filter_3_distance_4_x86_sse42(
62286 wuffs_png__decoder* self,
62287 wuffs_base__slice_u8 a_curr,
62288 wuffs_base__slice_u8 a_prev) {
62289 wuffs_base__slice_u8 v_curr = {0};
62290 wuffs_base__slice_u8 v_prev = {0};
62291 __m128i v_x128 = {0};
62292 __m128i v_a128 = {0};
62293 __m128i v_b128 = {0};
62294 __m128i v_p128 = {0};
62295 __m128i v_k128 = {0};
62297 if (((uint64_t)(a_prev.len)) == 0u) {
62298 v_k128 = _mm_set1_epi8((int8_t)(254u));
62300 wuffs_base__slice_u8 i_slice_curr = a_curr;
62301 v_curr.ptr = i_slice_curr.ptr;
62302 v_curr.len = 4;
62303 const uint8_t* i_end0_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8));
62304 while (v_curr.ptr < i_end0_curr) {
62305 v_p128 = _mm_avg_epu8(_mm_and_si128(v_a128, v_k128), v_b128);
62306 v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
62307 v_x128 = _mm_add_epi8(v_x128, v_p128);
62308 v_a128 = v_x128;
62309 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
62310 v_curr.ptr += 4;
62311 v_p128 = _mm_avg_epu8(_mm_and_si128(v_a128, v_k128), v_b128);
62312 v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
62313 v_x128 = _mm_add_epi8(v_x128, v_p128);
62314 v_a128 = v_x128;
62315 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
62316 v_curr.ptr += 4;
62318 v_curr.len = 4;
62319 const uint8_t* i_end1_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4));
62320 while (v_curr.ptr < i_end1_curr) {
62321 v_p128 = _mm_avg_epu8(_mm_and_si128(v_a128, v_k128), v_b128);
62322 v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
62323 v_x128 = _mm_add_epi8(v_x128, v_p128);
62324 v_a128 = v_x128;
62325 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
62326 v_curr.ptr += 4;
62328 v_curr.len = 0;
62330 } else {
62331 v_k128 = _mm_set1_epi8((int8_t)(1u));
62333 wuffs_base__slice_u8 i_slice_curr = a_curr;
62334 v_curr.ptr = i_slice_curr.ptr;
62335 wuffs_base__slice_u8 i_slice_prev = a_prev;
62336 v_prev.ptr = i_slice_prev.ptr;
62337 i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
62338 v_curr.len = 4;
62339 v_prev.len = 4;
62340 const uint8_t* i_end0_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8));
62341 while (v_curr.ptr < i_end0_curr) {
62342 v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
62343 v_p128 = _mm_avg_epu8(v_a128, v_b128);
62344 v_p128 = _mm_sub_epi8(v_p128, _mm_and_si128(v_k128, _mm_xor_si128(v_a128, v_b128)));
62345 v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
62346 v_x128 = _mm_add_epi8(v_x128, v_p128);
62347 v_a128 = v_x128;
62348 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
62349 v_curr.ptr += 4;
62350 v_prev.ptr += 4;
62351 v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
62352 v_p128 = _mm_avg_epu8(v_a128, v_b128);
62353 v_p128 = _mm_sub_epi8(v_p128, _mm_and_si128(v_k128, _mm_xor_si128(v_a128, v_b128)));
62354 v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
62355 v_x128 = _mm_add_epi8(v_x128, v_p128);
62356 v_a128 = v_x128;
62357 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
62358 v_curr.ptr += 4;
62359 v_prev.ptr += 4;
62361 v_curr.len = 4;
62362 v_prev.len = 4;
62363 const uint8_t* i_end1_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4));
62364 while (v_curr.ptr < i_end1_curr) {
62365 v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
62366 v_p128 = _mm_avg_epu8(v_a128, v_b128);
62367 v_p128 = _mm_sub_epi8(v_p128, _mm_and_si128(v_k128, _mm_xor_si128(v_a128, v_b128)));
62368 v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
62369 v_x128 = _mm_add_epi8(v_x128, v_p128);
62370 v_a128 = v_x128;
62371 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
62372 v_curr.ptr += 4;
62373 v_prev.ptr += 4;
62375 v_curr.len = 0;
62376 v_prev.len = 0;
62379 return wuffs_base__make_empty_struct();
62381 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
62382 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
62384 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
62385 // -------- func png.decoder.filter_4_distance_3_x86_sse42
62387 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
62388 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
62389 WUFFS_BASE__GENERATED_C_CODE
62390 static wuffs_base__empty_struct
62391 wuffs_png__decoder__filter_4_distance_3_x86_sse42(
62392 wuffs_png__decoder* self,
62393 wuffs_base__slice_u8 a_curr,
62394 wuffs_base__slice_u8 a_prev) {
62395 wuffs_base__slice_u8 v_curr = {0};
62396 wuffs_base__slice_u8 v_prev = {0};
62397 __m128i v_x128 = {0};
62398 __m128i v_a128 = {0};
62399 __m128i v_b128 = {0};
62400 __m128i v_c128 = {0};
62401 __m128i v_p128 = {0};
62402 __m128i v_pa128 = {0};
62403 __m128i v_pb128 = {0};
62404 __m128i v_pc128 = {0};
62405 __m128i v_smallest128 = {0};
62406 __m128i v_z128 = {0};
62409 wuffs_base__slice_u8 i_slice_curr = a_curr;
62410 v_curr.ptr = i_slice_curr.ptr;
62411 wuffs_base__slice_u8 i_slice_prev = a_prev;
62412 v_prev.ptr = i_slice_prev.ptr;
62413 i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
62414 v_curr.len = 4;
62415 v_prev.len = 4;
62416 const uint8_t* i_end0_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, wuffs_private_impl__iterate_total_advance((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)), 7, 6));
62417 while (v_curr.ptr < i_end0_curr) {
62418 v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
62419 v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
62420 v_pa128 = _mm_sub_epi16(v_b128, v_c128);
62421 v_pb128 = _mm_sub_epi16(v_a128, v_c128);
62422 v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
62423 v_pa128 = _mm_abs_epi16(v_pa128);
62424 v_pb128 = _mm_abs_epi16(v_pb128);
62425 v_pc128 = _mm_abs_epi16(v_pc128);
62426 v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
62427 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));
62428 v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
62429 v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
62430 v_x128 = _mm_add_epi8(v_x128, v_p128);
62431 v_a128 = v_x128;
62432 v_c128 = v_b128;
62433 v_x128 = _mm_packus_epi16(v_x128, v_x128);
62434 wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
62435 v_curr.ptr += 3;
62436 v_prev.ptr += 3;
62437 v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
62438 v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
62439 v_pa128 = _mm_sub_epi16(v_b128, v_c128);
62440 v_pb128 = _mm_sub_epi16(v_a128, v_c128);
62441 v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
62442 v_pa128 = _mm_abs_epi16(v_pa128);
62443 v_pb128 = _mm_abs_epi16(v_pb128);
62444 v_pc128 = _mm_abs_epi16(v_pc128);
62445 v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
62446 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));
62447 v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
62448 v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
62449 v_x128 = _mm_add_epi8(v_x128, v_p128);
62450 v_a128 = v_x128;
62451 v_c128 = v_b128;
62452 v_x128 = _mm_packus_epi16(v_x128, v_x128);
62453 wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
62454 v_curr.ptr += 3;
62455 v_prev.ptr += 3;
62457 v_curr.len = 4;
62458 v_prev.len = 4;
62459 const uint8_t* i_end1_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, wuffs_private_impl__iterate_total_advance((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)), 4, 3));
62460 while (v_curr.ptr < i_end1_curr) {
62461 v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
62462 v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
62463 v_pa128 = _mm_sub_epi16(v_b128, v_c128);
62464 v_pb128 = _mm_sub_epi16(v_a128, v_c128);
62465 v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
62466 v_pa128 = _mm_abs_epi16(v_pa128);
62467 v_pb128 = _mm_abs_epi16(v_pb128);
62468 v_pc128 = _mm_abs_epi16(v_pc128);
62469 v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
62470 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));
62471 v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
62472 v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
62473 v_x128 = _mm_add_epi8(v_x128, v_p128);
62474 v_a128 = v_x128;
62475 v_c128 = v_b128;
62476 v_x128 = _mm_packus_epi16(v_x128, v_x128);
62477 wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
62478 v_curr.ptr += 3;
62479 v_prev.ptr += 3;
62481 v_curr.len = 3;
62482 v_prev.len = 3;
62483 const uint8_t* i_end2_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3));
62484 while (v_curr.ptr < i_end2_curr) {
62485 v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u24le__no_bounds_check(v_prev.ptr)));
62486 v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
62487 v_pa128 = _mm_sub_epi16(v_b128, v_c128);
62488 v_pb128 = _mm_sub_epi16(v_a128, v_c128);
62489 v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
62490 v_pa128 = _mm_abs_epi16(v_pa128);
62491 v_pb128 = _mm_abs_epi16(v_pb128);
62492 v_pc128 = _mm_abs_epi16(v_pc128);
62493 v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
62494 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));
62495 v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u24le__no_bounds_check(v_curr.ptr)));
62496 v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
62497 v_x128 = _mm_add_epi8(v_x128, v_p128);
62498 v_x128 = _mm_packus_epi16(v_x128, v_x128);
62499 wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
62500 v_curr.ptr += 3;
62501 v_prev.ptr += 3;
62503 v_curr.len = 0;
62504 v_prev.len = 0;
62506 return wuffs_base__make_empty_struct();
62508 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
62509 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
62511 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
62512 // -------- func png.decoder.filter_4_distance_4_x86_sse42
62514 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
62515 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
62516 WUFFS_BASE__GENERATED_C_CODE
62517 static wuffs_base__empty_struct
62518 wuffs_png__decoder__filter_4_distance_4_x86_sse42(
62519 wuffs_png__decoder* self,
62520 wuffs_base__slice_u8 a_curr,
62521 wuffs_base__slice_u8 a_prev) {
62522 wuffs_base__slice_u8 v_curr = {0};
62523 wuffs_base__slice_u8 v_prev = {0};
62524 __m128i v_x128 = {0};
62525 __m128i v_a128 = {0};
62526 __m128i v_b128 = {0};
62527 __m128i v_c128 = {0};
62528 __m128i v_p128 = {0};
62529 __m128i v_pa128 = {0};
62530 __m128i v_pb128 = {0};
62531 __m128i v_pc128 = {0};
62532 __m128i v_smallest128 = {0};
62533 __m128i v_z128 = {0};
62536 wuffs_base__slice_u8 i_slice_curr = a_curr;
62537 v_curr.ptr = i_slice_curr.ptr;
62538 wuffs_base__slice_u8 i_slice_prev = a_prev;
62539 v_prev.ptr = i_slice_prev.ptr;
62540 i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
62541 v_curr.len = 4;
62542 v_prev.len = 4;
62543 const uint8_t* i_end0_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8));
62544 while (v_curr.ptr < i_end0_curr) {
62545 v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
62546 v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
62547 v_pa128 = _mm_sub_epi16(v_b128, v_c128);
62548 v_pb128 = _mm_sub_epi16(v_a128, v_c128);
62549 v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
62550 v_pa128 = _mm_abs_epi16(v_pa128);
62551 v_pb128 = _mm_abs_epi16(v_pb128);
62552 v_pc128 = _mm_abs_epi16(v_pc128);
62553 v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
62554 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));
62555 v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
62556 v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
62557 v_x128 = _mm_add_epi8(v_x128, v_p128);
62558 v_a128 = v_x128;
62559 v_c128 = v_b128;
62560 v_x128 = _mm_packus_epi16(v_x128, v_x128);
62561 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
62562 v_curr.ptr += 4;
62563 v_prev.ptr += 4;
62564 v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
62565 v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
62566 v_pa128 = _mm_sub_epi16(v_b128, v_c128);
62567 v_pb128 = _mm_sub_epi16(v_a128, v_c128);
62568 v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
62569 v_pa128 = _mm_abs_epi16(v_pa128);
62570 v_pb128 = _mm_abs_epi16(v_pb128);
62571 v_pc128 = _mm_abs_epi16(v_pc128);
62572 v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
62573 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));
62574 v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
62575 v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
62576 v_x128 = _mm_add_epi8(v_x128, v_p128);
62577 v_a128 = v_x128;
62578 v_c128 = v_b128;
62579 v_x128 = _mm_packus_epi16(v_x128, v_x128);
62580 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
62581 v_curr.ptr += 4;
62582 v_prev.ptr += 4;
62584 v_curr.len = 4;
62585 v_prev.len = 4;
62586 const uint8_t* i_end1_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4));
62587 while (v_curr.ptr < i_end1_curr) {
62588 v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
62589 v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
62590 v_pa128 = _mm_sub_epi16(v_b128, v_c128);
62591 v_pb128 = _mm_sub_epi16(v_a128, v_c128);
62592 v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
62593 v_pa128 = _mm_abs_epi16(v_pa128);
62594 v_pb128 = _mm_abs_epi16(v_pb128);
62595 v_pc128 = _mm_abs_epi16(v_pc128);
62596 v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
62597 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));
62598 v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
62599 v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
62600 v_x128 = _mm_add_epi8(v_x128, v_p128);
62601 v_a128 = v_x128;
62602 v_c128 = v_b128;
62603 v_x128 = _mm_packus_epi16(v_x128, v_x128);
62604 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
62605 v_curr.ptr += 4;
62606 v_prev.ptr += 4;
62608 v_curr.len = 0;
62609 v_prev.len = 0;
62611 return wuffs_base__make_empty_struct();
62613 #endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
62614 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
62616 // -------- func png.decoder.get_quirk
62618 WUFFS_BASE__GENERATED_C_CODE
62619 WUFFS_BASE__MAYBE_STATIC uint64_t
62620 wuffs_png__decoder__get_quirk(
62621 const wuffs_png__decoder* self,
62622 uint32_t a_key) {
62623 if (!self) {
62624 return 0;
62626 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
62627 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
62628 return 0;
62631 if ((a_key == 1u) && self->private_impl.f_ignore_checksum) {
62632 return 1u;
62634 return 0u;
62637 // -------- func png.decoder.set_quirk
62639 WUFFS_BASE__GENERATED_C_CODE
62640 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
62641 wuffs_png__decoder__set_quirk(
62642 wuffs_png__decoder* self,
62643 uint32_t a_key,
62644 uint64_t a_value) {
62645 if (!self) {
62646 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
62648 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
62649 return wuffs_base__make_status(
62650 (self->private_impl.magic == WUFFS_BASE__DISABLED)
62651 ? wuffs_base__error__disabled_by_previous_error
62652 : wuffs_base__error__initialize_not_called);
62655 if (a_key == 1u) {
62656 self->private_impl.f_ignore_checksum = (a_value > 0u);
62657 wuffs_zlib__decoder__set_quirk(&self->private_data.f_zlib, a_key, a_value);
62658 return wuffs_base__make_status(NULL);
62660 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
62663 // -------- func png.decoder.decode_image_config
62665 WUFFS_BASE__GENERATED_C_CODE
62666 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
62667 wuffs_png__decoder__decode_image_config(
62668 wuffs_png__decoder* self,
62669 wuffs_base__image_config* a_dst,
62670 wuffs_base__io_buffer* a_src) {
62671 if (!self) {
62672 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
62674 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
62675 return wuffs_base__make_status(
62676 (self->private_impl.magic == WUFFS_BASE__DISABLED)
62677 ? wuffs_base__error__disabled_by_previous_error
62678 : wuffs_base__error__initialize_not_called);
62680 if (!a_src) {
62681 self->private_impl.magic = WUFFS_BASE__DISABLED;
62682 return wuffs_base__make_status(wuffs_base__error__bad_argument);
62684 if ((self->private_impl.active_coroutine != 0) &&
62685 (self->private_impl.active_coroutine != 1)) {
62686 self->private_impl.magic = WUFFS_BASE__DISABLED;
62687 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
62689 self->private_impl.active_coroutine = 0;
62690 wuffs_base__status status = wuffs_base__make_status(NULL);
62692 wuffs_base__status v_status = wuffs_base__make_status(NULL);
62694 uint32_t coro_susp_point = self->private_impl.p_decode_image_config;
62695 switch (coro_susp_point) {
62696 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
62698 while (true) {
62700 wuffs_base__status t_0 = wuffs_png__decoder__do_decode_image_config(self, a_dst, a_src);
62701 v_status = t_0;
62703 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
62704 status = wuffs_base__make_status(wuffs_png__error__truncated_input);
62705 goto exit;
62707 status = v_status;
62708 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
62712 self->private_impl.p_decode_image_config = 0;
62713 goto exit;
62716 goto suspend;
62717 suspend:
62718 self->private_impl.p_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
62719 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
62721 goto exit;
62722 exit:
62723 if (wuffs_base__status__is_error(&status)) {
62724 self->private_impl.magic = WUFFS_BASE__DISABLED;
62726 return status;
62729 // -------- func png.decoder.do_decode_image_config
62731 WUFFS_BASE__GENERATED_C_CODE
62732 static wuffs_base__status
62733 wuffs_png__decoder__do_decode_image_config(
62734 wuffs_png__decoder* self,
62735 wuffs_base__image_config* a_dst,
62736 wuffs_base__io_buffer* a_src) {
62737 wuffs_base__status status = wuffs_base__make_status(NULL);
62739 uint64_t v_magic = 0;
62740 uint64_t v_mark = 0;
62741 uint32_t v_checksum_have = 0;
62742 uint32_t v_checksum_want = 0;
62743 wuffs_base__status v_status = wuffs_base__make_status(NULL);
62745 const uint8_t* iop_a_src = NULL;
62746 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
62747 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
62748 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
62749 if (a_src && a_src->data.ptr) {
62750 io0_a_src = a_src->data.ptr;
62751 io1_a_src = io0_a_src + a_src->meta.ri;
62752 iop_a_src = io1_a_src;
62753 io2_a_src = io0_a_src + a_src->meta.wi;
62756 uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config;
62757 if (coro_susp_point) {
62758 v_checksum_have = self->private_data.s_do_decode_image_config.v_checksum_have;
62760 switch (coro_susp_point) {
62761 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
62763 if (self->private_impl.f_call_sequence != 0u) {
62764 status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
62765 goto exit;
62766 } else if ( ! self->private_impl.f_seen_ihdr) {
62768 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
62769 uint64_t t_0;
62770 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 8)) {
62771 t_0 = wuffs_base__peek_u64le__no_bounds_check(iop_a_src);
62772 iop_a_src += 8;
62773 } else {
62774 self->private_data.s_do_decode_image_config.scratch = 0;
62775 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
62776 while (true) {
62777 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
62778 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
62779 goto suspend;
62781 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
62782 uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
62783 *scratch <<= 8;
62784 *scratch >>= 8;
62785 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
62786 if (num_bits_0 == 56) {
62787 t_0 = ((uint64_t)(*scratch));
62788 break;
62790 num_bits_0 += 8u;
62791 *scratch |= ((uint64_t)(num_bits_0)) << 56;
62794 v_magic = t_0;
62796 if (v_magic != 727905341920923785u) {
62797 status = wuffs_base__make_status(wuffs_png__error__bad_header);
62798 goto exit;
62801 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
62802 uint64_t t_1;
62803 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 8)) {
62804 t_1 = wuffs_base__peek_u64le__no_bounds_check(iop_a_src);
62805 iop_a_src += 8;
62806 } else {
62807 self->private_data.s_do_decode_image_config.scratch = 0;
62808 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
62809 while (true) {
62810 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
62811 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
62812 goto suspend;
62814 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
62815 uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
62816 *scratch <<= 8;
62817 *scratch >>= 8;
62818 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
62819 if (num_bits_1 == 56) {
62820 t_1 = ((uint64_t)(*scratch));
62821 break;
62823 num_bits_1 += 8u;
62824 *scratch |= ((uint64_t)(num_bits_1)) << 56;
62827 v_magic = t_1;
62829 if (v_magic != 5927942488114331648u) {
62830 if (v_magic == 5278895250759221248u) {
62831 status = wuffs_base__make_status(wuffs_png__error__unsupported_cgbi_extension);
62832 goto exit;
62834 status = wuffs_base__make_status(wuffs_png__error__bad_header);
62835 goto exit;
62837 self->private_impl.f_chunk_type_array[0u] = 73u;
62838 self->private_impl.f_chunk_type_array[1u] = 72u;
62839 self->private_impl.f_chunk_type_array[2u] = 68u;
62840 self->private_impl.f_chunk_type_array[3u] = 82u;
62841 wuffs_private_impl__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32,
62842 sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
62843 wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__make_slice_u8(self->private_impl.f_chunk_type_array, 4));
62844 while (true) {
62845 v_mark = ((uint64_t)(iop_a_src - io0_a_src));
62847 if (a_src) {
62848 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
62850 wuffs_base__status t_2 = wuffs_png__decoder__decode_ihdr(self, a_src);
62851 v_status = t_2;
62852 if (a_src) {
62853 iop_a_src = a_src->data.ptr + a_src->meta.ri;
62856 if ( ! self->private_impl.f_ignore_checksum) {
62857 v_checksum_have = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_private_impl__io__since(v_mark, ((uint64_t)(iop_a_src - io0_a_src)), io0_a_src));
62859 if (wuffs_base__status__is_ok(&v_status)) {
62860 break;
62862 status = v_status;
62863 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
62866 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
62867 uint32_t t_3;
62868 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
62869 t_3 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
62870 iop_a_src += 4;
62871 } else {
62872 self->private_data.s_do_decode_image_config.scratch = 0;
62873 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
62874 while (true) {
62875 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
62876 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
62877 goto suspend;
62879 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
62880 uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFFu));
62881 *scratch >>= 8;
62882 *scratch <<= 8;
62883 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3);
62884 if (num_bits_3 == 24) {
62885 t_3 = ((uint32_t)(*scratch >> 32));
62886 break;
62888 num_bits_3 += 8u;
62889 *scratch |= ((uint64_t)(num_bits_3));
62892 v_checksum_want = t_3;
62894 if ( ! self->private_impl.f_ignore_checksum && (v_checksum_have != v_checksum_want)) {
62895 status = wuffs_base__make_status(wuffs_png__error__bad_checksum);
62896 goto exit;
62898 self->private_impl.f_seen_ihdr = true;
62899 } else if (self->private_impl.f_metadata_fourcc != 0u) {
62900 self->private_impl.f_call_sequence = 16u;
62901 status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
62902 goto ok;
62904 while (true) {
62905 if (((uint64_t)(io2_a_src - iop_a_src)) < 8u) {
62906 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
62907 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8);
62908 continue;
62910 self->private_impl.f_chunk_length = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
62911 self->private_impl.f_chunk_type = ((uint32_t)((wuffs_base__peek_u64le__no_bounds_check(iop_a_src) >> 32u)));
62912 if (self->private_impl.f_chunk_type == 1413563465u) {
62913 if ( ! self->private_impl.f_seen_actl || self->private_impl.f_seen_fctl) {
62914 break;
62916 self->private_impl.f_seen_idat = true;
62917 } else if (self->private_impl.f_chunk_type == 1413571686u) {
62918 if (self->private_impl.f_seen_idat && self->private_impl.f_seen_fctl) {
62919 break;
62921 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
62922 goto exit;
62924 iop_a_src += 8u;
62925 if ( ! self->private_impl.f_ignore_checksum && ((self->private_impl.f_chunk_type & 32u) == 0u)) {
62926 self->private_impl.f_chunk_type_array[0u] = ((uint8_t)((self->private_impl.f_chunk_type >> 0u)));
62927 self->private_impl.f_chunk_type_array[1u] = ((uint8_t)((self->private_impl.f_chunk_type >> 8u)));
62928 self->private_impl.f_chunk_type_array[2u] = ((uint8_t)((self->private_impl.f_chunk_type >> 16u)));
62929 self->private_impl.f_chunk_type_array[3u] = ((uint8_t)((self->private_impl.f_chunk_type >> 24u)));
62930 wuffs_private_impl__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32,
62931 sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
62932 wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__make_slice_u8(self->private_impl.f_chunk_type_array, 4));
62934 while (true) {
62935 v_mark = ((uint64_t)(iop_a_src - io0_a_src));
62937 if (a_src) {
62938 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
62940 wuffs_base__status t_4 = wuffs_png__decoder__decode_other_chunk(self, a_src, false);
62941 v_status = t_4;
62942 if (a_src) {
62943 iop_a_src = a_src->data.ptr + a_src->meta.ri;
62946 if ( ! self->private_impl.f_ignore_checksum && ((self->private_impl.f_chunk_type & 32u) == 0u)) {
62947 v_checksum_have = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_private_impl__io__since(v_mark, ((uint64_t)(iop_a_src - io0_a_src)), io0_a_src));
62949 if (wuffs_base__status__is_ok(&v_status)) {
62950 break;
62952 status = v_status;
62953 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9);
62955 if (self->private_impl.f_metadata_fourcc != 0u) {
62956 self->private_impl.f_call_sequence = 16u;
62957 status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
62958 goto ok;
62961 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
62962 uint32_t t_5;
62963 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
62964 t_5 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
62965 iop_a_src += 4;
62966 } else {
62967 self->private_data.s_do_decode_image_config.scratch = 0;
62968 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
62969 while (true) {
62970 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
62971 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
62972 goto suspend;
62974 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
62975 uint32_t num_bits_5 = ((uint32_t)(*scratch & 0xFFu));
62976 *scratch >>= 8;
62977 *scratch <<= 8;
62978 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_5);
62979 if (num_bits_5 == 24) {
62980 t_5 = ((uint32_t)(*scratch >> 32));
62981 break;
62983 num_bits_5 += 8u;
62984 *scratch |= ((uint64_t)(num_bits_5));
62987 v_checksum_want = t_5;
62989 if ( ! self->private_impl.f_ignore_checksum && ((self->private_impl.f_chunk_type & 32u) == 0u) && (v_checksum_have != v_checksum_want)) {
62990 status = wuffs_base__make_status(wuffs_png__error__bad_checksum);
62991 goto exit;
62994 if ((self->private_impl.f_color_type == 3u) && ! self->private_impl.f_seen_plte) {
62995 status = wuffs_base__make_status(wuffs_png__error__missing_palette);
62996 goto exit;
62998 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)));
62999 self->private_impl.f_first_config_io_position = self->private_impl.f_frame_config_io_position;
63000 if (a_dst != NULL) {
63001 wuffs_base__image_config__set(
63002 a_dst,
63003 self->private_impl.f_dst_pixfmt,
63005 self->private_impl.f_width,
63006 self->private_impl.f_height,
63007 self->private_impl.f_first_config_io_position,
63008 ((self->private_impl.f_color_type <= 3u) && ! self->private_impl.f_seen_trns));
63010 if ( ! self->private_impl.f_seen_actl) {
63011 self->private_impl.f_num_animation_frames_value = 1u;
63012 self->private_impl.f_first_rect_x0 = 0u;
63013 self->private_impl.f_first_rect_y0 = 0u;
63014 self->private_impl.f_first_rect_x1 = self->private_impl.f_width;
63015 self->private_impl.f_first_rect_y1 = self->private_impl.f_height;
63016 self->private_impl.f_first_duration = 0u;
63017 self->private_impl.f_first_disposal = 0u;
63018 self->private_impl.f_first_overwrite_instead_of_blend = false;
63020 self->private_impl.f_call_sequence = 32u;
63023 self->private_impl.p_do_decode_image_config = 0;
63024 goto exit;
63027 goto suspend;
63028 suspend:
63029 self->private_impl.p_do_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
63030 self->private_data.s_do_decode_image_config.v_checksum_have = v_checksum_have;
63032 goto exit;
63033 exit:
63034 if (a_src && a_src->data.ptr) {
63035 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
63038 return status;
63041 // -------- func png.decoder.decode_ihdr
63043 WUFFS_BASE__GENERATED_C_CODE
63044 static wuffs_base__status
63045 wuffs_png__decoder__decode_ihdr(
63046 wuffs_png__decoder* self,
63047 wuffs_base__io_buffer* a_src) {
63048 wuffs_base__status status = wuffs_base__make_status(NULL);
63050 uint32_t v_a32 = 0;
63051 uint8_t v_a8 = 0;
63053 const uint8_t* iop_a_src = NULL;
63054 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
63055 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
63056 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
63057 if (a_src && a_src->data.ptr) {
63058 io0_a_src = a_src->data.ptr;
63059 io1_a_src = io0_a_src + a_src->meta.ri;
63060 iop_a_src = io1_a_src;
63061 io2_a_src = io0_a_src + a_src->meta.wi;
63064 uint32_t coro_susp_point = self->private_impl.p_decode_ihdr;
63065 switch (coro_susp_point) {
63066 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
63069 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
63070 uint32_t t_0;
63071 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
63072 t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
63073 iop_a_src += 4;
63074 } else {
63075 self->private_data.s_decode_ihdr.scratch = 0;
63076 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
63077 while (true) {
63078 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
63079 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
63080 goto suspend;
63082 uint64_t* scratch = &self->private_data.s_decode_ihdr.scratch;
63083 uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu));
63084 *scratch >>= 8;
63085 *scratch <<= 8;
63086 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
63087 if (num_bits_0 == 24) {
63088 t_0 = ((uint32_t)(*scratch >> 32));
63089 break;
63091 num_bits_0 += 8u;
63092 *scratch |= ((uint64_t)(num_bits_0));
63095 v_a32 = t_0;
63097 if ((v_a32 == 0u) || (v_a32 > 2147483647u)) {
63098 status = wuffs_base__make_status(wuffs_png__error__bad_header);
63099 goto exit;
63100 } else if (v_a32 > 16777215u) {
63101 status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension);
63102 goto exit;
63104 self->private_impl.f_width = v_a32;
63106 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
63107 uint32_t t_1;
63108 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
63109 t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
63110 iop_a_src += 4;
63111 } else {
63112 self->private_data.s_decode_ihdr.scratch = 0;
63113 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
63114 while (true) {
63115 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
63116 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
63117 goto suspend;
63119 uint64_t* scratch = &self->private_data.s_decode_ihdr.scratch;
63120 uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu));
63121 *scratch >>= 8;
63122 *scratch <<= 8;
63123 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
63124 if (num_bits_1 == 24) {
63125 t_1 = ((uint32_t)(*scratch >> 32));
63126 break;
63128 num_bits_1 += 8u;
63129 *scratch |= ((uint64_t)(num_bits_1));
63132 v_a32 = t_1;
63134 if ((v_a32 == 0u) || (v_a32 > 2147483647u)) {
63135 status = wuffs_base__make_status(wuffs_png__error__bad_header);
63136 goto exit;
63137 } else if (v_a32 > 16777215u) {
63138 status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension);
63139 goto exit;
63141 self->private_impl.f_height = v_a32;
63143 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
63144 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
63145 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
63146 goto suspend;
63148 uint8_t t_2 = *iop_a_src++;
63149 v_a8 = t_2;
63151 if (v_a8 > 16u) {
63152 status = wuffs_base__make_status(wuffs_png__error__bad_header);
63153 goto exit;
63155 self->private_impl.f_depth = v_a8;
63157 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
63158 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
63159 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
63160 goto suspend;
63162 uint8_t t_3 = *iop_a_src++;
63163 v_a8 = t_3;
63165 if ((v_a8 == 1u) || (v_a8 == 5u) || (v_a8 > 6u)) {
63166 status = wuffs_base__make_status(wuffs_png__error__bad_header);
63167 goto exit;
63169 self->private_impl.f_color_type = v_a8;
63171 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
63172 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
63173 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
63174 goto suspend;
63176 uint8_t t_4 = *iop_a_src++;
63177 v_a8 = t_4;
63179 if (v_a8 != 0u) {
63180 status = wuffs_base__make_status(wuffs_png__error__unsupported_png_compression_method);
63181 goto exit;
63184 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
63185 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
63186 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
63187 goto suspend;
63189 uint8_t t_5 = *iop_a_src++;
63190 v_a8 = t_5;
63192 if (v_a8 != 0u) {
63193 status = wuffs_base__make_status(wuffs_png__error__bad_header);
63194 goto exit;
63197 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
63198 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
63199 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
63200 goto suspend;
63202 uint8_t t_6 = *iop_a_src++;
63203 v_a8 = t_6;
63205 if (v_a8 == 0u) {
63206 self->private_impl.f_interlace_pass = 0u;
63207 } else if (v_a8 == 1u) {
63208 self->private_impl.f_interlace_pass = 1u;
63209 self->private_impl.choosy_filter_and_swizzle = (
63210 &wuffs_png__decoder__filter_and_swizzle_tricky);
63211 } else {
63212 status = wuffs_base__make_status(wuffs_png__error__bad_header);
63213 goto exit;
63215 self->private_impl.f_filter_distance = 0u;
63216 wuffs_png__decoder__assign_filter_distance(self);
63217 if (self->private_impl.f_filter_distance == 0u) {
63218 status = wuffs_base__make_status(wuffs_png__error__bad_header);
63219 goto exit;
63221 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)));
63222 wuffs_png__decoder__choose_filter_implementations(self);
63224 goto ok;
63226 self->private_impl.p_decode_ihdr = 0;
63227 goto exit;
63230 goto suspend;
63231 suspend:
63232 self->private_impl.p_decode_ihdr = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
63234 goto exit;
63235 exit:
63236 if (a_src && a_src->data.ptr) {
63237 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
63240 return status;
63243 // -------- func png.decoder.assign_filter_distance
63245 WUFFS_BASE__GENERATED_C_CODE
63246 static wuffs_base__empty_struct
63247 wuffs_png__decoder__assign_filter_distance(
63248 wuffs_png__decoder* self) {
63249 if (self->private_impl.f_depth < 8u) {
63250 if ((self->private_impl.f_depth != 1u) && (self->private_impl.f_depth != 2u) && (self->private_impl.f_depth != 4u)) {
63251 return wuffs_base__make_empty_struct();
63252 } else if (self->private_impl.f_color_type == 0u) {
63253 self->private_impl.f_dst_pixfmt = 536870920u;
63254 self->private_impl.f_src_pixfmt = 536870920u;
63255 } else if (self->private_impl.f_color_type == 3u) {
63256 self->private_impl.f_dst_pixfmt = 2198077448u;
63257 self->private_impl.f_src_pixfmt = 2198077448u;
63258 } else {
63259 return wuffs_base__make_empty_struct();
63261 self->private_impl.f_filter_distance = 1u;
63262 self->private_impl.choosy_filter_and_swizzle = (
63263 &wuffs_png__decoder__filter_and_swizzle_tricky);
63264 } else if (self->private_impl.f_color_type == 0u) {
63265 if (self->private_impl.f_depth == 8u) {
63266 self->private_impl.f_dst_pixfmt = 536870920u;
63267 self->private_impl.f_src_pixfmt = 536870920u;
63268 self->private_impl.f_filter_distance = 1u;
63269 } else if (self->private_impl.f_depth == 16u) {
63270 if (self->private_impl.f_interlace_pass == 0u) {
63271 self->private_impl.f_dst_pixfmt = 536870923u;
63272 self->private_impl.f_src_pixfmt = 537919499u;
63273 } else {
63274 self->private_impl.f_dst_pixfmt = 2164308923u;
63275 self->private_impl.f_src_pixfmt = 2164308923u;
63277 self->private_impl.f_filter_distance = 2u;
63279 } else if (self->private_impl.f_color_type == 2u) {
63280 if (self->private_impl.f_depth == 8u) {
63281 self->private_impl.f_dst_pixfmt = 2147485832u;
63282 self->private_impl.f_src_pixfmt = 2684356744u;
63283 self->private_impl.f_filter_distance = 3u;
63284 } else if (self->private_impl.f_depth == 16u) {
63285 self->private_impl.f_dst_pixfmt = 2164308923u;
63286 self->private_impl.f_src_pixfmt = 2164308923u;
63287 self->private_impl.f_filter_distance = 6u;
63288 self->private_impl.choosy_filter_and_swizzle = (
63289 &wuffs_png__decoder__filter_and_swizzle_tricky);
63291 } else if (self->private_impl.f_color_type == 3u) {
63292 if (self->private_impl.f_depth == 8u) {
63293 self->private_impl.f_dst_pixfmt = 2198077448u;
63294 self->private_impl.f_src_pixfmt = 2198077448u;
63295 self->private_impl.f_filter_distance = 1u;
63297 } else if (self->private_impl.f_color_type == 4u) {
63298 if (self->private_impl.f_depth == 8u) {
63299 self->private_impl.f_dst_pixfmt = 553648264u;
63300 self->private_impl.f_src_pixfmt = 553648264u;
63301 self->private_impl.f_filter_distance = 2u;
63302 } else if (self->private_impl.f_depth == 16u) {
63303 self->private_impl.f_dst_pixfmt = 2164308923u;
63304 self->private_impl.f_src_pixfmt = 2164308923u;
63305 self->private_impl.f_filter_distance = 4u;
63306 self->private_impl.choosy_filter_and_swizzle = (
63307 &wuffs_png__decoder__filter_and_swizzle_tricky);
63309 } else if (self->private_impl.f_color_type == 6u) {
63310 if (self->private_impl.f_depth == 8u) {
63311 self->private_impl.f_dst_pixfmt = 2164295816u;
63312 self->private_impl.f_src_pixfmt = 2701166728u;
63313 self->private_impl.f_filter_distance = 4u;
63314 } else if (self->private_impl.f_depth == 16u) {
63315 self->private_impl.f_dst_pixfmt = 2164308923u;
63316 self->private_impl.f_src_pixfmt = 2164308923u;
63317 self->private_impl.f_filter_distance = 8u;
63318 self->private_impl.choosy_filter_and_swizzle = (
63319 &wuffs_png__decoder__filter_and_swizzle_tricky);
63322 return wuffs_base__make_empty_struct();
63325 // -------- func png.decoder.calculate_bytes_per_row
63327 WUFFS_BASE__GENERATED_C_CODE
63328 static uint64_t
63329 wuffs_png__decoder__calculate_bytes_per_row(
63330 const wuffs_png__decoder* self,
63331 uint32_t a_width) {
63332 uint64_t v_bytes_per_channel = 0;
63334 if (self->private_impl.f_depth == 1u) {
63335 return ((uint64_t)(((a_width + 7u) / 8u)));
63336 } else if (self->private_impl.f_depth == 2u) {
63337 return ((uint64_t)(((a_width + 3u) / 4u)));
63338 } else if (self->private_impl.f_depth == 4u) {
63339 return ((uint64_t)(((a_width + 1u) / 2u)));
63341 v_bytes_per_channel = ((uint64_t)(((uint8_t)(self->private_impl.f_depth >> 3u))));
63342 return (((uint64_t)(a_width)) * v_bytes_per_channel * ((uint64_t)(WUFFS_PNG__NUM_CHANNELS[self->private_impl.f_color_type])));
63345 // -------- func png.decoder.choose_filter_implementations
63347 WUFFS_BASE__GENERATED_C_CODE
63348 static wuffs_base__empty_struct
63349 wuffs_png__decoder__choose_filter_implementations(
63350 wuffs_png__decoder* self) {
63351 if (self->private_impl.f_filter_distance == 3u) {
63352 self->private_impl.choosy_filter_1 = (
63353 &wuffs_png__decoder__filter_1_distance_3_fallback);
63354 self->private_impl.choosy_filter_3 = (
63355 &wuffs_png__decoder__filter_3_distance_3_fallback);
63356 self->private_impl.choosy_filter_4 = (
63357 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON)
63358 wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_png__decoder__filter_4_distance_3_arm_neon :
63359 #endif
63360 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
63361 wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_png__decoder__filter_4_distance_3_x86_sse42 :
63362 #endif
63363 &wuffs_png__decoder__filter_4_distance_3_fallback);
63364 } else if (self->private_impl.f_filter_distance == 4u) {
63365 self->private_impl.choosy_filter_1 = (
63366 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON)
63367 wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_png__decoder__filter_1_distance_4_arm_neon :
63368 #endif
63369 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
63370 wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_png__decoder__filter_1_distance_4_x86_sse42 :
63371 #endif
63372 &wuffs_png__decoder__filter_1_distance_4_fallback);
63373 self->private_impl.choosy_filter_3 = (
63374 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON)
63375 wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_png__decoder__filter_3_distance_4_arm_neon :
63376 #endif
63377 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
63378 wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_png__decoder__filter_3_distance_4_x86_sse42 :
63379 #endif
63380 &wuffs_png__decoder__filter_3_distance_4_fallback);
63381 self->private_impl.choosy_filter_4 = (
63382 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON)
63383 wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_png__decoder__filter_4_distance_4_arm_neon :
63384 #endif
63385 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2)
63386 wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_png__decoder__filter_4_distance_4_x86_sse42 :
63387 #endif
63388 &wuffs_png__decoder__filter_4_distance_4_fallback);
63390 return wuffs_base__make_empty_struct();
63393 // -------- func png.decoder.decode_other_chunk
63395 WUFFS_BASE__GENERATED_C_CODE
63396 static wuffs_base__status
63397 wuffs_png__decoder__decode_other_chunk(
63398 wuffs_png__decoder* self,
63399 wuffs_base__io_buffer* a_src,
63400 bool a_framy) {
63401 wuffs_base__status status = wuffs_base__make_status(NULL);
63403 const uint8_t* iop_a_src = NULL;
63404 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
63405 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
63406 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
63407 if (a_src && a_src->data.ptr) {
63408 io0_a_src = a_src->data.ptr;
63409 io1_a_src = io0_a_src + a_src->meta.ri;
63410 iop_a_src = io1_a_src;
63411 io2_a_src = io0_a_src + a_src->meta.wi;
63414 uint32_t coro_susp_point = self->private_impl.p_decode_other_chunk;
63415 switch (coro_susp_point) {
63416 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
63418 if ((self->private_impl.f_chunk_type == 1163152464u) && ! a_framy) {
63419 if (self->private_impl.f_seen_plte) {
63420 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
63421 goto exit;
63422 } else if (self->private_impl.f_color_type == 3u) {
63423 if (a_src) {
63424 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
63426 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
63427 status = wuffs_png__decoder__decode_plte(self, a_src);
63428 if (a_src) {
63429 iop_a_src = a_src->data.ptr + a_src->meta.ri;
63431 if (status.repr) {
63432 goto suspend;
63434 } else if ((self->private_impl.f_color_type == 2u) || (self->private_impl.f_color_type == 6u)) {
63435 } else {
63436 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
63437 goto exit;
63439 self->private_impl.f_seen_plte = true;
63440 } else if ((self->private_impl.f_chunk_type & 32u) == 0u) {
63441 if (self->private_impl.f_chunk_type != 1413563465u) {
63442 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
63443 goto exit;
63446 if (self->private_impl.f_chunk_type == 1716082789u) {
63447 if (self->private_impl.f_report_metadata_exif) {
63448 if (self->private_impl.f_seen_exif) {
63449 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
63450 goto exit;
63452 if (a_src) {
63453 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
63455 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
63456 status = wuffs_png__decoder__decode_exif(self, a_src);
63457 if (a_src) {
63458 iop_a_src = a_src->data.ptr + a_src->meta.ri;
63460 if (status.repr) {
63461 goto suspend;
63463 self->private_impl.f_seen_exif = true;
63465 } else if ((self->private_impl.f_chunk_type == 1951945833u) || (self->private_impl.f_chunk_type == 1951942004u) || (self->private_impl.f_chunk_type == 1951945850u)) {
63466 if (self->private_impl.f_report_metadata_kvp) {
63467 self->private_impl.f_metadata_flavor = 4u;
63468 self->private_impl.f_metadata_fourcc = 1263947851u;
63469 self->private_impl.f_metadata_x = 0u;
63470 self->private_impl.f_metadata_y = 0u;
63471 self->private_impl.f_metadata_z = 0u;
63473 } else if ( ! a_framy) {
63474 if (self->private_impl.f_chunk_type == 1280598881u) {
63475 if (self->private_impl.f_seen_actl) {
63476 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
63477 goto exit;
63479 if (a_src) {
63480 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
63482 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
63483 status = wuffs_png__decoder__decode_actl(self, a_src);
63484 if (a_src) {
63485 iop_a_src = a_src->data.ptr + a_src->meta.ri;
63487 if (status.repr) {
63488 goto suspend;
63490 self->private_impl.f_seen_actl = true;
63491 } else if (self->private_impl.f_chunk_type == 1297238115u) {
63492 if (self->private_impl.f_report_metadata_chrm) {
63493 if (self->private_impl.f_seen_chrm) {
63494 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
63495 goto exit;
63497 if (a_src) {
63498 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
63500 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
63501 status = wuffs_png__decoder__decode_chrm(self, a_src);
63502 if (a_src) {
63503 iop_a_src = a_src->data.ptr + a_src->meta.ri;
63505 if (status.repr) {
63506 goto suspend;
63508 self->private_impl.f_seen_chrm = true;
63510 } else if (self->private_impl.f_chunk_type == 1280598886u) {
63511 if (self->private_impl.f_seen_fctl) {
63512 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
63513 goto exit;
63515 if (a_src) {
63516 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
63518 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
63519 status = wuffs_png__decoder__decode_fctl(self, a_src);
63520 if (a_src) {
63521 iop_a_src = a_src->data.ptr + a_src->meta.ri;
63523 if (status.repr) {
63524 goto suspend;
63526 self->private_impl.f_seen_fctl = true;
63527 } else if (self->private_impl.f_chunk_type == 1095582055u) {
63528 if (self->private_impl.f_report_metadata_gama) {
63529 if (self->private_impl.f_seen_gama) {
63530 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
63531 goto exit;
63533 if (a_src) {
63534 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
63536 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
63537 status = wuffs_png__decoder__decode_gama(self, a_src);
63538 if (a_src) {
63539 iop_a_src = a_src->data.ptr + a_src->meta.ri;
63541 if (status.repr) {
63542 goto suspend;
63544 self->private_impl.f_seen_gama = true;
63546 } else if (self->private_impl.f_chunk_type == 1346585449u) {
63547 if (self->private_impl.f_report_metadata_iccp) {
63548 if (self->private_impl.f_seen_iccp) {
63549 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
63550 goto exit;
63552 if (a_src) {
63553 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
63555 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
63556 status = wuffs_png__decoder__decode_iccp(self, a_src);
63557 if (a_src) {
63558 iop_a_src = a_src->data.ptr + a_src->meta.ri;
63560 if (status.repr) {
63561 goto suspend;
63563 self->private_impl.f_seen_iccp = true;
63565 } else if (self->private_impl.f_chunk_type == 1111970419u) {
63566 if (self->private_impl.f_report_metadata_srgb) {
63567 if (self->private_impl.f_seen_srgb) {
63568 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
63569 goto exit;
63571 if (a_src) {
63572 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
63574 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
63575 status = wuffs_png__decoder__decode_srgb(self, a_src);
63576 if (a_src) {
63577 iop_a_src = a_src->data.ptr + a_src->meta.ri;
63579 if (status.repr) {
63580 goto suspend;
63582 self->private_impl.f_seen_srgb = true;
63584 } else if (self->private_impl.f_chunk_type == 1397641844u) {
63585 if (self->private_impl.f_seen_trns || ((self->private_impl.f_color_type == 3u) && ! self->private_impl.f_seen_plte)) {
63586 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
63587 goto exit;
63588 } else if (self->private_impl.f_color_type > 3u) {
63589 } else {
63590 if (a_src) {
63591 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
63593 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
63594 status = wuffs_png__decoder__decode_trns(self, a_src);
63595 if (a_src) {
63596 iop_a_src = a_src->data.ptr + a_src->meta.ri;
63598 if (status.repr) {
63599 goto suspend;
63602 self->private_impl.f_seen_trns = true;
63605 if (self->private_impl.f_metadata_fourcc == 0u) {
63606 self->private_data.s_decode_other_chunk.scratch = self->private_impl.f_chunk_length;
63607 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
63608 if (self->private_data.s_decode_other_chunk.scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
63609 self->private_data.s_decode_other_chunk.scratch -= ((uint64_t)(io2_a_src - iop_a_src));
63610 iop_a_src = io2_a_src;
63611 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
63612 goto suspend;
63614 iop_a_src += self->private_data.s_decode_other_chunk.scratch;
63617 goto ok;
63619 self->private_impl.p_decode_other_chunk = 0;
63620 goto exit;
63623 goto suspend;
63624 suspend:
63625 self->private_impl.p_decode_other_chunk = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
63627 goto exit;
63628 exit:
63629 if (a_src && a_src->data.ptr) {
63630 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
63633 return status;
63636 // -------- func png.decoder.decode_actl
63638 WUFFS_BASE__GENERATED_C_CODE
63639 static wuffs_base__status
63640 wuffs_png__decoder__decode_actl(
63641 wuffs_png__decoder* self,
63642 wuffs_base__io_buffer* a_src) {
63643 wuffs_base__status status = wuffs_base__make_status(NULL);
63645 const uint8_t* iop_a_src = NULL;
63646 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
63647 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
63648 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
63649 if (a_src && a_src->data.ptr) {
63650 io0_a_src = a_src->data.ptr;
63651 io1_a_src = io0_a_src + a_src->meta.ri;
63652 iop_a_src = io1_a_src;
63653 io2_a_src = io0_a_src + a_src->meta.wi;
63656 uint32_t coro_susp_point = self->private_impl.p_decode_actl;
63657 switch (coro_susp_point) {
63658 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
63660 if (self->private_impl.f_chunk_length != 8u) {
63661 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
63662 goto exit;
63663 } else if (self->private_impl.f_interlace_pass > 0u) {
63664 status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file);
63665 goto exit;
63667 self->private_impl.f_chunk_length = 0u;
63669 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
63670 uint32_t t_0;
63671 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
63672 t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
63673 iop_a_src += 4;
63674 } else {
63675 self->private_data.s_decode_actl.scratch = 0;
63676 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
63677 while (true) {
63678 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
63679 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
63680 goto suspend;
63682 uint64_t* scratch = &self->private_data.s_decode_actl.scratch;
63683 uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu));
63684 *scratch >>= 8;
63685 *scratch <<= 8;
63686 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
63687 if (num_bits_0 == 24) {
63688 t_0 = ((uint32_t)(*scratch >> 32));
63689 break;
63691 num_bits_0 += 8u;
63692 *scratch |= ((uint64_t)(num_bits_0));
63695 self->private_impl.f_num_animation_frames_value = t_0;
63697 if (self->private_impl.f_num_animation_frames_value == 0u) {
63698 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
63699 goto exit;
63702 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
63703 uint32_t t_1;
63704 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
63705 t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
63706 iop_a_src += 4;
63707 } else {
63708 self->private_data.s_decode_actl.scratch = 0;
63709 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
63710 while (true) {
63711 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
63712 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
63713 goto suspend;
63715 uint64_t* scratch = &self->private_data.s_decode_actl.scratch;
63716 uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu));
63717 *scratch >>= 8;
63718 *scratch <<= 8;
63719 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
63720 if (num_bits_1 == 24) {
63721 t_1 = ((uint32_t)(*scratch >> 32));
63722 break;
63724 num_bits_1 += 8u;
63725 *scratch |= ((uint64_t)(num_bits_1));
63728 self->private_impl.f_num_animation_loops_value = t_1;
63731 goto ok;
63733 self->private_impl.p_decode_actl = 0;
63734 goto exit;
63737 goto suspend;
63738 suspend:
63739 self->private_impl.p_decode_actl = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
63741 goto exit;
63742 exit:
63743 if (a_src && a_src->data.ptr) {
63744 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
63747 return status;
63750 // -------- func png.decoder.decode_chrm
63752 WUFFS_BASE__GENERATED_C_CODE
63753 static wuffs_base__status
63754 wuffs_png__decoder__decode_chrm(
63755 wuffs_png__decoder* self,
63756 wuffs_base__io_buffer* a_src) {
63757 wuffs_base__status status = wuffs_base__make_status(NULL);
63759 uint64_t v_u = 0;
63761 const uint8_t* iop_a_src = NULL;
63762 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
63763 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
63764 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
63765 if (a_src && a_src->data.ptr) {
63766 io0_a_src = a_src->data.ptr;
63767 io1_a_src = io0_a_src + a_src->meta.ri;
63768 iop_a_src = io1_a_src;
63769 io2_a_src = io0_a_src + a_src->meta.wi;
63772 uint32_t coro_susp_point = self->private_impl.p_decode_chrm;
63773 switch (coro_susp_point) {
63774 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
63776 if (self->private_impl.f_chunk_length != 32u) {
63777 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
63778 goto exit;
63780 self->private_impl.f_chunk_length = 0u;
63781 self->private_impl.f_metadata_flavor = 5u;
63782 self->private_impl.f_metadata_fourcc = 1128813133u;
63783 self->private_impl.f_metadata_x = 0u;
63784 self->private_impl.f_metadata_y = 0u;
63785 self->private_impl.f_metadata_z = 0u;
63787 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
63788 uint64_t t_0;
63789 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
63790 t_0 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
63791 iop_a_src += 4;
63792 } else {
63793 self->private_data.s_decode_chrm.scratch = 0;
63794 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
63795 while (true) {
63796 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
63797 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
63798 goto suspend;
63800 uint64_t* scratch = &self->private_data.s_decode_chrm.scratch;
63801 uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu));
63802 *scratch >>= 8;
63803 *scratch <<= 8;
63804 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
63805 if (num_bits_0 == 24) {
63806 t_0 = ((uint64_t)(*scratch >> 32));
63807 break;
63809 num_bits_0 += 8u;
63810 *scratch |= ((uint64_t)(num_bits_0));
63813 v_u = t_0;
63815 self->private_impl.f_metadata_x |= ((16777215u & v_u) << 0u);
63817 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
63818 uint64_t t_1;
63819 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
63820 t_1 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
63821 iop_a_src += 4;
63822 } else {
63823 self->private_data.s_decode_chrm.scratch = 0;
63824 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
63825 while (true) {
63826 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
63827 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
63828 goto suspend;
63830 uint64_t* scratch = &self->private_data.s_decode_chrm.scratch;
63831 uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu));
63832 *scratch >>= 8;
63833 *scratch <<= 8;
63834 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
63835 if (num_bits_1 == 24) {
63836 t_1 = ((uint64_t)(*scratch >> 32));
63837 break;
63839 num_bits_1 += 8u;
63840 *scratch |= ((uint64_t)(num_bits_1));
63843 v_u = t_1;
63845 self->private_impl.f_metadata_x |= ((16777215u & v_u) << 24u);
63847 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
63848 uint64_t t_2;
63849 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
63850 t_2 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
63851 iop_a_src += 4;
63852 } else {
63853 self->private_data.s_decode_chrm.scratch = 0;
63854 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
63855 while (true) {
63856 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
63857 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
63858 goto suspend;
63860 uint64_t* scratch = &self->private_data.s_decode_chrm.scratch;
63861 uint32_t num_bits_2 = ((uint32_t)(*scratch & 0xFFu));
63862 *scratch >>= 8;
63863 *scratch <<= 8;
63864 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_2);
63865 if (num_bits_2 == 24) {
63866 t_2 = ((uint64_t)(*scratch >> 32));
63867 break;
63869 num_bits_2 += 8u;
63870 *scratch |= ((uint64_t)(num_bits_2));
63873 v_u = t_2;
63875 self->private_impl.f_metadata_x |= ((uint64_t)((16777215u & v_u) << 48u));
63876 self->private_impl.f_metadata_y |= ((16777215u & v_u) >> 16u);
63878 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
63879 uint64_t t_3;
63880 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
63881 t_3 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
63882 iop_a_src += 4;
63883 } else {
63884 self->private_data.s_decode_chrm.scratch = 0;
63885 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
63886 while (true) {
63887 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
63888 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
63889 goto suspend;
63891 uint64_t* scratch = &self->private_data.s_decode_chrm.scratch;
63892 uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFFu));
63893 *scratch >>= 8;
63894 *scratch <<= 8;
63895 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3);
63896 if (num_bits_3 == 24) {
63897 t_3 = ((uint64_t)(*scratch >> 32));
63898 break;
63900 num_bits_3 += 8u;
63901 *scratch |= ((uint64_t)(num_bits_3));
63904 v_u = t_3;
63906 self->private_impl.f_metadata_y |= ((16777215u & v_u) << 8u);
63908 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
63909 uint64_t t_4;
63910 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
63911 t_4 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
63912 iop_a_src += 4;
63913 } else {
63914 self->private_data.s_decode_chrm.scratch = 0;
63915 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
63916 while (true) {
63917 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
63918 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
63919 goto suspend;
63921 uint64_t* scratch = &self->private_data.s_decode_chrm.scratch;
63922 uint32_t num_bits_4 = ((uint32_t)(*scratch & 0xFFu));
63923 *scratch >>= 8;
63924 *scratch <<= 8;
63925 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_4);
63926 if (num_bits_4 == 24) {
63927 t_4 = ((uint64_t)(*scratch >> 32));
63928 break;
63930 num_bits_4 += 8u;
63931 *scratch |= ((uint64_t)(num_bits_4));
63934 v_u = t_4;
63936 self->private_impl.f_metadata_y |= ((16777215u & v_u) << 32u);
63938 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
63939 uint64_t t_5;
63940 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
63941 t_5 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
63942 iop_a_src += 4;
63943 } else {
63944 self->private_data.s_decode_chrm.scratch = 0;
63945 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
63946 while (true) {
63947 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
63948 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
63949 goto suspend;
63951 uint64_t* scratch = &self->private_data.s_decode_chrm.scratch;
63952 uint32_t num_bits_5 = ((uint32_t)(*scratch & 0xFFu));
63953 *scratch >>= 8;
63954 *scratch <<= 8;
63955 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_5);
63956 if (num_bits_5 == 24) {
63957 t_5 = ((uint64_t)(*scratch >> 32));
63958 break;
63960 num_bits_5 += 8u;
63961 *scratch |= ((uint64_t)(num_bits_5));
63964 v_u = t_5;
63966 self->private_impl.f_metadata_y |= ((uint64_t)((16777215u & v_u) << 56u));
63967 self->private_impl.f_metadata_z |= ((16777215u & v_u) >> 8u);
63969 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
63970 uint64_t t_6;
63971 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
63972 t_6 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
63973 iop_a_src += 4;
63974 } else {
63975 self->private_data.s_decode_chrm.scratch = 0;
63976 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
63977 while (true) {
63978 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
63979 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
63980 goto suspend;
63982 uint64_t* scratch = &self->private_data.s_decode_chrm.scratch;
63983 uint32_t num_bits_6 = ((uint32_t)(*scratch & 0xFFu));
63984 *scratch >>= 8;
63985 *scratch <<= 8;
63986 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_6);
63987 if (num_bits_6 == 24) {
63988 t_6 = ((uint64_t)(*scratch >> 32));
63989 break;
63991 num_bits_6 += 8u;
63992 *scratch |= ((uint64_t)(num_bits_6));
63995 v_u = t_6;
63997 self->private_impl.f_metadata_z |= ((16777215u & v_u) << 16u);
63999 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
64000 uint64_t t_7;
64001 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
64002 t_7 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
64003 iop_a_src += 4;
64004 } else {
64005 self->private_data.s_decode_chrm.scratch = 0;
64006 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
64007 while (true) {
64008 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
64009 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
64010 goto suspend;
64012 uint64_t* scratch = &self->private_data.s_decode_chrm.scratch;
64013 uint32_t num_bits_7 = ((uint32_t)(*scratch & 0xFFu));
64014 *scratch >>= 8;
64015 *scratch <<= 8;
64016 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_7);
64017 if (num_bits_7 == 24) {
64018 t_7 = ((uint64_t)(*scratch >> 32));
64019 break;
64021 num_bits_7 += 8u;
64022 *scratch |= ((uint64_t)(num_bits_7));
64025 v_u = t_7;
64027 self->private_impl.f_metadata_z |= ((16777215u & v_u) << 40u);
64029 goto ok;
64031 self->private_impl.p_decode_chrm = 0;
64032 goto exit;
64035 goto suspend;
64036 suspend:
64037 self->private_impl.p_decode_chrm = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
64039 goto exit;
64040 exit:
64041 if (a_src && a_src->data.ptr) {
64042 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
64045 return status;
64048 // -------- func png.decoder.decode_exif
64050 WUFFS_BASE__GENERATED_C_CODE
64051 static wuffs_base__status
64052 wuffs_png__decoder__decode_exif(
64053 wuffs_png__decoder* self,
64054 wuffs_base__io_buffer* a_src) {
64055 wuffs_base__status status = wuffs_base__make_status(NULL);
64057 const uint8_t* iop_a_src = NULL;
64058 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
64059 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
64060 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
64061 if (a_src && a_src->data.ptr) {
64062 io0_a_src = a_src->data.ptr;
64063 io1_a_src = io0_a_src + a_src->meta.ri;
64064 iop_a_src = io1_a_src;
64065 io2_a_src = io0_a_src + a_src->meta.wi;
64068 if (self->private_impl.f_chunk_length < 4u) {
64069 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
64070 goto exit;
64072 self->private_impl.f_metadata_flavor = 3u;
64073 self->private_impl.f_metadata_fourcc = 1163413830u;
64074 self->private_impl.f_metadata_x = 0u;
64075 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)));
64076 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)));
64077 self->private_impl.f_chunk_length = 0u;
64079 goto ok;
64081 goto exit;
64082 exit:
64083 if (a_src && a_src->data.ptr) {
64084 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
64087 return status;
64090 // -------- func png.decoder.decode_fctl
64092 WUFFS_BASE__GENERATED_C_CODE
64093 static wuffs_base__status
64094 wuffs_png__decoder__decode_fctl(
64095 wuffs_png__decoder* self,
64096 wuffs_base__io_buffer* a_src) {
64097 wuffs_base__status status = wuffs_base__make_status(NULL);
64099 uint32_t v_x0 = 0;
64100 uint32_t v_y0 = 0;
64101 uint32_t v_x1 = 0;
64102 uint32_t v_y1 = 0;
64104 const uint8_t* iop_a_src = NULL;
64105 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
64106 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
64107 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
64108 if (a_src && a_src->data.ptr) {
64109 io0_a_src = a_src->data.ptr;
64110 io1_a_src = io0_a_src + a_src->meta.ri;
64111 iop_a_src = io1_a_src;
64112 io2_a_src = io0_a_src + a_src->meta.wi;
64115 uint32_t coro_susp_point = self->private_impl.p_decode_fctl;
64116 if (coro_susp_point) {
64117 v_x0 = self->private_data.s_decode_fctl.v_x0;
64118 v_x1 = self->private_data.s_decode_fctl.v_x1;
64119 v_y1 = self->private_data.s_decode_fctl.v_y1;
64121 switch (coro_susp_point) {
64122 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
64124 if (self->private_impl.f_chunk_length != 26u) {
64125 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
64126 goto exit;
64128 self->private_impl.f_chunk_length = 0u;
64130 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
64131 uint32_t t_0;
64132 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
64133 t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
64134 iop_a_src += 4;
64135 } else {
64136 self->private_data.s_decode_fctl.scratch = 0;
64137 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
64138 while (true) {
64139 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
64140 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
64141 goto suspend;
64143 uint64_t* scratch = &self->private_data.s_decode_fctl.scratch;
64144 uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu));
64145 *scratch >>= 8;
64146 *scratch <<= 8;
64147 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
64148 if (num_bits_0 == 24) {
64149 t_0 = ((uint32_t)(*scratch >> 32));
64150 break;
64152 num_bits_0 += 8u;
64153 *scratch |= ((uint64_t)(num_bits_0));
64156 v_x0 = t_0;
64158 if (v_x0 != self->private_impl.f_next_animation_seq_num) {
64159 status = wuffs_base__make_status(wuffs_png__error__bad_animation_sequence_number);
64160 goto exit;
64161 } else if (self->private_impl.f_next_animation_seq_num >= 4294967295u) {
64162 status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file);
64163 goto exit;
64165 self->private_impl.f_next_animation_seq_num += 1u;
64167 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
64168 uint32_t t_1;
64169 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
64170 t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
64171 iop_a_src += 4;
64172 } else {
64173 self->private_data.s_decode_fctl.scratch = 0;
64174 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
64175 while (true) {
64176 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
64177 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
64178 goto suspend;
64180 uint64_t* scratch = &self->private_data.s_decode_fctl.scratch;
64181 uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu));
64182 *scratch >>= 8;
64183 *scratch <<= 8;
64184 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
64185 if (num_bits_1 == 24) {
64186 t_1 = ((uint32_t)(*scratch >> 32));
64187 break;
64189 num_bits_1 += 8u;
64190 *scratch |= ((uint64_t)(num_bits_1));
64193 v_x1 = t_1;
64196 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
64197 uint32_t t_2;
64198 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
64199 t_2 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
64200 iop_a_src += 4;
64201 } else {
64202 self->private_data.s_decode_fctl.scratch = 0;
64203 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
64204 while (true) {
64205 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
64206 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
64207 goto suspend;
64209 uint64_t* scratch = &self->private_data.s_decode_fctl.scratch;
64210 uint32_t num_bits_2 = ((uint32_t)(*scratch & 0xFFu));
64211 *scratch >>= 8;
64212 *scratch <<= 8;
64213 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_2);
64214 if (num_bits_2 == 24) {
64215 t_2 = ((uint32_t)(*scratch >> 32));
64216 break;
64218 num_bits_2 += 8u;
64219 *scratch |= ((uint64_t)(num_bits_2));
64222 v_y1 = t_2;
64225 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
64226 uint32_t t_3;
64227 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
64228 t_3 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
64229 iop_a_src += 4;
64230 } else {
64231 self->private_data.s_decode_fctl.scratch = 0;
64232 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
64233 while (true) {
64234 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
64235 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
64236 goto suspend;
64238 uint64_t* scratch = &self->private_data.s_decode_fctl.scratch;
64239 uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFFu));
64240 *scratch >>= 8;
64241 *scratch <<= 8;
64242 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3);
64243 if (num_bits_3 == 24) {
64244 t_3 = ((uint32_t)(*scratch >> 32));
64245 break;
64247 num_bits_3 += 8u;
64248 *scratch |= ((uint64_t)(num_bits_3));
64251 v_x0 = t_3;
64254 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
64255 uint32_t t_4;
64256 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
64257 t_4 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
64258 iop_a_src += 4;
64259 } else {
64260 self->private_data.s_decode_fctl.scratch = 0;
64261 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
64262 while (true) {
64263 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
64264 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
64265 goto suspend;
64267 uint64_t* scratch = &self->private_data.s_decode_fctl.scratch;
64268 uint32_t num_bits_4 = ((uint32_t)(*scratch & 0xFFu));
64269 *scratch >>= 8;
64270 *scratch <<= 8;
64271 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_4);
64272 if (num_bits_4 == 24) {
64273 t_4 = ((uint32_t)(*scratch >> 32));
64274 break;
64276 num_bits_4 += 8u;
64277 *scratch |= ((uint64_t)(num_bits_4));
64280 v_y0 = t_4;
64282 v_x1 += v_x0;
64283 v_y1 += v_y0;
64284 if ((v_x0 >= v_x1) ||
64285 (v_x0 > self->private_impl.f_width) ||
64286 (v_x1 > self->private_impl.f_width) ||
64287 (v_y0 >= v_y1) ||
64288 (v_y0 > self->private_impl.f_height) ||
64289 (v_y1 > self->private_impl.f_height)) {
64290 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
64291 goto exit;
64293 self->private_impl.f_frame_rect_x0 = v_x0;
64294 self->private_impl.f_frame_rect_y0 = v_y0;
64295 self->private_impl.f_frame_rect_x1 = v_x1;
64296 self->private_impl.f_frame_rect_y1 = v_y1;
64298 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
64299 uint32_t t_5;
64300 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
64301 t_5 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
64302 iop_a_src += 2;
64303 } else {
64304 self->private_data.s_decode_fctl.scratch = 0;
64305 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
64306 while (true) {
64307 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
64308 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
64309 goto suspend;
64311 uint64_t* scratch = &self->private_data.s_decode_fctl.scratch;
64312 uint32_t num_bits_5 = ((uint32_t)(*scratch & 0xFFu));
64313 *scratch >>= 8;
64314 *scratch <<= 8;
64315 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_5);
64316 if (num_bits_5 == 8) {
64317 t_5 = ((uint32_t)(*scratch >> 48));
64318 break;
64320 num_bits_5 += 8u;
64321 *scratch |= ((uint64_t)(num_bits_5));
64324 v_x0 = t_5;
64327 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
64328 uint32_t t_6;
64329 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
64330 t_6 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
64331 iop_a_src += 2;
64332 } else {
64333 self->private_data.s_decode_fctl.scratch = 0;
64334 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
64335 while (true) {
64336 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
64337 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
64338 goto suspend;
64340 uint64_t* scratch = &self->private_data.s_decode_fctl.scratch;
64341 uint32_t num_bits_6 = ((uint32_t)(*scratch & 0xFFu));
64342 *scratch >>= 8;
64343 *scratch <<= 8;
64344 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_6);
64345 if (num_bits_6 == 8) {
64346 t_6 = ((uint32_t)(*scratch >> 48));
64347 break;
64349 num_bits_6 += 8u;
64350 *scratch |= ((uint64_t)(num_bits_6));
64353 v_x1 = t_6;
64355 if (v_x1 <= 0u) {
64356 self->private_impl.f_frame_duration = (((uint64_t)(v_x0)) * 7056000u);
64357 } else {
64358 self->private_impl.f_frame_duration = ((((uint64_t)(v_x0)) * 705600000u) / ((uint64_t)(v_x1)));
64361 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
64362 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
64363 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
64364 goto suspend;
64366 uint32_t t_7 = *iop_a_src++;
64367 v_x0 = t_7;
64369 if (v_x0 == 0u) {
64370 self->private_impl.f_frame_disposal = 0u;
64371 } else if (v_x0 == 1u) {
64372 self->private_impl.f_frame_disposal = 1u;
64373 } else if (v_x0 == 2u) {
64374 self->private_impl.f_frame_disposal = 2u;
64375 } else {
64376 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
64377 goto exit;
64380 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
64381 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
64382 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
64383 goto suspend;
64385 uint32_t t_8 = *iop_a_src++;
64386 v_x0 = t_8;
64388 if (v_x0 == 0u) {
64389 self->private_impl.f_frame_overwrite_instead_of_blend = true;
64390 } else if (v_x0 == 1u) {
64391 self->private_impl.f_frame_overwrite_instead_of_blend = false;
64392 } else {
64393 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
64394 goto exit;
64396 if (self->private_impl.f_num_decoded_frame_configs_value == 0u) {
64397 self->private_impl.f_first_rect_x0 = self->private_impl.f_frame_rect_x0;
64398 self->private_impl.f_first_rect_y0 = self->private_impl.f_frame_rect_y0;
64399 self->private_impl.f_first_rect_x1 = self->private_impl.f_frame_rect_x1;
64400 self->private_impl.f_first_rect_y1 = self->private_impl.f_frame_rect_y1;
64401 self->private_impl.f_first_duration = self->private_impl.f_frame_duration;
64402 self->private_impl.f_first_disposal = self->private_impl.f_frame_disposal;
64403 self->private_impl.f_first_overwrite_instead_of_blend = self->private_impl.f_frame_overwrite_instead_of_blend;
64406 goto ok;
64408 self->private_impl.p_decode_fctl = 0;
64409 goto exit;
64412 goto suspend;
64413 suspend:
64414 self->private_impl.p_decode_fctl = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
64415 self->private_data.s_decode_fctl.v_x0 = v_x0;
64416 self->private_data.s_decode_fctl.v_x1 = v_x1;
64417 self->private_data.s_decode_fctl.v_y1 = v_y1;
64419 goto exit;
64420 exit:
64421 if (a_src && a_src->data.ptr) {
64422 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
64425 return status;
64428 // -------- func png.decoder.decode_gama
64430 WUFFS_BASE__GENERATED_C_CODE
64431 static wuffs_base__status
64432 wuffs_png__decoder__decode_gama(
64433 wuffs_png__decoder* self,
64434 wuffs_base__io_buffer* a_src) {
64435 wuffs_base__status status = wuffs_base__make_status(NULL);
64437 const uint8_t* iop_a_src = NULL;
64438 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
64439 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
64440 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
64441 if (a_src && a_src->data.ptr) {
64442 io0_a_src = a_src->data.ptr;
64443 io1_a_src = io0_a_src + a_src->meta.ri;
64444 iop_a_src = io1_a_src;
64445 io2_a_src = io0_a_src + a_src->meta.wi;
64448 uint32_t coro_susp_point = self->private_impl.p_decode_gama;
64449 switch (coro_susp_point) {
64450 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
64452 if (self->private_impl.f_chunk_length != 4u) {
64453 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
64454 goto exit;
64456 self->private_impl.f_chunk_length = 0u;
64457 self->private_impl.f_metadata_flavor = 5u;
64458 self->private_impl.f_metadata_fourcc = 1195461953u;
64460 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
64461 uint64_t t_0;
64462 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
64463 t_0 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
64464 iop_a_src += 4;
64465 } else {
64466 self->private_data.s_decode_gama.scratch = 0;
64467 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
64468 while (true) {
64469 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
64470 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
64471 goto suspend;
64473 uint64_t* scratch = &self->private_data.s_decode_gama.scratch;
64474 uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu));
64475 *scratch >>= 8;
64476 *scratch <<= 8;
64477 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
64478 if (num_bits_0 == 24) {
64479 t_0 = ((uint64_t)(*scratch >> 32));
64480 break;
64482 num_bits_0 += 8u;
64483 *scratch |= ((uint64_t)(num_bits_0));
64486 self->private_impl.f_metadata_x = t_0;
64488 self->private_impl.f_metadata_y = 0u;
64489 self->private_impl.f_metadata_z = 0u;
64491 goto ok;
64493 self->private_impl.p_decode_gama = 0;
64494 goto exit;
64497 goto suspend;
64498 suspend:
64499 self->private_impl.p_decode_gama = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
64501 goto exit;
64502 exit:
64503 if (a_src && a_src->data.ptr) {
64504 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
64507 return status;
64510 // -------- func png.decoder.decode_iccp
64512 WUFFS_BASE__GENERATED_C_CODE
64513 static wuffs_base__status
64514 wuffs_png__decoder__decode_iccp(
64515 wuffs_png__decoder* self,
64516 wuffs_base__io_buffer* a_src) {
64517 wuffs_base__status status = wuffs_base__make_status(NULL);
64519 uint8_t v_c8 = 0;
64521 const uint8_t* iop_a_src = NULL;
64522 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
64523 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
64524 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
64525 if (a_src && a_src->data.ptr) {
64526 io0_a_src = a_src->data.ptr;
64527 io1_a_src = io0_a_src + a_src->meta.ri;
64528 iop_a_src = io1_a_src;
64529 io2_a_src = io0_a_src + a_src->meta.wi;
64532 uint32_t coro_susp_point = self->private_impl.p_decode_iccp;
64533 switch (coro_susp_point) {
64534 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
64536 while (true) {
64537 if (self->private_impl.f_chunk_length <= 0u) {
64538 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
64539 goto exit;
64541 self->private_impl.f_chunk_length -= 1u;
64543 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
64544 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
64545 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
64546 goto suspend;
64548 uint8_t t_0 = *iop_a_src++;
64549 v_c8 = t_0;
64551 if (v_c8 == 0u) {
64552 break;
64555 if (self->private_impl.f_chunk_length <= 0u) {
64556 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
64557 goto exit;
64559 self->private_impl.f_chunk_length -= 1u;
64561 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
64562 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
64563 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
64564 goto suspend;
64566 uint8_t t_1 = *iop_a_src++;
64567 v_c8 = t_1;
64569 if (v_c8 != 0u) {
64570 status = wuffs_base__make_status(wuffs_png__error__unsupported_png_compression_method);
64571 goto exit;
64573 self->private_impl.f_metadata_is_zlib_compressed = true;
64574 self->private_impl.f_metadata_flavor = 4u;
64575 self->private_impl.f_metadata_fourcc = 1229144912u;
64576 self->private_impl.f_metadata_x = 0u;
64577 self->private_impl.f_metadata_y = 0u;
64578 self->private_impl.f_metadata_z = 0u;
64580 goto ok;
64582 self->private_impl.p_decode_iccp = 0;
64583 goto exit;
64586 goto suspend;
64587 suspend:
64588 self->private_impl.p_decode_iccp = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
64590 goto exit;
64591 exit:
64592 if (a_src && a_src->data.ptr) {
64593 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
64596 return status;
64599 // -------- func png.decoder.decode_plte
64601 WUFFS_BASE__GENERATED_C_CODE
64602 static wuffs_base__status
64603 wuffs_png__decoder__decode_plte(
64604 wuffs_png__decoder* self,
64605 wuffs_base__io_buffer* a_src) {
64606 wuffs_base__status status = wuffs_base__make_status(NULL);
64608 uint32_t v_num_entries = 0;
64609 uint32_t v_i = 0;
64610 uint32_t v_argb = 0;
64612 const uint8_t* iop_a_src = NULL;
64613 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
64614 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
64615 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
64616 if (a_src && a_src->data.ptr) {
64617 io0_a_src = a_src->data.ptr;
64618 io1_a_src = io0_a_src + a_src->meta.ri;
64619 iop_a_src = io1_a_src;
64620 io2_a_src = io0_a_src + a_src->meta.wi;
64623 uint32_t coro_susp_point = self->private_impl.p_decode_plte;
64624 if (coro_susp_point) {
64625 v_num_entries = self->private_data.s_decode_plte.v_num_entries;
64626 v_i = self->private_data.s_decode_plte.v_i;
64628 switch (coro_susp_point) {
64629 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
64631 if ((self->private_impl.f_chunk_length > 768u) || ((self->private_impl.f_chunk_length % 3u) != 0u)) {
64632 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
64633 goto exit;
64635 v_num_entries = (((uint32_t)(self->private_impl.f_chunk_length)) / 3u);
64636 self->private_impl.f_chunk_length = 0u;
64637 while (v_i < v_num_entries) {
64639 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
64640 uint32_t t_0;
64641 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) {
64642 t_0 = ((uint32_t)(wuffs_base__peek_u24be__no_bounds_check(iop_a_src)));
64643 iop_a_src += 3;
64644 } else {
64645 self->private_data.s_decode_plte.scratch = 0;
64646 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
64647 while (true) {
64648 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
64649 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
64650 goto suspend;
64652 uint64_t* scratch = &self->private_data.s_decode_plte.scratch;
64653 uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu));
64654 *scratch >>= 8;
64655 *scratch <<= 8;
64656 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
64657 if (num_bits_0 == 16) {
64658 t_0 = ((uint32_t)(*scratch >> 40));
64659 break;
64661 num_bits_0 += 8u;
64662 *scratch |= ((uint64_t)(num_bits_0));
64665 v_argb = t_0;
64667 v_argb |= 4278190080u;
64668 self->private_data.f_src_palette[((4u * v_i) + 0u)] = ((uint8_t)((v_argb >> 0u)));
64669 self->private_data.f_src_palette[((4u * v_i) + 1u)] = ((uint8_t)((v_argb >> 8u)));
64670 self->private_data.f_src_palette[((4u * v_i) + 2u)] = ((uint8_t)((v_argb >> 16u)));
64671 self->private_data.f_src_palette[((4u * v_i) + 3u)] = ((uint8_t)((v_argb >> 24u)));
64672 v_i += 1u;
64674 while (v_i < 256u) {
64675 self->private_data.f_src_palette[((4u * v_i) + 0u)] = 0u;
64676 self->private_data.f_src_palette[((4u * v_i) + 1u)] = 0u;
64677 self->private_data.f_src_palette[((4u * v_i) + 2u)] = 0u;
64678 self->private_data.f_src_palette[((4u * v_i) + 3u)] = 255u;
64679 v_i += 1u;
64682 goto ok;
64684 self->private_impl.p_decode_plte = 0;
64685 goto exit;
64688 goto suspend;
64689 suspend:
64690 self->private_impl.p_decode_plte = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
64691 self->private_data.s_decode_plte.v_num_entries = v_num_entries;
64692 self->private_data.s_decode_plte.v_i = v_i;
64694 goto exit;
64695 exit:
64696 if (a_src && a_src->data.ptr) {
64697 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
64700 return status;
64703 // -------- func png.decoder.decode_srgb
64705 WUFFS_BASE__GENERATED_C_CODE
64706 static wuffs_base__status
64707 wuffs_png__decoder__decode_srgb(
64708 wuffs_png__decoder* self,
64709 wuffs_base__io_buffer* a_src) {
64710 wuffs_base__status status = wuffs_base__make_status(NULL);
64712 const uint8_t* iop_a_src = NULL;
64713 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
64714 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
64715 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
64716 if (a_src && a_src->data.ptr) {
64717 io0_a_src = a_src->data.ptr;
64718 io1_a_src = io0_a_src + a_src->meta.ri;
64719 iop_a_src = io1_a_src;
64720 io2_a_src = io0_a_src + a_src->meta.wi;
64723 uint32_t coro_susp_point = self->private_impl.p_decode_srgb;
64724 switch (coro_susp_point) {
64725 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
64727 if (self->private_impl.f_chunk_length != 1u) {
64728 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
64729 goto exit;
64731 self->private_impl.f_chunk_length = 0u;
64732 self->private_impl.f_metadata_flavor = 5u;
64733 self->private_impl.f_metadata_fourcc = 1397901122u;
64735 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
64736 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
64737 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
64738 goto suspend;
64740 uint64_t t_0 = *iop_a_src++;
64741 self->private_impl.f_metadata_x = t_0;
64743 self->private_impl.f_metadata_y = 0u;
64744 self->private_impl.f_metadata_z = 0u;
64746 goto ok;
64748 self->private_impl.p_decode_srgb = 0;
64749 goto exit;
64752 goto suspend;
64753 suspend:
64754 self->private_impl.p_decode_srgb = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
64756 goto exit;
64757 exit:
64758 if (a_src && a_src->data.ptr) {
64759 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
64762 return status;
64765 // -------- func png.decoder.decode_trns
64767 WUFFS_BASE__GENERATED_C_CODE
64768 static wuffs_base__status
64769 wuffs_png__decoder__decode_trns(
64770 wuffs_png__decoder* self,
64771 wuffs_base__io_buffer* a_src) {
64772 wuffs_base__status status = wuffs_base__make_status(NULL);
64774 uint32_t v_i = 0;
64775 uint32_t v_n = 0;
64776 uint64_t v_u = 0;
64778 const uint8_t* iop_a_src = NULL;
64779 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
64780 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
64781 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
64782 if (a_src && a_src->data.ptr) {
64783 io0_a_src = a_src->data.ptr;
64784 io1_a_src = io0_a_src + a_src->meta.ri;
64785 iop_a_src = io1_a_src;
64786 io2_a_src = io0_a_src + a_src->meta.wi;
64789 uint32_t coro_susp_point = self->private_impl.p_decode_trns;
64790 if (coro_susp_point) {
64791 v_i = self->private_data.s_decode_trns.v_i;
64792 v_n = self->private_data.s_decode_trns.v_n;
64794 switch (coro_susp_point) {
64795 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
64797 if (self->private_impl.f_color_type == 0u) {
64798 self->private_impl.choosy_filter_and_swizzle = (
64799 &wuffs_png__decoder__filter_and_swizzle_tricky);
64800 if (self->private_impl.f_depth <= 8u) {
64801 self->private_impl.f_dst_pixfmt = 2164295816u;
64802 self->private_impl.f_src_pixfmt = 2164295816u;
64803 } else {
64804 self->private_impl.f_dst_pixfmt = 2164308923u;
64805 self->private_impl.f_src_pixfmt = 2164308923u;
64807 if (self->private_impl.f_chunk_length != 2u) {
64808 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
64809 goto exit;
64811 self->private_impl.f_chunk_length = 0u;
64813 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
64814 uint64_t t_0;
64815 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
64816 t_0 = ((uint64_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
64817 iop_a_src += 2;
64818 } else {
64819 self->private_data.s_decode_trns.scratch = 0;
64820 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
64821 while (true) {
64822 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
64823 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
64824 goto suspend;
64826 uint64_t* scratch = &self->private_data.s_decode_trns.scratch;
64827 uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu));
64828 *scratch >>= 8;
64829 *scratch <<= 8;
64830 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
64831 if (num_bits_0 == 8) {
64832 t_0 = ((uint64_t)(*scratch >> 48));
64833 break;
64835 num_bits_0 += 8u;
64836 *scratch |= ((uint64_t)(num_bits_0));
64839 v_u = t_0;
64841 if (self->private_impl.f_depth <= 1u) {
64842 self->private_impl.f_remap_transparency = (((v_u & 1u) * 16777215u) | 4278190080u);
64843 } else if (self->private_impl.f_depth <= 2u) {
64844 self->private_impl.f_remap_transparency = (((v_u & 3u) * 5592405u) | 4278190080u);
64845 } else if (self->private_impl.f_depth <= 4u) {
64846 self->private_impl.f_remap_transparency = (((v_u & 15u) * 1118481u) | 4278190080u);
64847 } else if (self->private_impl.f_depth <= 8u) {
64848 self->private_impl.f_remap_transparency = (((v_u & 255u) * 65793u) | 4278190080u);
64849 } else {
64850 self->private_impl.f_remap_transparency = ((v_u * 4295032833u) | 18446462598732840960u);
64852 } else if (self->private_impl.f_color_type == 2u) {
64853 self->private_impl.choosy_filter_and_swizzle = (
64854 &wuffs_png__decoder__filter_and_swizzle_tricky);
64855 if (self->private_impl.f_depth <= 8u) {
64856 self->private_impl.f_dst_pixfmt = 2164295816u;
64857 self->private_impl.f_src_pixfmt = 2164295816u;
64858 } else {
64859 self->private_impl.f_dst_pixfmt = 2164308923u;
64860 self->private_impl.f_src_pixfmt = 2164308923u;
64862 if (self->private_impl.f_chunk_length != 6u) {
64863 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
64864 goto exit;
64866 self->private_impl.f_chunk_length = 0u;
64868 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
64869 uint64_t t_1;
64870 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 6)) {
64871 t_1 = ((uint64_t)(wuffs_base__peek_u48be__no_bounds_check(iop_a_src)));
64872 iop_a_src += 6;
64873 } else {
64874 self->private_data.s_decode_trns.scratch = 0;
64875 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
64876 while (true) {
64877 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
64878 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
64879 goto suspend;
64881 uint64_t* scratch = &self->private_data.s_decode_trns.scratch;
64882 uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu));
64883 *scratch >>= 8;
64884 *scratch <<= 8;
64885 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
64886 if (num_bits_1 == 40) {
64887 t_1 = ((uint64_t)(*scratch >> 16));
64888 break;
64890 num_bits_1 += 8u;
64891 *scratch |= ((uint64_t)(num_bits_1));
64894 v_u = t_1;
64896 if (self->private_impl.f_depth <= 8u) {
64897 self->private_impl.f_remap_transparency = ((255u & (v_u >> 0u)) |
64898 (65280u & (v_u >> 8u)) |
64899 (16711680u & (v_u >> 16u)) |
64900 4278190080u);
64901 } else {
64902 self->private_impl.f_remap_transparency = (v_u | 18446462598732840960u);
64904 } else if (self->private_impl.f_color_type == 3u) {
64905 self->private_impl.f_dst_pixfmt = 2164523016u;
64906 self->private_impl.f_src_pixfmt = 2164523016u;
64907 if (self->private_impl.f_chunk_length > 256u) {
64908 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
64909 goto exit;
64911 v_n = ((uint32_t)(self->private_impl.f_chunk_length));
64912 self->private_impl.f_chunk_length = 0u;
64913 while (v_i < v_n) {
64915 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
64916 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
64917 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
64918 goto suspend;
64920 uint8_t t_2 = *iop_a_src++;
64921 self->private_data.f_src_palette[((4u * v_i) + 3u)] = t_2;
64923 v_i += 1u;
64925 } else {
64926 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
64927 goto exit;
64930 goto ok;
64932 self->private_impl.p_decode_trns = 0;
64933 goto exit;
64936 goto suspend;
64937 suspend:
64938 self->private_impl.p_decode_trns = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
64939 self->private_data.s_decode_trns.v_i = v_i;
64940 self->private_data.s_decode_trns.v_n = v_n;
64942 goto exit;
64943 exit:
64944 if (a_src && a_src->data.ptr) {
64945 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
64948 return status;
64951 // -------- func png.decoder.decode_frame_config
64953 WUFFS_BASE__GENERATED_C_CODE
64954 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
64955 wuffs_png__decoder__decode_frame_config(
64956 wuffs_png__decoder* self,
64957 wuffs_base__frame_config* a_dst,
64958 wuffs_base__io_buffer* a_src) {
64959 if (!self) {
64960 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
64962 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
64963 return wuffs_base__make_status(
64964 (self->private_impl.magic == WUFFS_BASE__DISABLED)
64965 ? wuffs_base__error__disabled_by_previous_error
64966 : wuffs_base__error__initialize_not_called);
64968 if (!a_src) {
64969 self->private_impl.magic = WUFFS_BASE__DISABLED;
64970 return wuffs_base__make_status(wuffs_base__error__bad_argument);
64972 if ((self->private_impl.active_coroutine != 0) &&
64973 (self->private_impl.active_coroutine != 2)) {
64974 self->private_impl.magic = WUFFS_BASE__DISABLED;
64975 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
64977 self->private_impl.active_coroutine = 0;
64978 wuffs_base__status status = wuffs_base__make_status(NULL);
64980 wuffs_base__status v_status = wuffs_base__make_status(NULL);
64982 uint32_t coro_susp_point = self->private_impl.p_decode_frame_config;
64983 switch (coro_susp_point) {
64984 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
64986 while (true) {
64988 wuffs_base__status t_0 = wuffs_png__decoder__do_decode_frame_config(self, a_dst, a_src);
64989 v_status = t_0;
64991 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
64992 status = wuffs_base__make_status(wuffs_png__error__truncated_input);
64993 goto exit;
64995 status = v_status;
64996 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
65000 self->private_impl.p_decode_frame_config = 0;
65001 goto exit;
65004 goto suspend;
65005 suspend:
65006 self->private_impl.p_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
65007 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
65009 goto exit;
65010 exit:
65011 if (wuffs_base__status__is_error(&status)) {
65012 self->private_impl.magic = WUFFS_BASE__DISABLED;
65014 return status;
65017 // -------- func png.decoder.do_decode_frame_config
65019 WUFFS_BASE__GENERATED_C_CODE
65020 static wuffs_base__status
65021 wuffs_png__decoder__do_decode_frame_config(
65022 wuffs_png__decoder* self,
65023 wuffs_base__frame_config* a_dst,
65024 wuffs_base__io_buffer* a_src) {
65025 wuffs_base__status status = wuffs_base__make_status(NULL);
65027 uint32_t v_checksum_have = 0;
65029 const uint8_t* iop_a_src = NULL;
65030 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
65031 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
65032 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
65033 if (a_src && a_src->data.ptr) {
65034 io0_a_src = a_src->data.ptr;
65035 io1_a_src = io0_a_src + a_src->meta.ri;
65036 iop_a_src = io1_a_src;
65037 io2_a_src = io0_a_src + a_src->meta.wi;
65040 uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config;
65041 switch (coro_susp_point) {
65042 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
65044 if (((uint8_t)(self->private_impl.f_call_sequence & 16u)) != 0u) {
65045 status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
65046 goto exit;
65047 } else if (self->private_impl.f_call_sequence == 32u) {
65048 } else if (self->private_impl.f_call_sequence < 32u) {
65049 if (a_src) {
65050 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
65052 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
65053 status = wuffs_png__decoder__do_decode_image_config(self, NULL, a_src);
65054 if (a_src) {
65055 iop_a_src = a_src->data.ptr + a_src->meta.ri;
65057 if (status.repr) {
65058 goto suspend;
65060 } else if (self->private_impl.f_call_sequence == 40u) {
65061 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)))) {
65062 status = wuffs_base__make_status(wuffs_base__error__bad_restart);
65063 goto exit;
65065 } else if (self->private_impl.f_call_sequence == 64u) {
65066 if (a_src) {
65067 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
65069 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
65070 status = wuffs_png__decoder__skip_frame(self, a_src);
65071 if (a_src) {
65072 iop_a_src = a_src->data.ptr + a_src->meta.ri;
65074 if (status.repr) {
65075 goto suspend;
65077 } else {
65078 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
65079 goto ok;
65081 if (self->private_impl.f_metadata_fourcc != 0u) {
65082 self->private_impl.f_call_sequence = 48u;
65083 status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
65084 goto ok;
65086 if (self->private_impl.f_num_decoded_frame_configs_value == 0u) {
65087 self->private_impl.f_frame_rect_x0 = self->private_impl.f_first_rect_x0;
65088 self->private_impl.f_frame_rect_y0 = self->private_impl.f_first_rect_y0;
65089 self->private_impl.f_frame_rect_x1 = self->private_impl.f_first_rect_x1;
65090 self->private_impl.f_frame_rect_y1 = self->private_impl.f_first_rect_y1;
65091 self->private_impl.f_frame_config_io_position = self->private_impl.f_first_config_io_position;
65092 self->private_impl.f_frame_duration = self->private_impl.f_first_duration;
65093 self->private_impl.f_frame_disposal = self->private_impl.f_first_disposal;
65094 self->private_impl.f_frame_overwrite_instead_of_blend = self->private_impl.f_first_overwrite_instead_of_blend;
65095 } else {
65096 while (true) {
65098 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
65099 uint32_t t_0;
65100 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
65101 t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
65102 iop_a_src += 4;
65103 } else {
65104 self->private_data.s_do_decode_frame_config.scratch = 0;
65105 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
65106 while (true) {
65107 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
65108 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
65109 goto suspend;
65111 uint64_t* scratch = &self->private_data.s_do_decode_frame_config.scratch;
65112 uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu));
65113 *scratch >>= 8;
65114 *scratch <<= 8;
65115 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
65116 if (num_bits_0 == 24) {
65117 t_0 = ((uint32_t)(*scratch >> 32));
65118 break;
65120 num_bits_0 += 8u;
65121 *scratch |= ((uint64_t)(num_bits_0));
65124 self->private_impl.f_chunk_length = t_0;
65127 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
65128 uint32_t t_1;
65129 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
65130 t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
65131 iop_a_src += 4;
65132 } else {
65133 self->private_data.s_do_decode_frame_config.scratch = 0;
65134 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
65135 while (true) {
65136 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
65137 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
65138 goto suspend;
65140 uint64_t* scratch = &self->private_data.s_do_decode_frame_config.scratch;
65141 uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
65142 *scratch <<= 8;
65143 *scratch >>= 8;
65144 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
65145 if (num_bits_1 == 24) {
65146 t_1 = ((uint32_t)(*scratch));
65147 break;
65149 num_bits_1 += 8u;
65150 *scratch |= ((uint64_t)(num_bits_1)) << 56;
65153 self->private_impl.f_chunk_type = t_1;
65155 if (self->private_impl.f_chunk_type == 1145980233u) {
65156 if (self->private_impl.f_chunk_length != 0u) {
65157 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
65158 goto exit;
65161 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
65162 uint32_t t_2;
65163 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
65164 t_2 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
65165 iop_a_src += 4;
65166 } else {
65167 self->private_data.s_do_decode_frame_config.scratch = 0;
65168 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
65169 while (true) {
65170 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
65171 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
65172 goto suspend;
65174 uint64_t* scratch = &self->private_data.s_do_decode_frame_config.scratch;
65175 uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
65176 *scratch <<= 8;
65177 *scratch >>= 8;
65178 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
65179 if (num_bits_2 == 24) {
65180 t_2 = ((uint32_t)(*scratch));
65181 break;
65183 num_bits_2 += 8u;
65184 *scratch |= ((uint64_t)(num_bits_2)) << 56;
65187 v_checksum_have = t_2;
65189 if ( ! self->private_impl.f_ignore_checksum && (v_checksum_have != 2187346606u)) {
65190 status = wuffs_base__make_status(wuffs_png__error__bad_checksum);
65191 goto exit;
65193 self->private_impl.f_call_sequence = 96u;
65194 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
65195 goto ok;
65196 } else if (self->private_impl.f_chunk_type == 1413571686u) {
65197 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
65198 goto exit;
65199 } else if (self->private_impl.f_chunk_type == 1280598886u) {
65200 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));
65201 if (a_src) {
65202 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
65204 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
65205 status = wuffs_png__decoder__decode_fctl(self, a_src);
65206 if (a_src) {
65207 iop_a_src = a_src->data.ptr + a_src->meta.ri;
65209 if (status.repr) {
65210 goto suspend;
65212 self->private_data.s_do_decode_frame_config.scratch = 4u;
65213 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
65214 if (self->private_data.s_do_decode_frame_config.scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
65215 self->private_data.s_do_decode_frame_config.scratch -= ((uint64_t)(io2_a_src - iop_a_src));
65216 iop_a_src = io2_a_src;
65217 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
65218 goto suspend;
65220 iop_a_src += self->private_data.s_do_decode_frame_config.scratch;
65221 break;
65223 if (a_src) {
65224 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
65226 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
65227 status = wuffs_png__decoder__decode_other_chunk(self, a_src, true);
65228 if (a_src) {
65229 iop_a_src = a_src->data.ptr + a_src->meta.ri;
65231 if (status.repr) {
65232 goto suspend;
65234 if (self->private_impl.f_metadata_fourcc != 0u) {
65235 self->private_impl.f_call_sequence = 48u;
65236 status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
65237 goto ok;
65239 self->private_data.s_do_decode_frame_config.scratch = 4u;
65240 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
65241 if (self->private_data.s_do_decode_frame_config.scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
65242 self->private_data.s_do_decode_frame_config.scratch -= ((uint64_t)(io2_a_src - iop_a_src));
65243 iop_a_src = io2_a_src;
65244 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
65245 goto suspend;
65247 iop_a_src += self->private_data.s_do_decode_frame_config.scratch;
65248 self->private_impl.f_chunk_length = 0u;
65251 if (a_dst != NULL) {
65252 wuffs_base__frame_config__set(
65253 a_dst,
65254 wuffs_base__utility__make_rect_ie_u32(
65255 self->private_impl.f_frame_rect_x0,
65256 self->private_impl.f_frame_rect_y0,
65257 self->private_impl.f_frame_rect_x1,
65258 self->private_impl.f_frame_rect_y1),
65259 ((wuffs_base__flicks)(self->private_impl.f_frame_duration)),
65260 ((uint64_t)(self->private_impl.f_num_decoded_frame_configs_value)),
65261 self->private_impl.f_frame_config_io_position,
65262 self->private_impl.f_frame_disposal,
65263 ((self->private_impl.f_color_type <= 3u) && ! self->private_impl.f_seen_trns),
65264 self->private_impl.f_frame_overwrite_instead_of_blend,
65265 0u);
65267 wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_num_decoded_frame_configs_value, 1u);
65268 self->private_impl.f_call_sequence = 64u;
65271 self->private_impl.p_do_decode_frame_config = 0;
65272 goto exit;
65275 goto suspend;
65276 suspend:
65277 self->private_impl.p_do_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
65279 goto exit;
65280 exit:
65281 if (a_src && a_src->data.ptr) {
65282 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
65285 return status;
65288 // -------- func png.decoder.skip_frame
65290 WUFFS_BASE__GENERATED_C_CODE
65291 static wuffs_base__status
65292 wuffs_png__decoder__skip_frame(
65293 wuffs_png__decoder* self,
65294 wuffs_base__io_buffer* a_src) {
65295 wuffs_base__status status = wuffs_base__make_status(NULL);
65297 uint32_t v_seq_num = 0;
65299 const uint8_t* iop_a_src = NULL;
65300 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
65301 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
65302 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
65303 if (a_src && a_src->data.ptr) {
65304 io0_a_src = a_src->data.ptr;
65305 io1_a_src = io0_a_src + a_src->meta.ri;
65306 iop_a_src = io1_a_src;
65307 io2_a_src = io0_a_src + a_src->meta.wi;
65310 uint32_t coro_susp_point = self->private_impl.p_skip_frame;
65311 switch (coro_susp_point) {
65312 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
65314 self->private_impl.f_chunk_type_array[0u] = 0u;
65315 self->private_impl.f_chunk_type_array[1u] = 0u;
65316 self->private_impl.f_chunk_type_array[2u] = 0u;
65317 self->private_impl.f_chunk_type_array[3u] = 0u;
65318 while (true) {
65319 if (((uint64_t)(io2_a_src - iop_a_src)) < 8u) {
65320 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
65321 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
65322 continue;
65324 self->private_impl.f_chunk_length = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
65325 self->private_impl.f_chunk_type = ((uint32_t)((wuffs_base__peek_u64le__no_bounds_check(iop_a_src) >> 32u)));
65326 if (self->private_impl.f_chunk_type == 1413563465u) {
65327 if (self->private_impl.f_chunk_type_array[0u] == 102u) {
65328 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
65329 goto exit;
65331 self->private_impl.f_chunk_type_array[0u] = 73u;
65332 self->private_impl.f_chunk_type_array[1u] = 68u;
65333 self->private_impl.f_chunk_type_array[2u] = 65u;
65334 self->private_impl.f_chunk_type_array[3u] = 84u;
65335 } else if (self->private_impl.f_chunk_type == 1413571686u) {
65336 if (self->private_impl.f_chunk_type_array[0u] == 73u) {
65337 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
65338 goto exit;
65340 self->private_impl.f_chunk_type_array[0u] = 102u;
65341 self->private_impl.f_chunk_type_array[1u] = 100u;
65342 self->private_impl.f_chunk_type_array[2u] = 65u;
65343 self->private_impl.f_chunk_type_array[3u] = 84u;
65344 if (self->private_impl.f_chunk_length < 4u) {
65345 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
65346 goto exit;
65348 self->private_impl.f_chunk_length -= 4u;
65349 iop_a_src += 8u;
65351 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
65352 uint32_t t_0;
65353 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
65354 t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
65355 iop_a_src += 4;
65356 } else {
65357 self->private_data.s_skip_frame.scratch = 0;
65358 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
65359 while (true) {
65360 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
65361 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
65362 goto suspend;
65364 uint64_t* scratch = &self->private_data.s_skip_frame.scratch;
65365 uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu));
65366 *scratch >>= 8;
65367 *scratch <<= 8;
65368 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
65369 if (num_bits_0 == 24) {
65370 t_0 = ((uint32_t)(*scratch >> 32));
65371 break;
65373 num_bits_0 += 8u;
65374 *scratch |= ((uint64_t)(num_bits_0));
65377 v_seq_num = t_0;
65379 if (v_seq_num != self->private_impl.f_next_animation_seq_num) {
65380 status = wuffs_base__make_status(wuffs_png__error__bad_animation_sequence_number);
65381 goto exit;
65382 } else if (self->private_impl.f_next_animation_seq_num >= 4294967295u) {
65383 status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file);
65384 goto exit;
65386 self->private_impl.f_next_animation_seq_num += 1u;
65387 self->private_data.s_skip_frame.scratch = (((uint64_t)(self->private_impl.f_chunk_length)) + 4u);
65388 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
65389 if (self->private_data.s_skip_frame.scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
65390 self->private_data.s_skip_frame.scratch -= ((uint64_t)(io2_a_src - iop_a_src));
65391 iop_a_src = io2_a_src;
65392 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
65393 goto suspend;
65395 iop_a_src += self->private_data.s_skip_frame.scratch;
65396 self->private_impl.f_chunk_length = 0u;
65397 continue;
65398 } else if (self->private_impl.f_chunk_type_array[0u] != 0u) {
65399 break;
65400 } else if (self->private_impl.f_chunk_type == 1280598886u) {
65401 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
65402 goto exit;
65404 self->private_data.s_skip_frame.scratch = (((uint64_t)(self->private_impl.f_chunk_length)) + 12u);
65405 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
65406 if (self->private_data.s_skip_frame.scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
65407 self->private_data.s_skip_frame.scratch -= ((uint64_t)(io2_a_src - iop_a_src));
65408 iop_a_src = io2_a_src;
65409 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
65410 goto suspend;
65412 iop_a_src += self->private_data.s_skip_frame.scratch;
65413 self->private_impl.f_chunk_length = 0u;
65415 wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1u);
65416 self->private_impl.f_call_sequence = 32u;
65419 self->private_impl.p_skip_frame = 0;
65420 goto exit;
65423 goto suspend;
65424 suspend:
65425 self->private_impl.p_skip_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
65427 goto exit;
65428 exit:
65429 if (a_src && a_src->data.ptr) {
65430 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
65433 return status;
65436 // -------- func png.decoder.decode_frame
65438 WUFFS_BASE__GENERATED_C_CODE
65439 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
65440 wuffs_png__decoder__decode_frame(
65441 wuffs_png__decoder* self,
65442 wuffs_base__pixel_buffer* a_dst,
65443 wuffs_base__io_buffer* a_src,
65444 wuffs_base__pixel_blend a_blend,
65445 wuffs_base__slice_u8 a_workbuf,
65446 wuffs_base__decode_frame_options* a_opts) {
65447 if (!self) {
65448 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
65450 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
65451 return wuffs_base__make_status(
65452 (self->private_impl.magic == WUFFS_BASE__DISABLED)
65453 ? wuffs_base__error__disabled_by_previous_error
65454 : wuffs_base__error__initialize_not_called);
65456 if (!a_dst || !a_src) {
65457 self->private_impl.magic = WUFFS_BASE__DISABLED;
65458 return wuffs_base__make_status(wuffs_base__error__bad_argument);
65460 if ((self->private_impl.active_coroutine != 0) &&
65461 (self->private_impl.active_coroutine != 3)) {
65462 self->private_impl.magic = WUFFS_BASE__DISABLED;
65463 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
65465 self->private_impl.active_coroutine = 0;
65466 wuffs_base__status status = wuffs_base__make_status(NULL);
65468 wuffs_base__status v_status = wuffs_base__make_status(NULL);
65470 uint32_t coro_susp_point = self->private_impl.p_decode_frame;
65471 switch (coro_susp_point) {
65472 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
65474 while (true) {
65476 wuffs_base__status t_0 = wuffs_png__decoder__do_decode_frame(self,
65477 a_dst,
65478 a_src,
65479 a_blend,
65480 a_workbuf,
65481 a_opts);
65482 v_status = t_0;
65484 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
65485 status = wuffs_base__make_status(wuffs_png__error__truncated_input);
65486 goto exit;
65488 status = v_status;
65489 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
65493 self->private_impl.p_decode_frame = 0;
65494 goto exit;
65497 goto suspend;
65498 suspend:
65499 self->private_impl.p_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
65500 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
65502 goto exit;
65503 exit:
65504 if (wuffs_base__status__is_error(&status)) {
65505 self->private_impl.magic = WUFFS_BASE__DISABLED;
65507 return status;
65510 // -------- func png.decoder.do_decode_frame
65512 WUFFS_BASE__GENERATED_C_CODE
65513 static wuffs_base__status
65514 wuffs_png__decoder__do_decode_frame(
65515 wuffs_png__decoder* self,
65516 wuffs_base__pixel_buffer* a_dst,
65517 wuffs_base__io_buffer* a_src,
65518 wuffs_base__pixel_blend a_blend,
65519 wuffs_base__slice_u8 a_workbuf,
65520 wuffs_base__decode_frame_options* a_opts) {
65521 wuffs_base__status status = wuffs_base__make_status(NULL);
65523 uint32_t v_seq_num = 0;
65524 wuffs_base__status v_status = wuffs_base__make_status(NULL);
65525 uint32_t v_pass_width = 0;
65526 uint32_t v_pass_height = 0;
65528 const uint8_t* iop_a_src = NULL;
65529 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
65530 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
65531 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
65532 if (a_src && a_src->data.ptr) {
65533 io0_a_src = a_src->data.ptr;
65534 io1_a_src = io0_a_src + a_src->meta.ri;
65535 iop_a_src = io1_a_src;
65536 io2_a_src = io0_a_src + a_src->meta.wi;
65539 uint32_t coro_susp_point = self->private_impl.p_do_decode_frame;
65540 switch (coro_susp_point) {
65541 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
65543 if (((uint8_t)(self->private_impl.f_call_sequence & 16u)) != 0u) {
65544 status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
65545 goto exit;
65546 } else if (self->private_impl.f_call_sequence >= 96u) {
65547 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
65548 goto ok;
65549 } else if (self->private_impl.f_call_sequence != 64u) {
65550 if (a_src) {
65551 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
65553 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
65554 status = wuffs_png__decoder__do_decode_frame_config(self, NULL, a_src);
65555 if (a_src) {
65556 iop_a_src = a_src->data.ptr + a_src->meta.ri;
65558 if (status.repr) {
65559 goto suspend;
65562 while (true) {
65563 if (((uint64_t)(io2_a_src - iop_a_src)) < 8u) {
65564 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
65565 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
65566 continue;
65568 self->private_impl.f_chunk_length = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
65569 self->private_impl.f_chunk_type = ((uint32_t)((wuffs_base__peek_u64le__no_bounds_check(iop_a_src) >> 32u)));
65570 if (self->private_impl.f_chunk_type == 1413563465u) {
65571 self->private_impl.f_chunk_type_array[0u] = 73u;
65572 self->private_impl.f_chunk_type_array[1u] = 68u;
65573 self->private_impl.f_chunk_type_array[2u] = 65u;
65574 self->private_impl.f_chunk_type_array[3u] = 84u;
65575 iop_a_src += 8u;
65576 if ( ! self->private_impl.f_ignore_checksum) {
65577 wuffs_private_impl__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32,
65578 sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
65579 wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__make_slice_u8(self->private_impl.f_chunk_type_array, 4));
65581 break;
65582 } else if (self->private_impl.f_chunk_type == 1413571686u) {
65583 self->private_impl.f_chunk_type_array[0u] = 102u;
65584 self->private_impl.f_chunk_type_array[1u] = 100u;
65585 self->private_impl.f_chunk_type_array[2u] = 65u;
65586 self->private_impl.f_chunk_type_array[3u] = 84u;
65587 if (self->private_impl.f_chunk_length < 4u) {
65588 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
65589 goto exit;
65591 self->private_impl.f_chunk_length -= 4u;
65592 iop_a_src += 8u;
65594 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
65595 uint32_t t_0;
65596 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
65597 t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
65598 iop_a_src += 4;
65599 } else {
65600 self->private_data.s_do_decode_frame.scratch = 0;
65601 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
65602 while (true) {
65603 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
65604 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
65605 goto suspend;
65607 uint64_t* scratch = &self->private_data.s_do_decode_frame.scratch;
65608 uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu));
65609 *scratch >>= 8;
65610 *scratch <<= 8;
65611 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
65612 if (num_bits_0 == 24) {
65613 t_0 = ((uint32_t)(*scratch >> 32));
65614 break;
65616 num_bits_0 += 8u;
65617 *scratch |= ((uint64_t)(num_bits_0));
65620 v_seq_num = t_0;
65622 if (v_seq_num != self->private_impl.f_next_animation_seq_num) {
65623 status = wuffs_base__make_status(wuffs_png__error__bad_animation_sequence_number);
65624 goto exit;
65625 } else if (self->private_impl.f_next_animation_seq_num >= 4294967295u) {
65626 status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file);
65627 goto exit;
65629 self->private_impl.f_next_animation_seq_num += 1u;
65630 break;
65631 } else if (self->private_impl.f_chunk_type == 1280598886u) {
65632 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
65633 goto exit;
65635 self->private_data.s_do_decode_frame.scratch = (((uint64_t)(self->private_impl.f_chunk_length)) + 12u);
65636 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
65637 if (self->private_data.s_do_decode_frame.scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
65638 self->private_data.s_do_decode_frame.scratch -= ((uint64_t)(io2_a_src - iop_a_src));
65639 iop_a_src = io2_a_src;
65640 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
65641 goto suspend;
65643 iop_a_src += self->private_data.s_do_decode_frame.scratch;
65644 self->private_impl.f_chunk_length = 0u;
65646 if (self->private_impl.f_zlib_is_dirty) {
65647 wuffs_private_impl__ignore_status(wuffs_zlib__decoder__initialize(&self->private_data.f_zlib,
65648 sizeof (wuffs_zlib__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
65649 if (self->private_impl.f_ignore_checksum) {
65650 wuffs_zlib__decoder__set_quirk(&self->private_data.f_zlib, 1u, 1u);
65653 self->private_impl.f_zlib_is_dirty = true;
65654 v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
65655 wuffs_base__pixel_buffer__pixel_format(a_dst),
65656 wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)),
65657 wuffs_base__utility__make_pixel_format(self->private_impl.f_src_pixfmt),
65658 wuffs_base__make_slice_u8(self->private_data.f_src_palette, 1024),
65659 a_blend);
65660 if ( ! wuffs_base__status__is_ok(&v_status)) {
65661 status = v_status;
65662 if (wuffs_base__status__is_error(&status)) {
65663 goto exit;
65664 } else if (wuffs_base__status__is_suspension(&status)) {
65665 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
65666 goto exit;
65668 goto ok;
65670 self->private_impl.f_workbuf_hist_pos_base = 0u;
65671 while (true) {
65672 if (self->private_impl.f_chunk_type_array[0u] == 73u) {
65673 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]));
65674 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]));
65675 } else {
65676 v_pass_width = (16777215u & ((uint32_t)(self->private_impl.f_frame_rect_x1 - self->private_impl.f_frame_rect_x0)));
65677 v_pass_height = (16777215u & ((uint32_t)(self->private_impl.f_frame_rect_y1 - self->private_impl.f_frame_rect_y0)));
65679 if ((v_pass_width > 0u) && (v_pass_height > 0u)) {
65680 self->private_impl.f_pass_bytes_per_row = wuffs_png__decoder__calculate_bytes_per_row(self, v_pass_width);
65681 self->private_impl.f_pass_workbuf_length = (((uint64_t)(v_pass_height)) * (1u + self->private_impl.f_pass_bytes_per_row));
65682 while (true) {
65684 if (a_src) {
65685 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
65687 wuffs_base__status t_1 = wuffs_png__decoder__decode_pass(self, a_src, a_workbuf);
65688 v_status = t_1;
65689 if (a_src) {
65690 iop_a_src = a_src->data.ptr + a_src->meta.ri;
65693 if (wuffs_base__status__is_ok(&v_status)) {
65694 break;
65695 } else if (wuffs_base__status__is_error(&v_status) || ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed))) {
65696 if (self->private_impl.f_workbuf_wi <= ((uint64_t)(a_workbuf.len))) {
65697 wuffs_png__decoder__filter_and_swizzle(self, a_dst, wuffs_base__slice_u8__subslice_j(a_workbuf, self->private_impl.f_workbuf_wi));
65699 if (v_status.repr == wuffs_base__suspension__short_read) {
65700 status = wuffs_base__make_status(wuffs_png__error__truncated_input);
65701 goto exit;
65704 status = v_status;
65705 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
65707 v_status = wuffs_png__decoder__filter_and_swizzle(self, a_dst, a_workbuf);
65708 if ( ! wuffs_base__status__is_ok(&v_status)) {
65709 status = v_status;
65710 if (wuffs_base__status__is_error(&status)) {
65711 goto exit;
65712 } else if (wuffs_base__status__is_suspension(&status)) {
65713 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
65714 goto exit;
65716 goto ok;
65718 self->private_impl.f_workbuf_hist_pos_base += self->private_impl.f_pass_workbuf_length;
65720 if ((self->private_impl.f_interlace_pass == 0u) || (self->private_impl.f_interlace_pass >= 7u)) {
65721 break;
65723 #if defined(__GNUC__)
65724 #pragma GCC diagnostic push
65725 #pragma GCC diagnostic ignored "-Wconversion"
65726 #endif
65727 self->private_impl.f_interlace_pass += 1u;
65728 #if defined(__GNUC__)
65729 #pragma GCC diagnostic pop
65730 #endif
65732 wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1u);
65733 self->private_impl.f_call_sequence = 32u;
65736 self->private_impl.p_do_decode_frame = 0;
65737 goto exit;
65740 goto suspend;
65741 suspend:
65742 self->private_impl.p_do_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
65744 goto exit;
65745 exit:
65746 if (a_src && a_src->data.ptr) {
65747 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
65750 return status;
65753 // -------- func png.decoder.decode_pass
65755 WUFFS_BASE__GENERATED_C_CODE
65756 static wuffs_base__status
65757 wuffs_png__decoder__decode_pass(
65758 wuffs_png__decoder* self,
65759 wuffs_base__io_buffer* a_src,
65760 wuffs_base__slice_u8 a_workbuf) {
65761 wuffs_base__status status = wuffs_base__make_status(NULL);
65763 wuffs_base__io_buffer u_w = wuffs_base__empty_io_buffer();
65764 wuffs_base__io_buffer* v_w = &u_w;
65765 uint8_t* iop_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
65766 uint8_t* io0_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
65767 uint8_t* io1_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
65768 uint8_t* io2_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
65769 uint64_t v_w_mark = 0;
65770 uint64_t v_r_mark = 0;
65771 wuffs_base__status v_zlib_status = wuffs_base__make_status(NULL);
65772 uint32_t v_checksum_have = 0;
65773 uint32_t v_checksum_want = 0;
65774 uint32_t v_seq_num = 0;
65776 const uint8_t* iop_a_src = NULL;
65777 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
65778 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
65779 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
65780 if (a_src && a_src->data.ptr) {
65781 io0_a_src = a_src->data.ptr;
65782 io1_a_src = io0_a_src + a_src->meta.ri;
65783 iop_a_src = io1_a_src;
65784 io2_a_src = io0_a_src + a_src->meta.wi;
65787 uint32_t coro_susp_point = self->private_impl.p_decode_pass;
65788 switch (coro_susp_point) {
65789 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
65791 self->private_impl.f_workbuf_wi = 0u;
65792 while (true) {
65793 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)))) {
65794 status = wuffs_base__make_status(wuffs_base__error__bad_workbuf_length);
65795 goto exit;
65798 wuffs_base__io_buffer* o_0_v_w = v_w;
65799 uint8_t* o_0_iop_v_w = iop_v_w;
65800 uint8_t* o_0_io0_v_w = io0_v_w;
65801 uint8_t* o_0_io1_v_w = io1_v_w;
65802 uint8_t* o_0_io2_v_w = io2_v_w;
65803 v_w = wuffs_private_impl__io_writer__set(
65804 &u_w,
65805 &iop_v_w,
65806 &io0_v_w,
65807 &io1_v_w,
65808 &io2_v_w,
65809 wuffs_base__slice_u8__subslice_ij(a_workbuf,
65810 self->private_impl.f_workbuf_wi,
65811 self->private_impl.f_pass_workbuf_length),
65812 ((uint64_t)(self->private_impl.f_workbuf_hist_pos_base + self->private_impl.f_workbuf_wi)));
65814 const bool o_1_closed_a_src = a_src->meta.closed;
65815 const uint8_t* o_1_io2_a_src = io2_a_src;
65816 wuffs_private_impl__io_reader__limit(&io2_a_src, iop_a_src,
65817 ((uint64_t)(self->private_impl.f_chunk_length)));
65818 if (a_src) {
65819 size_t n = ((size_t)(io2_a_src - a_src->data.ptr));
65820 a_src->meta.closed = a_src->meta.closed && (a_src->meta.wi <= n);
65821 a_src->meta.wi = n;
65823 v_w_mark = ((uint64_t)(iop_v_w - io0_v_w));
65824 v_r_mark = ((uint64_t)(iop_a_src - io0_a_src));
65826 u_w.meta.wi = ((size_t)(iop_v_w - u_w.data.ptr));
65827 if (a_src) {
65828 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
65830 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());
65831 v_zlib_status = t_0;
65832 iop_v_w = u_w.data.ptr + u_w.meta.wi;
65833 if (a_src) {
65834 iop_a_src = a_src->data.ptr + a_src->meta.ri;
65837 if ( ! self->private_impl.f_ignore_checksum) {
65838 wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_private_impl__io__since(v_r_mark, ((uint64_t)(iop_a_src - io0_a_src)), io0_a_src));
65840 wuffs_private_impl__u32__sat_sub_indirect(&self->private_impl.f_chunk_length, ((uint32_t)(wuffs_private_impl__io__count_since(v_r_mark, ((uint64_t)(iop_a_src - io0_a_src))))));
65841 wuffs_private_impl__u64__sat_add_indirect(&self->private_impl.f_workbuf_wi, wuffs_private_impl__io__count_since(v_w_mark, ((uint64_t)(iop_v_w - io0_v_w))));
65842 io2_a_src = o_1_io2_a_src;
65843 if (a_src) {
65844 a_src->meta.closed = o_1_closed_a_src;
65845 a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
65848 v_w = o_0_v_w;
65849 iop_v_w = o_0_iop_v_w;
65850 io0_v_w = o_0_io0_v_w;
65851 io1_v_w = o_0_io1_v_w;
65852 io2_v_w = o_0_io2_v_w;
65854 if (wuffs_base__status__is_ok(&v_zlib_status)) {
65855 if (self->private_impl.f_chunk_length > 0u) {
65856 status = wuffs_base__make_status(wuffs_base__error__too_much_data);
65857 goto exit;
65860 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
65861 uint32_t t_1;
65862 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
65863 t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
65864 iop_a_src += 4;
65865 } else {
65866 self->private_data.s_decode_pass.scratch = 0;
65867 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
65868 while (true) {
65869 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
65870 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
65871 goto suspend;
65873 uint64_t* scratch = &self->private_data.s_decode_pass.scratch;
65874 uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu));
65875 *scratch >>= 8;
65876 *scratch <<= 8;
65877 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
65878 if (num_bits_1 == 24) {
65879 t_1 = ((uint32_t)(*scratch >> 32));
65880 break;
65882 num_bits_1 += 8u;
65883 *scratch |= ((uint64_t)(num_bits_1));
65886 v_checksum_want = t_1;
65888 if ( ! self->private_impl.f_ignore_checksum && (self->private_impl.f_chunk_type_array[0u] == 73u)) {
65889 v_checksum_have = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__utility__empty_slice_u8());
65890 if (v_checksum_have != v_checksum_want) {
65891 status = wuffs_base__make_status(wuffs_png__error__bad_checksum);
65892 goto exit;
65895 break;
65896 } else if (v_zlib_status.repr == wuffs_base__suspension__short_write) {
65897 if ((1u <= self->private_impl.f_interlace_pass) && (self->private_impl.f_interlace_pass <= 6u)) {
65898 break;
65900 status = wuffs_base__make_status(wuffs_base__error__too_much_data);
65901 goto exit;
65902 } else if (v_zlib_status.repr != wuffs_base__suspension__short_read) {
65903 status = v_zlib_status;
65904 if (wuffs_base__status__is_error(&status)) {
65905 goto exit;
65906 } else if (wuffs_base__status__is_suspension(&status)) {
65907 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
65908 goto exit;
65910 goto ok;
65911 } else if (self->private_impl.f_chunk_length == 0u) {
65913 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
65914 uint32_t t_2;
65915 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
65916 t_2 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
65917 iop_a_src += 4;
65918 } else {
65919 self->private_data.s_decode_pass.scratch = 0;
65920 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
65921 while (true) {
65922 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
65923 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
65924 goto suspend;
65926 uint64_t* scratch = &self->private_data.s_decode_pass.scratch;
65927 uint32_t num_bits_2 = ((uint32_t)(*scratch & 0xFFu));
65928 *scratch >>= 8;
65929 *scratch <<= 8;
65930 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_2);
65931 if (num_bits_2 == 24) {
65932 t_2 = ((uint32_t)(*scratch >> 32));
65933 break;
65935 num_bits_2 += 8u;
65936 *scratch |= ((uint64_t)(num_bits_2));
65939 v_checksum_want = t_2;
65941 if ( ! self->private_impl.f_ignore_checksum && (self->private_impl.f_chunk_type_array[0u] == 73u)) {
65942 v_checksum_have = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__utility__empty_slice_u8());
65943 if (v_checksum_have != v_checksum_want) {
65944 status = wuffs_base__make_status(wuffs_png__error__bad_checksum);
65945 goto exit;
65949 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
65950 uint32_t t_3;
65951 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
65952 t_3 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
65953 iop_a_src += 4;
65954 } else {
65955 self->private_data.s_decode_pass.scratch = 0;
65956 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
65957 while (true) {
65958 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
65959 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
65960 goto suspend;
65962 uint64_t* scratch = &self->private_data.s_decode_pass.scratch;
65963 uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFFu));
65964 *scratch >>= 8;
65965 *scratch <<= 8;
65966 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3);
65967 if (num_bits_3 == 24) {
65968 t_3 = ((uint32_t)(*scratch >> 32));
65969 break;
65971 num_bits_3 += 8u;
65972 *scratch |= ((uint64_t)(num_bits_3));
65975 self->private_impl.f_chunk_length = t_3;
65978 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
65979 uint32_t t_4;
65980 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
65981 t_4 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
65982 iop_a_src += 4;
65983 } else {
65984 self->private_data.s_decode_pass.scratch = 0;
65985 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
65986 while (true) {
65987 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
65988 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
65989 goto suspend;
65991 uint64_t* scratch = &self->private_data.s_decode_pass.scratch;
65992 uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
65993 *scratch <<= 8;
65994 *scratch >>= 8;
65995 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
65996 if (num_bits_4 == 24) {
65997 t_4 = ((uint32_t)(*scratch));
65998 break;
66000 num_bits_4 += 8u;
66001 *scratch |= ((uint64_t)(num_bits_4)) << 56;
66004 self->private_impl.f_chunk_type = t_4;
66006 if (self->private_impl.f_chunk_type_array[0u] == 73u) {
66007 if (self->private_impl.f_chunk_type != 1413563465u) {
66008 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
66009 goto exit;
66011 if ( ! self->private_impl.f_ignore_checksum) {
66012 wuffs_private_impl__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32,
66013 sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
66014 wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__make_slice_u8(self->private_impl.f_chunk_type_array, 4));
66016 } else {
66017 if ((self->private_impl.f_chunk_type != 1413571686u) || (self->private_impl.f_chunk_length < 4u)) {
66018 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
66019 goto exit;
66021 self->private_impl.f_chunk_length -= 4u;
66023 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
66024 uint32_t t_5;
66025 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
66026 t_5 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
66027 iop_a_src += 4;
66028 } else {
66029 self->private_data.s_decode_pass.scratch = 0;
66030 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
66031 while (true) {
66032 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
66033 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
66034 goto suspend;
66036 uint64_t* scratch = &self->private_data.s_decode_pass.scratch;
66037 uint32_t num_bits_5 = ((uint32_t)(*scratch & 0xFFu));
66038 *scratch >>= 8;
66039 *scratch <<= 8;
66040 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_5);
66041 if (num_bits_5 == 24) {
66042 t_5 = ((uint32_t)(*scratch >> 32));
66043 break;
66045 num_bits_5 += 8u;
66046 *scratch |= ((uint64_t)(num_bits_5));
66049 v_seq_num = t_5;
66051 if (v_seq_num != self->private_impl.f_next_animation_seq_num) {
66052 status = wuffs_base__make_status(wuffs_png__error__bad_animation_sequence_number);
66053 goto exit;
66054 } else if (self->private_impl.f_next_animation_seq_num >= 4294967295u) {
66055 status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file);
66056 goto exit;
66058 self->private_impl.f_next_animation_seq_num += 1u;
66060 continue;
66061 } else if (((uint64_t)(io2_a_src - iop_a_src)) > 0u) {
66062 status = wuffs_base__make_status(wuffs_png__error__internal_error_zlib_decoder_did_not_exhaust_its_input);
66063 goto exit;
66065 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
66066 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(11);
66068 if (self->private_impl.f_workbuf_wi != self->private_impl.f_pass_workbuf_length) {
66069 status = wuffs_base__make_status(wuffs_base__error__not_enough_data);
66070 goto exit;
66071 } else if (0u < ((uint64_t)(a_workbuf.len))) {
66072 if (a_workbuf.ptr[0u] == 4u) {
66073 a_workbuf.ptr[0u] = 1u;
66078 self->private_impl.p_decode_pass = 0;
66079 goto exit;
66082 goto suspend;
66083 suspend:
66084 self->private_impl.p_decode_pass = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
66086 goto exit;
66087 exit:
66088 if (a_src && a_src->data.ptr) {
66089 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
66092 return status;
66095 // -------- func png.decoder.frame_dirty_rect
66097 WUFFS_BASE__GENERATED_C_CODE
66098 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
66099 wuffs_png__decoder__frame_dirty_rect(
66100 const wuffs_png__decoder* self) {
66101 if (!self) {
66102 return wuffs_base__utility__empty_rect_ie_u32();
66104 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
66105 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
66106 return wuffs_base__utility__empty_rect_ie_u32();
66109 return wuffs_base__utility__make_rect_ie_u32(
66110 self->private_impl.f_frame_rect_x0,
66111 self->private_impl.f_frame_rect_y0,
66112 self->private_impl.f_frame_rect_x1,
66113 self->private_impl.f_frame_rect_y1);
66116 // -------- func png.decoder.num_animation_loops
66118 WUFFS_BASE__GENERATED_C_CODE
66119 WUFFS_BASE__MAYBE_STATIC uint32_t
66120 wuffs_png__decoder__num_animation_loops(
66121 const wuffs_png__decoder* self) {
66122 if (!self) {
66123 return 0;
66125 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
66126 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
66127 return 0;
66130 return self->private_impl.f_num_animation_loops_value;
66133 // -------- func png.decoder.num_decoded_frame_configs
66135 WUFFS_BASE__GENERATED_C_CODE
66136 WUFFS_BASE__MAYBE_STATIC uint64_t
66137 wuffs_png__decoder__num_decoded_frame_configs(
66138 const wuffs_png__decoder* self) {
66139 if (!self) {
66140 return 0;
66142 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
66143 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
66144 return 0;
66147 return ((uint64_t)(self->private_impl.f_num_decoded_frame_configs_value));
66150 // -------- func png.decoder.num_decoded_frames
66152 WUFFS_BASE__GENERATED_C_CODE
66153 WUFFS_BASE__MAYBE_STATIC uint64_t
66154 wuffs_png__decoder__num_decoded_frames(
66155 const wuffs_png__decoder* self) {
66156 if (!self) {
66157 return 0;
66159 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
66160 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
66161 return 0;
66164 return ((uint64_t)(self->private_impl.f_num_decoded_frames_value));
66167 // -------- func png.decoder.restart_frame
66169 WUFFS_BASE__GENERATED_C_CODE
66170 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
66171 wuffs_png__decoder__restart_frame(
66172 wuffs_png__decoder* self,
66173 uint64_t a_index,
66174 uint64_t a_io_position) {
66175 if (!self) {
66176 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
66178 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
66179 return wuffs_base__make_status(
66180 (self->private_impl.magic == WUFFS_BASE__DISABLED)
66181 ? wuffs_base__error__disabled_by_previous_error
66182 : wuffs_base__error__initialize_not_called);
66185 if (self->private_impl.f_call_sequence < 32u) {
66186 return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
66187 } 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))) {
66188 return wuffs_base__make_status(wuffs_base__error__bad_argument);
66190 self->private_impl.f_call_sequence = 40u;
66191 if (self->private_impl.f_interlace_pass >= 1u) {
66192 self->private_impl.f_interlace_pass = 1u;
66194 self->private_impl.f_frame_config_io_position = a_io_position;
66195 self->private_impl.f_num_decoded_frame_configs_value = ((uint32_t)(a_index));
66196 self->private_impl.f_num_decoded_frames_value = self->private_impl.f_num_decoded_frame_configs_value;
66197 return wuffs_base__make_status(NULL);
66200 // -------- func png.decoder.set_report_metadata
66202 WUFFS_BASE__GENERATED_C_CODE
66203 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
66204 wuffs_png__decoder__set_report_metadata(
66205 wuffs_png__decoder* self,
66206 uint32_t a_fourcc,
66207 bool a_report) {
66208 if (!self) {
66209 return wuffs_base__make_empty_struct();
66211 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
66212 return wuffs_base__make_empty_struct();
66215 if (a_fourcc == 1128813133u) {
66216 self->private_impl.f_report_metadata_chrm = a_report;
66217 } else if (a_fourcc == 1163413830u) {
66218 self->private_impl.f_report_metadata_exif = a_report;
66219 } else if (a_fourcc == 1195461953u) {
66220 self->private_impl.f_report_metadata_gama = a_report;
66221 } else if (a_fourcc == 1229144912u) {
66222 self->private_impl.f_report_metadata_iccp = a_report;
66223 } else if (a_fourcc == 1263947808u) {
66224 self->private_impl.f_report_metadata_kvp = a_report;
66225 } else if (a_fourcc == 1397901122u) {
66226 self->private_impl.f_report_metadata_srgb = a_report;
66228 return wuffs_base__make_empty_struct();
66231 // -------- func png.decoder.tell_me_more
66233 WUFFS_BASE__GENERATED_C_CODE
66234 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
66235 wuffs_png__decoder__tell_me_more(
66236 wuffs_png__decoder* self,
66237 wuffs_base__io_buffer* a_dst,
66238 wuffs_base__more_information* a_minfo,
66239 wuffs_base__io_buffer* a_src) {
66240 if (!self) {
66241 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
66243 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
66244 return wuffs_base__make_status(
66245 (self->private_impl.magic == WUFFS_BASE__DISABLED)
66246 ? wuffs_base__error__disabled_by_previous_error
66247 : wuffs_base__error__initialize_not_called);
66249 if (!a_dst || !a_src) {
66250 self->private_impl.magic = WUFFS_BASE__DISABLED;
66251 return wuffs_base__make_status(wuffs_base__error__bad_argument);
66253 if ((self->private_impl.active_coroutine != 0) &&
66254 (self->private_impl.active_coroutine != 4)) {
66255 self->private_impl.magic = WUFFS_BASE__DISABLED;
66256 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
66258 self->private_impl.active_coroutine = 0;
66259 wuffs_base__status status = wuffs_base__make_status(NULL);
66261 wuffs_base__status v_status = wuffs_base__make_status(NULL);
66263 uint32_t coro_susp_point = self->private_impl.p_tell_me_more;
66264 switch (coro_susp_point) {
66265 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
66267 while (true) {
66269 wuffs_base__status t_0 = wuffs_png__decoder__do_tell_me_more(self, a_dst, a_minfo, a_src);
66270 v_status = t_0;
66272 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
66273 status = wuffs_base__make_status(wuffs_png__error__truncated_input);
66274 goto exit;
66276 status = v_status;
66277 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
66281 self->private_impl.p_tell_me_more = 0;
66282 goto exit;
66285 goto suspend;
66286 suspend:
66287 self->private_impl.p_tell_me_more = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
66288 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 4 : 0;
66290 goto exit;
66291 exit:
66292 if (wuffs_base__status__is_error(&status)) {
66293 self->private_impl.magic = WUFFS_BASE__DISABLED;
66295 return status;
66298 // -------- func png.decoder.do_tell_me_more
66300 WUFFS_BASE__GENERATED_C_CODE
66301 static wuffs_base__status
66302 wuffs_png__decoder__do_tell_me_more(
66303 wuffs_png__decoder* self,
66304 wuffs_base__io_buffer* a_dst,
66305 wuffs_base__more_information* a_minfo,
66306 wuffs_base__io_buffer* a_src) {
66307 wuffs_base__status status = wuffs_base__make_status(NULL);
66309 uint8_t v_c8 = 0;
66310 uint16_t v_c16 = 0;
66311 wuffs_base__io_buffer u_w = wuffs_base__empty_io_buffer();
66312 wuffs_base__io_buffer* v_w = &u_w;
66313 uint8_t* iop_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
66314 uint8_t* io0_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
66315 uint8_t* io1_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
66316 uint8_t* io2_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
66317 uint64_t v_num_written = 0;
66318 uint64_t v_w_mark = 0;
66319 uint64_t v_r_mark = 0;
66320 wuffs_base__status v_zlib_status = wuffs_base__make_status(NULL);
66322 uint8_t* iop_a_dst = NULL;
66323 uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
66324 uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
66325 uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
66326 if (a_dst && a_dst->data.ptr) {
66327 io0_a_dst = a_dst->data.ptr;
66328 io1_a_dst = io0_a_dst + a_dst->meta.wi;
66329 iop_a_dst = io1_a_dst;
66330 io2_a_dst = io0_a_dst + a_dst->data.len;
66331 if (a_dst->meta.closed) {
66332 io2_a_dst = iop_a_dst;
66335 const uint8_t* iop_a_src = NULL;
66336 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
66337 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
66338 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
66339 if (a_src && a_src->data.ptr) {
66340 io0_a_src = a_src->data.ptr;
66341 io1_a_src = io0_a_src + a_src->meta.ri;
66342 iop_a_src = io1_a_src;
66343 io2_a_src = io0_a_src + a_src->meta.wi;
66346 uint32_t coro_susp_point = self->private_impl.p_do_tell_me_more;
66347 if (coro_susp_point) {
66348 v_zlib_status = self->private_data.s_do_tell_me_more.v_zlib_status;
66350 switch (coro_susp_point) {
66351 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
66353 if (((uint8_t)(self->private_impl.f_call_sequence & 16u)) == 0u) {
66354 status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
66355 goto exit;
66357 if (self->private_impl.f_metadata_fourcc == 0u) {
66358 status = wuffs_base__make_status(wuffs_base__error__no_more_information);
66359 goto exit;
66361 do {
66362 if (self->private_impl.f_metadata_flavor == 3u) {
66363 while (true) {
66364 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) {
66365 status = wuffs_base__make_status(wuffs_base__error__bad_i_o_position);
66366 goto exit;
66367 } else if (a_minfo != NULL) {
66368 wuffs_base__more_information__set(a_minfo,
66369 self->private_impl.f_metadata_flavor,
66370 self->private_impl.f_metadata_fourcc,
66371 self->private_impl.f_metadata_x,
66372 self->private_impl.f_metadata_y,
66373 self->private_impl.f_metadata_z);
66375 if (self->private_impl.f_metadata_y >= self->private_impl.f_metadata_z) {
66376 goto label__goto_done__break;
66378 self->private_impl.f_metadata_y = self->private_impl.f_metadata_z;
66379 status = wuffs_base__make_status(wuffs_base__suspension__even_more_information);
66380 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
66383 if (self->private_impl.f_metadata_is_zlib_compressed) {
66384 if (self->private_impl.f_zlib_is_dirty) {
66385 wuffs_private_impl__ignore_status(wuffs_zlib__decoder__initialize(&self->private_data.f_zlib,
66386 sizeof (wuffs_zlib__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
66387 if (self->private_impl.f_ignore_checksum) {
66388 wuffs_zlib__decoder__set_quirk(&self->private_data.f_zlib, 1u, 1u);
66391 self->private_impl.f_zlib_is_dirty = true;
66392 self->private_impl.f_ztxt_hist_pos = 0u;
66394 label__loop__continue:;
66395 while (true) {
66396 if (a_minfo != NULL) {
66397 wuffs_base__more_information__set(a_minfo,
66398 self->private_impl.f_metadata_flavor,
66399 self->private_impl.f_metadata_fourcc,
66400 self->private_impl.f_metadata_x,
66401 self->private_impl.f_metadata_y,
66402 self->private_impl.f_metadata_z);
66404 if (self->private_impl.f_metadata_flavor != 4u) {
66405 break;
66407 if (self->private_impl.f_metadata_is_zlib_compressed) {
66408 if (self->private_impl.f_chunk_type == 1346585449u) {
66410 const bool o_0_closed_a_src = a_src->meta.closed;
66411 const uint8_t* o_0_io2_a_src = io2_a_src;
66412 wuffs_private_impl__io_reader__limit(&io2_a_src, iop_a_src,
66413 ((uint64_t)(self->private_impl.f_chunk_length)));
66414 if (a_src) {
66415 size_t n = ((size_t)(io2_a_src - a_src->data.ptr));
66416 a_src->meta.closed = a_src->meta.closed && (a_src->meta.wi <= n);
66417 a_src->meta.wi = n;
66419 v_r_mark = ((uint64_t)(iop_a_src - io0_a_src));
66421 if (a_dst) {
66422 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
66424 if (a_src) {
66425 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
66427 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());
66428 v_zlib_status = t_0;
66429 if (a_dst) {
66430 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
66432 if (a_src) {
66433 iop_a_src = a_src->data.ptr + a_src->meta.ri;
66436 wuffs_private_impl__u32__sat_sub_indirect(&self->private_impl.f_chunk_length, ((uint32_t)(wuffs_private_impl__io__count_since(v_r_mark, ((uint64_t)(iop_a_src - io0_a_src))))));
66437 io2_a_src = o_0_io2_a_src;
66438 if (a_src) {
66439 a_src->meta.closed = o_0_closed_a_src;
66440 a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
66443 if (wuffs_base__status__is_ok(&v_zlib_status)) {
66444 self->private_impl.f_metadata_is_zlib_compressed = false;
66445 break;
66446 } else if ( ! wuffs_base__status__is_suspension(&v_zlib_status)) {
66447 status = v_zlib_status;
66448 if (wuffs_base__status__is_error(&status)) {
66449 goto exit;
66450 } else if (wuffs_base__status__is_suspension(&status)) {
66451 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
66452 goto exit;
66454 goto ok;
66456 status = v_zlib_status;
66457 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
66458 } else if (self->private_impl.f_chunk_type == 1951945833u) {
66460 const bool o_1_closed_a_src = a_src->meta.closed;
66461 const uint8_t* o_1_io2_a_src = io2_a_src;
66462 wuffs_private_impl__io_reader__limit(&io2_a_src, iop_a_src,
66463 ((uint64_t)(self->private_impl.f_chunk_length)));
66464 if (a_src) {
66465 size_t n = ((size_t)(io2_a_src - a_src->data.ptr));
66466 a_src->meta.closed = a_src->meta.closed && (a_src->meta.wi <= n);
66467 a_src->meta.wi = n;
66469 v_r_mark = ((uint64_t)(iop_a_src - io0_a_src));
66471 if (a_dst) {
66472 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
66474 if (a_src) {
66475 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
66477 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());
66478 v_zlib_status = t_1;
66479 if (a_dst) {
66480 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
66482 if (a_src) {
66483 iop_a_src = a_src->data.ptr + a_src->meta.ri;
66486 wuffs_private_impl__u32__sat_sub_indirect(&self->private_impl.f_chunk_length, ((uint32_t)(wuffs_private_impl__io__count_since(v_r_mark, ((uint64_t)(iop_a_src - io0_a_src))))));
66487 io2_a_src = o_1_io2_a_src;
66488 if (a_src) {
66489 a_src->meta.closed = o_1_closed_a_src;
66490 a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
66493 if (wuffs_base__status__is_ok(&v_zlib_status)) {
66494 self->private_impl.f_metadata_is_zlib_compressed = false;
66495 break;
66496 } else if ( ! wuffs_base__status__is_suspension(&v_zlib_status)) {
66497 status = v_zlib_status;
66498 if (wuffs_base__status__is_error(&status)) {
66499 goto exit;
66500 } else if (wuffs_base__status__is_suspension(&status)) {
66501 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
66502 goto exit;
66504 goto ok;
66506 status = v_zlib_status;
66507 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
66508 } else if (self->private_impl.f_chunk_type == 1951945850u) {
66509 if (self->private_impl.f_ztxt_ri == self->private_impl.f_ztxt_wi) {
66511 wuffs_base__io_buffer* o_2_v_w = v_w;
66512 uint8_t* o_2_iop_v_w = iop_v_w;
66513 uint8_t* o_2_io0_v_w = io0_v_w;
66514 uint8_t* o_2_io1_v_w = io1_v_w;
66515 uint8_t* o_2_io2_v_w = io2_v_w;
66516 v_w = wuffs_private_impl__io_writer__set(
66517 &u_w,
66518 &iop_v_w,
66519 &io0_v_w,
66520 &io1_v_w,
66521 &io2_v_w,
66522 wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024),
66523 self->private_impl.f_ztxt_hist_pos);
66525 const bool o_3_closed_a_src = a_src->meta.closed;
66526 const uint8_t* o_3_io2_a_src = io2_a_src;
66527 wuffs_private_impl__io_reader__limit(&io2_a_src, iop_a_src,
66528 ((uint64_t)(self->private_impl.f_chunk_length)));
66529 if (a_src) {
66530 size_t n = ((size_t)(io2_a_src - a_src->data.ptr));
66531 a_src->meta.closed = a_src->meta.closed && (a_src->meta.wi <= n);
66532 a_src->meta.wi = n;
66534 v_w_mark = ((uint64_t)(iop_v_w - io0_v_w));
66535 v_r_mark = ((uint64_t)(iop_a_src - io0_a_src));
66537 u_w.meta.wi = ((size_t)(iop_v_w - u_w.data.ptr));
66538 if (a_src) {
66539 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
66541 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());
66542 v_zlib_status = t_2;
66543 iop_v_w = u_w.data.ptr + u_w.meta.wi;
66544 if (a_src) {
66545 iop_a_src = a_src->data.ptr + a_src->meta.ri;
66548 wuffs_private_impl__u32__sat_sub_indirect(&self->private_impl.f_chunk_length, ((uint32_t)(wuffs_private_impl__io__count_since(v_r_mark, ((uint64_t)(iop_a_src - io0_a_src))))));
66549 v_num_written = wuffs_private_impl__io__count_since(v_w_mark, ((uint64_t)(iop_v_w - io0_v_w)));
66550 io2_a_src = o_3_io2_a_src;
66551 if (a_src) {
66552 a_src->meta.closed = o_3_closed_a_src;
66553 a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
66556 v_w = o_2_v_w;
66557 iop_v_w = o_2_iop_v_w;
66558 io0_v_w = o_2_io0_v_w;
66559 io1_v_w = o_2_io1_v_w;
66560 io2_v_w = o_2_io2_v_w;
66562 if (v_num_written > 1024u) {
66563 status = wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_i_o);
66564 goto exit;
66566 self->private_impl.f_ztxt_ri = 0u;
66567 self->private_impl.f_ztxt_wi = ((uint32_t)(v_num_written));
66568 wuffs_private_impl__u64__sat_add_indirect(&self->private_impl.f_ztxt_hist_pos, v_num_written);
66570 while (self->private_impl.f_ztxt_ri < self->private_impl.f_ztxt_wi) {
66571 v_c16 = WUFFS_PNG__LATIN_1[self->private_data.f_dst_palette[self->private_impl.f_ztxt_ri]];
66572 if (v_c16 == 0u) {
66573 status = wuffs_base__make_status(wuffs_png__error__bad_text_chunk_not_latin_1);
66574 goto exit;
66575 } else if (v_c16 <= 127u) {
66576 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
66577 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
66578 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
66579 goto label__loop__continue;
66581 self->private_impl.f_ztxt_ri += 1u;
66582 (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)(v_c16))), iop_a_dst += 1);
66583 } else {
66584 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 1u) {
66585 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
66586 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
66587 goto label__loop__continue;
66589 self->private_impl.f_ztxt_ri += 1u;
66590 (wuffs_base__poke_u16le__no_bounds_check(iop_a_dst, v_c16), iop_a_dst += 2);
66593 if (wuffs_base__status__is_ok(&v_zlib_status)) {
66594 self->private_impl.f_metadata_is_zlib_compressed = false;
66595 break;
66596 } else if ( ! wuffs_base__status__is_suspension(&v_zlib_status)) {
66597 status = v_zlib_status;
66598 if (wuffs_base__status__is_error(&status)) {
66599 goto exit;
66600 } else if (wuffs_base__status__is_suspension(&status)) {
66601 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
66602 goto exit;
66604 goto ok;
66605 } else if (v_zlib_status.repr != wuffs_base__suspension__short_write) {
66606 status = v_zlib_status;
66607 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
66609 } else {
66610 status = wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_chunk_type);
66611 goto exit;
66613 } else if ((self->private_impl.f_chunk_type == 1951945833u) && (self->private_impl.f_metadata_fourcc == 1263947862u)) {
66614 while (true) {
66615 if (self->private_impl.f_chunk_length <= 0u) {
66616 goto label__loop__break;
66617 } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
66618 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
66619 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7);
66620 goto label__loop__continue;
66621 } else if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
66622 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
66623 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8);
66624 goto label__loop__continue;
66626 self->private_impl.f_chunk_length -= 1u;
66627 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
66628 iop_a_src += 1u;
66629 (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, v_c8), iop_a_dst += 1);
66631 } else {
66632 while (true) {
66633 if (self->private_impl.f_chunk_length <= 0u) {
66634 if (self->private_impl.f_metadata_fourcc == 1263947851u) {
66635 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
66636 goto exit;
66638 goto label__loop__break;
66639 } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
66640 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
66641 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9);
66642 goto label__loop__continue;
66644 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
66645 if (v_c8 == 0u) {
66646 self->private_impl.f_chunk_length -= 1u;
66647 iop_a_src += 1u;
66648 goto label__loop__break;
66650 v_c16 = WUFFS_PNG__LATIN_1[v_c8];
66651 if (v_c16 == 0u) {
66652 status = wuffs_base__make_status(wuffs_png__error__bad_text_chunk_not_latin_1);
66653 goto exit;
66654 } else if (v_c16 <= 127u) {
66655 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
66656 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
66657 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10);
66658 goto label__loop__continue;
66660 self->private_impl.f_chunk_length -= 1u;
66661 iop_a_src += 1u;
66662 (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)(v_c16))), iop_a_dst += 1);
66663 } else {
66664 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 1u) {
66665 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
66666 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(11);
66667 goto label__loop__continue;
66669 self->private_impl.f_chunk_length -= 1u;
66670 iop_a_src += 1u;
66671 (wuffs_base__poke_u16le__no_bounds_check(iop_a_dst, v_c16), iop_a_dst += 2);
66676 label__loop__break:;
66677 if (self->private_impl.f_metadata_fourcc == 1263947851u) {
66678 self->private_impl.f_metadata_fourcc = 1263947862u;
66679 if (self->private_impl.f_chunk_type == 1951945833u) {
66680 if (self->private_impl.f_chunk_length <= 1u) {
66681 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
66682 goto exit;
66684 self->private_impl.f_chunk_length -= 2u;
66686 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
66687 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
66688 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
66689 goto suspend;
66691 uint8_t t_3 = *iop_a_src++;
66692 v_c8 = t_3;
66694 if (v_c8 == 0u) {
66695 self->private_impl.f_metadata_is_zlib_compressed = false;
66696 } else if (v_c8 == 1u) {
66697 self->private_impl.f_metadata_is_zlib_compressed = true;
66698 } else {
66699 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
66700 goto exit;
66703 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
66704 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
66705 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
66706 goto suspend;
66708 uint8_t t_4 = *iop_a_src++;
66709 v_c8 = t_4;
66711 if ((v_c8 != 0u) && self->private_impl.f_metadata_is_zlib_compressed) {
66712 status = wuffs_base__make_status(wuffs_png__error__unsupported_png_compression_method);
66713 goto exit;
66715 self->private_impl.f_metadata_fourcc -= 2u;
66716 while (self->private_impl.f_metadata_fourcc != 1263947862u) {
66717 self->private_impl.f_metadata_fourcc += 1u;
66718 while (true) {
66719 if (self->private_impl.f_chunk_length <= 0u) {
66720 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
66721 goto exit;
66723 self->private_impl.f_chunk_length -= 1u;
66725 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
66726 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
66727 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
66728 goto suspend;
66730 uint8_t t_5 = *iop_a_src++;
66731 v_c8 = t_5;
66733 if (v_c8 == 0u) {
66734 break;
66738 } else if (self->private_impl.f_chunk_type == 1951945850u) {
66739 if (self->private_impl.f_chunk_length <= 0u) {
66740 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
66741 goto exit;
66743 self->private_impl.f_chunk_length -= 1u;
66745 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
66746 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
66747 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
66748 goto suspend;
66750 uint8_t t_6 = *iop_a_src++;
66751 v_c8 = t_6;
66753 if (v_c8 != 0u) {
66754 status = wuffs_base__make_status(wuffs_png__error__unsupported_png_compression_method);
66755 goto exit;
66757 self->private_impl.f_metadata_is_zlib_compressed = true;
66759 self->private_impl.f_call_sequence &= 239u;
66760 status = wuffs_base__make_status(NULL);
66761 goto ok;
66763 } while (0);
66764 label__goto_done__break:;
66765 if (self->private_impl.f_chunk_length != 0u) {
66766 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
66767 goto exit;
66769 self->private_data.s_do_tell_me_more.scratch = 4u;
66770 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
66771 if (self->private_data.s_do_tell_me_more.scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
66772 self->private_data.s_do_tell_me_more.scratch -= ((uint64_t)(io2_a_src - iop_a_src));
66773 iop_a_src = io2_a_src;
66774 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
66775 goto suspend;
66777 iop_a_src += self->private_data.s_do_tell_me_more.scratch;
66778 self->private_impl.f_metadata_flavor = 0u;
66779 self->private_impl.f_metadata_fourcc = 0u;
66780 self->private_impl.f_metadata_x = 0u;
66781 self->private_impl.f_metadata_y = 0u;
66782 self->private_impl.f_metadata_z = 0u;
66783 self->private_impl.f_call_sequence &= 239u;
66784 status = wuffs_base__make_status(NULL);
66785 goto ok;
66788 self->private_impl.p_do_tell_me_more = 0;
66789 goto exit;
66792 goto suspend;
66793 suspend:
66794 self->private_impl.p_do_tell_me_more = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
66795 self->private_data.s_do_tell_me_more.v_zlib_status = v_zlib_status;
66797 goto exit;
66798 exit:
66799 if (a_dst && a_dst->data.ptr) {
66800 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
66802 if (a_src && a_src->data.ptr) {
66803 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
66806 return status;
66809 // -------- func png.decoder.workbuf_len
66811 WUFFS_BASE__GENERATED_C_CODE
66812 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
66813 wuffs_png__decoder__workbuf_len(
66814 const wuffs_png__decoder* self) {
66815 if (!self) {
66816 return wuffs_base__utility__empty_range_ii_u64();
66818 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
66819 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
66820 return wuffs_base__utility__empty_range_ii_u64();
66823 return wuffs_base__utility__make_range_ii_u64(self->private_impl.f_overall_workbuf_length, self->private_impl.f_overall_workbuf_length);
66826 // -------- func png.decoder.filter_and_swizzle
66828 WUFFS_BASE__GENERATED_C_CODE
66829 static wuffs_base__status
66830 wuffs_png__decoder__filter_and_swizzle(
66831 wuffs_png__decoder* self,
66832 wuffs_base__pixel_buffer* a_dst,
66833 wuffs_base__slice_u8 a_workbuf) {
66834 return (*self->private_impl.choosy_filter_and_swizzle)(self, a_dst, a_workbuf);
66837 WUFFS_BASE__GENERATED_C_CODE
66838 static wuffs_base__status
66839 wuffs_png__decoder__filter_and_swizzle__choosy_default(
66840 wuffs_png__decoder* self,
66841 wuffs_base__pixel_buffer* a_dst,
66842 wuffs_base__slice_u8 a_workbuf) {
66843 wuffs_base__pixel_format v_dst_pixfmt = {0};
66844 uint32_t v_dst_bits_per_pixel = 0;
66845 uint64_t v_dst_bytes_per_pixel = 0;
66846 uint64_t v_dst_bytes_per_row0 = 0;
66847 uint64_t v_dst_bytes_per_row1 = 0;
66848 wuffs_base__slice_u8 v_dst_palette = {0};
66849 wuffs_base__table_u8 v_tab = {0};
66850 uint32_t v_y = 0;
66851 wuffs_base__slice_u8 v_dst = {0};
66852 uint8_t v_filter = 0;
66853 wuffs_base__slice_u8 v_curr_row = {0};
66854 wuffs_base__slice_u8 v_prev_row = {0};
66856 v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
66857 v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
66858 if ((v_dst_bits_per_pixel & 7u) != 0u) {
66859 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
66861 v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8u)));
66862 v_dst_bytes_per_row0 = (((uint64_t)(self->private_impl.f_frame_rect_x0)) * v_dst_bytes_per_pixel);
66863 v_dst_bytes_per_row1 = (((uint64_t)(self->private_impl.f_frame_rect_x1)) * v_dst_bytes_per_pixel);
66864 v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024));
66865 v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
66866 if (v_dst_bytes_per_row1 < ((uint64_t)(v_tab.width))) {
66867 v_tab = wuffs_base__table_u8__subtable_ij(v_tab,
66870 v_dst_bytes_per_row1,
66871 ((uint64_t)(v_tab.height)));
66873 if (v_dst_bytes_per_row0 < ((uint64_t)(v_tab.width))) {
66874 v_tab = wuffs_base__table_u8__subtable_ij(v_tab,
66875 v_dst_bytes_per_row0,
66877 ((uint64_t)(v_tab.width)),
66878 ((uint64_t)(v_tab.height)));
66879 } else {
66880 v_tab = wuffs_base__table_u8__subtable_ij(v_tab,
66884 0u);
66886 v_y = self->private_impl.f_frame_rect_y0;
66887 while (v_y < self->private_impl.f_frame_rect_y1) {
66888 v_dst = wuffs_private_impl__table_u8__row_u32(v_tab, v_y);
66889 if (1u > ((uint64_t)(a_workbuf.len))) {
66890 return wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_workbuf_length);
66892 v_filter = a_workbuf.ptr[0u];
66893 a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, 1u);
66894 if (self->private_impl.f_pass_bytes_per_row > ((uint64_t)(a_workbuf.len))) {
66895 return wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_workbuf_length);
66897 v_curr_row = wuffs_base__slice_u8__subslice_j(a_workbuf, self->private_impl.f_pass_bytes_per_row);
66898 a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, self->private_impl.f_pass_bytes_per_row);
66899 if (v_filter == 0u) {
66900 } else if (v_filter == 1u) {
66901 wuffs_png__decoder__filter_1(self, v_curr_row);
66902 } else if (v_filter == 2u) {
66903 wuffs_png__decoder__filter_2(self, v_curr_row, v_prev_row);
66904 } else if (v_filter == 3u) {
66905 wuffs_png__decoder__filter_3(self, v_curr_row, v_prev_row);
66906 } else if (v_filter == 4u) {
66907 wuffs_png__decoder__filter_4(self, v_curr_row, v_prev_row);
66908 } else {
66909 return wuffs_base__make_status(wuffs_png__error__bad_filter);
66911 wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, v_curr_row);
66912 v_prev_row = v_curr_row;
66913 v_y += 1u;
66915 return wuffs_base__make_status(NULL);
66918 // -------- func png.decoder.filter_and_swizzle_tricky
66920 WUFFS_BASE__GENERATED_C_CODE
66921 static wuffs_base__status
66922 wuffs_png__decoder__filter_and_swizzle_tricky(
66923 wuffs_png__decoder* self,
66924 wuffs_base__pixel_buffer* a_dst,
66925 wuffs_base__slice_u8 a_workbuf) {
66926 wuffs_base__pixel_format v_dst_pixfmt = {0};
66927 uint32_t v_dst_bits_per_pixel = 0;
66928 uint64_t v_dst_bytes_per_pixel = 0;
66929 uint64_t v_dst_bytes_per_row1 = 0;
66930 wuffs_base__slice_u8 v_dst_palette = {0};
66931 wuffs_base__table_u8 v_tab = {0};
66932 uint64_t v_src_bytes_per_pixel = 0;
66933 uint32_t v_x = 0;
66934 uint32_t v_y = 0;
66935 uint64_t v_i = 0;
66936 wuffs_base__slice_u8 v_dst = {0};
66937 uint8_t v_filter = 0;
66938 wuffs_base__slice_u8 v_s = {0};
66939 wuffs_base__slice_u8 v_curr_row = {0};
66940 wuffs_base__slice_u8 v_prev_row = {0};
66941 uint8_t v_bits_unpacked[8] = {0};
66942 uint8_t v_bits_packed = 0;
66943 uint8_t v_packs_remaining = 0;
66944 uint8_t v_multiplier = 0;
66945 uint8_t v_shift = 0;
66947 v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
66948 v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
66949 if ((v_dst_bits_per_pixel & 7u) != 0u) {
66950 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
66952 v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8u)));
66953 v_dst_bytes_per_row1 = (((uint64_t)(self->private_impl.f_frame_rect_x1)) * v_dst_bytes_per_pixel);
66954 v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024));
66955 v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
66956 v_src_bytes_per_pixel = 1u;
66957 if (self->private_impl.f_depth >= 8u) {
66958 v_src_bytes_per_pixel = (((uint64_t)(WUFFS_PNG__NUM_CHANNELS[self->private_impl.f_color_type])) * ((uint64_t)(((uint8_t)(self->private_impl.f_depth >> 3u)))));
66960 if (self->private_impl.f_chunk_type_array[0u] == 73u) {
66961 v_y = ((uint32_t)(WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][5u]));
66962 } else {
66963 v_y = self->private_impl.f_frame_rect_y0;
66965 while (v_y < self->private_impl.f_frame_rect_y1) {
66966 v_dst = wuffs_private_impl__table_u8__row_u32(v_tab, v_y);
66967 if (v_dst_bytes_per_row1 < ((uint64_t)(v_dst.len))) {
66968 v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row1);
66970 if (1u > ((uint64_t)(a_workbuf.len))) {
66971 return wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_workbuf_length);
66973 v_filter = a_workbuf.ptr[0u];
66974 a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, 1u);
66975 if (self->private_impl.f_pass_bytes_per_row > ((uint64_t)(a_workbuf.len))) {
66976 return wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_workbuf_length);
66978 v_curr_row = wuffs_base__slice_u8__subslice_j(a_workbuf, self->private_impl.f_pass_bytes_per_row);
66979 a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, self->private_impl.f_pass_bytes_per_row);
66980 if (v_filter == 0u) {
66981 } else if (v_filter == 1u) {
66982 wuffs_png__decoder__filter_1(self, v_curr_row);
66983 } else if (v_filter == 2u) {
66984 wuffs_png__decoder__filter_2(self, v_curr_row, v_prev_row);
66985 } else if (v_filter == 3u) {
66986 wuffs_png__decoder__filter_3(self, v_curr_row, v_prev_row);
66987 } else if (v_filter == 4u) {
66988 wuffs_png__decoder__filter_4(self, v_curr_row, v_prev_row);
66989 } else {
66990 return wuffs_base__make_status(wuffs_png__error__bad_filter);
66992 v_s = v_curr_row;
66993 if (self->private_impl.f_chunk_type_array[0u] == 73u) {
66994 v_x = ((uint32_t)(WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][2u]));
66995 } else {
66996 v_x = self->private_impl.f_frame_rect_x0;
66998 if (self->private_impl.f_depth == 8u) {
66999 while (v_x < self->private_impl.f_frame_rect_x1) {
67000 v_i = (((uint64_t)(v_x)) * v_dst_bytes_per_pixel);
67001 if (v_i <= ((uint64_t)(v_dst.len))) {
67002 if (((uint32_t)(self->private_impl.f_remap_transparency)) != 0u) {
67003 if (self->private_impl.f_color_type == 0u) {
67004 if (1u <= ((uint64_t)(v_s.len))) {
67005 v_bits_unpacked[0u] = v_s.ptr[0u];
67006 v_bits_unpacked[1u] = v_s.ptr[0u];
67007 v_bits_unpacked[2u] = v_s.ptr[0u];
67008 v_bits_unpacked[3u] = 255u;
67009 v_s = wuffs_base__slice_u8__subslice_i(v_s, 1u);
67010 if (((uint32_t)(self->private_impl.f_remap_transparency)) == ((((uint32_t)(v_bits_unpacked[0u])) << 0u) |
67011 (((uint32_t)(v_bits_unpacked[1u])) << 8u) |
67012 (((uint32_t)(v_bits_unpacked[2u])) << 16u) |
67013 (((uint32_t)(v_bits_unpacked[3u])) << 24u))) {
67014 v_bits_unpacked[0u] = 0u;
67015 v_bits_unpacked[1u] = 0u;
67016 v_bits_unpacked[2u] = 0u;
67017 v_bits_unpacked[3u] = 0u;
67019 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));
67021 } else {
67022 if (3u <= ((uint64_t)(v_s.len))) {
67023 v_bits_unpacked[0u] = v_s.ptr[2u];
67024 v_bits_unpacked[1u] = v_s.ptr[1u];
67025 v_bits_unpacked[2u] = v_s.ptr[0u];
67026 v_bits_unpacked[3u] = 255u;
67027 v_s = wuffs_base__slice_u8__subslice_i(v_s, 3u);
67028 if (((uint32_t)(self->private_impl.f_remap_transparency)) == ((((uint32_t)(v_bits_unpacked[0u])) << 0u) |
67029 (((uint32_t)(v_bits_unpacked[1u])) << 8u) |
67030 (((uint32_t)(v_bits_unpacked[2u])) << 16u) |
67031 (((uint32_t)(v_bits_unpacked[3u])) << 24u))) {
67032 v_bits_unpacked[0u] = 0u;
67033 v_bits_unpacked[1u] = 0u;
67034 v_bits_unpacked[2u] = 0u;
67035 v_bits_unpacked[3u] = 0u;
67037 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));
67040 } else if (v_src_bytes_per_pixel <= ((uint64_t)(v_s.len))) {
67041 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));
67042 v_s = wuffs_base__slice_u8__subslice_i(v_s, v_src_bytes_per_pixel);
67045 v_x += (((uint32_t)(1u)) << WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][0u]);
67047 } else if (self->private_impl.f_depth < 8u) {
67048 v_multiplier = 1u;
67049 if (self->private_impl.f_color_type == 0u) {
67050 v_multiplier = WUFFS_PNG__LOW_BIT_DEPTH_MULTIPLIERS[self->private_impl.f_depth];
67052 v_shift = ((uint8_t)(((uint8_t)(8u - self->private_impl.f_depth)) & 7u));
67053 v_packs_remaining = 0u;
67054 while (v_x < self->private_impl.f_frame_rect_x1) {
67055 v_i = (((uint64_t)(v_x)) * v_dst_bytes_per_pixel);
67056 if (v_i <= ((uint64_t)(v_dst.len))) {
67057 if ((v_packs_remaining == 0u) && (1u <= ((uint64_t)(v_s.len)))) {
67058 v_packs_remaining = WUFFS_PNG__LOW_BIT_DEPTH_NUM_PACKS[self->private_impl.f_depth];
67059 v_bits_packed = v_s.ptr[0u];
67060 v_s = wuffs_base__slice_u8__subslice_i(v_s, 1u);
67062 v_bits_unpacked[0u] = ((uint8_t)(((uint8_t)(v_bits_packed >> v_shift)) * v_multiplier));
67063 v_bits_packed = ((uint8_t)(v_bits_packed << self->private_impl.f_depth));
67064 v_packs_remaining = ((uint8_t)(v_packs_remaining - 1u));
67065 if (((uint32_t)(self->private_impl.f_remap_transparency)) != 0u) {
67066 v_bits_unpacked[1u] = v_bits_unpacked[0u];
67067 v_bits_unpacked[2u] = v_bits_unpacked[0u];
67068 v_bits_unpacked[3u] = 255u;
67069 if (((uint32_t)(self->private_impl.f_remap_transparency)) == ((((uint32_t)(v_bits_unpacked[0u])) << 0u) |
67070 (((uint32_t)(v_bits_unpacked[1u])) << 8u) |
67071 (((uint32_t)(v_bits_unpacked[2u])) << 16u) |
67072 (((uint32_t)(v_bits_unpacked[3u])) << 24u))) {
67073 v_bits_unpacked[0u] = 0u;
67074 v_bits_unpacked[1u] = 0u;
67075 v_bits_unpacked[2u] = 0u;
67076 v_bits_unpacked[3u] = 0u;
67078 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));
67079 } else {
67080 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));
67083 v_x += (((uint32_t)(1u)) << WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][0u]);
67085 } else {
67086 while (v_x < self->private_impl.f_frame_rect_x1) {
67087 v_i = (((uint64_t)(v_x)) * v_dst_bytes_per_pixel);
67088 if (v_i <= ((uint64_t)(v_dst.len))) {
67089 if (self->private_impl.f_color_type == 0u) {
67090 if (2u <= ((uint64_t)(v_s.len))) {
67091 v_bits_unpacked[0u] = v_s.ptr[1u];
67092 v_bits_unpacked[1u] = v_s.ptr[0u];
67093 v_bits_unpacked[2u] = v_s.ptr[1u];
67094 v_bits_unpacked[3u] = v_s.ptr[0u];
67095 v_bits_unpacked[4u] = v_s.ptr[1u];
67096 v_bits_unpacked[5u] = v_s.ptr[0u];
67097 v_bits_unpacked[6u] = 255u;
67098 v_bits_unpacked[7u] = 255u;
67099 v_s = wuffs_base__slice_u8__subslice_i(v_s, 2u);
67100 if (self->private_impl.f_remap_transparency == ((((uint64_t)(v_bits_unpacked[0u])) << 0u) |
67101 (((uint64_t)(v_bits_unpacked[1u])) << 8u) |
67102 (((uint64_t)(v_bits_unpacked[2u])) << 16u) |
67103 (((uint64_t)(v_bits_unpacked[3u])) << 24u) |
67104 (((uint64_t)(v_bits_unpacked[4u])) << 32u) |
67105 (((uint64_t)(v_bits_unpacked[5u])) << 40u) |
67106 (((uint64_t)(v_bits_unpacked[6u])) << 48u) |
67107 (((uint64_t)(v_bits_unpacked[7u])) << 56u))) {
67108 v_bits_unpacked[0u] = 0u;
67109 v_bits_unpacked[1u] = 0u;
67110 v_bits_unpacked[2u] = 0u;
67111 v_bits_unpacked[3u] = 0u;
67112 v_bits_unpacked[4u] = 0u;
67113 v_bits_unpacked[5u] = 0u;
67114 v_bits_unpacked[6u] = 0u;
67115 v_bits_unpacked[7u] = 0u;
67118 } else if (self->private_impl.f_color_type == 2u) {
67119 if (6u <= ((uint64_t)(v_s.len))) {
67120 v_bits_unpacked[0u] = v_s.ptr[5u];
67121 v_bits_unpacked[1u] = v_s.ptr[4u];
67122 v_bits_unpacked[2u] = v_s.ptr[3u];
67123 v_bits_unpacked[3u] = v_s.ptr[2u];
67124 v_bits_unpacked[4u] = v_s.ptr[1u];
67125 v_bits_unpacked[5u] = v_s.ptr[0u];
67126 v_bits_unpacked[6u] = 255u;
67127 v_bits_unpacked[7u] = 255u;
67128 v_s = wuffs_base__slice_u8__subslice_i(v_s, 6u);
67129 if (self->private_impl.f_remap_transparency == ((((uint64_t)(v_bits_unpacked[0u])) << 0u) |
67130 (((uint64_t)(v_bits_unpacked[1u])) << 8u) |
67131 (((uint64_t)(v_bits_unpacked[2u])) << 16u) |
67132 (((uint64_t)(v_bits_unpacked[3u])) << 24u) |
67133 (((uint64_t)(v_bits_unpacked[4u])) << 32u) |
67134 (((uint64_t)(v_bits_unpacked[5u])) << 40u) |
67135 (((uint64_t)(v_bits_unpacked[6u])) << 48u) |
67136 (((uint64_t)(v_bits_unpacked[7u])) << 56u))) {
67137 v_bits_unpacked[0u] = 0u;
67138 v_bits_unpacked[1u] = 0u;
67139 v_bits_unpacked[2u] = 0u;
67140 v_bits_unpacked[3u] = 0u;
67141 v_bits_unpacked[4u] = 0u;
67142 v_bits_unpacked[5u] = 0u;
67143 v_bits_unpacked[6u] = 0u;
67144 v_bits_unpacked[7u] = 0u;
67147 } else if (self->private_impl.f_color_type == 4u) {
67148 if (4u <= ((uint64_t)(v_s.len))) {
67149 v_bits_unpacked[0u] = v_s.ptr[1u];
67150 v_bits_unpacked[1u] = v_s.ptr[0u];
67151 v_bits_unpacked[2u] = v_s.ptr[1u];
67152 v_bits_unpacked[3u] = v_s.ptr[0u];
67153 v_bits_unpacked[4u] = v_s.ptr[1u];
67154 v_bits_unpacked[5u] = v_s.ptr[0u];
67155 v_bits_unpacked[6u] = v_s.ptr[3u];
67156 v_bits_unpacked[7u] = v_s.ptr[2u];
67157 v_s = wuffs_base__slice_u8__subslice_i(v_s, 4u);
67159 } else {
67160 if (8u <= ((uint64_t)(v_s.len))) {
67161 v_bits_unpacked[0u] = v_s.ptr[5u];
67162 v_bits_unpacked[1u] = v_s.ptr[4u];
67163 v_bits_unpacked[2u] = v_s.ptr[3u];
67164 v_bits_unpacked[3u] = v_s.ptr[2u];
67165 v_bits_unpacked[4u] = v_s.ptr[1u];
67166 v_bits_unpacked[5u] = v_s.ptr[0u];
67167 v_bits_unpacked[6u] = v_s.ptr[7u];
67168 v_bits_unpacked[7u] = v_s.ptr[6u];
67169 v_s = wuffs_base__slice_u8__subslice_i(v_s, 8u);
67172 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));
67174 v_x += (((uint32_t)(1u)) << WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][0u]);
67177 v_prev_row = v_curr_row;
67178 v_y += (((uint32_t)(1u)) << WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][3u]);
67180 return wuffs_base__make_status(NULL);
67183 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__PNG)
67185 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__QOI)
67187 // ---------------- Status Codes Implementations
67189 const char wuffs_qoi__error__bad_footer[] = "#qoi: bad footer";
67190 const char wuffs_qoi__error__bad_header[] = "#qoi: bad header";
67191 const char wuffs_qoi__error__truncated_input[] = "#qoi: truncated input";
67193 // ---------------- Private Consts
67195 // ---------------- Private Initializer Prototypes
67197 // ---------------- Private Function Prototypes
67199 WUFFS_BASE__GENERATED_C_CODE
67200 static wuffs_base__status
67201 wuffs_qoi__decoder__do_decode_image_config(
67202 wuffs_qoi__decoder* self,
67203 wuffs_base__image_config* a_dst,
67204 wuffs_base__io_buffer* a_src);
67206 WUFFS_BASE__GENERATED_C_CODE
67207 static wuffs_base__status
67208 wuffs_qoi__decoder__do_decode_frame_config(
67209 wuffs_qoi__decoder* self,
67210 wuffs_base__frame_config* a_dst,
67211 wuffs_base__io_buffer* a_src);
67213 WUFFS_BASE__GENERATED_C_CODE
67214 static wuffs_base__status
67215 wuffs_qoi__decoder__do_decode_frame(
67216 wuffs_qoi__decoder* self,
67217 wuffs_base__pixel_buffer* a_dst,
67218 wuffs_base__io_buffer* a_src,
67219 wuffs_base__pixel_blend a_blend,
67220 wuffs_base__slice_u8 a_workbuf,
67221 wuffs_base__decode_frame_options* a_opts);
67223 WUFFS_BASE__GENERATED_C_CODE
67224 static wuffs_base__status
67225 wuffs_qoi__decoder__from_src_to_buffer(
67226 wuffs_qoi__decoder* self,
67227 wuffs_base__io_buffer* a_src);
67229 WUFFS_BASE__GENERATED_C_CODE
67230 static wuffs_base__status
67231 wuffs_qoi__decoder__from_buffer_to_dst(
67232 wuffs_qoi__decoder* self,
67233 wuffs_base__pixel_buffer* a_dst);
67235 // ---------------- VTables
67237 const wuffs_base__image_decoder__func_ptrs
67238 wuffs_qoi__decoder__func_ptrs_for__wuffs_base__image_decoder = {
67239 (wuffs_base__status(*)(void*,
67240 wuffs_base__pixel_buffer*,
67241 wuffs_base__io_buffer*,
67242 wuffs_base__pixel_blend,
67243 wuffs_base__slice_u8,
67244 wuffs_base__decode_frame_options*))(&wuffs_qoi__decoder__decode_frame),
67245 (wuffs_base__status(*)(void*,
67246 wuffs_base__frame_config*,
67247 wuffs_base__io_buffer*))(&wuffs_qoi__decoder__decode_frame_config),
67248 (wuffs_base__status(*)(void*,
67249 wuffs_base__image_config*,
67250 wuffs_base__io_buffer*))(&wuffs_qoi__decoder__decode_image_config),
67251 (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_qoi__decoder__frame_dirty_rect),
67252 (uint64_t(*)(const void*,
67253 uint32_t))(&wuffs_qoi__decoder__get_quirk),
67254 (uint32_t(*)(const void*))(&wuffs_qoi__decoder__num_animation_loops),
67255 (uint64_t(*)(const void*))(&wuffs_qoi__decoder__num_decoded_frame_configs),
67256 (uint64_t(*)(const void*))(&wuffs_qoi__decoder__num_decoded_frames),
67257 (wuffs_base__status(*)(void*,
67258 uint64_t,
67259 uint64_t))(&wuffs_qoi__decoder__restart_frame),
67260 (wuffs_base__status(*)(void*,
67261 uint32_t,
67262 uint64_t))(&wuffs_qoi__decoder__set_quirk),
67263 (wuffs_base__empty_struct(*)(void*,
67264 uint32_t,
67265 bool))(&wuffs_qoi__decoder__set_report_metadata),
67266 (wuffs_base__status(*)(void*,
67267 wuffs_base__io_buffer*,
67268 wuffs_base__more_information*,
67269 wuffs_base__io_buffer*))(&wuffs_qoi__decoder__tell_me_more),
67270 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_qoi__decoder__workbuf_len),
67273 // ---------------- Initializer Implementations
67275 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
67276 wuffs_qoi__decoder__initialize(
67277 wuffs_qoi__decoder* self,
67278 size_t sizeof_star_self,
67279 uint64_t wuffs_version,
67280 uint32_t options){
67281 if (!self) {
67282 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
67284 if (sizeof(*self) != sizeof_star_self) {
67285 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
67287 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
67288 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
67289 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
67292 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
67293 // The whole point of this if-check is to detect an uninitialized *self.
67294 // We disable the warning on GCC. Clang-5.0 does not have this warning.
67295 #if !defined(__clang__) && defined(__GNUC__)
67296 #pragma GCC diagnostic push
67297 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
67298 #endif
67299 if (self->private_impl.magic != 0) {
67300 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
67302 #if !defined(__clang__) && defined(__GNUC__)
67303 #pragma GCC diagnostic pop
67304 #endif
67305 } else {
67306 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
67307 memset(self, 0, sizeof(*self));
67308 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
67309 } else {
67310 memset(&(self->private_impl), 0, sizeof(self->private_impl));
67314 self->private_impl.magic = WUFFS_BASE__MAGIC;
67315 self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
67316 wuffs_base__image_decoder__vtable_name;
67317 self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
67318 (const void*)(&wuffs_qoi__decoder__func_ptrs_for__wuffs_base__image_decoder);
67319 return wuffs_base__make_status(NULL);
67322 wuffs_qoi__decoder*
67323 wuffs_qoi__decoder__alloc(void) {
67324 wuffs_qoi__decoder* x =
67325 (wuffs_qoi__decoder*)(calloc(1, sizeof(wuffs_qoi__decoder)));
67326 if (!x) {
67327 return NULL;
67329 if (wuffs_qoi__decoder__initialize(
67330 x, sizeof(wuffs_qoi__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
67331 free(x);
67332 return NULL;
67334 return x;
67337 size_t
67338 sizeof__wuffs_qoi__decoder(void) {
67339 return sizeof(wuffs_qoi__decoder);
67342 // ---------------- Function Implementations
67344 // -------- func qoi.decoder.get_quirk
67346 WUFFS_BASE__GENERATED_C_CODE
67347 WUFFS_BASE__MAYBE_STATIC uint64_t
67348 wuffs_qoi__decoder__get_quirk(
67349 const wuffs_qoi__decoder* self,
67350 uint32_t a_key) {
67351 if (!self) {
67352 return 0;
67354 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
67355 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
67356 return 0;
67359 return 0u;
67362 // -------- func qoi.decoder.set_quirk
67364 WUFFS_BASE__GENERATED_C_CODE
67365 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
67366 wuffs_qoi__decoder__set_quirk(
67367 wuffs_qoi__decoder* self,
67368 uint32_t a_key,
67369 uint64_t a_value) {
67370 if (!self) {
67371 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
67373 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
67374 return wuffs_base__make_status(
67375 (self->private_impl.magic == WUFFS_BASE__DISABLED)
67376 ? wuffs_base__error__disabled_by_previous_error
67377 : wuffs_base__error__initialize_not_called);
67380 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
67383 // -------- func qoi.decoder.decode_image_config
67385 WUFFS_BASE__GENERATED_C_CODE
67386 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
67387 wuffs_qoi__decoder__decode_image_config(
67388 wuffs_qoi__decoder* self,
67389 wuffs_base__image_config* a_dst,
67390 wuffs_base__io_buffer* a_src) {
67391 if (!self) {
67392 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
67394 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
67395 return wuffs_base__make_status(
67396 (self->private_impl.magic == WUFFS_BASE__DISABLED)
67397 ? wuffs_base__error__disabled_by_previous_error
67398 : wuffs_base__error__initialize_not_called);
67400 if (!a_src) {
67401 self->private_impl.magic = WUFFS_BASE__DISABLED;
67402 return wuffs_base__make_status(wuffs_base__error__bad_argument);
67404 if ((self->private_impl.active_coroutine != 0) &&
67405 (self->private_impl.active_coroutine != 1)) {
67406 self->private_impl.magic = WUFFS_BASE__DISABLED;
67407 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
67409 self->private_impl.active_coroutine = 0;
67410 wuffs_base__status status = wuffs_base__make_status(NULL);
67412 wuffs_base__status v_status = wuffs_base__make_status(NULL);
67414 uint32_t coro_susp_point = self->private_impl.p_decode_image_config;
67415 switch (coro_susp_point) {
67416 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
67418 while (true) {
67420 wuffs_base__status t_0 = wuffs_qoi__decoder__do_decode_image_config(self, a_dst, a_src);
67421 v_status = t_0;
67423 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
67424 status = wuffs_base__make_status(wuffs_qoi__error__truncated_input);
67425 goto exit;
67427 status = v_status;
67428 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
67432 self->private_impl.p_decode_image_config = 0;
67433 goto exit;
67436 goto suspend;
67437 suspend:
67438 self->private_impl.p_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
67439 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
67441 goto exit;
67442 exit:
67443 if (wuffs_base__status__is_error(&status)) {
67444 self->private_impl.magic = WUFFS_BASE__DISABLED;
67446 return status;
67449 // -------- func qoi.decoder.do_decode_image_config
67451 WUFFS_BASE__GENERATED_C_CODE
67452 static wuffs_base__status
67453 wuffs_qoi__decoder__do_decode_image_config(
67454 wuffs_qoi__decoder* self,
67455 wuffs_base__image_config* a_dst,
67456 wuffs_base__io_buffer* a_src) {
67457 wuffs_base__status status = wuffs_base__make_status(NULL);
67459 uint32_t v_a = 0;
67461 const uint8_t* iop_a_src = NULL;
67462 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
67463 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
67464 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
67465 if (a_src && a_src->data.ptr) {
67466 io0_a_src = a_src->data.ptr;
67467 io1_a_src = io0_a_src + a_src->meta.ri;
67468 iop_a_src = io1_a_src;
67469 io2_a_src = io0_a_src + a_src->meta.wi;
67472 uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config;
67473 switch (coro_susp_point) {
67474 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
67476 if (self->private_impl.f_call_sequence != 0u) {
67477 status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
67478 goto exit;
67481 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
67482 uint32_t t_0;
67483 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
67484 t_0 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
67485 iop_a_src += 4;
67486 } else {
67487 self->private_data.s_do_decode_image_config.scratch = 0;
67488 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
67489 while (true) {
67490 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
67491 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
67492 goto suspend;
67494 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
67495 uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
67496 *scratch <<= 8;
67497 *scratch >>= 8;
67498 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
67499 if (num_bits_0 == 24) {
67500 t_0 = ((uint32_t)(*scratch));
67501 break;
67503 num_bits_0 += 8u;
67504 *scratch |= ((uint64_t)(num_bits_0)) << 56;
67507 v_a = t_0;
67509 if (v_a != 1718185841u) {
67510 status = wuffs_base__make_status(wuffs_qoi__error__bad_header);
67511 goto exit;
67514 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
67515 uint32_t t_1;
67516 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
67517 t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
67518 iop_a_src += 4;
67519 } else {
67520 self->private_data.s_do_decode_image_config.scratch = 0;
67521 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
67522 while (true) {
67523 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
67524 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
67525 goto suspend;
67527 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
67528 uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu));
67529 *scratch >>= 8;
67530 *scratch <<= 8;
67531 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
67532 if (num_bits_1 == 24) {
67533 t_1 = ((uint32_t)(*scratch >> 32));
67534 break;
67536 num_bits_1 += 8u;
67537 *scratch |= ((uint64_t)(num_bits_1));
67540 v_a = t_1;
67542 if (v_a > 16777215u) {
67543 status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension);
67544 goto exit;
67546 self->private_impl.f_width = v_a;
67548 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
67549 uint32_t t_2;
67550 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
67551 t_2 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
67552 iop_a_src += 4;
67553 } else {
67554 self->private_data.s_do_decode_image_config.scratch = 0;
67555 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
67556 while (true) {
67557 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
67558 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
67559 goto suspend;
67561 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
67562 uint32_t num_bits_2 = ((uint32_t)(*scratch & 0xFFu));
67563 *scratch >>= 8;
67564 *scratch <<= 8;
67565 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_2);
67566 if (num_bits_2 == 24) {
67567 t_2 = ((uint32_t)(*scratch >> 32));
67568 break;
67570 num_bits_2 += 8u;
67571 *scratch |= ((uint64_t)(num_bits_2));
67574 v_a = t_2;
67576 if (v_a > 16777215u) {
67577 status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension);
67578 goto exit;
67580 self->private_impl.f_height = v_a;
67582 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
67583 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
67584 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
67585 goto suspend;
67587 uint32_t t_3 = *iop_a_src++;
67588 v_a = t_3;
67590 if (v_a == 3u) {
67591 self->private_impl.f_pixfmt = 2415954056u;
67592 } else if (v_a == 4u) {
67593 self->private_impl.f_pixfmt = 2164295816u;
67594 } else {
67595 status = wuffs_base__make_status(wuffs_qoi__error__bad_header);
67596 goto exit;
67598 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
67599 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
67600 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
67601 goto suspend;
67603 iop_a_src++;
67604 if (a_dst != NULL) {
67605 wuffs_base__image_config__set(
67606 a_dst,
67607 self->private_impl.f_pixfmt,
67609 self->private_impl.f_width,
67610 self->private_impl.f_height,
67611 14u,
67612 (self->private_impl.f_pixfmt == 2415954056u));
67614 self->private_impl.f_call_sequence = 32u;
67616 goto ok;
67618 self->private_impl.p_do_decode_image_config = 0;
67619 goto exit;
67622 goto suspend;
67623 suspend:
67624 self->private_impl.p_do_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
67626 goto exit;
67627 exit:
67628 if (a_src && a_src->data.ptr) {
67629 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
67632 return status;
67635 // -------- func qoi.decoder.decode_frame_config
67637 WUFFS_BASE__GENERATED_C_CODE
67638 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
67639 wuffs_qoi__decoder__decode_frame_config(
67640 wuffs_qoi__decoder* self,
67641 wuffs_base__frame_config* a_dst,
67642 wuffs_base__io_buffer* a_src) {
67643 if (!self) {
67644 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
67646 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
67647 return wuffs_base__make_status(
67648 (self->private_impl.magic == WUFFS_BASE__DISABLED)
67649 ? wuffs_base__error__disabled_by_previous_error
67650 : wuffs_base__error__initialize_not_called);
67652 if (!a_src) {
67653 self->private_impl.magic = WUFFS_BASE__DISABLED;
67654 return wuffs_base__make_status(wuffs_base__error__bad_argument);
67656 if ((self->private_impl.active_coroutine != 0) &&
67657 (self->private_impl.active_coroutine != 2)) {
67658 self->private_impl.magic = WUFFS_BASE__DISABLED;
67659 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
67661 self->private_impl.active_coroutine = 0;
67662 wuffs_base__status status = wuffs_base__make_status(NULL);
67664 wuffs_base__status v_status = wuffs_base__make_status(NULL);
67666 uint32_t coro_susp_point = self->private_impl.p_decode_frame_config;
67667 switch (coro_susp_point) {
67668 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
67670 while (true) {
67672 wuffs_base__status t_0 = wuffs_qoi__decoder__do_decode_frame_config(self, a_dst, a_src);
67673 v_status = t_0;
67675 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
67676 status = wuffs_base__make_status(wuffs_qoi__error__truncated_input);
67677 goto exit;
67679 status = v_status;
67680 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
67684 self->private_impl.p_decode_frame_config = 0;
67685 goto exit;
67688 goto suspend;
67689 suspend:
67690 self->private_impl.p_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
67691 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
67693 goto exit;
67694 exit:
67695 if (wuffs_base__status__is_error(&status)) {
67696 self->private_impl.magic = WUFFS_BASE__DISABLED;
67698 return status;
67701 // -------- func qoi.decoder.do_decode_frame_config
67703 WUFFS_BASE__GENERATED_C_CODE
67704 static wuffs_base__status
67705 wuffs_qoi__decoder__do_decode_frame_config(
67706 wuffs_qoi__decoder* self,
67707 wuffs_base__frame_config* a_dst,
67708 wuffs_base__io_buffer* a_src) {
67709 wuffs_base__status status = wuffs_base__make_status(NULL);
67711 const uint8_t* iop_a_src = NULL;
67712 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
67713 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
67714 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
67715 if (a_src && a_src->data.ptr) {
67716 io0_a_src = a_src->data.ptr;
67717 io1_a_src = io0_a_src + a_src->meta.ri;
67718 iop_a_src = io1_a_src;
67719 io2_a_src = io0_a_src + a_src->meta.wi;
67722 uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config;
67723 switch (coro_susp_point) {
67724 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
67726 if (self->private_impl.f_call_sequence == 32u) {
67727 } else if (self->private_impl.f_call_sequence < 32u) {
67728 if (a_src) {
67729 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
67731 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
67732 status = wuffs_qoi__decoder__do_decode_image_config(self, NULL, a_src);
67733 if (a_src) {
67734 iop_a_src = a_src->data.ptr + a_src->meta.ri;
67736 if (status.repr) {
67737 goto suspend;
67739 } else if (self->private_impl.f_call_sequence == 40u) {
67740 if (16u != wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)))) {
67741 status = wuffs_base__make_status(wuffs_base__error__bad_restart);
67742 goto exit;
67744 } else if (self->private_impl.f_call_sequence == 64u) {
67745 self->private_impl.f_call_sequence = 96u;
67746 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
67747 goto ok;
67748 } else {
67749 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
67750 goto ok;
67752 if (a_dst != NULL) {
67753 wuffs_base__frame_config__set(
67754 a_dst,
67755 wuffs_base__utility__make_rect_ie_u32(
67758 self->private_impl.f_width,
67759 self->private_impl.f_height),
67760 ((wuffs_base__flicks)(0u)),
67762 14u,
67764 (self->private_impl.f_pixfmt == 2415954056u),
67765 false,
67766 0u);
67768 self->private_impl.f_call_sequence = 64u;
67771 self->private_impl.p_do_decode_frame_config = 0;
67772 goto exit;
67775 goto suspend;
67776 suspend:
67777 self->private_impl.p_do_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
67779 goto exit;
67780 exit:
67781 if (a_src && a_src->data.ptr) {
67782 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
67785 return status;
67788 // -------- func qoi.decoder.decode_frame
67790 WUFFS_BASE__GENERATED_C_CODE
67791 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
67792 wuffs_qoi__decoder__decode_frame(
67793 wuffs_qoi__decoder* self,
67794 wuffs_base__pixel_buffer* a_dst,
67795 wuffs_base__io_buffer* a_src,
67796 wuffs_base__pixel_blend a_blend,
67797 wuffs_base__slice_u8 a_workbuf,
67798 wuffs_base__decode_frame_options* a_opts) {
67799 if (!self) {
67800 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
67802 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
67803 return wuffs_base__make_status(
67804 (self->private_impl.magic == WUFFS_BASE__DISABLED)
67805 ? wuffs_base__error__disabled_by_previous_error
67806 : wuffs_base__error__initialize_not_called);
67808 if (!a_dst || !a_src) {
67809 self->private_impl.magic = WUFFS_BASE__DISABLED;
67810 return wuffs_base__make_status(wuffs_base__error__bad_argument);
67812 if ((self->private_impl.active_coroutine != 0) &&
67813 (self->private_impl.active_coroutine != 3)) {
67814 self->private_impl.magic = WUFFS_BASE__DISABLED;
67815 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
67817 self->private_impl.active_coroutine = 0;
67818 wuffs_base__status status = wuffs_base__make_status(NULL);
67820 wuffs_base__status v_status = wuffs_base__make_status(NULL);
67822 uint32_t coro_susp_point = self->private_impl.p_decode_frame;
67823 switch (coro_susp_point) {
67824 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
67826 while (true) {
67828 wuffs_base__status t_0 = wuffs_qoi__decoder__do_decode_frame(self,
67829 a_dst,
67830 a_src,
67831 a_blend,
67832 a_workbuf,
67833 a_opts);
67834 v_status = t_0;
67836 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
67837 status = wuffs_base__make_status(wuffs_qoi__error__truncated_input);
67838 goto exit;
67840 status = v_status;
67841 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
67845 self->private_impl.p_decode_frame = 0;
67846 goto exit;
67849 goto suspend;
67850 suspend:
67851 self->private_impl.p_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
67852 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
67854 goto exit;
67855 exit:
67856 if (wuffs_base__status__is_error(&status)) {
67857 self->private_impl.magic = WUFFS_BASE__DISABLED;
67859 return status;
67862 // -------- func qoi.decoder.do_decode_frame
67864 WUFFS_BASE__GENERATED_C_CODE
67865 static wuffs_base__status
67866 wuffs_qoi__decoder__do_decode_frame(
67867 wuffs_qoi__decoder* self,
67868 wuffs_base__pixel_buffer* a_dst,
67869 wuffs_base__io_buffer* a_src,
67870 wuffs_base__pixel_blend a_blend,
67871 wuffs_base__slice_u8 a_workbuf,
67872 wuffs_base__decode_frame_options* a_opts) {
67873 wuffs_base__status status = wuffs_base__make_status(NULL);
67875 wuffs_base__status v_status = wuffs_base__make_status(NULL);
67876 uint64_t v_c64 = 0;
67878 const uint8_t* iop_a_src = NULL;
67879 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
67880 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
67881 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
67882 if (a_src && a_src->data.ptr) {
67883 io0_a_src = a_src->data.ptr;
67884 io1_a_src = io0_a_src + a_src->meta.ri;
67885 iop_a_src = io1_a_src;
67886 io2_a_src = io0_a_src + a_src->meta.wi;
67889 uint32_t coro_susp_point = self->private_impl.p_do_decode_frame;
67890 switch (coro_susp_point) {
67891 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
67893 if (self->private_impl.f_call_sequence == 64u) {
67894 } else if (self->private_impl.f_call_sequence < 64u) {
67895 if (a_src) {
67896 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
67898 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
67899 status = wuffs_qoi__decoder__do_decode_frame_config(self, NULL, a_src);
67900 if (a_src) {
67901 iop_a_src = a_src->data.ptr + a_src->meta.ri;
67903 if (status.repr) {
67904 goto suspend;
67906 } else {
67907 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
67908 goto ok;
67910 v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
67911 wuffs_base__pixel_buffer__pixel_format(a_dst),
67912 wuffs_base__pixel_buffer__palette(a_dst),
67913 wuffs_base__utility__make_pixel_format(self->private_impl.f_pixfmt),
67914 wuffs_base__utility__empty_slice_u8(),
67915 a_blend);
67916 if ( ! wuffs_base__status__is_ok(&v_status)) {
67917 status = v_status;
67918 if (wuffs_base__status__is_error(&status)) {
67919 goto exit;
67920 } else if (wuffs_base__status__is_suspension(&status)) {
67921 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
67922 goto exit;
67924 goto ok;
67926 self->private_impl.f_dst_x = 0u;
67927 self->private_impl.f_dst_y = 0u;
67928 self->private_data.f_pixel[0u] = 0u;
67929 self->private_data.f_pixel[1u] = 0u;
67930 self->private_data.f_pixel[2u] = 0u;
67931 self->private_data.f_pixel[3u] = 255u;
67932 wuffs_private_impl__bulk_memset(&self->private_data.f_cache[0], 256u, 0u);
67933 self->private_impl.f_remaining_pixels_times_4 = (((uint64_t)(self->private_impl.f_width)) * ((uint64_t)(self->private_impl.f_height)) * 4u);
67934 while (self->private_impl.f_remaining_pixels_times_4 > 0u) {
67935 if (a_src) {
67936 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
67938 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
67939 status = wuffs_qoi__decoder__from_src_to_buffer(self, a_src);
67940 if (a_src) {
67941 iop_a_src = a_src->data.ptr + a_src->meta.ri;
67943 if (status.repr) {
67944 goto suspend;
67946 if (self->private_impl.f_remaining_pixels_times_4 < ((uint64_t)(self->private_impl.f_buffer_index))) {
67947 status = wuffs_base__make_status(wuffs_base__error__too_much_data);
67948 goto exit;
67950 self->private_impl.f_remaining_pixels_times_4 -= ((uint64_t)(self->private_impl.f_buffer_index));
67951 v_status = wuffs_qoi__decoder__from_buffer_to_dst(self, a_dst);
67952 if ( ! wuffs_base__status__is_ok(&v_status)) {
67953 status = v_status;
67954 if (wuffs_base__status__is_error(&status)) {
67955 goto exit;
67956 } else if (wuffs_base__status__is_suspension(&status)) {
67957 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
67958 goto exit;
67960 goto ok;
67964 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
67965 uint64_t t_0;
67966 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 8)) {
67967 t_0 = wuffs_base__peek_u64be__no_bounds_check(iop_a_src);
67968 iop_a_src += 8;
67969 } else {
67970 self->private_data.s_do_decode_frame.scratch = 0;
67971 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
67972 while (true) {
67973 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
67974 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
67975 goto suspend;
67977 uint64_t* scratch = &self->private_data.s_do_decode_frame.scratch;
67978 uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu));
67979 *scratch >>= 8;
67980 *scratch <<= 8;
67981 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
67982 if (num_bits_0 == 56) {
67983 t_0 = ((uint64_t)(*scratch >> 0));
67984 break;
67986 num_bits_0 += 8u;
67987 *scratch |= ((uint64_t)(num_bits_0));
67990 v_c64 = t_0;
67992 if (v_c64 != 1u) {
67993 status = wuffs_base__make_status(wuffs_qoi__error__bad_footer);
67994 goto exit;
67996 self->private_impl.f_call_sequence = 96u;
67999 self->private_impl.p_do_decode_frame = 0;
68000 goto exit;
68003 goto suspend;
68004 suspend:
68005 self->private_impl.p_do_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
68007 goto exit;
68008 exit:
68009 if (a_src && a_src->data.ptr) {
68010 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
68013 return status;
68016 // -------- func qoi.decoder.from_src_to_buffer
68018 WUFFS_BASE__GENERATED_C_CODE
68019 static wuffs_base__status
68020 wuffs_qoi__decoder__from_src_to_buffer(
68021 wuffs_qoi__decoder* self,
68022 wuffs_base__io_buffer* a_src) {
68023 wuffs_base__status status = wuffs_base__make_status(NULL);
68025 uint8_t v_c8 = 0;
68026 uint8_t v_dg = 0;
68027 uint32_t v_bi = 0;
68028 uint32_t v_bj = 0;
68029 uint32_t v_bk = 0;
68030 uint32_t v_ci = 0;
68031 uint32_t v_hash4 = 0;
68033 const uint8_t* iop_a_src = NULL;
68034 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
68035 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
68036 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
68037 if (a_src && a_src->data.ptr) {
68038 io0_a_src = a_src->data.ptr;
68039 io1_a_src = io0_a_src + a_src->meta.ri;
68040 iop_a_src = io1_a_src;
68041 io2_a_src = io0_a_src + a_src->meta.wi;
68044 uint32_t coro_susp_point = self->private_impl.p_from_src_to_buffer;
68045 if (coro_susp_point) {
68046 v_dg = self->private_data.s_from_src_to_buffer.v_dg;
68047 v_bi = self->private_data.s_from_src_to_buffer.v_bi;
68048 v_bk = self->private_data.s_from_src_to_buffer.v_bk;
68050 switch (coro_susp_point) {
68051 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
68053 v_bk = 7936u;
68054 if (self->private_impl.f_remaining_pixels_times_4 < 7936u) {
68055 v_bk = ((uint32_t)(self->private_impl.f_remaining_pixels_times_4));
68057 while (v_bi < v_bk) {
68059 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
68060 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
68061 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
68062 goto suspend;
68064 uint8_t t_0 = *iop_a_src++;
68065 v_c8 = t_0;
68067 if (v_c8 == 254u) {
68069 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
68070 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
68071 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
68072 goto suspend;
68074 uint8_t t_1 = *iop_a_src++;
68075 self->private_data.f_pixel[2u] = t_1;
68078 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
68079 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
68080 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
68081 goto suspend;
68083 uint8_t t_2 = *iop_a_src++;
68084 self->private_data.f_pixel[1u] = t_2;
68087 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
68088 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
68089 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
68090 goto suspend;
68092 uint8_t t_3 = *iop_a_src++;
68093 self->private_data.f_pixel[0u] = t_3;
68095 } else if (v_c8 == 255u) {
68097 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
68098 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
68099 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
68100 goto suspend;
68102 uint8_t t_4 = *iop_a_src++;
68103 self->private_data.f_pixel[2u] = t_4;
68106 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
68107 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
68108 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
68109 goto suspend;
68111 uint8_t t_5 = *iop_a_src++;
68112 self->private_data.f_pixel[1u] = t_5;
68115 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
68116 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
68117 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
68118 goto suspend;
68120 uint8_t t_6 = *iop_a_src++;
68121 self->private_data.f_pixel[0u] = t_6;
68124 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
68125 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
68126 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
68127 goto suspend;
68129 uint8_t t_7 = *iop_a_src++;
68130 self->private_data.f_pixel[3u] = t_7;
68132 } else if (((uint8_t)(v_c8 >> 6u)) == 0u) {
68133 v_ci = (4u * ((uint32_t)(((uint8_t)(v_c8 & 63u)))));
68134 self->private_data.f_pixel[0u] = self->private_data.f_cache[(v_ci + 0u)];
68135 self->private_data.f_pixel[1u] = self->private_data.f_cache[(v_ci + 1u)];
68136 self->private_data.f_pixel[2u] = self->private_data.f_cache[(v_ci + 2u)];
68137 self->private_data.f_pixel[3u] = self->private_data.f_cache[(v_ci + 3u)];
68138 self->private_data.f_buffer[(v_bi + 0u)] = self->private_data.f_pixel[0u];
68139 self->private_data.f_buffer[(v_bi + 1u)] = self->private_data.f_pixel[1u];
68140 self->private_data.f_buffer[(v_bi + 2u)] = self->private_data.f_pixel[2u];
68141 self->private_data.f_buffer[(v_bi + 3u)] = self->private_data.f_pixel[3u];
68142 v_bi += 4u;
68143 continue;
68144 } else if (((uint8_t)(v_c8 >> 6u)) == 1u) {
68145 #if defined(__GNUC__)
68146 #pragma GCC diagnostic push
68147 #pragma GCC diagnostic ignored "-Wconversion"
68148 #endif
68149 self->private_data.f_pixel[2u] += ((uint8_t)(((uint8_t)(((uint8_t)(v_c8 >> 4u)) & 3u)) + 254u));
68150 self->private_data.f_pixel[1u] += ((uint8_t)(((uint8_t)(((uint8_t)(v_c8 >> 2u)) & 3u)) + 254u));
68151 self->private_data.f_pixel[0u] += ((uint8_t)(((uint8_t)(((uint8_t)(v_c8 >> 0u)) & 3u)) + 254u));
68152 #if defined(__GNUC__)
68153 #pragma GCC diagnostic pop
68154 #endif
68155 } else if (((uint8_t)(v_c8 >> 6u)) == 2u) {
68156 v_dg = ((uint8_t)(((uint8_t)(v_c8 & 63u)) + 224u));
68158 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
68159 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
68160 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
68161 goto suspend;
68163 uint8_t t_8 = *iop_a_src++;
68164 v_c8 = t_8;
68166 #if defined(__GNUC__)
68167 #pragma GCC diagnostic push
68168 #pragma GCC diagnostic ignored "-Wconversion"
68169 #endif
68170 self->private_data.f_pixel[2u] += ((uint8_t)(((uint8_t)(v_dg + 248u)) + ((uint8_t)(15u & ((uint8_t)(v_c8 >> 4u))))));
68171 self->private_data.f_pixel[1u] += v_dg;
68172 self->private_data.f_pixel[0u] += ((uint8_t)(((uint8_t)(v_dg + 248u)) + ((uint8_t)(15u & ((uint8_t)(v_c8 >> 0u))))));
68173 #if defined(__GNUC__)
68174 #pragma GCC diagnostic pop
68175 #endif
68176 } else {
68177 v_bj = (v_bi + (4u * (63u & (1u + ((uint32_t)(v_c8))))));
68178 while (v_bi < v_bj) {
68179 self->private_data.f_buffer[(v_bi + 0u)] = self->private_data.f_pixel[0u];
68180 self->private_data.f_buffer[(v_bi + 1u)] = self->private_data.f_pixel[1u];
68181 self->private_data.f_buffer[(v_bi + 2u)] = self->private_data.f_pixel[2u];
68182 self->private_data.f_buffer[(v_bi + 3u)] = self->private_data.f_pixel[3u];
68183 v_bi += 4u;
68185 continue;
68187 v_hash4 = (4u * (63u & ((((uint32_t)(self->private_data.f_pixel[2u])) * 3u) +
68188 (((uint32_t)(self->private_data.f_pixel[1u])) * 5u) +
68189 (((uint32_t)(self->private_data.f_pixel[0u])) * 7u) +
68190 (((uint32_t)(self->private_data.f_pixel[3u])) * 11u))));
68191 self->private_data.f_cache[(v_hash4 + 0u)] = self->private_data.f_pixel[0u];
68192 self->private_data.f_cache[(v_hash4 + 1u)] = self->private_data.f_pixel[1u];
68193 self->private_data.f_cache[(v_hash4 + 2u)] = self->private_data.f_pixel[2u];
68194 self->private_data.f_cache[(v_hash4 + 3u)] = self->private_data.f_pixel[3u];
68195 self->private_data.f_buffer[(v_bi + 0u)] = self->private_data.f_pixel[0u];
68196 self->private_data.f_buffer[(v_bi + 1u)] = self->private_data.f_pixel[1u];
68197 self->private_data.f_buffer[(v_bi + 2u)] = self->private_data.f_pixel[2u];
68198 self->private_data.f_buffer[(v_bi + 3u)] = self->private_data.f_pixel[3u];
68199 v_bi += 4u;
68201 self->private_impl.f_buffer_index = v_bi;
68203 goto ok;
68205 self->private_impl.p_from_src_to_buffer = 0;
68206 goto exit;
68209 goto suspend;
68210 suspend:
68211 self->private_impl.p_from_src_to_buffer = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
68212 self->private_data.s_from_src_to_buffer.v_dg = v_dg;
68213 self->private_data.s_from_src_to_buffer.v_bi = v_bi;
68214 self->private_data.s_from_src_to_buffer.v_bk = v_bk;
68216 goto exit;
68217 exit:
68218 if (a_src && a_src->data.ptr) {
68219 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
68222 return status;
68225 // -------- func qoi.decoder.from_buffer_to_dst
68227 WUFFS_BASE__GENERATED_C_CODE
68228 static wuffs_base__status
68229 wuffs_qoi__decoder__from_buffer_to_dst(
68230 wuffs_qoi__decoder* self,
68231 wuffs_base__pixel_buffer* a_dst) {
68232 wuffs_base__pixel_format v_dst_pixfmt = {0};
68233 uint32_t v_dst_bits_per_pixel = 0;
68234 uint32_t v_dst_bytes_per_pixel = 0;
68235 uint64_t v_dst_bytes_per_row = 0;
68236 wuffs_base__table_u8 v_tab = {0};
68237 uint32_t v_bi = 0;
68238 uint32_t v_rem_x = 0;
68239 wuffs_base__slice_u8 v_dst = {0};
68240 wuffs_base__slice_u8 v_src = {0};
68241 uint32_t v_src_length = 0;
68242 uint64_t v_i = 0;
68244 v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
68245 v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
68246 if ((v_dst_bits_per_pixel & 7u) != 0u) {
68247 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
68249 v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u);
68250 v_dst_bytes_per_row = ((uint64_t)((self->private_impl.f_width * v_dst_bytes_per_pixel)));
68251 v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
68252 while (v_bi < self->private_impl.f_buffer_index) {
68253 if (self->private_impl.f_width <= self->private_impl.f_dst_x) {
68254 self->private_impl.f_dst_x = 0u;
68255 self->private_impl.f_dst_y += 1u;
68256 if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
68257 break;
68259 v_rem_x = self->private_impl.f_width;
68260 } else {
68261 v_rem_x = (self->private_impl.f_width - self->private_impl.f_dst_x);
68263 v_src = wuffs_base__make_slice_u8_ij(self->private_data.f_buffer, v_bi, self->private_impl.f_buffer_index);
68264 if (((uint64_t)((4u * v_rem_x))) < ((uint64_t)(v_src.len))) {
68265 v_src = wuffs_base__slice_u8__subslice_j(v_src, ((uint64_t)((4u * v_rem_x))));
68267 v_src_length = ((uint32_t)(((uint64_t)(v_src.len))));
68268 v_bi += v_src_length;
68269 v_dst = wuffs_private_impl__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
68270 if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) {
68271 v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row);
68273 v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_dst_bytes_per_pixel)));
68274 self->private_impl.f_dst_x += (v_src_length / 4u);
68275 if (v_i < ((uint64_t)(v_dst.len))) {
68276 wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, wuffs_base__slice_u8__subslice_i(v_dst, v_i), wuffs_base__pixel_buffer__palette(a_dst), v_src);
68279 return wuffs_base__make_status(NULL);
68282 // -------- func qoi.decoder.frame_dirty_rect
68284 WUFFS_BASE__GENERATED_C_CODE
68285 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
68286 wuffs_qoi__decoder__frame_dirty_rect(
68287 const wuffs_qoi__decoder* self) {
68288 if (!self) {
68289 return wuffs_base__utility__empty_rect_ie_u32();
68291 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
68292 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
68293 return wuffs_base__utility__empty_rect_ie_u32();
68296 return wuffs_base__utility__make_rect_ie_u32(
68299 self->private_impl.f_width,
68300 self->private_impl.f_height);
68303 // -------- func qoi.decoder.num_animation_loops
68305 WUFFS_BASE__GENERATED_C_CODE
68306 WUFFS_BASE__MAYBE_STATIC uint32_t
68307 wuffs_qoi__decoder__num_animation_loops(
68308 const wuffs_qoi__decoder* self) {
68309 if (!self) {
68310 return 0;
68312 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
68313 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
68314 return 0;
68317 return 0u;
68320 // -------- func qoi.decoder.num_decoded_frame_configs
68322 WUFFS_BASE__GENERATED_C_CODE
68323 WUFFS_BASE__MAYBE_STATIC uint64_t
68324 wuffs_qoi__decoder__num_decoded_frame_configs(
68325 const wuffs_qoi__decoder* self) {
68326 if (!self) {
68327 return 0;
68329 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
68330 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
68331 return 0;
68334 if (self->private_impl.f_call_sequence > 32u) {
68335 return 1u;
68337 return 0u;
68340 // -------- func qoi.decoder.num_decoded_frames
68342 WUFFS_BASE__GENERATED_C_CODE
68343 WUFFS_BASE__MAYBE_STATIC uint64_t
68344 wuffs_qoi__decoder__num_decoded_frames(
68345 const wuffs_qoi__decoder* self) {
68346 if (!self) {
68347 return 0;
68349 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
68350 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
68351 return 0;
68354 if (self->private_impl.f_call_sequence > 64u) {
68355 return 1u;
68357 return 0u;
68360 // -------- func qoi.decoder.restart_frame
68362 WUFFS_BASE__GENERATED_C_CODE
68363 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
68364 wuffs_qoi__decoder__restart_frame(
68365 wuffs_qoi__decoder* self,
68366 uint64_t a_index,
68367 uint64_t a_io_position) {
68368 if (!self) {
68369 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
68371 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
68372 return wuffs_base__make_status(
68373 (self->private_impl.magic == WUFFS_BASE__DISABLED)
68374 ? wuffs_base__error__disabled_by_previous_error
68375 : wuffs_base__error__initialize_not_called);
68378 if (self->private_impl.f_call_sequence < 32u) {
68379 return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
68381 if ((a_index != 0u) || (a_io_position != 14u)) {
68382 return wuffs_base__make_status(wuffs_base__error__bad_argument);
68384 self->private_impl.f_call_sequence = 40u;
68385 return wuffs_base__make_status(NULL);
68388 // -------- func qoi.decoder.set_report_metadata
68390 WUFFS_BASE__GENERATED_C_CODE
68391 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
68392 wuffs_qoi__decoder__set_report_metadata(
68393 wuffs_qoi__decoder* self,
68394 uint32_t a_fourcc,
68395 bool a_report) {
68396 return wuffs_base__make_empty_struct();
68399 // -------- func qoi.decoder.tell_me_more
68401 WUFFS_BASE__GENERATED_C_CODE
68402 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
68403 wuffs_qoi__decoder__tell_me_more(
68404 wuffs_qoi__decoder* self,
68405 wuffs_base__io_buffer* a_dst,
68406 wuffs_base__more_information* a_minfo,
68407 wuffs_base__io_buffer* a_src) {
68408 if (!self) {
68409 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
68411 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
68412 return wuffs_base__make_status(
68413 (self->private_impl.magic == WUFFS_BASE__DISABLED)
68414 ? wuffs_base__error__disabled_by_previous_error
68415 : wuffs_base__error__initialize_not_called);
68417 if (!a_dst || !a_src) {
68418 self->private_impl.magic = WUFFS_BASE__DISABLED;
68419 return wuffs_base__make_status(wuffs_base__error__bad_argument);
68421 if ((self->private_impl.active_coroutine != 0) &&
68422 (self->private_impl.active_coroutine != 4)) {
68423 self->private_impl.magic = WUFFS_BASE__DISABLED;
68424 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
68426 self->private_impl.active_coroutine = 0;
68427 wuffs_base__status status = wuffs_base__make_status(NULL);
68429 status = wuffs_base__make_status(wuffs_base__error__no_more_information);
68430 goto exit;
68432 goto ok;
68434 goto exit;
68435 exit:
68436 if (wuffs_base__status__is_error(&status)) {
68437 self->private_impl.magic = WUFFS_BASE__DISABLED;
68439 return status;
68442 // -------- func qoi.decoder.workbuf_len
68444 WUFFS_BASE__GENERATED_C_CODE
68445 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
68446 wuffs_qoi__decoder__workbuf_len(
68447 const wuffs_qoi__decoder* self) {
68448 if (!self) {
68449 return wuffs_base__utility__empty_range_ii_u64();
68451 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
68452 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
68453 return wuffs_base__utility__empty_range_ii_u64();
68456 return wuffs_base__utility__make_range_ii_u64(0u, 0u);
68459 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__QOI)
68461 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__SHA256)
68463 // ---------------- Status Codes Implementations
68465 // ---------------- Private Consts
68467 static const uint32_t
68468 WUFFS_SHA256__INITIAL_SHA256_H[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
68469 1779033703u, 3144134277u, 1013904242u, 2773480762u, 1359893119u, 2600822924u, 528734635u, 1541459225u,
68472 static const uint32_t
68473 WUFFS_SHA256__K[64] WUFFS_BASE__POTENTIALLY_UNUSED = {
68474 1116352408u, 1899447441u, 3049323471u, 3921009573u, 961987163u, 1508970993u, 2453635748u, 2870763221u,
68475 3624381080u, 310598401u, 607225278u, 1426881987u, 1925078388u, 2162078206u, 2614888103u, 3248222580u,
68476 3835390401u, 4022224774u, 264347078u, 604807628u, 770255983u, 1249150122u, 1555081692u, 1996064986u,
68477 2554220882u, 2821834349u, 2952996808u, 3210313671u, 3336571891u, 3584528711u, 113926993u, 338241895u,
68478 666307205u, 773529912u, 1294757372u, 1396182291u, 1695183700u, 1986661051u, 2177026350u, 2456956037u,
68479 2730485921u, 2820302411u, 3259730800u, 3345764771u, 3516065817u, 3600352804u, 4094571909u, 275423344u,
68480 430227734u, 506948616u, 659060556u, 883997877u, 958139571u, 1322822218u, 1537002063u, 1747873779u,
68481 1955562222u, 2024104815u, 2227730452u, 2361852424u, 2428436474u, 2756734187u, 3204031479u, 3329325298u,
68484 // ---------------- Private Initializer Prototypes
68486 // ---------------- Private Function Prototypes
68488 WUFFS_BASE__GENERATED_C_CODE
68489 static wuffs_base__empty_struct
68490 wuffs_sha256__hasher__up(
68491 wuffs_sha256__hasher* self,
68492 wuffs_base__slice_u8 a_x);
68494 // ---------------- VTables
68496 const wuffs_base__hasher_bitvec256__func_ptrs
68497 wuffs_sha256__hasher__func_ptrs_for__wuffs_base__hasher_bitvec256 = {
68498 (wuffs_base__bitvec256(*)(const void*))(&wuffs_sha256__hasher__checksum_bitvec256),
68499 (uint64_t(*)(const void*,
68500 uint32_t))(&wuffs_sha256__hasher__get_quirk),
68501 (wuffs_base__status(*)(void*,
68502 uint32_t,
68503 uint64_t))(&wuffs_sha256__hasher__set_quirk),
68504 (wuffs_base__empty_struct(*)(void*,
68505 wuffs_base__slice_u8))(&wuffs_sha256__hasher__update),
68506 (wuffs_base__bitvec256(*)(void*,
68507 wuffs_base__slice_u8))(&wuffs_sha256__hasher__update_bitvec256),
68510 // ---------------- Initializer Implementations
68512 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
68513 wuffs_sha256__hasher__initialize(
68514 wuffs_sha256__hasher* self,
68515 size_t sizeof_star_self,
68516 uint64_t wuffs_version,
68517 uint32_t options){
68518 if (!self) {
68519 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
68521 if (sizeof(*self) != sizeof_star_self) {
68522 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
68524 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
68525 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
68526 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
68529 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
68530 // The whole point of this if-check is to detect an uninitialized *self.
68531 // We disable the warning on GCC. Clang-5.0 does not have this warning.
68532 #if !defined(__clang__) && defined(__GNUC__)
68533 #pragma GCC diagnostic push
68534 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
68535 #endif
68536 if (self->private_impl.magic != 0) {
68537 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
68539 #if !defined(__clang__) && defined(__GNUC__)
68540 #pragma GCC diagnostic pop
68541 #endif
68542 } else {
68543 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
68544 memset(self, 0, sizeof(*self));
68545 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
68546 } else {
68547 memset(&(self->private_impl), 0, sizeof(self->private_impl));
68551 self->private_impl.magic = WUFFS_BASE__MAGIC;
68552 self->private_impl.vtable_for__wuffs_base__hasher_bitvec256.vtable_name =
68553 wuffs_base__hasher_bitvec256__vtable_name;
68554 self->private_impl.vtable_for__wuffs_base__hasher_bitvec256.function_pointers =
68555 (const void*)(&wuffs_sha256__hasher__func_ptrs_for__wuffs_base__hasher_bitvec256);
68556 return wuffs_base__make_status(NULL);
68559 wuffs_sha256__hasher*
68560 wuffs_sha256__hasher__alloc(void) {
68561 wuffs_sha256__hasher* x =
68562 (wuffs_sha256__hasher*)(calloc(1, sizeof(wuffs_sha256__hasher)));
68563 if (!x) {
68564 return NULL;
68566 if (wuffs_sha256__hasher__initialize(
68567 x, sizeof(wuffs_sha256__hasher), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
68568 free(x);
68569 return NULL;
68571 return x;
68574 size_t
68575 sizeof__wuffs_sha256__hasher(void) {
68576 return sizeof(wuffs_sha256__hasher);
68579 // ---------------- Function Implementations
68581 // -------- func sha256.hasher.get_quirk
68583 WUFFS_BASE__GENERATED_C_CODE
68584 WUFFS_BASE__MAYBE_STATIC uint64_t
68585 wuffs_sha256__hasher__get_quirk(
68586 const wuffs_sha256__hasher* self,
68587 uint32_t a_key) {
68588 if (!self) {
68589 return 0;
68591 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
68592 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
68593 return 0;
68596 return 0u;
68599 // -------- func sha256.hasher.set_quirk
68601 WUFFS_BASE__GENERATED_C_CODE
68602 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
68603 wuffs_sha256__hasher__set_quirk(
68604 wuffs_sha256__hasher* self,
68605 uint32_t a_key,
68606 uint64_t a_value) {
68607 if (!self) {
68608 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
68610 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
68611 return wuffs_base__make_status(
68612 (self->private_impl.magic == WUFFS_BASE__DISABLED)
68613 ? wuffs_base__error__disabled_by_previous_error
68614 : wuffs_base__error__initialize_not_called);
68617 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
68620 // -------- func sha256.hasher.update
68622 WUFFS_BASE__GENERATED_C_CODE
68623 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
68624 wuffs_sha256__hasher__update(
68625 wuffs_sha256__hasher* self,
68626 wuffs_base__slice_u8 a_x) {
68627 if (!self) {
68628 return wuffs_base__make_empty_struct();
68630 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
68631 return wuffs_base__make_empty_struct();
68634 uint64_t v_new_lmu = 0;
68636 if ((self->private_impl.f_length_modulo_u64 == 0u) && ! self->private_impl.f_length_overflows_u64) {
68637 self->private_impl.f_h0 = WUFFS_SHA256__INITIAL_SHA256_H[0u];
68638 self->private_impl.f_h1 = WUFFS_SHA256__INITIAL_SHA256_H[1u];
68639 self->private_impl.f_h2 = WUFFS_SHA256__INITIAL_SHA256_H[2u];
68640 self->private_impl.f_h3 = WUFFS_SHA256__INITIAL_SHA256_H[3u];
68641 self->private_impl.f_h4 = WUFFS_SHA256__INITIAL_SHA256_H[4u];
68642 self->private_impl.f_h5 = WUFFS_SHA256__INITIAL_SHA256_H[5u];
68643 self->private_impl.f_h6 = WUFFS_SHA256__INITIAL_SHA256_H[6u];
68644 self->private_impl.f_h7 = WUFFS_SHA256__INITIAL_SHA256_H[7u];
68646 v_new_lmu = ((uint64_t)(self->private_impl.f_length_modulo_u64 + ((uint64_t)(a_x.len))));
68647 self->private_impl.f_length_overflows_u64 = ((v_new_lmu < self->private_impl.f_length_modulo_u64) || self->private_impl.f_length_overflows_u64);
68648 self->private_impl.f_length_modulo_u64 = v_new_lmu;
68649 if (self->private_impl.f_buf_len != 0u) {
68650 while (self->private_impl.f_buf_len < 64u) {
68651 if (((uint64_t)(a_x.len)) <= 0u) {
68652 return wuffs_base__make_empty_struct();
68654 self->private_impl.f_buf_data[self->private_impl.f_buf_len] = a_x.ptr[0u];
68655 self->private_impl.f_buf_len += 1u;
68656 a_x = wuffs_base__slice_u8__subslice_i(a_x, 1u);
68658 self->private_impl.f_buf_len = 0u;
68659 wuffs_sha256__hasher__up(self, wuffs_base__make_slice_u8(self->private_impl.f_buf_data, 64));
68661 wuffs_sha256__hasher__up(self, a_x);
68662 return wuffs_base__make_empty_struct();
68665 // -------- func sha256.hasher.update_bitvec256
68667 WUFFS_BASE__GENERATED_C_CODE
68668 WUFFS_BASE__MAYBE_STATIC wuffs_base__bitvec256
68669 wuffs_sha256__hasher__update_bitvec256(
68670 wuffs_sha256__hasher* self,
68671 wuffs_base__slice_u8 a_x) {
68672 if (!self) {
68673 return wuffs_base__utility__make_bitvec256(0u, 0u, 0u, 0u);
68675 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
68676 return wuffs_base__utility__make_bitvec256(0u, 0u, 0u, 0u);
68679 wuffs_sha256__hasher__update(self, a_x);
68680 return wuffs_sha256__hasher__checksum_bitvec256(self);
68683 // -------- func sha256.hasher.up
68685 WUFFS_BASE__GENERATED_C_CODE
68686 static wuffs_base__empty_struct
68687 wuffs_sha256__hasher__up(
68688 wuffs_sha256__hasher* self,
68689 wuffs_base__slice_u8 a_x) {
68690 wuffs_base__slice_u8 v_p = {0};
68691 uint32_t v_w[64] = {0};
68692 uint32_t v_w2 = 0;
68693 uint32_t v_w15 = 0;
68694 uint32_t v_s0 = 0;
68695 uint32_t v_s1 = 0;
68696 uint32_t v_t1 = 0;
68697 uint32_t v_t2 = 0;
68698 uint32_t v_a = 0;
68699 uint32_t v_b = 0;
68700 uint32_t v_c = 0;
68701 uint32_t v_d = 0;
68702 uint32_t v_e = 0;
68703 uint32_t v_f = 0;
68704 uint32_t v_g = 0;
68705 uint32_t v_h = 0;
68706 uint32_t v_i = 0;
68707 uint32_t v_buf_len = 0;
68709 v_a = self->private_impl.f_h0;
68710 v_b = self->private_impl.f_h1;
68711 v_c = self->private_impl.f_h2;
68712 v_d = self->private_impl.f_h3;
68713 v_e = self->private_impl.f_h4;
68714 v_f = self->private_impl.f_h5;
68715 v_g = self->private_impl.f_h6;
68716 v_h = self->private_impl.f_h7;
68718 wuffs_base__slice_u8 i_slice_p = a_x;
68719 v_p.ptr = i_slice_p.ptr;
68720 v_p.len = 64;
68721 const uint8_t* i_end0_p = wuffs_private_impl__ptr_u8_plus_len(v_p.ptr, (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 64) * 64));
68722 while (v_p.ptr < i_end0_p) {
68723 v_w[0u] = ((((uint32_t)(v_p.ptr[0u])) << 24u) |
68724 (((uint32_t)(v_p.ptr[1u])) << 16u) |
68725 (((uint32_t)(v_p.ptr[2u])) << 8u) |
68726 ((uint32_t)(v_p.ptr[3u])));
68727 v_w[1u] = ((((uint32_t)(v_p.ptr[4u])) << 24u) |
68728 (((uint32_t)(v_p.ptr[5u])) << 16u) |
68729 (((uint32_t)(v_p.ptr[6u])) << 8u) |
68730 ((uint32_t)(v_p.ptr[7u])));
68731 v_w[2u] = ((((uint32_t)(v_p.ptr[8u])) << 24u) |
68732 (((uint32_t)(v_p.ptr[9u])) << 16u) |
68733 (((uint32_t)(v_p.ptr[10u])) << 8u) |
68734 ((uint32_t)(v_p.ptr[11u])));
68735 v_w[3u] = ((((uint32_t)(v_p.ptr[12u])) << 24u) |
68736 (((uint32_t)(v_p.ptr[13u])) << 16u) |
68737 (((uint32_t)(v_p.ptr[14u])) << 8u) |
68738 ((uint32_t)(v_p.ptr[15u])));
68739 v_w[4u] = ((((uint32_t)(v_p.ptr[16u])) << 24u) |
68740 (((uint32_t)(v_p.ptr[17u])) << 16u) |
68741 (((uint32_t)(v_p.ptr[18u])) << 8u) |
68742 ((uint32_t)(v_p.ptr[19u])));
68743 v_w[5u] = ((((uint32_t)(v_p.ptr[20u])) << 24u) |
68744 (((uint32_t)(v_p.ptr[21u])) << 16u) |
68745 (((uint32_t)(v_p.ptr[22u])) << 8u) |
68746 ((uint32_t)(v_p.ptr[23u])));
68747 v_w[6u] = ((((uint32_t)(v_p.ptr[24u])) << 24u) |
68748 (((uint32_t)(v_p.ptr[25u])) << 16u) |
68749 (((uint32_t)(v_p.ptr[26u])) << 8u) |
68750 ((uint32_t)(v_p.ptr[27u])));
68751 v_w[7u] = ((((uint32_t)(v_p.ptr[28u])) << 24u) |
68752 (((uint32_t)(v_p.ptr[29u])) << 16u) |
68753 (((uint32_t)(v_p.ptr[30u])) << 8u) |
68754 ((uint32_t)(v_p.ptr[31u])));
68755 v_w[8u] = ((((uint32_t)(v_p.ptr[32u])) << 24u) |
68756 (((uint32_t)(v_p.ptr[33u])) << 16u) |
68757 (((uint32_t)(v_p.ptr[34u])) << 8u) |
68758 ((uint32_t)(v_p.ptr[35u])));
68759 v_w[9u] = ((((uint32_t)(v_p.ptr[36u])) << 24u) |
68760 (((uint32_t)(v_p.ptr[37u])) << 16u) |
68761 (((uint32_t)(v_p.ptr[38u])) << 8u) |
68762 ((uint32_t)(v_p.ptr[39u])));
68763 v_w[10u] = ((((uint32_t)(v_p.ptr[40u])) << 24u) |
68764 (((uint32_t)(v_p.ptr[41u])) << 16u) |
68765 (((uint32_t)(v_p.ptr[42u])) << 8u) |
68766 ((uint32_t)(v_p.ptr[43u])));
68767 v_w[11u] = ((((uint32_t)(v_p.ptr[44u])) << 24u) |
68768 (((uint32_t)(v_p.ptr[45u])) << 16u) |
68769 (((uint32_t)(v_p.ptr[46u])) << 8u) |
68770 ((uint32_t)(v_p.ptr[47u])));
68771 v_w[12u] = ((((uint32_t)(v_p.ptr[48u])) << 24u) |
68772 (((uint32_t)(v_p.ptr[49u])) << 16u) |
68773 (((uint32_t)(v_p.ptr[50u])) << 8u) |
68774 ((uint32_t)(v_p.ptr[51u])));
68775 v_w[13u] = ((((uint32_t)(v_p.ptr[52u])) << 24u) |
68776 (((uint32_t)(v_p.ptr[53u])) << 16u) |
68777 (((uint32_t)(v_p.ptr[54u])) << 8u) |
68778 ((uint32_t)(v_p.ptr[55u])));
68779 v_w[14u] = ((((uint32_t)(v_p.ptr[56u])) << 24u) |
68780 (((uint32_t)(v_p.ptr[57u])) << 16u) |
68781 (((uint32_t)(v_p.ptr[58u])) << 8u) |
68782 ((uint32_t)(v_p.ptr[59u])));
68783 v_w[15u] = ((((uint32_t)(v_p.ptr[60u])) << 24u) |
68784 (((uint32_t)(v_p.ptr[61u])) << 16u) |
68785 (((uint32_t)(v_p.ptr[62u])) << 8u) |
68786 ((uint32_t)(v_p.ptr[63u])));
68787 v_i = 16u;
68788 while (v_i < 64u) {
68789 v_w2 = v_w[(v_i - 2u)];
68790 v_s1 = ((v_w2 >> 10u) ^ (((uint32_t)(v_w2 << 15u)) | (v_w2 >> 17u)) ^ (((uint32_t)(v_w2 << 13u)) | (v_w2 >> 19u)));
68791 v_w15 = v_w[(v_i - 15u)];
68792 v_s0 = ((v_w15 >> 3u) ^ (((uint32_t)(v_w15 << 25u)) | (v_w15 >> 7u)) ^ (((uint32_t)(v_w15 << 14u)) | (v_w15 >> 18u)));
68793 v_w[v_i] = ((uint32_t)(((uint32_t)(((uint32_t)(v_s1 + v_w[(v_i - 7u)])) + v_s0)) + v_w[(v_i - 16u)]));
68794 v_i += 1u;
68796 v_i = 0u;
68797 while (v_i < 64u) {
68798 v_t1 = v_h;
68799 v_t1 += ((((uint32_t)(v_e << 26u)) | (v_e >> 6u)) ^ (((uint32_t)(v_e << 21u)) | (v_e >> 11u)) ^ (((uint32_t)(v_e << 7u)) | (v_e >> 25u)));
68800 v_t1 += ((v_e & v_f) ^ ((4294967295u ^ v_e) & v_g));
68801 v_t1 += WUFFS_SHA256__K[v_i];
68802 v_t1 += v_w[v_i];
68803 v_t2 = ((((uint32_t)(v_a << 30u)) | (v_a >> 2u)) ^ (((uint32_t)(v_a << 19u)) | (v_a >> 13u)) ^ (((uint32_t)(v_a << 10u)) | (v_a >> 22u)));
68804 v_t2 += ((v_a & v_b) ^ (v_a & v_c) ^ (v_b & v_c));
68805 v_h = v_g;
68806 v_g = v_f;
68807 v_f = v_e;
68808 v_e = ((uint32_t)(v_d + v_t1));
68809 v_d = v_c;
68810 v_c = v_b;
68811 v_b = v_a;
68812 v_a = ((uint32_t)(v_t1 + v_t2));
68813 v_i += 1u;
68815 v_a += self->private_impl.f_h0;
68816 self->private_impl.f_h0 = v_a;
68817 v_b += self->private_impl.f_h1;
68818 self->private_impl.f_h1 = v_b;
68819 v_c += self->private_impl.f_h2;
68820 self->private_impl.f_h2 = v_c;
68821 v_d += self->private_impl.f_h3;
68822 self->private_impl.f_h3 = v_d;
68823 v_e += self->private_impl.f_h4;
68824 self->private_impl.f_h4 = v_e;
68825 v_f += self->private_impl.f_h5;
68826 self->private_impl.f_h5 = v_f;
68827 v_g += self->private_impl.f_h6;
68828 self->private_impl.f_h6 = v_g;
68829 v_h += self->private_impl.f_h7;
68830 self->private_impl.f_h7 = v_h;
68831 v_p.ptr += 64;
68833 v_p.len = 1;
68834 const uint8_t* i_end1_p = wuffs_private_impl__ptr_u8_plus_len(i_slice_p.ptr, i_slice_p.len);
68835 while (v_p.ptr < i_end1_p) {
68836 self->private_impl.f_buf_data[v_buf_len] = v_p.ptr[0u];
68837 v_buf_len = ((v_buf_len + 1u) & 63u);
68838 v_p.ptr += 1;
68840 v_p.len = 0;
68842 self->private_impl.f_buf_len = ((uint32_t)((((uint64_t)(a_x.len)) & 63u)));
68843 return wuffs_base__make_empty_struct();
68846 // -------- func sha256.hasher.checksum_bitvec256
68848 WUFFS_BASE__GENERATED_C_CODE
68849 WUFFS_BASE__MAYBE_STATIC wuffs_base__bitvec256
68850 wuffs_sha256__hasher__checksum_bitvec256(
68851 const wuffs_sha256__hasher* self) {
68852 if (!self) {
68853 return wuffs_base__utility__make_bitvec256(0u, 0u, 0u, 0u);
68855 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
68856 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
68857 return wuffs_base__utility__make_bitvec256(0u, 0u, 0u, 0u);
68860 uint32_t v_buf_len = 0;
68861 uint8_t v_buf_data[64] = {0};
68862 uint64_t v_length_in_bits = 0;
68863 uint32_t v_w[64] = {0};
68864 uint32_t v_w2 = 0;
68865 uint32_t v_w15 = 0;
68866 uint32_t v_s0 = 0;
68867 uint32_t v_s1 = 0;
68868 uint32_t v_t1 = 0;
68869 uint32_t v_t2 = 0;
68870 uint32_t v_h0 = 0;
68871 uint32_t v_h1 = 0;
68872 uint32_t v_h2 = 0;
68873 uint32_t v_h3 = 0;
68874 uint32_t v_h4 = 0;
68875 uint32_t v_h5 = 0;
68876 uint32_t v_h6 = 0;
68877 uint32_t v_h7 = 0;
68878 uint32_t v_a = 0;
68879 uint32_t v_b = 0;
68880 uint32_t v_c = 0;
68881 uint32_t v_d = 0;
68882 uint32_t v_e = 0;
68883 uint32_t v_f = 0;
68884 uint32_t v_g = 0;
68885 uint32_t v_h = 0;
68886 uint32_t v_i = 0;
68887 bool v_final_block = false;
68889 v_i = 0u;
68890 while (v_i < 64u) {
68891 v_buf_data[v_i] = self->private_impl.f_buf_data[v_i];
68892 v_i += 1u;
68894 v_buf_len = (self->private_impl.f_buf_len & 63u);
68895 if (v_buf_len < 56u) {
68896 v_buf_data[v_buf_len] = 128u;
68897 v_buf_len += 1u;
68898 while (v_buf_len < 56u) {
68899 v_buf_data[v_buf_len] = 0u;
68900 v_buf_len += 1u;
68902 v_final_block = true;
68903 } else {
68904 v_buf_data[v_buf_len] = 128u;
68905 v_buf_len += 1u;
68906 while (v_buf_len < 64u) {
68907 v_buf_data[v_buf_len] = 0u;
68908 v_buf_len += 1u;
68911 v_h0 = self->private_impl.f_h0;
68912 v_a = v_h0;
68913 v_h1 = self->private_impl.f_h1;
68914 v_b = v_h1;
68915 v_h2 = self->private_impl.f_h2;
68916 v_c = v_h2;
68917 v_h3 = self->private_impl.f_h3;
68918 v_d = v_h3;
68919 v_h4 = self->private_impl.f_h4;
68920 v_e = v_h4;
68921 v_h5 = self->private_impl.f_h5;
68922 v_f = v_h5;
68923 v_h6 = self->private_impl.f_h6;
68924 v_g = v_h6;
68925 v_h7 = self->private_impl.f_h7;
68926 v_h = v_h7;
68927 while (true) {
68928 if (v_final_block) {
68929 v_length_in_bits = ((uint64_t)(self->private_impl.f_length_modulo_u64 * 8u));
68930 v_buf_data[56u] = ((uint8_t)((v_length_in_bits >> 56u)));
68931 v_buf_data[57u] = ((uint8_t)((v_length_in_bits >> 48u)));
68932 v_buf_data[58u] = ((uint8_t)((v_length_in_bits >> 40u)));
68933 v_buf_data[59u] = ((uint8_t)((v_length_in_bits >> 32u)));
68934 v_buf_data[60u] = ((uint8_t)((v_length_in_bits >> 24u)));
68935 v_buf_data[61u] = ((uint8_t)((v_length_in_bits >> 16u)));
68936 v_buf_data[62u] = ((uint8_t)((v_length_in_bits >> 8u)));
68937 v_buf_data[63u] = ((uint8_t)(v_length_in_bits));
68939 v_w[0u] = ((((uint32_t)(v_buf_data[0u])) << 24u) |
68940 (((uint32_t)(v_buf_data[1u])) << 16u) |
68941 (((uint32_t)(v_buf_data[2u])) << 8u) |
68942 ((uint32_t)(v_buf_data[3u])));
68943 v_w[1u] = ((((uint32_t)(v_buf_data[4u])) << 24u) |
68944 (((uint32_t)(v_buf_data[5u])) << 16u) |
68945 (((uint32_t)(v_buf_data[6u])) << 8u) |
68946 ((uint32_t)(v_buf_data[7u])));
68947 v_w[2u] = ((((uint32_t)(v_buf_data[8u])) << 24u) |
68948 (((uint32_t)(v_buf_data[9u])) << 16u) |
68949 (((uint32_t)(v_buf_data[10u])) << 8u) |
68950 ((uint32_t)(v_buf_data[11u])));
68951 v_w[3u] = ((((uint32_t)(v_buf_data[12u])) << 24u) |
68952 (((uint32_t)(v_buf_data[13u])) << 16u) |
68953 (((uint32_t)(v_buf_data[14u])) << 8u) |
68954 ((uint32_t)(v_buf_data[15u])));
68955 v_w[4u] = ((((uint32_t)(v_buf_data[16u])) << 24u) |
68956 (((uint32_t)(v_buf_data[17u])) << 16u) |
68957 (((uint32_t)(v_buf_data[18u])) << 8u) |
68958 ((uint32_t)(v_buf_data[19u])));
68959 v_w[5u] = ((((uint32_t)(v_buf_data[20u])) << 24u) |
68960 (((uint32_t)(v_buf_data[21u])) << 16u) |
68961 (((uint32_t)(v_buf_data[22u])) << 8u) |
68962 ((uint32_t)(v_buf_data[23u])));
68963 v_w[6u] = ((((uint32_t)(v_buf_data[24u])) << 24u) |
68964 (((uint32_t)(v_buf_data[25u])) << 16u) |
68965 (((uint32_t)(v_buf_data[26u])) << 8u) |
68966 ((uint32_t)(v_buf_data[27u])));
68967 v_w[7u] = ((((uint32_t)(v_buf_data[28u])) << 24u) |
68968 (((uint32_t)(v_buf_data[29u])) << 16u) |
68969 (((uint32_t)(v_buf_data[30u])) << 8u) |
68970 ((uint32_t)(v_buf_data[31u])));
68971 v_w[8u] = ((((uint32_t)(v_buf_data[32u])) << 24u) |
68972 (((uint32_t)(v_buf_data[33u])) << 16u) |
68973 (((uint32_t)(v_buf_data[34u])) << 8u) |
68974 ((uint32_t)(v_buf_data[35u])));
68975 v_w[9u] = ((((uint32_t)(v_buf_data[36u])) << 24u) |
68976 (((uint32_t)(v_buf_data[37u])) << 16u) |
68977 (((uint32_t)(v_buf_data[38u])) << 8u) |
68978 ((uint32_t)(v_buf_data[39u])));
68979 v_w[10u] = ((((uint32_t)(v_buf_data[40u])) << 24u) |
68980 (((uint32_t)(v_buf_data[41u])) << 16u) |
68981 (((uint32_t)(v_buf_data[42u])) << 8u) |
68982 ((uint32_t)(v_buf_data[43u])));
68983 v_w[11u] = ((((uint32_t)(v_buf_data[44u])) << 24u) |
68984 (((uint32_t)(v_buf_data[45u])) << 16u) |
68985 (((uint32_t)(v_buf_data[46u])) << 8u) |
68986 ((uint32_t)(v_buf_data[47u])));
68987 v_w[12u] = ((((uint32_t)(v_buf_data[48u])) << 24u) |
68988 (((uint32_t)(v_buf_data[49u])) << 16u) |
68989 (((uint32_t)(v_buf_data[50u])) << 8u) |
68990 ((uint32_t)(v_buf_data[51u])));
68991 v_w[13u] = ((((uint32_t)(v_buf_data[52u])) << 24u) |
68992 (((uint32_t)(v_buf_data[53u])) << 16u) |
68993 (((uint32_t)(v_buf_data[54u])) << 8u) |
68994 ((uint32_t)(v_buf_data[55u])));
68995 v_w[14u] = ((((uint32_t)(v_buf_data[56u])) << 24u) |
68996 (((uint32_t)(v_buf_data[57u])) << 16u) |
68997 (((uint32_t)(v_buf_data[58u])) << 8u) |
68998 ((uint32_t)(v_buf_data[59u])));
68999 v_w[15u] = ((((uint32_t)(v_buf_data[60u])) << 24u) |
69000 (((uint32_t)(v_buf_data[61u])) << 16u) |
69001 (((uint32_t)(v_buf_data[62u])) << 8u) |
69002 ((uint32_t)(v_buf_data[63u])));
69003 v_i = 16u;
69004 while (v_i < 64u) {
69005 v_w2 = v_w[(v_i - 2u)];
69006 v_s1 = ((v_w2 >> 10u) ^ (((uint32_t)(v_w2 << 15u)) | (v_w2 >> 17u)) ^ (((uint32_t)(v_w2 << 13u)) | (v_w2 >> 19u)));
69007 v_w15 = v_w[(v_i - 15u)];
69008 v_s0 = ((v_w15 >> 3u) ^ (((uint32_t)(v_w15 << 25u)) | (v_w15 >> 7u)) ^ (((uint32_t)(v_w15 << 14u)) | (v_w15 >> 18u)));
69009 v_w[v_i] = ((uint32_t)(((uint32_t)(((uint32_t)(v_s1 + v_w[(v_i - 7u)])) + v_s0)) + v_w[(v_i - 16u)]));
69010 v_i += 1u;
69012 v_i = 0u;
69013 while (v_i < 64u) {
69014 v_t1 = v_h;
69015 v_t1 += ((((uint32_t)(v_e << 26u)) | (v_e >> 6u)) ^ (((uint32_t)(v_e << 21u)) | (v_e >> 11u)) ^ (((uint32_t)(v_e << 7u)) | (v_e >> 25u)));
69016 v_t1 += ((v_e & v_f) ^ ((4294967295u ^ v_e) & v_g));
69017 v_t1 += WUFFS_SHA256__K[v_i];
69018 v_t1 += v_w[v_i];
69019 v_t2 = ((((uint32_t)(v_a << 30u)) | (v_a >> 2u)) ^ (((uint32_t)(v_a << 19u)) | (v_a >> 13u)) ^ (((uint32_t)(v_a << 10u)) | (v_a >> 22u)));
69020 v_t2 += ((v_a & v_b) ^ (v_a & v_c) ^ (v_b & v_c));
69021 v_h = v_g;
69022 v_g = v_f;
69023 v_f = v_e;
69024 v_e = ((uint32_t)(v_d + v_t1));
69025 v_d = v_c;
69026 v_c = v_b;
69027 v_b = v_a;
69028 v_a = ((uint32_t)(v_t1 + v_t2));
69029 v_i += 1u;
69031 v_a += v_h0;
69032 v_b += v_h1;
69033 v_c += v_h2;
69034 v_d += v_h3;
69035 v_e += v_h4;
69036 v_f += v_h5;
69037 v_g += v_h6;
69038 v_h += v_h7;
69039 if (v_final_block) {
69040 break;
69042 v_final_block = true;
69043 v_h0 = v_a;
69044 v_h1 = v_b;
69045 v_h2 = v_c;
69046 v_h3 = v_d;
69047 v_h4 = v_e;
69048 v_h5 = v_f;
69049 v_h6 = v_g;
69050 v_h7 = v_h;
69051 v_buf_len = 0u;
69052 while (v_buf_len < 56u) {
69053 v_buf_data[v_buf_len] = 0u;
69054 v_buf_len += 1u;
69057 return wuffs_base__utility__make_bitvec256(
69058 (((uint64_t)(v_h)) | (((uint64_t)(v_g)) << 32u)),
69059 (((uint64_t)(v_f)) | (((uint64_t)(v_e)) << 32u)),
69060 (((uint64_t)(v_d)) | (((uint64_t)(v_c)) << 32u)),
69061 (((uint64_t)(v_b)) | (((uint64_t)(v_a)) << 32u)));
69064 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__SHA256)
69066 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__TGA)
69068 // ---------------- Status Codes Implementations
69070 const char wuffs_tga__error__bad_header[] = "#tga: bad header";
69071 const char wuffs_tga__error__bad_run_length_encoding[] = "#tga: bad run length encoding";
69072 const char wuffs_tga__error__truncated_input[] = "#tga: truncated input";
69073 const char wuffs_tga__error__unsupported_tga_file[] = "#tga: unsupported TGA file";
69075 // ---------------- Private Consts
69077 // ---------------- Private Initializer Prototypes
69079 // ---------------- Private Function Prototypes
69081 WUFFS_BASE__GENERATED_C_CODE
69082 static wuffs_base__status
69083 wuffs_tga__decoder__do_decode_image_config(
69084 wuffs_tga__decoder* self,
69085 wuffs_base__image_config* a_dst,
69086 wuffs_base__io_buffer* a_src);
69088 WUFFS_BASE__GENERATED_C_CODE
69089 static wuffs_base__status
69090 wuffs_tga__decoder__do_decode_frame_config(
69091 wuffs_tga__decoder* self,
69092 wuffs_base__frame_config* a_dst,
69093 wuffs_base__io_buffer* a_src);
69095 WUFFS_BASE__GENERATED_C_CODE
69096 static wuffs_base__status
69097 wuffs_tga__decoder__do_decode_frame(
69098 wuffs_tga__decoder* self,
69099 wuffs_base__pixel_buffer* a_dst,
69100 wuffs_base__io_buffer* a_src,
69101 wuffs_base__pixel_blend a_blend,
69102 wuffs_base__slice_u8 a_workbuf,
69103 wuffs_base__decode_frame_options* a_opts);
69105 // ---------------- VTables
69107 const wuffs_base__image_decoder__func_ptrs
69108 wuffs_tga__decoder__func_ptrs_for__wuffs_base__image_decoder = {
69109 (wuffs_base__status(*)(void*,
69110 wuffs_base__pixel_buffer*,
69111 wuffs_base__io_buffer*,
69112 wuffs_base__pixel_blend,
69113 wuffs_base__slice_u8,
69114 wuffs_base__decode_frame_options*))(&wuffs_tga__decoder__decode_frame),
69115 (wuffs_base__status(*)(void*,
69116 wuffs_base__frame_config*,
69117 wuffs_base__io_buffer*))(&wuffs_tga__decoder__decode_frame_config),
69118 (wuffs_base__status(*)(void*,
69119 wuffs_base__image_config*,
69120 wuffs_base__io_buffer*))(&wuffs_tga__decoder__decode_image_config),
69121 (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_tga__decoder__frame_dirty_rect),
69122 (uint64_t(*)(const void*,
69123 uint32_t))(&wuffs_tga__decoder__get_quirk),
69124 (uint32_t(*)(const void*))(&wuffs_tga__decoder__num_animation_loops),
69125 (uint64_t(*)(const void*))(&wuffs_tga__decoder__num_decoded_frame_configs),
69126 (uint64_t(*)(const void*))(&wuffs_tga__decoder__num_decoded_frames),
69127 (wuffs_base__status(*)(void*,
69128 uint64_t,
69129 uint64_t))(&wuffs_tga__decoder__restart_frame),
69130 (wuffs_base__status(*)(void*,
69131 uint32_t,
69132 uint64_t))(&wuffs_tga__decoder__set_quirk),
69133 (wuffs_base__empty_struct(*)(void*,
69134 uint32_t,
69135 bool))(&wuffs_tga__decoder__set_report_metadata),
69136 (wuffs_base__status(*)(void*,
69137 wuffs_base__io_buffer*,
69138 wuffs_base__more_information*,
69139 wuffs_base__io_buffer*))(&wuffs_tga__decoder__tell_me_more),
69140 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_tga__decoder__workbuf_len),
69143 // ---------------- Initializer Implementations
69145 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
69146 wuffs_tga__decoder__initialize(
69147 wuffs_tga__decoder* self,
69148 size_t sizeof_star_self,
69149 uint64_t wuffs_version,
69150 uint32_t options){
69151 if (!self) {
69152 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
69154 if (sizeof(*self) != sizeof_star_self) {
69155 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
69157 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
69158 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
69159 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
69162 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
69163 // The whole point of this if-check is to detect an uninitialized *self.
69164 // We disable the warning on GCC. Clang-5.0 does not have this warning.
69165 #if !defined(__clang__) && defined(__GNUC__)
69166 #pragma GCC diagnostic push
69167 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
69168 #endif
69169 if (self->private_impl.magic != 0) {
69170 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
69172 #if !defined(__clang__) && defined(__GNUC__)
69173 #pragma GCC diagnostic pop
69174 #endif
69175 } else {
69176 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
69177 memset(self, 0, sizeof(*self));
69178 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
69179 } else {
69180 memset(&(self->private_impl), 0, sizeof(self->private_impl));
69184 self->private_impl.magic = WUFFS_BASE__MAGIC;
69185 self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
69186 wuffs_base__image_decoder__vtable_name;
69187 self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
69188 (const void*)(&wuffs_tga__decoder__func_ptrs_for__wuffs_base__image_decoder);
69189 return wuffs_base__make_status(NULL);
69192 wuffs_tga__decoder*
69193 wuffs_tga__decoder__alloc(void) {
69194 wuffs_tga__decoder* x =
69195 (wuffs_tga__decoder*)(calloc(1, sizeof(wuffs_tga__decoder)));
69196 if (!x) {
69197 return NULL;
69199 if (wuffs_tga__decoder__initialize(
69200 x, sizeof(wuffs_tga__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
69201 free(x);
69202 return NULL;
69204 return x;
69207 size_t
69208 sizeof__wuffs_tga__decoder(void) {
69209 return sizeof(wuffs_tga__decoder);
69212 // ---------------- Function Implementations
69214 // -------- func tga.decoder.get_quirk
69216 WUFFS_BASE__GENERATED_C_CODE
69217 WUFFS_BASE__MAYBE_STATIC uint64_t
69218 wuffs_tga__decoder__get_quirk(
69219 const wuffs_tga__decoder* self,
69220 uint32_t a_key) {
69221 if (!self) {
69222 return 0;
69224 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
69225 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
69226 return 0;
69229 return 0u;
69232 // -------- func tga.decoder.set_quirk
69234 WUFFS_BASE__GENERATED_C_CODE
69235 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
69236 wuffs_tga__decoder__set_quirk(
69237 wuffs_tga__decoder* self,
69238 uint32_t a_key,
69239 uint64_t a_value) {
69240 if (!self) {
69241 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
69243 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
69244 return wuffs_base__make_status(
69245 (self->private_impl.magic == WUFFS_BASE__DISABLED)
69246 ? wuffs_base__error__disabled_by_previous_error
69247 : wuffs_base__error__initialize_not_called);
69250 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
69253 // -------- func tga.decoder.decode_image_config
69255 WUFFS_BASE__GENERATED_C_CODE
69256 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
69257 wuffs_tga__decoder__decode_image_config(
69258 wuffs_tga__decoder* self,
69259 wuffs_base__image_config* a_dst,
69260 wuffs_base__io_buffer* a_src) {
69261 if (!self) {
69262 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
69264 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
69265 return wuffs_base__make_status(
69266 (self->private_impl.magic == WUFFS_BASE__DISABLED)
69267 ? wuffs_base__error__disabled_by_previous_error
69268 : wuffs_base__error__initialize_not_called);
69270 if (!a_src) {
69271 self->private_impl.magic = WUFFS_BASE__DISABLED;
69272 return wuffs_base__make_status(wuffs_base__error__bad_argument);
69274 if ((self->private_impl.active_coroutine != 0) &&
69275 (self->private_impl.active_coroutine != 1)) {
69276 self->private_impl.magic = WUFFS_BASE__DISABLED;
69277 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
69279 self->private_impl.active_coroutine = 0;
69280 wuffs_base__status status = wuffs_base__make_status(NULL);
69282 wuffs_base__status v_status = wuffs_base__make_status(NULL);
69284 uint32_t coro_susp_point = self->private_impl.p_decode_image_config;
69285 switch (coro_susp_point) {
69286 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
69288 while (true) {
69290 wuffs_base__status t_0 = wuffs_tga__decoder__do_decode_image_config(self, a_dst, a_src);
69291 v_status = t_0;
69293 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
69294 status = wuffs_base__make_status(wuffs_tga__error__truncated_input);
69295 goto exit;
69297 status = v_status;
69298 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
69302 self->private_impl.p_decode_image_config = 0;
69303 goto exit;
69306 goto suspend;
69307 suspend:
69308 self->private_impl.p_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
69309 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
69311 goto exit;
69312 exit:
69313 if (wuffs_base__status__is_error(&status)) {
69314 self->private_impl.magic = WUFFS_BASE__DISABLED;
69316 return status;
69319 // -------- func tga.decoder.do_decode_image_config
69321 WUFFS_BASE__GENERATED_C_CODE
69322 static wuffs_base__status
69323 wuffs_tga__decoder__do_decode_image_config(
69324 wuffs_tga__decoder* self,
69325 wuffs_base__image_config* a_dst,
69326 wuffs_base__io_buffer* a_src) {
69327 wuffs_base__status status = wuffs_base__make_status(NULL);
69329 uint32_t v_c32 = 0;
69330 uint32_t v_c5 = 0;
69331 uint32_t v_i = 0;
69333 const uint8_t* iop_a_src = NULL;
69334 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
69335 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
69336 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
69337 if (a_src && a_src->data.ptr) {
69338 io0_a_src = a_src->data.ptr;
69339 io1_a_src = io0_a_src + a_src->meta.ri;
69340 iop_a_src = io1_a_src;
69341 io2_a_src = io0_a_src + a_src->meta.wi;
69344 uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config;
69345 if (coro_susp_point) {
69346 v_i = self->private_data.s_do_decode_image_config.v_i;
69348 switch (coro_susp_point) {
69349 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
69351 if (self->private_impl.f_call_sequence != 0u) {
69352 status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
69353 goto exit;
69356 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
69357 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
69358 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
69359 goto suspend;
69361 uint8_t t_0 = *iop_a_src++;
69362 self->private_impl.f_header_id_length = t_0;
69365 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
69366 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
69367 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
69368 goto suspend;
69370 uint8_t t_1 = *iop_a_src++;
69371 self->private_impl.f_header_color_map_type = t_1;
69373 if (self->private_impl.f_header_color_map_type > 1u) {
69374 status = wuffs_base__make_status(wuffs_tga__error__bad_header);
69375 goto exit;
69378 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
69379 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
69380 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
69381 goto suspend;
69383 uint8_t t_2 = *iop_a_src++;
69384 self->private_impl.f_header_image_type = t_2;
69386 if ((self->private_impl.f_header_image_type == 1u) ||
69387 (self->private_impl.f_header_image_type == 2u) ||
69388 (self->private_impl.f_header_image_type == 3u) ||
69389 (self->private_impl.f_header_image_type == 9u) ||
69390 (self->private_impl.f_header_image_type == 10u) ||
69391 (self->private_impl.f_header_image_type == 11u)) {
69392 } else {
69393 status = wuffs_base__make_status(wuffs_tga__error__bad_header);
69394 goto exit;
69397 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
69398 uint16_t t_3;
69399 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
69400 t_3 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src);
69401 iop_a_src += 2;
69402 } else {
69403 self->private_data.s_do_decode_image_config.scratch = 0;
69404 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
69405 while (true) {
69406 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
69407 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
69408 goto suspend;
69410 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
69411 uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56));
69412 *scratch <<= 8;
69413 *scratch >>= 8;
69414 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3;
69415 if (num_bits_3 == 8) {
69416 t_3 = ((uint16_t)(*scratch));
69417 break;
69419 num_bits_3 += 8u;
69420 *scratch |= ((uint64_t)(num_bits_3)) << 56;
69423 self->private_impl.f_header_color_map_first_entry_index = t_3;
69426 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
69427 uint16_t t_4;
69428 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
69429 t_4 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src);
69430 iop_a_src += 2;
69431 } else {
69432 self->private_data.s_do_decode_image_config.scratch = 0;
69433 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
69434 while (true) {
69435 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
69436 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
69437 goto suspend;
69439 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
69440 uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
69441 *scratch <<= 8;
69442 *scratch >>= 8;
69443 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
69444 if (num_bits_4 == 8) {
69445 t_4 = ((uint16_t)(*scratch));
69446 break;
69448 num_bits_4 += 8u;
69449 *scratch |= ((uint64_t)(num_bits_4)) << 56;
69452 self->private_impl.f_header_color_map_length = t_4;
69455 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
69456 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
69457 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
69458 goto suspend;
69460 uint8_t t_5 = *iop_a_src++;
69461 self->private_impl.f_header_color_map_entry_size = t_5;
69463 if (self->private_impl.f_header_color_map_type != 0u) {
69464 if ((self->private_impl.f_header_color_map_first_entry_index != 0u) || (self->private_impl.f_header_color_map_length > 256u)) {
69465 status = wuffs_base__make_status(wuffs_tga__error__unsupported_tga_file);
69466 goto exit;
69467 } else if ((self->private_impl.f_header_color_map_entry_size != 15u) &&
69468 (self->private_impl.f_header_color_map_entry_size != 16u) &&
69469 (self->private_impl.f_header_color_map_entry_size != 24u) &&
69470 (self->private_impl.f_header_color_map_entry_size != 32u)) {
69471 status = wuffs_base__make_status(wuffs_tga__error__bad_header);
69472 goto exit;
69474 } else {
69475 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)) {
69476 status = wuffs_base__make_status(wuffs_tga__error__bad_header);
69477 goto exit;
69480 self->private_data.s_do_decode_image_config.scratch = 4u;
69481 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
69482 if (self->private_data.s_do_decode_image_config.scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
69483 self->private_data.s_do_decode_image_config.scratch -= ((uint64_t)(io2_a_src - iop_a_src));
69484 iop_a_src = io2_a_src;
69485 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
69486 goto suspend;
69488 iop_a_src += self->private_data.s_do_decode_image_config.scratch;
69490 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
69491 uint32_t t_6;
69492 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
69493 t_6 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
69494 iop_a_src += 2;
69495 } else {
69496 self->private_data.s_do_decode_image_config.scratch = 0;
69497 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
69498 while (true) {
69499 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
69500 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
69501 goto suspend;
69503 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
69504 uint32_t num_bits_6 = ((uint32_t)(*scratch >> 56));
69505 *scratch <<= 8;
69506 *scratch >>= 8;
69507 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_6;
69508 if (num_bits_6 == 8) {
69509 t_6 = ((uint32_t)(*scratch));
69510 break;
69512 num_bits_6 += 8u;
69513 *scratch |= ((uint64_t)(num_bits_6)) << 56;
69516 self->private_impl.f_width = t_6;
69519 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
69520 uint32_t t_7;
69521 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
69522 t_7 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
69523 iop_a_src += 2;
69524 } else {
69525 self->private_data.s_do_decode_image_config.scratch = 0;
69526 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
69527 while (true) {
69528 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
69529 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
69530 goto suspend;
69532 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
69533 uint32_t num_bits_7 = ((uint32_t)(*scratch >> 56));
69534 *scratch <<= 8;
69535 *scratch >>= 8;
69536 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_7;
69537 if (num_bits_7 == 8) {
69538 t_7 = ((uint32_t)(*scratch));
69539 break;
69541 num_bits_7 += 8u;
69542 *scratch |= ((uint64_t)(num_bits_7)) << 56;
69545 self->private_impl.f_height = t_7;
69548 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
69549 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
69550 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
69551 goto suspend;
69553 uint8_t t_8 = *iop_a_src++;
69554 self->private_impl.f_header_pixel_depth = t_8;
69556 if ((self->private_impl.f_header_pixel_depth != 1u) &&
69557 (self->private_impl.f_header_pixel_depth != 8u) &&
69558 (self->private_impl.f_header_pixel_depth != 15u) &&
69559 (self->private_impl.f_header_pixel_depth != 16u) &&
69560 (self->private_impl.f_header_pixel_depth != 24u) &&
69561 (self->private_impl.f_header_pixel_depth != 32u)) {
69562 status = wuffs_base__make_status(wuffs_tga__error__bad_header);
69563 goto exit;
69565 if (((uint8_t)(self->private_impl.f_header_image_type | 8u)) == 9u) {
69566 self->private_impl.f_scratch_bytes_per_pixel = 1u;
69567 self->private_impl.f_src_bytes_per_pixel = 1u;
69568 self->private_impl.f_src_pixfmt = 2164523016u;
69569 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));
69570 } else if (((uint8_t)(self->private_impl.f_header_image_type | 8u)) == 10u) {
69571 if ((self->private_impl.f_header_pixel_depth == 15u) || (self->private_impl.f_header_pixel_depth == 16u)) {
69572 self->private_impl.f_scratch_bytes_per_pixel = 4u;
69573 self->private_impl.f_src_bytes_per_pixel = 0u;
69574 self->private_impl.f_src_pixfmt = 2164295816u;
69575 } else if (self->private_impl.f_header_pixel_depth == 24u) {
69576 self->private_impl.f_scratch_bytes_per_pixel = 3u;
69577 self->private_impl.f_src_bytes_per_pixel = 3u;
69578 self->private_impl.f_src_pixfmt = 2147485832u;
69579 self->private_impl.f_opaque = true;
69580 } else if (self->private_impl.f_header_pixel_depth == 32u) {
69581 self->private_impl.f_scratch_bytes_per_pixel = 4u;
69582 self->private_impl.f_src_bytes_per_pixel = 4u;
69583 self->private_impl.f_src_pixfmt = 2164295816u;
69584 } else {
69585 status = wuffs_base__make_status(wuffs_tga__error__unsupported_tga_file);
69586 goto exit;
69588 } else {
69589 if (self->private_impl.f_header_pixel_depth == 8u) {
69590 self->private_impl.f_scratch_bytes_per_pixel = 1u;
69591 self->private_impl.f_src_bytes_per_pixel = 1u;
69592 self->private_impl.f_src_pixfmt = 536870920u;
69593 self->private_impl.f_opaque = true;
69594 } else {
69595 status = wuffs_base__make_status(wuffs_tga__error__unsupported_tga_file);
69596 goto exit;
69600 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
69601 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
69602 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
69603 goto suspend;
69605 uint8_t t_9 = *iop_a_src++;
69606 self->private_impl.f_header_image_descriptor = t_9;
69608 if (((uint8_t)(self->private_impl.f_header_image_descriptor & 16u)) != 0u) {
69609 status = wuffs_base__make_status(wuffs_tga__error__unsupported_tga_file);
69610 goto exit;
69612 self->private_data.s_do_decode_image_config.scratch = ((uint32_t)(self->private_impl.f_header_id_length));
69613 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
69614 if (self->private_data.s_do_decode_image_config.scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
69615 self->private_data.s_do_decode_image_config.scratch -= ((uint64_t)(io2_a_src - iop_a_src));
69616 iop_a_src = io2_a_src;
69617 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
69618 goto suspend;
69620 iop_a_src += self->private_data.s_do_decode_image_config.scratch;
69621 if (self->private_impl.f_header_color_map_type != 0u) {
69622 while (v_i < ((uint32_t)(self->private_impl.f_header_color_map_length))) {
69623 if (self->private_impl.f_header_color_map_entry_size == 24u) {
69625 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(17);
69626 uint32_t t_10;
69627 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) {
69628 t_10 = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src)));
69629 iop_a_src += 3;
69630 } else {
69631 self->private_data.s_do_decode_image_config.scratch = 0;
69632 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(18);
69633 while (true) {
69634 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
69635 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
69636 goto suspend;
69638 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
69639 uint32_t num_bits_10 = ((uint32_t)(*scratch >> 56));
69640 *scratch <<= 8;
69641 *scratch >>= 8;
69642 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_10;
69643 if (num_bits_10 == 16) {
69644 t_10 = ((uint32_t)(*scratch));
69645 break;
69647 num_bits_10 += 8u;
69648 *scratch |= ((uint64_t)(num_bits_10)) << 56;
69651 v_c32 = t_10;
69653 self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 0u)] = ((uint8_t)((v_c32 >> 0u)));
69654 self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 1u)] = ((uint8_t)((v_c32 >> 8u)));
69655 self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 2u)] = ((uint8_t)((v_c32 >> 16u)));
69656 self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 3u)] = 255u;
69657 } else if (self->private_impl.f_header_color_map_entry_size == 32u) {
69659 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(19);
69660 uint32_t t_11;
69661 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
69662 t_11 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
69663 iop_a_src += 4;
69664 } else {
69665 self->private_data.s_do_decode_image_config.scratch = 0;
69666 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(20);
69667 while (true) {
69668 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
69669 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
69670 goto suspend;
69672 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
69673 uint32_t num_bits_11 = ((uint32_t)(*scratch >> 56));
69674 *scratch <<= 8;
69675 *scratch >>= 8;
69676 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_11;
69677 if (num_bits_11 == 24) {
69678 t_11 = ((uint32_t)(*scratch));
69679 break;
69681 num_bits_11 += 8u;
69682 *scratch |= ((uint64_t)(num_bits_11)) << 56;
69685 v_c32 = t_11;
69687 self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 0u)] = ((uint8_t)((v_c32 >> 0u)));
69688 self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 1u)] = ((uint8_t)((v_c32 >> 8u)));
69689 self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 2u)] = ((uint8_t)((v_c32 >> 16u)));
69690 self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 3u)] = ((uint8_t)((v_c32 >> 24u)));
69691 } else {
69693 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(21);
69694 uint32_t t_12;
69695 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
69696 t_12 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
69697 iop_a_src += 2;
69698 } else {
69699 self->private_data.s_do_decode_image_config.scratch = 0;
69700 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(22);
69701 while (true) {
69702 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
69703 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
69704 goto suspend;
69706 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
69707 uint32_t num_bits_12 = ((uint32_t)(*scratch >> 56));
69708 *scratch <<= 8;
69709 *scratch >>= 8;
69710 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_12;
69711 if (num_bits_12 == 8) {
69712 t_12 = ((uint32_t)(*scratch));
69713 break;
69715 num_bits_12 += 8u;
69716 *scratch |= ((uint64_t)(num_bits_12)) << 56;
69719 v_c32 = t_12;
69721 v_c5 = (31u & (v_c32 >> 0u));
69722 self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 0u)] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u))));
69723 v_c5 = (31u & (v_c32 >> 5u));
69724 self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 1u)] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u))));
69725 v_c5 = (31u & (v_c32 >> 10u));
69726 self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 2u)] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u))));
69727 self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 3u)] = 255u;
69729 v_i += 1u;
69731 while (v_i < 256u) {
69732 self->private_data.f_src_palette[((v_i * 4u) + 0u)] = 0u;
69733 self->private_data.f_src_palette[((v_i * 4u) + 1u)] = 0u;
69734 self->private_data.f_src_palette[((v_i * 4u) + 2u)] = 0u;
69735 self->private_data.f_src_palette[((v_i * 4u) + 3u)] = 255u;
69736 v_i += 1u;
69739 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)));
69740 if (a_dst != NULL) {
69741 wuffs_base__image_config__set(
69742 a_dst,
69743 self->private_impl.f_src_pixfmt,
69745 self->private_impl.f_width,
69746 self->private_impl.f_height,
69747 self->private_impl.f_frame_config_io_position,
69748 self->private_impl.f_opaque);
69750 self->private_impl.f_call_sequence = 32u;
69752 goto ok;
69754 self->private_impl.p_do_decode_image_config = 0;
69755 goto exit;
69758 goto suspend;
69759 suspend:
69760 self->private_impl.p_do_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
69761 self->private_data.s_do_decode_image_config.v_i = v_i;
69763 goto exit;
69764 exit:
69765 if (a_src && a_src->data.ptr) {
69766 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
69769 return status;
69772 // -------- func tga.decoder.decode_frame_config
69774 WUFFS_BASE__GENERATED_C_CODE
69775 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
69776 wuffs_tga__decoder__decode_frame_config(
69777 wuffs_tga__decoder* self,
69778 wuffs_base__frame_config* a_dst,
69779 wuffs_base__io_buffer* a_src) {
69780 if (!self) {
69781 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
69783 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
69784 return wuffs_base__make_status(
69785 (self->private_impl.magic == WUFFS_BASE__DISABLED)
69786 ? wuffs_base__error__disabled_by_previous_error
69787 : wuffs_base__error__initialize_not_called);
69789 if (!a_src) {
69790 self->private_impl.magic = WUFFS_BASE__DISABLED;
69791 return wuffs_base__make_status(wuffs_base__error__bad_argument);
69793 if ((self->private_impl.active_coroutine != 0) &&
69794 (self->private_impl.active_coroutine != 2)) {
69795 self->private_impl.magic = WUFFS_BASE__DISABLED;
69796 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
69798 self->private_impl.active_coroutine = 0;
69799 wuffs_base__status status = wuffs_base__make_status(NULL);
69801 wuffs_base__status v_status = wuffs_base__make_status(NULL);
69803 uint32_t coro_susp_point = self->private_impl.p_decode_frame_config;
69804 switch (coro_susp_point) {
69805 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
69807 while (true) {
69809 wuffs_base__status t_0 = wuffs_tga__decoder__do_decode_frame_config(self, a_dst, a_src);
69810 v_status = t_0;
69812 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
69813 status = wuffs_base__make_status(wuffs_tga__error__truncated_input);
69814 goto exit;
69816 status = v_status;
69817 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
69821 self->private_impl.p_decode_frame_config = 0;
69822 goto exit;
69825 goto suspend;
69826 suspend:
69827 self->private_impl.p_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
69828 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
69830 goto exit;
69831 exit:
69832 if (wuffs_base__status__is_error(&status)) {
69833 self->private_impl.magic = WUFFS_BASE__DISABLED;
69835 return status;
69838 // -------- func tga.decoder.do_decode_frame_config
69840 WUFFS_BASE__GENERATED_C_CODE
69841 static wuffs_base__status
69842 wuffs_tga__decoder__do_decode_frame_config(
69843 wuffs_tga__decoder* self,
69844 wuffs_base__frame_config* a_dst,
69845 wuffs_base__io_buffer* a_src) {
69846 wuffs_base__status status = wuffs_base__make_status(NULL);
69848 const uint8_t* iop_a_src = NULL;
69849 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
69850 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
69851 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
69852 if (a_src && a_src->data.ptr) {
69853 io0_a_src = a_src->data.ptr;
69854 io1_a_src = io0_a_src + a_src->meta.ri;
69855 iop_a_src = io1_a_src;
69856 io2_a_src = io0_a_src + a_src->meta.wi;
69859 uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config;
69860 switch (coro_susp_point) {
69861 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
69863 if (self->private_impl.f_call_sequence == 32u) {
69864 } else if (self->private_impl.f_call_sequence < 32u) {
69865 if (a_src) {
69866 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
69868 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
69869 status = wuffs_tga__decoder__do_decode_image_config(self, NULL, a_src);
69870 if (a_src) {
69871 iop_a_src = a_src->data.ptr + a_src->meta.ri;
69873 if (status.repr) {
69874 goto suspend;
69876 } else if (self->private_impl.f_call_sequence == 40u) {
69877 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)))) {
69878 status = wuffs_base__make_status(wuffs_base__error__bad_restart);
69879 goto exit;
69881 } else if (self->private_impl.f_call_sequence == 64u) {
69882 self->private_impl.f_call_sequence = 96u;
69883 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
69884 goto ok;
69885 } else {
69886 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
69887 goto ok;
69889 if (a_dst != NULL) {
69890 wuffs_base__frame_config__set(
69891 a_dst,
69892 wuffs_base__utility__make_rect_ie_u32(
69895 self->private_impl.f_width,
69896 self->private_impl.f_height),
69897 ((wuffs_base__flicks)(0u)),
69899 self->private_impl.f_frame_config_io_position,
69901 self->private_impl.f_opaque,
69902 false,
69903 4278190080u);
69905 self->private_impl.f_call_sequence = 64u;
69908 self->private_impl.p_do_decode_frame_config = 0;
69909 goto exit;
69912 goto suspend;
69913 suspend:
69914 self->private_impl.p_do_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
69916 goto exit;
69917 exit:
69918 if (a_src && a_src->data.ptr) {
69919 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
69922 return status;
69925 // -------- func tga.decoder.decode_frame
69927 WUFFS_BASE__GENERATED_C_CODE
69928 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
69929 wuffs_tga__decoder__decode_frame(
69930 wuffs_tga__decoder* self,
69931 wuffs_base__pixel_buffer* a_dst,
69932 wuffs_base__io_buffer* a_src,
69933 wuffs_base__pixel_blend a_blend,
69934 wuffs_base__slice_u8 a_workbuf,
69935 wuffs_base__decode_frame_options* a_opts) {
69936 if (!self) {
69937 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
69939 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
69940 return wuffs_base__make_status(
69941 (self->private_impl.magic == WUFFS_BASE__DISABLED)
69942 ? wuffs_base__error__disabled_by_previous_error
69943 : wuffs_base__error__initialize_not_called);
69945 if (!a_dst || !a_src) {
69946 self->private_impl.magic = WUFFS_BASE__DISABLED;
69947 return wuffs_base__make_status(wuffs_base__error__bad_argument);
69949 if ((self->private_impl.active_coroutine != 0) &&
69950 (self->private_impl.active_coroutine != 3)) {
69951 self->private_impl.magic = WUFFS_BASE__DISABLED;
69952 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
69954 self->private_impl.active_coroutine = 0;
69955 wuffs_base__status status = wuffs_base__make_status(NULL);
69957 wuffs_base__status v_status = wuffs_base__make_status(NULL);
69959 uint32_t coro_susp_point = self->private_impl.p_decode_frame;
69960 switch (coro_susp_point) {
69961 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
69963 while (true) {
69965 wuffs_base__status t_0 = wuffs_tga__decoder__do_decode_frame(self,
69966 a_dst,
69967 a_src,
69968 a_blend,
69969 a_workbuf,
69970 a_opts);
69971 v_status = t_0;
69973 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
69974 status = wuffs_base__make_status(wuffs_tga__error__truncated_input);
69975 goto exit;
69977 status = v_status;
69978 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
69982 self->private_impl.p_decode_frame = 0;
69983 goto exit;
69986 goto suspend;
69987 suspend:
69988 self->private_impl.p_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
69989 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
69991 goto exit;
69992 exit:
69993 if (wuffs_base__status__is_error(&status)) {
69994 self->private_impl.magic = WUFFS_BASE__DISABLED;
69996 return status;
69999 // -------- func tga.decoder.do_decode_frame
70001 WUFFS_BASE__GENERATED_C_CODE
70002 static wuffs_base__status
70003 wuffs_tga__decoder__do_decode_frame(
70004 wuffs_tga__decoder* self,
70005 wuffs_base__pixel_buffer* a_dst,
70006 wuffs_base__io_buffer* a_src,
70007 wuffs_base__pixel_blend a_blend,
70008 wuffs_base__slice_u8 a_workbuf,
70009 wuffs_base__decode_frame_options* a_opts) {
70010 wuffs_base__status status = wuffs_base__make_status(NULL);
70012 wuffs_base__status v_status = wuffs_base__make_status(NULL);
70013 wuffs_base__pixel_format v_dst_pixfmt = {0};
70014 uint32_t v_dst_bits_per_pixel = 0;
70015 uint64_t v_dst_bytes_per_pixel = 0;
70016 uint32_t v_dst_x = 0;
70017 uint32_t v_dst_y = 0;
70018 wuffs_base__table_u8 v_tab = {0};
70019 wuffs_base__slice_u8 v_dst_palette = {0};
70020 wuffs_base__slice_u8 v_dst = {0};
70021 uint64_t v_dst_start = 0;
70022 wuffs_base__slice_u8 v_src_palette = {0};
70023 uint64_t v_mark = 0;
70024 uint64_t v_num_pixels64 = 0;
70025 uint32_t v_num_pixels32 = 0;
70026 uint32_t v_lit_length = 0;
70027 uint32_t v_run_length = 0;
70028 uint64_t v_num_dst_bytes = 0;
70029 uint32_t v_num_src_bytes = 0;
70030 uint32_t v_c32 = 0;
70031 uint32_t v_c5 = 0;
70033 const uint8_t* iop_a_src = NULL;
70034 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
70035 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
70036 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
70037 if (a_src && a_src->data.ptr) {
70038 io0_a_src = a_src->data.ptr;
70039 io1_a_src = io0_a_src + a_src->meta.ri;
70040 iop_a_src = io1_a_src;
70041 io2_a_src = io0_a_src + a_src->meta.wi;
70044 uint32_t coro_susp_point = self->private_impl.p_do_decode_frame;
70045 if (coro_susp_point) {
70046 v_dst_bytes_per_pixel = self->private_data.s_do_decode_frame.v_dst_bytes_per_pixel;
70047 v_dst_x = self->private_data.s_do_decode_frame.v_dst_x;
70048 v_dst_y = self->private_data.s_do_decode_frame.v_dst_y;
70049 v_mark = self->private_data.s_do_decode_frame.v_mark;
70050 v_num_pixels32 = self->private_data.s_do_decode_frame.v_num_pixels32;
70051 v_lit_length = self->private_data.s_do_decode_frame.v_lit_length;
70052 v_run_length = self->private_data.s_do_decode_frame.v_run_length;
70053 v_num_dst_bytes = self->private_data.s_do_decode_frame.v_num_dst_bytes;
70055 switch (coro_susp_point) {
70056 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
70058 if (self->private_impl.f_call_sequence == 64u) {
70059 } else if (self->private_impl.f_call_sequence < 64u) {
70060 if (a_src) {
70061 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
70063 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
70064 status = wuffs_tga__decoder__do_decode_frame_config(self, NULL, a_src);
70065 if (a_src) {
70066 iop_a_src = a_src->data.ptr + a_src->meta.ri;
70068 if (status.repr) {
70069 goto suspend;
70071 } else {
70072 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
70073 goto ok;
70075 if (self->private_impl.f_header_color_map_type != 0u) {
70076 v_src_palette = wuffs_base__make_slice_u8(self->private_data.f_src_palette, 1024);
70078 v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
70079 wuffs_base__pixel_buffer__pixel_format(a_dst),
70080 wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)),
70081 wuffs_base__utility__make_pixel_format(self->private_impl.f_src_pixfmt),
70082 v_src_palette,
70083 a_blend);
70084 if ( ! wuffs_base__status__is_ok(&v_status)) {
70085 status = v_status;
70086 if (wuffs_base__status__is_error(&status)) {
70087 goto exit;
70088 } else if (wuffs_base__status__is_suspension(&status)) {
70089 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
70090 goto exit;
70092 goto ok;
70094 v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
70095 v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
70096 if ((v_dst_bits_per_pixel & 7u) != 0u) {
70097 status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
70098 goto exit;
70100 v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8u)));
70101 if (((uint8_t)(self->private_impl.f_header_image_descriptor & 32u)) == 0u) {
70102 v_dst_y = ((uint32_t)(self->private_impl.f_height - 1u));
70104 if (((uint8_t)(self->private_impl.f_header_image_type & 8u)) == 0u) {
70105 v_lit_length = self->private_impl.f_width;
70107 label__resume__continue:;
70108 while (true) {
70109 v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
70110 v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024));
70111 while (v_dst_y < self->private_impl.f_height) {
70112 v_dst = wuffs_private_impl__table_u8__row_u32(v_tab, v_dst_y);
70113 v_dst_start = (((uint64_t)(v_dst_x)) * v_dst_bytes_per_pixel);
70114 if (v_dst_start <= ((uint64_t)(v_dst.len))) {
70115 v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_start);
70116 } else {
70117 v_dst = wuffs_base__utility__empty_slice_u8();
70119 while (v_dst_x < self->private_impl.f_width) {
70120 if (self->private_impl.f_src_bytes_per_pixel > 0u) {
70121 if (v_lit_length > 0u) {
70122 v_mark = ((uint64_t)(iop_a_src - io0_a_src));
70123 v_num_pixels64 = (((uint64_t)(io2_a_src - iop_a_src)) / ((uint64_t)(self->private_impl.f_src_bytes_per_pixel)));
70124 v_num_pixels32 = ((uint32_t)(wuffs_base__u64__min(v_num_pixels64, ((uint64_t)(v_lit_length)))));
70125 v_num_dst_bytes = (((uint64_t)(v_num_pixels32)) * v_dst_bytes_per_pixel);
70126 v_num_src_bytes = (v_num_pixels32 * self->private_impl.f_src_bytes_per_pixel);
70127 self->private_data.s_do_decode_frame.scratch = v_num_src_bytes;
70128 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
70129 if (self->private_data.s_do_decode_frame.scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
70130 self->private_data.s_do_decode_frame.scratch -= ((uint64_t)(io2_a_src - iop_a_src));
70131 iop_a_src = io2_a_src;
70132 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
70133 goto suspend;
70135 iop_a_src += self->private_data.s_do_decode_frame.scratch;
70136 wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, wuffs_private_impl__io__since(v_mark, ((uint64_t)(iop_a_src - io0_a_src)), io0_a_src));
70137 if (v_num_dst_bytes <= ((uint64_t)(v_dst.len))) {
70138 v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_num_dst_bytes);
70139 } else {
70140 v_dst = wuffs_base__utility__empty_slice_u8();
70142 v_dst_x += v_num_pixels32;
70143 v_lit_length = (((uint32_t)(v_lit_length - v_num_pixels32)) & 65535u);
70144 if (v_lit_length > 0u) {
70145 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
70146 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
70147 goto label__resume__continue;
70149 } else if (v_run_length > 0u) {
70150 v_run_length -= 1u;
70151 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));
70152 if (v_dst_bytes_per_pixel <= ((uint64_t)(v_dst.len))) {
70153 v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_bytes_per_pixel);
70155 v_dst_x += 1u;
70156 } else {
70157 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
70158 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
70159 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
70160 goto label__resume__continue;
70162 if (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) < 128u) {
70163 v_lit_length = (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) + 1u);
70164 iop_a_src += 1u;
70165 if ((v_lit_length + v_dst_x) > self->private_impl.f_width) {
70166 status = wuffs_base__make_status(wuffs_tga__error__bad_run_length_encoding);
70167 goto exit;
70169 } else {
70170 if (self->private_impl.f_src_bytes_per_pixel == 1u) {
70171 if (((uint64_t)(io2_a_src - iop_a_src)) < 2u) {
70172 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
70173 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
70174 goto label__resume__continue;
70176 v_run_length = ((((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) & 127u) + 1u);
70177 iop_a_src += 1u;
70178 self->private_data.f_scratch[0u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
70179 iop_a_src += 1u;
70180 } else if (self->private_impl.f_src_bytes_per_pixel == 3u) {
70181 if (((uint64_t)(io2_a_src - iop_a_src)) < 4u) {
70182 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
70183 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
70184 goto label__resume__continue;
70186 v_run_length = ((((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) & 127u) + 1u);
70187 iop_a_src += 1u;
70188 self->private_data.f_scratch[0u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
70189 iop_a_src += 1u;
70190 self->private_data.f_scratch[1u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
70191 iop_a_src += 1u;
70192 self->private_data.f_scratch[2u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
70193 iop_a_src += 1u;
70194 } else {
70195 if (((uint64_t)(io2_a_src - iop_a_src)) < 5u) {
70196 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
70197 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7);
70198 goto label__resume__continue;
70200 v_run_length = ((((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) & 127u) + 1u);
70201 iop_a_src += 1u;
70202 self->private_data.f_scratch[0u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
70203 iop_a_src += 1u;
70204 self->private_data.f_scratch[1u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
70205 iop_a_src += 1u;
70206 self->private_data.f_scratch[2u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
70207 iop_a_src += 1u;
70208 self->private_data.f_scratch[3u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
70209 iop_a_src += 1u;
70211 if ((v_run_length + v_dst_x) > self->private_impl.f_width) {
70212 status = wuffs_base__make_status(wuffs_tga__error__bad_run_length_encoding);
70213 goto exit;
70217 } else {
70218 if (v_lit_length > 0u) {
70219 if (((uint64_t)(io2_a_src - iop_a_src)) < 2u) {
70220 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
70221 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8);
70222 goto label__resume__continue;
70224 v_c32 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
70225 iop_a_src += 2u;
70226 v_c5 = (31u & (v_c32 >> 0u));
70227 self->private_data.f_scratch[0u] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u))));
70228 v_c5 = (31u & (v_c32 >> 5u));
70229 self->private_data.f_scratch[1u] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u))));
70230 v_c5 = (31u & (v_c32 >> 10u));
70231 self->private_data.f_scratch[2u] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u))));
70232 self->private_data.f_scratch[3u] = 255u;
70233 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));
70234 if (v_dst_bytes_per_pixel <= ((uint64_t)(v_dst.len))) {
70235 v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_bytes_per_pixel);
70237 v_dst_x += 1u;
70238 v_lit_length -= 1u;
70239 } else if (v_run_length > 0u) {
70240 v_run_length -= 1u;
70241 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));
70242 if (v_dst_bytes_per_pixel <= ((uint64_t)(v_dst.len))) {
70243 v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_bytes_per_pixel);
70245 v_dst_x += 1u;
70246 } else {
70247 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
70248 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
70249 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9);
70250 goto label__resume__continue;
70252 if (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) < 128u) {
70253 v_lit_length = (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) + 1u);
70254 iop_a_src += 1u;
70255 if ((v_lit_length + v_dst_x) > self->private_impl.f_width) {
70256 status = wuffs_base__make_status(wuffs_tga__error__bad_run_length_encoding);
70257 goto exit;
70259 } else {
70260 if (((uint64_t)(io2_a_src - iop_a_src)) < 3u) {
70261 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
70262 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10);
70263 goto label__resume__continue;
70265 v_run_length = ((((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) & 127u) + 1u);
70266 iop_a_src += 1u;
70267 v_c32 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
70268 iop_a_src += 2u;
70269 v_c5 = (31u & (v_c32 >> 0u));
70270 self->private_data.f_scratch[0u] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u))));
70271 v_c5 = (31u & (v_c32 >> 5u));
70272 self->private_data.f_scratch[1u] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u))));
70273 v_c5 = (31u & (v_c32 >> 10u));
70274 self->private_data.f_scratch[2u] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u))));
70275 self->private_data.f_scratch[3u] = 255u;
70276 if ((v_run_length + v_dst_x) > self->private_impl.f_width) {
70277 status = wuffs_base__make_status(wuffs_tga__error__bad_run_length_encoding);
70278 goto exit;
70284 v_dst_x = 0u;
70285 if (((uint8_t)(self->private_impl.f_header_image_descriptor & 32u)) == 0u) {
70286 v_dst_y -= 1u;
70287 } else {
70288 v_dst_y += 1u;
70290 if (((uint8_t)(self->private_impl.f_header_image_type & 8u)) == 0u) {
70291 v_lit_length = self->private_impl.f_width;
70294 break;
70296 self->private_impl.f_call_sequence = 96u;
70299 self->private_impl.p_do_decode_frame = 0;
70300 goto exit;
70303 goto suspend;
70304 suspend:
70305 self->private_impl.p_do_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
70306 self->private_data.s_do_decode_frame.v_dst_bytes_per_pixel = v_dst_bytes_per_pixel;
70307 self->private_data.s_do_decode_frame.v_dst_x = v_dst_x;
70308 self->private_data.s_do_decode_frame.v_dst_y = v_dst_y;
70309 self->private_data.s_do_decode_frame.v_mark = v_mark;
70310 self->private_data.s_do_decode_frame.v_num_pixels32 = v_num_pixels32;
70311 self->private_data.s_do_decode_frame.v_lit_length = v_lit_length;
70312 self->private_data.s_do_decode_frame.v_run_length = v_run_length;
70313 self->private_data.s_do_decode_frame.v_num_dst_bytes = v_num_dst_bytes;
70315 goto exit;
70316 exit:
70317 if (a_src && a_src->data.ptr) {
70318 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
70321 return status;
70324 // -------- func tga.decoder.frame_dirty_rect
70326 WUFFS_BASE__GENERATED_C_CODE
70327 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
70328 wuffs_tga__decoder__frame_dirty_rect(
70329 const wuffs_tga__decoder* self) {
70330 if (!self) {
70331 return wuffs_base__utility__empty_rect_ie_u32();
70333 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
70334 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
70335 return wuffs_base__utility__empty_rect_ie_u32();
70338 return wuffs_base__utility__make_rect_ie_u32(
70341 self->private_impl.f_width,
70342 self->private_impl.f_height);
70345 // -------- func tga.decoder.num_animation_loops
70347 WUFFS_BASE__GENERATED_C_CODE
70348 WUFFS_BASE__MAYBE_STATIC uint32_t
70349 wuffs_tga__decoder__num_animation_loops(
70350 const wuffs_tga__decoder* self) {
70351 if (!self) {
70352 return 0;
70354 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
70355 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
70356 return 0;
70359 return 0u;
70362 // -------- func tga.decoder.num_decoded_frame_configs
70364 WUFFS_BASE__GENERATED_C_CODE
70365 WUFFS_BASE__MAYBE_STATIC uint64_t
70366 wuffs_tga__decoder__num_decoded_frame_configs(
70367 const wuffs_tga__decoder* self) {
70368 if (!self) {
70369 return 0;
70371 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
70372 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
70373 return 0;
70376 if (self->private_impl.f_call_sequence > 32u) {
70377 return 1u;
70379 return 0u;
70382 // -------- func tga.decoder.num_decoded_frames
70384 WUFFS_BASE__GENERATED_C_CODE
70385 WUFFS_BASE__MAYBE_STATIC uint64_t
70386 wuffs_tga__decoder__num_decoded_frames(
70387 const wuffs_tga__decoder* self) {
70388 if (!self) {
70389 return 0;
70391 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
70392 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
70393 return 0;
70396 if (self->private_impl.f_call_sequence > 64u) {
70397 return 1u;
70399 return 0u;
70402 // -------- func tga.decoder.restart_frame
70404 WUFFS_BASE__GENERATED_C_CODE
70405 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
70406 wuffs_tga__decoder__restart_frame(
70407 wuffs_tga__decoder* self,
70408 uint64_t a_index,
70409 uint64_t a_io_position) {
70410 if (!self) {
70411 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
70413 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
70414 return wuffs_base__make_status(
70415 (self->private_impl.magic == WUFFS_BASE__DISABLED)
70416 ? wuffs_base__error__disabled_by_previous_error
70417 : wuffs_base__error__initialize_not_called);
70420 if (self->private_impl.f_call_sequence < 32u) {
70421 return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
70423 if (a_index != 0u) {
70424 return wuffs_base__make_status(wuffs_base__error__bad_argument);
70426 self->private_impl.f_call_sequence = 40u;
70427 self->private_impl.f_frame_config_io_position = a_io_position;
70428 return wuffs_base__make_status(NULL);
70431 // -------- func tga.decoder.set_report_metadata
70433 WUFFS_BASE__GENERATED_C_CODE
70434 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
70435 wuffs_tga__decoder__set_report_metadata(
70436 wuffs_tga__decoder* self,
70437 uint32_t a_fourcc,
70438 bool a_report) {
70439 return wuffs_base__make_empty_struct();
70442 // -------- func tga.decoder.tell_me_more
70444 WUFFS_BASE__GENERATED_C_CODE
70445 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
70446 wuffs_tga__decoder__tell_me_more(
70447 wuffs_tga__decoder* self,
70448 wuffs_base__io_buffer* a_dst,
70449 wuffs_base__more_information* a_minfo,
70450 wuffs_base__io_buffer* a_src) {
70451 if (!self) {
70452 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
70454 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
70455 return wuffs_base__make_status(
70456 (self->private_impl.magic == WUFFS_BASE__DISABLED)
70457 ? wuffs_base__error__disabled_by_previous_error
70458 : wuffs_base__error__initialize_not_called);
70460 if (!a_dst || !a_src) {
70461 self->private_impl.magic = WUFFS_BASE__DISABLED;
70462 return wuffs_base__make_status(wuffs_base__error__bad_argument);
70464 if ((self->private_impl.active_coroutine != 0) &&
70465 (self->private_impl.active_coroutine != 4)) {
70466 self->private_impl.magic = WUFFS_BASE__DISABLED;
70467 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
70469 self->private_impl.active_coroutine = 0;
70470 wuffs_base__status status = wuffs_base__make_status(NULL);
70472 status = wuffs_base__make_status(wuffs_base__error__no_more_information);
70473 goto exit;
70475 goto ok;
70477 goto exit;
70478 exit:
70479 if (wuffs_base__status__is_error(&status)) {
70480 self->private_impl.magic = WUFFS_BASE__DISABLED;
70482 return status;
70485 // -------- func tga.decoder.workbuf_len
70487 WUFFS_BASE__GENERATED_C_CODE
70488 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
70489 wuffs_tga__decoder__workbuf_len(
70490 const wuffs_tga__decoder* self) {
70491 if (!self) {
70492 return wuffs_base__utility__empty_range_ii_u64();
70494 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
70495 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
70496 return wuffs_base__utility__empty_range_ii_u64();
70499 return wuffs_base__utility__make_range_ii_u64(0u, 0u);
70502 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__TGA)
70504 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__VP8)
70506 // ---------------- Status Codes Implementations
70508 // ---------------- Private Consts
70510 // ---------------- Private Initializer Prototypes
70512 // ---------------- Private Function Prototypes
70514 // ---------------- VTables
70516 // ---------------- Initializer Implementations
70518 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
70519 wuffs_vp8__placeholder__initialize(
70520 wuffs_vp8__placeholder* self,
70521 size_t sizeof_star_self,
70522 uint64_t wuffs_version,
70523 uint32_t options){
70524 if (!self) {
70525 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
70527 if (sizeof(*self) != sizeof_star_self) {
70528 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
70530 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
70531 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
70532 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
70535 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
70536 // The whole point of this if-check is to detect an uninitialized *self.
70537 // We disable the warning on GCC. Clang-5.0 does not have this warning.
70538 #if !defined(__clang__) && defined(__GNUC__)
70539 #pragma GCC diagnostic push
70540 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
70541 #endif
70542 if (self->private_impl.magic != 0) {
70543 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
70545 #if !defined(__clang__) && defined(__GNUC__)
70546 #pragma GCC diagnostic pop
70547 #endif
70548 } else {
70549 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
70550 memset(self, 0, sizeof(*self));
70551 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
70552 } else {
70553 memset(&(self->private_impl), 0, sizeof(self->private_impl));
70557 self->private_impl.magic = WUFFS_BASE__MAGIC;
70558 return wuffs_base__make_status(NULL);
70561 wuffs_vp8__placeholder*
70562 wuffs_vp8__placeholder__alloc(void) {
70563 wuffs_vp8__placeholder* x =
70564 (wuffs_vp8__placeholder*)(calloc(1, sizeof(wuffs_vp8__placeholder)));
70565 if (!x) {
70566 return NULL;
70568 if (wuffs_vp8__placeholder__initialize(
70569 x, sizeof(wuffs_vp8__placeholder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
70570 free(x);
70571 return NULL;
70573 return x;
70576 size_t
70577 sizeof__wuffs_vp8__placeholder(void) {
70578 return sizeof(wuffs_vp8__placeholder);
70581 // ---------------- Function Implementations
70583 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__VP8)
70585 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP)
70587 // ---------------- Status Codes Implementations
70589 const char wuffs_wbmp__error__bad_header[] = "#wbmp: bad header";
70590 const char wuffs_wbmp__error__truncated_input[] = "#wbmp: truncated input";
70592 // ---------------- Private Consts
70594 // ---------------- Private Initializer Prototypes
70596 // ---------------- Private Function Prototypes
70598 WUFFS_BASE__GENERATED_C_CODE
70599 static wuffs_base__status
70600 wuffs_wbmp__decoder__do_decode_image_config(
70601 wuffs_wbmp__decoder* self,
70602 wuffs_base__image_config* a_dst,
70603 wuffs_base__io_buffer* a_src);
70605 WUFFS_BASE__GENERATED_C_CODE
70606 static wuffs_base__status
70607 wuffs_wbmp__decoder__do_decode_frame_config(
70608 wuffs_wbmp__decoder* self,
70609 wuffs_base__frame_config* a_dst,
70610 wuffs_base__io_buffer* a_src);
70612 WUFFS_BASE__GENERATED_C_CODE
70613 static wuffs_base__status
70614 wuffs_wbmp__decoder__do_decode_frame(
70615 wuffs_wbmp__decoder* self,
70616 wuffs_base__pixel_buffer* a_dst,
70617 wuffs_base__io_buffer* a_src,
70618 wuffs_base__pixel_blend a_blend,
70619 wuffs_base__slice_u8 a_workbuf,
70620 wuffs_base__decode_frame_options* a_opts);
70622 // ---------------- VTables
70624 const wuffs_base__image_decoder__func_ptrs
70625 wuffs_wbmp__decoder__func_ptrs_for__wuffs_base__image_decoder = {
70626 (wuffs_base__status(*)(void*,
70627 wuffs_base__pixel_buffer*,
70628 wuffs_base__io_buffer*,
70629 wuffs_base__pixel_blend,
70630 wuffs_base__slice_u8,
70631 wuffs_base__decode_frame_options*))(&wuffs_wbmp__decoder__decode_frame),
70632 (wuffs_base__status(*)(void*,
70633 wuffs_base__frame_config*,
70634 wuffs_base__io_buffer*))(&wuffs_wbmp__decoder__decode_frame_config),
70635 (wuffs_base__status(*)(void*,
70636 wuffs_base__image_config*,
70637 wuffs_base__io_buffer*))(&wuffs_wbmp__decoder__decode_image_config),
70638 (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_wbmp__decoder__frame_dirty_rect),
70639 (uint64_t(*)(const void*,
70640 uint32_t))(&wuffs_wbmp__decoder__get_quirk),
70641 (uint32_t(*)(const void*))(&wuffs_wbmp__decoder__num_animation_loops),
70642 (uint64_t(*)(const void*))(&wuffs_wbmp__decoder__num_decoded_frame_configs),
70643 (uint64_t(*)(const void*))(&wuffs_wbmp__decoder__num_decoded_frames),
70644 (wuffs_base__status(*)(void*,
70645 uint64_t,
70646 uint64_t))(&wuffs_wbmp__decoder__restart_frame),
70647 (wuffs_base__status(*)(void*,
70648 uint32_t,
70649 uint64_t))(&wuffs_wbmp__decoder__set_quirk),
70650 (wuffs_base__empty_struct(*)(void*,
70651 uint32_t,
70652 bool))(&wuffs_wbmp__decoder__set_report_metadata),
70653 (wuffs_base__status(*)(void*,
70654 wuffs_base__io_buffer*,
70655 wuffs_base__more_information*,
70656 wuffs_base__io_buffer*))(&wuffs_wbmp__decoder__tell_me_more),
70657 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_wbmp__decoder__workbuf_len),
70660 // ---------------- Initializer Implementations
70662 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
70663 wuffs_wbmp__decoder__initialize(
70664 wuffs_wbmp__decoder* self,
70665 size_t sizeof_star_self,
70666 uint64_t wuffs_version,
70667 uint32_t options){
70668 if (!self) {
70669 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
70671 if (sizeof(*self) != sizeof_star_self) {
70672 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
70674 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
70675 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
70676 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
70679 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
70680 // The whole point of this if-check is to detect an uninitialized *self.
70681 // We disable the warning on GCC. Clang-5.0 does not have this warning.
70682 #if !defined(__clang__) && defined(__GNUC__)
70683 #pragma GCC diagnostic push
70684 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
70685 #endif
70686 if (self->private_impl.magic != 0) {
70687 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
70689 #if !defined(__clang__) && defined(__GNUC__)
70690 #pragma GCC diagnostic pop
70691 #endif
70692 } else {
70693 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
70694 memset(self, 0, sizeof(*self));
70695 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
70696 } else {
70697 memset(&(self->private_impl), 0, sizeof(self->private_impl));
70701 self->private_impl.magic = WUFFS_BASE__MAGIC;
70702 self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
70703 wuffs_base__image_decoder__vtable_name;
70704 self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
70705 (const void*)(&wuffs_wbmp__decoder__func_ptrs_for__wuffs_base__image_decoder);
70706 return wuffs_base__make_status(NULL);
70709 wuffs_wbmp__decoder*
70710 wuffs_wbmp__decoder__alloc(void) {
70711 wuffs_wbmp__decoder* x =
70712 (wuffs_wbmp__decoder*)(calloc(1, sizeof(wuffs_wbmp__decoder)));
70713 if (!x) {
70714 return NULL;
70716 if (wuffs_wbmp__decoder__initialize(
70717 x, sizeof(wuffs_wbmp__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
70718 free(x);
70719 return NULL;
70721 return x;
70724 size_t
70725 sizeof__wuffs_wbmp__decoder(void) {
70726 return sizeof(wuffs_wbmp__decoder);
70729 // ---------------- Function Implementations
70731 // -------- func wbmp.decoder.get_quirk
70733 WUFFS_BASE__GENERATED_C_CODE
70734 WUFFS_BASE__MAYBE_STATIC uint64_t
70735 wuffs_wbmp__decoder__get_quirk(
70736 const wuffs_wbmp__decoder* self,
70737 uint32_t a_key) {
70738 if (!self) {
70739 return 0;
70741 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
70742 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
70743 return 0;
70746 return 0u;
70749 // -------- func wbmp.decoder.set_quirk
70751 WUFFS_BASE__GENERATED_C_CODE
70752 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
70753 wuffs_wbmp__decoder__set_quirk(
70754 wuffs_wbmp__decoder* self,
70755 uint32_t a_key,
70756 uint64_t a_value) {
70757 if (!self) {
70758 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
70760 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
70761 return wuffs_base__make_status(
70762 (self->private_impl.magic == WUFFS_BASE__DISABLED)
70763 ? wuffs_base__error__disabled_by_previous_error
70764 : wuffs_base__error__initialize_not_called);
70767 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
70770 // -------- func wbmp.decoder.decode_image_config
70772 WUFFS_BASE__GENERATED_C_CODE
70773 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
70774 wuffs_wbmp__decoder__decode_image_config(
70775 wuffs_wbmp__decoder* self,
70776 wuffs_base__image_config* a_dst,
70777 wuffs_base__io_buffer* a_src) {
70778 if (!self) {
70779 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
70781 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
70782 return wuffs_base__make_status(
70783 (self->private_impl.magic == WUFFS_BASE__DISABLED)
70784 ? wuffs_base__error__disabled_by_previous_error
70785 : wuffs_base__error__initialize_not_called);
70787 if (!a_src) {
70788 self->private_impl.magic = WUFFS_BASE__DISABLED;
70789 return wuffs_base__make_status(wuffs_base__error__bad_argument);
70791 if ((self->private_impl.active_coroutine != 0) &&
70792 (self->private_impl.active_coroutine != 1)) {
70793 self->private_impl.magic = WUFFS_BASE__DISABLED;
70794 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
70796 self->private_impl.active_coroutine = 0;
70797 wuffs_base__status status = wuffs_base__make_status(NULL);
70799 wuffs_base__status v_status = wuffs_base__make_status(NULL);
70801 uint32_t coro_susp_point = self->private_impl.p_decode_image_config;
70802 switch (coro_susp_point) {
70803 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
70805 while (true) {
70807 wuffs_base__status t_0 = wuffs_wbmp__decoder__do_decode_image_config(self, a_dst, a_src);
70808 v_status = t_0;
70810 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
70811 status = wuffs_base__make_status(wuffs_wbmp__error__truncated_input);
70812 goto exit;
70814 status = v_status;
70815 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
70819 self->private_impl.p_decode_image_config = 0;
70820 goto exit;
70823 goto suspend;
70824 suspend:
70825 self->private_impl.p_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
70826 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
70828 goto exit;
70829 exit:
70830 if (wuffs_base__status__is_error(&status)) {
70831 self->private_impl.magic = WUFFS_BASE__DISABLED;
70833 return status;
70836 // -------- func wbmp.decoder.do_decode_image_config
70838 WUFFS_BASE__GENERATED_C_CODE
70839 static wuffs_base__status
70840 wuffs_wbmp__decoder__do_decode_image_config(
70841 wuffs_wbmp__decoder* self,
70842 wuffs_base__image_config* a_dst,
70843 wuffs_base__io_buffer* a_src) {
70844 wuffs_base__status status = wuffs_base__make_status(NULL);
70846 uint8_t v_c8 = 0;
70847 uint32_t v_i = 0;
70848 uint32_t v_p = 0;
70850 const uint8_t* iop_a_src = NULL;
70851 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
70852 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
70853 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
70854 if (a_src && a_src->data.ptr) {
70855 io0_a_src = a_src->data.ptr;
70856 io1_a_src = io0_a_src + a_src->meta.ri;
70857 iop_a_src = io1_a_src;
70858 io2_a_src = io0_a_src + a_src->meta.wi;
70861 uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config;
70862 if (coro_susp_point) {
70863 v_i = self->private_data.s_do_decode_image_config.v_i;
70864 v_p = self->private_data.s_do_decode_image_config.v_p;
70866 switch (coro_susp_point) {
70867 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
70869 if (self->private_impl.f_call_sequence != 0u) {
70870 status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
70871 goto exit;
70873 v_i = 0u;
70874 while (v_i < 2u) {
70876 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
70877 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
70878 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
70879 goto suspend;
70881 uint8_t t_0 = *iop_a_src++;
70882 v_c8 = t_0;
70884 if (v_c8 != 0u) {
70885 status = wuffs_base__make_status(wuffs_wbmp__error__bad_header);
70886 goto exit;
70888 v_i += 1u;
70890 v_i = 0u;
70891 while (v_i < 2u) {
70892 v_p = 0u;
70893 while (true) {
70895 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
70896 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
70897 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
70898 goto suspend;
70900 uint8_t t_1 = *iop_a_src++;
70901 v_c8 = t_1;
70903 v_p |= ((uint32_t)(((uint8_t)(v_c8 & 127u))));
70904 if (((uint8_t)(v_c8 >> 7u)) == 0u) {
70905 break;
70906 } else if (v_p > 131071u) {
70907 status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension);
70908 goto exit;
70910 v_p <<= 7u;
70912 if (v_i == 0u) {
70913 self->private_impl.f_width = v_p;
70914 } else {
70915 self->private_impl.f_height = v_p;
70917 v_i += 1u;
70919 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)));
70920 if (a_dst != NULL) {
70921 wuffs_base__image_config__set(
70922 a_dst,
70923 2198077448u,
70925 self->private_impl.f_width,
70926 self->private_impl.f_height,
70927 self->private_impl.f_frame_config_io_position,
70928 true);
70930 self->private_impl.f_call_sequence = 32u;
70932 goto ok;
70934 self->private_impl.p_do_decode_image_config = 0;
70935 goto exit;
70938 goto suspend;
70939 suspend:
70940 self->private_impl.p_do_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
70941 self->private_data.s_do_decode_image_config.v_i = v_i;
70942 self->private_data.s_do_decode_image_config.v_p = v_p;
70944 goto exit;
70945 exit:
70946 if (a_src && a_src->data.ptr) {
70947 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
70950 return status;
70953 // -------- func wbmp.decoder.decode_frame_config
70955 WUFFS_BASE__GENERATED_C_CODE
70956 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
70957 wuffs_wbmp__decoder__decode_frame_config(
70958 wuffs_wbmp__decoder* self,
70959 wuffs_base__frame_config* a_dst,
70960 wuffs_base__io_buffer* a_src) {
70961 if (!self) {
70962 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
70964 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
70965 return wuffs_base__make_status(
70966 (self->private_impl.magic == WUFFS_BASE__DISABLED)
70967 ? wuffs_base__error__disabled_by_previous_error
70968 : wuffs_base__error__initialize_not_called);
70970 if (!a_src) {
70971 self->private_impl.magic = WUFFS_BASE__DISABLED;
70972 return wuffs_base__make_status(wuffs_base__error__bad_argument);
70974 if ((self->private_impl.active_coroutine != 0) &&
70975 (self->private_impl.active_coroutine != 2)) {
70976 self->private_impl.magic = WUFFS_BASE__DISABLED;
70977 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
70979 self->private_impl.active_coroutine = 0;
70980 wuffs_base__status status = wuffs_base__make_status(NULL);
70982 wuffs_base__status v_status = wuffs_base__make_status(NULL);
70984 uint32_t coro_susp_point = self->private_impl.p_decode_frame_config;
70985 switch (coro_susp_point) {
70986 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
70988 while (true) {
70990 wuffs_base__status t_0 = wuffs_wbmp__decoder__do_decode_frame_config(self, a_dst, a_src);
70991 v_status = t_0;
70993 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
70994 status = wuffs_base__make_status(wuffs_wbmp__error__truncated_input);
70995 goto exit;
70997 status = v_status;
70998 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
71002 self->private_impl.p_decode_frame_config = 0;
71003 goto exit;
71006 goto suspend;
71007 suspend:
71008 self->private_impl.p_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
71009 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
71011 goto exit;
71012 exit:
71013 if (wuffs_base__status__is_error(&status)) {
71014 self->private_impl.magic = WUFFS_BASE__DISABLED;
71016 return status;
71019 // -------- func wbmp.decoder.do_decode_frame_config
71021 WUFFS_BASE__GENERATED_C_CODE
71022 static wuffs_base__status
71023 wuffs_wbmp__decoder__do_decode_frame_config(
71024 wuffs_wbmp__decoder* self,
71025 wuffs_base__frame_config* a_dst,
71026 wuffs_base__io_buffer* a_src) {
71027 wuffs_base__status status = wuffs_base__make_status(NULL);
71029 const uint8_t* iop_a_src = NULL;
71030 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
71031 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
71032 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
71033 if (a_src && a_src->data.ptr) {
71034 io0_a_src = a_src->data.ptr;
71035 io1_a_src = io0_a_src + a_src->meta.ri;
71036 iop_a_src = io1_a_src;
71037 io2_a_src = io0_a_src + a_src->meta.wi;
71040 uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config;
71041 switch (coro_susp_point) {
71042 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
71044 if (self->private_impl.f_call_sequence == 32u) {
71045 } else if (self->private_impl.f_call_sequence < 32u) {
71046 if (a_src) {
71047 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
71049 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
71050 status = wuffs_wbmp__decoder__do_decode_image_config(self, NULL, a_src);
71051 if (a_src) {
71052 iop_a_src = a_src->data.ptr + a_src->meta.ri;
71054 if (status.repr) {
71055 goto suspend;
71057 } else if (self->private_impl.f_call_sequence == 40u) {
71058 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)))) {
71059 status = wuffs_base__make_status(wuffs_base__error__bad_restart);
71060 goto exit;
71062 } else if (self->private_impl.f_call_sequence == 64u) {
71063 self->private_impl.f_call_sequence = 96u;
71064 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
71065 goto ok;
71066 } else {
71067 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
71068 goto ok;
71070 if (a_dst != NULL) {
71071 wuffs_base__frame_config__set(
71072 a_dst,
71073 wuffs_base__utility__make_rect_ie_u32(
71076 self->private_impl.f_width,
71077 self->private_impl.f_height),
71078 ((wuffs_base__flicks)(0u)),
71080 self->private_impl.f_frame_config_io_position,
71082 true,
71083 false,
71084 4278190080u);
71086 self->private_impl.f_call_sequence = 64u;
71089 self->private_impl.p_do_decode_frame_config = 0;
71090 goto exit;
71093 goto suspend;
71094 suspend:
71095 self->private_impl.p_do_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
71097 goto exit;
71098 exit:
71099 if (a_src && a_src->data.ptr) {
71100 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
71103 return status;
71106 // -------- func wbmp.decoder.decode_frame
71108 WUFFS_BASE__GENERATED_C_CODE
71109 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
71110 wuffs_wbmp__decoder__decode_frame(
71111 wuffs_wbmp__decoder* self,
71112 wuffs_base__pixel_buffer* a_dst,
71113 wuffs_base__io_buffer* a_src,
71114 wuffs_base__pixel_blend a_blend,
71115 wuffs_base__slice_u8 a_workbuf,
71116 wuffs_base__decode_frame_options* a_opts) {
71117 if (!self) {
71118 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
71120 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
71121 return wuffs_base__make_status(
71122 (self->private_impl.magic == WUFFS_BASE__DISABLED)
71123 ? wuffs_base__error__disabled_by_previous_error
71124 : wuffs_base__error__initialize_not_called);
71126 if (!a_dst || !a_src) {
71127 self->private_impl.magic = WUFFS_BASE__DISABLED;
71128 return wuffs_base__make_status(wuffs_base__error__bad_argument);
71130 if ((self->private_impl.active_coroutine != 0) &&
71131 (self->private_impl.active_coroutine != 3)) {
71132 self->private_impl.magic = WUFFS_BASE__DISABLED;
71133 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
71135 self->private_impl.active_coroutine = 0;
71136 wuffs_base__status status = wuffs_base__make_status(NULL);
71138 wuffs_base__status v_status = wuffs_base__make_status(NULL);
71140 uint32_t coro_susp_point = self->private_impl.p_decode_frame;
71141 switch (coro_susp_point) {
71142 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
71144 while (true) {
71146 wuffs_base__status t_0 = wuffs_wbmp__decoder__do_decode_frame(self,
71147 a_dst,
71148 a_src,
71149 a_blend,
71150 a_workbuf,
71151 a_opts);
71152 v_status = t_0;
71154 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
71155 status = wuffs_base__make_status(wuffs_wbmp__error__truncated_input);
71156 goto exit;
71158 status = v_status;
71159 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
71163 self->private_impl.p_decode_frame = 0;
71164 goto exit;
71167 goto suspend;
71168 suspend:
71169 self->private_impl.p_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
71170 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
71172 goto exit;
71173 exit:
71174 if (wuffs_base__status__is_error(&status)) {
71175 self->private_impl.magic = WUFFS_BASE__DISABLED;
71177 return status;
71180 // -------- func wbmp.decoder.do_decode_frame
71182 WUFFS_BASE__GENERATED_C_CODE
71183 static wuffs_base__status
71184 wuffs_wbmp__decoder__do_decode_frame(
71185 wuffs_wbmp__decoder* self,
71186 wuffs_base__pixel_buffer* a_dst,
71187 wuffs_base__io_buffer* a_src,
71188 wuffs_base__pixel_blend a_blend,
71189 wuffs_base__slice_u8 a_workbuf,
71190 wuffs_base__decode_frame_options* a_opts) {
71191 wuffs_base__status status = wuffs_base__make_status(NULL);
71193 wuffs_base__status v_status = wuffs_base__make_status(NULL);
71194 wuffs_base__pixel_format v_dst_pixfmt = {0};
71195 uint32_t v_dst_bits_per_pixel = 0;
71196 uint64_t v_dst_bytes_per_pixel = 0;
71197 uint64_t v_dst_x_in_bytes = 0;
71198 uint32_t v_dst_x = 0;
71199 uint32_t v_dst_y = 0;
71200 wuffs_base__table_u8 v_tab = {0};
71201 wuffs_base__slice_u8 v_dst = {0};
71202 uint8_t v_src[1] = {0};
71203 uint8_t v_c8 = 0;
71205 const uint8_t* iop_a_src = NULL;
71206 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
71207 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
71208 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
71209 if (a_src && a_src->data.ptr) {
71210 io0_a_src = a_src->data.ptr;
71211 io1_a_src = io0_a_src + a_src->meta.ri;
71212 iop_a_src = io1_a_src;
71213 io2_a_src = io0_a_src + a_src->meta.wi;
71216 uint32_t coro_susp_point = self->private_impl.p_do_decode_frame;
71217 if (coro_susp_point) {
71218 v_dst_bytes_per_pixel = self->private_data.s_do_decode_frame.v_dst_bytes_per_pixel;
71219 v_dst_x = self->private_data.s_do_decode_frame.v_dst_x;
71220 v_dst_y = self->private_data.s_do_decode_frame.v_dst_y;
71221 memcpy(v_src, self->private_data.s_do_decode_frame.v_src, sizeof(v_src));
71222 v_c8 = self->private_data.s_do_decode_frame.v_c8;
71224 switch (coro_susp_point) {
71225 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
71227 if (self->private_impl.f_call_sequence == 64u) {
71228 } else if (self->private_impl.f_call_sequence < 64u) {
71229 if (a_src) {
71230 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
71232 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
71233 status = wuffs_wbmp__decoder__do_decode_frame_config(self, NULL, a_src);
71234 if (a_src) {
71235 iop_a_src = a_src->data.ptr + a_src->meta.ri;
71237 if (status.repr) {
71238 goto suspend;
71240 } else {
71241 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
71242 goto ok;
71244 v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
71245 wuffs_base__pixel_buffer__pixel_format(a_dst),
71246 wuffs_base__pixel_buffer__palette(a_dst),
71247 wuffs_base__utility__make_pixel_format(536870920u),
71248 wuffs_base__utility__empty_slice_u8(),
71249 a_blend);
71250 if ( ! wuffs_base__status__is_ok(&v_status)) {
71251 status = v_status;
71252 if (wuffs_base__status__is_error(&status)) {
71253 goto exit;
71254 } else if (wuffs_base__status__is_suspension(&status)) {
71255 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
71256 goto exit;
71258 goto ok;
71260 v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
71261 v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
71262 if ((v_dst_bits_per_pixel & 7u) != 0u) {
71263 status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
71264 goto exit;
71266 v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8u)));
71267 if (self->private_impl.f_width > 0u) {
71268 v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
71269 while (v_dst_y < self->private_impl.f_height) {
71270 v_dst = wuffs_private_impl__table_u8__row_u32(v_tab, v_dst_y);
71271 v_dst_x = 0u;
71272 while (v_dst_x < self->private_impl.f_width) {
71273 if ((v_dst_x & 7u) == 0u) {
71274 while (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
71275 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
71276 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
71277 v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
71278 v_dst = wuffs_private_impl__table_u8__row_u32(v_tab, v_dst_y);
71279 v_dst_x_in_bytes = (((uint64_t)(v_dst_x)) * v_dst_bytes_per_pixel);
71280 if (v_dst_x_in_bytes <= ((uint64_t)(v_dst.len))) {
71281 v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_x_in_bytes);
71284 v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
71285 iop_a_src += 1u;
71287 if (((uint8_t)(v_c8 & 128u)) == 0u) {
71288 v_src[0u] = 0u;
71289 } else {
71290 v_src[0u] = 255u;
71292 v_c8 = ((uint8_t)((((uint32_t)(v_c8)) << 1u)));
71293 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));
71294 if (v_dst_bytes_per_pixel <= ((uint64_t)(v_dst.len))) {
71295 v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_bytes_per_pixel);
71297 v_dst_x += 1u;
71299 v_dst_y += 1u;
71302 self->private_impl.f_call_sequence = 96u;
71305 self->private_impl.p_do_decode_frame = 0;
71306 goto exit;
71309 goto suspend;
71310 suspend:
71311 self->private_impl.p_do_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
71312 self->private_data.s_do_decode_frame.v_dst_bytes_per_pixel = v_dst_bytes_per_pixel;
71313 self->private_data.s_do_decode_frame.v_dst_x = v_dst_x;
71314 self->private_data.s_do_decode_frame.v_dst_y = v_dst_y;
71315 memcpy(self->private_data.s_do_decode_frame.v_src, v_src, sizeof(v_src));
71316 self->private_data.s_do_decode_frame.v_c8 = v_c8;
71318 goto exit;
71319 exit:
71320 if (a_src && a_src->data.ptr) {
71321 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
71324 return status;
71327 // -------- func wbmp.decoder.frame_dirty_rect
71329 WUFFS_BASE__GENERATED_C_CODE
71330 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
71331 wuffs_wbmp__decoder__frame_dirty_rect(
71332 const wuffs_wbmp__decoder* self) {
71333 if (!self) {
71334 return wuffs_base__utility__empty_rect_ie_u32();
71336 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
71337 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
71338 return wuffs_base__utility__empty_rect_ie_u32();
71341 return wuffs_base__utility__make_rect_ie_u32(
71344 self->private_impl.f_width,
71345 self->private_impl.f_height);
71348 // -------- func wbmp.decoder.num_animation_loops
71350 WUFFS_BASE__GENERATED_C_CODE
71351 WUFFS_BASE__MAYBE_STATIC uint32_t
71352 wuffs_wbmp__decoder__num_animation_loops(
71353 const wuffs_wbmp__decoder* self) {
71354 if (!self) {
71355 return 0;
71357 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
71358 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
71359 return 0;
71362 return 0u;
71365 // -------- func wbmp.decoder.num_decoded_frame_configs
71367 WUFFS_BASE__GENERATED_C_CODE
71368 WUFFS_BASE__MAYBE_STATIC uint64_t
71369 wuffs_wbmp__decoder__num_decoded_frame_configs(
71370 const wuffs_wbmp__decoder* self) {
71371 if (!self) {
71372 return 0;
71374 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
71375 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
71376 return 0;
71379 if (self->private_impl.f_call_sequence > 32u) {
71380 return 1u;
71382 return 0u;
71385 // -------- func wbmp.decoder.num_decoded_frames
71387 WUFFS_BASE__GENERATED_C_CODE
71388 WUFFS_BASE__MAYBE_STATIC uint64_t
71389 wuffs_wbmp__decoder__num_decoded_frames(
71390 const wuffs_wbmp__decoder* self) {
71391 if (!self) {
71392 return 0;
71394 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
71395 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
71396 return 0;
71399 if (self->private_impl.f_call_sequence > 64u) {
71400 return 1u;
71402 return 0u;
71405 // -------- func wbmp.decoder.restart_frame
71407 WUFFS_BASE__GENERATED_C_CODE
71408 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
71409 wuffs_wbmp__decoder__restart_frame(
71410 wuffs_wbmp__decoder* self,
71411 uint64_t a_index,
71412 uint64_t a_io_position) {
71413 if (!self) {
71414 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
71416 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
71417 return wuffs_base__make_status(
71418 (self->private_impl.magic == WUFFS_BASE__DISABLED)
71419 ? wuffs_base__error__disabled_by_previous_error
71420 : wuffs_base__error__initialize_not_called);
71423 if (self->private_impl.f_call_sequence < 32u) {
71424 return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
71426 if (a_index != 0u) {
71427 return wuffs_base__make_status(wuffs_base__error__bad_argument);
71429 self->private_impl.f_call_sequence = 40u;
71430 self->private_impl.f_frame_config_io_position = a_io_position;
71431 return wuffs_base__make_status(NULL);
71434 // -------- func wbmp.decoder.set_report_metadata
71436 WUFFS_BASE__GENERATED_C_CODE
71437 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
71438 wuffs_wbmp__decoder__set_report_metadata(
71439 wuffs_wbmp__decoder* self,
71440 uint32_t a_fourcc,
71441 bool a_report) {
71442 return wuffs_base__make_empty_struct();
71445 // -------- func wbmp.decoder.tell_me_more
71447 WUFFS_BASE__GENERATED_C_CODE
71448 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
71449 wuffs_wbmp__decoder__tell_me_more(
71450 wuffs_wbmp__decoder* self,
71451 wuffs_base__io_buffer* a_dst,
71452 wuffs_base__more_information* a_minfo,
71453 wuffs_base__io_buffer* a_src) {
71454 if (!self) {
71455 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
71457 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
71458 return wuffs_base__make_status(
71459 (self->private_impl.magic == WUFFS_BASE__DISABLED)
71460 ? wuffs_base__error__disabled_by_previous_error
71461 : wuffs_base__error__initialize_not_called);
71463 if (!a_dst || !a_src) {
71464 self->private_impl.magic = WUFFS_BASE__DISABLED;
71465 return wuffs_base__make_status(wuffs_base__error__bad_argument);
71467 if ((self->private_impl.active_coroutine != 0) &&
71468 (self->private_impl.active_coroutine != 4)) {
71469 self->private_impl.magic = WUFFS_BASE__DISABLED;
71470 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
71472 self->private_impl.active_coroutine = 0;
71473 wuffs_base__status status = wuffs_base__make_status(NULL);
71475 status = wuffs_base__make_status(wuffs_base__error__no_more_information);
71476 goto exit;
71478 goto ok;
71480 goto exit;
71481 exit:
71482 if (wuffs_base__status__is_error(&status)) {
71483 self->private_impl.magic = WUFFS_BASE__DISABLED;
71485 return status;
71488 // -------- func wbmp.decoder.workbuf_len
71490 WUFFS_BASE__GENERATED_C_CODE
71491 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
71492 wuffs_wbmp__decoder__workbuf_len(
71493 const wuffs_wbmp__decoder* self) {
71494 if (!self) {
71495 return wuffs_base__utility__empty_range_ii_u64();
71497 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
71498 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
71499 return wuffs_base__utility__empty_range_ii_u64();
71502 return wuffs_base__utility__make_range_ii_u64(0u, 0u);
71505 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP)
71507 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WEBP)
71509 // ---------------- Status Codes Implementations
71511 const char wuffs_webp__error__bad_huffman_code_over_subscribed[] = "#webp: bad Huffman code (over-subscribed)";
71512 const char wuffs_webp__error__bad_huffman_code_under_subscribed[] = "#webp: bad Huffman code (under-subscribed)";
71513 const char wuffs_webp__error__bad_huffman_code[] = "#webp: bad Huffman code";
71514 const char wuffs_webp__error__bad_back_reference[] = "#webp: bad back-reference";
71515 const char wuffs_webp__error__bad_color_cache[] = "#webp: bad color cache";
71516 const char wuffs_webp__error__bad_header[] = "#webp: bad header";
71517 const char wuffs_webp__error__bad_transform[] = "#webp: bad transform";
71518 const char wuffs_webp__error__short_chunk[] = "#webp: short chunk";
71519 const char wuffs_webp__error__truncated_input[] = "#webp: truncated input";
71520 const char wuffs_webp__error__unsupported_number_of_huffman_groups[] = "#webp: unsupported number of Huffman groups";
71521 const char wuffs_webp__error__unsupported_transform_after_color_indexing_transform[] = "#webp: unsupported transform after color indexing transform";
71522 const char wuffs_webp__error__unsupported_webp_file[] = "#webp: unsupported WebP file";
71523 const char wuffs_webp__error__internal_error_inconsistent_huffman_code[] = "#webp: internal error: inconsistent Huffman code";
71524 const char wuffs_webp__error__internal_error_inconsistent_dst_buffer[] = "#webp: internal error: inconsistent dst buffer";
71525 const char wuffs_webp__error__internal_error_inconsistent_n_bits[] = "#webp: internal error: inconsistent n_bits";
71527 // ---------------- Private Consts
71529 static const uint8_t
71530 WUFFS_WEBP__CODE_LENGTH_CODE_ORDER[19] WUFFS_BASE__POTENTIALLY_UNUSED = {
71531 17u, 18u, 0u, 1u, 2u, 3u, 4u, 5u,
71532 16u, 6u, 7u, 8u, 9u, 10u, 11u, 12u,
71533 13u, 14u, 15u,
71536 static const uint8_t
71537 WUFFS_WEBP__REPEAT_N_BITS[4] WUFFS_BASE__POTENTIALLY_UNUSED = {
71538 2u, 3u, 7u, 0u,
71541 static const uint8_t
71542 WUFFS_WEBP__REPEAT_COUNTS[4] WUFFS_BASE__POTENTIALLY_UNUSED = {
71543 3u, 3u, 11u, 0u,
71546 static const uint16_t
71547 WUFFS_WEBP__HUFFMAN_TABLE_BASE_OFFSETS[5] WUFFS_BASE__POTENTIALLY_UNUSED = {
71548 1612u, 0u, 511u, 1022u, 1533u,
71551 static const uint8_t
71552 WUFFS_WEBP__DISTANCE_MAP[120] WUFFS_BASE__POTENTIALLY_UNUSED = {
71553 24u, 7u, 23u, 25u, 40u, 6u, 39u, 41u,
71554 22u, 26u, 38u, 42u, 56u, 5u, 55u, 57u,
71555 21u, 27u, 54u, 58u, 37u, 43u, 72u, 4u,
71556 71u, 73u, 20u, 28u, 53u, 59u, 70u, 74u,
71557 36u, 44u, 88u, 69u, 75u, 52u, 60u, 3u,
71558 87u, 89u, 19u, 29u, 86u, 90u, 35u, 45u,
71559 68u, 76u, 85u, 91u, 51u, 61u, 104u, 2u,
71560 103u, 105u, 18u, 30u, 102u, 106u, 34u, 46u,
71561 84u, 92u, 67u, 77u, 101u, 107u, 50u, 62u,
71562 120u, 1u, 119u, 121u, 83u, 93u, 17u, 31u,
71563 100u, 108u, 66u, 78u, 118u, 122u, 33u, 47u,
71564 117u, 123u, 49u, 63u, 99u, 109u, 82u, 94u,
71565 0u, 116u, 124u, 65u, 79u, 16u, 32u, 98u,
71566 110u, 48u, 115u, 125u, 81u, 95u, 64u, 114u,
71567 126u, 97u, 111u, 80u, 113u, 127u, 96u, 112u,
71570 // ---------------- Private Initializer Prototypes
71572 // ---------------- Private Function Prototypes
71574 WUFFS_BASE__GENERATED_C_CODE
71575 static wuffs_base__status
71576 wuffs_webp__decoder__decode_huffman_groups(
71577 wuffs_webp__decoder* self,
71578 wuffs_base__io_buffer* a_src,
71579 uint32_t a_n_huffman_groups);
71581 WUFFS_BASE__GENERATED_C_CODE
71582 static wuffs_base__status
71583 wuffs_webp__decoder__decode_huffman_tree(
71584 wuffs_webp__decoder* self,
71585 wuffs_base__io_buffer* a_src,
71586 uint32_t a_hg,
71587 uint32_t a_ht);
71589 WUFFS_BASE__GENERATED_C_CODE
71590 static wuffs_base__status
71591 wuffs_webp__decoder__decode_huffman_tree_simple(
71592 wuffs_webp__decoder* self,
71593 wuffs_base__io_buffer* a_src,
71594 uint32_t a_hg,
71595 uint32_t a_ht);
71597 WUFFS_BASE__GENERATED_C_CODE
71598 static wuffs_base__status
71599 wuffs_webp__decoder__decode_code_length_code_lengths(
71600 wuffs_webp__decoder* self,
71601 wuffs_base__io_buffer* a_src);
71603 WUFFS_BASE__GENERATED_C_CODE
71604 static wuffs_base__status
71605 wuffs_webp__decoder__build_code_lengths_huffman_nodes(
71606 wuffs_webp__decoder* self);
71608 WUFFS_BASE__GENERATED_C_CODE
71609 static wuffs_base__status
71610 wuffs_webp__decoder__build_huffman_nodes(
71611 wuffs_webp__decoder* self,
71612 uint32_t a_hg,
71613 uint32_t a_ht);
71615 WUFFS_BASE__GENERATED_C_CODE
71616 static wuffs_base__status
71617 wuffs_webp__decoder__build_code_lengths(
71618 wuffs_webp__decoder* self,
71619 wuffs_base__io_buffer* a_src);
71621 WUFFS_BASE__GENERATED_C_CODE
71622 static wuffs_base__status
71623 wuffs_webp__decoder__decode_pixels_slow(
71624 wuffs_webp__decoder* self,
71625 wuffs_base__slice_u8 a_dst,
71626 wuffs_base__io_buffer* a_src,
71627 uint32_t a_width,
71628 uint32_t a_height,
71629 wuffs_base__slice_u8 a_tile_data,
71630 uint32_t a_tile_size_log2);
71632 WUFFS_BASE__GENERATED_C_CODE
71633 static wuffs_base__empty_struct
71634 wuffs_webp__decoder__apply_transform_predictor(
71635 wuffs_webp__decoder* self,
71636 wuffs_base__slice_u8 a_pix,
71637 wuffs_base__slice_u8 a_tile_data);
71639 WUFFS_BASE__GENERATED_C_CODE
71640 static uint32_t
71641 wuffs_webp__decoder__absolute_difference(
71642 const wuffs_webp__decoder* self,
71643 uint32_t a_a,
71644 uint32_t a_b);
71646 WUFFS_BASE__GENERATED_C_CODE
71647 static uint8_t
71648 wuffs_webp__decoder__mode12(
71649 const wuffs_webp__decoder* self,
71650 uint8_t a_l,
71651 uint8_t a_t,
71652 uint8_t a_tl);
71654 WUFFS_BASE__GENERATED_C_CODE
71655 static uint8_t
71656 wuffs_webp__decoder__mode13(
71657 const wuffs_webp__decoder* self,
71658 uint8_t a_l,
71659 uint8_t a_t,
71660 uint8_t a_tl);
71662 WUFFS_BASE__GENERATED_C_CODE
71663 static wuffs_base__empty_struct
71664 wuffs_webp__decoder__apply_transform_cross_color(
71665 wuffs_webp__decoder* self,
71666 wuffs_base__slice_u8 a_pix,
71667 wuffs_base__slice_u8 a_tile_data);
71669 WUFFS_BASE__GENERATED_C_CODE
71670 static wuffs_base__empty_struct
71671 wuffs_webp__decoder__apply_transform_subtract_green(
71672 wuffs_webp__decoder* self,
71673 wuffs_base__slice_u8 a_pix);
71675 WUFFS_BASE__GENERATED_C_CODE
71676 static wuffs_base__empty_struct
71677 wuffs_webp__decoder__apply_transform_color_indexing(
71678 wuffs_webp__decoder* self,
71679 wuffs_base__slice_u8 a_pix);
71681 WUFFS_BASE__GENERATED_C_CODE
71682 static wuffs_base__status
71683 wuffs_webp__decoder__do_decode_image_config(
71684 wuffs_webp__decoder* self,
71685 wuffs_base__image_config* a_dst,
71686 wuffs_base__io_buffer* a_src);
71688 WUFFS_BASE__GENERATED_C_CODE
71689 static wuffs_base__status
71690 wuffs_webp__decoder__do_decode_image_config_limited(
71691 wuffs_webp__decoder* self,
71692 wuffs_base__io_buffer* a_src);
71694 WUFFS_BASE__GENERATED_C_CODE
71695 static wuffs_base__status
71696 wuffs_webp__decoder__do_decode_image_config_limited_vp8l(
71697 wuffs_webp__decoder* self,
71698 wuffs_base__io_buffer* a_src);
71700 WUFFS_BASE__GENERATED_C_CODE
71701 static wuffs_base__status
71702 wuffs_webp__decoder__do_decode_frame_config(
71703 wuffs_webp__decoder* self,
71704 wuffs_base__frame_config* a_dst,
71705 wuffs_base__io_buffer* a_src);
71707 WUFFS_BASE__GENERATED_C_CODE
71708 static wuffs_base__status
71709 wuffs_webp__decoder__do_decode_frame(
71710 wuffs_webp__decoder* self,
71711 wuffs_base__pixel_buffer* a_dst,
71712 wuffs_base__io_buffer* a_src,
71713 wuffs_base__pixel_blend a_blend,
71714 wuffs_base__slice_u8 a_workbuf,
71715 wuffs_base__decode_frame_options* a_opts);
71717 WUFFS_BASE__GENERATED_C_CODE
71718 static wuffs_base__status
71719 wuffs_webp__decoder__decode_transform(
71720 wuffs_webp__decoder* self,
71721 wuffs_base__io_buffer* a_src,
71722 wuffs_base__slice_u8 a_workbuf);
71724 WUFFS_BASE__GENERATED_C_CODE
71725 static wuffs_base__status
71726 wuffs_webp__decoder__decode_color_cache_parameters(
71727 wuffs_webp__decoder* self,
71728 wuffs_base__io_buffer* a_src);
71730 WUFFS_BASE__GENERATED_C_CODE
71731 static wuffs_base__status
71732 wuffs_webp__decoder__decode_hg_table(
71733 wuffs_webp__decoder* self,
71734 wuffs_base__io_buffer* a_src,
71735 uint32_t a_width,
71736 wuffs_base__slice_u8 a_workbuf);
71738 WUFFS_BASE__GENERATED_C_CODE
71739 static wuffs_base__status
71740 wuffs_webp__decoder__decode_pixels(
71741 wuffs_webp__decoder* self,
71742 wuffs_base__slice_u8 a_dst,
71743 wuffs_base__io_buffer* a_src,
71744 uint32_t a_width,
71745 uint32_t a_height,
71746 wuffs_base__slice_u8 a_tile_data,
71747 uint32_t a_tile_size_log2);
71749 WUFFS_BASE__GENERATED_C_CODE
71750 static wuffs_base__status
71751 wuffs_webp__decoder__swizzle(
71752 wuffs_webp__decoder* self,
71753 wuffs_base__pixel_buffer* a_dst,
71754 wuffs_base__slice_u8 a_src,
71755 wuffs_base__pixel_blend a_blend);
71757 // ---------------- VTables
71759 const wuffs_base__image_decoder__func_ptrs
71760 wuffs_webp__decoder__func_ptrs_for__wuffs_base__image_decoder = {
71761 (wuffs_base__status(*)(void*,
71762 wuffs_base__pixel_buffer*,
71763 wuffs_base__io_buffer*,
71764 wuffs_base__pixel_blend,
71765 wuffs_base__slice_u8,
71766 wuffs_base__decode_frame_options*))(&wuffs_webp__decoder__decode_frame),
71767 (wuffs_base__status(*)(void*,
71768 wuffs_base__frame_config*,
71769 wuffs_base__io_buffer*))(&wuffs_webp__decoder__decode_frame_config),
71770 (wuffs_base__status(*)(void*,
71771 wuffs_base__image_config*,
71772 wuffs_base__io_buffer*))(&wuffs_webp__decoder__decode_image_config),
71773 (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_webp__decoder__frame_dirty_rect),
71774 (uint64_t(*)(const void*,
71775 uint32_t))(&wuffs_webp__decoder__get_quirk),
71776 (uint32_t(*)(const void*))(&wuffs_webp__decoder__num_animation_loops),
71777 (uint64_t(*)(const void*))(&wuffs_webp__decoder__num_decoded_frame_configs),
71778 (uint64_t(*)(const void*))(&wuffs_webp__decoder__num_decoded_frames),
71779 (wuffs_base__status(*)(void*,
71780 uint64_t,
71781 uint64_t))(&wuffs_webp__decoder__restart_frame),
71782 (wuffs_base__status(*)(void*,
71783 uint32_t,
71784 uint64_t))(&wuffs_webp__decoder__set_quirk),
71785 (wuffs_base__empty_struct(*)(void*,
71786 uint32_t,
71787 bool))(&wuffs_webp__decoder__set_report_metadata),
71788 (wuffs_base__status(*)(void*,
71789 wuffs_base__io_buffer*,
71790 wuffs_base__more_information*,
71791 wuffs_base__io_buffer*))(&wuffs_webp__decoder__tell_me_more),
71792 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_webp__decoder__workbuf_len),
71795 // ---------------- Initializer Implementations
71797 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
71798 wuffs_webp__decoder__initialize(
71799 wuffs_webp__decoder* self,
71800 size_t sizeof_star_self,
71801 uint64_t wuffs_version,
71802 uint32_t options){
71803 if (!self) {
71804 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
71806 if (sizeof(*self) != sizeof_star_self) {
71807 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
71809 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
71810 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
71811 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
71814 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
71815 // The whole point of this if-check is to detect an uninitialized *self.
71816 // We disable the warning on GCC. Clang-5.0 does not have this warning.
71817 #if !defined(__clang__) && defined(__GNUC__)
71818 #pragma GCC diagnostic push
71819 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
71820 #endif
71821 if (self->private_impl.magic != 0) {
71822 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
71824 #if !defined(__clang__) && defined(__GNUC__)
71825 #pragma GCC diagnostic pop
71826 #endif
71827 } else {
71828 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
71829 memset(self, 0, sizeof(*self));
71830 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
71831 } else {
71832 memset(&(self->private_impl), 0, sizeof(self->private_impl));
71836 self->private_impl.magic = WUFFS_BASE__MAGIC;
71837 self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
71838 wuffs_base__image_decoder__vtable_name;
71839 self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
71840 (const void*)(&wuffs_webp__decoder__func_ptrs_for__wuffs_base__image_decoder);
71841 return wuffs_base__make_status(NULL);
71844 wuffs_webp__decoder*
71845 wuffs_webp__decoder__alloc(void) {
71846 wuffs_webp__decoder* x =
71847 (wuffs_webp__decoder*)(calloc(1, sizeof(wuffs_webp__decoder)));
71848 if (!x) {
71849 return NULL;
71851 if (wuffs_webp__decoder__initialize(
71852 x, sizeof(wuffs_webp__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
71853 free(x);
71854 return NULL;
71856 return x;
71859 size_t
71860 sizeof__wuffs_webp__decoder(void) {
71861 return sizeof(wuffs_webp__decoder);
71864 // ---------------- Function Implementations
71866 // -------- func webp.decoder.decode_huffman_groups
71868 WUFFS_BASE__GENERATED_C_CODE
71869 static wuffs_base__status
71870 wuffs_webp__decoder__decode_huffman_groups(
71871 wuffs_webp__decoder* self,
71872 wuffs_base__io_buffer* a_src,
71873 uint32_t a_n_huffman_groups) {
71874 wuffs_base__status status = wuffs_base__make_status(NULL);
71876 uint32_t v_hg = 0;
71877 uint32_t v_ht = 0;
71879 uint32_t coro_susp_point = self->private_impl.p_decode_huffman_groups;
71880 if (coro_susp_point) {
71881 v_hg = self->private_data.s_decode_huffman_groups.v_hg;
71882 v_ht = self->private_data.s_decode_huffman_groups.v_ht;
71884 switch (coro_susp_point) {
71885 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
71887 v_hg = 0u;
71888 while (v_hg < a_n_huffman_groups) {
71889 v_ht = 0u;
71890 while (v_ht < 5u) {
71891 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
71892 status = wuffs_webp__decoder__decode_huffman_tree(self, a_src, v_hg, v_ht);
71893 if (status.repr) {
71894 goto suspend;
71896 v_ht += 1u;
71898 v_hg += 1u;
71901 goto ok;
71903 self->private_impl.p_decode_huffman_groups = 0;
71904 goto exit;
71907 goto suspend;
71908 suspend:
71909 self->private_impl.p_decode_huffman_groups = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
71910 self->private_data.s_decode_huffman_groups.v_hg = v_hg;
71911 self->private_data.s_decode_huffman_groups.v_ht = v_ht;
71913 goto exit;
71914 exit:
71915 return status;
71918 // -------- func webp.decoder.decode_huffman_tree
71920 WUFFS_BASE__GENERATED_C_CODE
71921 static wuffs_base__status
71922 wuffs_webp__decoder__decode_huffman_tree(
71923 wuffs_webp__decoder* self,
71924 wuffs_base__io_buffer* a_src,
71925 uint32_t a_hg,
71926 uint32_t a_ht) {
71927 wuffs_base__status status = wuffs_base__make_status(NULL);
71929 uint8_t v_c8 = 0;
71930 uint32_t v_use_simple = 0;
71931 wuffs_base__status v_status = wuffs_base__make_status(NULL);
71933 const uint8_t* iop_a_src = NULL;
71934 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
71935 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
71936 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
71937 if (a_src && a_src->data.ptr) {
71938 io0_a_src = a_src->data.ptr;
71939 io1_a_src = io0_a_src + a_src->meta.ri;
71940 iop_a_src = io1_a_src;
71941 io2_a_src = io0_a_src + a_src->meta.wi;
71944 uint32_t coro_susp_point = self->private_impl.p_decode_huffman_tree;
71945 switch (coro_susp_point) {
71946 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
71948 if (a_ht >= 4u) {
71949 self->private_impl.f_ht_n_symbols = 40u;
71950 } else if (a_ht > 0u) {
71951 self->private_impl.f_ht_n_symbols = 256u;
71952 } else if (self->private_impl.f_color_cache_bits == 0u) {
71953 self->private_impl.f_ht_n_symbols = 280u;
71954 } else {
71955 self->private_impl.f_ht_n_symbols = (280u + (((uint32_t)(1u)) << self->private_impl.f_color_cache_bits));
71957 if (self->private_impl.f_n_bits < 1u) {
71959 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
71960 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
71961 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
71962 goto suspend;
71964 uint8_t t_0 = *iop_a_src++;
71965 v_c8 = t_0;
71967 self->private_impl.f_bits = ((uint32_t)(v_c8));
71968 self->private_impl.f_n_bits = 8u;
71970 v_use_simple = (self->private_impl.f_bits & 1u);
71971 self->private_impl.f_bits >>= 1u;
71972 self->private_impl.f_n_bits -= 1u;
71973 if (v_use_simple != 0u) {
71974 if (a_src) {
71975 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
71977 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
71978 status = wuffs_webp__decoder__decode_huffman_tree_simple(self, a_src, a_hg, a_ht);
71979 if (a_src) {
71980 iop_a_src = a_src->data.ptr + a_src->meta.ri;
71982 if (status.repr) {
71983 goto suspend;
71985 } else {
71986 if (a_src) {
71987 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
71989 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
71990 status = wuffs_webp__decoder__decode_code_length_code_lengths(self, a_src);
71991 if (a_src) {
71992 iop_a_src = a_src->data.ptr + a_src->meta.ri;
71994 if (status.repr) {
71995 goto suspend;
71997 v_status = wuffs_webp__decoder__build_code_lengths_huffman_nodes(self);
71998 if ( ! wuffs_base__status__is_ok(&v_status)) {
71999 status = v_status;
72000 if (wuffs_base__status__is_error(&status)) {
72001 goto exit;
72002 } else if (wuffs_base__status__is_suspension(&status)) {
72003 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
72004 goto exit;
72006 goto ok;
72008 if (a_src) {
72009 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
72011 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
72012 status = wuffs_webp__decoder__build_code_lengths(self, a_src);
72013 if (a_src) {
72014 iop_a_src = a_src->data.ptr + a_src->meta.ri;
72016 if (status.repr) {
72017 goto suspend;
72019 v_status = wuffs_webp__decoder__build_huffman_nodes(self, a_hg, a_ht);
72020 if ( ! wuffs_base__status__is_ok(&v_status)) {
72021 status = v_status;
72022 if (wuffs_base__status__is_error(&status)) {
72023 goto exit;
72024 } else if (wuffs_base__status__is_suspension(&status)) {
72025 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
72026 goto exit;
72028 goto ok;
72033 self->private_impl.p_decode_huffman_tree = 0;
72034 goto exit;
72037 goto suspend;
72038 suspend:
72039 self->private_impl.p_decode_huffman_tree = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
72041 goto exit;
72042 exit:
72043 if (a_src && a_src->data.ptr) {
72044 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
72047 return status;
72050 // -------- func webp.decoder.decode_huffman_tree_simple
72052 WUFFS_BASE__GENERATED_C_CODE
72053 static wuffs_base__status
72054 wuffs_webp__decoder__decode_huffman_tree_simple(
72055 wuffs_webp__decoder* self,
72056 wuffs_base__io_buffer* a_src,
72057 uint32_t a_hg,
72058 uint32_t a_ht) {
72059 wuffs_base__status status = wuffs_base__make_status(NULL);
72061 uint8_t v_c8 = 0;
72062 uint32_t v_use_second_symbol = 0;
72063 uint32_t v_first_symbol_n_bits = 0;
72064 uint32_t v_symbol0 = 0;
72065 uint32_t v_symbol1 = 0;
72066 uint32_t v_base_offset = 0;
72068 const uint8_t* iop_a_src = NULL;
72069 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
72070 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
72071 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
72072 if (a_src && a_src->data.ptr) {
72073 io0_a_src = a_src->data.ptr;
72074 io1_a_src = io0_a_src + a_src->meta.ri;
72075 iop_a_src = io1_a_src;
72076 io2_a_src = io0_a_src + a_src->meta.wi;
72079 uint32_t coro_susp_point = self->private_impl.p_decode_huffman_tree_simple;
72080 if (coro_susp_point) {
72081 v_use_second_symbol = self->private_data.s_decode_huffman_tree_simple.v_use_second_symbol;
72082 v_first_symbol_n_bits = self->private_data.s_decode_huffman_tree_simple.v_first_symbol_n_bits;
72083 v_symbol0 = self->private_data.s_decode_huffman_tree_simple.v_symbol0;
72084 v_base_offset = self->private_data.s_decode_huffman_tree_simple.v_base_offset;
72086 switch (coro_susp_point) {
72087 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
72089 if (self->private_impl.f_n_bits < 2u) {
72091 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
72092 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
72093 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
72094 goto suspend;
72096 uint8_t t_0 = *iop_a_src++;
72097 v_c8 = t_0;
72099 if (self->private_impl.f_n_bits >= 2u) {
72100 status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_n_bits);
72101 goto exit;
72103 self->private_impl.f_bits |= (((uint32_t)(v_c8)) << self->private_impl.f_n_bits);
72104 self->private_impl.f_n_bits += 8u;
72106 v_use_second_symbol = (self->private_impl.f_bits & 1u);
72107 v_first_symbol_n_bits = ((((self->private_impl.f_bits & 2u) >> 1u) * 7u) + 1u);
72108 self->private_impl.f_bits >>= 2u;
72109 self->private_impl.f_n_bits -= 2u;
72110 if (self->private_impl.f_n_bits < v_first_symbol_n_bits) {
72112 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
72113 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
72114 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
72115 goto suspend;
72117 uint8_t t_1 = *iop_a_src++;
72118 v_c8 = t_1;
72120 if (self->private_impl.f_n_bits >= v_first_symbol_n_bits) {
72121 status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_n_bits);
72122 goto exit;
72124 self->private_impl.f_bits |= (((uint32_t)(v_c8)) << self->private_impl.f_n_bits);
72125 self->private_impl.f_n_bits += 8u;
72127 v_symbol0 = (self->private_impl.f_bits & ((((uint32_t)(1u)) << v_first_symbol_n_bits) - 1u));
72128 self->private_impl.f_bits >>= v_first_symbol_n_bits;
72129 self->private_impl.f_n_bits -= v_first_symbol_n_bits;
72130 v_base_offset = ((uint32_t)(WUFFS_WEBP__HUFFMAN_TABLE_BASE_OFFSETS[a_ht]));
72131 if (v_use_second_symbol != 0u) {
72132 if (self->private_impl.f_n_bits < 8u) {
72134 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
72135 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
72136 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
72137 goto suspend;
72139 uint8_t t_2 = *iop_a_src++;
72140 v_c8 = t_2;
72142 if (self->private_impl.f_n_bits >= 8u) {
72143 status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_n_bits);
72144 goto exit;
72146 self->private_impl.f_bits |= (((uint32_t)(v_c8)) << self->private_impl.f_n_bits);
72147 self->private_impl.f_n_bits += 8u;
72149 v_symbol1 = (self->private_impl.f_bits & 255u);
72150 self->private_impl.f_bits >>= 8u;
72151 self->private_impl.f_n_bits -= 8u;
72152 self->private_data.f_huffman_nodes[a_hg][(v_base_offset + 0u)] = ((uint16_t)((v_base_offset + 1u)));
72153 self->private_data.f_huffman_nodes[a_hg][(v_base_offset + 1u)] = ((uint16_t)((v_symbol0 | 32768u)));
72154 self->private_data.f_huffman_nodes[a_hg][(v_base_offset + 2u)] = ((uint16_t)((v_symbol1 | 32768u)));
72155 } else {
72156 self->private_data.f_huffman_nodes[a_hg][v_base_offset] = ((uint16_t)((v_symbol0 | 32768u)));
72159 goto ok;
72161 self->private_impl.p_decode_huffman_tree_simple = 0;
72162 goto exit;
72165 goto suspend;
72166 suspend:
72167 self->private_impl.p_decode_huffman_tree_simple = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
72168 self->private_data.s_decode_huffman_tree_simple.v_use_second_symbol = v_use_second_symbol;
72169 self->private_data.s_decode_huffman_tree_simple.v_first_symbol_n_bits = v_first_symbol_n_bits;
72170 self->private_data.s_decode_huffman_tree_simple.v_symbol0 = v_symbol0;
72171 self->private_data.s_decode_huffman_tree_simple.v_base_offset = v_base_offset;
72173 goto exit;
72174 exit:
72175 if (a_src && a_src->data.ptr) {
72176 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
72179 return status;
72182 // -------- func webp.decoder.decode_code_length_code_lengths
72184 WUFFS_BASE__GENERATED_C_CODE
72185 static wuffs_base__status
72186 wuffs_webp__decoder__decode_code_length_code_lengths(
72187 wuffs_webp__decoder* self,
72188 wuffs_base__io_buffer* a_src) {
72189 wuffs_base__status status = wuffs_base__make_status(NULL);
72191 uint8_t v_c8 = 0;
72192 uint32_t v_n_codes = 0;
72193 uint32_t v_i = 0;
72195 const uint8_t* iop_a_src = NULL;
72196 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
72197 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
72198 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
72199 if (a_src && a_src->data.ptr) {
72200 io0_a_src = a_src->data.ptr;
72201 io1_a_src = io0_a_src + a_src->meta.ri;
72202 iop_a_src = io1_a_src;
72203 io2_a_src = io0_a_src + a_src->meta.wi;
72206 uint32_t coro_susp_point = self->private_impl.p_decode_code_length_code_lengths;
72207 if (coro_susp_point) {
72208 v_n_codes = self->private_data.s_decode_code_length_code_lengths.v_n_codes;
72209 v_i = self->private_data.s_decode_code_length_code_lengths.v_i;
72211 switch (coro_susp_point) {
72212 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
72214 if (self->private_impl.f_n_bits < 4u) {
72216 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
72217 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
72218 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
72219 goto suspend;
72221 uint8_t t_0 = *iop_a_src++;
72222 v_c8 = t_0;
72224 if (self->private_impl.f_n_bits >= 4u) {
72225 status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_n_bits);
72226 goto exit;
72228 self->private_impl.f_bits |= (((uint32_t)(v_c8)) << self->private_impl.f_n_bits);
72229 self->private_impl.f_n_bits += 8u;
72231 v_n_codes = ((self->private_impl.f_bits & 15u) + 4u);
72232 self->private_impl.f_bits >>= 4u;
72233 self->private_impl.f_n_bits -= 4u;
72234 v_i = 0u;
72235 while (v_i < v_n_codes) {
72236 if (self->private_impl.f_n_bits < 3u) {
72238 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
72239 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
72240 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
72241 goto suspend;
72243 uint8_t t_1 = *iop_a_src++;
72244 v_c8 = t_1;
72246 if (self->private_impl.f_n_bits >= 3u) {
72247 status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_n_bits);
72248 goto exit;
72250 self->private_impl.f_bits |= (((uint32_t)(v_c8)) << self->private_impl.f_n_bits);
72251 self->private_impl.f_n_bits += 8u;
72253 self->private_impl.f_code_length_code_lengths[WUFFS_WEBP__CODE_LENGTH_CODE_ORDER[v_i]] = ((uint8_t)((self->private_impl.f_bits & 7u)));
72254 self->private_impl.f_bits >>= 3u;
72255 self->private_impl.f_n_bits -= 3u;
72256 v_i += 1u;
72258 while (v_i < 19u) {
72259 self->private_impl.f_code_length_code_lengths[WUFFS_WEBP__CODE_LENGTH_CODE_ORDER[v_i]] = 0u;
72260 v_i += 1u;
72263 goto ok;
72265 self->private_impl.p_decode_code_length_code_lengths = 0;
72266 goto exit;
72269 goto suspend;
72270 suspend:
72271 self->private_impl.p_decode_code_length_code_lengths = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
72272 self->private_data.s_decode_code_length_code_lengths.v_n_codes = v_n_codes;
72273 self->private_data.s_decode_code_length_code_lengths.v_i = v_i;
72275 goto exit;
72276 exit:
72277 if (a_src && a_src->data.ptr) {
72278 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
72281 return status;
72284 // -------- func webp.decoder.build_code_lengths_huffman_nodes
72286 WUFFS_BASE__GENERATED_C_CODE
72287 static wuffs_base__status
72288 wuffs_webp__decoder__build_code_lengths_huffman_nodes(
72289 wuffs_webp__decoder* self) {
72290 uint32_t v_code_bits = 0;
72291 uint32_t v_code_len = 0;
72292 uint32_t v_symbol = 0;
72293 uint32_t v_histogram[8] = {0};
72294 uint32_t v_n_used_symbols = 0;
72295 uint32_t v_last_used_symbol = 0;
72296 uint32_t v_subscription_weight = 0;
72297 uint32_t v_subscription_total = 0;
72298 uint32_t v_curr_code = 0;
72299 uint32_t v_next_codes[9] = {0};
72300 uint32_t v_n_branches = 0;
72301 uint32_t v_h = 0;
72302 uint32_t v_children = 0;
72303 uint16_t v_node = 0;
72305 v_symbol = 0u;
72306 while (v_symbol < 19u) {
72307 v_code_len = ((uint32_t)(self->private_impl.f_code_length_code_lengths[v_symbol]));
72308 if (v_code_len != 0u) {
72309 v_histogram[v_code_len] += 1u;
72310 v_n_used_symbols += 1u;
72311 v_last_used_symbol = v_symbol;
72313 v_symbol += 1u;
72315 if (v_n_used_symbols < 1u) {
72316 return wuffs_base__make_status(wuffs_webp__error__bad_huffman_code);
72317 } else if (v_n_used_symbols == 1u) {
72318 self->private_data.f_code_lengths_huffman_nodes[0u] = ((uint16_t)((v_last_used_symbol | 32768u)));
72319 return wuffs_base__make_status(NULL);
72321 v_subscription_weight = 16384u;
72322 v_code_len = 1u;
72323 while (true) {
72324 v_curr_code = ((uint32_t)(((uint32_t)(v_curr_code + v_histogram[v_code_len])) << 1u));
72325 v_next_codes[(v_code_len + 1u)] = v_curr_code;
72326 v_subscription_total += ((uint32_t)(v_subscription_weight * v_histogram[v_code_len]));
72327 v_subscription_weight >>= 1u;
72328 if (v_code_len >= 7u) {
72329 break;
72331 v_code_len += 1u;
72333 if (v_subscription_total > 32768u) {
72334 return wuffs_base__make_status(wuffs_webp__error__bad_huffman_code_over_subscribed);
72335 } else if (v_subscription_total < 32768u) {
72336 return wuffs_base__make_status(wuffs_webp__error__bad_huffman_code_under_subscribed);
72338 self->private_data.f_code_lengths_huffman_nodes[0u] = 0u;
72339 v_symbol = 0u;
72340 while (v_symbol < 19u) {
72341 v_code_len = ((uint32_t)(self->private_impl.f_code_length_code_lengths[v_symbol]));
72342 if (v_code_len > 0u) {
72343 v_code_bits = v_next_codes[v_code_len];
72344 v_next_codes[v_code_len] += 1u;
72345 v_code_bits <<= (32u - v_code_len);
72346 v_h = 0u;
72347 while (v_code_len > 0u) {
72348 v_node = self->private_data.f_code_lengths_huffman_nodes[v_h];
72349 if (v_node == 0u) {
72350 v_children = ((uint32_t)(1u + ((uint32_t)(2u * v_n_branches))));
72351 v_children = wuffs_base__u32__min(v_children, 35u);
72352 self->private_data.f_code_lengths_huffman_nodes[v_h] = ((uint16_t)(v_children));
72353 self->private_data.f_code_lengths_huffman_nodes[(v_children + 0u)] = 0u;
72354 self->private_data.f_code_lengths_huffman_nodes[(v_children + 1u)] = 0u;
72355 v_h = (v_children + (v_code_bits >> 31u));
72356 v_n_branches += 1u;
72357 } else {
72358 v_children = ((uint32_t)(v_node));
72359 v_h = (wuffs_base__u32__min(v_children, 35u) + (v_code_bits >> 31u));
72361 v_code_bits <<= 1u;
72362 v_code_len -= 1u;
72364 self->private_data.f_code_lengths_huffman_nodes[v_h] = ((uint16_t)((v_symbol | 32768u)));
72366 v_symbol += 1u;
72368 return wuffs_base__make_status(NULL);
72371 // -------- func webp.decoder.build_huffman_nodes
72373 WUFFS_BASE__GENERATED_C_CODE
72374 static wuffs_base__status
72375 wuffs_webp__decoder__build_huffman_nodes(
72376 wuffs_webp__decoder* self,
72377 uint32_t a_hg,
72378 uint32_t a_ht) {
72379 uint32_t v_base_offset = 0;
72380 uint32_t v_code_bits = 0;
72381 uint32_t v_code_len = 0;
72382 uint32_t v_symbol = 0;
72383 uint32_t v_histogram[16] = {0};
72384 uint32_t v_n_used_symbols = 0;
72385 uint32_t v_last_used_symbol = 0;
72386 uint32_t v_subscription_weight = 0;
72387 uint32_t v_subscription_total = 0;
72388 uint32_t v_curr_code = 0;
72389 uint32_t v_next_codes[17] = {0};
72390 uint32_t v_n_branches = 0;
72391 uint32_t v_h = 0;
72392 uint32_t v_children = 0;
72393 uint16_t v_node = 0;
72395 v_base_offset = ((uint32_t)(WUFFS_WEBP__HUFFMAN_TABLE_BASE_OFFSETS[a_ht]));
72396 v_symbol = 0u;
72397 while (v_symbol < self->private_impl.f_ht_n_symbols) {
72398 v_code_len = ((uint32_t)(((uint16_t)(self->private_data.f_code_lengths[v_symbol] & 15u))));
72399 if (v_code_len != 0u) {
72400 v_histogram[v_code_len] += 1u;
72401 v_n_used_symbols += 1u;
72402 v_last_used_symbol = v_symbol;
72404 v_symbol += 1u;
72406 if (v_n_used_symbols < 1u) {
72407 return wuffs_base__make_status(wuffs_webp__error__bad_huffman_code);
72408 } else if (v_n_used_symbols == 1u) {
72409 self->private_data.f_huffman_nodes[a_hg][v_base_offset] = ((uint16_t)((v_last_used_symbol | 32768u)));
72410 return wuffs_base__make_status(NULL);
72412 v_subscription_weight = 16384u;
72413 v_code_len = 1u;
72414 while (true) {
72415 v_curr_code = ((uint32_t)(((uint32_t)(v_curr_code + v_histogram[v_code_len])) << 1u));
72416 v_next_codes[(v_code_len + 1u)] = v_curr_code;
72417 v_subscription_total += ((uint32_t)(v_subscription_weight * v_histogram[v_code_len]));
72418 v_subscription_weight >>= 1u;
72419 if (v_code_len >= 15u) {
72420 break;
72422 v_code_len += 1u;
72424 if (v_subscription_total > 32768u) {
72425 return wuffs_base__make_status(wuffs_webp__error__bad_huffman_code_over_subscribed);
72426 } else if (v_subscription_total < 32768u) {
72427 return wuffs_base__make_status(wuffs_webp__error__bad_huffman_code_under_subscribed);
72429 self->private_data.f_huffman_nodes[a_hg][v_base_offset] = 0u;
72430 v_symbol = 0u;
72431 while (v_symbol < self->private_impl.f_ht_n_symbols) {
72432 v_code_len = ((uint32_t)(((uint16_t)(self->private_data.f_code_lengths[v_symbol] & 15u))));
72433 if (v_code_len != 0u) {
72434 v_code_bits = v_next_codes[v_code_len];
72435 v_next_codes[v_code_len] += 1u;
72436 v_code_bits <<= (32u - v_code_len);
72437 v_h = v_base_offset;
72438 while (v_code_len > 0u) {
72439 v_node = self->private_data.f_huffman_nodes[a_hg][v_h];
72440 if (v_node == 0u) {
72441 v_children = ((uint32_t)(v_base_offset + ((uint32_t)(1u + ((uint32_t)(2u * v_n_branches))))));
72442 v_children = wuffs_base__u32__min(v_children, 6265u);
72443 self->private_data.f_huffman_nodes[a_hg][v_h] = ((uint16_t)(v_children));
72444 self->private_data.f_huffman_nodes[a_hg][(v_children + 0u)] = 0u;
72445 self->private_data.f_huffman_nodes[a_hg][(v_children + 1u)] = 0u;
72446 v_h = (v_children + (v_code_bits >> 31u));
72447 v_n_branches += 1u;
72448 } else {
72449 v_children = ((uint32_t)(v_node));
72450 v_h = (wuffs_base__u32__min(v_children, 6265u) + (v_code_bits >> 31u));
72452 v_code_bits <<= 1u;
72453 v_code_len -= 1u;
72455 self->private_data.f_huffman_nodes[a_hg][v_h] = ((uint16_t)((v_symbol | 32768u)));
72457 v_symbol += 1u;
72459 return wuffs_base__make_status(NULL);
72462 // -------- func webp.decoder.build_code_lengths
72464 WUFFS_BASE__GENERATED_C_CODE
72465 static wuffs_base__status
72466 wuffs_webp__decoder__build_code_lengths(
72467 wuffs_webp__decoder* self,
72468 wuffs_base__io_buffer* a_src) {
72469 wuffs_base__status status = wuffs_base__make_status(NULL);
72471 uint8_t v_c8 = 0;
72472 uint32_t v_use_length = 0;
72473 uint32_t v_length_n_bits = 0;
72474 uint32_t v_length = 0;
72475 uint16_t v_prev_code_length = 0;
72476 uint32_t v_h = 0;
72477 uint32_t v_s = 0;
72478 uint32_t v_s_max = 0;
72479 uint16_t v_node = 0;
72480 uint32_t v_symbol = 0;
72481 uint16_t v_repeat_value = 0;
72482 uint32_t v_repeat_n_bits = 0;
72484 const uint8_t* iop_a_src = NULL;
72485 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
72486 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
72487 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
72488 if (a_src && a_src->data.ptr) {
72489 io0_a_src = a_src->data.ptr;
72490 io1_a_src = io0_a_src + a_src->meta.ri;
72491 iop_a_src = io1_a_src;
72492 io2_a_src = io0_a_src + a_src->meta.wi;
72495 uint32_t coro_susp_point = self->private_impl.p_build_code_lengths;
72496 if (coro_susp_point) {
72497 v_length_n_bits = self->private_data.s_build_code_lengths.v_length_n_bits;
72498 v_prev_code_length = self->private_data.s_build_code_lengths.v_prev_code_length;
72499 v_s = self->private_data.s_build_code_lengths.v_s;
72500 v_s_max = self->private_data.s_build_code_lengths.v_s_max;
72501 v_node = self->private_data.s_build_code_lengths.v_node;
72502 v_repeat_value = self->private_data.s_build_code_lengths.v_repeat_value;
72503 v_repeat_n_bits = self->private_data.s_build_code_lengths.v_repeat_n_bits;
72505 switch (coro_susp_point) {
72506 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
72508 if (self->private_impl.f_n_bits < 1u) {
72510 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
72511 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
72512 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
72513 goto suspend;
72515 uint8_t t_0 = *iop_a_src++;
72516 v_c8 = t_0;
72518 self->private_impl.f_bits = ((uint32_t)(v_c8));
72519 self->private_impl.f_n_bits = 8u;
72521 v_use_length = (self->private_impl.f_bits & 1u);
72522 self->private_impl.f_bits >>= 1u;
72523 self->private_impl.f_n_bits -= 1u;
72524 self->private_impl.f_ht_code_lengths_remaining = self->private_impl.f_ht_n_symbols;
72525 if (v_use_length != 0u) {
72526 if (self->private_impl.f_n_bits < 3u) {
72528 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
72529 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
72530 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
72531 goto suspend;
72533 uint8_t t_1 = *iop_a_src++;
72534 v_c8 = t_1;
72536 if (self->private_impl.f_n_bits >= 3u) {
72537 status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_n_bits);
72538 goto exit;
72540 self->private_impl.f_bits |= (((uint32_t)(v_c8)) << self->private_impl.f_n_bits);
72541 self->private_impl.f_n_bits += 8u;
72543 v_length_n_bits = (((self->private_impl.f_bits & 7u) * 2u) + 2u);
72544 self->private_impl.f_bits >>= 3u;
72545 self->private_impl.f_n_bits -= 3u;
72546 while (self->private_impl.f_n_bits < v_length_n_bits) {
72548 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
72549 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
72550 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
72551 goto suspend;
72553 uint8_t t_2 = *iop_a_src++;
72554 v_c8 = t_2;
72556 if (self->private_impl.f_n_bits >= v_length_n_bits) {
72557 status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_n_bits);
72558 goto exit;
72560 self->private_impl.f_bits |= (((uint32_t)(v_c8)) << self->private_impl.f_n_bits);
72561 self->private_impl.f_n_bits += 8u;
72563 v_length = ((self->private_impl.f_bits & ((((uint32_t)(1u)) << v_length_n_bits) - 1u)) + 2u);
72564 self->private_impl.f_bits >>= v_length_n_bits;
72565 self->private_impl.f_n_bits -= v_length_n_bits;
72566 if (v_length > self->private_impl.f_ht_n_symbols) {
72567 status = wuffs_base__make_status(wuffs_webp__error__bad_huffman_code);
72568 goto exit;
72570 self->private_impl.f_ht_code_lengths_remaining = v_length;
72572 v_prev_code_length = 8u;
72573 while (v_s < self->private_impl.f_ht_n_symbols) {
72574 if (self->private_impl.f_ht_code_lengths_remaining <= 0u) {
72575 while (v_s < self->private_impl.f_ht_n_symbols) {
72576 self->private_data.f_code_lengths[v_s] = 0u;
72577 v_s += 1u;
72579 break;
72581 self->private_impl.f_ht_code_lengths_remaining -= 1u;
72582 v_h = 0u;
72583 while (true) {
72584 v_node = self->private_data.f_code_lengths_huffman_nodes[v_h];
72585 if (v_node >= 32768u) {
72586 break;
72587 } else if (v_node > 35u) {
72588 status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_huffman_code);
72589 goto exit;
72591 if (self->private_impl.f_n_bits < 1u) {
72593 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
72594 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
72595 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
72596 goto suspend;
72598 uint8_t t_3 = *iop_a_src++;
72599 v_c8 = t_3;
72601 self->private_impl.f_bits = ((uint32_t)(v_c8));
72602 self->private_impl.f_n_bits = 8u;
72604 v_h = (((uint32_t)(v_node)) + (self->private_impl.f_bits & 1u));
72605 self->private_impl.f_bits >>= 1u;
72606 self->private_impl.f_n_bits -= 1u;
72608 v_symbol = ((uint32_t)(((uint16_t)(v_node & 32767u))));
72609 if (v_symbol == 0u) {
72610 self->private_data.f_code_lengths[v_s] = 0u;
72611 v_s += 1u;
72612 continue;
72613 } else if (v_symbol < 16u) {
72614 v_prev_code_length = ((uint16_t)(v_symbol));
72615 self->private_data.f_code_lengths[v_s] = v_prev_code_length;
72616 v_s += 1u;
72617 continue;
72618 } else if (v_symbol == 16u) {
72619 v_repeat_value = v_prev_code_length;
72620 } else {
72621 v_repeat_value = 0u;
72623 v_repeat_n_bits = ((uint32_t)(WUFFS_WEBP__REPEAT_N_BITS[(v_symbol & 3u)]));
72624 v_s_max = ((uint32_t)(((uint32_t)(WUFFS_WEBP__REPEAT_COUNTS[(v_symbol & 3u)])) + v_s));
72625 if (self->private_impl.f_n_bits < v_repeat_n_bits) {
72627 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
72628 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
72629 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
72630 goto suspend;
72632 uint8_t t_4 = *iop_a_src++;
72633 v_c8 = t_4;
72635 if (self->private_impl.f_n_bits >= v_repeat_n_bits) {
72636 status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_n_bits);
72637 goto exit;
72639 self->private_impl.f_bits |= (((uint32_t)(v_c8)) << self->private_impl.f_n_bits);
72640 self->private_impl.f_n_bits += 8u;
72642 v_s_max += (self->private_impl.f_bits & ((((uint32_t)(1u)) << v_repeat_n_bits) - 1u));
72643 self->private_impl.f_bits >>= v_repeat_n_bits;
72644 self->private_impl.f_n_bits -= v_repeat_n_bits;
72645 if (v_s_max > self->private_impl.f_ht_n_symbols) {
72646 status = wuffs_base__make_status(wuffs_webp__error__bad_huffman_code);
72647 goto exit;
72649 while (v_s < v_s_max) {
72650 self->private_data.f_code_lengths[v_s] = v_repeat_value;
72651 v_s += 1u;
72655 goto ok;
72657 self->private_impl.p_build_code_lengths = 0;
72658 goto exit;
72661 goto suspend;
72662 suspend:
72663 self->private_impl.p_build_code_lengths = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
72664 self->private_data.s_build_code_lengths.v_length_n_bits = v_length_n_bits;
72665 self->private_data.s_build_code_lengths.v_prev_code_length = v_prev_code_length;
72666 self->private_data.s_build_code_lengths.v_s = v_s;
72667 self->private_data.s_build_code_lengths.v_s_max = v_s_max;
72668 self->private_data.s_build_code_lengths.v_node = v_node;
72669 self->private_data.s_build_code_lengths.v_repeat_value = v_repeat_value;
72670 self->private_data.s_build_code_lengths.v_repeat_n_bits = v_repeat_n_bits;
72672 goto exit;
72673 exit:
72674 if (a_src && a_src->data.ptr) {
72675 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
72678 return status;
72681 // -------- func webp.decoder.decode_pixels_slow
72683 WUFFS_BASE__GENERATED_C_CODE
72684 static wuffs_base__status
72685 wuffs_webp__decoder__decode_pixels_slow(
72686 wuffs_webp__decoder* self,
72687 wuffs_base__slice_u8 a_dst,
72688 wuffs_base__io_buffer* a_src,
72689 uint32_t a_width,
72690 uint32_t a_height,
72691 wuffs_base__slice_u8 a_tile_data,
72692 uint32_t a_tile_size_log2) {
72693 wuffs_base__status status = wuffs_base__make_status(NULL);
72695 uint8_t v_c8 = 0;
72696 uint64_t v_p = 0;
72697 uint64_t v_p_max = 0;
72698 uint32_t v_tile_size_log2 = 0;
72699 uint32_t v_width_in_tiles = 0;
72700 uint32_t v_x = 0;
72701 uint32_t v_y = 0;
72702 uint32_t v_i = 0;
72703 uint32_t v_hg = 0;
72704 uint32_t v_h = 0;
72705 uint16_t v_node = 0;
72706 uint32_t v_pixel_g = 0;
72707 uint32_t v_color = 0;
72708 wuffs_base__slice_u8 v_dst_pixel = {0};
72709 uint32_t v_back_ref_len_n_bits = 0;
72710 uint32_t v_back_ref_len_minus_1 = 0;
72711 uint32_t v_back_ref_dist_n_bits = 0;
72712 uint32_t v_back_ref_dist_sym = 0;
72713 uint32_t v_back_ref_dist_premap_minus_1 = 0;
72714 uint32_t v_back_ref_dist_minus_1 = 0;
72715 uint32_t v_dm = 0;
72716 uint32_t v_dx = 0;
72717 uint32_t v_dy = 0;
72718 uint64_t v_p_end = 0;
72719 uint64_t v_dist4 = 0;
72720 uint64_t v_q = 0;
72721 wuffs_base__slice_u8 v_color_cache_pixels = {0};
72722 uint64_t v_color_cache_p = 0;
72723 uint32_t v_color_cache_shift = 0;
72725 const uint8_t* iop_a_src = NULL;
72726 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
72727 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
72728 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
72729 if (a_src && a_src->data.ptr) {
72730 io0_a_src = a_src->data.ptr;
72731 io1_a_src = io0_a_src + a_src->meta.ri;
72732 iop_a_src = io1_a_src;
72733 io2_a_src = io0_a_src + a_src->meta.wi;
72736 uint32_t coro_susp_point = self->private_impl.p_decode_pixels_slow;
72737 if (coro_susp_point) {
72738 v_p = self->private_data.s_decode_pixels_slow.v_p;
72739 v_p_max = self->private_data.s_decode_pixels_slow.v_p_max;
72740 v_tile_size_log2 = self->private_data.s_decode_pixels_slow.v_tile_size_log2;
72741 v_width_in_tiles = self->private_data.s_decode_pixels_slow.v_width_in_tiles;
72742 v_x = self->private_data.s_decode_pixels_slow.v_x;
72743 v_y = self->private_data.s_decode_pixels_slow.v_y;
72744 v_hg = self->private_data.s_decode_pixels_slow.v_hg;
72745 v_node = self->private_data.s_decode_pixels_slow.v_node;
72746 v_color = self->private_data.s_decode_pixels_slow.v_color;
72747 v_back_ref_len_n_bits = self->private_data.s_decode_pixels_slow.v_back_ref_len_n_bits;
72748 v_back_ref_len_minus_1 = self->private_data.s_decode_pixels_slow.v_back_ref_len_minus_1;
72749 v_back_ref_dist_n_bits = self->private_data.s_decode_pixels_slow.v_back_ref_dist_n_bits;
72750 v_back_ref_dist_premap_minus_1 = self->private_data.s_decode_pixels_slow.v_back_ref_dist_premap_minus_1;
72751 v_color_cache_p = self->private_data.s_decode_pixels_slow.v_color_cache_p;
72753 switch (coro_susp_point) {
72754 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
72756 v_p_max = ((uint64_t)((4u * a_width * a_height)));
72757 if (((uint64_t)(a_dst.len)) < v_p_max) {
72758 status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_dst_buffer);
72759 goto exit;
72761 if (a_tile_size_log2 != 0u) {
72762 v_tile_size_log2 = a_tile_size_log2;
72763 v_width_in_tiles = ((a_width + ((((uint32_t)(1u)) << v_tile_size_log2) - 1u)) >> v_tile_size_log2);
72764 } else {
72765 v_tile_size_log2 = 31u;
72766 v_width_in_tiles = 1u;
72768 while (v_p < v_p_max) {
72769 v_i = ((uint32_t)(((uint32_t)(((uint32_t)(((uint32_t)((v_y >> v_tile_size_log2) * v_width_in_tiles)) + (v_x >> v_tile_size_log2))) * 4u)) + 1u));
72770 if (((uint64_t)(v_i)) < ((uint64_t)(a_tile_data.len))) {
72771 v_hg = ((uint32_t)(a_tile_data.ptr[((uint64_t)(v_i))]));
72773 v_h = ((uint32_t)(WUFFS_WEBP__HUFFMAN_TABLE_BASE_OFFSETS[0u]));
72774 while (true) {
72775 v_node = self->private_data.f_huffman_nodes[v_hg][v_h];
72776 if (v_node >= 32768u) {
72777 break;
72778 } else if (v_node > 6265u) {
72779 status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_huffman_code);
72780 goto exit;
72782 if (self->private_impl.f_n_bits < 1u) {
72784 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
72785 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
72786 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
72787 goto suspend;
72789 uint8_t t_0 = *iop_a_src++;
72790 v_c8 = t_0;
72792 self->private_impl.f_bits = ((uint32_t)(v_c8));
72793 self->private_impl.f_n_bits = 8u;
72795 v_h = (((uint32_t)(v_node)) + (self->private_impl.f_bits & 1u));
72796 self->private_impl.f_bits >>= 1u;
72797 self->private_impl.f_n_bits -= 1u;
72799 v_pixel_g = ((uint32_t)(((uint16_t)(v_node & 32767u))));
72800 if (v_pixel_g < 256u) {
72801 v_color = (v_pixel_g << 8u);
72802 v_h = ((uint32_t)(WUFFS_WEBP__HUFFMAN_TABLE_BASE_OFFSETS[1u]));
72803 while (true) {
72804 v_node = self->private_data.f_huffman_nodes[v_hg][v_h];
72805 if (v_node >= 32768u) {
72806 break;
72808 if (self->private_impl.f_n_bits < 1u) {
72810 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
72811 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
72812 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
72813 goto suspend;
72815 uint8_t t_1 = *iop_a_src++;
72816 v_c8 = t_1;
72818 self->private_impl.f_bits = ((uint32_t)(v_c8));
72819 self->private_impl.f_n_bits = 8u;
72821 v_h = ((((uint32_t)(v_node)) & 4095u) + (self->private_impl.f_bits & 1u));
72822 self->private_impl.f_bits >>= 1u;
72823 self->private_impl.f_n_bits -= 1u;
72825 v_color |= (((uint32_t)(((uint16_t)(v_node & 255u)))) << 16u);
72826 v_h = ((uint32_t)(WUFFS_WEBP__HUFFMAN_TABLE_BASE_OFFSETS[2u]));
72827 while (true) {
72828 v_node = self->private_data.f_huffman_nodes[v_hg][v_h];
72829 if (v_node >= 32768u) {
72830 break;
72832 if (self->private_impl.f_n_bits < 1u) {
72834 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
72835 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
72836 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
72837 goto suspend;
72839 uint8_t t_2 = *iop_a_src++;
72840 v_c8 = t_2;
72842 self->private_impl.f_bits = ((uint32_t)(v_c8));
72843 self->private_impl.f_n_bits = 8u;
72845 v_h = ((((uint32_t)(v_node)) & 4095u) + (self->private_impl.f_bits & 1u));
72846 self->private_impl.f_bits >>= 1u;
72847 self->private_impl.f_n_bits -= 1u;
72849 v_color |= (((uint32_t)(((uint16_t)(v_node & 255u)))) << 0u);
72850 v_h = ((uint32_t)(WUFFS_WEBP__HUFFMAN_TABLE_BASE_OFFSETS[3u]));
72851 while (true) {
72852 v_node = self->private_data.f_huffman_nodes[v_hg][v_h];
72853 if (v_node >= 32768u) {
72854 break;
72856 if (self->private_impl.f_n_bits < 1u) {
72858 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
72859 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
72860 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
72861 goto suspend;
72863 uint8_t t_3 = *iop_a_src++;
72864 v_c8 = t_3;
72866 self->private_impl.f_bits = ((uint32_t)(v_c8));
72867 self->private_impl.f_n_bits = 8u;
72869 v_h = ((((uint32_t)(v_node)) & 4095u) + (self->private_impl.f_bits & 1u));
72870 self->private_impl.f_bits >>= 1u;
72871 self->private_impl.f_n_bits -= 1u;
72873 v_color |= (((uint32_t)(((uint16_t)(v_node & 255u)))) << 24u);
72874 } else if (v_pixel_g < 280u) {
72875 if (v_pixel_g < 260u) {
72876 v_back_ref_len_minus_1 = (v_pixel_g - 256u);
72877 } else {
72878 v_back_ref_len_n_bits = ((v_pixel_g - 258u) >> 1u);
72879 v_back_ref_len_minus_1 = ((((uint32_t)(2u)) + (v_pixel_g & 1u)) << v_back_ref_len_n_bits);
72880 while (self->private_impl.f_n_bits < v_back_ref_len_n_bits) {
72882 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
72883 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
72884 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
72885 goto suspend;
72887 uint8_t t_4 = *iop_a_src++;
72888 v_c8 = t_4;
72890 if (self->private_impl.f_n_bits >= v_back_ref_len_n_bits) {
72891 status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_n_bits);
72892 goto exit;
72894 self->private_impl.f_bits |= (((uint32_t)(v_c8)) << self->private_impl.f_n_bits);
72895 self->private_impl.f_n_bits += 8u;
72897 v_back_ref_len_minus_1 += (self->private_impl.f_bits & ((((uint32_t)(1u)) << v_back_ref_len_n_bits) - 1u));
72898 self->private_impl.f_bits >>= v_back_ref_len_n_bits;
72899 self->private_impl.f_n_bits -= v_back_ref_len_n_bits;
72901 v_h = ((uint32_t)(WUFFS_WEBP__HUFFMAN_TABLE_BASE_OFFSETS[4u]));
72902 while (true) {
72903 v_node = self->private_data.f_huffman_nodes[v_hg][v_h];
72904 if (v_node >= 32768u) {
72905 break;
72907 if (self->private_impl.f_n_bits < 1u) {
72909 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
72910 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
72911 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
72912 goto suspend;
72914 uint8_t t_5 = *iop_a_src++;
72915 v_c8 = t_5;
72917 self->private_impl.f_bits = ((uint32_t)(v_c8));
72918 self->private_impl.f_n_bits = 8u;
72920 v_h = ((((uint32_t)(v_node)) & 4095u) + (self->private_impl.f_bits & 1u));
72921 self->private_impl.f_bits >>= 1u;
72922 self->private_impl.f_n_bits -= 1u;
72924 v_back_ref_dist_sym = ((uint32_t)(((uint16_t)(v_node & 32767u))));
72925 if (v_back_ref_dist_sym < 4u) {
72926 v_back_ref_dist_premap_minus_1 = v_back_ref_dist_sym;
72927 } else if (v_back_ref_dist_sym < 40u) {
72928 v_back_ref_dist_n_bits = ((v_back_ref_dist_sym - 2u) >> 1u);
72929 v_back_ref_dist_premap_minus_1 = ((((uint32_t)(2u)) + (v_back_ref_dist_sym & 1u)) << v_back_ref_dist_n_bits);
72930 while (self->private_impl.f_n_bits < v_back_ref_dist_n_bits) {
72932 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
72933 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
72934 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
72935 goto suspend;
72937 uint8_t t_6 = *iop_a_src++;
72938 v_c8 = t_6;
72940 if (self->private_impl.f_n_bits >= v_back_ref_dist_n_bits) {
72941 status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_n_bits);
72942 goto exit;
72944 self->private_impl.f_bits |= (((uint32_t)(v_c8)) << self->private_impl.f_n_bits);
72945 self->private_impl.f_n_bits += 8u;
72947 v_back_ref_dist_premap_minus_1 += (self->private_impl.f_bits & ((((uint32_t)(1u)) << v_back_ref_dist_n_bits) - 1u));
72948 self->private_impl.f_bits >>= v_back_ref_dist_n_bits;
72949 self->private_impl.f_n_bits -= v_back_ref_dist_n_bits;
72951 if (v_back_ref_dist_premap_minus_1 >= 120u) {
72952 v_back_ref_dist_minus_1 = (v_back_ref_dist_premap_minus_1 - 120u);
72953 } else {
72954 v_dm = ((uint32_t)(WUFFS_WEBP__DISTANCE_MAP[v_back_ref_dist_premap_minus_1]));
72955 v_dy = (v_dm >> 4u);
72956 v_dx = ((uint32_t)(7u - (v_dm & 15u)));
72957 v_back_ref_dist_minus_1 = ((uint32_t)((a_width * v_dy) + v_dx));
72959 v_p_end = (v_p + ((uint64_t)(((v_back_ref_len_minus_1 + 1u) * 4u))));
72960 v_dist4 = ((((uint64_t)(v_back_ref_dist_minus_1)) * 4u) + 4u);
72961 if ((v_p_end > v_p_max) || (v_p_end > ((uint64_t)(a_dst.len))) || (v_p < v_dist4)) {
72962 status = wuffs_base__make_status(wuffs_webp__error__bad_back_reference);
72963 goto exit;
72965 v_q = (v_p - v_dist4);
72966 while ((v_q < v_p) && (v_p < v_p_end)) {
72967 a_dst.ptr[v_p] = a_dst.ptr[v_q];
72968 v_p += 1u;
72969 v_q += 1u;
72971 v_x += (v_back_ref_len_minus_1 + 1u);
72972 while (v_x >= a_width) {
72973 v_x -= a_width;
72974 v_y += 1u;
72976 continue;
72977 } else {
72978 if ((v_color_cache_p > v_p) || (v_p > ((uint64_t)(a_dst.len)))) {
72979 status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_dst_buffer);
72980 goto exit;
72982 v_color_cache_pixels = wuffs_base__slice_u8__subslice_ij(a_dst, v_color_cache_p, v_p);
72983 v_color_cache_p = v_p;
72984 v_color_cache_shift = ((32u - self->private_impl.f_color_cache_bits) & 31u);
72985 while (((uint64_t)(v_color_cache_pixels.len)) >= 4u) {
72986 v_color = wuffs_base__peek_u32le__no_bounds_check(v_color_cache_pixels.ptr);
72987 self->private_data.f_color_cache[((((uint32_t)(v_color * 506832829u)) >> v_color_cache_shift) & 2047u)] = v_color;
72988 v_color_cache_pixels = wuffs_base__slice_u8__subslice_i(v_color_cache_pixels, 4u);
72990 v_color = self->private_data.f_color_cache[((v_pixel_g - 280u) & 2047u)];
72992 if (v_p > ((uint64_t)(a_dst.len))) {
72993 status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_dst_buffer);
72994 goto exit;
72996 v_dst_pixel = wuffs_base__slice_u8__subslice_i(a_dst, v_p);
72997 if (((uint64_t)(v_dst_pixel.len)) < 4u) {
72998 status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_dst_buffer);
72999 goto exit;
73001 wuffs_base__poke_u32le__no_bounds_check(v_dst_pixel.ptr, v_color);
73002 v_p += 4u;
73003 v_x += 1u;
73004 if (v_x == a_width) {
73005 v_x = 0u;
73006 v_y += 1u;
73010 goto ok;
73012 self->private_impl.p_decode_pixels_slow = 0;
73013 goto exit;
73016 goto suspend;
73017 suspend:
73018 self->private_impl.p_decode_pixels_slow = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
73019 self->private_data.s_decode_pixels_slow.v_p = v_p;
73020 self->private_data.s_decode_pixels_slow.v_p_max = v_p_max;
73021 self->private_data.s_decode_pixels_slow.v_tile_size_log2 = v_tile_size_log2;
73022 self->private_data.s_decode_pixels_slow.v_width_in_tiles = v_width_in_tiles;
73023 self->private_data.s_decode_pixels_slow.v_x = v_x;
73024 self->private_data.s_decode_pixels_slow.v_y = v_y;
73025 self->private_data.s_decode_pixels_slow.v_hg = v_hg;
73026 self->private_data.s_decode_pixels_slow.v_node = v_node;
73027 self->private_data.s_decode_pixels_slow.v_color = v_color;
73028 self->private_data.s_decode_pixels_slow.v_back_ref_len_n_bits = v_back_ref_len_n_bits;
73029 self->private_data.s_decode_pixels_slow.v_back_ref_len_minus_1 = v_back_ref_len_minus_1;
73030 self->private_data.s_decode_pixels_slow.v_back_ref_dist_n_bits = v_back_ref_dist_n_bits;
73031 self->private_data.s_decode_pixels_slow.v_back_ref_dist_premap_minus_1 = v_back_ref_dist_premap_minus_1;
73032 self->private_data.s_decode_pixels_slow.v_color_cache_p = v_color_cache_p;
73034 goto exit;
73035 exit:
73036 if (a_src && a_src->data.ptr) {
73037 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
73040 return status;
73043 // -------- func webp.decoder.apply_transform_predictor
73045 WUFFS_BASE__GENERATED_C_CODE
73046 static wuffs_base__empty_struct
73047 wuffs_webp__decoder__apply_transform_predictor(
73048 wuffs_webp__decoder* self,
73049 wuffs_base__slice_u8 a_pix,
73050 wuffs_base__slice_u8 a_tile_data) {
73051 uint64_t v_w4 = 0;
73052 wuffs_base__slice_u8 v_prev_row = {0};
73053 wuffs_base__slice_u8 v_curr_row = {0};
73054 uint32_t v_tile_size_log2 = 0;
73055 uint32_t v_tiles_per_row = 0;
73056 uint32_t v_mask = 0;
73057 uint32_t v_y = 0;
73058 uint32_t v_x = 0;
73059 uint64_t v_t = 0;
73060 wuffs_base__slice_u8 v_tile_data = {0};
73061 uint8_t v_mode = 0;
73062 uint32_t v_l0 = 0;
73063 uint32_t v_l1 = 0;
73064 uint32_t v_l2 = 0;
73065 uint32_t v_l3 = 0;
73066 uint32_t v_c0 = 0;
73067 uint32_t v_c1 = 0;
73068 uint32_t v_c2 = 0;
73069 uint32_t v_c3 = 0;
73070 uint32_t v_t0 = 0;
73071 uint32_t v_t1 = 0;
73072 uint32_t v_t2 = 0;
73073 uint32_t v_t3 = 0;
73074 uint32_t v_sum_l = 0;
73075 uint32_t v_sum_t = 0;
73077 if ((self->private_impl.f_width <= 0u) || (self->private_impl.f_height <= 0u)) {
73078 return wuffs_base__make_empty_struct();
73080 v_w4 = ((uint64_t)((self->private_impl.f_width * 4u)));
73081 v_curr_row = wuffs_base__utility__empty_slice_u8();
73082 if (v_w4 <= ((uint64_t)(a_pix.len))) {
73083 v_curr_row = wuffs_base__slice_u8__subslice_j(a_pix, v_w4);
73085 if (((uint64_t)(v_curr_row.len)) >= 4u) {
73086 #if defined(__GNUC__)
73087 #pragma GCC diagnostic push
73088 #pragma GCC diagnostic ignored "-Wconversion"
73089 #endif
73090 v_curr_row.ptr[3u] += 255u;
73091 #if defined(__GNUC__)
73092 #pragma GCC diagnostic pop
73093 #endif
73095 while (((uint64_t)(v_curr_row.len)) >= 8u) {
73096 #if defined(__GNUC__)
73097 #pragma GCC diagnostic push
73098 #pragma GCC diagnostic ignored "-Wconversion"
73099 #endif
73100 v_curr_row.ptr[4u] += v_curr_row.ptr[0u];
73101 v_curr_row.ptr[5u] += v_curr_row.ptr[1u];
73102 v_curr_row.ptr[6u] += v_curr_row.ptr[2u];
73103 v_curr_row.ptr[7u] += v_curr_row.ptr[3u];
73104 #if defined(__GNUC__)
73105 #pragma GCC diagnostic pop
73106 #endif
73107 v_curr_row = wuffs_base__slice_u8__subslice_i(v_curr_row, 4u);
73109 v_tile_size_log2 = ((uint32_t)(self->private_impl.f_transform_tile_size_log2[0u]));
73110 v_tiles_per_row = ((self->private_impl.f_width + ((((uint32_t)(1u)) << v_tile_size_log2) - 1u)) >> v_tile_size_log2);
73111 v_mask = ((((uint32_t)(1u)) << v_tile_size_log2) - 1u);
73112 v_y = 1u;
73113 while (v_y < self->private_impl.f_height) {
73114 v_t = ((uint64_t)((4u * (v_y >> v_tile_size_log2) * v_tiles_per_row)));
73115 v_tile_data = wuffs_base__utility__empty_slice_u8();
73116 if (v_t <= ((uint64_t)(a_tile_data.len))) {
73117 v_tile_data = wuffs_base__slice_u8__subslice_i(a_tile_data, v_t);
73118 if (((uint64_t)(v_tile_data.len)) >= 4u) {
73119 v_mode = ((uint8_t)(v_tile_data.ptr[1u] & 15u));
73120 v_tile_data = wuffs_base__slice_u8__subslice_i(v_tile_data, 4u);
73123 if (v_w4 <= ((uint64_t)(a_pix.len))) {
73124 v_prev_row = a_pix;
73125 a_pix = wuffs_base__slice_u8__subslice_i(a_pix, v_w4);
73126 v_curr_row = a_pix;
73128 if ((((uint64_t)(v_prev_row.len)) >= 4u) && (((uint64_t)(v_curr_row.len)) >= 4u)) {
73129 #if defined(__GNUC__)
73130 #pragma GCC diagnostic push
73131 #pragma GCC diagnostic ignored "-Wconversion"
73132 #endif
73133 v_curr_row.ptr[0u] += v_prev_row.ptr[0u];
73134 v_curr_row.ptr[1u] += v_prev_row.ptr[1u];
73135 v_curr_row.ptr[2u] += v_prev_row.ptr[2u];
73136 v_curr_row.ptr[3u] += v_prev_row.ptr[3u];
73137 #if defined(__GNUC__)
73138 #pragma GCC diagnostic pop
73139 #endif
73141 v_x = 1u;
73142 while (v_x < self->private_impl.f_width) {
73143 if (((v_x & v_mask) == 0u) && (((uint64_t)(v_tile_data.len)) >= 4u)) {
73144 v_mode = ((uint8_t)(v_tile_data.ptr[1u] & 15u));
73145 v_tile_data = wuffs_base__slice_u8__subslice_i(v_tile_data, 4u);
73147 if ((((uint64_t)(v_prev_row.len)) < 12u) || (((uint64_t)(v_curr_row.len)) < 8u)) {
73148 break;
73150 if (v_mode == 0u) {
73151 #if defined(__GNUC__)
73152 #pragma GCC diagnostic push
73153 #pragma GCC diagnostic ignored "-Wconversion"
73154 #endif
73155 v_curr_row.ptr[7u] += 255u;
73156 #if defined(__GNUC__)
73157 #pragma GCC diagnostic pop
73158 #endif
73159 } else if (v_mode == 1u) {
73160 #if defined(__GNUC__)
73161 #pragma GCC diagnostic push
73162 #pragma GCC diagnostic ignored "-Wconversion"
73163 #endif
73164 v_curr_row.ptr[4u] += v_curr_row.ptr[0u];
73165 v_curr_row.ptr[5u] += v_curr_row.ptr[1u];
73166 v_curr_row.ptr[6u] += v_curr_row.ptr[2u];
73167 v_curr_row.ptr[7u] += v_curr_row.ptr[3u];
73168 #if defined(__GNUC__)
73169 #pragma GCC diagnostic pop
73170 #endif
73171 } else if (v_mode == 2u) {
73172 #if defined(__GNUC__)
73173 #pragma GCC diagnostic push
73174 #pragma GCC diagnostic ignored "-Wconversion"
73175 #endif
73176 v_curr_row.ptr[4u] += v_prev_row.ptr[4u];
73177 v_curr_row.ptr[5u] += v_prev_row.ptr[5u];
73178 v_curr_row.ptr[6u] += v_prev_row.ptr[6u];
73179 v_curr_row.ptr[7u] += v_prev_row.ptr[7u];
73180 #if defined(__GNUC__)
73181 #pragma GCC diagnostic pop
73182 #endif
73183 } else if (v_mode == 3u) {
73184 #if defined(__GNUC__)
73185 #pragma GCC diagnostic push
73186 #pragma GCC diagnostic ignored "-Wconversion"
73187 #endif
73188 v_curr_row.ptr[4u] += v_prev_row.ptr[8u];
73189 v_curr_row.ptr[5u] += v_prev_row.ptr[9u];
73190 v_curr_row.ptr[6u] += v_prev_row.ptr[10u];
73191 v_curr_row.ptr[7u] += v_prev_row.ptr[11u];
73192 #if defined(__GNUC__)
73193 #pragma GCC diagnostic pop
73194 #endif
73195 } else if (v_mode == 4u) {
73196 #if defined(__GNUC__)
73197 #pragma GCC diagnostic push
73198 #pragma GCC diagnostic ignored "-Wconversion"
73199 #endif
73200 v_curr_row.ptr[4u] += v_prev_row.ptr[0u];
73201 v_curr_row.ptr[5u] += v_prev_row.ptr[1u];
73202 v_curr_row.ptr[6u] += v_prev_row.ptr[2u];
73203 v_curr_row.ptr[7u] += v_prev_row.ptr[3u];
73204 #if defined(__GNUC__)
73205 #pragma GCC diagnostic pop
73206 #endif
73207 } else if (v_mode == 5u) {
73208 v_l0 = ((((uint32_t)(v_curr_row.ptr[0u])) + ((uint32_t)(v_prev_row.ptr[8u]))) / 2u);
73209 v_l1 = ((((uint32_t)(v_curr_row.ptr[1u])) + ((uint32_t)(v_prev_row.ptr[9u]))) / 2u);
73210 v_l2 = ((((uint32_t)(v_curr_row.ptr[2u])) + ((uint32_t)(v_prev_row.ptr[10u]))) / 2u);
73211 v_l3 = ((((uint32_t)(v_curr_row.ptr[3u])) + ((uint32_t)(v_prev_row.ptr[11u]))) / 2u);
73212 #if defined(__GNUC__)
73213 #pragma GCC diagnostic push
73214 #pragma GCC diagnostic ignored "-Wconversion"
73215 #endif
73216 v_curr_row.ptr[4u] += ((uint8_t)(((v_l0 + ((uint32_t)(v_prev_row.ptr[4u]))) / 2u)));
73217 v_curr_row.ptr[5u] += ((uint8_t)(((v_l1 + ((uint32_t)(v_prev_row.ptr[5u]))) / 2u)));
73218 v_curr_row.ptr[6u] += ((uint8_t)(((v_l2 + ((uint32_t)(v_prev_row.ptr[6u]))) / 2u)));
73219 v_curr_row.ptr[7u] += ((uint8_t)(((v_l3 + ((uint32_t)(v_prev_row.ptr[7u]))) / 2u)));
73220 #if defined(__GNUC__)
73221 #pragma GCC diagnostic pop
73222 #endif
73223 } else if (v_mode == 6u) {
73224 #if defined(__GNUC__)
73225 #pragma GCC diagnostic push
73226 #pragma GCC diagnostic ignored "-Wconversion"
73227 #endif
73228 v_curr_row.ptr[4u] += ((uint8_t)(((((uint32_t)(v_curr_row.ptr[0u])) + ((uint32_t)(v_prev_row.ptr[0u]))) / 2u)));
73229 v_curr_row.ptr[5u] += ((uint8_t)(((((uint32_t)(v_curr_row.ptr[1u])) + ((uint32_t)(v_prev_row.ptr[1u]))) / 2u)));
73230 v_curr_row.ptr[6u] += ((uint8_t)(((((uint32_t)(v_curr_row.ptr[2u])) + ((uint32_t)(v_prev_row.ptr[2u]))) / 2u)));
73231 v_curr_row.ptr[7u] += ((uint8_t)(((((uint32_t)(v_curr_row.ptr[3u])) + ((uint32_t)(v_prev_row.ptr[3u]))) / 2u)));
73232 #if defined(__GNUC__)
73233 #pragma GCC diagnostic pop
73234 #endif
73235 } else if (v_mode == 7u) {
73236 #if defined(__GNUC__)
73237 #pragma GCC diagnostic push
73238 #pragma GCC diagnostic ignored "-Wconversion"
73239 #endif
73240 v_curr_row.ptr[4u] += ((uint8_t)(((((uint32_t)(v_curr_row.ptr[0u])) + ((uint32_t)(v_prev_row.ptr[4u]))) / 2u)));
73241 v_curr_row.ptr[5u] += ((uint8_t)(((((uint32_t)(v_curr_row.ptr[1u])) + ((uint32_t)(v_prev_row.ptr[5u]))) / 2u)));
73242 v_curr_row.ptr[6u] += ((uint8_t)(((((uint32_t)(v_curr_row.ptr[2u])) + ((uint32_t)(v_prev_row.ptr[6u]))) / 2u)));
73243 v_curr_row.ptr[7u] += ((uint8_t)(((((uint32_t)(v_curr_row.ptr[3u])) + ((uint32_t)(v_prev_row.ptr[7u]))) / 2u)));
73244 #if defined(__GNUC__)
73245 #pragma GCC diagnostic pop
73246 #endif
73247 } else if (v_mode == 8u) {
73248 #if defined(__GNUC__)
73249 #pragma GCC diagnostic push
73250 #pragma GCC diagnostic ignored "-Wconversion"
73251 #endif
73252 v_curr_row.ptr[4u] += ((uint8_t)(((((uint32_t)(v_prev_row.ptr[0u])) + ((uint32_t)(v_prev_row.ptr[4u]))) / 2u)));
73253 v_curr_row.ptr[5u] += ((uint8_t)(((((uint32_t)(v_prev_row.ptr[1u])) + ((uint32_t)(v_prev_row.ptr[5u]))) / 2u)));
73254 v_curr_row.ptr[6u] += ((uint8_t)(((((uint32_t)(v_prev_row.ptr[2u])) + ((uint32_t)(v_prev_row.ptr[6u]))) / 2u)));
73255 v_curr_row.ptr[7u] += ((uint8_t)(((((uint32_t)(v_prev_row.ptr[3u])) + ((uint32_t)(v_prev_row.ptr[7u]))) / 2u)));
73256 #if defined(__GNUC__)
73257 #pragma GCC diagnostic pop
73258 #endif
73259 } else if (v_mode == 9u) {
73260 #if defined(__GNUC__)
73261 #pragma GCC diagnostic push
73262 #pragma GCC diagnostic ignored "-Wconversion"
73263 #endif
73264 v_curr_row.ptr[4u] += ((uint8_t)(((((uint32_t)(v_prev_row.ptr[4u])) + ((uint32_t)(v_prev_row.ptr[8u]))) / 2u)));
73265 v_curr_row.ptr[5u] += ((uint8_t)(((((uint32_t)(v_prev_row.ptr[5u])) + ((uint32_t)(v_prev_row.ptr[9u]))) / 2u)));
73266 v_curr_row.ptr[6u] += ((uint8_t)(((((uint32_t)(v_prev_row.ptr[6u])) + ((uint32_t)(v_prev_row.ptr[10u]))) / 2u)));
73267 v_curr_row.ptr[7u] += ((uint8_t)(((((uint32_t)(v_prev_row.ptr[7u])) + ((uint32_t)(v_prev_row.ptr[11u]))) / 2u)));
73268 #if defined(__GNUC__)
73269 #pragma GCC diagnostic pop
73270 #endif
73271 } else if (v_mode == 10u) {
73272 v_l0 = ((((uint32_t)(v_curr_row.ptr[0u])) + ((uint32_t)(v_prev_row.ptr[0u]))) / 2u);
73273 v_l1 = ((((uint32_t)(v_curr_row.ptr[1u])) + ((uint32_t)(v_prev_row.ptr[1u]))) / 2u);
73274 v_l2 = ((((uint32_t)(v_curr_row.ptr[2u])) + ((uint32_t)(v_prev_row.ptr[2u]))) / 2u);
73275 v_l3 = ((((uint32_t)(v_curr_row.ptr[3u])) + ((uint32_t)(v_prev_row.ptr[3u]))) / 2u);
73276 v_t0 = ((((uint32_t)(v_prev_row.ptr[4u])) + ((uint32_t)(v_prev_row.ptr[8u]))) / 2u);
73277 v_t1 = ((((uint32_t)(v_prev_row.ptr[5u])) + ((uint32_t)(v_prev_row.ptr[9u]))) / 2u);
73278 v_t2 = ((((uint32_t)(v_prev_row.ptr[6u])) + ((uint32_t)(v_prev_row.ptr[10u]))) / 2u);
73279 v_t3 = ((((uint32_t)(v_prev_row.ptr[7u])) + ((uint32_t)(v_prev_row.ptr[11u]))) / 2u);
73280 #if defined(__GNUC__)
73281 #pragma GCC diagnostic push
73282 #pragma GCC diagnostic ignored "-Wconversion"
73283 #endif
73284 v_curr_row.ptr[4u] += ((uint8_t)(((v_l0 + v_t0) / 2u)));
73285 v_curr_row.ptr[5u] += ((uint8_t)(((v_l1 + v_t1) / 2u)));
73286 v_curr_row.ptr[6u] += ((uint8_t)(((v_l2 + v_t2) / 2u)));
73287 v_curr_row.ptr[7u] += ((uint8_t)(((v_l3 + v_t3) / 2u)));
73288 #if defined(__GNUC__)
73289 #pragma GCC diagnostic pop
73290 #endif
73291 } else if (v_mode == 11u) {
73292 v_l0 = ((uint32_t)(v_curr_row.ptr[0u]));
73293 v_l1 = ((uint32_t)(v_curr_row.ptr[1u]));
73294 v_l2 = ((uint32_t)(v_curr_row.ptr[2u]));
73295 v_l3 = ((uint32_t)(v_curr_row.ptr[3u]));
73296 v_c0 = ((uint32_t)(v_prev_row.ptr[0u]));
73297 v_c1 = ((uint32_t)(v_prev_row.ptr[1u]));
73298 v_c2 = ((uint32_t)(v_prev_row.ptr[2u]));
73299 v_c3 = ((uint32_t)(v_prev_row.ptr[3u]));
73300 v_t0 = ((uint32_t)(v_prev_row.ptr[4u]));
73301 v_t1 = ((uint32_t)(v_prev_row.ptr[5u]));
73302 v_t2 = ((uint32_t)(v_prev_row.ptr[6u]));
73303 v_t3 = ((uint32_t)(v_prev_row.ptr[7u]));
73304 v_sum_l = (wuffs_webp__decoder__absolute_difference(self, v_c0, v_t0) +
73305 wuffs_webp__decoder__absolute_difference(self, v_c1, v_t1) +
73306 wuffs_webp__decoder__absolute_difference(self, v_c2, v_t2) +
73307 wuffs_webp__decoder__absolute_difference(self, v_c3, v_t3));
73308 v_sum_t = (wuffs_webp__decoder__absolute_difference(self, v_c0, v_l0) +
73309 wuffs_webp__decoder__absolute_difference(self, v_c1, v_l1) +
73310 wuffs_webp__decoder__absolute_difference(self, v_c2, v_l2) +
73311 wuffs_webp__decoder__absolute_difference(self, v_c3, v_l3));
73312 if (v_sum_l < v_sum_t) {
73313 #if defined(__GNUC__)
73314 #pragma GCC diagnostic push
73315 #pragma GCC diagnostic ignored "-Wconversion"
73316 #endif
73317 v_curr_row.ptr[4u] += ((uint8_t)(v_l0));
73318 v_curr_row.ptr[5u] += ((uint8_t)(v_l1));
73319 v_curr_row.ptr[6u] += ((uint8_t)(v_l2));
73320 v_curr_row.ptr[7u] += ((uint8_t)(v_l3));
73321 #if defined(__GNUC__)
73322 #pragma GCC diagnostic pop
73323 #endif
73324 } else {
73325 #if defined(__GNUC__)
73326 #pragma GCC diagnostic push
73327 #pragma GCC diagnostic ignored "-Wconversion"
73328 #endif
73329 v_curr_row.ptr[4u] += ((uint8_t)(v_t0));
73330 v_curr_row.ptr[5u] += ((uint8_t)(v_t1));
73331 v_curr_row.ptr[6u] += ((uint8_t)(v_t2));
73332 v_curr_row.ptr[7u] += ((uint8_t)(v_t3));
73333 #if defined(__GNUC__)
73334 #pragma GCC diagnostic pop
73335 #endif
73337 } else if (v_mode == 12u) {
73338 #if defined(__GNUC__)
73339 #pragma GCC diagnostic push
73340 #pragma GCC diagnostic ignored "-Wconversion"
73341 #endif
73342 v_curr_row.ptr[4u] += wuffs_webp__decoder__mode12(self, v_curr_row.ptr[0u], v_prev_row.ptr[4u], v_prev_row.ptr[0u]);
73343 v_curr_row.ptr[5u] += wuffs_webp__decoder__mode12(self, v_curr_row.ptr[1u], v_prev_row.ptr[5u], v_prev_row.ptr[1u]);
73344 v_curr_row.ptr[6u] += wuffs_webp__decoder__mode12(self, v_curr_row.ptr[2u], v_prev_row.ptr[6u], v_prev_row.ptr[2u]);
73345 v_curr_row.ptr[7u] += wuffs_webp__decoder__mode12(self, v_curr_row.ptr[3u], v_prev_row.ptr[7u], v_prev_row.ptr[3u]);
73346 #if defined(__GNUC__)
73347 #pragma GCC diagnostic pop
73348 #endif
73349 } else if (v_mode == 13u) {
73350 #if defined(__GNUC__)
73351 #pragma GCC diagnostic push
73352 #pragma GCC diagnostic ignored "-Wconversion"
73353 #endif
73354 v_curr_row.ptr[4u] += wuffs_webp__decoder__mode13(self, v_curr_row.ptr[0u], v_prev_row.ptr[4u], v_prev_row.ptr[0u]);
73355 v_curr_row.ptr[5u] += wuffs_webp__decoder__mode13(self, v_curr_row.ptr[1u], v_prev_row.ptr[5u], v_prev_row.ptr[1u]);
73356 v_curr_row.ptr[6u] += wuffs_webp__decoder__mode13(self, v_curr_row.ptr[2u], v_prev_row.ptr[6u], v_prev_row.ptr[2u]);
73357 v_curr_row.ptr[7u] += wuffs_webp__decoder__mode13(self, v_curr_row.ptr[3u], v_prev_row.ptr[7u], v_prev_row.ptr[3u]);
73358 #if defined(__GNUC__)
73359 #pragma GCC diagnostic pop
73360 #endif
73362 v_curr_row = wuffs_base__slice_u8__subslice_i(v_curr_row, 4u);
73363 v_prev_row = wuffs_base__slice_u8__subslice_i(v_prev_row, 4u);
73364 v_x += 1u;
73366 v_y += 1u;
73368 return wuffs_base__make_empty_struct();
73371 // -------- func webp.decoder.absolute_difference
73373 WUFFS_BASE__GENERATED_C_CODE
73374 static uint32_t
73375 wuffs_webp__decoder__absolute_difference(
73376 const wuffs_webp__decoder* self,
73377 uint32_t a_a,
73378 uint32_t a_b) {
73379 if (a_a < a_b) {
73380 return (a_b - a_a);
73382 return (a_a - a_b);
73385 // -------- func webp.decoder.mode12
73387 WUFFS_BASE__GENERATED_C_CODE
73388 static uint8_t
73389 wuffs_webp__decoder__mode12(
73390 const wuffs_webp__decoder* self,
73391 uint8_t a_l,
73392 uint8_t a_t,
73393 uint8_t a_tl) {
73394 uint32_t v_v = 0;
73396 v_v = ((uint32_t)((((uint32_t)(a_l)) + ((uint32_t)(a_t))) - ((uint32_t)(a_tl))));
73397 if (v_v < 256u) {
73398 return ((uint8_t)(v_v));
73399 } else if (v_v < 512u) {
73400 return 255u;
73402 return 0u;
73405 // -------- func webp.decoder.mode13
73407 WUFFS_BASE__GENERATED_C_CODE
73408 static uint8_t
73409 wuffs_webp__decoder__mode13(
73410 const wuffs_webp__decoder* self,
73411 uint8_t a_l,
73412 uint8_t a_t,
73413 uint8_t a_tl) {
73414 uint32_t v_x = 0;
73415 uint32_t v_y = 0;
73416 uint32_t v_z = 0;
73417 uint32_t v_v = 0;
73419 v_x = ((((uint32_t)(a_l)) + ((uint32_t)(a_t))) / 2u);
73420 v_y = ((uint32_t)(a_tl));
73421 v_z = ((uint32_t)(v_x - v_y));
73422 v_v = ((uint32_t)(v_x + wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(v_z + (v_z >> 31u))), 1u)));
73423 if (v_v < 256u) {
73424 return ((uint8_t)(v_v));
73425 } else if (v_v < 512u) {
73426 return 255u;
73428 return 0u;
73431 // -------- func webp.decoder.apply_transform_cross_color
73433 WUFFS_BASE__GENERATED_C_CODE
73434 static wuffs_base__empty_struct
73435 wuffs_webp__decoder__apply_transform_cross_color(
73436 wuffs_webp__decoder* self,
73437 wuffs_base__slice_u8 a_pix,
73438 wuffs_base__slice_u8 a_tile_data) {
73439 uint32_t v_tile_size_log2 = 0;
73440 uint32_t v_tiles_per_row = 0;
73441 uint32_t v_mask = 0;
73442 uint32_t v_y = 0;
73443 uint32_t v_x = 0;
73444 uint64_t v_t = 0;
73445 wuffs_base__slice_u8 v_tile_data = {0};
73446 uint32_t v_g2r = 0;
73447 uint32_t v_g2b = 0;
73448 uint32_t v_r2b = 0;
73449 uint8_t v_b = 0;
73450 uint8_t v_g = 0;
73451 uint8_t v_r = 0;
73453 v_tile_size_log2 = ((uint32_t)(self->private_impl.f_transform_tile_size_log2[1u]));
73454 v_tiles_per_row = ((self->private_impl.f_width + ((((uint32_t)(1u)) << v_tile_size_log2) - 1u)) >> v_tile_size_log2);
73455 v_mask = ((((uint32_t)(1u)) << v_tile_size_log2) - 1u);
73456 v_y = 0u;
73457 while (v_y < self->private_impl.f_height) {
73458 v_t = ((uint64_t)((4u * (v_y >> v_tile_size_log2) * v_tiles_per_row)));
73459 v_tile_data = wuffs_base__utility__empty_slice_u8();
73460 if (v_t <= ((uint64_t)(a_tile_data.len))) {
73461 v_tile_data = wuffs_base__slice_u8__subslice_i(a_tile_data, v_t);
73463 v_x = 0u;
73464 while (v_x < self->private_impl.f_width) {
73465 if (((v_x & v_mask) == 0u) && (((uint64_t)(v_tile_data.len)) >= 4u)) {
73466 v_g2r = wuffs_base__utility__sign_extend_convert_u8_u32(v_tile_data.ptr[0u]);
73467 v_g2b = wuffs_base__utility__sign_extend_convert_u8_u32(v_tile_data.ptr[1u]);
73468 v_r2b = wuffs_base__utility__sign_extend_convert_u8_u32(v_tile_data.ptr[2u]);
73469 v_tile_data = wuffs_base__slice_u8__subslice_i(v_tile_data, 4u);
73471 if (((uint64_t)(a_pix.len)) >= 4u) {
73472 v_b = a_pix.ptr[0u];
73473 v_g = a_pix.ptr[1u];
73474 v_r = a_pix.ptr[2u];
73475 #if defined(__GNUC__)
73476 #pragma GCC diagnostic push
73477 #pragma GCC diagnostic ignored "-Wconversion"
73478 #endif
73479 v_r += ((uint8_t)((((uint32_t)(wuffs_base__utility__sign_extend_convert_u8_u32(v_g) * v_g2r)) >> 5u)));
73480 v_b += ((uint8_t)((((uint32_t)(wuffs_base__utility__sign_extend_convert_u8_u32(v_g) * v_g2b)) >> 5u)));
73481 v_b += ((uint8_t)((((uint32_t)(wuffs_base__utility__sign_extend_convert_u8_u32(v_r) * v_r2b)) >> 5u)));
73482 #if defined(__GNUC__)
73483 #pragma GCC diagnostic pop
73484 #endif
73485 a_pix.ptr[0u] = v_b;
73486 a_pix.ptr[2u] = v_r;
73487 a_pix = wuffs_base__slice_u8__subslice_i(a_pix, 4u);
73489 v_x += 1u;
73491 v_y += 1u;
73493 return wuffs_base__make_empty_struct();
73496 // -------- func webp.decoder.apply_transform_subtract_green
73498 WUFFS_BASE__GENERATED_C_CODE
73499 static wuffs_base__empty_struct
73500 wuffs_webp__decoder__apply_transform_subtract_green(
73501 wuffs_webp__decoder* self,
73502 wuffs_base__slice_u8 a_pix) {
73503 wuffs_base__slice_u8 v_p = {0};
73504 uint8_t v_g = 0;
73507 wuffs_base__slice_u8 i_slice_p = a_pix;
73508 v_p.ptr = i_slice_p.ptr;
73509 v_p.len = 4;
73510 const uint8_t* i_end0_p = wuffs_private_impl__ptr_u8_plus_len(v_p.ptr, (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 4) * 4));
73511 while (v_p.ptr < i_end0_p) {
73512 v_g = v_p.ptr[1u];
73513 #if defined(__GNUC__)
73514 #pragma GCC diagnostic push
73515 #pragma GCC diagnostic ignored "-Wconversion"
73516 #endif
73517 v_p.ptr[0u] += v_g;
73518 v_p.ptr[2u] += v_g;
73519 #if defined(__GNUC__)
73520 #pragma GCC diagnostic pop
73521 #endif
73522 v_p.ptr += 4;
73524 v_p.len = 0;
73526 return wuffs_base__make_empty_struct();
73529 // -------- func webp.decoder.apply_transform_color_indexing
73531 WUFFS_BASE__GENERATED_C_CODE
73532 static wuffs_base__empty_struct
73533 wuffs_webp__decoder__apply_transform_color_indexing(
73534 wuffs_webp__decoder* self,
73535 wuffs_base__slice_u8 a_pix) {
73536 uint32_t v_tile_size_log2 = 0;
73537 uint32_t v_bits_per_pixel = 0;
73538 uint32_t v_x_mask = 0;
73539 uint32_t v_s_mask = 0;
73540 uint64_t v_src_index = 0;
73541 uint32_t v_y = 0;
73542 uint64_t v_di = 0;
73543 uint64_t v_dj = 0;
73544 wuffs_base__slice_u8 v_dst = {0};
73545 uint32_t v_x = 0;
73546 uint32_t v_s = 0;
73547 uint32_t v_p = 0;
73548 uint8_t v_p0 = 0;
73549 uint8_t v_p1 = 0;
73550 uint8_t v_p2 = 0;
73551 uint8_t v_p3 = 0;
73553 v_tile_size_log2 = ((uint32_t)(self->private_impl.f_transform_tile_size_log2[3u]));
73554 if (v_tile_size_log2 == 0u) {
73556 wuffs_base__slice_u8 i_slice_dst = a_pix;
73557 v_dst.ptr = i_slice_dst.ptr;
73558 v_dst.len = 4;
73559 const uint8_t* i_end0_dst = wuffs_private_impl__ptr_u8_plus_len(v_dst.ptr, (((i_slice_dst.len - (size_t)(v_dst.ptr - i_slice_dst.ptr)) / 4) * 4));
73560 while (v_dst.ptr < i_end0_dst) {
73561 v_p = (((uint32_t)(v_dst.ptr[1u])) * 4u);
73562 v_p0 = self->private_data.f_palette[(v_p + 0u)];
73563 v_p1 = self->private_data.f_palette[(v_p + 1u)];
73564 v_p2 = self->private_data.f_palette[(v_p + 2u)];
73565 v_p3 = self->private_data.f_palette[(v_p + 3u)];
73566 v_dst.ptr[0u] = v_p0;
73567 v_dst.ptr[1u] = v_p1;
73568 v_dst.ptr[2u] = v_p2;
73569 v_dst.ptr[3u] = v_p3;
73570 v_dst.ptr += 4;
73572 v_dst.len = 0;
73574 return wuffs_base__make_empty_struct();
73576 v_bits_per_pixel = (((uint32_t)(8u)) >> v_tile_size_log2);
73577 v_x_mask = ((((uint32_t)(1u)) << v_tile_size_log2) - 1u);
73578 v_s_mask = ((((uint32_t)(1u)) << v_bits_per_pixel) - 1u);
73579 v_src_index = ((uint64_t)((self->private_impl.f_workbuf_offset_for_color_indexing + 1u)));
73580 v_y = 0u;
73581 while (v_y < self->private_impl.f_height) {
73582 v_di = ((uint64_t)((4u * (v_y + 0u) * self->private_impl.f_width)));
73583 v_dj = ((uint64_t)((4u * (v_y + 1u) * self->private_impl.f_width)));
73584 if ((v_di > v_dj) || (v_dj > ((uint64_t)(a_pix.len)))) {
73585 break;
73587 v_dst = wuffs_base__slice_u8__subslice_ij(a_pix, v_di, v_dj);
73588 v_x = 0u;
73589 while (((uint64_t)(v_dst.len)) >= 4u) {
73590 if (((v_x & v_x_mask) == 0u) && (v_src_index < ((uint64_t)(a_pix.len)))) {
73591 v_s = ((uint32_t)(a_pix.ptr[v_src_index]));
73592 v_src_index += 4u;
73594 v_p = ((v_s & v_s_mask) * 4u);
73595 v_s >>= v_bits_per_pixel;
73596 v_p0 = self->private_data.f_palette[(v_p + 0u)];
73597 v_p1 = self->private_data.f_palette[(v_p + 1u)];
73598 v_p2 = self->private_data.f_palette[(v_p + 2u)];
73599 v_p3 = self->private_data.f_palette[(v_p + 3u)];
73600 v_dst.ptr[0u] = v_p0;
73601 v_dst.ptr[1u] = v_p1;
73602 v_dst.ptr[2u] = v_p2;
73603 v_dst.ptr[3u] = v_p3;
73604 v_dst = wuffs_base__slice_u8__subslice_i(v_dst, 4u);
73605 v_x += 1u;
73607 v_y += 1u;
73609 return wuffs_base__make_empty_struct();
73612 // -------- func webp.decoder.get_quirk
73614 WUFFS_BASE__GENERATED_C_CODE
73615 WUFFS_BASE__MAYBE_STATIC uint64_t
73616 wuffs_webp__decoder__get_quirk(
73617 const wuffs_webp__decoder* self,
73618 uint32_t a_key) {
73619 if (!self) {
73620 return 0;
73622 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
73623 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
73624 return 0;
73627 return 0u;
73630 // -------- func webp.decoder.set_quirk
73632 WUFFS_BASE__GENERATED_C_CODE
73633 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
73634 wuffs_webp__decoder__set_quirk(
73635 wuffs_webp__decoder* self,
73636 uint32_t a_key,
73637 uint64_t a_value) {
73638 if (!self) {
73639 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
73641 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
73642 return wuffs_base__make_status(
73643 (self->private_impl.magic == WUFFS_BASE__DISABLED)
73644 ? wuffs_base__error__disabled_by_previous_error
73645 : wuffs_base__error__initialize_not_called);
73648 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
73651 // -------- func webp.decoder.decode_image_config
73653 WUFFS_BASE__GENERATED_C_CODE
73654 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
73655 wuffs_webp__decoder__decode_image_config(
73656 wuffs_webp__decoder* self,
73657 wuffs_base__image_config* a_dst,
73658 wuffs_base__io_buffer* a_src) {
73659 if (!self) {
73660 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
73662 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
73663 return wuffs_base__make_status(
73664 (self->private_impl.magic == WUFFS_BASE__DISABLED)
73665 ? wuffs_base__error__disabled_by_previous_error
73666 : wuffs_base__error__initialize_not_called);
73668 if (!a_src) {
73669 self->private_impl.magic = WUFFS_BASE__DISABLED;
73670 return wuffs_base__make_status(wuffs_base__error__bad_argument);
73672 if ((self->private_impl.active_coroutine != 0) &&
73673 (self->private_impl.active_coroutine != 1)) {
73674 self->private_impl.magic = WUFFS_BASE__DISABLED;
73675 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
73677 self->private_impl.active_coroutine = 0;
73678 wuffs_base__status status = wuffs_base__make_status(NULL);
73680 wuffs_base__status v_status = wuffs_base__make_status(NULL);
73682 uint32_t coro_susp_point = self->private_impl.p_decode_image_config;
73683 switch (coro_susp_point) {
73684 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
73686 while (true) {
73688 wuffs_base__status t_0 = wuffs_webp__decoder__do_decode_image_config(self, a_dst, a_src);
73689 v_status = t_0;
73691 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
73692 status = wuffs_base__make_status(wuffs_webp__error__truncated_input);
73693 goto exit;
73695 status = v_status;
73696 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
73700 self->private_impl.p_decode_image_config = 0;
73701 goto exit;
73704 goto suspend;
73705 suspend:
73706 self->private_impl.p_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
73707 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
73709 goto exit;
73710 exit:
73711 if (wuffs_base__status__is_error(&status)) {
73712 self->private_impl.magic = WUFFS_BASE__DISABLED;
73714 return status;
73717 // -------- func webp.decoder.do_decode_image_config
73719 WUFFS_BASE__GENERATED_C_CODE
73720 static wuffs_base__status
73721 wuffs_webp__decoder__do_decode_image_config(
73722 wuffs_webp__decoder* self,
73723 wuffs_base__image_config* a_dst,
73724 wuffs_base__io_buffer* a_src) {
73725 wuffs_base__status status = wuffs_base__make_status(NULL);
73727 uint32_t v_c32 = 0;
73728 uint64_t v_r_mark = 0;
73729 wuffs_base__status v_status = wuffs_base__make_status(NULL);
73731 const uint8_t* iop_a_src = NULL;
73732 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
73733 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
73734 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
73735 if (a_src && a_src->data.ptr) {
73736 io0_a_src = a_src->data.ptr;
73737 io1_a_src = io0_a_src + a_src->meta.ri;
73738 iop_a_src = io1_a_src;
73739 io2_a_src = io0_a_src + a_src->meta.wi;
73742 uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config;
73743 switch (coro_susp_point) {
73744 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
73746 if (self->private_impl.f_call_sequence != 0u) {
73747 status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
73748 goto exit;
73751 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
73752 uint32_t t_0;
73753 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
73754 t_0 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
73755 iop_a_src += 4;
73756 } else {
73757 self->private_data.s_do_decode_image_config.scratch = 0;
73758 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
73759 while (true) {
73760 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
73761 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
73762 goto suspend;
73764 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
73765 uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
73766 *scratch <<= 8;
73767 *scratch >>= 8;
73768 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
73769 if (num_bits_0 == 24) {
73770 t_0 = ((uint32_t)(*scratch));
73771 break;
73773 num_bits_0 += 8u;
73774 *scratch |= ((uint64_t)(num_bits_0)) << 56;
73777 v_c32 = t_0;
73779 if (v_c32 != 1179011410u) {
73780 status = wuffs_base__make_status(wuffs_webp__error__bad_header);
73781 goto exit;
73784 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
73785 uint32_t t_1;
73786 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
73787 t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
73788 iop_a_src += 4;
73789 } else {
73790 self->private_data.s_do_decode_image_config.scratch = 0;
73791 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
73792 while (true) {
73793 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
73794 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
73795 goto suspend;
73797 uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch;
73798 uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
73799 *scratch <<= 8;
73800 *scratch >>= 8;
73801 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
73802 if (num_bits_1 == 24) {
73803 t_1 = ((uint32_t)(*scratch));
73804 break;
73806 num_bits_1 += 8u;
73807 *scratch |= ((uint64_t)(num_bits_1)) << 56;
73810 self->private_impl.f_riff_chunk_length = t_1;
73812 if ((self->private_impl.f_riff_chunk_length & 1u) != 0u) {
73813 status = wuffs_base__make_status(wuffs_webp__error__bad_header);
73814 goto exit;
73816 while (true) {
73818 const bool o_0_closed_a_src = a_src->meta.closed;
73819 const uint8_t* o_0_io2_a_src = io2_a_src;
73820 wuffs_private_impl__io_reader__limit(&io2_a_src, iop_a_src,
73821 ((uint64_t)(self->private_impl.f_riff_chunk_length)));
73822 if (a_src) {
73823 size_t n = ((size_t)(io2_a_src - a_src->data.ptr));
73824 a_src->meta.closed = a_src->meta.closed && (a_src->meta.wi <= n);
73825 a_src->meta.wi = n;
73827 v_r_mark = ((uint64_t)(iop_a_src - io0_a_src));
73829 if (a_src) {
73830 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
73832 wuffs_base__status t_2 = wuffs_webp__decoder__do_decode_image_config_limited(self, a_src);
73833 v_status = t_2;
73834 if (a_src) {
73835 iop_a_src = a_src->data.ptr + a_src->meta.ri;
73838 wuffs_private_impl__u32__sat_sub_indirect(&self->private_impl.f_riff_chunk_length, ((uint32_t)(wuffs_private_impl__io__count_since(v_r_mark, ((uint64_t)(iop_a_src - io0_a_src))))));
73839 io2_a_src = o_0_io2_a_src;
73840 if (a_src) {
73841 a_src->meta.closed = o_0_closed_a_src;
73842 a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
73845 if (wuffs_base__status__is_ok(&v_status)) {
73846 break;
73847 } else if ( ! wuffs_base__status__is_suspension(&v_status)) {
73848 status = v_status;
73849 if (wuffs_base__status__is_error(&status)) {
73850 goto exit;
73851 } else if (wuffs_base__status__is_suspension(&status)) {
73852 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
73853 goto exit;
73855 goto ok;
73856 } else if ((v_status.repr == wuffs_base__suspension__short_read) && (self->private_impl.f_riff_chunk_length == 0u)) {
73857 status = wuffs_base__make_status(wuffs_webp__error__short_chunk);
73858 goto exit;
73860 status = v_status;
73861 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
73863 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)));
73864 if (a_dst != NULL) {
73865 wuffs_base__image_config__set(
73866 a_dst,
73867 self->private_impl.f_pixfmt,
73869 self->private_impl.f_width,
73870 self->private_impl.f_height,
73871 self->private_impl.f_frame_config_io_position,
73872 false);
73874 self->private_impl.f_call_sequence = 32u;
73877 self->private_impl.p_do_decode_image_config = 0;
73878 goto exit;
73881 goto suspend;
73882 suspend:
73883 self->private_impl.p_do_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
73885 goto exit;
73886 exit:
73887 if (a_src && a_src->data.ptr) {
73888 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
73891 return status;
73894 // -------- func webp.decoder.do_decode_image_config_limited
73896 WUFFS_BASE__GENERATED_C_CODE
73897 static wuffs_base__status
73898 wuffs_webp__decoder__do_decode_image_config_limited(
73899 wuffs_webp__decoder* self,
73900 wuffs_base__io_buffer* a_src) {
73901 wuffs_base__status status = wuffs_base__make_status(NULL);
73903 uint32_t v_c32 = 0;
73904 uint64_t v_r_mark = 0;
73905 wuffs_base__status v_status = wuffs_base__make_status(NULL);
73907 const uint8_t* iop_a_src = NULL;
73908 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
73909 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
73910 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
73911 if (a_src && a_src->data.ptr) {
73912 io0_a_src = a_src->data.ptr;
73913 io1_a_src = io0_a_src + a_src->meta.ri;
73914 iop_a_src = io1_a_src;
73915 io2_a_src = io0_a_src + a_src->meta.wi;
73918 uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config_limited;
73919 switch (coro_susp_point) {
73920 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
73923 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
73924 uint32_t t_0;
73925 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
73926 t_0 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
73927 iop_a_src += 4;
73928 } else {
73929 self->private_data.s_do_decode_image_config_limited.scratch = 0;
73930 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
73931 while (true) {
73932 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
73933 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
73934 goto suspend;
73936 uint64_t* scratch = &self->private_data.s_do_decode_image_config_limited.scratch;
73937 uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
73938 *scratch <<= 8;
73939 *scratch >>= 8;
73940 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
73941 if (num_bits_0 == 24) {
73942 t_0 = ((uint32_t)(*scratch));
73943 break;
73945 num_bits_0 += 8u;
73946 *scratch |= ((uint64_t)(num_bits_0)) << 56;
73949 v_c32 = t_0;
73951 if (v_c32 != 1346520407u) {
73952 status = wuffs_base__make_status(wuffs_webp__error__bad_header);
73953 goto exit;
73956 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
73957 uint32_t t_1;
73958 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
73959 t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
73960 iop_a_src += 4;
73961 } else {
73962 self->private_data.s_do_decode_image_config_limited.scratch = 0;
73963 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
73964 while (true) {
73965 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
73966 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
73967 goto suspend;
73969 uint64_t* scratch = &self->private_data.s_do_decode_image_config_limited.scratch;
73970 uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
73971 *scratch <<= 8;
73972 *scratch >>= 8;
73973 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
73974 if (num_bits_1 == 24) {
73975 t_1 = ((uint32_t)(*scratch));
73976 break;
73978 num_bits_1 += 8u;
73979 *scratch |= ((uint64_t)(num_bits_1)) << 56;
73982 v_c32 = t_1;
73984 if (v_c32 == 540561494u) {
73985 status = wuffs_base__make_status(wuffs_webp__error__unsupported_webp_file);
73986 goto exit;
73987 } else if (v_c32 == 1278758998u) {
73989 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
73990 uint32_t t_2;
73991 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
73992 t_2 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
73993 iop_a_src += 4;
73994 } else {
73995 self->private_data.s_do_decode_image_config_limited.scratch = 0;
73996 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
73997 while (true) {
73998 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
73999 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
74000 goto suspend;
74002 uint64_t* scratch = &self->private_data.s_do_decode_image_config_limited.scratch;
74003 uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
74004 *scratch <<= 8;
74005 *scratch >>= 8;
74006 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
74007 if (num_bits_2 == 24) {
74008 t_2 = ((uint32_t)(*scratch));
74009 break;
74011 num_bits_2 += 8u;
74012 *scratch |= ((uint64_t)(num_bits_2)) << 56;
74015 self->private_impl.f_sub_chunk_length = t_2;
74017 if (self->private_impl.f_sub_chunk_length < 4u) {
74018 status = wuffs_base__make_status(wuffs_webp__error__bad_header);
74019 goto exit;
74021 self->private_impl.f_sub_chunk_has_padding = ((self->private_impl.f_sub_chunk_length & 1u) != 0u);
74022 while (true) {
74024 const bool o_0_closed_a_src = a_src->meta.closed;
74025 const uint8_t* o_0_io2_a_src = io2_a_src;
74026 wuffs_private_impl__io_reader__limit(&io2_a_src, iop_a_src,
74027 ((uint64_t)(self->private_impl.f_sub_chunk_length)));
74028 if (a_src) {
74029 size_t n = ((size_t)(io2_a_src - a_src->data.ptr));
74030 a_src->meta.closed = a_src->meta.closed && (a_src->meta.wi <= n);
74031 a_src->meta.wi = n;
74033 v_r_mark = ((uint64_t)(iop_a_src - io0_a_src));
74035 if (a_src) {
74036 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
74038 wuffs_base__status t_3 = wuffs_webp__decoder__do_decode_image_config_limited_vp8l(self, a_src);
74039 v_status = t_3;
74040 if (a_src) {
74041 iop_a_src = a_src->data.ptr + a_src->meta.ri;
74044 wuffs_private_impl__u32__sat_sub_indirect(&self->private_impl.f_sub_chunk_length, ((uint32_t)(wuffs_private_impl__io__count_since(v_r_mark, ((uint64_t)(iop_a_src - io0_a_src))))));
74045 io2_a_src = o_0_io2_a_src;
74046 if (a_src) {
74047 a_src->meta.closed = o_0_closed_a_src;
74048 a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
74051 if (wuffs_base__status__is_ok(&v_status)) {
74052 break;
74053 } else if ( ! wuffs_base__status__is_suspension(&v_status)) {
74054 status = v_status;
74055 if (wuffs_base__status__is_error(&status)) {
74056 goto exit;
74057 } else if (wuffs_base__status__is_suspension(&status)) {
74058 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
74059 goto exit;
74061 goto ok;
74062 } else if ((v_status.repr == wuffs_base__suspension__short_read) && (self->private_impl.f_sub_chunk_length == 0u)) {
74063 status = wuffs_base__make_status(wuffs_webp__error__short_chunk);
74064 goto exit;
74066 status = v_status;
74067 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7);
74069 } else if (v_c32 == 1480085590u) {
74070 status = wuffs_base__make_status(wuffs_webp__error__unsupported_webp_file);
74071 goto exit;
74072 } else {
74073 status = wuffs_base__make_status(wuffs_webp__error__bad_header);
74074 goto exit;
74078 self->private_impl.p_do_decode_image_config_limited = 0;
74079 goto exit;
74082 goto suspend;
74083 suspend:
74084 self->private_impl.p_do_decode_image_config_limited = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
74086 goto exit;
74087 exit:
74088 if (a_src && a_src->data.ptr) {
74089 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
74092 return status;
74095 // -------- func webp.decoder.do_decode_image_config_limited_vp8l
74097 WUFFS_BASE__GENERATED_C_CODE
74098 static wuffs_base__status
74099 wuffs_webp__decoder__do_decode_image_config_limited_vp8l(
74100 wuffs_webp__decoder* self,
74101 wuffs_base__io_buffer* a_src) {
74102 wuffs_base__status status = wuffs_base__make_status(NULL);
74104 uint32_t v_c32 = 0;
74105 uint32_t v_transform_size = 0;
74107 const uint8_t* iop_a_src = NULL;
74108 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
74109 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
74110 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
74111 if (a_src && a_src->data.ptr) {
74112 io0_a_src = a_src->data.ptr;
74113 io1_a_src = io0_a_src + a_src->meta.ri;
74114 iop_a_src = io1_a_src;
74115 io2_a_src = io0_a_src + a_src->meta.wi;
74118 uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config_limited_vp8l;
74119 switch (coro_susp_point) {
74120 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
74123 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
74124 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
74125 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
74126 goto suspend;
74128 uint32_t t_0 = *iop_a_src++;
74129 v_c32 = t_0;
74131 if (v_c32 != 47u) {
74132 status = wuffs_base__make_status(wuffs_webp__error__bad_header);
74133 goto exit;
74136 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
74137 uint32_t t_1;
74138 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
74139 t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
74140 iop_a_src += 4;
74141 } else {
74142 self->private_data.s_do_decode_image_config_limited_vp8l.scratch = 0;
74143 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
74144 while (true) {
74145 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
74146 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
74147 goto suspend;
74149 uint64_t* scratch = &self->private_data.s_do_decode_image_config_limited_vp8l.scratch;
74150 uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
74151 *scratch <<= 8;
74152 *scratch >>= 8;
74153 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
74154 if (num_bits_1 == 24) {
74155 t_1 = ((uint32_t)(*scratch));
74156 break;
74158 num_bits_1 += 8u;
74159 *scratch |= ((uint64_t)(num_bits_1)) << 56;
74162 v_c32 = t_1;
74164 self->private_impl.f_width = ((v_c32 & 16383u) + 1u);
74165 v_c32 >>= 14u;
74166 self->private_impl.f_height = ((v_c32 & 16383u) + 1u);
74167 v_c32 >>= 14u;
74168 self->private_impl.f_pixfmt = 2415954056u;
74169 if ((v_c32 & 1u) != 0u) {
74170 self->private_impl.f_pixfmt = 2164295816u;
74172 v_c32 >>= 1u;
74173 if (v_c32 != 0u) {
74174 status = wuffs_base__make_status(wuffs_webp__error__bad_header);
74175 goto exit;
74177 v_transform_size = (4u * ((self->private_impl.f_width + 3u) >> 2u) * ((self->private_impl.f_height + 3u) >> 2u));
74178 self->private_impl.f_workbuf_offset_for_transform[0u] = ((4u * self->private_impl.f_width * self->private_impl.f_height) + (0u * v_transform_size));
74179 self->private_impl.f_workbuf_offset_for_transform[1u] = ((4u * self->private_impl.f_width * self->private_impl.f_height) + (1u * v_transform_size));
74180 self->private_impl.f_workbuf_offset_for_transform[2u] = ((4u * self->private_impl.f_width * self->private_impl.f_height) + (2u * v_transform_size));
74181 self->private_impl.f_workbuf_offset_for_transform[3u] = ((4u * self->private_impl.f_width * self->private_impl.f_height) + (3u * v_transform_size));
74183 goto ok;
74185 self->private_impl.p_do_decode_image_config_limited_vp8l = 0;
74186 goto exit;
74189 goto suspend;
74190 suspend:
74191 self->private_impl.p_do_decode_image_config_limited_vp8l = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
74193 goto exit;
74194 exit:
74195 if (a_src && a_src->data.ptr) {
74196 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
74199 return status;
74202 // -------- func webp.decoder.decode_frame_config
74204 WUFFS_BASE__GENERATED_C_CODE
74205 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
74206 wuffs_webp__decoder__decode_frame_config(
74207 wuffs_webp__decoder* self,
74208 wuffs_base__frame_config* a_dst,
74209 wuffs_base__io_buffer* a_src) {
74210 if (!self) {
74211 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
74213 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
74214 return wuffs_base__make_status(
74215 (self->private_impl.magic == WUFFS_BASE__DISABLED)
74216 ? wuffs_base__error__disabled_by_previous_error
74217 : wuffs_base__error__initialize_not_called);
74219 if (!a_src) {
74220 self->private_impl.magic = WUFFS_BASE__DISABLED;
74221 return wuffs_base__make_status(wuffs_base__error__bad_argument);
74223 if ((self->private_impl.active_coroutine != 0) &&
74224 (self->private_impl.active_coroutine != 2)) {
74225 self->private_impl.magic = WUFFS_BASE__DISABLED;
74226 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
74228 self->private_impl.active_coroutine = 0;
74229 wuffs_base__status status = wuffs_base__make_status(NULL);
74231 wuffs_base__status v_status = wuffs_base__make_status(NULL);
74233 uint32_t coro_susp_point = self->private_impl.p_decode_frame_config;
74234 switch (coro_susp_point) {
74235 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
74237 while (true) {
74239 wuffs_base__status t_0 = wuffs_webp__decoder__do_decode_frame_config(self, a_dst, a_src);
74240 v_status = t_0;
74242 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
74243 status = wuffs_base__make_status(wuffs_webp__error__truncated_input);
74244 goto exit;
74246 status = v_status;
74247 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
74251 self->private_impl.p_decode_frame_config = 0;
74252 goto exit;
74255 goto suspend;
74256 suspend:
74257 self->private_impl.p_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
74258 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
74260 goto exit;
74261 exit:
74262 if (wuffs_base__status__is_error(&status)) {
74263 self->private_impl.magic = WUFFS_BASE__DISABLED;
74265 return status;
74268 // -------- func webp.decoder.do_decode_frame_config
74270 WUFFS_BASE__GENERATED_C_CODE
74271 static wuffs_base__status
74272 wuffs_webp__decoder__do_decode_frame_config(
74273 wuffs_webp__decoder* self,
74274 wuffs_base__frame_config* a_dst,
74275 wuffs_base__io_buffer* a_src) {
74276 wuffs_base__status status = wuffs_base__make_status(NULL);
74278 const uint8_t* iop_a_src = NULL;
74279 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
74280 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
74281 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
74282 if (a_src && a_src->data.ptr) {
74283 io0_a_src = a_src->data.ptr;
74284 io1_a_src = io0_a_src + a_src->meta.ri;
74285 iop_a_src = io1_a_src;
74286 io2_a_src = io0_a_src + a_src->meta.wi;
74289 uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config;
74290 switch (coro_susp_point) {
74291 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
74293 if (self->private_impl.f_call_sequence == 32u) {
74294 } else if (self->private_impl.f_call_sequence < 32u) {
74295 if (a_src) {
74296 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
74298 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
74299 status = wuffs_webp__decoder__do_decode_image_config(self, NULL, a_src);
74300 if (a_src) {
74301 iop_a_src = a_src->data.ptr + a_src->meta.ri;
74303 if (status.repr) {
74304 goto suspend;
74306 } else if (self->private_impl.f_call_sequence == 40u) {
74307 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)))) {
74308 status = wuffs_base__make_status(wuffs_base__error__bad_restart);
74309 goto exit;
74311 } else if (self->private_impl.f_call_sequence == 64u) {
74312 self->private_impl.f_call_sequence = 96u;
74313 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
74314 goto ok;
74315 } else {
74316 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
74317 goto ok;
74319 if (a_dst != NULL) {
74320 wuffs_base__frame_config__set(
74321 a_dst,
74322 wuffs_base__utility__make_rect_ie_u32(
74325 self->private_impl.f_width,
74326 self->private_impl.f_height),
74327 ((wuffs_base__flicks)(0u)),
74329 self->private_impl.f_frame_config_io_position,
74331 false,
74332 false,
74333 0u);
74335 self->private_impl.f_call_sequence = 64u;
74338 self->private_impl.p_do_decode_frame_config = 0;
74339 goto exit;
74342 goto suspend;
74343 suspend:
74344 self->private_impl.p_do_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
74346 goto exit;
74347 exit:
74348 if (a_src && a_src->data.ptr) {
74349 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
74352 return status;
74355 // -------- func webp.decoder.decode_frame
74357 WUFFS_BASE__GENERATED_C_CODE
74358 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
74359 wuffs_webp__decoder__decode_frame(
74360 wuffs_webp__decoder* self,
74361 wuffs_base__pixel_buffer* a_dst,
74362 wuffs_base__io_buffer* a_src,
74363 wuffs_base__pixel_blend a_blend,
74364 wuffs_base__slice_u8 a_workbuf,
74365 wuffs_base__decode_frame_options* a_opts) {
74366 if (!self) {
74367 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
74369 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
74370 return wuffs_base__make_status(
74371 (self->private_impl.magic == WUFFS_BASE__DISABLED)
74372 ? wuffs_base__error__disabled_by_previous_error
74373 : wuffs_base__error__initialize_not_called);
74375 if (!a_dst || !a_src) {
74376 self->private_impl.magic = WUFFS_BASE__DISABLED;
74377 return wuffs_base__make_status(wuffs_base__error__bad_argument);
74379 if ((self->private_impl.active_coroutine != 0) &&
74380 (self->private_impl.active_coroutine != 3)) {
74381 self->private_impl.magic = WUFFS_BASE__DISABLED;
74382 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
74384 self->private_impl.active_coroutine = 0;
74385 wuffs_base__status status = wuffs_base__make_status(NULL);
74387 wuffs_base__status v_status = wuffs_base__make_status(NULL);
74389 uint32_t coro_susp_point = self->private_impl.p_decode_frame;
74390 switch (coro_susp_point) {
74391 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
74393 while (true) {
74395 wuffs_base__status t_0 = wuffs_webp__decoder__do_decode_frame(self,
74396 a_dst,
74397 a_src,
74398 a_blend,
74399 a_workbuf,
74400 a_opts);
74401 v_status = t_0;
74403 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
74404 status = wuffs_base__make_status(wuffs_webp__error__truncated_input);
74405 goto exit;
74407 status = v_status;
74408 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
74412 self->private_impl.p_decode_frame = 0;
74413 goto exit;
74416 goto suspend;
74417 suspend:
74418 self->private_impl.p_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
74419 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
74421 goto exit;
74422 exit:
74423 if (wuffs_base__status__is_error(&status)) {
74424 self->private_impl.magic = WUFFS_BASE__DISABLED;
74426 return status;
74429 // -------- func webp.decoder.do_decode_frame
74431 WUFFS_BASE__GENERATED_C_CODE
74432 static wuffs_base__status
74433 wuffs_webp__decoder__do_decode_frame(
74434 wuffs_webp__decoder* self,
74435 wuffs_base__pixel_buffer* a_dst,
74436 wuffs_base__io_buffer* a_src,
74437 wuffs_base__pixel_blend a_blend,
74438 wuffs_base__slice_u8 a_workbuf,
74439 wuffs_base__decode_frame_options* a_opts) {
74440 wuffs_base__status status = wuffs_base__make_status(NULL);
74442 uint8_t v_c8 = 0;
74443 uint32_t v_has_more = 0;
74444 uint32_t v_width = 0;
74445 wuffs_base__slice_u8 v_dst = {0};
74446 wuffs_base__slice_u8 v_tile_data = {0};
74447 wuffs_base__status v_status = wuffs_base__make_status(NULL);
74448 wuffs_base__slice_u8 v_pix = {0};
74449 uint32_t v_which = 0;
74450 uint32_t v_transform_type = 0;
74451 uint64_t v_ti = 0;
74452 uint64_t v_tj = 0;
74454 const uint8_t* iop_a_src = NULL;
74455 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
74456 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
74457 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
74458 if (a_src && a_src->data.ptr) {
74459 io0_a_src = a_src->data.ptr;
74460 io1_a_src = io0_a_src + a_src->meta.ri;
74461 iop_a_src = io1_a_src;
74462 io2_a_src = io0_a_src + a_src->meta.wi;
74465 uint32_t coro_susp_point = self->private_impl.p_do_decode_frame;
74466 if (coro_susp_point) {
74467 v_width = self->private_data.s_do_decode_frame.v_width;
74469 switch (coro_susp_point) {
74470 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
74472 if (self->private_impl.f_call_sequence == 64u) {
74473 } else if (self->private_impl.f_call_sequence < 64u) {
74474 if (a_src) {
74475 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
74477 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
74478 status = wuffs_webp__decoder__do_decode_frame_config(self, NULL, a_src);
74479 if (a_src) {
74480 iop_a_src = a_src->data.ptr + a_src->meta.ri;
74482 if (status.repr) {
74483 goto suspend;
74485 } else {
74486 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
74487 goto ok;
74489 self->private_impl.f_seen_transform[0u] = false;
74490 self->private_impl.f_seen_transform[1u] = false;
74491 self->private_impl.f_seen_transform[2u] = false;
74492 self->private_impl.f_seen_transform[3u] = false;
74493 self->private_impl.f_n_transforms = 0u;
74494 while (true) {
74495 if (self->private_impl.f_n_bits < 1u) {
74497 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
74498 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
74499 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
74500 goto suspend;
74502 uint8_t t_0 = *iop_a_src++;
74503 v_c8 = t_0;
74505 self->private_impl.f_bits = ((uint32_t)(v_c8));
74506 self->private_impl.f_n_bits = 8u;
74508 v_has_more = (self->private_impl.f_bits & 1u);
74509 self->private_impl.f_bits >>= 1u;
74510 self->private_impl.f_n_bits -= 1u;
74511 if (v_has_more == 0u) {
74512 break;
74514 if (a_src) {
74515 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
74517 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
74518 status = wuffs_webp__decoder__decode_transform(self, a_src, a_workbuf);
74519 if (a_src) {
74520 iop_a_src = a_src->data.ptr + a_src->meta.ri;
74522 if (status.repr) {
74523 goto suspend;
74526 v_width = self->private_impl.f_width;
74527 if (self->private_impl.f_seen_transform[3u]) {
74528 v_width = self->private_impl.f_color_indexing_width;
74530 if (a_src) {
74531 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
74533 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
74534 status = wuffs_webp__decoder__decode_color_cache_parameters(self, a_src);
74535 if (a_src) {
74536 iop_a_src = a_src->data.ptr + a_src->meta.ri;
74538 if (status.repr) {
74539 goto suspend;
74541 self->private_impl.f_overall_color_cache_bits = self->private_impl.f_color_cache_bits;
74542 if (a_src) {
74543 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
74545 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
74546 status = wuffs_webp__decoder__decode_hg_table(self, a_src, v_width, a_workbuf);
74547 if (a_src) {
74548 iop_a_src = a_src->data.ptr + a_src->meta.ri;
74550 if (status.repr) {
74551 goto suspend;
74553 self->private_impl.f_color_cache_bits = self->private_impl.f_overall_color_cache_bits;
74554 if (a_src) {
74555 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
74557 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
74558 status = wuffs_webp__decoder__decode_huffman_groups(self, a_src, self->private_impl.f_overall_n_huffman_groups);
74559 if (a_src) {
74560 iop_a_src = a_src->data.ptr + a_src->meta.ri;
74562 if (status.repr) {
74563 goto suspend;
74565 while (true) {
74566 if ((((uint64_t)(self->private_impl.f_workbuf_offset_for_color_indexing)) > ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[0u]))) ||
74567 (((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[0u])) > ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[1u]))) ||
74568 (((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[1u])) > ((uint64_t)(a_workbuf.len))) ||
74569 (((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[0u])) > ((uint64_t)(a_workbuf.len)))) {
74570 status = wuffs_base__make_status(wuffs_base__error__bad_workbuf_length);
74571 goto exit;
74573 v_dst = wuffs_base__slice_u8__subslice_ij(a_workbuf,
74574 ((uint64_t)(self->private_impl.f_workbuf_offset_for_color_indexing)),
74575 ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[0u])));
74576 v_tile_data = wuffs_base__slice_u8__subslice_ij(a_workbuf,
74577 ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[0u])),
74578 ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[1u])));
74580 if (a_src) {
74581 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
74583 wuffs_base__status t_1 = wuffs_webp__decoder__decode_pixels(self,
74584 v_dst,
74585 a_src,
74586 v_width,
74587 self->private_impl.f_height,
74588 v_tile_data,
74589 self->private_impl.f_overall_tile_size_log2);
74590 v_status = t_1;
74591 if (a_src) {
74592 iop_a_src = a_src->data.ptr + a_src->meta.ri;
74595 if (wuffs_base__status__is_ok(&v_status)) {
74596 break;
74598 status = v_status;
74599 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7);
74601 if (((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[0u])) > ((uint64_t)(a_workbuf.len))) {
74602 status = wuffs_base__make_status(wuffs_base__error__bad_workbuf_length);
74603 goto exit;
74605 v_pix = wuffs_base__slice_u8__subslice_j(a_workbuf, ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[0u])));
74606 v_which = self->private_impl.f_n_transforms;
74607 while (v_which > 0u) {
74608 v_which -= 1u;
74609 v_transform_type = ((uint32_t)(self->private_impl.f_transform_type[v_which]));
74610 v_tile_data = wuffs_base__utility__empty_slice_u8();
74611 if (v_transform_type < 2u) {
74612 v_ti = ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[(v_transform_type + 1u)]));
74613 v_tj = ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[(v_transform_type + 2u)]));
74614 if ((v_ti <= v_tj) && (v_tj <= ((uint64_t)(a_workbuf.len)))) {
74615 v_tile_data = wuffs_base__slice_u8__subslice_ij(a_workbuf, v_ti, v_tj);
74618 if (v_transform_type == 0u) {
74619 wuffs_webp__decoder__apply_transform_predictor(self, v_pix, v_tile_data);
74620 } else if (v_transform_type == 1u) {
74621 wuffs_webp__decoder__apply_transform_cross_color(self, v_pix, v_tile_data);
74622 } else if (v_transform_type == 2u) {
74623 wuffs_webp__decoder__apply_transform_subtract_green(self, v_pix);
74624 } else {
74625 wuffs_webp__decoder__apply_transform_color_indexing(self, v_pix);
74626 v_width = self->private_impl.f_width;
74629 v_status = wuffs_webp__decoder__swizzle(self, a_dst, v_pix, a_blend);
74630 if ( ! wuffs_base__status__is_ok(&v_status)) {
74631 status = v_status;
74632 if (wuffs_base__status__is_error(&status)) {
74633 goto exit;
74634 } else if (wuffs_base__status__is_suspension(&status)) {
74635 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
74636 goto exit;
74638 goto ok;
74640 self->private_impl.f_call_sequence = 96u;
74643 self->private_impl.p_do_decode_frame = 0;
74644 goto exit;
74647 goto suspend;
74648 suspend:
74649 self->private_impl.p_do_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
74650 self->private_data.s_do_decode_frame.v_width = v_width;
74652 goto exit;
74653 exit:
74654 if (a_src && a_src->data.ptr) {
74655 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
74658 return status;
74661 // -------- func webp.decoder.decode_transform
74663 WUFFS_BASE__GENERATED_C_CODE
74664 static wuffs_base__status
74665 wuffs_webp__decoder__decode_transform(
74666 wuffs_webp__decoder* self,
74667 wuffs_base__io_buffer* a_src,
74668 wuffs_base__slice_u8 a_workbuf) {
74669 wuffs_base__status status = wuffs_base__make_status(NULL);
74671 wuffs_base__status v_status = wuffs_base__make_status(NULL);
74672 uint8_t v_c8 = 0;
74673 uint32_t v_transform_type = 0;
74674 uint32_t v_tile_size_log2 = 0;
74675 wuffs_base__slice_u8 v_p = {0};
74677 const uint8_t* iop_a_src = NULL;
74678 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
74679 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
74680 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
74681 if (a_src && a_src->data.ptr) {
74682 io0_a_src = a_src->data.ptr;
74683 io1_a_src = io0_a_src + a_src->meta.ri;
74684 iop_a_src = io1_a_src;
74685 io2_a_src = io0_a_src + a_src->meta.wi;
74688 uint32_t coro_susp_point = self->private_impl.p_decode_transform;
74689 if (coro_susp_point) {
74690 v_transform_type = self->private_data.s_decode_transform.v_transform_type;
74691 v_tile_size_log2 = self->private_data.s_decode_transform.v_tile_size_log2;
74693 switch (coro_susp_point) {
74694 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
74696 if (self->private_impl.f_n_bits < 2u) {
74698 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
74699 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
74700 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
74701 goto suspend;
74703 uint8_t t_0 = *iop_a_src++;
74704 v_c8 = t_0;
74706 if (self->private_impl.f_n_bits >= 2u) {
74707 status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_n_bits);
74708 goto exit;
74710 self->private_impl.f_bits |= (((uint32_t)(v_c8)) << self->private_impl.f_n_bits);
74711 self->private_impl.f_n_bits += 8u;
74713 v_transform_type = (self->private_impl.f_bits & 3u);
74714 self->private_impl.f_bits >>= 2u;
74715 self->private_impl.f_n_bits -= 2u;
74716 if (self->private_impl.f_seen_transform[v_transform_type] || (self->private_impl.f_n_transforms >= 4u)) {
74717 status = wuffs_base__make_status(wuffs_webp__error__bad_transform);
74718 goto exit;
74719 } else if (self->private_impl.f_seen_transform[3u]) {
74720 status = wuffs_base__make_status(wuffs_webp__error__unsupported_transform_after_color_indexing_transform);
74721 goto exit;
74723 self->private_impl.f_seen_transform[v_transform_type] = true;
74724 self->private_impl.f_transform_type[self->private_impl.f_n_transforms] = ((uint8_t)(v_transform_type));
74725 self->private_impl.f_n_transforms += 1u;
74726 if (v_transform_type < 2u) {
74727 if (self->private_impl.f_n_bits < 3u) {
74729 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
74730 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
74731 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
74732 goto suspend;
74734 uint8_t t_1 = *iop_a_src++;
74735 v_c8 = t_1;
74737 if (self->private_impl.f_n_bits >= 3u) {
74738 status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_n_bits);
74739 goto exit;
74741 self->private_impl.f_bits |= (((uint32_t)(v_c8)) << self->private_impl.f_n_bits);
74742 self->private_impl.f_n_bits += 8u;
74744 v_tile_size_log2 = ((self->private_impl.f_bits & 7u) + 2u);
74745 self->private_impl.f_transform_tile_size_log2[v_transform_type] = ((uint8_t)(v_tile_size_log2));
74746 self->private_impl.f_bits >>= 3u;
74747 self->private_impl.f_n_bits -= 3u;
74748 if (a_src) {
74749 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
74751 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
74752 status = wuffs_webp__decoder__decode_color_cache_parameters(self, a_src);
74753 if (a_src) {
74754 iop_a_src = a_src->data.ptr + a_src->meta.ri;
74756 if (status.repr) {
74757 goto suspend;
74759 if (a_src) {
74760 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
74762 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
74763 status = wuffs_webp__decoder__decode_huffman_groups(self, a_src, 1u);
74764 if (a_src) {
74765 iop_a_src = a_src->data.ptr + a_src->meta.ri;
74767 if (status.repr) {
74768 goto suspend;
74770 while (true) {
74771 if ((((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[(v_transform_type + 1u)])) > ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[(v_transform_type + 2u)]))) || (((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[(v_transform_type + 2u)])) > ((uint64_t)(a_workbuf.len)))) {
74772 status = wuffs_base__make_status(wuffs_base__error__bad_workbuf_length);
74773 goto exit;
74776 if (a_src) {
74777 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
74779 wuffs_base__status t_2 = wuffs_webp__decoder__decode_pixels(self,
74780 wuffs_base__slice_u8__subslice_ij(a_workbuf,
74781 ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[(v_transform_type + 1u)])),
74782 ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[(v_transform_type + 2u)]))),
74783 a_src,
74784 ((self->private_impl.f_width + ((((uint32_t)(1u)) << v_tile_size_log2) - 1u)) >> v_tile_size_log2),
74785 ((self->private_impl.f_height + ((((uint32_t)(1u)) << v_tile_size_log2) - 1u)) >> v_tile_size_log2),
74786 wuffs_base__utility__empty_slice_u8(),
74787 0u);
74788 v_status = t_2;
74789 if (a_src) {
74790 iop_a_src = a_src->data.ptr + a_src->meta.ri;
74793 if (wuffs_base__status__is_ok(&v_status)) {
74794 break;
74796 status = v_status;
74797 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
74799 } else if (v_transform_type == 2u) {
74800 } else {
74801 if (self->private_impl.f_n_bits < 8u) {
74803 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
74804 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
74805 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
74806 goto suspend;
74808 uint8_t t_3 = *iop_a_src++;
74809 v_c8 = t_3;
74811 if (self->private_impl.f_n_bits >= 8u) {
74812 status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_n_bits);
74813 goto exit;
74815 self->private_impl.f_bits |= (((uint32_t)(v_c8)) << self->private_impl.f_n_bits);
74816 self->private_impl.f_n_bits += 8u;
74818 self->private_impl.f_color_indexing_palette_size = ((self->private_impl.f_bits & 255u) + 1u);
74819 self->private_impl.f_bits >>= 8u;
74820 self->private_impl.f_n_bits -= 8u;
74821 if (self->private_impl.f_color_indexing_palette_size <= 2u) {
74822 self->private_impl.f_color_indexing_width = ((self->private_impl.f_width + 7u) / 8u);
74823 self->private_impl.f_transform_tile_size_log2[3u] = 3u;
74824 } else if (self->private_impl.f_color_indexing_palette_size <= 4u) {
74825 self->private_impl.f_color_indexing_width = ((self->private_impl.f_width + 3u) / 4u);
74826 self->private_impl.f_transform_tile_size_log2[3u] = 2u;
74827 } else if (self->private_impl.f_color_indexing_palette_size <= 16u) {
74828 self->private_impl.f_color_indexing_width = ((self->private_impl.f_width + 1u) / 2u);
74829 self->private_impl.f_transform_tile_size_log2[3u] = 1u;
74830 } else {
74831 self->private_impl.f_color_indexing_width = self->private_impl.f_width;
74832 self->private_impl.f_transform_tile_size_log2[3u] = 0u;
74834 if (self->private_impl.f_width >= self->private_impl.f_color_indexing_width) {
74835 self->private_impl.f_workbuf_offset_for_color_indexing = (4u * (self->private_impl.f_width - self->private_impl.f_color_indexing_width) * self->private_impl.f_height);
74837 if (a_src) {
74838 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
74840 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
74841 status = wuffs_webp__decoder__decode_color_cache_parameters(self, a_src);
74842 if (a_src) {
74843 iop_a_src = a_src->data.ptr + a_src->meta.ri;
74845 if (status.repr) {
74846 goto suspend;
74848 if (a_src) {
74849 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
74851 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
74852 status = wuffs_webp__decoder__decode_huffman_groups(self, a_src, 1u);
74853 if (a_src) {
74854 iop_a_src = a_src->data.ptr + a_src->meta.ri;
74856 if (status.repr) {
74857 goto suspend;
74859 if (a_src) {
74860 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
74862 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
74863 status = wuffs_webp__decoder__decode_pixels(self,
74864 wuffs_base__make_slice_u8(self->private_data.f_palette, (4u * self->private_impl.f_color_indexing_palette_size)),
74865 a_src,
74866 self->private_impl.f_color_indexing_palette_size,
74868 wuffs_base__utility__empty_slice_u8(),
74869 0u);
74870 if (a_src) {
74871 iop_a_src = a_src->data.ptr + a_src->meta.ri;
74873 if (status.repr) {
74874 goto suspend;
74876 wuffs_private_impl__bulk_memset(&self->private_data.f_palette[(4u * self->private_impl.f_color_indexing_palette_size)], (1024u - (4u * self->private_impl.f_color_indexing_palette_size)), 0u);
74877 v_p = wuffs_base__make_slice_u8(self->private_data.f_palette, (4u * self->private_impl.f_color_indexing_palette_size));
74878 while (((uint64_t)(v_p.len)) >= 8u) {
74879 #if defined(__GNUC__)
74880 #pragma GCC diagnostic push
74881 #pragma GCC diagnostic ignored "-Wconversion"
74882 #endif
74883 v_p.ptr[4u] += v_p.ptr[0u];
74884 v_p.ptr[5u] += v_p.ptr[1u];
74885 v_p.ptr[6u] += v_p.ptr[2u];
74886 v_p.ptr[7u] += v_p.ptr[3u];
74887 #if defined(__GNUC__)
74888 #pragma GCC diagnostic pop
74889 #endif
74890 v_p = wuffs_base__slice_u8__subslice_i(v_p, 4u);
74895 self->private_impl.p_decode_transform = 0;
74896 goto exit;
74899 goto suspend;
74900 suspend:
74901 self->private_impl.p_decode_transform = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
74902 self->private_data.s_decode_transform.v_transform_type = v_transform_type;
74903 self->private_data.s_decode_transform.v_tile_size_log2 = v_tile_size_log2;
74905 goto exit;
74906 exit:
74907 if (a_src && a_src->data.ptr) {
74908 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
74911 return status;
74914 // -------- func webp.decoder.decode_color_cache_parameters
74916 WUFFS_BASE__GENERATED_C_CODE
74917 static wuffs_base__status
74918 wuffs_webp__decoder__decode_color_cache_parameters(
74919 wuffs_webp__decoder* self,
74920 wuffs_base__io_buffer* a_src) {
74921 wuffs_base__status status = wuffs_base__make_status(NULL);
74923 uint8_t v_c8 = 0;
74924 uint32_t v_use_color_cache = 0;
74925 uint32_t v_color_cache_bits = 0;
74927 const uint8_t* iop_a_src = NULL;
74928 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
74929 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
74930 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
74931 if (a_src && a_src->data.ptr) {
74932 io0_a_src = a_src->data.ptr;
74933 io1_a_src = io0_a_src + a_src->meta.ri;
74934 iop_a_src = io1_a_src;
74935 io2_a_src = io0_a_src + a_src->meta.wi;
74938 uint32_t coro_susp_point = self->private_impl.p_decode_color_cache_parameters;
74939 switch (coro_susp_point) {
74940 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
74942 if (self->private_impl.f_n_bits < 1u) {
74944 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
74945 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
74946 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
74947 goto suspend;
74949 uint8_t t_0 = *iop_a_src++;
74950 v_c8 = t_0;
74952 self->private_impl.f_bits = ((uint32_t)(v_c8));
74953 self->private_impl.f_n_bits = 8u;
74955 v_use_color_cache = (self->private_impl.f_bits & 1u);
74956 self->private_impl.f_bits >>= 1u;
74957 self->private_impl.f_n_bits -= 1u;
74958 self->private_impl.f_color_cache_bits = 0u;
74959 if (v_use_color_cache != 0u) {
74960 if (self->private_impl.f_n_bits < 4u) {
74962 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
74963 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
74964 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
74965 goto suspend;
74967 uint8_t t_1 = *iop_a_src++;
74968 v_c8 = t_1;
74970 if (self->private_impl.f_n_bits >= 4u) {
74971 status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_n_bits);
74972 goto exit;
74974 self->private_impl.f_bits |= (((uint32_t)(v_c8)) << self->private_impl.f_n_bits);
74975 self->private_impl.f_n_bits += 8u;
74977 v_color_cache_bits = (self->private_impl.f_bits & 15u);
74978 self->private_impl.f_bits >>= 4u;
74979 self->private_impl.f_n_bits -= 4u;
74980 if ((v_color_cache_bits < 1u) || (11u < v_color_cache_bits)) {
74981 status = wuffs_base__make_status(wuffs_webp__error__bad_color_cache);
74982 goto exit;
74984 self->private_impl.f_color_cache_bits = v_color_cache_bits;
74987 goto ok;
74989 self->private_impl.p_decode_color_cache_parameters = 0;
74990 goto exit;
74993 goto suspend;
74994 suspend:
74995 self->private_impl.p_decode_color_cache_parameters = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
74997 goto exit;
74998 exit:
74999 if (a_src && a_src->data.ptr) {
75000 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
75003 return status;
75006 // -------- func webp.decoder.decode_hg_table
75008 WUFFS_BASE__GENERATED_C_CODE
75009 static wuffs_base__status
75010 wuffs_webp__decoder__decode_hg_table(
75011 wuffs_webp__decoder* self,
75012 wuffs_base__io_buffer* a_src,
75013 uint32_t a_width,
75014 wuffs_base__slice_u8 a_workbuf) {
75015 wuffs_base__status status = wuffs_base__make_status(NULL);
75017 wuffs_base__status v_status = wuffs_base__make_status(NULL);
75018 uint8_t v_c8 = 0;
75019 uint32_t v_use_hg_table = 0;
75020 uint32_t v_tile_size_log2 = 0;
75021 wuffs_base__slice_u8 v_hg_pixels = {0};
75022 uint64_t v_n = 0;
75023 wuffs_base__slice_u8 v_p = {0};
75024 uint32_t v_hg_plus_1 = 0;
75026 const uint8_t* iop_a_src = NULL;
75027 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
75028 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
75029 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
75030 if (a_src && a_src->data.ptr) {
75031 io0_a_src = a_src->data.ptr;
75032 io1_a_src = io0_a_src + a_src->meta.ri;
75033 iop_a_src = io1_a_src;
75034 io2_a_src = io0_a_src + a_src->meta.wi;
75037 uint32_t coro_susp_point = self->private_impl.p_decode_hg_table;
75038 if (coro_susp_point) {
75039 v_tile_size_log2 = self->private_data.s_decode_hg_table.v_tile_size_log2;
75041 switch (coro_susp_point) {
75042 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
75044 if (self->private_impl.f_n_bits < 1u) {
75046 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
75047 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
75048 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
75049 goto suspend;
75051 uint8_t t_0 = *iop_a_src++;
75052 v_c8 = t_0;
75054 self->private_impl.f_bits = ((uint32_t)(v_c8));
75055 self->private_impl.f_n_bits = 8u;
75057 v_use_hg_table = (self->private_impl.f_bits & 1u);
75058 self->private_impl.f_bits >>= 1u;
75059 self->private_impl.f_n_bits -= 1u;
75060 if (v_use_hg_table == 0u) {
75061 self->private_impl.f_overall_n_huffman_groups = 1u;
75062 self->private_impl.f_overall_tile_size_log2 = 0u;
75063 if ((((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[0u])) > ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[1u]))) || (((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[1u])) > ((uint64_t)(a_workbuf.len)))) {
75064 status = wuffs_base__make_status(wuffs_base__error__bad_workbuf_length);
75065 goto exit;
75067 v_hg_pixels = wuffs_base__slice_u8__subslice_ij(a_workbuf,
75068 ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[0u])),
75069 ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[1u])));
75070 if (((uint64_t)(v_hg_pixels.len)) >= 4u) {
75071 v_hg_pixels.ptr[0u] = 0u;
75072 v_hg_pixels.ptr[1u] = 0u;
75073 v_hg_pixels.ptr[2u] = 0u;
75074 v_hg_pixels.ptr[3u] = 0u;
75076 status = wuffs_base__make_status(NULL);
75077 goto ok;
75079 if (self->private_impl.f_n_bits < 3u) {
75081 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
75082 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
75083 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
75084 goto suspend;
75086 uint8_t t_1 = *iop_a_src++;
75087 v_c8 = t_1;
75089 if (self->private_impl.f_n_bits >= 3u) {
75090 status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_n_bits);
75091 goto exit;
75093 self->private_impl.f_bits |= (((uint32_t)(v_c8)) << self->private_impl.f_n_bits);
75094 self->private_impl.f_n_bits += 8u;
75096 v_tile_size_log2 = ((self->private_impl.f_bits & 7u) + 2u);
75097 self->private_impl.f_bits >>= 3u;
75098 self->private_impl.f_n_bits -= 3u;
75099 self->private_impl.f_overall_tile_size_log2 = v_tile_size_log2;
75100 if (a_src) {
75101 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
75103 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
75104 status = wuffs_webp__decoder__decode_color_cache_parameters(self, a_src);
75105 if (a_src) {
75106 iop_a_src = a_src->data.ptr + a_src->meta.ri;
75108 if (status.repr) {
75109 goto suspend;
75111 if (a_src) {
75112 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
75114 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
75115 status = wuffs_webp__decoder__decode_huffman_groups(self, a_src, 1u);
75116 if (a_src) {
75117 iop_a_src = a_src->data.ptr + a_src->meta.ri;
75119 if (status.repr) {
75120 goto suspend;
75122 while (true) {
75123 if ((((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[0u])) > ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[1u]))) || (((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[1u])) > ((uint64_t)(a_workbuf.len)))) {
75124 status = wuffs_base__make_status(wuffs_base__error__bad_workbuf_length);
75125 goto exit;
75128 if (a_src) {
75129 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
75131 wuffs_base__status t_2 = wuffs_webp__decoder__decode_pixels(self,
75132 wuffs_base__slice_u8__subslice_ij(a_workbuf,
75133 ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[0u])),
75134 ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[1u]))),
75135 a_src,
75136 ((a_width + ((((uint32_t)(1u)) << v_tile_size_log2) - 1u)) >> v_tile_size_log2),
75137 ((self->private_impl.f_height + ((((uint32_t)(1u)) << v_tile_size_log2) - 1u)) >> v_tile_size_log2),
75138 wuffs_base__utility__empty_slice_u8(),
75139 0u);
75140 v_status = t_2;
75141 if (a_src) {
75142 iop_a_src = a_src->data.ptr + a_src->meta.ri;
75145 if (wuffs_base__status__is_ok(&v_status)) {
75146 break;
75148 status = v_status;
75149 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
75151 self->private_impl.f_overall_n_huffman_groups = 1u;
75152 if ((((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[0u])) > ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[1u]))) || (((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[1u])) > ((uint64_t)(a_workbuf.len)))) {
75153 status = wuffs_base__make_status(wuffs_base__error__bad_workbuf_length);
75154 goto exit;
75156 v_hg_pixels = wuffs_base__slice_u8__subslice_ij(a_workbuf,
75157 ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[0u])),
75158 ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[1u])));
75159 v_n = ((uint64_t)((((a_width + ((((uint32_t)(1u)) << v_tile_size_log2) - 1u)) >> v_tile_size_log2) * ((self->private_impl.f_height + ((((uint32_t)(1u)) << v_tile_size_log2) - 1u)) >> v_tile_size_log2) * 4u)));
75160 if (v_n > ((uint64_t)(v_hg_pixels.len))) {
75161 status = wuffs_base__make_status(wuffs_base__error__bad_workbuf_length);
75162 goto exit;
75164 v_p = wuffs_base__slice_u8__subslice_j(v_hg_pixels, v_n);
75165 while (((uint64_t)(v_p.len)) >= 4u) {
75166 if (v_p.ptr[2u] != 0u) {
75167 status = wuffs_base__make_status(wuffs_webp__error__unsupported_number_of_huffman_groups);
75168 goto exit;
75170 v_hg_plus_1 = (((uint32_t)(v_p.ptr[1u])) + 1u);
75171 if (self->private_impl.f_overall_n_huffman_groups < v_hg_plus_1) {
75172 self->private_impl.f_overall_n_huffman_groups = v_hg_plus_1;
75174 v_p = wuffs_base__slice_u8__subslice_i(v_p, 4u);
75178 self->private_impl.p_decode_hg_table = 0;
75179 goto exit;
75182 goto suspend;
75183 suspend:
75184 self->private_impl.p_decode_hg_table = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
75185 self->private_data.s_decode_hg_table.v_tile_size_log2 = v_tile_size_log2;
75187 goto exit;
75188 exit:
75189 if (a_src && a_src->data.ptr) {
75190 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
75193 return status;
75196 // -------- func webp.decoder.decode_pixels
75198 WUFFS_BASE__GENERATED_C_CODE
75199 static wuffs_base__status
75200 wuffs_webp__decoder__decode_pixels(
75201 wuffs_webp__decoder* self,
75202 wuffs_base__slice_u8 a_dst,
75203 wuffs_base__io_buffer* a_src,
75204 uint32_t a_width,
75205 uint32_t a_height,
75206 wuffs_base__slice_u8 a_tile_data,
75207 uint32_t a_tile_size_log2) {
75208 wuffs_base__status status = wuffs_base__make_status(NULL);
75210 uint32_t v_i = 0;
75211 uint32_t v_n = 0;
75213 uint32_t coro_susp_point = self->private_impl.p_decode_pixels;
75214 switch (coro_susp_point) {
75215 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
75217 v_i = 0u;
75218 v_n = (((uint32_t)(1u)) << self->private_impl.f_color_cache_bits);
75219 while (v_i < v_n) {
75220 self->private_data.f_color_cache[v_i] = 0u;
75221 v_i += 1u;
75223 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
75224 status = wuffs_webp__decoder__decode_pixels_slow(self,
75225 a_dst,
75226 a_src,
75227 a_width,
75228 a_height,
75229 a_tile_data,
75230 a_tile_size_log2);
75231 if (status.repr) {
75232 goto suspend;
75235 goto ok;
75237 self->private_impl.p_decode_pixels = 0;
75238 goto exit;
75241 goto suspend;
75242 suspend:
75243 self->private_impl.p_decode_pixels = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
75245 goto exit;
75246 exit:
75247 return status;
75250 // -------- func webp.decoder.swizzle
75252 WUFFS_BASE__GENERATED_C_CODE
75253 static wuffs_base__status
75254 wuffs_webp__decoder__swizzle(
75255 wuffs_webp__decoder* self,
75256 wuffs_base__pixel_buffer* a_dst,
75257 wuffs_base__slice_u8 a_src,
75258 wuffs_base__pixel_blend a_blend) {
75259 wuffs_base__status v_status = wuffs_base__make_status(NULL);
75260 wuffs_base__pixel_format v_dst_pixfmt = {0};
75261 uint32_t v_dst_bits_per_pixel = 0;
75262 uint32_t v_dst_bytes_per_pixel = 0;
75263 uint64_t v_dst_bytes_per_row = 0;
75264 wuffs_base__slice_u8 v_dst_palette = {0};
75265 wuffs_base__table_u8 v_tab = {0};
75266 uint64_t v_src_bytes_per_row = 0;
75267 wuffs_base__slice_u8 v_dst = {0};
75268 uint32_t v_y = 0;
75270 v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
75271 wuffs_base__pixel_buffer__pixel_format(a_dst),
75272 wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_palette, 1024)),
75273 wuffs_base__utility__make_pixel_format(self->private_impl.f_pixfmt),
75274 wuffs_base__utility__empty_slice_u8(),
75275 a_blend);
75276 if ( ! wuffs_base__status__is_ok(&v_status)) {
75277 return wuffs_private_impl__status__ensure_not_a_suspension(v_status);
75279 v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
75280 v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
75281 if ((v_dst_bits_per_pixel & 7u) != 0u) {
75282 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
75284 v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u);
75285 v_dst_bytes_per_row = ((uint64_t)((self->private_impl.f_width * v_dst_bytes_per_pixel)));
75286 v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_palette, 1024));
75287 v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
75288 v_src_bytes_per_row = ((uint64_t)((self->private_impl.f_width * 4u)));
75289 while (v_src_bytes_per_row <= ((uint64_t)(a_src.len))) {
75290 v_dst = wuffs_private_impl__table_u8__row_u32(v_tab, v_y);
75291 if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) {
75292 v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row);
75294 wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, wuffs_base__slice_u8__subslice_j(a_src, v_src_bytes_per_row));
75295 a_src = wuffs_base__slice_u8__subslice_i(a_src, v_src_bytes_per_row);
75296 v_y += 1u;
75298 return wuffs_base__make_status(NULL);
75301 // -------- func webp.decoder.frame_dirty_rect
75303 WUFFS_BASE__GENERATED_C_CODE
75304 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
75305 wuffs_webp__decoder__frame_dirty_rect(
75306 const wuffs_webp__decoder* self) {
75307 if (!self) {
75308 return wuffs_base__utility__empty_rect_ie_u32();
75310 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
75311 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
75312 return wuffs_base__utility__empty_rect_ie_u32();
75315 return wuffs_base__utility__make_rect_ie_u32(
75318 self->private_impl.f_width,
75319 self->private_impl.f_height);
75322 // -------- func webp.decoder.num_animation_loops
75324 WUFFS_BASE__GENERATED_C_CODE
75325 WUFFS_BASE__MAYBE_STATIC uint32_t
75326 wuffs_webp__decoder__num_animation_loops(
75327 const wuffs_webp__decoder* self) {
75328 if (!self) {
75329 return 0;
75331 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
75332 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
75333 return 0;
75336 return 0u;
75339 // -------- func webp.decoder.num_decoded_frame_configs
75341 WUFFS_BASE__GENERATED_C_CODE
75342 WUFFS_BASE__MAYBE_STATIC uint64_t
75343 wuffs_webp__decoder__num_decoded_frame_configs(
75344 const wuffs_webp__decoder* self) {
75345 if (!self) {
75346 return 0;
75348 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
75349 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
75350 return 0;
75353 if (self->private_impl.f_call_sequence > 32u) {
75354 return 1u;
75356 return 0u;
75359 // -------- func webp.decoder.num_decoded_frames
75361 WUFFS_BASE__GENERATED_C_CODE
75362 WUFFS_BASE__MAYBE_STATIC uint64_t
75363 wuffs_webp__decoder__num_decoded_frames(
75364 const wuffs_webp__decoder* self) {
75365 if (!self) {
75366 return 0;
75368 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
75369 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
75370 return 0;
75373 if (self->private_impl.f_call_sequence > 64u) {
75374 return 1u;
75376 return 0u;
75379 // -------- func webp.decoder.restart_frame
75381 WUFFS_BASE__GENERATED_C_CODE
75382 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
75383 wuffs_webp__decoder__restart_frame(
75384 wuffs_webp__decoder* self,
75385 uint64_t a_index,
75386 uint64_t a_io_position) {
75387 if (!self) {
75388 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
75390 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
75391 return wuffs_base__make_status(
75392 (self->private_impl.magic == WUFFS_BASE__DISABLED)
75393 ? wuffs_base__error__disabled_by_previous_error
75394 : wuffs_base__error__initialize_not_called);
75397 if (self->private_impl.f_call_sequence < 32u) {
75398 return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
75400 if ((a_index != 0u) || (a_io_position != self->private_impl.f_frame_config_io_position)) {
75401 return wuffs_base__make_status(wuffs_base__error__bad_argument);
75403 self->private_impl.f_call_sequence = 40u;
75404 return wuffs_base__make_status(NULL);
75407 // -------- func webp.decoder.set_report_metadata
75409 WUFFS_BASE__GENERATED_C_CODE
75410 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
75411 wuffs_webp__decoder__set_report_metadata(
75412 wuffs_webp__decoder* self,
75413 uint32_t a_fourcc,
75414 bool a_report) {
75415 return wuffs_base__make_empty_struct();
75418 // -------- func webp.decoder.tell_me_more
75420 WUFFS_BASE__GENERATED_C_CODE
75421 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
75422 wuffs_webp__decoder__tell_me_more(
75423 wuffs_webp__decoder* self,
75424 wuffs_base__io_buffer* a_dst,
75425 wuffs_base__more_information* a_minfo,
75426 wuffs_base__io_buffer* a_src) {
75427 if (!self) {
75428 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
75430 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
75431 return wuffs_base__make_status(
75432 (self->private_impl.magic == WUFFS_BASE__DISABLED)
75433 ? wuffs_base__error__disabled_by_previous_error
75434 : wuffs_base__error__initialize_not_called);
75436 if (!a_dst || !a_src) {
75437 self->private_impl.magic = WUFFS_BASE__DISABLED;
75438 return wuffs_base__make_status(wuffs_base__error__bad_argument);
75440 if ((self->private_impl.active_coroutine != 0) &&
75441 (self->private_impl.active_coroutine != 4)) {
75442 self->private_impl.magic = WUFFS_BASE__DISABLED;
75443 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
75445 self->private_impl.active_coroutine = 0;
75446 wuffs_base__status status = wuffs_base__make_status(NULL);
75448 status = wuffs_base__make_status(wuffs_base__error__no_more_information);
75449 goto exit;
75451 goto ok;
75453 goto exit;
75454 exit:
75455 if (wuffs_base__status__is_error(&status)) {
75456 self->private_impl.magic = WUFFS_BASE__DISABLED;
75458 return status;
75461 // -------- func webp.decoder.workbuf_len
75463 WUFFS_BASE__GENERATED_C_CODE
75464 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
75465 wuffs_webp__decoder__workbuf_len(
75466 const wuffs_webp__decoder* self) {
75467 if (!self) {
75468 return wuffs_base__utility__empty_range_ii_u64();
75470 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
75471 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
75472 return wuffs_base__utility__empty_range_ii_u64();
75475 return wuffs_base__utility__make_range_ii_u64(((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[3u])), ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[3u])));
75478 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WEBP)
75480 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH32)
75482 // ---------------- Status Codes Implementations
75484 // ---------------- Private Consts
75486 #define WUFFS_XXHASH32__XXH_PRIME32_1 2654435761u
75488 #define WUFFS_XXHASH32__XXH_PRIME32_2 2246822519u
75490 #define WUFFS_XXHASH32__XXH_PRIME32_3 3266489917u
75492 #define WUFFS_XXHASH32__XXH_PRIME32_4 668265263u
75494 #define WUFFS_XXHASH32__XXH_PRIME32_5 374761393u
75496 #define WUFFS_XXHASH32__INITIAL_V0 606290984u
75498 #define WUFFS_XXHASH32__INITIAL_V1 2246822519u
75500 #define WUFFS_XXHASH32__INITIAL_V2 0u
75502 #define WUFFS_XXHASH32__INITIAL_V3 1640531535u
75504 // ---------------- Private Initializer Prototypes
75506 // ---------------- Private Function Prototypes
75508 WUFFS_BASE__GENERATED_C_CODE
75509 static wuffs_base__empty_struct
75510 wuffs_xxhash32__hasher__up(
75511 wuffs_xxhash32__hasher* self,
75512 wuffs_base__slice_u8 a_x);
75514 // ---------------- VTables
75516 const wuffs_base__hasher_u32__func_ptrs
75517 wuffs_xxhash32__hasher__func_ptrs_for__wuffs_base__hasher_u32 = {
75518 (uint32_t(*)(const void*))(&wuffs_xxhash32__hasher__checksum_u32),
75519 (uint64_t(*)(const void*,
75520 uint32_t))(&wuffs_xxhash32__hasher__get_quirk),
75521 (wuffs_base__status(*)(void*,
75522 uint32_t,
75523 uint64_t))(&wuffs_xxhash32__hasher__set_quirk),
75524 (wuffs_base__empty_struct(*)(void*,
75525 wuffs_base__slice_u8))(&wuffs_xxhash32__hasher__update),
75526 (uint32_t(*)(void*,
75527 wuffs_base__slice_u8))(&wuffs_xxhash32__hasher__update_u32),
75530 // ---------------- Initializer Implementations
75532 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
75533 wuffs_xxhash32__hasher__initialize(
75534 wuffs_xxhash32__hasher* self,
75535 size_t sizeof_star_self,
75536 uint64_t wuffs_version,
75537 uint32_t options){
75538 if (!self) {
75539 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
75541 if (sizeof(*self) != sizeof_star_self) {
75542 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
75544 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
75545 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
75546 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
75549 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
75550 // The whole point of this if-check is to detect an uninitialized *self.
75551 // We disable the warning on GCC. Clang-5.0 does not have this warning.
75552 #if !defined(__clang__) && defined(__GNUC__)
75553 #pragma GCC diagnostic push
75554 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
75555 #endif
75556 if (self->private_impl.magic != 0) {
75557 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
75559 #if !defined(__clang__) && defined(__GNUC__)
75560 #pragma GCC diagnostic pop
75561 #endif
75562 } else {
75563 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
75564 memset(self, 0, sizeof(*self));
75565 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
75566 } else {
75567 memset(&(self->private_impl), 0, sizeof(self->private_impl));
75571 self->private_impl.magic = WUFFS_BASE__MAGIC;
75572 self->private_impl.vtable_for__wuffs_base__hasher_u32.vtable_name =
75573 wuffs_base__hasher_u32__vtable_name;
75574 self->private_impl.vtable_for__wuffs_base__hasher_u32.function_pointers =
75575 (const void*)(&wuffs_xxhash32__hasher__func_ptrs_for__wuffs_base__hasher_u32);
75576 return wuffs_base__make_status(NULL);
75579 wuffs_xxhash32__hasher*
75580 wuffs_xxhash32__hasher__alloc(void) {
75581 wuffs_xxhash32__hasher* x =
75582 (wuffs_xxhash32__hasher*)(calloc(1, sizeof(wuffs_xxhash32__hasher)));
75583 if (!x) {
75584 return NULL;
75586 if (wuffs_xxhash32__hasher__initialize(
75587 x, sizeof(wuffs_xxhash32__hasher), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
75588 free(x);
75589 return NULL;
75591 return x;
75594 size_t
75595 sizeof__wuffs_xxhash32__hasher(void) {
75596 return sizeof(wuffs_xxhash32__hasher);
75599 // ---------------- Function Implementations
75601 // -------- func xxhash32.hasher.get_quirk
75603 WUFFS_BASE__GENERATED_C_CODE
75604 WUFFS_BASE__MAYBE_STATIC uint64_t
75605 wuffs_xxhash32__hasher__get_quirk(
75606 const wuffs_xxhash32__hasher* self,
75607 uint32_t a_key) {
75608 if (!self) {
75609 return 0;
75611 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
75612 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
75613 return 0;
75616 return 0u;
75619 // -------- func xxhash32.hasher.set_quirk
75621 WUFFS_BASE__GENERATED_C_CODE
75622 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
75623 wuffs_xxhash32__hasher__set_quirk(
75624 wuffs_xxhash32__hasher* self,
75625 uint32_t a_key,
75626 uint64_t a_value) {
75627 if (!self) {
75628 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
75630 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
75631 return wuffs_base__make_status(
75632 (self->private_impl.magic == WUFFS_BASE__DISABLED)
75633 ? wuffs_base__error__disabled_by_previous_error
75634 : wuffs_base__error__initialize_not_called);
75637 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
75640 // -------- func xxhash32.hasher.update
75642 WUFFS_BASE__GENERATED_C_CODE
75643 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
75644 wuffs_xxhash32__hasher__update(
75645 wuffs_xxhash32__hasher* self,
75646 wuffs_base__slice_u8 a_x) {
75647 if (!self) {
75648 return wuffs_base__make_empty_struct();
75650 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
75651 return wuffs_base__make_empty_struct();
75654 wuffs_base__slice_u8 v_remaining = {0};
75656 if ((self->private_impl.f_length_modulo_u32 == 0u) && ! self->private_impl.f_length_overflows_u32) {
75657 self->private_impl.f_v0 = 606290984u;
75658 self->private_impl.f_v1 = 2246822519u;
75659 self->private_impl.f_v2 = 0u;
75660 self->private_impl.f_v3 = 1640531535u;
75662 while (((uint64_t)(a_x.len)) > 0u) {
75663 v_remaining = wuffs_base__slice_u8__subslice_j(a_x, 0u);
75664 if (((uint64_t)(a_x.len)) > 16777216u) {
75665 v_remaining = wuffs_base__slice_u8__subslice_i(a_x, 16777216u);
75666 a_x = wuffs_base__slice_u8__subslice_j(a_x, 16777216u);
75668 wuffs_xxhash32__hasher__up(self, a_x);
75669 a_x = v_remaining;
75671 return wuffs_base__make_empty_struct();
75674 // -------- func xxhash32.hasher.update_u32
75676 WUFFS_BASE__GENERATED_C_CODE
75677 WUFFS_BASE__MAYBE_STATIC uint32_t
75678 wuffs_xxhash32__hasher__update_u32(
75679 wuffs_xxhash32__hasher* self,
75680 wuffs_base__slice_u8 a_x) {
75681 if (!self) {
75682 return 0;
75684 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
75685 return 0;
75688 wuffs_xxhash32__hasher__update(self, a_x);
75689 return wuffs_xxhash32__hasher__checksum_u32(self);
75692 // -------- func xxhash32.hasher.up
75694 WUFFS_BASE__GENERATED_C_CODE
75695 static wuffs_base__empty_struct
75696 wuffs_xxhash32__hasher__up(
75697 wuffs_xxhash32__hasher* self,
75698 wuffs_base__slice_u8 a_x) {
75699 uint32_t v_new_lmu = 0;
75700 uint32_t v_buf_u32 = 0;
75701 uint32_t v_buf_len = 0;
75702 uint32_t v_v0 = 0;
75703 uint32_t v_v1 = 0;
75704 uint32_t v_v2 = 0;
75705 uint32_t v_v3 = 0;
75706 wuffs_base__slice_u8 v_p = {0};
75708 v_new_lmu = ((uint32_t)(self->private_impl.f_length_modulo_u32 + ((uint32_t)(((uint64_t)(a_x.len))))));
75709 self->private_impl.f_length_overflows_u32 = ((v_new_lmu < self->private_impl.f_length_modulo_u32) || self->private_impl.f_length_overflows_u32);
75710 self->private_impl.f_length_modulo_u32 = v_new_lmu;
75711 while (true) {
75712 if (self->private_impl.f_buf_len >= 16u) {
75713 v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[0u])) |
75714 (((uint32_t)(self->private_impl.f_buf_data[1u])) << 8u) |
75715 (((uint32_t)(self->private_impl.f_buf_data[2u])) << 16u) |
75716 (((uint32_t)(self->private_impl.f_buf_data[3u])) << 24u));
75717 v_v0 = ((uint32_t)(self->private_impl.f_v0 + ((uint32_t)(v_buf_u32 * 2246822519u))));
75718 v_v0 = (((uint32_t)(v_v0 << 13u)) | (v_v0 >> 19u));
75719 self->private_impl.f_v0 = ((uint32_t)(v_v0 * 2654435761u));
75720 v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[4u])) |
75721 (((uint32_t)(self->private_impl.f_buf_data[5u])) << 8u) |
75722 (((uint32_t)(self->private_impl.f_buf_data[6u])) << 16u) |
75723 (((uint32_t)(self->private_impl.f_buf_data[7u])) << 24u));
75724 v_v1 = ((uint32_t)(self->private_impl.f_v1 + ((uint32_t)(v_buf_u32 * 2246822519u))));
75725 v_v1 = (((uint32_t)(v_v1 << 13u)) | (v_v1 >> 19u));
75726 self->private_impl.f_v1 = ((uint32_t)(v_v1 * 2654435761u));
75727 v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[8u])) |
75728 (((uint32_t)(self->private_impl.f_buf_data[9u])) << 8u) |
75729 (((uint32_t)(self->private_impl.f_buf_data[10u])) << 16u) |
75730 (((uint32_t)(self->private_impl.f_buf_data[11u])) << 24u));
75731 v_v2 = ((uint32_t)(self->private_impl.f_v2 + ((uint32_t)(v_buf_u32 * 2246822519u))));
75732 v_v2 = (((uint32_t)(v_v2 << 13u)) | (v_v2 >> 19u));
75733 self->private_impl.f_v2 = ((uint32_t)(v_v2 * 2654435761u));
75734 v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[12u])) |
75735 (((uint32_t)(self->private_impl.f_buf_data[13u])) << 8u) |
75736 (((uint32_t)(self->private_impl.f_buf_data[14u])) << 16u) |
75737 (((uint32_t)(self->private_impl.f_buf_data[15u])) << 24u));
75738 v_v3 = ((uint32_t)(self->private_impl.f_v3 + ((uint32_t)(v_buf_u32 * 2246822519u))));
75739 v_v3 = (((uint32_t)(v_v3 << 13u)) | (v_v3 >> 19u));
75740 self->private_impl.f_v3 = ((uint32_t)(v_v3 * 2654435761u));
75741 self->private_impl.f_buf_len = 0u;
75742 break;
75744 if (((uint64_t)(a_x.len)) <= 0u) {
75745 return wuffs_base__make_empty_struct();
75747 self->private_impl.f_buf_data[self->private_impl.f_buf_len] = a_x.ptr[0u];
75748 #if defined(__GNUC__)
75749 #pragma GCC diagnostic push
75750 #pragma GCC diagnostic ignored "-Wconversion"
75751 #endif
75752 self->private_impl.f_buf_len += 1u;
75753 #if defined(__GNUC__)
75754 #pragma GCC diagnostic pop
75755 #endif
75756 a_x = wuffs_base__slice_u8__subslice_i(a_x, 1u);
75758 v_buf_len = ((uint32_t)(((uint8_t)(self->private_impl.f_buf_len & 15u))));
75759 v_v0 = self->private_impl.f_v0;
75760 v_v1 = self->private_impl.f_v1;
75761 v_v2 = self->private_impl.f_v2;
75762 v_v3 = self->private_impl.f_v3;
75764 wuffs_base__slice_u8 i_slice_p = a_x;
75765 v_p.ptr = i_slice_p.ptr;
75766 v_p.len = 16;
75767 const uint8_t* i_end0_p = wuffs_private_impl__ptr_u8_plus_len(v_p.ptr, (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 16) * 16));
75768 while (v_p.ptr < i_end0_p) {
75769 v_buf_u32 = (((uint32_t)(v_p.ptr[0u])) |
75770 (((uint32_t)(v_p.ptr[1u])) << 8u) |
75771 (((uint32_t)(v_p.ptr[2u])) << 16u) |
75772 (((uint32_t)(v_p.ptr[3u])) << 24u));
75773 v_v0 = ((uint32_t)(v_v0 + ((uint32_t)(v_buf_u32 * 2246822519u))));
75774 v_v0 = (((uint32_t)(v_v0 << 13u)) | (v_v0 >> 19u));
75775 v_v0 = ((uint32_t)(v_v0 * 2654435761u));
75776 v_buf_u32 = (((uint32_t)(v_p.ptr[4u])) |
75777 (((uint32_t)(v_p.ptr[5u])) << 8u) |
75778 (((uint32_t)(v_p.ptr[6u])) << 16u) |
75779 (((uint32_t)(v_p.ptr[7u])) << 24u));
75780 v_v1 = ((uint32_t)(v_v1 + ((uint32_t)(v_buf_u32 * 2246822519u))));
75781 v_v1 = (((uint32_t)(v_v1 << 13u)) | (v_v1 >> 19u));
75782 v_v1 = ((uint32_t)(v_v1 * 2654435761u));
75783 v_buf_u32 = (((uint32_t)(v_p.ptr[8u])) |
75784 (((uint32_t)(v_p.ptr[9u])) << 8u) |
75785 (((uint32_t)(v_p.ptr[10u])) << 16u) |
75786 (((uint32_t)(v_p.ptr[11u])) << 24u));
75787 v_v2 = ((uint32_t)(v_v2 + ((uint32_t)(v_buf_u32 * 2246822519u))));
75788 v_v2 = (((uint32_t)(v_v2 << 13u)) | (v_v2 >> 19u));
75789 v_v2 = ((uint32_t)(v_v2 * 2654435761u));
75790 v_buf_u32 = (((uint32_t)(v_p.ptr[12u])) |
75791 (((uint32_t)(v_p.ptr[13u])) << 8u) |
75792 (((uint32_t)(v_p.ptr[14u])) << 16u) |
75793 (((uint32_t)(v_p.ptr[15u])) << 24u));
75794 v_v3 = ((uint32_t)(v_v3 + ((uint32_t)(v_buf_u32 * 2246822519u))));
75795 v_v3 = (((uint32_t)(v_v3 << 13u)) | (v_v3 >> 19u));
75796 v_v3 = ((uint32_t)(v_v3 * 2654435761u));
75797 v_p.ptr += 16;
75799 v_p.len = 1;
75800 const uint8_t* i_end1_p = wuffs_private_impl__ptr_u8_plus_len(i_slice_p.ptr, i_slice_p.len);
75801 while (v_p.ptr < i_end1_p) {
75802 self->private_impl.f_buf_data[v_buf_len] = v_p.ptr[0u];
75803 v_buf_len = ((v_buf_len + 1u) & 15u);
75804 v_p.ptr += 1;
75806 v_p.len = 0;
75808 self->private_impl.f_buf_len = ((uint8_t)(v_buf_len));
75809 self->private_impl.f_v0 = v_v0;
75810 self->private_impl.f_v1 = v_v1;
75811 self->private_impl.f_v2 = v_v2;
75812 self->private_impl.f_v3 = v_v3;
75813 return wuffs_base__make_empty_struct();
75816 // -------- func xxhash32.hasher.checksum_u32
75818 WUFFS_BASE__GENERATED_C_CODE
75819 WUFFS_BASE__MAYBE_STATIC uint32_t
75820 wuffs_xxhash32__hasher__checksum_u32(
75821 const wuffs_xxhash32__hasher* self) {
75822 if (!self) {
75823 return 0;
75825 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
75826 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
75827 return 0;
75830 uint32_t v_ret = 0;
75831 uint32_t v_i = 0;
75832 uint32_t v_n = 0;
75833 uint32_t v_buf_u32 = 0;
75835 if ((self->private_impl.f_length_modulo_u32 >= 16u) || self->private_impl.f_length_overflows_u32) {
75836 v_ret += (((uint32_t)(self->private_impl.f_v0 << 1u)) | (self->private_impl.f_v0 >> 31u));
75837 v_ret += (((uint32_t)(self->private_impl.f_v1 << 7u)) | (self->private_impl.f_v1 >> 25u));
75838 v_ret += (((uint32_t)(self->private_impl.f_v2 << 12u)) | (self->private_impl.f_v2 >> 20u));
75839 v_ret += (((uint32_t)(self->private_impl.f_v3 << 18u)) | (self->private_impl.f_v3 >> 14u));
75840 v_ret += self->private_impl.f_length_modulo_u32;
75841 } else {
75842 v_ret += 374761393u;
75843 v_ret += self->private_impl.f_length_modulo_u32;
75845 v_n = 16u;
75846 v_n = wuffs_base__u32__min(v_n, ((uint32_t)(self->private_impl.f_buf_len)));
75847 if (4u <= v_n) {
75848 v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[0u])) |
75849 (((uint32_t)(self->private_impl.f_buf_data[1u])) << 8u) |
75850 (((uint32_t)(self->private_impl.f_buf_data[2u])) << 16u) |
75851 (((uint32_t)(self->private_impl.f_buf_data[3u])) << 24u));
75852 v_ret += ((uint32_t)(v_buf_u32 * 3266489917u));
75853 v_ret = (((uint32_t)(v_ret << 17u)) | (v_ret >> 15u));
75854 v_ret *= 668265263u;
75855 v_i = 4u;
75857 if (8u <= v_n) {
75858 v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[4u])) |
75859 (((uint32_t)(self->private_impl.f_buf_data[5u])) << 8u) |
75860 (((uint32_t)(self->private_impl.f_buf_data[6u])) << 16u) |
75861 (((uint32_t)(self->private_impl.f_buf_data[7u])) << 24u));
75862 v_ret += ((uint32_t)(v_buf_u32 * 3266489917u));
75863 v_ret = (((uint32_t)(v_ret << 17u)) | (v_ret >> 15u));
75864 v_ret *= 668265263u;
75865 v_i = 8u;
75867 if (12u <= v_n) {
75868 v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[8u])) |
75869 (((uint32_t)(self->private_impl.f_buf_data[9u])) << 8u) |
75870 (((uint32_t)(self->private_impl.f_buf_data[10u])) << 16u) |
75871 (((uint32_t)(self->private_impl.f_buf_data[11u])) << 24u));
75872 v_ret += ((uint32_t)(v_buf_u32 * 3266489917u));
75873 v_ret = (((uint32_t)(v_ret << 17u)) | (v_ret >> 15u));
75874 v_ret *= 668265263u;
75875 v_i = 12u;
75877 while (v_i < v_n) {
75878 v_ret += ((uint32_t)(((uint32_t)(self->private_impl.f_buf_data[v_i])) * 374761393u));
75879 v_ret = (((uint32_t)(v_ret << 11u)) | (v_ret >> 21u));
75880 v_ret *= 2654435761u;
75881 v_i += 1u;
75883 v_ret ^= (v_ret >> 15u);
75884 v_ret *= 2246822519u;
75885 v_ret ^= (v_ret >> 13u);
75886 v_ret *= 3266489917u;
75887 v_ret ^= (v_ret >> 16u);
75888 return v_ret;
75891 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH32)
75893 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH64)
75895 // ---------------- Status Codes Implementations
75897 // ---------------- Private Consts
75899 #define WUFFS_XXHASH64__XXH_PRIME64_1 11400714785074694791u
75901 #define WUFFS_XXHASH64__XXH_PRIME64_2 14029467366897019727u
75903 #define WUFFS_XXHASH64__XXH_PRIME64_3 1609587929392839161u
75905 #define WUFFS_XXHASH64__XXH_PRIME64_4 9650029242287828579u
75907 #define WUFFS_XXHASH64__XXH_PRIME64_5 2870177450012600261u
75909 #define WUFFS_XXHASH64__INITIAL_V0 6983438078262162902u
75911 #define WUFFS_XXHASH64__INITIAL_V1 14029467366897019727u
75913 #define WUFFS_XXHASH64__INITIAL_V2 0u
75915 #define WUFFS_XXHASH64__INITIAL_V3 7046029288634856825u
75917 // ---------------- Private Initializer Prototypes
75919 // ---------------- Private Function Prototypes
75921 WUFFS_BASE__GENERATED_C_CODE
75922 static wuffs_base__empty_struct
75923 wuffs_xxhash64__hasher__up(
75924 wuffs_xxhash64__hasher* self,
75925 wuffs_base__slice_u8 a_x);
75927 // ---------------- VTables
75929 const wuffs_base__hasher_u64__func_ptrs
75930 wuffs_xxhash64__hasher__func_ptrs_for__wuffs_base__hasher_u64 = {
75931 (uint64_t(*)(const void*))(&wuffs_xxhash64__hasher__checksum_u64),
75932 (uint64_t(*)(const void*,
75933 uint32_t))(&wuffs_xxhash64__hasher__get_quirk),
75934 (wuffs_base__status(*)(void*,
75935 uint32_t,
75936 uint64_t))(&wuffs_xxhash64__hasher__set_quirk),
75937 (wuffs_base__empty_struct(*)(void*,
75938 wuffs_base__slice_u8))(&wuffs_xxhash64__hasher__update),
75939 (uint64_t(*)(void*,
75940 wuffs_base__slice_u8))(&wuffs_xxhash64__hasher__update_u64),
75943 // ---------------- Initializer Implementations
75945 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
75946 wuffs_xxhash64__hasher__initialize(
75947 wuffs_xxhash64__hasher* self,
75948 size_t sizeof_star_self,
75949 uint64_t wuffs_version,
75950 uint32_t options){
75951 if (!self) {
75952 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
75954 if (sizeof(*self) != sizeof_star_self) {
75955 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
75957 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
75958 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
75959 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
75962 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
75963 // The whole point of this if-check is to detect an uninitialized *self.
75964 // We disable the warning on GCC. Clang-5.0 does not have this warning.
75965 #if !defined(__clang__) && defined(__GNUC__)
75966 #pragma GCC diagnostic push
75967 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
75968 #endif
75969 if (self->private_impl.magic != 0) {
75970 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
75972 #if !defined(__clang__) && defined(__GNUC__)
75973 #pragma GCC diagnostic pop
75974 #endif
75975 } else {
75976 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
75977 memset(self, 0, sizeof(*self));
75978 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
75979 } else {
75980 memset(&(self->private_impl), 0, sizeof(self->private_impl));
75984 self->private_impl.magic = WUFFS_BASE__MAGIC;
75985 self->private_impl.vtable_for__wuffs_base__hasher_u64.vtable_name =
75986 wuffs_base__hasher_u64__vtable_name;
75987 self->private_impl.vtable_for__wuffs_base__hasher_u64.function_pointers =
75988 (const void*)(&wuffs_xxhash64__hasher__func_ptrs_for__wuffs_base__hasher_u64);
75989 return wuffs_base__make_status(NULL);
75992 wuffs_xxhash64__hasher*
75993 wuffs_xxhash64__hasher__alloc(void) {
75994 wuffs_xxhash64__hasher* x =
75995 (wuffs_xxhash64__hasher*)(calloc(1, sizeof(wuffs_xxhash64__hasher)));
75996 if (!x) {
75997 return NULL;
75999 if (wuffs_xxhash64__hasher__initialize(
76000 x, sizeof(wuffs_xxhash64__hasher), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
76001 free(x);
76002 return NULL;
76004 return x;
76007 size_t
76008 sizeof__wuffs_xxhash64__hasher(void) {
76009 return sizeof(wuffs_xxhash64__hasher);
76012 // ---------------- Function Implementations
76014 // -------- func xxhash64.hasher.get_quirk
76016 WUFFS_BASE__GENERATED_C_CODE
76017 WUFFS_BASE__MAYBE_STATIC uint64_t
76018 wuffs_xxhash64__hasher__get_quirk(
76019 const wuffs_xxhash64__hasher* self,
76020 uint32_t a_key) {
76021 if (!self) {
76022 return 0;
76024 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
76025 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
76026 return 0;
76029 return 0u;
76032 // -------- func xxhash64.hasher.set_quirk
76034 WUFFS_BASE__GENERATED_C_CODE
76035 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
76036 wuffs_xxhash64__hasher__set_quirk(
76037 wuffs_xxhash64__hasher* self,
76038 uint32_t a_key,
76039 uint64_t a_value) {
76040 if (!self) {
76041 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
76043 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
76044 return wuffs_base__make_status(
76045 (self->private_impl.magic == WUFFS_BASE__DISABLED)
76046 ? wuffs_base__error__disabled_by_previous_error
76047 : wuffs_base__error__initialize_not_called);
76050 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
76053 // -------- func xxhash64.hasher.update
76055 WUFFS_BASE__GENERATED_C_CODE
76056 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
76057 wuffs_xxhash64__hasher__update(
76058 wuffs_xxhash64__hasher* self,
76059 wuffs_base__slice_u8 a_x) {
76060 if (!self) {
76061 return wuffs_base__make_empty_struct();
76063 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
76064 return wuffs_base__make_empty_struct();
76067 if ((self->private_impl.f_length_modulo_u64 == 0u) && ! self->private_impl.f_length_overflows_u64) {
76068 self->private_impl.f_v0 = 6983438078262162902u;
76069 self->private_impl.f_v1 = 14029467366897019727u;
76070 self->private_impl.f_v2 = 0u;
76071 self->private_impl.f_v3 = 7046029288634856825u;
76073 wuffs_xxhash64__hasher__up(self, a_x);
76074 return wuffs_base__make_empty_struct();
76077 // -------- func xxhash64.hasher.update_u64
76079 WUFFS_BASE__GENERATED_C_CODE
76080 WUFFS_BASE__MAYBE_STATIC uint64_t
76081 wuffs_xxhash64__hasher__update_u64(
76082 wuffs_xxhash64__hasher* self,
76083 wuffs_base__slice_u8 a_x) {
76084 if (!self) {
76085 return 0;
76087 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
76088 return 0;
76091 wuffs_xxhash64__hasher__update(self, a_x);
76092 return wuffs_xxhash64__hasher__checksum_u64(self);
76095 // -------- func xxhash64.hasher.up
76097 WUFFS_BASE__GENERATED_C_CODE
76098 static wuffs_base__empty_struct
76099 wuffs_xxhash64__hasher__up(
76100 wuffs_xxhash64__hasher* self,
76101 wuffs_base__slice_u8 a_x) {
76102 uint64_t v_new_lmu = 0;
76103 uint64_t v_buf_u64 = 0;
76104 uint32_t v_buf_len = 0;
76105 uint64_t v_v0 = 0;
76106 uint64_t v_v1 = 0;
76107 uint64_t v_v2 = 0;
76108 uint64_t v_v3 = 0;
76109 wuffs_base__slice_u8 v_p = {0};
76111 v_new_lmu = ((uint64_t)(self->private_impl.f_length_modulo_u64 + ((uint64_t)(a_x.len))));
76112 self->private_impl.f_length_overflows_u64 = ((v_new_lmu < self->private_impl.f_length_modulo_u64) || self->private_impl.f_length_overflows_u64);
76113 self->private_impl.f_length_modulo_u64 = v_new_lmu;
76114 while (true) {
76115 if (self->private_impl.f_buf_len >= 32u) {
76116 v_buf_u64 = (((uint64_t)(self->private_impl.f_buf_data[0u])) |
76117 (((uint64_t)(self->private_impl.f_buf_data[1u])) << 8u) |
76118 (((uint64_t)(self->private_impl.f_buf_data[2u])) << 16u) |
76119 (((uint64_t)(self->private_impl.f_buf_data[3u])) << 24u) |
76120 (((uint64_t)(self->private_impl.f_buf_data[4u])) << 32u) |
76121 (((uint64_t)(self->private_impl.f_buf_data[5u])) << 40u) |
76122 (((uint64_t)(self->private_impl.f_buf_data[6u])) << 48u) |
76123 (((uint64_t)(self->private_impl.f_buf_data[7u])) << 56u));
76124 v_v0 = ((uint64_t)(self->private_impl.f_v0 + ((uint64_t)(v_buf_u64 * 14029467366897019727u))));
76125 v_v0 = (((uint64_t)(v_v0 << 31u)) | (v_v0 >> 33u));
76126 self->private_impl.f_v0 = ((uint64_t)(v_v0 * 11400714785074694791u));
76127 v_buf_u64 = (((uint64_t)(self->private_impl.f_buf_data[8u])) |
76128 (((uint64_t)(self->private_impl.f_buf_data[9u])) << 8u) |
76129 (((uint64_t)(self->private_impl.f_buf_data[10u])) << 16u) |
76130 (((uint64_t)(self->private_impl.f_buf_data[11u])) << 24u) |
76131 (((uint64_t)(self->private_impl.f_buf_data[12u])) << 32u) |
76132 (((uint64_t)(self->private_impl.f_buf_data[13u])) << 40u) |
76133 (((uint64_t)(self->private_impl.f_buf_data[14u])) << 48u) |
76134 (((uint64_t)(self->private_impl.f_buf_data[15u])) << 56u));
76135 v_v1 = ((uint64_t)(self->private_impl.f_v1 + ((uint64_t)(v_buf_u64 * 14029467366897019727u))));
76136 v_v1 = (((uint64_t)(v_v1 << 31u)) | (v_v1 >> 33u));
76137 self->private_impl.f_v1 = ((uint64_t)(v_v1 * 11400714785074694791u));
76138 v_buf_u64 = (((uint64_t)(self->private_impl.f_buf_data[16u])) |
76139 (((uint64_t)(self->private_impl.f_buf_data[17u])) << 8u) |
76140 (((uint64_t)(self->private_impl.f_buf_data[18u])) << 16u) |
76141 (((uint64_t)(self->private_impl.f_buf_data[19u])) << 24u) |
76142 (((uint64_t)(self->private_impl.f_buf_data[20u])) << 32u) |
76143 (((uint64_t)(self->private_impl.f_buf_data[21u])) << 40u) |
76144 (((uint64_t)(self->private_impl.f_buf_data[22u])) << 48u) |
76145 (((uint64_t)(self->private_impl.f_buf_data[23u])) << 56u));
76146 v_v2 = ((uint64_t)(self->private_impl.f_v2 + ((uint64_t)(v_buf_u64 * 14029467366897019727u))));
76147 v_v2 = (((uint64_t)(v_v2 << 31u)) | (v_v2 >> 33u));
76148 self->private_impl.f_v2 = ((uint64_t)(v_v2 * 11400714785074694791u));
76149 v_buf_u64 = (((uint64_t)(self->private_impl.f_buf_data[24u])) |
76150 (((uint64_t)(self->private_impl.f_buf_data[25u])) << 8u) |
76151 (((uint64_t)(self->private_impl.f_buf_data[26u])) << 16u) |
76152 (((uint64_t)(self->private_impl.f_buf_data[27u])) << 24u) |
76153 (((uint64_t)(self->private_impl.f_buf_data[28u])) << 32u) |
76154 (((uint64_t)(self->private_impl.f_buf_data[29u])) << 40u) |
76155 (((uint64_t)(self->private_impl.f_buf_data[30u])) << 48u) |
76156 (((uint64_t)(self->private_impl.f_buf_data[31u])) << 56u));
76157 v_v3 = ((uint64_t)(self->private_impl.f_v3 + ((uint64_t)(v_buf_u64 * 14029467366897019727u))));
76158 v_v3 = (((uint64_t)(v_v3 << 31u)) | (v_v3 >> 33u));
76159 self->private_impl.f_v3 = ((uint64_t)(v_v3 * 11400714785074694791u));
76160 self->private_impl.f_buf_len = 0u;
76161 break;
76163 if (((uint64_t)(a_x.len)) <= 0u) {
76164 return wuffs_base__make_empty_struct();
76166 self->private_impl.f_buf_data[self->private_impl.f_buf_len] = a_x.ptr[0u];
76167 self->private_impl.f_buf_len += 1u;
76168 a_x = wuffs_base__slice_u8__subslice_i(a_x, 1u);
76170 v_buf_len = (self->private_impl.f_buf_len & 31u);
76171 v_v0 = self->private_impl.f_v0;
76172 v_v1 = self->private_impl.f_v1;
76173 v_v2 = self->private_impl.f_v2;
76174 v_v3 = self->private_impl.f_v3;
76176 wuffs_base__slice_u8 i_slice_p = a_x;
76177 v_p.ptr = i_slice_p.ptr;
76178 v_p.len = 32;
76179 const uint8_t* i_end0_p = wuffs_private_impl__ptr_u8_plus_len(v_p.ptr, (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 32) * 32));
76180 while (v_p.ptr < i_end0_p) {
76181 v_buf_u64 = (((uint64_t)(v_p.ptr[0u])) |
76182 (((uint64_t)(v_p.ptr[1u])) << 8u) |
76183 (((uint64_t)(v_p.ptr[2u])) << 16u) |
76184 (((uint64_t)(v_p.ptr[3u])) << 24u) |
76185 (((uint64_t)(v_p.ptr[4u])) << 32u) |
76186 (((uint64_t)(v_p.ptr[5u])) << 40u) |
76187 (((uint64_t)(v_p.ptr[6u])) << 48u) |
76188 (((uint64_t)(v_p.ptr[7u])) << 56u));
76189 v_v0 = ((uint64_t)(v_v0 + ((uint64_t)(v_buf_u64 * 14029467366897019727u))));
76190 v_v0 = (((uint64_t)(v_v0 << 31u)) | (v_v0 >> 33u));
76191 v_v0 = ((uint64_t)(v_v0 * 11400714785074694791u));
76192 v_buf_u64 = (((uint64_t)(v_p.ptr[8u])) |
76193 (((uint64_t)(v_p.ptr[9u])) << 8u) |
76194 (((uint64_t)(v_p.ptr[10u])) << 16u) |
76195 (((uint64_t)(v_p.ptr[11u])) << 24u) |
76196 (((uint64_t)(v_p.ptr[12u])) << 32u) |
76197 (((uint64_t)(v_p.ptr[13u])) << 40u) |
76198 (((uint64_t)(v_p.ptr[14u])) << 48u) |
76199 (((uint64_t)(v_p.ptr[15u])) << 56u));
76200 v_v1 = ((uint64_t)(v_v1 + ((uint64_t)(v_buf_u64 * 14029467366897019727u))));
76201 v_v1 = (((uint64_t)(v_v1 << 31u)) | (v_v1 >> 33u));
76202 v_v1 = ((uint64_t)(v_v1 * 11400714785074694791u));
76203 v_buf_u64 = (((uint64_t)(v_p.ptr[16u])) |
76204 (((uint64_t)(v_p.ptr[17u])) << 8u) |
76205 (((uint64_t)(v_p.ptr[18u])) << 16u) |
76206 (((uint64_t)(v_p.ptr[19u])) << 24u) |
76207 (((uint64_t)(v_p.ptr[20u])) << 32u) |
76208 (((uint64_t)(v_p.ptr[21u])) << 40u) |
76209 (((uint64_t)(v_p.ptr[22u])) << 48u) |
76210 (((uint64_t)(v_p.ptr[23u])) << 56u));
76211 v_v2 = ((uint64_t)(v_v2 + ((uint64_t)(v_buf_u64 * 14029467366897019727u))));
76212 v_v2 = (((uint64_t)(v_v2 << 31u)) | (v_v2 >> 33u));
76213 v_v2 = ((uint64_t)(v_v2 * 11400714785074694791u));
76214 v_buf_u64 = (((uint64_t)(v_p.ptr[24u])) |
76215 (((uint64_t)(v_p.ptr[25u])) << 8u) |
76216 (((uint64_t)(v_p.ptr[26u])) << 16u) |
76217 (((uint64_t)(v_p.ptr[27u])) << 24u) |
76218 (((uint64_t)(v_p.ptr[28u])) << 32u) |
76219 (((uint64_t)(v_p.ptr[29u])) << 40u) |
76220 (((uint64_t)(v_p.ptr[30u])) << 48u) |
76221 (((uint64_t)(v_p.ptr[31u])) << 56u));
76222 v_v3 = ((uint64_t)(v_v3 + ((uint64_t)(v_buf_u64 * 14029467366897019727u))));
76223 v_v3 = (((uint64_t)(v_v3 << 31u)) | (v_v3 >> 33u));
76224 v_v3 = ((uint64_t)(v_v3 * 11400714785074694791u));
76225 v_p.ptr += 32;
76227 v_p.len = 1;
76228 const uint8_t* i_end1_p = wuffs_private_impl__ptr_u8_plus_len(i_slice_p.ptr, i_slice_p.len);
76229 while (v_p.ptr < i_end1_p) {
76230 self->private_impl.f_buf_data[v_buf_len] = v_p.ptr[0u];
76231 v_buf_len = ((v_buf_len + 1u) & 31u);
76232 v_p.ptr += 1;
76234 v_p.len = 0;
76236 self->private_impl.f_buf_len = v_buf_len;
76237 self->private_impl.f_v0 = v_v0;
76238 self->private_impl.f_v1 = v_v1;
76239 self->private_impl.f_v2 = v_v2;
76240 self->private_impl.f_v3 = v_v3;
76241 return wuffs_base__make_empty_struct();
76244 // -------- func xxhash64.hasher.checksum_u64
76246 WUFFS_BASE__GENERATED_C_CODE
76247 WUFFS_BASE__MAYBE_STATIC uint64_t
76248 wuffs_xxhash64__hasher__checksum_u64(
76249 const wuffs_xxhash64__hasher* self) {
76250 if (!self) {
76251 return 0;
76253 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
76254 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
76255 return 0;
76258 uint64_t v_ret = 0;
76259 uint64_t v_v0 = 0;
76260 uint64_t v_v1 = 0;
76261 uint64_t v_v2 = 0;
76262 uint64_t v_v3 = 0;
76263 uint32_t v_i = 0;
76264 uint32_t v_i8 = 0;
76265 uint32_t v_n = 0;
76266 uint32_t v_buf_u32 = 0;
76267 uint64_t v_buf_u64 = 0;
76269 if ((self->private_impl.f_length_modulo_u64 >= 32u) || self->private_impl.f_length_overflows_u64) {
76270 v_ret += (((uint64_t)(self->private_impl.f_v0 << 1u)) | (self->private_impl.f_v0 >> 63u));
76271 v_ret += (((uint64_t)(self->private_impl.f_v1 << 7u)) | (self->private_impl.f_v1 >> 57u));
76272 v_ret += (((uint64_t)(self->private_impl.f_v2 << 12u)) | (self->private_impl.f_v2 >> 52u));
76273 v_ret += (((uint64_t)(self->private_impl.f_v3 << 18u)) | (self->private_impl.f_v3 >> 46u));
76274 v_v0 = ((uint64_t)(self->private_impl.f_v0 * 14029467366897019727u));
76275 v_v0 = (((uint64_t)(v_v0 << 31u)) | (v_v0 >> 33u));
76276 v_v0 *= 11400714785074694791u;
76277 v_v1 = ((uint64_t)(self->private_impl.f_v1 * 14029467366897019727u));
76278 v_v1 = (((uint64_t)(v_v1 << 31u)) | (v_v1 >> 33u));
76279 v_v1 *= 11400714785074694791u;
76280 v_v2 = ((uint64_t)(self->private_impl.f_v2 * 14029467366897019727u));
76281 v_v2 = (((uint64_t)(v_v2 << 31u)) | (v_v2 >> 33u));
76282 v_v2 *= 11400714785074694791u;
76283 v_v3 = ((uint64_t)(self->private_impl.f_v3 * 14029467366897019727u));
76284 v_v3 = (((uint64_t)(v_v3 << 31u)) | (v_v3 >> 33u));
76285 v_v3 *= 11400714785074694791u;
76286 v_ret = ((uint64_t)(((uint64_t)((v_ret ^ v_v0) * 11400714785074694791u)) + 9650029242287828579u));
76287 v_ret = ((uint64_t)(((uint64_t)((v_ret ^ v_v1) * 11400714785074694791u)) + 9650029242287828579u));
76288 v_ret = ((uint64_t)(((uint64_t)((v_ret ^ v_v2) * 11400714785074694791u)) + 9650029242287828579u));
76289 v_ret = ((uint64_t)(((uint64_t)((v_ret ^ v_v3) * 11400714785074694791u)) + 9650029242287828579u));
76290 v_ret += self->private_impl.f_length_modulo_u64;
76291 } else {
76292 v_ret += 2870177450012600261u;
76293 v_ret += self->private_impl.f_length_modulo_u64;
76295 v_n = 32u;
76296 v_n = wuffs_base__u32__min(v_n, self->private_impl.f_buf_len);
76297 if (8u <= v_n) {
76298 v_buf_u64 = (((uint64_t)(self->private_impl.f_buf_data[0u])) |
76299 (((uint64_t)(self->private_impl.f_buf_data[1u])) << 8u) |
76300 (((uint64_t)(self->private_impl.f_buf_data[2u])) << 16u) |
76301 (((uint64_t)(self->private_impl.f_buf_data[3u])) << 24u) |
76302 (((uint64_t)(self->private_impl.f_buf_data[4u])) << 32u) |
76303 (((uint64_t)(self->private_impl.f_buf_data[5u])) << 40u) |
76304 (((uint64_t)(self->private_impl.f_buf_data[6u])) << 48u) |
76305 (((uint64_t)(self->private_impl.f_buf_data[7u])) << 56u));
76306 v_buf_u64 *= 14029467366897019727u;
76307 v_buf_u64 = (((uint64_t)(v_buf_u64 << 31u)) | (v_buf_u64 >> 33u));
76308 v_buf_u64 *= 11400714785074694791u;
76309 v_ret ^= v_buf_u64;
76310 v_ret = (((uint64_t)(v_ret << 27u)) | (v_ret >> 37u));
76311 v_ret *= 11400714785074694791u;
76312 v_ret += 9650029242287828579u;
76313 v_i = 8u;
76315 if (16u <= v_n) {
76316 v_buf_u64 = (((uint64_t)(self->private_impl.f_buf_data[8u])) |
76317 (((uint64_t)(self->private_impl.f_buf_data[9u])) << 8u) |
76318 (((uint64_t)(self->private_impl.f_buf_data[10u])) << 16u) |
76319 (((uint64_t)(self->private_impl.f_buf_data[11u])) << 24u) |
76320 (((uint64_t)(self->private_impl.f_buf_data[12u])) << 32u) |
76321 (((uint64_t)(self->private_impl.f_buf_data[13u])) << 40u) |
76322 (((uint64_t)(self->private_impl.f_buf_data[14u])) << 48u) |
76323 (((uint64_t)(self->private_impl.f_buf_data[15u])) << 56u));
76324 v_buf_u64 *= 14029467366897019727u;
76325 v_buf_u64 = (((uint64_t)(v_buf_u64 << 31u)) | (v_buf_u64 >> 33u));
76326 v_buf_u64 *= 11400714785074694791u;
76327 v_ret ^= v_buf_u64;
76328 v_ret = (((uint64_t)(v_ret << 27u)) | (v_ret >> 37u));
76329 v_ret *= 11400714785074694791u;
76330 v_ret += 9650029242287828579u;
76331 v_i = 16u;
76333 if (24u <= v_n) {
76334 v_buf_u64 = (((uint64_t)(self->private_impl.f_buf_data[16u])) |
76335 (((uint64_t)(self->private_impl.f_buf_data[17u])) << 8u) |
76336 (((uint64_t)(self->private_impl.f_buf_data[18u])) << 16u) |
76337 (((uint64_t)(self->private_impl.f_buf_data[19u])) << 24u) |
76338 (((uint64_t)(self->private_impl.f_buf_data[20u])) << 32u) |
76339 (((uint64_t)(self->private_impl.f_buf_data[21u])) << 40u) |
76340 (((uint64_t)(self->private_impl.f_buf_data[22u])) << 48u) |
76341 (((uint64_t)(self->private_impl.f_buf_data[23u])) << 56u));
76342 v_buf_u64 *= 14029467366897019727u;
76343 v_buf_u64 = (((uint64_t)(v_buf_u64 << 31u)) | (v_buf_u64 >> 33u));
76344 v_buf_u64 *= 11400714785074694791u;
76345 v_ret ^= v_buf_u64;
76346 v_ret = (((uint64_t)(v_ret << 27u)) | (v_ret >> 37u));
76347 v_ret *= 11400714785074694791u;
76348 v_ret += 9650029242287828579u;
76349 v_i = 24u;
76351 if ((v_n & 4u) != 0u) {
76352 v_i8 = (v_i & 24u);
76353 v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[(v_i8 + 0u)])) |
76354 (((uint32_t)(self->private_impl.f_buf_data[(v_i8 + 1u)])) << 8u) |
76355 (((uint32_t)(self->private_impl.f_buf_data[(v_i8 + 2u)])) << 16u) |
76356 (((uint32_t)(self->private_impl.f_buf_data[(v_i8 + 3u)])) << 24u));
76357 v_ret ^= ((uint64_t)(((uint64_t)(v_buf_u32)) * 11400714785074694791u));
76358 v_ret = (((uint64_t)(v_ret << 23u)) | (v_ret >> 41u));
76359 v_ret *= 14029467366897019727u;
76360 v_ret += 1609587929392839161u;
76361 v_i = (v_i8 + 4u);
76363 while (v_i < v_n) {
76364 v_ret ^= ((uint64_t)(((uint64_t)(self->private_impl.f_buf_data[v_i])) * 2870177450012600261u));
76365 v_ret = (((uint64_t)(v_ret << 11u)) | (v_ret >> 53u));
76366 v_ret *= 11400714785074694791u;
76367 v_i += 1u;
76369 v_ret ^= (v_ret >> 33u);
76370 v_ret *= 14029467366897019727u;
76371 v_ret ^= (v_ret >> 29u);
76372 v_ret *= 1609587929392839161u;
76373 v_ret ^= (v_ret >> 32u);
76374 return ((uint64_t)(v_ret));
76377 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH64)
76379 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XZ)
76381 // ---------------- Status Codes Implementations
76383 const char wuffs_xz__error__bad_bcj_offset[] = "#xz: bad BCJ offset";
76384 const char wuffs_xz__error__bad_block_header[] = "#xz: bad block header";
76385 const char wuffs_xz__error__bad_checksum[] = "#xz: bad checksum";
76386 const char wuffs_xz__error__bad_filter[] = "#xz: bad filter";
76387 const char wuffs_xz__error__bad_footer[] = "#xz: bad footer";
76388 const char wuffs_xz__error__bad_header[] = "#xz: bad header";
76389 const char wuffs_xz__error__bad_header_concatenated_stream[] = "#xz: bad header (concatenated stream)";
76390 const char wuffs_xz__error__bad_index[] = "#xz: bad index";
76391 const char wuffs_xz__error__bad_padding[] = "#xz: bad padding";
76392 const char wuffs_xz__error__truncated_input[] = "#xz: truncated input";
76393 const char wuffs_xz__error__unsupported_checksum_algorithm[] = "#xz: unsupported checksum algorithm";
76394 const char wuffs_xz__error__unsupported_filter[] = "#xz: unsupported filter";
76395 const char wuffs_xz__error__unsupported_filter_combination[] = "#xz: unsupported filter combination";
76396 const char wuffs_xz__error__internal_error_inconsistent_bcj_filter_state[] = "#xz: internal error: inconsistent BCJ filter state";
76398 // ---------------- Private Consts
76400 static const bool
76401 WUFFS_XZ__FILTER_04_X86_MASK_TO_ALLOWED_STATUS[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
76402 1u, 1u, 1u, 0u, 1u, 0u, 0u, 0u,
76405 static const uint8_t
76406 WUFFS_XZ__FILTER_04_X86_MASK_TO_BIT_NUM[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
76407 0u, 1u, 2u, 2u, 3u, 3u, 3u, 3u,
76410 static const uint32_t
76411 WUFFS_XZ__FILTER_04_X86_MASK_TO_XOR_OPERAND[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
76412 4294967295u, 16777215u, 65535u, 65535u, 255u, 255u, 255u, 255u,
76415 static const uint8_t
76416 WUFFS_XZ__FILTER_06_IA64_BRANCH_TABLE[32] WUFFS_BASE__POTENTIALLY_UNUSED = {
76417 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
76418 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
76419 4u, 4u, 6u, 6u, 0u, 0u, 7u, 7u,
76420 4u, 4u, 0u, 0u, 4u, 4u, 0u, 0u,
76423 #define WUFFS_XZ__QUIRKS_BASE 2021322752u
76425 static const uint8_t
76426 WUFFS_XZ__CHECKSUM_LENGTH[4] WUFFS_BASE__POTENTIALLY_UNUSED = {
76427 0u, 4u, 8u, 32u,
76430 static const uint8_t
76431 WUFFS_XZ__ZEROES[3] WUFFS_BASE__POTENTIALLY_UNUSED = {
76432 0u, 0u, 0u,
76435 static const uint8_t
76436 WUFFS_XZ__BCJ_OFFSET_ALIGNMENT[12] WUFFS_BASE__POTENTIALLY_UNUSED = {
76437 0u, 0u, 0u, 0u, 1u, 4u, 16u, 4u,
76438 2u, 4u, 4u, 2u,
76441 // ---------------- Private Initializer Prototypes
76443 // ---------------- Private Function Prototypes
76445 WUFFS_BASE__GENERATED_C_CODE
76446 static uint8_t
76447 wuffs_xz__decoder__apply_non_final_filters(
76448 wuffs_xz__decoder* self,
76449 wuffs_base__slice_u8 a_dst_slice);
76451 WUFFS_BASE__GENERATED_C_CODE
76452 static uint8_t
76453 wuffs_xz__decoder__apply_non_final_filters__choosy_default(
76454 wuffs_xz__decoder* self,
76455 wuffs_base__slice_u8 a_dst_slice);
76457 WUFFS_BASE__GENERATED_C_CODE
76458 static uint8_t
76459 wuffs_xz__decoder__apply_filter_04_x86(
76460 wuffs_xz__decoder* self,
76461 wuffs_base__slice_u8 a_dst_slice);
76463 WUFFS_BASE__GENERATED_C_CODE
76464 static uint8_t
76465 wuffs_xz__decoder__apply_filter_05_powerpc(
76466 wuffs_xz__decoder* self,
76467 wuffs_base__slice_u8 a_dst_slice);
76469 WUFFS_BASE__GENERATED_C_CODE
76470 static uint8_t
76471 wuffs_xz__decoder__apply_filter_06_ia64(
76472 wuffs_xz__decoder* self,
76473 wuffs_base__slice_u8 a_dst_slice);
76475 WUFFS_BASE__GENERATED_C_CODE
76476 static uint8_t
76477 wuffs_xz__decoder__apply_filter_07_arm(
76478 wuffs_xz__decoder* self,
76479 wuffs_base__slice_u8 a_dst_slice);
76481 WUFFS_BASE__GENERATED_C_CODE
76482 static uint8_t
76483 wuffs_xz__decoder__apply_filter_08_armthumb(
76484 wuffs_xz__decoder* self,
76485 wuffs_base__slice_u8 a_dst_slice);
76487 WUFFS_BASE__GENERATED_C_CODE
76488 static uint8_t
76489 wuffs_xz__decoder__apply_filter_09_sparc(
76490 wuffs_xz__decoder* self,
76491 wuffs_base__slice_u8 a_dst_slice);
76493 WUFFS_BASE__GENERATED_C_CODE
76494 static uint8_t
76495 wuffs_xz__decoder__apply_filter_0a_arm64(
76496 wuffs_xz__decoder* self,
76497 wuffs_base__slice_u8 a_dst_slice);
76499 WUFFS_BASE__GENERATED_C_CODE
76500 static uint8_t
76501 wuffs_xz__decoder__apply_filter_0b_riscv(
76502 wuffs_xz__decoder* self,
76503 wuffs_base__slice_u8 a_dst_slice);
76505 WUFFS_BASE__GENERATED_C_CODE
76506 static wuffs_base__status
76507 wuffs_xz__decoder__do_transform_io(
76508 wuffs_xz__decoder* self,
76509 wuffs_base__io_buffer* a_dst,
76510 wuffs_base__io_buffer* a_src,
76511 wuffs_base__slice_u8 a_workbuf);
76513 WUFFS_BASE__GENERATED_C_CODE
76514 static wuffs_base__status
76515 wuffs_xz__decoder__decode_block_header_with_padding(
76516 wuffs_xz__decoder* self,
76517 wuffs_base__io_buffer* a_src);
76519 WUFFS_BASE__GENERATED_C_CODE
76520 static wuffs_base__status
76521 wuffs_xz__decoder__decode_block_header_sans_padding(
76522 wuffs_xz__decoder* self,
76523 wuffs_base__io_buffer* a_src);
76525 WUFFS_BASE__GENERATED_C_CODE
76526 static wuffs_base__status
76527 wuffs_xz__decoder__verify_index(
76528 wuffs_xz__decoder* self,
76529 wuffs_base__io_buffer* a_src);
76531 WUFFS_BASE__GENERATED_C_CODE
76532 static wuffs_base__status
76533 wuffs_xz__decoder__verify_footer(
76534 wuffs_xz__decoder* self,
76535 wuffs_base__io_buffer* a_src);
76537 // ---------------- VTables
76539 const wuffs_base__io_transformer__func_ptrs
76540 wuffs_xz__decoder__func_ptrs_for__wuffs_base__io_transformer = {
76541 (wuffs_base__optional_u63(*)(const void*))(&wuffs_xz__decoder__dst_history_retain_length),
76542 (uint64_t(*)(const void*,
76543 uint32_t))(&wuffs_xz__decoder__get_quirk),
76544 (wuffs_base__status(*)(void*,
76545 uint32_t,
76546 uint64_t))(&wuffs_xz__decoder__set_quirk),
76547 (wuffs_base__status(*)(void*,
76548 wuffs_base__io_buffer*,
76549 wuffs_base__io_buffer*,
76550 wuffs_base__slice_u8))(&wuffs_xz__decoder__transform_io),
76551 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_xz__decoder__workbuf_len),
76554 // ---------------- Initializer Implementations
76556 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
76557 wuffs_xz__decoder__initialize(
76558 wuffs_xz__decoder* self,
76559 size_t sizeof_star_self,
76560 uint64_t wuffs_version,
76561 uint32_t options){
76562 if (!self) {
76563 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
76565 if (sizeof(*self) != sizeof_star_self) {
76566 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
76568 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
76569 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
76570 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
76573 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
76574 // The whole point of this if-check is to detect an uninitialized *self.
76575 // We disable the warning on GCC. Clang-5.0 does not have this warning.
76576 #if !defined(__clang__) && defined(__GNUC__)
76577 #pragma GCC diagnostic push
76578 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
76579 #endif
76580 if (self->private_impl.magic != 0) {
76581 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
76583 #if !defined(__clang__) && defined(__GNUC__)
76584 #pragma GCC diagnostic pop
76585 #endif
76586 } else {
76587 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
76588 memset(self, 0, sizeof(*self));
76589 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
76590 } else {
76591 memset(&(self->private_impl), 0, sizeof(self->private_impl));
76595 self->private_impl.choosy_apply_non_final_filters = &wuffs_xz__decoder__apply_non_final_filters__choosy_default;
76598 wuffs_base__status z = wuffs_crc32__ieee_hasher__initialize(
76599 &self->private_data.f_crc32, sizeof(self->private_data.f_crc32), WUFFS_VERSION, options);
76600 if (z.repr) {
76601 return z;
76605 wuffs_base__status z = wuffs_crc64__ecma_hasher__initialize(
76606 &self->private_data.f_crc64, sizeof(self->private_data.f_crc64), WUFFS_VERSION, options);
76607 if (z.repr) {
76608 return z;
76612 wuffs_base__status z = wuffs_sha256__hasher__initialize(
76613 &self->private_data.f_sha256, sizeof(self->private_data.f_sha256), WUFFS_VERSION, options);
76614 if (z.repr) {
76615 return z;
76619 wuffs_base__status z = wuffs_lzma__decoder__initialize(
76620 &self->private_data.f_lzma, sizeof(self->private_data.f_lzma), WUFFS_VERSION, options);
76621 if (z.repr) {
76622 return z;
76625 self->private_impl.magic = WUFFS_BASE__MAGIC;
76626 self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name =
76627 wuffs_base__io_transformer__vtable_name;
76628 self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers =
76629 (const void*)(&wuffs_xz__decoder__func_ptrs_for__wuffs_base__io_transformer);
76630 return wuffs_base__make_status(NULL);
76633 wuffs_xz__decoder*
76634 wuffs_xz__decoder__alloc(void) {
76635 wuffs_xz__decoder* x =
76636 (wuffs_xz__decoder*)(calloc(1, sizeof(wuffs_xz__decoder)));
76637 if (!x) {
76638 return NULL;
76640 if (wuffs_xz__decoder__initialize(
76641 x, sizeof(wuffs_xz__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
76642 free(x);
76643 return NULL;
76645 return x;
76648 size_t
76649 sizeof__wuffs_xz__decoder(void) {
76650 return sizeof(wuffs_xz__decoder);
76653 // ---------------- Function Implementations
76655 // -------- func xz.decoder.apply_non_final_filters
76657 WUFFS_BASE__GENERATED_C_CODE
76658 static uint8_t
76659 wuffs_xz__decoder__apply_non_final_filters(
76660 wuffs_xz__decoder* self,
76661 wuffs_base__slice_u8 a_dst_slice) {
76662 return (*self->private_impl.choosy_apply_non_final_filters)(self, a_dst_slice);
76665 WUFFS_BASE__GENERATED_C_CODE
76666 static uint8_t
76667 wuffs_xz__decoder__apply_non_final_filters__choosy_default(
76668 wuffs_xz__decoder* self,
76669 wuffs_base__slice_u8 a_dst_slice) {
76670 uint32_t v_f = 0;
76671 uint64_t v_i = 0;
76672 uint32_t v_filter_id = 0;
76673 uint32_t v_delta_dist = 0;
76674 uint32_t v_delta_pos = 0;
76675 uint8_t v_c8 = 0;
76677 if (self->private_impl.f_num_non_final_filters <= 0u) {
76678 return 0u;
76680 v_f = (self->private_impl.f_num_non_final_filters - 1u);
76681 while (true) {
76682 v_filter_id = (self->private_impl.f_filters[v_f] & 127u);
76683 if (v_filter_id == 3u) {
76684 v_delta_dist = (((self->private_impl.f_filters[v_f] >> 8u) & 255u) + 1u);
76685 v_delta_pos = (self->private_impl.f_filters[v_f] >> 24u);
76686 v_i = 0u;
76687 while (v_i < ((uint64_t)(a_dst_slice.len))) {
76688 v_c8 = a_dst_slice.ptr[v_i];
76689 #if defined(__GNUC__)
76690 #pragma GCC diagnostic push
76691 #pragma GCC diagnostic ignored "-Wconversion"
76692 #endif
76693 v_c8 += self->private_data.f_filter_data[v_f][(((uint32_t)(v_delta_dist + v_delta_pos)) & 255u)];
76694 #if defined(__GNUC__)
76695 #pragma GCC diagnostic pop
76696 #endif
76697 self->private_data.f_filter_data[v_f][(v_delta_pos & 255u)] = v_c8;
76698 v_delta_pos -= 1u;
76699 a_dst_slice.ptr[v_i] = v_c8;
76700 v_i += 1u;
76702 self->private_impl.f_filters[v_f] &= 65535u;
76703 self->private_impl.f_filters[v_f] |= ((uint32_t)(v_delta_pos << 24u));
76705 if (v_f <= 0u) {
76706 break;
76708 v_f -= 1u;
76710 return 0u;
76713 // -------- func xz.decoder.apply_filter_04_x86
76715 WUFFS_BASE__GENERATED_C_CODE
76716 static uint8_t
76717 wuffs_xz__decoder__apply_filter_04_x86(
76718 wuffs_xz__decoder* self,
76719 wuffs_base__slice_u8 a_dst_slice) {
76720 wuffs_base__slice_u8 v_s = {0};
76721 uint32_t v_p = 0;
76722 uint64_t v_i = 0;
76723 uint64_t v_prev_pos = 0;
76724 uint32_t v_prev_mask = 0;
76725 uint8_t v_c8 = 0;
76726 uint32_t v_src = 0;
76727 uint32_t v_dst = 0;
76728 uint32_t v_bit_num = 0;
76730 v_s = a_dst_slice;
76731 v_p = ((uint32_t)(self->private_impl.f_bcj_pos + 5u));
76732 v_prev_pos = 18446744073709551615u;
76733 v_prev_mask = self->private_impl.f_bcj_x86_prev_mask;
76734 while (((uint64_t)(v_s.len)) >= 5u) {
76735 if (((uint8_t)(v_s.ptr[0u] & 254u)) != 232u) {
76736 v_i += 1u;
76737 v_p += 1u;
76738 v_s = wuffs_base__slice_u8__subslice_i(v_s, 1u);
76739 continue;
76741 v_prev_pos = ((uint64_t)(v_i - v_prev_pos));
76742 if (v_prev_pos > 3u) {
76743 v_prev_mask = 0u;
76744 } else if (v_prev_pos > 0u) {
76745 v_prev_mask = (((uint32_t)(v_prev_mask << (v_prev_pos - 1u))) & 7u);
76746 if (v_prev_mask != 0u) {
76747 v_c8 = v_s.ptr[((uint8_t)(4u - WUFFS_XZ__FILTER_04_X86_MASK_TO_BIT_NUM[(v_prev_mask & 7u)]))];
76748 if ( ! WUFFS_XZ__FILTER_04_X86_MASK_TO_ALLOWED_STATUS[(v_prev_mask & 7u)] || (v_c8 == 0u) || (v_c8 == 255u)) {
76749 v_prev_pos = v_i;
76750 v_prev_mask = (((uint32_t)(v_prev_mask << 1u)) | 1u);
76751 v_i += 1u;
76752 v_p += 1u;
76753 v_s = wuffs_base__slice_u8__subslice_i(v_s, 1u);
76754 continue;
76758 v_prev_pos = v_i;
76759 v_c8 = v_s.ptr[4u];
76760 if ((v_c8 != 0u) && (v_c8 != 255u)) {
76761 v_prev_mask = (((uint32_t)(v_prev_mask << 1u)) | 1u);
76762 v_i += 1u;
76763 v_p += 1u;
76764 v_s = wuffs_base__slice_u8__subslice_i(v_s, 1u);
76765 continue;
76767 v_src = ((((uint32_t)(v_s.ptr[1u])) << 0u) |
76768 (((uint32_t)(v_s.ptr[2u])) << 8u) |
76769 (((uint32_t)(v_s.ptr[3u])) << 16u) |
76770 (((uint32_t)(v_s.ptr[4u])) << 24u));
76771 while (true) {
76772 v_dst = ((uint32_t)(v_src - v_p));
76773 if (v_prev_mask == 0u) {
76774 break;
76776 v_bit_num = ((uint32_t)(WUFFS_XZ__FILTER_04_X86_MASK_TO_BIT_NUM[(v_prev_mask & 7u)]));
76777 v_c8 = ((uint8_t)((v_dst >> (24u - (v_bit_num * 8u)))));
76778 if ((v_c8 != 0u) && (v_c8 != 255u)) {
76779 break;
76781 v_src = (v_dst ^ WUFFS_XZ__FILTER_04_X86_MASK_TO_XOR_OPERAND[(v_prev_mask & 7u)]);
76783 v_dst &= 33554431u;
76784 v_dst |= ((uint32_t)(0u - (v_dst & 16777216u)));
76785 v_s.ptr[1u] = ((uint8_t)((v_dst >> 0u)));
76786 v_s.ptr[2u] = ((uint8_t)((v_dst >> 8u)));
76787 v_s.ptr[3u] = ((uint8_t)((v_dst >> 16u)));
76788 v_s.ptr[4u] = ((uint8_t)((v_dst >> 24u)));
76789 v_i += 5u;
76790 v_p += 5u;
76791 v_s = wuffs_base__slice_u8__subslice_i(v_s, 5u);
76793 v_prev_pos = ((uint64_t)(v_i - v_prev_pos));
76794 if (v_prev_pos > 3u) {
76795 self->private_impl.f_bcj_x86_prev_mask = 0u;
76796 } else if (v_prev_pos > 0u) {
76797 self->private_impl.f_bcj_x86_prev_mask = ((uint32_t)(v_prev_mask << (v_prev_pos - 1u)));
76799 self->private_impl.f_bcj_pos = ((uint32_t)(v_p - 5u));
76800 return ((uint8_t)(((uint64_t)(v_s.len))));
76803 // -------- func xz.decoder.apply_filter_05_powerpc
76805 WUFFS_BASE__GENERATED_C_CODE
76806 static uint8_t
76807 wuffs_xz__decoder__apply_filter_05_powerpc(
76808 wuffs_xz__decoder* self,
76809 wuffs_base__slice_u8 a_dst_slice) {
76810 wuffs_base__slice_u8 v_s = {0};
76811 uint32_t v_p = 0;
76812 uint32_t v_x = 0;
76814 v_s = a_dst_slice;
76815 v_p = self->private_impl.f_bcj_pos;
76816 while (((uint64_t)(v_s.len)) >= 4u) {
76817 v_x = ((((uint32_t)(v_s.ptr[0u])) << 24u) |
76818 (((uint32_t)(v_s.ptr[1u])) << 16u) |
76819 (((uint32_t)(v_s.ptr[2u])) << 8u) |
76820 (((uint32_t)(v_s.ptr[3u])) << 0u));
76821 if ((v_x & 4227858435u) == 1207959553u) {
76822 v_x = ((((uint32_t)((v_x & 67108860u) - v_p)) & 67108860u) | 1207959553u);
76823 v_s.ptr[0u] = ((uint8_t)((v_x >> 24u)));
76824 v_s.ptr[1u] = ((uint8_t)((v_x >> 16u)));
76825 v_s.ptr[2u] = ((uint8_t)((v_x >> 8u)));
76826 v_s.ptr[3u] = ((uint8_t)((v_x >> 0u)));
76828 v_p += 4u;
76829 v_s = wuffs_base__slice_u8__subslice_i(v_s, 4u);
76831 self->private_impl.f_bcj_pos = v_p;
76832 return ((uint8_t)(((uint64_t)(v_s.len))));
76835 // -------- func xz.decoder.apply_filter_06_ia64
76837 WUFFS_BASE__GENERATED_C_CODE
76838 static uint8_t
76839 wuffs_xz__decoder__apply_filter_06_ia64(
76840 wuffs_xz__decoder* self,
76841 wuffs_base__slice_u8 a_dst_slice) {
76842 wuffs_base__slice_u8 v_s = {0};
76843 uint32_t v_p = 0;
76844 uint32_t v_mask = 0;
76845 uint32_t v_slot = 0;
76846 uint32_t v_bit_pos = 0;
76847 uint32_t v_byte_pos = 0;
76848 uint32_t v_bit_res = 0;
76849 uint64_t v_x = 0;
76850 uint32_t v_j = 0;
76851 uint64_t v_norm = 0;
76852 uint32_t v_addr = 0;
76854 v_s = a_dst_slice;
76855 v_p = self->private_impl.f_bcj_pos;
76856 while (((uint64_t)(v_s.len)) >= 16u) {
76857 v_mask = ((uint32_t)(WUFFS_XZ__FILTER_06_IA64_BRANCH_TABLE[((uint8_t)(v_s.ptr[0u] & 31u))]));
76858 v_slot = 0u;
76859 while (true) {
76860 do {
76861 if (((v_mask >> v_slot) & 1u) == 0u) {
76862 break;
76864 v_bit_pos = ((v_slot * 41u) + 5u);
76865 v_byte_pos = (v_bit_pos >> 3u);
76866 v_bit_res = (v_bit_pos & 7u);
76867 v_x = 0u;
76868 v_j = 0u;
76869 while (v_j < 6u) {
76870 v_x |= (((uint64_t)(v_s.ptr[(v_j + v_byte_pos)])) << (8u * v_j));
76871 v_j += 1u;
76873 v_norm = (v_x >> v_bit_res);
76874 if ((((v_norm >> 37u) & 15u) != 5u) || (((v_norm >> 9u) & 7u) != 0u)) {
76875 break;
76877 v_addr = ((uint32_t)(((v_norm >> 13u) & 1048575u)));
76878 v_addr |= (((uint32_t)(((v_norm >> 36u) & 1u))) << 20u);
76879 v_addr <<= 4u;
76880 v_addr -= v_p;
76881 v_addr >>= 4u;
76882 v_norm &= 18446743996400148479u;
76883 v_norm |= (((uint64_t)((v_addr & 1048575u))) << 13u);
76884 v_norm |= (((uint64_t)((v_addr & 1048576u))) << 16u);
76885 v_x &= ((((uint64_t)(1u)) << v_bit_res) - 1u);
76886 v_x |= ((uint64_t)(v_norm << v_bit_res));
76887 v_j = 0u;
76888 while (v_j < 6u) {
76889 v_s.ptr[(v_j + v_byte_pos)] = ((uint8_t)((v_x >> (8u * v_j))));
76890 v_j += 1u;
76892 } while (0);
76893 if (v_slot >= 2u) {
76894 break;
76896 v_slot += 1u;
76898 v_p += 16u;
76899 v_s = wuffs_base__slice_u8__subslice_i(v_s, 16u);
76901 self->private_impl.f_bcj_pos = v_p;
76902 return ((uint8_t)(((uint64_t)(v_s.len))));
76905 // -------- func xz.decoder.apply_filter_07_arm
76907 WUFFS_BASE__GENERATED_C_CODE
76908 static uint8_t
76909 wuffs_xz__decoder__apply_filter_07_arm(
76910 wuffs_xz__decoder* self,
76911 wuffs_base__slice_u8 a_dst_slice) {
76912 wuffs_base__slice_u8 v_s = {0};
76913 uint32_t v_p = 0;
76914 uint32_t v_x = 0;
76916 v_s = a_dst_slice;
76917 v_p = ((uint32_t)(self->private_impl.f_bcj_pos + 8u));
76918 while (((uint64_t)(v_s.len)) >= 4u) {
76919 if (v_s.ptr[3u] == 235u) {
76920 v_x = ((((uint32_t)(v_s.ptr[0u])) << 0u) |
76921 (((uint32_t)(v_s.ptr[1u])) << 8u) |
76922 (((uint32_t)(v_s.ptr[2u])) << 16u) |
76923 (((uint32_t)(v_s.ptr[3u])) << 24u));
76924 v_x = (((uint32_t)(((v_x & 16777215u) << 2u) - v_p)) >> 2u);
76925 v_s.ptr[0u] = ((uint8_t)((v_x >> 0u)));
76926 v_s.ptr[1u] = ((uint8_t)((v_x >> 8u)));
76927 v_s.ptr[2u] = ((uint8_t)((v_x >> 16u)));
76929 v_p += 4u;
76930 v_s = wuffs_base__slice_u8__subslice_i(v_s, 4u);
76932 self->private_impl.f_bcj_pos = ((uint32_t)(v_p - 8u));
76933 return ((uint8_t)(((uint64_t)(v_s.len))));
76936 // -------- func xz.decoder.apply_filter_08_armthumb
76938 WUFFS_BASE__GENERATED_C_CODE
76939 static uint8_t
76940 wuffs_xz__decoder__apply_filter_08_armthumb(
76941 wuffs_xz__decoder* self,
76942 wuffs_base__slice_u8 a_dst_slice) {
76943 wuffs_base__slice_u8 v_s = {0};
76944 uint32_t v_p = 0;
76945 uint32_t v_x = 0;
76946 uint32_t v_y = 0;
76948 v_s = a_dst_slice;
76949 v_p = ((uint32_t)(self->private_impl.f_bcj_pos + 4u));
76950 while (((uint64_t)(v_s.len)) >= 4u) {
76951 v_x = ((((uint32_t)(v_s.ptr[0u])) << 0u) |
76952 (((uint32_t)(v_s.ptr[1u])) << 8u) |
76953 (((uint32_t)(v_s.ptr[2u])) << 16u) |
76954 (((uint32_t)(v_s.ptr[3u])) << 24u));
76955 if ((v_x & 4160813056u) != 4160811008u) {
76956 v_p += 2u;
76957 v_s = wuffs_base__slice_u8__subslice_i(v_s, 2u);
76958 continue;
76960 v_y = ((((uint32_t)(((uint8_t)(v_s.ptr[0u] & 255u)))) << 11u) |
76961 (((uint32_t)(((uint8_t)(v_s.ptr[1u] & 7u)))) << 19u) |
76962 (((uint32_t)(((uint8_t)(v_s.ptr[2u] & 255u)))) << 0u) |
76963 (((uint32_t)(((uint8_t)(v_s.ptr[3u] & 7u)))) << 8u));
76964 v_y = (((uint32_t)(((uint32_t)(v_y << 1u)) - v_p)) >> 1u);
76965 v_s.ptr[0u] = ((uint8_t)((v_y >> 11u)));
76966 v_s.ptr[1u] = ((uint8_t)((((v_y >> 19u) & 7u) | 240u)));
76967 v_s.ptr[2u] = ((uint8_t)((v_y >> 0u)));
76968 v_s.ptr[3u] = ((uint8_t)((((v_y >> 8u) & 7u) | 248u)));
76969 v_p += 4u;
76970 v_s = wuffs_base__slice_u8__subslice_i(v_s, 4u);
76972 self->private_impl.f_bcj_pos = ((uint32_t)(v_p - 4u));
76973 return ((uint8_t)(((uint64_t)(v_s.len))));
76976 // -------- func xz.decoder.apply_filter_09_sparc
76978 WUFFS_BASE__GENERATED_C_CODE
76979 static uint8_t
76980 wuffs_xz__decoder__apply_filter_09_sparc(
76981 wuffs_xz__decoder* self,
76982 wuffs_base__slice_u8 a_dst_slice) {
76983 wuffs_base__slice_u8 v_s = {0};
76984 uint32_t v_p = 0;
76985 uint32_t v_x = 0;
76987 v_s = a_dst_slice;
76988 v_p = self->private_impl.f_bcj_pos;
76989 while (((uint64_t)(v_s.len)) >= 4u) {
76990 v_x = ((((uint32_t)(v_s.ptr[0u])) << 24u) |
76991 (((uint32_t)(v_s.ptr[1u])) << 16u) |
76992 (((uint32_t)(v_s.ptr[2u])) << 8u) |
76993 (((uint32_t)(v_s.ptr[3u])) << 0u));
76994 if (((v_x >> 22u) == 256u) || ((v_x >> 22u) == 511u)) {
76995 v_x = (((uint32_t)(((uint32_t)(v_x << 2u)) - v_p)) >> 2u);
76996 v_x = ((1073741824u - (v_x & 4194304u)) | 1073741824u | (v_x & 4194303u));
76997 v_s.ptr[0u] = ((uint8_t)((v_x >> 24u)));
76998 v_s.ptr[1u] = ((uint8_t)((v_x >> 16u)));
76999 v_s.ptr[2u] = ((uint8_t)((v_x >> 8u)));
77000 v_s.ptr[3u] = ((uint8_t)((v_x >> 0u)));
77002 v_p += 4u;
77003 v_s = wuffs_base__slice_u8__subslice_i(v_s, 4u);
77005 self->private_impl.f_bcj_pos = v_p;
77006 return ((uint8_t)(((uint64_t)(v_s.len))));
77009 // -------- func xz.decoder.apply_filter_0a_arm64
77011 WUFFS_BASE__GENERATED_C_CODE
77012 static uint8_t
77013 wuffs_xz__decoder__apply_filter_0a_arm64(
77014 wuffs_xz__decoder* self,
77015 wuffs_base__slice_u8 a_dst_slice) {
77016 wuffs_base__slice_u8 v_s = {0};
77017 uint32_t v_p = 0;
77018 uint32_t v_x = 0;
77019 uint32_t v_y = 0;
77021 v_s = a_dst_slice;
77022 v_p = self->private_impl.f_bcj_pos;
77023 while (((uint64_t)(v_s.len)) >= 4u) {
77024 v_x = ((((uint32_t)(v_s.ptr[0u])) << 0u) |
77025 (((uint32_t)(v_s.ptr[1u])) << 8u) |
77026 (((uint32_t)(v_s.ptr[2u])) << 16u) |
77027 (((uint32_t)(v_s.ptr[3u])) << 24u));
77028 if ((v_x >> 26u) == 37u) {
77029 v_y = ((uint32_t)(v_x - (v_p >> 2u)));
77030 v_x = (2483027968u | (v_y & 67108863u));
77031 v_s.ptr[0u] = ((uint8_t)((v_x >> 0u)));
77032 v_s.ptr[1u] = ((uint8_t)((v_x >> 8u)));
77033 v_s.ptr[2u] = ((uint8_t)((v_x >> 16u)));
77034 v_s.ptr[3u] = ((uint8_t)((v_x >> 24u)));
77035 } else if ((v_x & 2667577344u) == 2415919104u) {
77036 v_y = (((v_x >> 29u) & 3u) | ((v_x >> 3u) & 2097148u));
77037 if ((((uint32_t)(v_y + 131072u)) & 1835008u) == 0u) {
77038 v_y -= (v_p >> 12u);
77039 v_x &= 2415919135u;
77040 v_x |= ((v_y & 3u) << 29u);
77041 v_x |= ((v_y & 262140u) << 3u);
77042 v_x |= (((uint32_t)(0u - (v_y & 131072u))) & 14680064u);
77043 v_s.ptr[0u] = ((uint8_t)((v_x >> 0u)));
77044 v_s.ptr[1u] = ((uint8_t)((v_x >> 8u)));
77045 v_s.ptr[2u] = ((uint8_t)((v_x >> 16u)));
77046 v_s.ptr[3u] = ((uint8_t)((v_x >> 24u)));
77049 v_p += 4u;
77050 v_s = wuffs_base__slice_u8__subslice_i(v_s, 4u);
77052 self->private_impl.f_bcj_pos = v_p;
77053 return ((uint8_t)(((uint64_t)(v_s.len))));
77056 // -------- func xz.decoder.apply_filter_0b_riscv
77058 WUFFS_BASE__GENERATED_C_CODE
77059 static uint8_t
77060 wuffs_xz__decoder__apply_filter_0b_riscv(
77061 wuffs_xz__decoder* self,
77062 wuffs_base__slice_u8 a_dst_slice) {
77063 wuffs_base__slice_u8 v_s = {0};
77064 uint32_t v_p = 0;
77065 uint32_t v_x = 0;
77066 uint32_t v_x27 = 0;
77067 uint32_t v_y = 0;
77068 uint32_t v_addr = 0;
77070 v_s = a_dst_slice;
77071 v_p = self->private_impl.f_bcj_pos;
77072 while (((uint64_t)(v_s.len)) >= 8u) {
77073 if (v_s.ptr[0u] == 239u) {
77074 if (((uint8_t)(v_s.ptr[1u] & 13u)) != 0u) {
77075 v_p += 2u;
77076 v_s = wuffs_base__slice_u8__subslice_i(v_s, 2u);
77077 continue;
77079 v_addr = ((((uint32_t)(((uint8_t)(v_s.ptr[1u] & 240u)))) << 13u) | (((uint32_t)(v_s.ptr[2u])) << 9u) | (((uint32_t)(v_s.ptr[3u])) << 1u));
77080 v_addr -= v_p;
77081 v_s.ptr[1u] = ((uint8_t)(((uint8_t)(v_s.ptr[1u] & 15u)) | ((uint8_t)(((v_addr >> 8u) & 240u)))));
77082 v_s.ptr[2u] = ((uint8_t)((((v_addr >> 16u) & 15u) | ((v_addr >> 7u) & 16u) | (((uint32_t)(v_addr << 4u)) & 224u))));
77083 v_s.ptr[3u] = ((uint8_t)((((v_addr >> 4u) & 127u) | ((v_addr >> 13u) & 128u))));
77084 v_p += 4u;
77085 v_s = wuffs_base__slice_u8__subslice_i(v_s, 4u);
77086 continue;
77087 } else if (((uint8_t)(v_s.ptr[0u] & 127u)) == 23u) {
77088 v_x = ((((uint32_t)(v_s.ptr[0u])) << 0u) |
77089 (((uint32_t)(v_s.ptr[1u])) << 8u) |
77090 (((uint32_t)(v_s.ptr[2u])) << 16u) |
77091 (((uint32_t)(v_s.ptr[3u])) << 24u));
77092 if ((v_x & 3712u) != 0u) {
77093 v_y = ((((uint32_t)(v_s.ptr[4u])) << 0u) |
77094 (((uint32_t)(v_s.ptr[5u])) << 8u) |
77095 (((uint32_t)(v_s.ptr[6u])) << 16u) |
77096 (((uint32_t)(v_s.ptr[7u])) << 24u));
77097 if (((((uint32_t)(v_x << 8u)) ^ ((uint32_t)(v_y - 3u))) & 1015811u) != 0u) {
77098 v_p += 6u;
77099 v_s = wuffs_base__slice_u8__subslice_i(v_s, 6u);
77100 continue;
77102 v_addr = ((v_x & 4294963200u) | (v_y >> 20u));
77103 v_x = (279u | ((uint32_t)(v_y << 12u)));
77104 v_s.ptr[0u] = ((uint8_t)((v_x >> 0u)));
77105 v_s.ptr[1u] = ((uint8_t)((v_x >> 8u)));
77106 v_s.ptr[2u] = ((uint8_t)((v_x >> 16u)));
77107 v_s.ptr[3u] = ((uint8_t)((v_x >> 24u)));
77108 v_s.ptr[4u] = ((uint8_t)((v_addr >> 0u)));
77109 v_s.ptr[5u] = ((uint8_t)((v_addr >> 8u)));
77110 v_s.ptr[6u] = ((uint8_t)((v_addr >> 16u)));
77111 v_s.ptr[7u] = ((uint8_t)((v_addr >> 24u)));
77112 v_p += 8u;
77113 v_s = wuffs_base__slice_u8__subslice_i(v_s, 8u);
77114 continue;
77116 v_x27 = (v_x >> 27u);
77117 if (((uint32_t)(((uint32_t)(v_x - 12567u)) << 18u)) >= (v_x27 & 29u)) {
77118 v_p += 4u;
77119 v_s = wuffs_base__slice_u8__subslice_i(v_s, 4u);
77120 continue;
77122 v_addr = ((((uint32_t)(v_s.ptr[4u])) << 24u) |
77123 (((uint32_t)(v_s.ptr[5u])) << 16u) |
77124 (((uint32_t)(v_s.ptr[6u])) << 8u) |
77125 (((uint32_t)(v_s.ptr[7u])) << 0u));
77126 v_addr -= v_p;
77127 v_y = ((v_x >> 12u) | ((uint32_t)(v_addr << 20u)));
77128 v_x = (23u | (v_x27 << 7u) | (((uint32_t)(v_addr + 2048u)) & 4294963200u));
77129 v_s.ptr[0u] = ((uint8_t)((v_x >> 0u)));
77130 v_s.ptr[1u] = ((uint8_t)((v_x >> 8u)));
77131 v_s.ptr[2u] = ((uint8_t)((v_x >> 16u)));
77132 v_s.ptr[3u] = ((uint8_t)((v_x >> 24u)));
77133 v_s.ptr[4u] = ((uint8_t)((v_y >> 0u)));
77134 v_s.ptr[5u] = ((uint8_t)((v_y >> 8u)));
77135 v_s.ptr[6u] = ((uint8_t)((v_y >> 16u)));
77136 v_s.ptr[7u] = ((uint8_t)((v_y >> 24u)));
77137 v_p += 8u;
77138 v_s = wuffs_base__slice_u8__subslice_i(v_s, 8u);
77139 continue;
77141 v_p += 2u;
77142 v_s = wuffs_base__slice_u8__subslice_i(v_s, 2u);
77144 self->private_impl.f_bcj_pos = v_p;
77145 return ((uint8_t)(((uint64_t)(v_s.len))));
77148 // -------- func xz.decoder.get_quirk
77150 WUFFS_BASE__GENERATED_C_CODE
77151 WUFFS_BASE__MAYBE_STATIC uint64_t
77152 wuffs_xz__decoder__get_quirk(
77153 const wuffs_xz__decoder* self,
77154 uint32_t a_key) {
77155 if (!self) {
77156 return 0;
77158 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
77159 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
77160 return 0;
77163 if (a_key == 1u) {
77164 if (self->private_impl.f_ignore_checksum) {
77165 return 1u;
77167 } else if (a_key == 2021322752u) {
77168 if (self->private_impl.f_standalone_format) {
77169 return 1u;
77172 return 0u;
77175 // -------- func xz.decoder.set_quirk
77177 WUFFS_BASE__GENERATED_C_CODE
77178 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
77179 wuffs_xz__decoder__set_quirk(
77180 wuffs_xz__decoder* self,
77181 uint32_t a_key,
77182 uint64_t a_value) {
77183 if (!self) {
77184 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
77186 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
77187 return wuffs_base__make_status(
77188 (self->private_impl.magic == WUFFS_BASE__DISABLED)
77189 ? wuffs_base__error__disabled_by_previous_error
77190 : wuffs_base__error__initialize_not_called);
77193 if (a_key == 1u) {
77194 self->private_impl.f_ignore_checksum = (a_value > 0u);
77195 return wuffs_base__make_status(NULL);
77196 } else if (a_key == 2021322752u) {
77197 self->private_impl.f_standalone_format = (a_value > 0u);
77198 return wuffs_base__make_status(NULL);
77200 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
77203 // -------- func xz.decoder.dst_history_retain_length
77205 WUFFS_BASE__GENERATED_C_CODE
77206 WUFFS_BASE__MAYBE_STATIC wuffs_base__optional_u63
77207 wuffs_xz__decoder__dst_history_retain_length(
77208 const wuffs_xz__decoder* self) {
77209 if (!self) {
77210 return wuffs_base__utility__make_optional_u63(false, 0u);
77212 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
77213 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
77214 return wuffs_base__utility__make_optional_u63(false, 0u);
77217 return wuffs_lzma__decoder__dst_history_retain_length(&self->private_data.f_lzma);
77220 // -------- func xz.decoder.workbuf_len
77222 WUFFS_BASE__GENERATED_C_CODE
77223 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
77224 wuffs_xz__decoder__workbuf_len(
77225 const wuffs_xz__decoder* self) {
77226 if (!self) {
77227 return wuffs_base__utility__empty_range_ii_u64();
77229 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
77230 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
77231 return wuffs_base__utility__empty_range_ii_u64();
77234 return wuffs_lzma__decoder__workbuf_len(&self->private_data.f_lzma);
77237 // -------- func xz.decoder.transform_io
77239 WUFFS_BASE__GENERATED_C_CODE
77240 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
77241 wuffs_xz__decoder__transform_io(
77242 wuffs_xz__decoder* self,
77243 wuffs_base__io_buffer* a_dst,
77244 wuffs_base__io_buffer* a_src,
77245 wuffs_base__slice_u8 a_workbuf) {
77246 if (!self) {
77247 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
77249 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
77250 return wuffs_base__make_status(
77251 (self->private_impl.magic == WUFFS_BASE__DISABLED)
77252 ? wuffs_base__error__disabled_by_previous_error
77253 : wuffs_base__error__initialize_not_called);
77255 if (!a_dst || !a_src) {
77256 self->private_impl.magic = WUFFS_BASE__DISABLED;
77257 return wuffs_base__make_status(wuffs_base__error__bad_argument);
77259 if ((self->private_impl.active_coroutine != 0) &&
77260 (self->private_impl.active_coroutine != 1)) {
77261 self->private_impl.magic = WUFFS_BASE__DISABLED;
77262 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
77264 self->private_impl.active_coroutine = 0;
77265 wuffs_base__status status = wuffs_base__make_status(NULL);
77267 wuffs_base__status v_status = wuffs_base__make_status(NULL);
77269 uint32_t coro_susp_point = self->private_impl.p_transform_io;
77270 switch (coro_susp_point) {
77271 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
77273 while (true) {
77275 wuffs_base__status t_0 = wuffs_xz__decoder__do_transform_io(self, a_dst, a_src, a_workbuf);
77276 v_status = t_0;
77278 if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
77279 status = wuffs_base__make_status(wuffs_xz__error__truncated_input);
77280 goto exit;
77282 status = v_status;
77283 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
77287 self->private_impl.p_transform_io = 0;
77288 goto exit;
77291 goto suspend;
77292 suspend:
77293 self->private_impl.p_transform_io = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
77294 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
77296 goto exit;
77297 exit:
77298 if (wuffs_base__status__is_error(&status)) {
77299 self->private_impl.magic = WUFFS_BASE__DISABLED;
77301 return status;
77304 // -------- func xz.decoder.do_transform_io
77306 WUFFS_BASE__GENERATED_C_CODE
77307 static wuffs_base__status
77308 wuffs_xz__decoder__do_transform_io(
77309 wuffs_xz__decoder* self,
77310 wuffs_base__io_buffer* a_dst,
77311 wuffs_base__io_buffer* a_src,
77312 wuffs_base__slice_u8 a_workbuf) {
77313 wuffs_base__status status = wuffs_base__make_status(NULL);
77315 uint64_t v_header_magic = 0;
77316 uint64_t v_dmark = 0;
77317 uint64_t v_smark = 0;
77318 uint8_t v_i8 = 0;
77319 wuffs_base__status v_status = wuffs_base__make_status(NULL);
77320 uint32_t v_checksum32_have = 0;
77321 uint32_t v_checksum32_want = 0;
77322 uint64_t v_checksum64_have = 0;
77323 uint64_t v_checksum64_want = 0;
77324 wuffs_base__bitvec256 v_checksum256_have = {0};
77325 uint64_t v_compressed_size = 0;
77326 uint64_t v_uncompressed_size = 0;
77327 uint32_t v_hash = 0;
77328 uint8_t v_c8 = 0;
77329 uint32_t v_c32 = 0;
77330 uint16_t v_footer_magic = 0;
77332 uint8_t* iop_a_dst = NULL;
77333 uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
77334 uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
77335 uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
77336 if (a_dst && a_dst->data.ptr) {
77337 io0_a_dst = a_dst->data.ptr;
77338 io1_a_dst = io0_a_dst + a_dst->meta.wi;
77339 iop_a_dst = io1_a_dst;
77340 io2_a_dst = io0_a_dst + a_dst->data.len;
77341 if (a_dst->meta.closed) {
77342 io2_a_dst = iop_a_dst;
77345 const uint8_t* iop_a_src = NULL;
77346 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
77347 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
77348 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
77349 if (a_src && a_src->data.ptr) {
77350 io0_a_src = a_src->data.ptr;
77351 io1_a_src = io0_a_src + a_src->meta.ri;
77352 iop_a_src = io1_a_src;
77353 io2_a_src = io0_a_src + a_src->meta.wi;
77356 uint32_t coro_susp_point = self->private_impl.p_do_transform_io;
77357 if (coro_susp_point) {
77358 v_checksum32_have = self->private_data.s_do_transform_io.v_checksum32_have;
77359 v_checksum32_want = self->private_data.s_do_transform_io.v_checksum32_want;
77360 v_checksum256_have = self->private_data.s_do_transform_io.v_checksum256_have;
77361 v_compressed_size = self->private_data.s_do_transform_io.v_compressed_size;
77362 v_uncompressed_size = self->private_data.s_do_transform_io.v_uncompressed_size;
77364 switch (coro_susp_point) {
77365 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
77367 while (true) {
77369 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
77370 uint64_t t_0;
77371 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 6)) {
77372 t_0 = ((uint64_t)(wuffs_base__peek_u48le__no_bounds_check(iop_a_src)));
77373 iop_a_src += 6;
77374 } else {
77375 self->private_data.s_do_transform_io.scratch = 0;
77376 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
77377 while (true) {
77378 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
77379 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
77380 goto suspend;
77382 uint64_t* scratch = &self->private_data.s_do_transform_io.scratch;
77383 uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
77384 *scratch <<= 8;
77385 *scratch >>= 8;
77386 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
77387 if (num_bits_0 == 40) {
77388 t_0 = ((uint64_t)(*scratch));
77389 break;
77391 num_bits_0 += 8u;
77392 *scratch |= ((uint64_t)(num_bits_0)) << 56;
77395 v_header_magic = t_0;
77397 if (v_header_magic != 388031461373u) {
77398 status = wuffs_base__make_status(wuffs_xz__error__bad_header);
77399 goto exit;
77402 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
77403 uint64_t t_1;
77404 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 6)) {
77405 t_1 = ((uint64_t)(wuffs_base__peek_u48le__no_bounds_check(iop_a_src)));
77406 iop_a_src += 6;
77407 } else {
77408 self->private_data.s_do_transform_io.scratch = 0;
77409 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
77410 while (true) {
77411 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
77412 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
77413 goto suspend;
77415 uint64_t* scratch = &self->private_data.s_do_transform_io.scratch;
77416 uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
77417 *scratch <<= 8;
77418 *scratch >>= 8;
77419 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
77420 if (num_bits_1 == 40) {
77421 t_1 = ((uint64_t)(*scratch));
77422 break;
77424 num_bits_1 += 8u;
77425 *scratch |= ((uint64_t)(num_bits_1)) << 56;
77428 v_header_magic = t_1;
77430 if (v_header_magic == 72400582410240u) {
77431 self->private_impl.f_checksummer = 0u;
77432 } else if (v_header_magic == 60327687946496u) {
77433 self->private_impl.f_checksummer = 1u;
77434 } else if (v_header_magic == 77742513456128u) {
77435 self->private_impl.f_checksummer = 2u;
77436 } else if (v_header_magic == 177077137508864u) {
77437 self->private_impl.f_checksummer = 3u;
77438 } else if ((v_header_magic & 61695u) != 0u) {
77439 status = wuffs_base__make_status(wuffs_xz__error__bad_header);
77440 goto exit;
77441 } else {
77442 v_header_magic = (15u & (v_header_magic >> 8u));
77443 if ((v_header_magic != 0u) &&
77444 (v_header_magic != 1u) &&
77445 (v_header_magic != 4u) &&
77446 (v_header_magic != 10u)) {
77447 status = wuffs_base__make_status(wuffs_xz__error__unsupported_checksum_algorithm);
77448 goto exit;
77450 status = wuffs_base__make_status(wuffs_xz__error__bad_checksum);
77451 goto exit;
77453 self->private_impl.f_flags = ((uint16_t)(v_header_magic));
77454 self->private_impl.f_num_actual_blocks = 0u;
77455 while (true) {
77456 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
77457 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
77458 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
77459 continue;
77460 } else if (wuffs_base__peek_u8be__no_bounds_check(iop_a_src) == 0u) {
77461 break;
77463 self->private_impl.f_num_actual_blocks += 1u;
77464 if ( ! self->private_impl.f_ignore_checksum) {
77465 wuffs_private_impl__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32,
77466 sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
77468 self->private_impl.f_compressed_size_for_index = 4u;
77469 while (true) {
77470 v_smark = ((uint64_t)(iop_a_src - io0_a_src));
77472 if (a_src) {
77473 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
77475 wuffs_base__status t_2 = wuffs_xz__decoder__decode_block_header_with_padding(self, a_src);
77476 v_status = t_2;
77477 if (a_src) {
77478 iop_a_src = a_src->data.ptr + a_src->meta.ri;
77481 wuffs_private_impl__u64__sat_add_indirect(&self->private_impl.f_compressed_size_for_index, wuffs_private_impl__io__count_since(v_smark, ((uint64_t)(iop_a_src - io0_a_src))));
77482 if ( ! self->private_impl.f_ignore_checksum) {
77483 v_checksum32_have = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_private_impl__io__since(v_smark, ((uint64_t)(iop_a_src - io0_a_src)), io0_a_src));
77485 if (wuffs_base__status__is_ok(&v_status)) {
77486 break;
77488 status = v_status;
77489 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
77492 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
77493 uint32_t t_3;
77494 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
77495 t_3 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
77496 iop_a_src += 4;
77497 } else {
77498 self->private_data.s_do_transform_io.scratch = 0;
77499 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
77500 while (true) {
77501 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
77502 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
77503 goto suspend;
77505 uint64_t* scratch = &self->private_data.s_do_transform_io.scratch;
77506 uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56));
77507 *scratch <<= 8;
77508 *scratch >>= 8;
77509 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3;
77510 if (num_bits_3 == 24) {
77511 t_3 = ((uint32_t)(*scratch));
77512 break;
77514 num_bits_3 += 8u;
77515 *scratch |= ((uint64_t)(num_bits_3)) << 56;
77518 v_checksum32_want = t_3;
77520 if (self->private_impl.f_ignore_checksum) {
77521 } else if (v_checksum32_have != v_checksum32_want) {
77522 status = wuffs_base__make_status(wuffs_xz__error__bad_checksum);
77523 goto exit;
77524 } else {
77525 wuffs_private_impl__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32,
77526 sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
77527 wuffs_private_impl__ignore_status(wuffs_crc64__ecma_hasher__initialize(&self->private_data.f_crc64,
77528 sizeof (wuffs_crc64__ecma_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
77529 wuffs_private_impl__ignore_status(wuffs_sha256__hasher__initialize(&self->private_data.f_sha256,
77530 sizeof (wuffs_sha256__hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
77532 v_compressed_size = 0u;
77533 v_uncompressed_size = 0u;
77534 while (true) {
77535 if (((uint64_t)(self->private_impl.f_bcj_undo_index)) > ((uint64_t)(io2_a_dst - iop_a_dst))) {
77536 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
77537 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9);
77538 continue;
77540 v_dmark = ((uint64_t)(iop_a_dst - io0_a_dst));
77541 v_smark = ((uint64_t)(iop_a_src - io0_a_src));
77542 if (self->private_impl.f_num_non_final_filters == 0u) {
77544 if (a_dst) {
77545 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
77547 if (a_src) {
77548 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
77550 wuffs_base__status t_4 = wuffs_lzma__decoder__transform_io(&self->private_data.f_lzma, a_dst, a_src, a_workbuf);
77551 v_status = t_4;
77552 if (a_dst) {
77553 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
77555 if (a_src) {
77556 iop_a_src = a_src->data.ptr + a_src->meta.ri;
77559 } else {
77560 if (self->private_impl.f_bcj_undo_index > 0u) {
77561 wuffs_private_impl__io_writer__copy_from_slice(&iop_a_dst, io2_a_dst,wuffs_base__make_slice_u8(self->private_data.f_filter_data[0u], self->private_impl.f_bcj_undo_index));
77562 self->private_impl.f_bcj_undo_index = 0u;
77565 uint8_t* o_0_io0_a_dst = io0_a_dst;
77566 uint8_t* o_0_io1_a_dst = io1_a_dst;
77567 io0_a_dst = iop_a_dst;
77568 io1_a_dst = iop_a_dst;
77569 wuffs_base__io_buffer o_0_a_dst;
77570 if (a_dst) {
77571 memcpy(&o_0_a_dst, a_dst, sizeof(*a_dst));
77572 size_t wi0 = a_dst->meta.wi;
77573 a_dst->data.ptr += wi0;
77574 a_dst->data.len -= wi0;
77575 a_dst->meta.ri = 0;
77576 a_dst->meta.wi = 0;
77577 a_dst->meta.pos = wuffs_base__u64__sat_add(a_dst->meta.pos, wi0);
77580 if (a_dst) {
77581 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
77583 if (a_src) {
77584 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
77586 wuffs_base__status t_5 = wuffs_lzma__decoder__transform_io(&self->private_data.f_lzma, a_dst, a_src, a_workbuf);
77587 v_status = t_5;
77588 if (a_dst) {
77589 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
77591 if (a_src) {
77592 iop_a_src = a_src->data.ptr + a_src->meta.ri;
77595 if (a_dst) {
77596 memcpy(a_dst, &o_0_a_dst, sizeof(*a_dst));
77597 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
77598 io0_a_dst = o_0_io0_a_dst;
77599 io1_a_dst = o_0_io1_a_dst;
77602 self->private_impl.f_bcj_undo_index = wuffs_xz__decoder__apply_non_final_filters(self, wuffs_private_impl__io__since(v_dmark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst));
77603 if ((self->private_impl.f_bcj_undo_index > 0u) && ! wuffs_base__status__is_ok(&v_status)) {
77604 v_i8 = ((uint8_t)(self->private_impl.f_bcj_undo_index - 1u));
77605 while (true) {
77606 if ( ! (iop_a_dst > io1_a_dst)) {
77607 status = wuffs_base__make_status(wuffs_xz__error__internal_error_inconsistent_bcj_filter_state);
77608 goto exit;
77610 self->private_data.f_filter_data[0u][v_i8] = iop_a_dst[-1];
77611 iop_a_dst--;
77612 if (v_i8 <= 0u) {
77613 break;
77615 #if defined(__GNUC__)
77616 #pragma GCC diagnostic push
77617 #pragma GCC diagnostic ignored "-Wconversion"
77618 #endif
77619 v_i8 -= 1u;
77620 #if defined(__GNUC__)
77621 #pragma GCC diagnostic pop
77622 #endif
77626 v_compressed_size += wuffs_private_impl__io__count_since(v_smark, ((uint64_t)(iop_a_src - io0_a_src)));
77627 v_uncompressed_size += wuffs_private_impl__io__count_since(v_dmark, ((uint64_t)(iop_a_dst - io0_a_dst)));
77628 if (self->private_impl.f_ignore_checksum) {
77629 } else if (self->private_impl.f_checksummer == 1u) {
77630 wuffs_crc32__ieee_hasher__update(&self->private_data.f_crc32, wuffs_private_impl__io__since(v_dmark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst));
77631 } else if (self->private_impl.f_checksummer == 2u) {
77632 wuffs_crc64__ecma_hasher__update(&self->private_data.f_crc64, wuffs_private_impl__io__since(v_dmark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst));
77633 } else if (self->private_impl.f_checksummer == 3u) {
77634 wuffs_sha256__hasher__update(&self->private_data.f_sha256, wuffs_private_impl__io__since(v_dmark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst));
77636 if (wuffs_base__status__is_ok(&v_status)) {
77637 break;
77639 status = v_status;
77640 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10);
77642 if ((self->private_impl.f_block_has_compressed_size && (self->private_impl.f_block_compressed_size != v_compressed_size)) || (self->private_impl.f_block_has_uncompressed_size && (self->private_impl.f_block_uncompressed_size != v_uncompressed_size))) {
77643 status = wuffs_base__make_status(wuffs_xz__error__bad_block_header);
77644 goto exit;
77646 wuffs_private_impl__u64__sat_add_indirect(&self->private_impl.f_compressed_size_for_index, v_compressed_size);
77647 wuffs_private_impl__u64__sat_add_indirect(&self->private_impl.f_compressed_size_for_index, ((uint64_t)(WUFFS_XZ__CHECKSUM_LENGTH[self->private_impl.f_checksummer])));
77648 self->private_impl.f_verification_have_total_sizes[0u] += self->private_impl.f_compressed_size_for_index;
77649 v_hash = ((uint32_t)((self->private_impl.f_compressed_size_for_index ^ (self->private_impl.f_compressed_size_for_index >> 32u))));
77650 v_hash *= 3432918353u;
77651 v_hash = (((uint32_t)(v_hash << 15u)) | (v_hash >> 17u));
77652 v_hash *= 461845907u;
77653 v_hash ^= self->private_impl.f_verification_have_hashed_sizes[0u];
77654 v_hash = (((uint32_t)(v_hash << 13u)) | (v_hash >> 19u));
77655 self->private_impl.f_verification_have_hashed_sizes[0u] = ((uint32_t)(((uint32_t)(v_hash * 5u)) + 3864292196u));
77656 self->private_impl.f_verification_have_total_sizes[1u] += v_uncompressed_size;
77657 v_hash = ((uint32_t)((v_uncompressed_size ^ (v_uncompressed_size >> 32u))));
77658 v_hash *= 3432918353u;
77659 v_hash = (((uint32_t)(v_hash << 15u)) | (v_hash >> 17u));
77660 v_hash *= 461845907u;
77661 v_hash ^= self->private_impl.f_verification_have_hashed_sizes[1u];
77662 v_hash = (((uint32_t)(v_hash << 13u)) | (v_hash >> 19u));
77663 self->private_impl.f_verification_have_hashed_sizes[1u] = ((uint32_t)(((uint32_t)(v_hash * 5u)) + 3864292196u));
77664 while ((v_compressed_size & 3u) != 0u) {
77666 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
77667 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
77668 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
77669 goto suspend;
77671 uint8_t t_6 = *iop_a_src++;
77672 v_c8 = t_6;
77674 if (v_c8 != 0u) {
77675 status = wuffs_base__make_status(wuffs_xz__error__bad_padding);
77676 goto exit;
77678 v_compressed_size += 1u;
77680 self->private_impl.f_lzma_needs_reset = true;
77681 if (self->private_impl.f_ignore_checksum) {
77682 self->private_data.s_do_transform_io.scratch = ((uint32_t)(WUFFS_XZ__CHECKSUM_LENGTH[self->private_impl.f_checksummer]));
77683 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
77684 if (self->private_data.s_do_transform_io.scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
77685 self->private_data.s_do_transform_io.scratch -= ((uint64_t)(io2_a_src - iop_a_src));
77686 iop_a_src = io2_a_src;
77687 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
77688 goto suspend;
77690 iop_a_src += self->private_data.s_do_transform_io.scratch;
77691 } else if (self->private_impl.f_checksummer == 1u) {
77693 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
77694 uint32_t t_7;
77695 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
77696 t_7 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
77697 iop_a_src += 4;
77698 } else {
77699 self->private_data.s_do_transform_io.scratch = 0;
77700 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
77701 while (true) {
77702 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
77703 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
77704 goto suspend;
77706 uint64_t* scratch = &self->private_data.s_do_transform_io.scratch;
77707 uint32_t num_bits_7 = ((uint32_t)(*scratch >> 56));
77708 *scratch <<= 8;
77709 *scratch >>= 8;
77710 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_7;
77711 if (num_bits_7 == 24) {
77712 t_7 = ((uint32_t)(*scratch));
77713 break;
77715 num_bits_7 += 8u;
77716 *scratch |= ((uint64_t)(num_bits_7)) << 56;
77719 v_checksum32_want = t_7;
77721 v_checksum32_have = wuffs_crc32__ieee_hasher__checksum_u32(&self->private_data.f_crc32);
77722 if (v_checksum32_have != v_checksum32_want) {
77723 status = wuffs_base__make_status(wuffs_xz__error__bad_checksum);
77724 goto exit;
77726 } else if (self->private_impl.f_checksummer == 2u) {
77728 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
77729 uint64_t t_8;
77730 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 8)) {
77731 t_8 = wuffs_base__peek_u64le__no_bounds_check(iop_a_src);
77732 iop_a_src += 8;
77733 } else {
77734 self->private_data.s_do_transform_io.scratch = 0;
77735 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
77736 while (true) {
77737 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
77738 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
77739 goto suspend;
77741 uint64_t* scratch = &self->private_data.s_do_transform_io.scratch;
77742 uint32_t num_bits_8 = ((uint32_t)(*scratch >> 56));
77743 *scratch <<= 8;
77744 *scratch >>= 8;
77745 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_8;
77746 if (num_bits_8 == 56) {
77747 t_8 = ((uint64_t)(*scratch));
77748 break;
77750 num_bits_8 += 8u;
77751 *scratch |= ((uint64_t)(num_bits_8)) << 56;
77754 v_checksum64_want = t_8;
77756 v_checksum64_have = wuffs_crc64__ecma_hasher__checksum_u64(&self->private_data.f_crc64);
77757 if (v_checksum64_have != v_checksum64_want) {
77758 status = wuffs_base__make_status(wuffs_xz__error__bad_checksum);
77759 goto exit;
77761 } else if (self->private_impl.f_checksummer == 3u) {
77762 v_checksum256_have = wuffs_sha256__hasher__checksum_bitvec256(&self->private_data.f_sha256);
77764 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(17);
77765 uint64_t t_9;
77766 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 8)) {
77767 t_9 = wuffs_base__peek_u64be__no_bounds_check(iop_a_src);
77768 iop_a_src += 8;
77769 } else {
77770 self->private_data.s_do_transform_io.scratch = 0;
77771 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(18);
77772 while (true) {
77773 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
77774 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
77775 goto suspend;
77777 uint64_t* scratch = &self->private_data.s_do_transform_io.scratch;
77778 uint32_t num_bits_9 = ((uint32_t)(*scratch & 0xFFu));
77779 *scratch >>= 8;
77780 *scratch <<= 8;
77781 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_9);
77782 if (num_bits_9 == 56) {
77783 t_9 = ((uint64_t)(*scratch >> 0));
77784 break;
77786 num_bits_9 += 8u;
77787 *scratch |= ((uint64_t)(num_bits_9));
77790 v_checksum64_want = t_9;
77792 if (wuffs_base__bitvec256__get_u64(&v_checksum256_have, 3u) != v_checksum64_want) {
77793 status = wuffs_base__make_status(wuffs_xz__error__bad_checksum);
77794 goto exit;
77797 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(19);
77798 uint64_t t_10;
77799 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 8)) {
77800 t_10 = wuffs_base__peek_u64be__no_bounds_check(iop_a_src);
77801 iop_a_src += 8;
77802 } else {
77803 self->private_data.s_do_transform_io.scratch = 0;
77804 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(20);
77805 while (true) {
77806 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
77807 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
77808 goto suspend;
77810 uint64_t* scratch = &self->private_data.s_do_transform_io.scratch;
77811 uint32_t num_bits_10 = ((uint32_t)(*scratch & 0xFFu));
77812 *scratch >>= 8;
77813 *scratch <<= 8;
77814 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_10);
77815 if (num_bits_10 == 56) {
77816 t_10 = ((uint64_t)(*scratch >> 0));
77817 break;
77819 num_bits_10 += 8u;
77820 *scratch |= ((uint64_t)(num_bits_10));
77823 v_checksum64_want = t_10;
77825 if (wuffs_base__bitvec256__get_u64(&v_checksum256_have, 2u) != v_checksum64_want) {
77826 status = wuffs_base__make_status(wuffs_xz__error__bad_checksum);
77827 goto exit;
77830 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(21);
77831 uint64_t t_11;
77832 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 8)) {
77833 t_11 = wuffs_base__peek_u64be__no_bounds_check(iop_a_src);
77834 iop_a_src += 8;
77835 } else {
77836 self->private_data.s_do_transform_io.scratch = 0;
77837 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(22);
77838 while (true) {
77839 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
77840 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
77841 goto suspend;
77843 uint64_t* scratch = &self->private_data.s_do_transform_io.scratch;
77844 uint32_t num_bits_11 = ((uint32_t)(*scratch & 0xFFu));
77845 *scratch >>= 8;
77846 *scratch <<= 8;
77847 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_11);
77848 if (num_bits_11 == 56) {
77849 t_11 = ((uint64_t)(*scratch >> 0));
77850 break;
77852 num_bits_11 += 8u;
77853 *scratch |= ((uint64_t)(num_bits_11));
77856 v_checksum64_want = t_11;
77858 if (wuffs_base__bitvec256__get_u64(&v_checksum256_have, 1u) != v_checksum64_want) {
77859 status = wuffs_base__make_status(wuffs_xz__error__bad_checksum);
77860 goto exit;
77863 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(23);
77864 uint64_t t_12;
77865 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 8)) {
77866 t_12 = wuffs_base__peek_u64be__no_bounds_check(iop_a_src);
77867 iop_a_src += 8;
77868 } else {
77869 self->private_data.s_do_transform_io.scratch = 0;
77870 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(24);
77871 while (true) {
77872 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
77873 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
77874 goto suspend;
77876 uint64_t* scratch = &self->private_data.s_do_transform_io.scratch;
77877 uint32_t num_bits_12 = ((uint32_t)(*scratch & 0xFFu));
77878 *scratch >>= 8;
77879 *scratch <<= 8;
77880 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_12);
77881 if (num_bits_12 == 56) {
77882 t_12 = ((uint64_t)(*scratch >> 0));
77883 break;
77885 num_bits_12 += 8u;
77886 *scratch |= ((uint64_t)(num_bits_12));
77889 v_checksum64_want = t_12;
77891 if (wuffs_base__bitvec256__get_u64(&v_checksum256_have, 0u) != v_checksum64_want) {
77892 status = wuffs_base__make_status(wuffs_xz__error__bad_checksum);
77893 goto exit;
77897 self->private_impl.f_backwards_size = 0u;
77898 if ( ! self->private_impl.f_ignore_checksum) {
77899 wuffs_private_impl__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32,
77900 sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
77902 while (true) {
77903 v_smark = ((uint64_t)(iop_a_src - io0_a_src));
77905 if (a_src) {
77906 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
77908 wuffs_base__status t_13 = wuffs_xz__decoder__verify_index(self, a_src);
77909 v_status = t_13;
77910 if (a_src) {
77911 iop_a_src = a_src->data.ptr + a_src->meta.ri;
77914 wuffs_private_impl__u64__sat_add_indirect(&self->private_impl.f_backwards_size, wuffs_private_impl__io__count_since(v_smark, ((uint64_t)(iop_a_src - io0_a_src))));
77915 if ( ! self->private_impl.f_ignore_checksum) {
77916 wuffs_crc32__ieee_hasher__update(&self->private_data.f_crc32, wuffs_private_impl__io__since(v_smark, ((uint64_t)(iop_a_src - io0_a_src)), io0_a_src));
77918 if (wuffs_base__status__is_ok(&v_status)) {
77919 break;
77921 status = v_status;
77922 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(25);
77924 if ( ! self->private_impl.f_ignore_checksum) {
77925 wuffs_crc32__ieee_hasher__update(&self->private_data.f_crc32, wuffs_base__make_slice_u8(wuffs_base__strip_const_from_u8_ptr(WUFFS_XZ__ZEROES), (3u & ((uint64_t)(0u - (3u & self->private_impl.f_backwards_size))))));
77927 while ((self->private_impl.f_backwards_size & 3u) != 0u) {
77929 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(26);
77930 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
77931 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
77932 goto suspend;
77934 uint8_t t_14 = *iop_a_src++;
77935 v_c8 = t_14;
77937 if (v_c8 != 0u) {
77938 status = wuffs_base__make_status(wuffs_xz__error__bad_index);
77939 goto exit;
77941 self->private_impl.f_backwards_size += 1u;
77943 self->private_impl.f_backwards_size >>= 2u;
77944 if ((self->private_impl.f_backwards_size == 0u) || (self->private_impl.f_backwards_size > 4294967295u)) {
77945 status = wuffs_base__make_status(wuffs_xz__error__bad_index);
77946 goto exit;
77949 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(27);
77950 uint32_t t_15;
77951 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
77952 t_15 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
77953 iop_a_src += 4;
77954 } else {
77955 self->private_data.s_do_transform_io.scratch = 0;
77956 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(28);
77957 while (true) {
77958 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
77959 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
77960 goto suspend;
77962 uint64_t* scratch = &self->private_data.s_do_transform_io.scratch;
77963 uint32_t num_bits_15 = ((uint32_t)(*scratch >> 56));
77964 *scratch <<= 8;
77965 *scratch >>= 8;
77966 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_15;
77967 if (num_bits_15 == 24) {
77968 t_15 = ((uint32_t)(*scratch));
77969 break;
77971 num_bits_15 += 8u;
77972 *scratch |= ((uint64_t)(num_bits_15)) << 56;
77975 v_checksum32_want = t_15;
77977 if (self->private_impl.f_ignore_checksum) {
77978 } else if (v_checksum32_want != wuffs_crc32__ieee_hasher__checksum_u32(&self->private_data.f_crc32)) {
77979 status = wuffs_base__make_status(wuffs_xz__error__bad_checksum);
77980 goto exit;
77981 } else {
77982 wuffs_private_impl__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32,
77983 sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
77986 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(29);
77987 uint32_t t_16;
77988 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
77989 t_16 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
77990 iop_a_src += 4;
77991 } else {
77992 self->private_data.s_do_transform_io.scratch = 0;
77993 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(30);
77994 while (true) {
77995 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
77996 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
77997 goto suspend;
77999 uint64_t* scratch = &self->private_data.s_do_transform_io.scratch;
78000 uint32_t num_bits_16 = ((uint32_t)(*scratch >> 56));
78001 *scratch <<= 8;
78002 *scratch >>= 8;
78003 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_16;
78004 if (num_bits_16 == 24) {
78005 t_16 = ((uint32_t)(*scratch));
78006 break;
78008 num_bits_16 += 8u;
78009 *scratch |= ((uint64_t)(num_bits_16)) << 56;
78012 v_checksum32_want = t_16;
78014 while (true) {
78015 v_smark = ((uint64_t)(iop_a_src - io0_a_src));
78017 if (a_src) {
78018 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
78020 wuffs_base__status t_17 = wuffs_xz__decoder__verify_footer(self, a_src);
78021 v_status = t_17;
78022 if (a_src) {
78023 iop_a_src = a_src->data.ptr + a_src->meta.ri;
78026 if ( ! self->private_impl.f_ignore_checksum) {
78027 wuffs_crc32__ieee_hasher__update(&self->private_data.f_crc32, wuffs_private_impl__io__since(v_smark, ((uint64_t)(iop_a_src - io0_a_src)), io0_a_src));
78029 if (wuffs_base__status__is_ok(&v_status)) {
78030 break;
78032 status = v_status;
78033 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(31);
78035 if ( ! self->private_impl.f_ignore_checksum && (v_checksum32_want != wuffs_crc32__ieee_hasher__checksum_u32(&self->private_data.f_crc32))) {
78036 status = wuffs_base__make_status(wuffs_xz__error__bad_checksum);
78037 goto exit;
78040 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(32);
78041 uint16_t t_18;
78042 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
78043 t_18 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src);
78044 iop_a_src += 2;
78045 } else {
78046 self->private_data.s_do_transform_io.scratch = 0;
78047 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(33);
78048 while (true) {
78049 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
78050 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
78051 goto suspend;
78053 uint64_t* scratch = &self->private_data.s_do_transform_io.scratch;
78054 uint32_t num_bits_18 = ((uint32_t)(*scratch >> 56));
78055 *scratch <<= 8;
78056 *scratch >>= 8;
78057 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_18;
78058 if (num_bits_18 == 8) {
78059 t_18 = ((uint16_t)(*scratch));
78060 break;
78062 num_bits_18 += 8u;
78063 *scratch |= ((uint64_t)(num_bits_18)) << 56;
78066 v_footer_magic = t_18;
78068 if (v_footer_magic != 23129u) {
78069 status = wuffs_base__make_status(wuffs_xz__error__bad_footer);
78070 goto exit;
78072 if ( ! self->private_impl.f_standalone_format) {
78073 break;
78075 while (true) {
78076 while (((uint64_t)(io2_a_src - iop_a_src)) < 4u) {
78077 if (a_src && a_src->meta.closed) {
78078 if (((uint64_t)(io2_a_src - iop_a_src)) == 0u) {
78079 goto label__streams__break;
78080 } else {
78081 status = wuffs_base__make_status(wuffs_xz__error__truncated_input);
78082 goto exit;
78085 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
78086 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(34);
78088 v_c32 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
78089 if (v_c32 == 1484404733u) {
78090 break;
78091 } else if (v_c32 != 0u) {
78092 status = wuffs_base__make_status(wuffs_xz__error__bad_header_concatenated_stream);
78093 goto exit;
78095 iop_a_src += 4u;
78097 self->private_impl.f_started_verify_index = false;
78099 label__streams__break:;
78102 self->private_impl.p_do_transform_io = 0;
78103 goto exit;
78106 goto suspend;
78107 suspend:
78108 self->private_impl.p_do_transform_io = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
78109 self->private_data.s_do_transform_io.v_checksum32_have = v_checksum32_have;
78110 self->private_data.s_do_transform_io.v_checksum32_want = v_checksum32_want;
78111 self->private_data.s_do_transform_io.v_checksum256_have = v_checksum256_have;
78112 self->private_data.s_do_transform_io.v_compressed_size = v_compressed_size;
78113 self->private_data.s_do_transform_io.v_uncompressed_size = v_uncompressed_size;
78115 goto exit;
78116 exit:
78117 if (a_dst && a_dst->data.ptr) {
78118 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
78120 if (a_src && a_src->data.ptr) {
78121 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
78124 return status;
78127 // -------- func xz.decoder.decode_block_header_with_padding
78129 WUFFS_BASE__GENERATED_C_CODE
78130 static wuffs_base__status
78131 wuffs_xz__decoder__decode_block_header_with_padding(
78132 wuffs_xz__decoder* self,
78133 wuffs_base__io_buffer* a_src) {
78134 wuffs_base__status status = wuffs_base__make_status(NULL);
78136 uint8_t v_c8 = 0;
78137 uint64_t v_padded_size_have = 0;
78138 uint64_t v_padded_size_want = 0;
78139 uint64_t v_smark = 0;
78140 wuffs_base__status v_status = wuffs_base__make_status(NULL);
78142 const uint8_t* iop_a_src = NULL;
78143 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
78144 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
78145 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
78146 if (a_src && a_src->data.ptr) {
78147 io0_a_src = a_src->data.ptr;
78148 io1_a_src = io0_a_src + a_src->meta.ri;
78149 iop_a_src = io1_a_src;
78150 io2_a_src = io0_a_src + a_src->meta.wi;
78153 uint32_t coro_susp_point = self->private_impl.p_decode_block_header_with_padding;
78154 if (coro_susp_point) {
78155 v_padded_size_have = self->private_data.s_decode_block_header_with_padding.v_padded_size_have;
78156 v_padded_size_want = self->private_data.s_decode_block_header_with_padding.v_padded_size_want;
78158 switch (coro_susp_point) {
78159 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
78162 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
78163 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
78164 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
78165 goto suspend;
78167 uint8_t t_0 = *iop_a_src++;
78168 v_c8 = t_0;
78170 v_padded_size_want = ((uint64_t)((((uint64_t)(v_c8)) * 4u) - 1u));
78171 while (true) {
78172 v_smark = ((uint64_t)(iop_a_src - io0_a_src));
78174 if (a_src) {
78175 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
78177 wuffs_base__status t_1 = wuffs_xz__decoder__decode_block_header_sans_padding(self, a_src);
78178 v_status = t_1;
78179 if (a_src) {
78180 iop_a_src = a_src->data.ptr + a_src->meta.ri;
78183 wuffs_private_impl__u64__sat_add_indirect(&v_padded_size_have, wuffs_private_impl__io__count_since(v_smark, ((uint64_t)(iop_a_src - io0_a_src))));
78184 if (wuffs_base__status__is_ok(&v_status)) {
78185 break;
78187 status = v_status;
78188 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
78190 if (v_padded_size_have > v_padded_size_want) {
78191 status = wuffs_base__make_status(wuffs_xz__error__bad_block_header);
78192 goto exit;
78194 while (v_padded_size_have < v_padded_size_want) {
78196 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
78197 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
78198 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
78199 goto suspend;
78201 uint8_t t_2 = *iop_a_src++;
78202 v_c8 = t_2;
78204 if (v_c8 != 0u) {
78205 status = wuffs_base__make_status(wuffs_xz__error__bad_block_header);
78206 goto exit;
78208 v_padded_size_have += 1u;
78212 self->private_impl.p_decode_block_header_with_padding = 0;
78213 goto exit;
78216 goto suspend;
78217 suspend:
78218 self->private_impl.p_decode_block_header_with_padding = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
78219 self->private_data.s_decode_block_header_with_padding.v_padded_size_have = v_padded_size_have;
78220 self->private_data.s_decode_block_header_with_padding.v_padded_size_want = v_padded_size_want;
78222 goto exit;
78223 exit:
78224 if (a_src && a_src->data.ptr) {
78225 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
78228 return status;
78231 // -------- func xz.decoder.decode_block_header_sans_padding
78233 WUFFS_BASE__GENERATED_C_CODE
78234 static wuffs_base__status
78235 wuffs_xz__decoder__decode_block_header_sans_padding(
78236 wuffs_xz__decoder* self,
78237 wuffs_base__io_buffer* a_src) {
78238 wuffs_base__status status = wuffs_base__make_status(NULL);
78240 uint8_t v_c8 = 0;
78241 uint32_t v_c32 = 0;
78242 uint32_t v_alignment = 0;
78243 uint8_t v_flags = 0;
78244 uint8_t v_filter_id = 0;
78245 wuffs_base__status v_status = wuffs_base__make_status(NULL);
78246 uint32_t v_shift = 0;
78247 uint32_t v_f = 0;
78248 uint32_t v_k = 0;
78250 const uint8_t* iop_a_src = NULL;
78251 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
78252 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
78253 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
78254 if (a_src && a_src->data.ptr) {
78255 io0_a_src = a_src->data.ptr;
78256 io1_a_src = io0_a_src + a_src->meta.ri;
78257 iop_a_src = io1_a_src;
78258 io2_a_src = io0_a_src + a_src->meta.wi;
78261 uint32_t coro_susp_point = self->private_impl.p_decode_block_header_sans_padding;
78262 if (coro_susp_point) {
78263 v_flags = self->private_data.s_decode_block_header_sans_padding.v_flags;
78264 v_filter_id = self->private_data.s_decode_block_header_sans_padding.v_filter_id;
78265 v_shift = self->private_data.s_decode_block_header_sans_padding.v_shift;
78266 v_f = self->private_data.s_decode_block_header_sans_padding.v_f;
78268 switch (coro_susp_point) {
78269 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
78272 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
78273 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
78274 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
78275 goto suspend;
78277 uint8_t t_0 = *iop_a_src++;
78278 v_flags = t_0;
78280 self->private_impl.f_num_non_final_filters = ((uint32_t)(((uint8_t)(v_flags & 3u))));
78281 if (((uint8_t)(v_flags & 60u)) != 0u) {
78282 status = wuffs_base__make_status(wuffs_xz__error__bad_block_header);
78283 goto exit;
78285 self->private_impl.f_block_has_compressed_size = (((uint8_t)(v_flags & 64u)) != 0u);
78286 if (self->private_impl.f_block_has_compressed_size) {
78287 self->private_impl.f_block_compressed_size = 0u;
78288 v_shift = 0u;
78289 while (true) {
78291 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
78292 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
78293 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
78294 goto suspend;
78296 uint8_t t_1 = *iop_a_src++;
78297 v_c8 = t_1;
78299 if (v_shift <= 56u) {
78300 self->private_impl.f_block_compressed_size |= (((uint64_t)(((uint8_t)(v_c8 & 127u)))) << v_shift);
78301 if (v_c8 >= 128u) {
78302 v_shift += 7u;
78303 continue;
78304 } else if ((v_c8 == 0u) && (v_shift > 0u)) {
78305 status = wuffs_base__make_status(wuffs_xz__error__bad_block_header);
78306 goto exit;
78308 break;
78309 } else if (v_c8 != 1u) {
78310 status = wuffs_base__make_status(wuffs_xz__error__bad_block_header);
78311 goto exit;
78313 self->private_impl.f_block_compressed_size |= (((uint64_t)(1u)) << 63u);
78314 break;
78317 self->private_impl.f_block_has_uncompressed_size = (((uint8_t)(v_flags & 128u)) != 0u);
78318 if (self->private_impl.f_block_has_uncompressed_size) {
78319 self->private_impl.f_block_uncompressed_size = 0u;
78320 v_shift = 0u;
78321 while (true) {
78323 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
78324 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
78325 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
78326 goto suspend;
78328 uint8_t t_2 = *iop_a_src++;
78329 v_c8 = t_2;
78331 if (v_shift <= 56u) {
78332 self->private_impl.f_block_uncompressed_size |= (((uint64_t)(((uint8_t)(v_c8 & 127u)))) << v_shift);
78333 if (v_c8 >= 128u) {
78334 v_shift += 7u;
78335 continue;
78336 } else if ((v_c8 == 0u) && (v_shift > 0u)) {
78337 status = wuffs_base__make_status(wuffs_xz__error__bad_block_header);
78338 goto exit;
78340 break;
78341 } else if (v_c8 != 1u) {
78342 status = wuffs_base__make_status(wuffs_xz__error__bad_block_header);
78343 goto exit;
78345 self->private_impl.f_block_uncompressed_size |= (((uint64_t)(1u)) << 63u);
78346 break;
78349 self->private_impl.f_bcj_x86_prev_mask = 0u;
78350 self->private_impl.choosy_apply_non_final_filters = (
78351 &wuffs_xz__decoder__apply_non_final_filters__choosy_default);
78352 v_f = 0u;
78353 while (v_f < self->private_impl.f_num_non_final_filters) {
78355 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
78356 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
78357 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
78358 goto suspend;
78360 uint8_t t_3 = *iop_a_src++;
78361 v_filter_id = t_3;
78363 if (v_filter_id == 33u) {
78364 status = wuffs_base__make_status(wuffs_xz__error__bad_filter);
78365 goto exit;
78366 } else if (v_filter_id == 3u) {
78368 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
78369 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
78370 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
78371 goto suspend;
78373 uint8_t t_4 = *iop_a_src++;
78374 v_c8 = t_4;
78376 if (v_c8 != 1u) {
78377 status = wuffs_base__make_status(wuffs_xz__error__bad_filter);
78378 goto exit;
78381 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
78382 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
78383 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
78384 goto suspend;
78386 uint8_t t_5 = *iop_a_src++;
78387 v_c8 = t_5;
78389 self->private_impl.f_filters[v_f] = ((((uint32_t)(v_c8)) << 8u) | 3u);
78390 v_k = 0u;
78391 while (v_k < 256u) {
78392 self->private_data.f_filter_data[v_f][v_k] = 0u;
78393 v_k += 1u;
78395 } else if ((v_filter_id < 3u) || (11u < v_filter_id)) {
78396 status = wuffs_base__make_status(wuffs_xz__error__unsupported_filter);
78397 goto exit;
78398 } else if (v_f != 0u) {
78399 status = wuffs_base__make_status(wuffs_xz__error__unsupported_filter_combination);
78400 goto exit;
78401 } else {
78402 self->private_impl.f_filters[v_f] = ((uint32_t)(v_filter_id));
78403 if (v_filter_id == 4u) {
78404 self->private_impl.choosy_apply_non_final_filters = (
78405 &wuffs_xz__decoder__apply_filter_04_x86);
78406 } else if (v_filter_id == 5u) {
78407 self->private_impl.choosy_apply_non_final_filters = (
78408 &wuffs_xz__decoder__apply_filter_05_powerpc);
78409 } else if (v_filter_id == 6u) {
78410 self->private_impl.choosy_apply_non_final_filters = (
78411 &wuffs_xz__decoder__apply_filter_06_ia64);
78412 } else if (v_filter_id == 7u) {
78413 self->private_impl.choosy_apply_non_final_filters = (
78414 &wuffs_xz__decoder__apply_filter_07_arm);
78415 } else if (v_filter_id == 8u) {
78416 self->private_impl.choosy_apply_non_final_filters = (
78417 &wuffs_xz__decoder__apply_filter_08_armthumb);
78418 } else if (v_filter_id == 9u) {
78419 self->private_impl.choosy_apply_non_final_filters = (
78420 &wuffs_xz__decoder__apply_filter_09_sparc);
78421 } else if (v_filter_id == 10u) {
78422 self->private_impl.choosy_apply_non_final_filters = (
78423 &wuffs_xz__decoder__apply_filter_0a_arm64);
78424 } else {
78425 self->private_impl.choosy_apply_non_final_filters = (
78426 &wuffs_xz__decoder__apply_filter_0b_riscv);
78429 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
78430 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
78431 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
78432 goto suspend;
78434 uint8_t t_6 = *iop_a_src++;
78435 v_c8 = t_6;
78437 if (v_c8 == 0u) {
78438 self->private_impl.f_bcj_pos = 0u;
78439 } else if (v_c8 == 4u) {
78441 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
78442 uint32_t t_7;
78443 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
78444 t_7 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
78445 iop_a_src += 4;
78446 } else {
78447 self->private_data.s_decode_block_header_sans_padding.scratch = 0;
78448 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
78449 while (true) {
78450 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
78451 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
78452 goto suspend;
78454 uint64_t* scratch = &self->private_data.s_decode_block_header_sans_padding.scratch;
78455 uint32_t num_bits_7 = ((uint32_t)(*scratch >> 56));
78456 *scratch <<= 8;
78457 *scratch >>= 8;
78458 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_7;
78459 if (num_bits_7 == 24) {
78460 t_7 = ((uint32_t)(*scratch));
78461 break;
78463 num_bits_7 += 8u;
78464 *scratch |= ((uint64_t)(num_bits_7)) << 56;
78467 v_c32 = t_7;
78469 v_alignment = ((uint32_t)(WUFFS_XZ__BCJ_OFFSET_ALIGNMENT[v_filter_id]));
78470 if (v_alignment > 0u) {
78471 if ((v_c32 % v_alignment) != 0u) {
78472 status = wuffs_base__make_status(wuffs_xz__error__bad_bcj_offset);
78473 goto exit;
78476 self->private_impl.f_bcj_pos = v_c32;
78477 } else {
78478 status = wuffs_base__make_status(wuffs_xz__error__unsupported_filter);
78479 goto exit;
78482 v_f += 1u;
78485 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
78486 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
78487 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
78488 goto suspend;
78490 uint8_t t_8 = *iop_a_src++;
78491 v_filter_id = t_8;
78493 if (v_filter_id == 33u) {
78494 if (self->private_impl.f_lzma_needs_reset) {
78495 wuffs_private_impl__ignore_status(wuffs_lzma__decoder__initialize(&self->private_data.f_lzma,
78496 sizeof (wuffs_lzma__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
78499 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
78500 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
78501 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
78502 goto suspend;
78504 uint8_t t_9 = *iop_a_src++;
78505 v_c8 = t_9;
78507 if (v_c8 != 1u) {
78508 status = wuffs_base__make_status(wuffs_xz__error__bad_filter);
78509 goto exit;
78512 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
78513 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
78514 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
78515 goto suspend;
78517 uint8_t t_10 = *iop_a_src++;
78518 v_c8 = t_10;
78520 v_status = wuffs_lzma__decoder__set_quirk(&self->private_data.f_lzma, 1348001793u, (2u | (((uint64_t)(v_c8)) << 8u)));
78521 if ( ! wuffs_base__status__is_ok(&v_status)) {
78522 status = wuffs_base__make_status(wuffs_xz__error__bad_filter);
78523 goto exit;
78525 } else if ((v_filter_id < 3u) || (11u < v_filter_id)) {
78526 status = wuffs_base__make_status(wuffs_xz__error__unsupported_filter);
78527 goto exit;
78528 } else {
78529 status = wuffs_base__make_status(wuffs_xz__error__bad_filter);
78530 goto exit;
78533 goto ok;
78535 self->private_impl.p_decode_block_header_sans_padding = 0;
78536 goto exit;
78539 goto suspend;
78540 suspend:
78541 self->private_impl.p_decode_block_header_sans_padding = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
78542 self->private_data.s_decode_block_header_sans_padding.v_flags = v_flags;
78543 self->private_data.s_decode_block_header_sans_padding.v_filter_id = v_filter_id;
78544 self->private_data.s_decode_block_header_sans_padding.v_shift = v_shift;
78545 self->private_data.s_decode_block_header_sans_padding.v_f = v_f;
78547 goto exit;
78548 exit:
78549 if (a_src && a_src->data.ptr) {
78550 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
78553 return status;
78556 // -------- func xz.decoder.verify_index
78558 WUFFS_BASE__GENERATED_C_CODE
78559 static wuffs_base__status
78560 wuffs_xz__decoder__verify_index(
78561 wuffs_xz__decoder* self,
78562 wuffs_base__io_buffer* a_src) {
78563 wuffs_base__status status = wuffs_base__make_status(NULL);
78565 uint8_t v_c8 = 0;
78566 uint32_t v_shift = 0;
78567 uint32_t v_hash = 0;
78569 const uint8_t* iop_a_src = NULL;
78570 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
78571 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
78572 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
78573 if (a_src && a_src->data.ptr) {
78574 io0_a_src = a_src->data.ptr;
78575 io1_a_src = io0_a_src + a_src->meta.ri;
78576 iop_a_src = io1_a_src;
78577 io2_a_src = io0_a_src + a_src->meta.wi;
78580 uint32_t coro_susp_point = self->private_impl.p_verify_index;
78581 if (coro_susp_point) {
78582 v_shift = self->private_data.s_verify_index.v_shift;
78584 switch (coro_susp_point) {
78585 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
78587 if ( ! self->private_impl.f_started_verify_index) {
78588 self->private_impl.f_started_verify_index = true;
78590 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
78591 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
78592 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
78593 goto suspend;
78595 uint8_t t_0 = *iop_a_src++;
78596 v_c8 = t_0;
78598 if (v_c8 != 0u) {
78599 status = wuffs_base__make_status(wuffs_xz__error__bad_index);
78600 goto exit;
78602 self->private_impl.f_num_index_blocks = 0u;
78603 v_shift = 0u;
78604 while (true) {
78606 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
78607 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
78608 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
78609 goto suspend;
78611 uint8_t t_1 = *iop_a_src++;
78612 v_c8 = t_1;
78614 if (v_shift <= 56u) {
78615 self->private_impl.f_num_index_blocks |= (((uint64_t)(((uint8_t)(v_c8 & 127u)))) << v_shift);
78616 if (v_c8 >= 128u) {
78617 v_shift += 7u;
78618 continue;
78619 } else if ((v_c8 == 0u) && (v_shift > 0u)) {
78620 status = wuffs_base__make_status(wuffs_xz__error__bad_index);
78621 goto exit;
78623 break;
78624 } else if (v_c8 != 1u) {
78625 status = wuffs_base__make_status(wuffs_xz__error__bad_index);
78626 goto exit;
78628 self->private_impl.f_num_index_blocks |= (((uint64_t)(1u)) << 63u);
78629 break;
78631 if (self->private_impl.f_num_index_blocks != self->private_impl.f_num_actual_blocks) {
78632 status = wuffs_base__make_status(wuffs_xz__error__bad_index);
78633 goto exit;
78636 while (self->private_impl.f_num_index_blocks > 0u) {
78637 self->private_impl.f_num_index_blocks -= 1u;
78638 self->private_impl.f_index_block_compressed_size = 0u;
78639 v_shift = 0u;
78640 while (true) {
78642 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
78643 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
78644 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
78645 goto suspend;
78647 uint8_t t_2 = *iop_a_src++;
78648 v_c8 = t_2;
78650 if (v_shift <= 56u) {
78651 self->private_impl.f_index_block_compressed_size |= (((uint64_t)(((uint8_t)(v_c8 & 127u)))) << v_shift);
78652 if (v_c8 >= 128u) {
78653 v_shift += 7u;
78654 continue;
78655 } else if ((v_c8 == 0u) && (v_shift > 0u)) {
78656 status = wuffs_base__make_status(wuffs_xz__error__bad_index);
78657 goto exit;
78659 break;
78660 } else if (v_c8 != 1u) {
78661 status = wuffs_base__make_status(wuffs_xz__error__bad_index);
78662 goto exit;
78664 self->private_impl.f_index_block_compressed_size |= (((uint64_t)(1u)) << 63u);
78665 break;
78667 self->private_impl.f_index_block_uncompressed_size = 0u;
78668 v_shift = 0u;
78669 while (true) {
78671 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
78672 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
78673 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
78674 goto suspend;
78676 uint8_t t_3 = *iop_a_src++;
78677 v_c8 = t_3;
78679 if (v_shift <= 56u) {
78680 self->private_impl.f_index_block_uncompressed_size |= (((uint64_t)(((uint8_t)(v_c8 & 127u)))) << v_shift);
78681 if (v_c8 >= 128u) {
78682 v_shift += 7u;
78683 continue;
78684 } else if ((v_c8 == 0u) && (v_shift > 0u)) {
78685 status = wuffs_base__make_status(wuffs_xz__error__bad_index);
78686 goto exit;
78688 break;
78689 } else if (v_c8 != 1u) {
78690 status = wuffs_base__make_status(wuffs_xz__error__bad_index);
78691 goto exit;
78693 self->private_impl.f_index_block_uncompressed_size |= (((uint64_t)(1u)) << 63u);
78694 break;
78696 self->private_impl.f_verification_want_total_sizes[0u] += self->private_impl.f_index_block_compressed_size;
78697 v_hash = ((uint32_t)((self->private_impl.f_index_block_compressed_size ^ (self->private_impl.f_index_block_compressed_size >> 32u))));
78698 v_hash *= 3432918353u;
78699 v_hash = (((uint32_t)(v_hash << 15u)) | (v_hash >> 17u));
78700 v_hash *= 461845907u;
78701 v_hash ^= self->private_impl.f_verification_want_hashed_sizes[0u];
78702 v_hash = (((uint32_t)(v_hash << 13u)) | (v_hash >> 19u));
78703 self->private_impl.f_verification_want_hashed_sizes[0u] = ((uint32_t)(((uint32_t)(v_hash * 5u)) + 3864292196u));
78704 self->private_impl.f_verification_want_total_sizes[1u] += self->private_impl.f_index_block_uncompressed_size;
78705 v_hash = ((uint32_t)((self->private_impl.f_index_block_uncompressed_size ^ (self->private_impl.f_index_block_uncompressed_size >> 32u))));
78706 v_hash *= 3432918353u;
78707 v_hash = (((uint32_t)(v_hash << 15u)) | (v_hash >> 17u));
78708 v_hash *= 461845907u;
78709 v_hash ^= self->private_impl.f_verification_want_hashed_sizes[1u];
78710 v_hash = (((uint32_t)(v_hash << 13u)) | (v_hash >> 19u));
78711 self->private_impl.f_verification_want_hashed_sizes[1u] = ((uint32_t)(((uint32_t)(v_hash * 5u)) + 3864292196u));
78713 if ((self->private_impl.f_verification_have_hashed_sizes[0u] != self->private_impl.f_verification_want_hashed_sizes[0u]) ||
78714 (self->private_impl.f_verification_have_hashed_sizes[1u] != self->private_impl.f_verification_want_hashed_sizes[1u]) ||
78715 (self->private_impl.f_verification_have_total_sizes[0u] != self->private_impl.f_verification_want_total_sizes[0u]) ||
78716 (self->private_impl.f_verification_have_total_sizes[1u] != self->private_impl.f_verification_want_total_sizes[1u])) {
78717 status = wuffs_base__make_status(wuffs_xz__error__bad_index);
78718 goto exit;
78721 goto ok;
78723 self->private_impl.p_verify_index = 0;
78724 goto exit;
78727 goto suspend;
78728 suspend:
78729 self->private_impl.p_verify_index = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
78730 self->private_data.s_verify_index.v_shift = v_shift;
78732 goto exit;
78733 exit:
78734 if (a_src && a_src->data.ptr) {
78735 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
78738 return status;
78741 // -------- func xz.decoder.verify_footer
78743 WUFFS_BASE__GENERATED_C_CODE
78744 static wuffs_base__status
78745 wuffs_xz__decoder__verify_footer(
78746 wuffs_xz__decoder* self,
78747 wuffs_base__io_buffer* a_src) {
78748 wuffs_base__status status = wuffs_base__make_status(NULL);
78750 uint32_t v_c32 = 0;
78752 const uint8_t* iop_a_src = NULL;
78753 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
78754 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
78755 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
78756 if (a_src && a_src->data.ptr) {
78757 io0_a_src = a_src->data.ptr;
78758 io1_a_src = io0_a_src + a_src->meta.ri;
78759 iop_a_src = io1_a_src;
78760 io2_a_src = io0_a_src + a_src->meta.wi;
78763 uint32_t coro_susp_point = self->private_impl.p_verify_footer;
78764 switch (coro_susp_point) {
78765 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
78768 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
78769 uint32_t t_0;
78770 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
78771 t_0 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
78772 iop_a_src += 4;
78773 } else {
78774 self->private_data.s_verify_footer.scratch = 0;
78775 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
78776 while (true) {
78777 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
78778 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
78779 goto suspend;
78781 uint64_t* scratch = &self->private_data.s_verify_footer.scratch;
78782 uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
78783 *scratch <<= 8;
78784 *scratch >>= 8;
78785 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
78786 if (num_bits_0 == 24) {
78787 t_0 = ((uint32_t)(*scratch));
78788 break;
78790 num_bits_0 += 8u;
78791 *scratch |= ((uint64_t)(num_bits_0)) << 56;
78794 v_c32 = t_0;
78796 if (v_c32 != ((uint32_t)(self->private_impl.f_backwards_size))) {
78797 status = wuffs_base__make_status(wuffs_xz__error__bad_footer);
78798 goto exit;
78801 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
78802 uint32_t t_1;
78803 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
78804 t_1 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
78805 iop_a_src += 2;
78806 } else {
78807 self->private_data.s_verify_footer.scratch = 0;
78808 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
78809 while (true) {
78810 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
78811 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
78812 goto suspend;
78814 uint64_t* scratch = &self->private_data.s_verify_footer.scratch;
78815 uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
78816 *scratch <<= 8;
78817 *scratch >>= 8;
78818 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
78819 if (num_bits_1 == 8) {
78820 t_1 = ((uint32_t)(*scratch));
78821 break;
78823 num_bits_1 += 8u;
78824 *scratch |= ((uint64_t)(num_bits_1)) << 56;
78827 v_c32 = t_1;
78829 if (v_c32 != ((uint32_t)(self->private_impl.f_flags))) {
78830 status = wuffs_base__make_status(wuffs_xz__error__bad_footer);
78831 goto exit;
78834 goto ok;
78836 self->private_impl.p_verify_footer = 0;
78837 goto exit;
78840 goto suspend;
78841 suspend:
78842 self->private_impl.p_verify_footer = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
78844 goto exit;
78845 exit:
78846 if (a_src && a_src->data.ptr) {
78847 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
78850 return status;
78853 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XZ)
78855 #if defined(__cplusplus) && defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
78857 // ---------------- Auxiliary - Base
78859 // Auxiliary code is discussed at
78860 // https://github.com/google/wuffs/blob/main/doc/note/auxiliary-code.md
78862 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__AUX__BASE)
78864 namespace wuffs_aux {
78866 namespace sync_io {
78868 // --------
78870 DynIOBuffer::DynIOBuffer(uint64_t max_incl)
78871 : m_buf(wuffs_base__empty_io_buffer()), m_max_incl(max_incl) {}
78873 DynIOBuffer::~DynIOBuffer() {
78874 free(m_buf.data.ptr);
78877 void //
78878 DynIOBuffer::drop() {
78879 free(m_buf.data.ptr);
78880 m_buf = wuffs_base__empty_io_buffer();
78883 DynIOBuffer::GrowResult //
78884 DynIOBuffer::grow(uint64_t min_incl) {
78885 uint64_t n = round_up(min_incl, m_max_incl);
78886 if (n == 0) {
78887 return ((min_incl == 0) && (m_max_incl == 0))
78888 ? DynIOBuffer::GrowResult::OK
78889 : DynIOBuffer::GrowResult::FailedMaxInclExceeded;
78890 } else if (n > SIZE_MAX) {
78891 return DynIOBuffer::GrowResult::FailedOutOfMemory;
78892 } else if (n > m_buf.data.len) {
78893 uint8_t* ptr =
78894 static_cast<uint8_t*>(realloc(m_buf.data.ptr, static_cast<size_t>(n)));
78895 if (!ptr) {
78896 return DynIOBuffer::GrowResult::FailedOutOfMemory;
78898 m_buf.data.ptr = ptr;
78899 m_buf.data.len = static_cast<size_t>(n);
78901 return DynIOBuffer::GrowResult::OK;
78904 // round_up rounds min_incl up, returning the smallest value x satisfying
78905 // (min_incl <= x) and (x <= max_incl) and some other constraints. It returns 0
78906 // if there is no such x.
78908 // When max_incl <= 4096, the other constraints are:
78909 // - (x == max_incl)
78911 // When max_incl > 4096, the other constraints are:
78912 // - (x == max_incl) or (x is a power of 2)
78913 // - (x >= 4096)
78914 uint64_t //
78915 DynIOBuffer::round_up(uint64_t min_incl, uint64_t max_incl) {
78916 if (min_incl > max_incl) {
78917 return 0;
78919 uint64_t n = 4096;
78920 if (n >= max_incl) {
78921 return max_incl;
78923 while (n < min_incl) {
78924 if (n >= (max_incl / 2)) {
78925 return max_incl;
78927 n *= 2;
78929 return n;
78932 // --------
78934 Input::~Input() {}
78936 IOBuffer* //
78937 Input::BringsItsOwnIOBuffer() {
78938 return nullptr;
78941 // --------
78943 FileInput::FileInput(FILE* f) : m_f(f) {}
78945 std::string //
78946 FileInput::CopyIn(IOBuffer* dst) {
78947 if (!m_f) {
78948 return "wuffs_aux::sync_io::FileInput: nullptr file";
78949 } else if (!dst) {
78950 return "wuffs_aux::sync_io::FileInput: nullptr IOBuffer";
78951 } else if (dst->meta.closed) {
78952 return "wuffs_aux::sync_io::FileInput: end of file";
78953 } else {
78954 dst->compact();
78955 size_t n = fread(dst->writer_pointer(), 1, dst->writer_length(), m_f);
78956 dst->meta.wi += n;
78957 dst->meta.closed = feof(m_f);
78958 if (ferror(m_f)) {
78959 return "wuffs_aux::sync_io::FileInput: error reading file";
78962 return "";
78965 // --------
78967 MemoryInput::MemoryInput(const char* ptr, size_t len)
78968 : m_io(wuffs_base__ptr_u8__reader(
78969 static_cast<uint8_t*>(static_cast<void*>(const_cast<char*>(ptr))),
78970 len,
78971 true)) {}
78973 MemoryInput::MemoryInput(const uint8_t* ptr, size_t len)
78974 : m_io(wuffs_base__ptr_u8__reader(const_cast<uint8_t*>(ptr), len, true)) {}
78976 IOBuffer* //
78977 MemoryInput::BringsItsOwnIOBuffer() {
78978 return &m_io;
78981 std::string //
78982 MemoryInput::CopyIn(IOBuffer* dst) {
78983 if (!dst) {
78984 return "wuffs_aux::sync_io::MemoryInput: nullptr IOBuffer";
78985 } else if (dst->meta.closed) {
78986 return "wuffs_aux::sync_io::MemoryInput: end of file";
78987 } else if (wuffs_base__slice_u8__overlaps(dst->data, m_io.data)) {
78988 // Treat m_io's data as immutable, so don't compact dst or otherwise write
78989 // to it.
78990 return "wuffs_aux::sync_io::MemoryInput: overlapping buffers";
78991 } else {
78992 dst->compact();
78993 size_t nd = dst->writer_length();
78994 size_t ns = m_io.reader_length();
78995 size_t n = (nd < ns) ? nd : ns;
78996 memcpy(dst->writer_pointer(), m_io.reader_pointer(), n);
78997 m_io.meta.ri += n;
78998 dst->meta.wi += n;
78999 dst->meta.closed = m_io.reader_length() == 0;
79001 return "";
79004 // --------
79006 } // namespace sync_io
79008 namespace private_impl {
79010 struct ErrorMessages {
79011 const char* max_incl_metadata_length_exceeded;
79012 const char* out_of_memory;
79013 const char* unexpected_end_of_file;
79014 const char* unsupported_metadata;
79015 const char* unsupported_negative_advance;
79017 // If adding new "const char*" typed fields to this struct, either add them
79018 // after existing fields or, if re-ordering fields, make sure that you update
79019 // all of the "const private_impl::ErrorMessages FooBarErrorMessages" values
79020 // in all of the sibling *.cc files.
79022 static inline const char* resolve(const char* s) {
79023 return s ? s : "wuffs_aux::private_impl: unknown error";
79027 std::string //
79028 AdvanceIOBufferTo(const ErrorMessages& error_messages,
79029 sync_io::Input& input,
79030 IOBuffer& io_buf,
79031 uint64_t absolute_position) {
79032 if (absolute_position < io_buf.reader_position()) {
79033 return error_messages.resolve(error_messages.unsupported_negative_advance);
79035 while (true) {
79036 uint64_t relative_position = absolute_position - io_buf.reader_position();
79037 if (relative_position <= io_buf.reader_length()) {
79038 io_buf.meta.ri += (size_t)relative_position;
79039 break;
79040 } else if (io_buf.meta.closed) {
79041 return error_messages.resolve(error_messages.unexpected_end_of_file);
79043 io_buf.meta.ri = io_buf.meta.wi;
79044 if (!input.BringsItsOwnIOBuffer()) {
79045 io_buf.compact();
79047 std::string error_message = input.CopyIn(&io_buf);
79048 if (!error_message.empty()) {
79049 return error_message;
79052 return "";
79055 std::string //
79056 HandleMetadata(
79057 const ErrorMessages& error_messages,
79058 sync_io::Input& input,
79059 wuffs_base__io_buffer& io_buf,
79060 sync_io::DynIOBuffer& raw,
79061 wuffs_base__status (*tell_me_more_func)(void*,
79062 wuffs_base__io_buffer*,
79063 wuffs_base__more_information*,
79064 wuffs_base__io_buffer*),
79065 void* tell_me_more_receiver,
79066 std::string (*handle_metadata_func)(void*,
79067 const wuffs_base__more_information*,
79068 wuffs_base__slice_u8),
79069 void* handle_metadata_receiver) {
79070 wuffs_base__more_information minfo = wuffs_base__empty_more_information();
79071 // Reset raw but keep its backing array (the raw.m_buf.data slice).
79072 raw.m_buf.meta = wuffs_base__empty_io_buffer_meta();
79074 while (true) {
79075 minfo = wuffs_base__empty_more_information();
79076 wuffs_base__status status = (*tell_me_more_func)(
79077 tell_me_more_receiver, &raw.m_buf, &minfo, &io_buf);
79078 switch (minfo.flavor) {
79079 case 0:
79080 case WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_RAW_TRANSFORM:
79081 case WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_PARSED:
79082 break;
79084 case WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_RAW_PASSTHROUGH: {
79085 wuffs_base__range_ie_u64 r = minfo.metadata_raw_passthrough__range();
79086 if (r.is_empty()) {
79087 break;
79089 uint64_t num_to_copy = r.length();
79090 if (num_to_copy > (raw.m_max_incl - raw.m_buf.meta.wi)) {
79091 return error_messages.resolve(
79092 error_messages.max_incl_metadata_length_exceeded);
79093 } else if (num_to_copy > (raw.m_buf.data.len - raw.m_buf.meta.wi)) {
79094 switch (raw.grow(num_to_copy + raw.m_buf.meta.wi)) {
79095 case sync_io::DynIOBuffer::GrowResult::OK:
79096 break;
79097 case sync_io::DynIOBuffer::GrowResult::FailedMaxInclExceeded:
79098 return error_messages.resolve(
79099 error_messages.max_incl_metadata_length_exceeded);
79100 case sync_io::DynIOBuffer::GrowResult::FailedOutOfMemory:
79101 return error_messages.resolve(error_messages.out_of_memory);
79105 if (io_buf.reader_position() > r.min_incl) {
79106 return error_messages.resolve(error_messages.unsupported_metadata);
79107 } else {
79108 std::string error_message =
79109 AdvanceIOBufferTo(error_messages, input, io_buf, r.min_incl);
79110 if (!error_message.empty()) {
79111 return error_message;
79115 while (true) {
79116 uint64_t n =
79117 wuffs_base__u64__min(num_to_copy, io_buf.reader_length());
79118 memcpy(raw.m_buf.writer_pointer(), io_buf.reader_pointer(), n);
79119 raw.m_buf.meta.wi += n;
79120 io_buf.meta.ri += n;
79121 num_to_copy -= n;
79122 if (num_to_copy == 0) {
79123 break;
79124 } else if (io_buf.meta.closed) {
79125 return error_messages.resolve(
79126 error_messages.unexpected_end_of_file);
79127 } else if (!input.BringsItsOwnIOBuffer()) {
79128 io_buf.compact();
79130 std::string error_message = input.CopyIn(&io_buf);
79131 if (!error_message.empty()) {
79132 return error_message;
79135 break;
79138 default:
79139 return error_messages.resolve(error_messages.unsupported_metadata);
79142 if (status.repr == nullptr) {
79143 break;
79144 } else if (status.repr != wuffs_base__suspension__even_more_information) {
79145 if (status.repr != wuffs_base__suspension__short_write) {
79146 return status.message();
79148 switch (raw.grow(wuffs_base__u64__sat_add(raw.m_buf.data.len, 1))) {
79149 case sync_io::DynIOBuffer::GrowResult::OK:
79150 break;
79151 case sync_io::DynIOBuffer::GrowResult::FailedMaxInclExceeded:
79152 return error_messages.resolve(
79153 error_messages.max_incl_metadata_length_exceeded);
79154 case sync_io::DynIOBuffer::GrowResult::FailedOutOfMemory:
79155 return error_messages.resolve(error_messages.out_of_memory);
79160 return (*handle_metadata_func)(handle_metadata_receiver, &minfo,
79161 raw.m_buf.reader_slice());
79164 } // namespace private_impl
79166 } // namespace wuffs_aux
79168 #endif // !defined(WUFFS_CONFIG__MODULES) ||
79169 // defined(WUFFS_CONFIG__MODULE__AUX__BASE)
79171 // ---------------- Auxiliary - CBOR
79173 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__AUX__CBOR)
79175 #include <utility>
79177 namespace wuffs_aux {
79179 DecodeCborResult::DecodeCborResult(std::string&& error_message0,
79180 uint64_t cursor_position0)
79181 : error_message(std::move(error_message0)),
79182 cursor_position(cursor_position0) {}
79184 DecodeCborCallbacks::~DecodeCborCallbacks() {}
79186 void //
79187 DecodeCborCallbacks::Done(DecodeCborResult& result,
79188 sync_io::Input& input,
79189 IOBuffer& buffer) {}
79191 DecodeCborArgQuirks::DecodeCborArgQuirks(const QuirkKeyValuePair* ptr0,
79192 const size_t len0)
79193 : ptr(ptr0), len(len0) {}
79195 DecodeCborArgQuirks //
79196 DecodeCborArgQuirks::DefaultValue() {
79197 return DecodeCborArgQuirks(nullptr, 0);
79200 DecodeCborResult //
79201 DecodeCbor(DecodeCborCallbacks& callbacks,
79202 sync_io::Input& input,
79203 DecodeCborArgQuirks quirks) {
79204 // Prepare the wuffs_base__io_buffer and the resultant error_message.
79205 wuffs_base__io_buffer* io_buf = input.BringsItsOwnIOBuffer();
79206 wuffs_base__io_buffer fallback_io_buf = wuffs_base__empty_io_buffer();
79207 std::unique_ptr<uint8_t[]> fallback_io_array(nullptr);
79208 if (!io_buf) {
79209 fallback_io_array = std::unique_ptr<uint8_t[]>(new uint8_t[4096]);
79210 fallback_io_buf = wuffs_base__ptr_u8__writer(fallback_io_array.get(), 4096);
79211 io_buf = &fallback_io_buf;
79213 // cursor_index is discussed at
79214 // https://nigeltao.github.io/blog/2020/jsonptr.html#the-cursor-index
79215 size_t cursor_index = 0;
79216 std::string ret_error_message;
79217 std::string io_error_message;
79219 do {
79220 // Prepare the low-level CBOR decoder.
79221 wuffs_cbor__decoder::unique_ptr dec = wuffs_cbor__decoder::alloc();
79222 if (!dec) {
79223 ret_error_message = "wuffs_aux::DecodeCbor: out of memory";
79224 goto done;
79226 for (size_t i = 0; i < quirks.len; i++) {
79227 dec->set_quirk(quirks.ptr[i].first, quirks.ptr[i].second);
79230 // Prepare the wuffs_base__tok_buffer. 256 tokens is 2KiB.
79231 wuffs_base__token tok_array[256];
79232 wuffs_base__token_buffer tok_buf =
79233 wuffs_base__slice_token__writer(wuffs_base__make_slice_token(
79234 &tok_array[0], (sizeof(tok_array) / sizeof(tok_array[0]))));
79235 wuffs_base__status tok_status = wuffs_base__make_status(nullptr);
79237 // Prepare other state.
79238 int32_t depth = 0;
79239 std::string str;
79240 int64_t extension_category = 0;
79241 uint64_t extension_detail = 0;
79243 // Valid token's VBCs range in 0 ..= 15. Values over that are for tokens
79244 // from outside of the base package, such as the CBOR package.
79245 constexpr int64_t EXT_CAT__CBOR_TAG = 16;
79247 // Loop, doing these two things:
79248 // 1. Get the next token.
79249 // 2. Process that token.
79250 while (true) {
79251 // 1. Get the next token.
79253 while (tok_buf.meta.ri >= tok_buf.meta.wi) {
79254 if (tok_status.repr == nullptr) {
79255 // No-op.
79256 } else if (tok_status.repr == wuffs_base__suspension__short_write) {
79257 tok_buf.compact();
79258 } else if (tok_status.repr == wuffs_base__suspension__short_read) {
79259 // Read from input to io_buf.
79260 if (!io_error_message.empty()) {
79261 ret_error_message = std::move(io_error_message);
79262 goto done;
79263 } else if (cursor_index != io_buf->meta.ri) {
79264 ret_error_message =
79265 "wuffs_aux::DecodeCbor: internal error: bad cursor_index";
79266 goto done;
79267 } else if (io_buf->meta.closed) {
79268 ret_error_message =
79269 "wuffs_aux::DecodeCbor: internal error: io_buf is closed";
79270 goto done;
79272 io_buf->compact();
79273 if (io_buf->meta.wi >= io_buf->data.len) {
79274 ret_error_message =
79275 "wuffs_aux::DecodeCbor: internal error: io_buf is full";
79276 goto done;
79278 cursor_index = io_buf->meta.ri;
79279 io_error_message = input.CopyIn(io_buf);
79280 } else {
79281 ret_error_message = tok_status.message();
79282 goto done;
79285 if (WUFFS_CBOR__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE != 0) {
79286 ret_error_message =
79287 "wuffs_aux::DecodeCbor: internal error: bad WORKBUF_LEN";
79288 goto done;
79290 wuffs_base__slice_u8 work_buf = wuffs_base__empty_slice_u8();
79291 tok_status = dec->decode_tokens(&tok_buf, io_buf, work_buf);
79292 if ((tok_buf.meta.ri > tok_buf.meta.wi) ||
79293 (tok_buf.meta.wi > tok_buf.data.len) ||
79294 (io_buf->meta.ri > io_buf->meta.wi) ||
79295 (io_buf->meta.wi > io_buf->data.len)) {
79296 ret_error_message =
79297 "wuffs_aux::DecodeCbor: internal error: bad buffer indexes";
79298 goto done;
79302 wuffs_base__token token = tok_buf.data.ptr[tok_buf.meta.ri++];
79303 uint64_t token_len = token.length();
79304 if ((io_buf->meta.ri < cursor_index) ||
79305 ((io_buf->meta.ri - cursor_index) < token_len)) {
79306 ret_error_message =
79307 "wuffs_aux::DecodeCbor: internal error: bad token indexes";
79308 goto done;
79310 uint8_t* token_ptr = io_buf->data.ptr + cursor_index;
79311 cursor_index += static_cast<size_t>(token_len);
79313 // 2. Process that token.
79315 uint64_t vbd = token.value_base_detail();
79317 if (extension_category != 0) {
79318 int64_t ext = token.value_extension();
79319 if ((ext >= 0) && !token.continued()) {
79320 extension_detail = (extension_detail
79321 << WUFFS_BASE__TOKEN__VALUE_EXTENSION__NUM_BITS) |
79322 static_cast<uint64_t>(ext);
79323 switch (extension_category) {
79324 case WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_SIGNED:
79325 extension_category = 0;
79326 ret_error_message =
79327 callbacks.AppendI64(static_cast<int64_t>(extension_detail));
79328 goto parsed_a_value;
79329 case WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_UNSIGNED:
79330 extension_category = 0;
79331 ret_error_message = callbacks.AppendU64(extension_detail);
79332 goto parsed_a_value;
79333 case EXT_CAT__CBOR_TAG:
79334 extension_category = 0;
79335 ret_error_message = callbacks.AppendCborTag(extension_detail);
79336 if (!ret_error_message.empty()) {
79337 goto done;
79339 continue;
79342 ret_error_message =
79343 "wuffs_aux::DecodeCbor: internal error: bad extended token";
79344 goto done;
79347 switch (token.value_base_category()) {
79348 case WUFFS_BASE__TOKEN__VBC__FILLER:
79349 continue;
79351 case WUFFS_BASE__TOKEN__VBC__STRUCTURE: {
79352 if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {
79353 ret_error_message = callbacks.Push(static_cast<uint32_t>(vbd));
79354 if (!ret_error_message.empty()) {
79355 goto done;
79357 depth++;
79358 if (depth > (int32_t)WUFFS_CBOR__DECODER_DEPTH_MAX_INCL) {
79359 ret_error_message =
79360 "wuffs_aux::DecodeCbor: internal error: bad depth";
79361 goto done;
79363 continue;
79365 ret_error_message = callbacks.Pop(static_cast<uint32_t>(vbd));
79366 depth--;
79367 if (depth < 0) {
79368 ret_error_message =
79369 "wuffs_aux::DecodeCbor: internal error: bad depth";
79370 goto done;
79372 goto parsed_a_value;
79375 case WUFFS_BASE__TOKEN__VBC__STRING: {
79376 if (vbd & WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_0_DST_1_SRC_DROP) {
79377 // No-op.
79378 } else if (vbd &
79379 WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_1_SRC_COPY) {
79380 const char* ptr = // Convert from (uint8_t*).
79381 static_cast<const char*>(static_cast<void*>(token_ptr));
79382 str.append(ptr, static_cast<size_t>(token_len));
79383 } else {
79384 goto fail;
79386 if (token.continued()) {
79387 continue;
79389 ret_error_message =
79390 (vbd & WUFFS_BASE__TOKEN__VBD__STRING__CHAIN_MUST_BE_UTF_8)
79391 ? callbacks.AppendTextString(std::move(str))
79392 : callbacks.AppendByteString(std::move(str));
79393 str.clear();
79394 goto parsed_a_value;
79397 case WUFFS_BASE__TOKEN__VBC__UNICODE_CODE_POINT: {
79398 uint8_t u[WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL];
79399 size_t n = wuffs_base__utf_8__encode(
79400 wuffs_base__make_slice_u8(
79401 &u[0], WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL),
79402 static_cast<uint32_t>(vbd));
79403 const char* ptr = // Convert from (uint8_t*).
79404 static_cast<const char*>(static_cast<void*>(&u[0]));
79405 str.append(ptr, n);
79406 if (token.continued()) {
79407 continue;
79409 goto fail;
79412 case WUFFS_BASE__TOKEN__VBC__LITERAL: {
79413 if (vbd & WUFFS_BASE__TOKEN__VBD__LITERAL__NULL) {
79414 ret_error_message = callbacks.AppendNull();
79415 } else if (vbd & WUFFS_BASE__TOKEN__VBD__LITERAL__UNDEFINED) {
79416 ret_error_message = callbacks.AppendUndefined();
79417 } else {
79418 ret_error_message = callbacks.AppendBool(
79419 vbd & WUFFS_BASE__TOKEN__VBD__LITERAL__TRUE);
79421 goto parsed_a_value;
79424 case WUFFS_BASE__TOKEN__VBC__NUMBER: {
79425 const uint64_t cfp_fbbe_fifb =
79426 WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_FLOATING_POINT |
79427 WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_BINARY_BIG_ENDIAN |
79428 WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_IGNORE_FIRST_BYTE;
79429 if ((vbd & cfp_fbbe_fifb) == cfp_fbbe_fifb) {
79430 double f;
79431 switch (token_len) {
79432 case 3:
79433 f = wuffs_base__ieee_754_bit_representation__from_u16_to_f64(
79434 wuffs_base__peek_u16be__no_bounds_check(token_ptr + 1));
79435 break;
79436 case 5:
79437 f = wuffs_base__ieee_754_bit_representation__from_u32_to_f64(
79438 wuffs_base__peek_u32be__no_bounds_check(token_ptr + 1));
79439 break;
79440 case 9:
79441 f = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
79442 wuffs_base__peek_u64be__no_bounds_check(token_ptr + 1));
79443 break;
79444 default:
79445 goto fail;
79447 ret_error_message = callbacks.AppendF64(f);
79448 goto parsed_a_value;
79450 goto fail;
79453 case WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_SIGNED: {
79454 if (token.continued()) {
79455 extension_category = WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_SIGNED;
79456 extension_detail =
79457 static_cast<uint64_t>(token.value_base_detail__sign_extended());
79458 continue;
79460 ret_error_message =
79461 callbacks.AppendI64(token.value_base_detail__sign_extended());
79462 goto parsed_a_value;
79465 case WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_UNSIGNED: {
79466 if (token.continued()) {
79467 extension_category =
79468 WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_UNSIGNED;
79469 extension_detail = vbd;
79470 continue;
79472 ret_error_message = callbacks.AppendU64(vbd);
79473 goto parsed_a_value;
79477 if (token.value_major() == WUFFS_CBOR__TOKEN_VALUE_MAJOR) {
79478 uint64_t value_minor = token.value_minor();
79479 if (value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__MINUS_1_MINUS_X) {
79480 if (token_len == 9) {
79481 ret_error_message = callbacks.AppendMinus1MinusX(
79482 wuffs_base__peek_u64be__no_bounds_check(token_ptr + 1));
79483 goto parsed_a_value;
79485 } else if (value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__SIMPLE_VALUE) {
79486 ret_error_message =
79487 callbacks.AppendCborSimpleValue(static_cast<uint8_t>(
79488 value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__DETAIL_MASK));
79489 goto parsed_a_value;
79490 } else if (value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__TAG) {
79491 if (token.continued()) {
79492 extension_category = EXT_CAT__CBOR_TAG;
79493 extension_detail =
79494 value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__DETAIL_MASK;
79495 continue;
79497 ret_error_message = callbacks.AppendCborTag(
79498 value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__DETAIL_MASK);
79499 if (!ret_error_message.empty()) {
79500 goto done;
79502 continue;
79506 fail:
79507 ret_error_message =
79508 "wuffs_aux::DecodeCbor: internal error: unexpected token";
79509 goto done;
79511 parsed_a_value:
79512 if (!ret_error_message.empty() || (depth == 0)) {
79513 goto done;
79516 } while (false);
79518 done:
79519 DecodeCborResult result(
79520 std::move(ret_error_message),
79521 wuffs_base__u64__sat_add(io_buf->meta.pos, cursor_index));
79522 callbacks.Done(result, input, *io_buf);
79523 return result;
79526 } // namespace wuffs_aux
79528 #endif // !defined(WUFFS_CONFIG__MODULES) ||
79529 // defined(WUFFS_CONFIG__MODULE__AUX__CBOR)
79531 // ---------------- Auxiliary - Image
79533 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__AUX__IMAGE)
79535 #include <utility>
79537 namespace wuffs_aux {
79539 DecodeImageResult::DecodeImageResult(MemOwner&& pixbuf_mem_owner0,
79540 wuffs_base__pixel_buffer pixbuf0,
79541 std::string&& error_message0)
79542 : pixbuf_mem_owner(std::move(pixbuf_mem_owner0)),
79543 pixbuf(pixbuf0),
79544 error_message(std::move(error_message0)) {}
79546 DecodeImageResult::DecodeImageResult(std::string&& error_message0)
79547 : pixbuf_mem_owner(nullptr, &free),
79548 pixbuf(wuffs_base__null_pixel_buffer()),
79549 error_message(std::move(error_message0)) {}
79551 DecodeImageCallbacks::~DecodeImageCallbacks() {}
79553 DecodeImageCallbacks::AllocPixbufResult::AllocPixbufResult(
79554 MemOwner&& mem_owner0,
79555 wuffs_base__pixel_buffer pixbuf0)
79556 : mem_owner(std::move(mem_owner0)), pixbuf(pixbuf0), error_message("") {}
79558 DecodeImageCallbacks::AllocPixbufResult::AllocPixbufResult(
79559 std::string&& error_message0)
79560 : mem_owner(nullptr, &free),
79561 pixbuf(wuffs_base__null_pixel_buffer()),
79562 error_message(std::move(error_message0)) {}
79564 DecodeImageCallbacks::AllocWorkbufResult::AllocWorkbufResult(
79565 MemOwner&& mem_owner0,
79566 wuffs_base__slice_u8 workbuf0)
79567 : mem_owner(std::move(mem_owner0)), workbuf(workbuf0), error_message("") {}
79569 DecodeImageCallbacks::AllocWorkbufResult::AllocWorkbufResult(
79570 std::string&& error_message0)
79571 : mem_owner(nullptr, &free),
79572 workbuf(wuffs_base__empty_slice_u8()),
79573 error_message(std::move(error_message0)) {}
79575 wuffs_base__image_decoder::unique_ptr //
79576 DecodeImageCallbacks::SelectDecoder(uint32_t fourcc,
79577 wuffs_base__slice_u8 prefix_data,
79578 bool prefix_closed) {
79579 switch (fourcc) {
79580 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BMP)
79581 case WUFFS_BASE__FOURCC__BMP:
79582 return wuffs_bmp__decoder::alloc_as__wuffs_base__image_decoder();
79583 #endif
79585 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GIF)
79586 case WUFFS_BASE__FOURCC__GIF:
79587 return wuffs_gif__decoder::alloc_as__wuffs_base__image_decoder();
79588 #endif
79590 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JPEG)
79591 case WUFFS_BASE__FOURCC__JPEG:
79592 return wuffs_jpeg__decoder::alloc_as__wuffs_base__image_decoder();
79593 #endif
79595 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NIE)
79596 case WUFFS_BASE__FOURCC__NIE:
79597 return wuffs_nie__decoder::alloc_as__wuffs_base__image_decoder();
79598 #endif
79600 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NETPBM)
79601 case WUFFS_BASE__FOURCC__NPBM:
79602 return wuffs_netpbm__decoder::alloc_as__wuffs_base__image_decoder();
79603 #endif
79605 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__PNG)
79606 case WUFFS_BASE__FOURCC__PNG: {
79607 auto dec = wuffs_png__decoder::alloc_as__wuffs_base__image_decoder();
79608 // Favor faster decodes over rejecting invalid checksums.
79609 dec->set_quirk(WUFFS_BASE__QUIRK_IGNORE_CHECKSUM, 1);
79610 return dec;
79612 #endif
79614 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__QOI)
79615 case WUFFS_BASE__FOURCC__QOI:
79616 return wuffs_qoi__decoder::alloc_as__wuffs_base__image_decoder();
79617 #endif
79619 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__TGA)
79620 case WUFFS_BASE__FOURCC__TGA:
79621 return wuffs_tga__decoder::alloc_as__wuffs_base__image_decoder();
79622 #endif
79624 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP)
79625 case WUFFS_BASE__FOURCC__WBMP:
79626 return wuffs_wbmp__decoder::alloc_as__wuffs_base__image_decoder();
79627 #endif
79629 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WEBP)
79630 case WUFFS_BASE__FOURCC__WEBP:
79631 return wuffs_webp__decoder::alloc_as__wuffs_base__image_decoder();
79632 #endif
79635 return wuffs_base__image_decoder::unique_ptr(nullptr);
79638 std::string //
79639 DecodeImageCallbacks::HandleMetadata(const wuffs_base__more_information& minfo,
79640 wuffs_base__slice_u8 raw) {
79641 return "";
79644 wuffs_base__pixel_format //
79645 DecodeImageCallbacks::SelectPixfmt(
79646 const wuffs_base__image_config& image_config) {
79647 return wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL);
79650 DecodeImageCallbacks::AllocPixbufResult //
79651 DecodeImageCallbacks::AllocPixbuf(const wuffs_base__image_config& image_config,
79652 bool allow_uninitialized_memory) {
79653 uint32_t w = image_config.pixcfg.width();
79654 uint32_t h = image_config.pixcfg.height();
79655 if ((w == 0) || (h == 0)) {
79656 return AllocPixbufResult("");
79658 uint64_t len = image_config.pixcfg.pixbuf_len();
79659 if ((len == 0) || (SIZE_MAX < len)) {
79660 return AllocPixbufResult(DecodeImage_UnsupportedPixelConfiguration);
79662 void* ptr =
79663 allow_uninitialized_memory ? malloc((size_t)len) : calloc(1, (size_t)len);
79664 if (!ptr) {
79665 return AllocPixbufResult(DecodeImage_OutOfMemory);
79667 wuffs_base__pixel_buffer pixbuf;
79668 wuffs_base__status status = pixbuf.set_from_slice(
79669 &image_config.pixcfg,
79670 wuffs_base__make_slice_u8((uint8_t*)ptr, (size_t)len));
79671 if (!status.is_ok()) {
79672 free(ptr);
79673 return AllocPixbufResult(status.message());
79675 return AllocPixbufResult(MemOwner(ptr, &free), pixbuf);
79678 DecodeImageCallbacks::AllocWorkbufResult //
79679 DecodeImageCallbacks::AllocWorkbuf(wuffs_base__range_ii_u64 len_range,
79680 bool allow_uninitialized_memory) {
79681 uint64_t len = len_range.max_incl;
79682 if (len == 0) {
79683 return AllocWorkbufResult("");
79684 } else if (SIZE_MAX < len) {
79685 return AllocWorkbufResult(DecodeImage_OutOfMemory);
79687 void* ptr =
79688 allow_uninitialized_memory ? malloc((size_t)len) : calloc(1, (size_t)len);
79689 if (!ptr) {
79690 return AllocWorkbufResult(DecodeImage_OutOfMemory);
79692 return AllocWorkbufResult(
79693 MemOwner(ptr, &free),
79694 wuffs_base__make_slice_u8((uint8_t*)ptr, (size_t)len));
79697 void //
79698 DecodeImageCallbacks::Done(
79699 DecodeImageResult& result,
79700 sync_io::Input& input,
79701 IOBuffer& buffer,
79702 wuffs_base__image_decoder::unique_ptr image_decoder) {}
79704 const char DecodeImage_BufferIsTooShort[] = //
79705 "wuffs_aux::DecodeImage: buffer is too short";
79706 const char DecodeImage_MaxInclDimensionExceeded[] = //
79707 "wuffs_aux::DecodeImage: max_incl_dimension exceeded";
79708 const char DecodeImage_MaxInclMetadataLengthExceeded[] = //
79709 "wuffs_aux::DecodeImage: max_incl_metadata_length exceeded";
79710 const char DecodeImage_OutOfMemory[] = //
79711 "wuffs_aux::DecodeImage: out of memory";
79712 const char DecodeImage_UnexpectedEndOfFile[] = //
79713 "wuffs_aux::DecodeImage: unexpected end of file";
79714 const char DecodeImage_UnsupportedImageFormat[] = //
79715 "wuffs_aux::DecodeImage: unsupported image format";
79716 const char DecodeImage_UnsupportedMetadata[] = //
79717 "wuffs_aux::DecodeImage: unsupported metadata";
79718 const char DecodeImage_UnsupportedPixelBlend[] = //
79719 "wuffs_aux::DecodeImage: unsupported pixel blend";
79720 const char DecodeImage_UnsupportedPixelConfiguration[] = //
79721 "wuffs_aux::DecodeImage: unsupported pixel configuration";
79722 const char DecodeImage_UnsupportedPixelFormat[] = //
79723 "wuffs_aux::DecodeImage: unsupported pixel format";
79725 DecodeImageArgQuirks::DecodeImageArgQuirks(const QuirkKeyValuePair* ptr0,
79726 const size_t len0)
79727 : ptr(ptr0), len(len0) {}
79729 DecodeImageArgQuirks //
79730 DecodeImageArgQuirks::DefaultValue() {
79731 return DecodeImageArgQuirks(nullptr, 0);
79734 DecodeImageArgFlags::DecodeImageArgFlags(uint64_t repr0) : repr(repr0) {}
79736 DecodeImageArgFlags //
79737 DecodeImageArgFlags::DefaultValue() {
79738 return DecodeImageArgFlags(0);
79741 DecodeImageArgPixelBlend::DecodeImageArgPixelBlend(
79742 wuffs_base__pixel_blend repr0)
79743 : repr(repr0) {}
79745 DecodeImageArgPixelBlend //
79746 DecodeImageArgPixelBlend::DefaultValue() {
79747 return DecodeImageArgPixelBlend(WUFFS_BASE__PIXEL_BLEND__SRC);
79750 DecodeImageArgBackgroundColor::DecodeImageArgBackgroundColor(
79751 wuffs_base__color_u32_argb_premul repr0)
79752 : repr(repr0) {}
79754 DecodeImageArgBackgroundColor //
79755 DecodeImageArgBackgroundColor::DefaultValue() {
79756 return DecodeImageArgBackgroundColor(1);
79759 DecodeImageArgMaxInclDimension::DecodeImageArgMaxInclDimension(uint32_t repr0)
79760 : repr(repr0) {}
79762 DecodeImageArgMaxInclDimension //
79763 DecodeImageArgMaxInclDimension::DefaultValue() {
79764 return DecodeImageArgMaxInclDimension(1048575);
79767 DecodeImageArgMaxInclMetadataLength::DecodeImageArgMaxInclMetadataLength(
79768 uint64_t repr0)
79769 : repr(repr0) {}
79771 DecodeImageArgMaxInclMetadataLength //
79772 DecodeImageArgMaxInclMetadataLength::DefaultValue() {
79773 return DecodeImageArgMaxInclMetadataLength(16777215);
79776 // --------
79778 namespace {
79780 const private_impl::ErrorMessages DecodeImageErrorMessages = {
79781 DecodeImage_MaxInclMetadataLengthExceeded, //
79782 DecodeImage_OutOfMemory, //
79783 DecodeImage_UnexpectedEndOfFile, //
79784 DecodeImage_UnsupportedMetadata, //
79785 DecodeImage_UnsupportedImageFormat, //
79788 std::string //
79789 DecodeImageAdvanceIOBufferTo(sync_io::Input& input,
79790 wuffs_base__io_buffer& io_buf,
79791 uint64_t absolute_position) {
79792 return private_impl::AdvanceIOBufferTo(DecodeImageErrorMessages, input,
79793 io_buf, absolute_position);
79796 wuffs_base__status //
79797 DIHM0(void* self,
79798 wuffs_base__io_buffer* a_dst,
79799 wuffs_base__more_information* a_minfo,
79800 wuffs_base__io_buffer* a_src) {
79801 return wuffs_base__image_decoder__tell_me_more(
79802 static_cast<wuffs_base__image_decoder*>(self), a_dst, a_minfo, a_src);
79805 std::string //
79806 DIHM1(void* self,
79807 const wuffs_base__more_information* minfo,
79808 wuffs_base__slice_u8 raw) {
79809 return static_cast<DecodeImageCallbacks*>(self)->HandleMetadata(*minfo, raw);
79812 std::string //
79813 DecodeImageHandleMetadata(wuffs_base__image_decoder::unique_ptr& image_decoder,
79814 DecodeImageCallbacks& callbacks,
79815 sync_io::Input& input,
79816 wuffs_base__io_buffer& io_buf,
79817 sync_io::DynIOBuffer& raw_metadata_buf) {
79818 return private_impl::HandleMetadata(DecodeImageErrorMessages, input, io_buf,
79819 raw_metadata_buf, DIHM0,
79820 static_cast<void*>(image_decoder.get()),
79821 DIHM1, static_cast<void*>(&callbacks));
79824 DecodeImageResult //
79825 DecodeImage0(wuffs_base__image_decoder::unique_ptr& image_decoder,
79826 DecodeImageCallbacks& callbacks,
79827 sync_io::Input& input,
79828 wuffs_base__io_buffer& io_buf,
79829 const QuirkKeyValuePair* quirks_ptr,
79830 const size_t quirks_len,
79831 uint64_t flags,
79832 wuffs_base__pixel_blend pixel_blend,
79833 wuffs_base__color_u32_argb_premul background_color,
79834 uint32_t max_incl_dimension,
79835 uint64_t max_incl_metadata_length) {
79836 // Check args.
79837 switch (pixel_blend) {
79838 case WUFFS_BASE__PIXEL_BLEND__SRC:
79839 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
79840 break;
79841 default:
79842 return DecodeImageResult(DecodeImage_UnsupportedPixelBlend);
79845 wuffs_base__image_config image_config = wuffs_base__null_image_config();
79846 sync_io::DynIOBuffer raw_metadata_buf(max_incl_metadata_length);
79847 uint64_t start_pos = io_buf.reader_position();
79848 bool interested_in_metadata_after_the_frame = false;
79849 bool redirected = false;
79850 int32_t fourcc = 0;
79851 redirect:
79852 do {
79853 // Determine the image format.
79854 if (!redirected) {
79855 while (true) {
79856 fourcc = wuffs_base__magic_number_guess_fourcc(io_buf.reader_slice(),
79857 io_buf.meta.closed);
79858 if (fourcc > 0) {
79859 break;
79860 } else if ((fourcc == 0) && (io_buf.reader_length() >= 64)) {
79861 // Having (fourcc == 0) means that Wuffs' built in MIME sniffer
79862 // didn't recognize the image format. Nonetheless, custom callbacks
79863 // may still be able to do their own MIME sniffing, for exotic image
79864 // types. We try to give them at least 64 bytes of prefix data when
79865 // one-shot-calling callbacks.SelectDecoder. There is no mechanism
79866 // for the callbacks to request a longer prefix.
79867 break;
79868 } else if (io_buf.meta.closed || (io_buf.writer_length() == 0)) {
79869 fourcc = 0;
79870 break;
79872 std::string error_message = input.CopyIn(&io_buf);
79873 if (!error_message.empty()) {
79874 return DecodeImageResult(std::move(error_message));
79877 } else {
79878 wuffs_base__io_buffer empty = wuffs_base__empty_io_buffer();
79879 wuffs_base__more_information minfo = wuffs_base__empty_more_information();
79880 wuffs_base__status tmm_status =
79881 image_decoder->tell_me_more(&empty, &minfo, &io_buf);
79882 if (tmm_status.repr != nullptr) {
79883 return DecodeImageResult(tmm_status.message());
79885 if (minfo.flavor != WUFFS_BASE__MORE_INFORMATION__FLAVOR__IO_REDIRECT) {
79886 return DecodeImageResult(DecodeImage_UnsupportedImageFormat);
79888 uint64_t pos = minfo.io_redirect__range().min_incl;
79889 if (pos <= start_pos) {
79890 // Redirects must go forward.
79891 return DecodeImageResult(DecodeImage_UnsupportedImageFormat);
79893 std::string error_message =
79894 DecodeImageAdvanceIOBufferTo(input, io_buf, pos);
79895 if (!error_message.empty()) {
79896 return DecodeImageResult(std::move(error_message));
79898 fourcc = (int32_t)(minfo.io_redirect__fourcc());
79899 if (fourcc == 0) {
79900 return DecodeImageResult(DecodeImage_UnsupportedImageFormat);
79902 image_decoder.reset();
79905 // Select the image decoder.
79906 image_decoder = callbacks.SelectDecoder(
79907 (uint32_t)fourcc, io_buf.reader_slice(), io_buf.meta.closed);
79908 if (!image_decoder) {
79909 return DecodeImageResult(DecodeImage_UnsupportedImageFormat);
79912 // Apply quirks.
79913 for (size_t i = 0; i < quirks_len; i++) {
79914 image_decoder->set_quirk(quirks_ptr[i].first, quirks_ptr[i].second);
79917 // Apply flags.
79918 if (flags != 0) {
79919 if (flags & DecodeImageArgFlags::REPORT_METADATA_CHRM) {
79920 image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__CHRM, true);
79922 if (flags & DecodeImageArgFlags::REPORT_METADATA_EXIF) {
79923 interested_in_metadata_after_the_frame = true;
79924 image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__EXIF, true);
79926 if (flags & DecodeImageArgFlags::REPORT_METADATA_GAMA) {
79927 image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__GAMA, true);
79929 if (flags & DecodeImageArgFlags::REPORT_METADATA_ICCP) {
79930 image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__ICCP, true);
79932 if (flags & DecodeImageArgFlags::REPORT_METADATA_KVP) {
79933 interested_in_metadata_after_the_frame = true;
79934 image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__KVP, true);
79936 if (flags & DecodeImageArgFlags::REPORT_METADATA_SRGB) {
79937 image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__SRGB, true);
79939 if (flags & DecodeImageArgFlags::REPORT_METADATA_XMP) {
79940 interested_in_metadata_after_the_frame = true;
79941 image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__XMP, true);
79945 // Decode the image config.
79946 while (true) {
79947 wuffs_base__status id_dic_status =
79948 image_decoder->decode_image_config(&image_config, &io_buf);
79949 if (id_dic_status.repr == nullptr) {
79950 break;
79951 } else if (id_dic_status.repr == wuffs_base__note__i_o_redirect) {
79952 if (redirected) {
79953 return DecodeImageResult(DecodeImage_UnsupportedImageFormat);
79955 redirected = true;
79956 goto redirect;
79957 } else if (id_dic_status.repr == wuffs_base__note__metadata_reported) {
79958 std::string error_message = DecodeImageHandleMetadata(
79959 image_decoder, callbacks, input, io_buf, raw_metadata_buf);
79960 if (!error_message.empty()) {
79961 return DecodeImageResult(std::move(error_message));
79963 } else if (id_dic_status.repr != wuffs_base__suspension__short_read) {
79964 return DecodeImageResult(id_dic_status.message());
79965 } else if (io_buf.meta.closed) {
79966 return DecodeImageResult(DecodeImage_UnexpectedEndOfFile);
79967 } else {
79968 std::string error_message = input.CopyIn(&io_buf);
79969 if (!error_message.empty()) {
79970 return DecodeImageResult(std::move(error_message));
79974 } while (false);
79975 if (!interested_in_metadata_after_the_frame) {
79976 raw_metadata_buf.drop();
79979 // Select the pixel format.
79980 uint32_t w = image_config.pixcfg.width();
79981 uint32_t h = image_config.pixcfg.height();
79982 if ((w > max_incl_dimension) || (h > max_incl_dimension)) {
79983 return DecodeImageResult(DecodeImage_MaxInclDimensionExceeded);
79985 wuffs_base__pixel_format pixel_format = callbacks.SelectPixfmt(image_config);
79986 if (pixel_format.repr != image_config.pixcfg.pixel_format().repr) {
79987 switch (pixel_format.repr) {
79988 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
79989 case WUFFS_BASE__PIXEL_FORMAT__BGR:
79990 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
79991 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
79992 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
79993 case WUFFS_BASE__PIXEL_FORMAT__RGB:
79994 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
79995 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
79996 break;
79997 default:
79998 return DecodeImageResult(DecodeImage_UnsupportedPixelFormat);
80000 image_config.pixcfg.set(pixel_format.repr,
80001 WUFFS_BASE__PIXEL_SUBSAMPLING__NONE, w, h);
80004 // Allocate the pixel buffer.
80005 bool valid_background_color =
80006 wuffs_base__color_u32_argb_premul__is_valid(background_color);
80007 DecodeImageCallbacks::AllocPixbufResult alloc_pixbuf_result =
80008 callbacks.AllocPixbuf(image_config, valid_background_color);
80009 if (!alloc_pixbuf_result.error_message.empty()) {
80010 return DecodeImageResult(std::move(alloc_pixbuf_result.error_message));
80012 wuffs_base__pixel_buffer pixel_buffer = alloc_pixbuf_result.pixbuf;
80013 if (valid_background_color) {
80014 wuffs_base__status pb_scufr_status = pixel_buffer.set_color_u32_fill_rect(
80015 pixel_buffer.pixcfg.bounds(), background_color);
80016 if (pb_scufr_status.repr != nullptr) {
80017 return DecodeImageResult(pb_scufr_status.message());
80021 // Allocate the work buffer. Wuffs' decoders conventionally assume that this
80022 // can be uninitialized memory.
80023 wuffs_base__range_ii_u64 workbuf_len = image_decoder->workbuf_len();
80024 DecodeImageCallbacks::AllocWorkbufResult alloc_workbuf_result =
80025 callbacks.AllocWorkbuf(workbuf_len, true);
80026 if (!alloc_workbuf_result.error_message.empty()) {
80027 return DecodeImageResult(std::move(alloc_workbuf_result.error_message));
80028 } else if (alloc_workbuf_result.workbuf.len < workbuf_len.min_incl) {
80029 return DecodeImageResult(DecodeImage_BufferIsTooShort);
80032 // Decode the frame config.
80033 wuffs_base__frame_config frame_config = wuffs_base__null_frame_config();
80034 while (true) {
80035 wuffs_base__status id_dfc_status =
80036 image_decoder->decode_frame_config(&frame_config, &io_buf);
80037 if (id_dfc_status.repr == nullptr) {
80038 break;
80039 } else if (id_dfc_status.repr == wuffs_base__note__metadata_reported) {
80040 std::string error_message = DecodeImageHandleMetadata(
80041 image_decoder, callbacks, input, io_buf, raw_metadata_buf);
80042 if (!error_message.empty()) {
80043 return DecodeImageResult(std::move(error_message));
80045 } else if (id_dfc_status.repr != wuffs_base__suspension__short_read) {
80046 return DecodeImageResult(id_dfc_status.message());
80047 } else if (io_buf.meta.closed) {
80048 return DecodeImageResult(DecodeImage_UnexpectedEndOfFile);
80049 } else {
80050 std::string error_message = input.CopyIn(&io_buf);
80051 if (!error_message.empty()) {
80052 return DecodeImageResult(std::move(error_message));
80057 // Decode the frame (the pixels).
80059 // From here on, always returns the pixel_buffer. If we get this far, we can
80060 // still display a partial image, even if we encounter an error.
80061 std::string message("");
80062 if ((pixel_blend == WUFFS_BASE__PIXEL_BLEND__SRC_OVER) &&
80063 frame_config.overwrite_instead_of_blend()) {
80064 pixel_blend = WUFFS_BASE__PIXEL_BLEND__SRC;
80066 while (true) {
80067 wuffs_base__status id_df_status =
80068 image_decoder->decode_frame(&pixel_buffer, &io_buf, pixel_blend,
80069 alloc_workbuf_result.workbuf, nullptr);
80070 if (id_df_status.repr == nullptr) {
80071 break;
80072 } else if (id_df_status.repr != wuffs_base__suspension__short_read) {
80073 message = id_df_status.message();
80074 break;
80075 } else if (io_buf.meta.closed) {
80076 message = DecodeImage_UnexpectedEndOfFile;
80077 break;
80078 } else {
80079 std::string error_message = input.CopyIn(&io_buf);
80080 if (!error_message.empty()) {
80081 message = std::move(error_message);
80082 break;
80087 // Decode any metadata after the frame.
80088 if (interested_in_metadata_after_the_frame) {
80089 while (true) {
80090 wuffs_base__status id_dfc_status =
80091 image_decoder->decode_frame_config(NULL, &io_buf);
80092 if (id_dfc_status.repr == wuffs_base__note__end_of_data) {
80093 break;
80094 } else if (id_dfc_status.repr == nullptr) {
80095 continue;
80096 } else if (id_dfc_status.repr == wuffs_base__note__metadata_reported) {
80097 std::string error_message = DecodeImageHandleMetadata(
80098 image_decoder, callbacks, input, io_buf, raw_metadata_buf);
80099 if (!error_message.empty()) {
80100 return DecodeImageResult(std::move(error_message));
80102 } else if (id_dfc_status.repr != wuffs_base__suspension__short_read) {
80103 return DecodeImageResult(id_dfc_status.message());
80104 } else if (io_buf.meta.closed) {
80105 return DecodeImageResult(DecodeImage_UnexpectedEndOfFile);
80106 } else {
80107 std::string error_message = input.CopyIn(&io_buf);
80108 if (!error_message.empty()) {
80109 return DecodeImageResult(std::move(error_message));
80115 return DecodeImageResult(std::move(alloc_pixbuf_result.mem_owner),
80116 pixel_buffer, std::move(message));
80119 } // namespace
80121 DecodeImageResult //
80122 DecodeImage(DecodeImageCallbacks& callbacks,
80123 sync_io::Input& input,
80124 DecodeImageArgQuirks quirks,
80125 DecodeImageArgFlags flags,
80126 DecodeImageArgPixelBlend pixel_blend,
80127 DecodeImageArgBackgroundColor background_color,
80128 DecodeImageArgMaxInclDimension max_incl_dimension,
80129 DecodeImageArgMaxInclMetadataLength max_incl_metadata_length) {
80130 wuffs_base__io_buffer* io_buf = input.BringsItsOwnIOBuffer();
80131 wuffs_base__io_buffer fallback_io_buf = wuffs_base__empty_io_buffer();
80132 std::unique_ptr<uint8_t[]> fallback_io_array(nullptr);
80133 if (!io_buf) {
80134 fallback_io_array = std::unique_ptr<uint8_t[]>(new uint8_t[32768]);
80135 fallback_io_buf =
80136 wuffs_base__ptr_u8__writer(fallback_io_array.get(), 32768);
80137 io_buf = &fallback_io_buf;
80140 wuffs_base__image_decoder::unique_ptr image_decoder(nullptr);
80141 DecodeImageResult result = DecodeImage0(
80142 image_decoder, callbacks, input, *io_buf, quirks.ptr, quirks.len,
80143 flags.repr, pixel_blend.repr, background_color.repr,
80144 max_incl_dimension.repr, max_incl_metadata_length.repr);
80145 callbacks.Done(result, input, *io_buf, std::move(image_decoder));
80146 return result;
80149 } // namespace wuffs_aux
80151 #endif // !defined(WUFFS_CONFIG__MODULES) ||
80152 // defined(WUFFS_CONFIG__MODULE__AUX__IMAGE)
80154 // ---------------- Auxiliary - JSON
80156 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__AUX__JSON)
80158 #include <utility>
80160 namespace wuffs_aux {
80162 DecodeJsonResult::DecodeJsonResult(std::string&& error_message0,
80163 uint64_t cursor_position0)
80164 : error_message(std::move(error_message0)),
80165 cursor_position(cursor_position0) {}
80167 DecodeJsonCallbacks::~DecodeJsonCallbacks() {}
80169 void //
80170 DecodeJsonCallbacks::Done(DecodeJsonResult& result,
80171 sync_io::Input& input,
80172 IOBuffer& buffer) {}
80174 const char DecodeJson_BadJsonPointer[] = //
80175 "wuffs_aux::DecodeJson: bad JSON Pointer";
80176 const char DecodeJson_NoMatch[] = //
80177 "wuffs_aux::DecodeJson: no match";
80179 DecodeJsonArgQuirks::DecodeJsonArgQuirks(const QuirkKeyValuePair* ptr0,
80180 const size_t len0)
80181 : ptr(ptr0), len(len0) {}
80183 DecodeJsonArgQuirks //
80184 DecodeJsonArgQuirks::DefaultValue() {
80185 return DecodeJsonArgQuirks(nullptr, 0);
80188 DecodeJsonArgJsonPointer::DecodeJsonArgJsonPointer(std::string repr0)
80189 : repr(repr0) {}
80191 DecodeJsonArgJsonPointer //
80192 DecodeJsonArgJsonPointer::DefaultValue() {
80193 return DecodeJsonArgJsonPointer(std::string());
80196 // --------
80198 #define WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN \
80199 while (tok_buf.meta.ri >= tok_buf.meta.wi) { \
80200 if (tok_status.repr == nullptr) { \
80201 goto done; \
80202 } else if (tok_status.repr == wuffs_base__suspension__short_write) { \
80203 tok_buf.compact(); \
80204 } else if (tok_status.repr == wuffs_base__suspension__short_read) { \
80205 if (!io_error_message.empty()) { \
80206 ret_error_message = std::move(io_error_message); \
80207 goto done; \
80208 } else if (cursor_index != io_buf->meta.ri) { \
80209 ret_error_message = \
80210 "wuffs_aux::DecodeJson: internal error: bad cursor_index"; \
80211 goto done; \
80212 } else if (io_buf->meta.closed) { \
80213 ret_error_message = \
80214 "wuffs_aux::DecodeJson: internal error: io_buf is closed"; \
80215 goto done; \
80217 io_buf->compact(); \
80218 if (io_buf->meta.wi >= io_buf->data.len) { \
80219 ret_error_message = \
80220 "wuffs_aux::DecodeJson: internal error: io_buf is full"; \
80221 goto done; \
80223 cursor_index = io_buf->meta.ri; \
80224 io_error_message = input.CopyIn(io_buf); \
80225 } else { \
80226 ret_error_message = tok_status.message(); \
80227 goto done; \
80229 tok_status = \
80230 dec->decode_tokens(&tok_buf, io_buf, wuffs_base__empty_slice_u8()); \
80231 if ((tok_buf.meta.ri > tok_buf.meta.wi) || \
80232 (tok_buf.meta.wi > tok_buf.data.len) || \
80233 (io_buf->meta.ri > io_buf->meta.wi) || \
80234 (io_buf->meta.wi > io_buf->data.len)) { \
80235 ret_error_message = \
80236 "wuffs_aux::DecodeJson: internal error: bad buffer indexes"; \
80237 goto done; \
80240 wuffs_base__token token = tok_buf.data.ptr[tok_buf.meta.ri++]; \
80241 uint64_t token_len = token.length(); \
80242 if ((io_buf->meta.ri < cursor_index) || \
80243 ((io_buf->meta.ri - cursor_index) < token_len)) { \
80244 ret_error_message = \
80245 "wuffs_aux::DecodeJson: internal error: bad token indexes"; \
80246 goto done; \
80248 uint8_t* token_ptr = io_buf->data.ptr + cursor_index; \
80249 (void)(token_ptr); \
80250 cursor_index += static_cast<size_t>(token_len)
80252 // --------
80254 namespace {
80256 // DecodeJson_SplitJsonPointer returns ("bar", 8) for ("/foo/bar/b~1z/qux", 5,
80257 // etc). It returns a 0 size_t when s has invalid JSON Pointer syntax or i is
80258 // out of bounds.
80260 // The string returned is unescaped. If calling it again, this time with i=8,
80261 // the "b~1z" substring would be returned as "b/z".
80262 std::pair<std::string, size_t> //
80263 DecodeJson_SplitJsonPointer(std::string& s,
80264 size_t i,
80265 bool allow_tilde_n_tilde_r_tilde_t) {
80266 std::string fragment;
80267 if (i > s.size()) {
80268 return std::make_pair(std::string(), 0);
80270 while (i < s.size()) {
80271 char c = s[i];
80272 if (c == '/') {
80273 break;
80274 } else if (c != '~') {
80275 fragment.push_back(c);
80276 i++;
80277 continue;
80279 i++;
80280 if (i >= s.size()) {
80281 return std::make_pair(std::string(), 0);
80283 c = s[i];
80284 if (c == '0') {
80285 fragment.push_back('~');
80286 i++;
80287 continue;
80288 } else if (c == '1') {
80289 fragment.push_back('/');
80290 i++;
80291 continue;
80292 } else if (allow_tilde_n_tilde_r_tilde_t) {
80293 if (c == 'n') {
80294 fragment.push_back('\n');
80295 i++;
80296 continue;
80297 } else if (c == 'r') {
80298 fragment.push_back('\r');
80299 i++;
80300 continue;
80301 } else if (c == 't') {
80302 fragment.push_back('\t');
80303 i++;
80304 continue;
80307 return std::make_pair(std::string(), 0);
80309 return std::make_pair(std::move(fragment), i);
80312 // --------
80314 std::string //
80315 DecodeJson_WalkJsonPointerFragment(wuffs_base__token_buffer& tok_buf,
80316 wuffs_base__status& tok_status,
80317 wuffs_json__decoder::unique_ptr& dec,
80318 wuffs_base__io_buffer* io_buf,
80319 std::string& io_error_message,
80320 size_t& cursor_index,
80321 sync_io::Input& input,
80322 std::string& json_pointer_fragment) {
80323 std::string ret_error_message;
80324 while (true) {
80325 WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;
80327 int64_t vbc = token.value_base_category();
80328 uint64_t vbd = token.value_base_detail();
80329 if (vbc == WUFFS_BASE__TOKEN__VBC__FILLER) {
80330 continue;
80331 } else if ((vbc != WUFFS_BASE__TOKEN__VBC__STRUCTURE) ||
80332 !(vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH)) {
80333 return DecodeJson_NoMatch;
80334 } else if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_LIST) {
80335 goto do_list;
80337 goto do_dict;
80340 do_dict:
80341 // Alternate between these two things:
80342 // 1. Decode the next dict key (a string). If it matches the fragment, we're
80343 // done (success). If we've reached the dict's end (VBD__STRUCTURE__POP)
80344 // so that there was no next dict key, we're done (failure).
80345 // 2. Otherwise, skip the next dict value.
80346 while (true) {
80347 for (std::string str; true;) {
80348 WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;
80350 int64_t vbc = token.value_base_category();
80351 uint64_t vbd = token.value_base_detail();
80352 switch (vbc) {
80353 case WUFFS_BASE__TOKEN__VBC__FILLER:
80354 continue;
80356 case WUFFS_BASE__TOKEN__VBC__STRUCTURE:
80357 if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {
80358 goto fail;
80360 return DecodeJson_NoMatch;
80362 case WUFFS_BASE__TOKEN__VBC__STRING: {
80363 if (vbd & WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_0_DST_1_SRC_DROP) {
80364 // No-op.
80365 } else if (vbd &
80366 WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_1_SRC_COPY) {
80367 const char* ptr = // Convert from (uint8_t*).
80368 static_cast<const char*>(static_cast<void*>(token_ptr));
80369 str.append(ptr, static_cast<size_t>(token_len));
80370 } else {
80371 goto fail;
80373 break;
80376 case WUFFS_BASE__TOKEN__VBC__UNICODE_CODE_POINT: {
80377 uint8_t u[WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL];
80378 size_t n = wuffs_base__utf_8__encode(
80379 wuffs_base__make_slice_u8(
80380 &u[0], WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL),
80381 static_cast<uint32_t>(vbd));
80382 const char* ptr = // Convert from (uint8_t*).
80383 static_cast<const char*>(static_cast<void*>(&u[0]));
80384 str.append(ptr, n);
80385 break;
80388 default:
80389 goto fail;
80392 if (token.continued()) {
80393 continue;
80395 if (str == json_pointer_fragment) {
80396 return "";
80398 goto skip_the_next_dict_value;
80401 skip_the_next_dict_value:
80402 for (uint32_t skip_depth = 0; true;) {
80403 WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;
80405 int64_t vbc = token.value_base_category();
80406 uint64_t vbd = token.value_base_detail();
80407 if (token.continued() || (vbc == WUFFS_BASE__TOKEN__VBC__FILLER)) {
80408 continue;
80409 } else if (vbc == WUFFS_BASE__TOKEN__VBC__STRUCTURE) {
80410 if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {
80411 skip_depth++;
80412 continue;
80414 skip_depth--;
80417 if (skip_depth == 0) {
80418 break;
80420 } // skip_the_next_dict_value
80421 } // do_dict
80423 do_list:
80424 do {
80425 wuffs_base__result_u64 result_u64 = wuffs_base__parse_number_u64(
80426 wuffs_base__make_slice_u8(
80427 static_cast<uint8_t*>(static_cast<void*>(
80428 const_cast<char*>(json_pointer_fragment.data()))),
80429 json_pointer_fragment.size()),
80430 WUFFS_BASE__PARSE_NUMBER_XXX__DEFAULT_OPTIONS);
80431 if (!result_u64.status.is_ok()) {
80432 return DecodeJson_NoMatch;
80434 uint64_t remaining = result_u64.value;
80435 if (remaining == 0) {
80436 goto check_that_a_value_follows;
80438 for (uint32_t skip_depth = 0; true;) {
80439 WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;
80441 int64_t vbc = token.value_base_category();
80442 uint64_t vbd = token.value_base_detail();
80443 if (token.continued() || (vbc == WUFFS_BASE__TOKEN__VBC__FILLER)) {
80444 continue;
80445 } else if (vbc == WUFFS_BASE__TOKEN__VBC__STRUCTURE) {
80446 if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {
80447 skip_depth++;
80448 continue;
80450 if (skip_depth == 0) {
80451 return DecodeJson_NoMatch;
80453 skip_depth--;
80456 if (skip_depth > 0) {
80457 continue;
80459 remaining--;
80460 if (remaining == 0) {
80461 goto check_that_a_value_follows;
80464 } while (false); // do_list
80466 check_that_a_value_follows:
80467 while (true) {
80468 WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;
80470 int64_t vbc = token.value_base_category();
80471 uint64_t vbd = token.value_base_detail();
80472 if (vbc == WUFFS_BASE__TOKEN__VBC__FILLER) {
80473 continue;
80476 // Undo the last part of WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN, so
80477 // that we're only peeking at the next token.
80478 tok_buf.meta.ri--;
80479 cursor_index -= static_cast<size_t>(token_len);
80481 if ((vbc == WUFFS_BASE__TOKEN__VBC__STRUCTURE) &&
80482 (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__POP)) {
80483 return DecodeJson_NoMatch;
80485 return "";
80486 } // check_that_a_value_follows
80488 fail:
80489 return "wuffs_aux::DecodeJson: internal error: unexpected token";
80490 done:
80491 return ret_error_message;
80494 } // namespace
80496 // --------
80498 DecodeJsonResult //
80499 DecodeJson(DecodeJsonCallbacks& callbacks,
80500 sync_io::Input& input,
80501 DecodeJsonArgQuirks quirks,
80502 DecodeJsonArgJsonPointer json_pointer) {
80503 // Prepare the wuffs_base__io_buffer and the resultant error_message.
80504 wuffs_base__io_buffer* io_buf = input.BringsItsOwnIOBuffer();
80505 wuffs_base__io_buffer fallback_io_buf = wuffs_base__empty_io_buffer();
80506 std::unique_ptr<uint8_t[]> fallback_io_array(nullptr);
80507 if (!io_buf) {
80508 fallback_io_array = std::unique_ptr<uint8_t[]>(new uint8_t[4096]);
80509 fallback_io_buf = wuffs_base__ptr_u8__writer(fallback_io_array.get(), 4096);
80510 io_buf = &fallback_io_buf;
80512 // cursor_index is discussed at
80513 // https://nigeltao.github.io/blog/2020/jsonptr.html#the-cursor-index
80514 size_t cursor_index = 0;
80515 std::string ret_error_message;
80516 std::string io_error_message;
80518 do {
80519 // Prepare the low-level JSON decoder.
80520 wuffs_json__decoder::unique_ptr dec = wuffs_json__decoder::alloc();
80521 if (!dec) {
80522 ret_error_message = "wuffs_aux::DecodeJson: out of memory";
80523 goto done;
80524 } else if (WUFFS_JSON__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE != 0) {
80525 ret_error_message =
80526 "wuffs_aux::DecodeJson: internal error: bad WORKBUF_LEN";
80527 goto done;
80529 bool allow_tilde_n_tilde_r_tilde_t = false;
80530 for (size_t i = 0; i < quirks.len; i++) {
80531 dec->set_quirk(quirks.ptr[i].first, quirks.ptr[i].second);
80532 if (quirks.ptr[i].first ==
80533 WUFFS_JSON__QUIRK_JSON_POINTER_ALLOW_TILDE_N_TILDE_R_TILDE_T) {
80534 allow_tilde_n_tilde_r_tilde_t = (quirks.ptr[i].second != 0);
80538 // Prepare the wuffs_base__tok_buffer. 256 tokens is 2KiB.
80539 wuffs_base__token tok_array[256];
80540 wuffs_base__token_buffer tok_buf =
80541 wuffs_base__slice_token__writer(wuffs_base__make_slice_token(
80542 &tok_array[0], (sizeof(tok_array) / sizeof(tok_array[0]))));
80543 wuffs_base__status tok_status =
80544 dec->decode_tokens(&tok_buf, io_buf, wuffs_base__empty_slice_u8());
80546 // Prepare other state.
80547 int32_t depth = 0;
80548 std::string str;
80550 // Walk the (optional) JSON Pointer.
80551 for (size_t i = 0; i < json_pointer.repr.size();) {
80552 if (json_pointer.repr[i] != '/') {
80553 ret_error_message = DecodeJson_BadJsonPointer;
80554 goto done;
80556 std::pair<std::string, size_t> split = DecodeJson_SplitJsonPointer(
80557 json_pointer.repr, i + 1, allow_tilde_n_tilde_r_tilde_t);
80558 i = split.second;
80559 if (i == 0) {
80560 ret_error_message = DecodeJson_BadJsonPointer;
80561 goto done;
80563 ret_error_message = DecodeJson_WalkJsonPointerFragment(
80564 tok_buf, tok_status, dec, io_buf, io_error_message, cursor_index,
80565 input, split.first);
80566 if (!ret_error_message.empty()) {
80567 goto done;
80571 // Loop, doing these two things:
80572 // 1. Get the next token.
80573 // 2. Process that token.
80574 while (true) {
80575 WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;
80577 int64_t vbc = token.value_base_category();
80578 uint64_t vbd = token.value_base_detail();
80579 switch (vbc) {
80580 case WUFFS_BASE__TOKEN__VBC__FILLER:
80581 continue;
80583 case WUFFS_BASE__TOKEN__VBC__STRUCTURE: {
80584 if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {
80585 ret_error_message = callbacks.Push(static_cast<uint32_t>(vbd));
80586 if (!ret_error_message.empty()) {
80587 goto done;
80589 depth++;
80590 if (depth > (int32_t)WUFFS_JSON__DECODER_DEPTH_MAX_INCL) {
80591 ret_error_message =
80592 "wuffs_aux::DecodeJson: internal error: bad depth";
80593 goto done;
80595 continue;
80597 ret_error_message = callbacks.Pop(static_cast<uint32_t>(vbd));
80598 depth--;
80599 if (depth < 0) {
80600 ret_error_message =
80601 "wuffs_aux::DecodeJson: internal error: bad depth";
80602 goto done;
80604 goto parsed_a_value;
80607 case WUFFS_BASE__TOKEN__VBC__STRING: {
80608 if (vbd & WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_0_DST_1_SRC_DROP) {
80609 // No-op.
80610 } else if (vbd &
80611 WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_1_SRC_COPY) {
80612 const char* ptr = // Convert from (uint8_t*).
80613 static_cast<const char*>(static_cast<void*>(token_ptr));
80614 str.append(ptr, static_cast<size_t>(token_len));
80615 } else {
80616 goto fail;
80618 if (token.continued()) {
80619 continue;
80621 ret_error_message = callbacks.AppendTextString(std::move(str));
80622 str.clear();
80623 goto parsed_a_value;
80626 case WUFFS_BASE__TOKEN__VBC__UNICODE_CODE_POINT: {
80627 uint8_t u[WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL];
80628 size_t n = wuffs_base__utf_8__encode(
80629 wuffs_base__make_slice_u8(
80630 &u[0], WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL),
80631 static_cast<uint32_t>(vbd));
80632 const char* ptr = // Convert from (uint8_t*).
80633 static_cast<const char*>(static_cast<void*>(&u[0]));
80634 str.append(ptr, n);
80635 if (token.continued()) {
80636 continue;
80638 goto fail;
80641 case WUFFS_BASE__TOKEN__VBC__LITERAL: {
80642 ret_error_message =
80643 (vbd & WUFFS_BASE__TOKEN__VBD__LITERAL__NULL)
80644 ? callbacks.AppendNull()
80645 : callbacks.AppendBool(vbd &
80646 WUFFS_BASE__TOKEN__VBD__LITERAL__TRUE);
80647 goto parsed_a_value;
80650 case WUFFS_BASE__TOKEN__VBC__NUMBER: {
80651 if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_TEXT) {
80652 if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_SIGNED) {
80653 wuffs_base__result_i64 r = wuffs_base__parse_number_i64(
80654 wuffs_base__make_slice_u8(token_ptr,
80655 static_cast<size_t>(token_len)),
80656 WUFFS_BASE__PARSE_NUMBER_XXX__DEFAULT_OPTIONS);
80657 if (r.status.is_ok()) {
80658 ret_error_message = callbacks.AppendI64(r.value);
80659 goto parsed_a_value;
80662 if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_FLOATING_POINT) {
80663 wuffs_base__result_f64 r = wuffs_base__parse_number_f64(
80664 wuffs_base__make_slice_u8(token_ptr,
80665 static_cast<size_t>(token_len)),
80666 WUFFS_BASE__PARSE_NUMBER_XXX__DEFAULT_OPTIONS);
80667 if (r.status.is_ok()) {
80668 ret_error_message = callbacks.AppendF64(r.value);
80669 goto parsed_a_value;
80672 } else if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_NEG_INF) {
80673 ret_error_message = callbacks.AppendF64(
80674 wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
80675 0xFFF0000000000000ul));
80676 goto parsed_a_value;
80677 } else if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_POS_INF) {
80678 ret_error_message = callbacks.AppendF64(
80679 wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
80680 0x7FF0000000000000ul));
80681 goto parsed_a_value;
80682 } else if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_NEG_NAN) {
80683 ret_error_message = callbacks.AppendF64(
80684 wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
80685 0xFFFFFFFFFFFFFFFFul));
80686 goto parsed_a_value;
80687 } else if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_POS_NAN) {
80688 ret_error_message = callbacks.AppendF64(
80689 wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
80690 0x7FFFFFFFFFFFFFFFul));
80691 goto parsed_a_value;
80693 goto fail;
80697 fail:
80698 ret_error_message =
80699 "wuffs_aux::DecodeJson: internal error: unexpected token";
80700 goto done;
80702 parsed_a_value:
80703 // If an error was encountered, we are done. Otherwise, (depth == 0)
80704 // after parsing a value is equivalent to having decoded the entire JSON
80705 // value (for an empty json_pointer query) or having decoded the
80706 // pointed-to JSON value (for a non-empty json_pointer query). In the
80707 // latter case, we are also done.
80709 // However, if quirks like WUFFS_JSON__QUIRK_ALLOW_TRAILING_FILLER or
80710 // WUFFS_JSON__QUIRK_EXPECT_TRAILING_NEW_LINE_OR_EOF are passed, decoding
80711 // the entire JSON value should also consume any trailing filler, in case
80712 // the DecodeJson caller wants to subsequently check that the input is
80713 // completely exhausted (and otherwise raise "valid JSON followed by
80714 // further (unexpected) data"). We aren't done yet. Instead, keep the
80715 // loop running until WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN's
80716 // decode_tokens returns an ok status.
80717 if (!ret_error_message.empty() ||
80718 ((depth == 0) && !json_pointer.repr.empty())) {
80719 goto done;
80722 } while (false);
80724 done:
80725 DecodeJsonResult result(
80726 std::move(ret_error_message),
80727 wuffs_base__u64__sat_add(io_buf->meta.pos, cursor_index));
80728 callbacks.Done(result, input, *io_buf);
80729 return result;
80732 #undef WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN
80734 } // namespace wuffs_aux
80736 #endif // !defined(WUFFS_CONFIG__MODULES) ||
80737 // defined(WUFFS_CONFIG__MODULE__AUX__JSON)
80739 #endif // defined(__cplusplus) && defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
80741 #endif // WUFFS_IMPLEMENTATION
80743 #if defined(__GNUC__)
80744 #pragma GCC diagnostic pop
80745 #elif defined(__clang__)
80746 #pragma clang diagnostic pop
80747 #endif
80749 #endif // WUFFS_INCLUDE_GUARD