xref: /aosp_15_r20/external/coreboot/src/vendorcode/wuffs/wuffs-v0.4.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 #ifndef WUFFS_INCLUDE_GUARD
2 #define WUFFS_INCLUDE_GUARD
3 
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.
10 
11 // Wuffs' C code is generated automatically, not hand-written. These warnings'
12 // costs outweigh the benefits.
13 //
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
37 
38 // Copyright 2017 The Wuffs Authors.
39 //
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.
45 //
46 // SPDX-License-Identifier: Apache-2.0 OR MIT
47 
48 #include <stdbool.h>
49 #include <stdint.h>
50 #include <stdlib.h>
51 #include <string.h>
52 
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
63 
64 extern "C" {
65 #endif
66 
67 // ---------------- Version
68 
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.
74 //
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.
78 //
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.
82 //
83 // WUFFS_VERSION was overridden by "wuffs gen -version" based on revision
84 // ae8531f7f846fbbe3a7340bf88499ad294a1367b committed on 2023-10-07.
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.2"
90 #define WUFFS_VERSION_BUILD_METADATA_COMMIT_COUNT 3603
91 #define WUFFS_VERSION_BUILD_METADATA_COMMIT_DATE 20231007
92 #define WUFFS_VERSION_STRING "0.4.0-alpha.2+3603.20231007"
93 
94 // ---------------- Configuration
95 
96 // Define WUFFS_CONFIG__AVOID_CPU_ARCH to avoid any code tied to a specific CPU
97 // architecture, such as SSE SIMD for the x86 CPU family.
98 #if defined(WUFFS_CONFIG__AVOID_CPU_ARCH)  // (#if-chain ref AVOID_CPU_ARCH_0)
99 // No-op.
100 #else  // (#if-chain ref AVOID_CPU_ARCH_0)
101 
102 // The "defined(__clang__)" isn't redundant. While vanilla clang defines
103 // __GNUC__, clang-cl (which mimics MSVC's cl.exe) does not.
104 #if defined(__GNUC__) || defined(__clang__)
105 #define WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET(arg) __attribute__((target(arg)))
106 #else
107 #define WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET(arg)
108 #endif  // defined(__GNUC__) || defined(__clang__)
109 
110 #if defined(__GNUC__)  // (#if-chain ref AVOID_CPU_ARCH_1)
111 
112 // To simplify Wuffs code, "cpu_arch >= arm_xxx" requires xxx but also
113 // unaligned little-endian load/stores.
114 #if defined(__ARM_FEATURE_UNALIGNED) && !defined(__native_client__) && \
115     defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
116 // Not all gcc versions define __ARM_ACLE, even if they support crc32
117 // intrinsics. Look for __ARM_FEATURE_CRC32 instead.
118 #if defined(__ARM_FEATURE_CRC32)
119 #include <arm_acle.h>
120 #define WUFFS_BASE__CPU_ARCH__ARM_CRC32
121 #endif  // defined(__ARM_FEATURE_CRC32)
122 #if defined(__ARM_NEON)
123 #include <arm_neon.h>
124 #define WUFFS_BASE__CPU_ARCH__ARM_NEON
125 #endif  // defined(__ARM_NEON)
126 #endif  // defined(__ARM_FEATURE_UNALIGNED) etc
127 
128 // Similarly, "cpu_arch >= x86_sse42" requires SSE4.2 but also PCLMUL and
129 // POPCNT. This is checked at runtime via cpuid, not at compile time.
130 //
131 // Likewise, "cpu_arch >= x86_avx2" also requires PCLMUL, POPCNT and SSE4.2.
132 #if defined(__i386__) || defined(__x86_64__)
133 #if !defined(__native_client__)
134 #include <cpuid.h>
135 #include <x86intrin.h>
136 // X86_FAMILY means X86 (32-bit) or X86_64 (64-bit, obviously).
137 #define WUFFS_BASE__CPU_ARCH__X86_FAMILY
138 #if defined(__x86_64__)
139 #define WUFFS_BASE__CPU_ARCH__X86_64
140 #endif  // defined(__x86_64__)
141 #endif  // !defined(__native_client__)
142 #endif  // defined(__i386__) || defined(__x86_64__)
143 
144 #elif defined(_MSC_VER)  // (#if-chain ref AVOID_CPU_ARCH_1)
145 
146 #if defined(_M_IX86) || defined(_M_X64)
147 #if defined(__AVX__) || defined(__clang__)
148 
149 // We need <intrin.h> for the __cpuid function.
150 #include <intrin.h>
151 // That's not enough for X64 SIMD, with clang-cl, if we want to use
152 // "__attribute__((target(arg)))" without e.g. "/arch:AVX".
153 //
154 // Some web pages suggest that <immintrin.h> is all you need, as it pulls in
155 // the earlier SIMD families like SSE4.2, but that doesn't seem to work in
156 // practice, possibly for the same reason that just <intrin.h> doesn't work.
157 #include <immintrin.h>  // AVX, AVX2, FMA, POPCNT
158 #include <nmmintrin.h>  // SSE4.2
159 #include <wmmintrin.h>  // AES, PCLMUL
160 // X86_FAMILY means X86 (32-bit) or X86_64 (64-bit, obviously).
161 #define WUFFS_BASE__CPU_ARCH__X86_FAMILY
162 #if defined(_M_X64)
163 #define WUFFS_BASE__CPU_ARCH__X86_64
164 #endif  // defined(_M_X64)
165 
166 #else  // defined(__AVX__) || defined(__clang__)
167 
168 // clang-cl (which defines both __clang__ and _MSC_VER) supports
169 // "__attribute__((target(arg)))".
170 //
171 // For MSVC's cl.exe (unlike clang or gcc), SIMD capability is a compile-time
172 // property of the source file (e.g. a /arch:AVX or -mavx compiler flag), not
173 // of individual functions (that can be conditionally selected at runtime).
174 #pragma message("Wuffs with MSVC+IX86/X64 needs /arch:AVX for best performance")
175 
176 #endif  // defined(__AVX__) || defined(__clang__)
177 #endif  // defined(_M_IX86) || defined(_M_X64)
178 
179 #endif  // (#if-chain ref AVOID_CPU_ARCH_1)
180 #endif  // (#if-chain ref AVOID_CPU_ARCH_0)
181 
182 // --------
183 
184 // Define WUFFS_CONFIG__STATIC_FUNCTIONS (combined with WUFFS_IMPLEMENTATION)
185 // to make all of Wuffs' functions have static storage.
186 //
187 // This can help the compiler ignore or discard unused code, which can produce
188 // faster compiles and smaller binaries. Other motivations are discussed in the
189 // "ALLOW STATIC IMPLEMENTATION" section of
190 // https://raw.githubusercontent.com/nothings/stb/master/docs/stb_howto.txt
191 #if defined(WUFFS_CONFIG__STATIC_FUNCTIONS)
192 #define WUFFS_BASE__MAYBE_STATIC static
193 #else
194 #define WUFFS_BASE__MAYBE_STATIC
195 #endif  // defined(WUFFS_CONFIG__STATIC_FUNCTIONS)
196 
197 // ---------------- CPU Architecture
198 
199 static inline bool  //
wuffs_base__cpu_arch__have_arm_crc32(void)200 wuffs_base__cpu_arch__have_arm_crc32(void) {
201 #if defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32)
202   return true;
203 #else
204   return false;
205 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32)
206 }
207 
208 static inline bool  //
wuffs_base__cpu_arch__have_arm_neon(void)209 wuffs_base__cpu_arch__have_arm_neon(void) {
210 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
211   return true;
212 #else
213   return false;
214 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
215 }
216 
217 static inline bool  //
wuffs_base__cpu_arch__have_x86_avx2(void)218 wuffs_base__cpu_arch__have_x86_avx2(void) {
219 #if defined(__PCLMUL__) && defined(__POPCNT__) && defined(__SSE4_2__) && \
220     defined(__AVX2__)
221   return true;
222 #else
223 #if defined(WUFFS_BASE__CPU_ARCH__X86_64)
224   // GCC defines these macros but MSVC does not.
225   //  - bit_AVX2 = (1 <<  5)
226   const unsigned int avx2_ebx7 = 0x00000020;
227   // GCC defines these macros but MSVC does not.
228   //  - bit_PCLMUL = (1 <<  1)
229   //  - bit_POPCNT = (1 << 23)
230   //  - bit_SSE4_2 = (1 << 20)
231   const unsigned int avx2_ecx1 = 0x00900002;
232 
233   // clang defines __GNUC__ and clang-cl defines _MSC_VER (but not __GNUC__).
234 #if defined(__GNUC__)
235   unsigned int eax7 = 0;
236   unsigned int ebx7 = 0;
237   unsigned int ecx7 = 0;
238   unsigned int edx7 = 0;
239   if (__get_cpuid_count(7, 0, &eax7, &ebx7, &ecx7, &edx7) &&
240       ((ebx7 & avx2_ebx7) == avx2_ebx7)) {
241     unsigned int eax1 = 0;
242     unsigned int ebx1 = 0;
243     unsigned int ecx1 = 0;
244     unsigned int edx1 = 0;
245     if (__get_cpuid(1, &eax1, &ebx1, &ecx1, &edx1) &&
246         ((ecx1 & avx2_ecx1) == avx2_ecx1)) {
247       return true;
248     }
249   }
250 #elif defined(_MSC_VER)  // defined(__GNUC__)
251   int x7[4];
252   __cpuidex(x7, 7, 0);
253   if ((((unsigned int)(x7[1])) & avx2_ebx7) == avx2_ebx7) {
254     int x1[4];
255     __cpuid(x1, 1);
256     if ((((unsigned int)(x1[2])) & avx2_ecx1) == avx2_ecx1) {
257       return true;
258     }
259   }
260 #else
261 #error "WUFFS_BASE__CPU_ARCH__ETC combined with an unsupported compiler"
262 #endif  // defined(__GNUC__); defined(_MSC_VER)
263 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_64)
264   return false;
265 #endif  // defined(__PCLMUL__) && defined(__POPCNT__) && defined(__SSE4_2__) &&
266         // defined(__AVX2__)
267 }
268 
269 static inline bool  //
wuffs_base__cpu_arch__have_x86_bmi2(void)270 wuffs_base__cpu_arch__have_x86_bmi2(void) {
271 #if defined(__BMI2__)
272   return true;
273 #else
274 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
275   // GCC defines these macros but MSVC does not.
276   //  - bit_BMI2 = (1 <<  8)
277   const unsigned int bmi2_ebx7 = 0x00000100;
278 
279   // clang defines __GNUC__ and clang-cl defines _MSC_VER (but not __GNUC__).
280 #if defined(__GNUC__)
281   unsigned int eax7 = 0;
282   unsigned int ebx7 = 0;
283   unsigned int ecx7 = 0;
284   unsigned int edx7 = 0;
285   if (__get_cpuid_count(7, 0, &eax7, &ebx7, &ecx7, &edx7) &&
286       ((ebx7 & bmi2_ebx7) == bmi2_ebx7)) {
287     return true;
288   }
289 #elif defined(_MSC_VER)  // defined(__GNUC__)
290   int x7[4];
291   __cpuidex(x7, 7, 0);
292   if ((((unsigned int)(x7[1])) & bmi2_ebx7) == bmi2_ebx7) {
293     return true;
294   }
295 #else
296 #error "WUFFS_BASE__CPU_ARCH__ETC combined with an unsupported compiler"
297 #endif  // defined(__GNUC__); defined(_MSC_VER)
298 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
299   return false;
300 #endif  // defined(__BMI2__)
301 }
302 
303 static inline bool  //
wuffs_base__cpu_arch__have_x86_sse42(void)304 wuffs_base__cpu_arch__have_x86_sse42(void) {
305 #if defined(__PCLMUL__) && defined(__POPCNT__) && defined(__SSE4_2__)
306   return true;
307 #else
308 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
309   // GCC defines these macros but MSVC does not.
310   //  - bit_PCLMUL = (1 <<  1)
311   //  - bit_POPCNT = (1 << 23)
312   //  - bit_SSE4_2 = (1 << 20)
313   const unsigned int sse42_ecx1 = 0x00900002;
314 
315   // clang defines __GNUC__ and clang-cl defines _MSC_VER (but not __GNUC__).
316 #if defined(__GNUC__)
317   unsigned int eax1 = 0;
318   unsigned int ebx1 = 0;
319   unsigned int ecx1 = 0;
320   unsigned int edx1 = 0;
321   if (__get_cpuid(1, &eax1, &ebx1, &ecx1, &edx1) &&
322       ((ecx1 & sse42_ecx1) == sse42_ecx1)) {
323     return true;
324   }
325 #elif defined(_MSC_VER)  // defined(__GNUC__)
326   int x1[4];
327   __cpuid(x1, 1);
328   if ((((unsigned int)(x1[2])) & sse42_ecx1) == sse42_ecx1) {
329     return true;
330   }
331 #else
332 #error "WUFFS_BASE__CPU_ARCH__ETC combined with an unsupported compiler"
333 #endif  // defined(__GNUC__); defined(_MSC_VER)
334 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
335   return false;
336 #endif  // defined(__PCLMUL__) && defined(__POPCNT__) && defined(__SSE4_2__)
337 }
338 
339 // ---------------- Fundamentals
340 
341 // Wuffs assumes that:
342 //  - converting a uint32_t to a size_t will never overflow.
343 //  - converting a size_t to a uint64_t will never overflow.
344 #if defined(__WORDSIZE)
345 #if (__WORDSIZE != 32) && (__WORDSIZE != 64)
346 #error "Wuffs requires a word size of either 32 or 64 bits"
347 #endif
348 #endif
349 
350 // The "defined(__clang__)" isn't redundant. While vanilla clang defines
351 // __GNUC__, clang-cl (which mimics MSVC's cl.exe) does not.
352 #if defined(__GNUC__) || defined(__clang__)
353 #define WUFFS_BASE__POTENTIALLY_UNUSED __attribute__((unused))
354 #define WUFFS_BASE__WARN_UNUSED_RESULT __attribute__((warn_unused_result))
355 #else
356 #define WUFFS_BASE__POTENTIALLY_UNUSED
357 #define WUFFS_BASE__WARN_UNUSED_RESULT
358 #endif
359 
360 // Clang's "-fsanitize=integer" checks for "unsigned-integer-overflow" even
361 // though, for *unsigned* integers, it is *not* undefined behavior. The check
362 // is still made because unsigned integer overflow "is often unintentional".
363 // https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html
364 //
365 // However, for Wuffs' generated C code, unsigned overflow is intentional. The
366 // programmer has to use "~mod+" instead of a plain "+" operator in Wuffs code.
367 // Further runtime checks for unsigned integer overflow can add performance
368 // overhead (fuzzers can then time out) and can raise false negatives, without
369 // generating much benefits. We disable the "unsigned-integer-overflow" check.
370 #if defined(__has_feature)
371 #if __has_feature(undefined_behavior_sanitizer)
372 #define WUFFS_BASE__GENERATED_C_CODE \
373   __attribute__((no_sanitize("unsigned-integer-overflow")))
374 #endif
375 #endif
376 #if !defined(WUFFS_BASE__GENERATED_C_CODE)
377 #define WUFFS_BASE__GENERATED_C_CODE
378 #endif
379 
380 // --------
381 
382 // Options (bitwise or'ed together) for wuffs_foo__bar__initialize functions.
383 
384 #define WUFFS_INITIALIZE__DEFAULT_OPTIONS ((uint32_t)0x00000000)
385 
386 // WUFFS_INITIALIZE__ALREADY_ZEROED means that the "self" receiver struct value
387 // has already been set to all zeroes.
388 #define WUFFS_INITIALIZE__ALREADY_ZEROED ((uint32_t)0x00000001)
389 
390 // WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED means that, absent
391 // WUFFS_INITIALIZE__ALREADY_ZEROED, only some of the "self" receiver struct
392 // value will be set to all zeroes. Internal buffers, which tend to be a large
393 // proportion of the struct's size, will be left uninitialized. Internal means
394 // that the buffer is contained by the receiver struct, as opposed to being
395 // passed as a separately allocated "work buffer".
396 //
397 // For more detail, see:
398 // https://github.com/google/wuffs/blob/main/doc/note/initialization.md
399 #define WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED \
400   ((uint32_t)0x00000002)
401 
402 // --------
403 
404 #ifdef __cplusplus
405 // Wuffs structs are just data, not resources (in the RAII sense). They don't
406 // subclass anything. They don't have virtual destructors. They don't contain
407 // pointers to dynamically allocated memory. They don't contain file
408 // descriptors. And so on. Destroying such a struct (e.g. via a
409 // wuffs_foo__bar::unique_ptr) can just call free, especially as
410 // sizeof(wuffs_foo__bar) isn't supposed to be part of the public (stable) API.
411 struct wuffs_unique_ptr_deleter {
operatorwuffs_unique_ptr_deleter412   void operator()(void* p) { free(p); }
413 };
414 #endif  // __cplusplus
415 
416 // --------
417 
418 // wuffs_base__empty_struct is used when a Wuffs function returns an empty
419 // struct. In C, if a function f returns void, you can't say "x = f()", but in
420 // Wuffs, if a function g returns empty, you can say "y = g()".
421 typedef struct wuffs_base__empty_struct__struct {
422   // private_impl is a placeholder field. It isn't explicitly used, except that
423   // without it, the sizeof a struct with no fields can differ across C/C++
424   // compilers, and it is undefined behavior in C99. For example, gcc says that
425   // the sizeof an empty struct is 0, and g++ says that it is 1. This leads to
426   // ABI incompatibility if a Wuffs .c file is processed by one compiler and
427   // its .h file with another compiler.
428   //
429   // Instead, we explicitly insert an otherwise unused field, so that the
430   // sizeof this struct is always 1.
431   uint8_t private_impl;
432 } wuffs_base__empty_struct;
433 
434 static inline wuffs_base__empty_struct  //
wuffs_base__make_empty_struct(void)435 wuffs_base__make_empty_struct(void) {
436   wuffs_base__empty_struct ret;
437   ret.private_impl = 0;
438   return ret;
439 }
440 
441 // wuffs_base__utility is a placeholder receiver type. It enables what Java
442 // calls static methods, as opposed to regular methods.
443 typedef struct wuffs_base__utility__struct {
444   // private_impl is a placeholder field. It isn't explicitly used, except that
445   // without it, the sizeof a struct with no fields can differ across C/C++
446   // compilers, and it is undefined behavior in C99. For example, gcc says that
447   // the sizeof an empty struct is 0, and g++ says that it is 1. This leads to
448   // ABI incompatibility if a Wuffs .c file is processed by one compiler and
449   // its .h file with another compiler.
450   //
451   // Instead, we explicitly insert an otherwise unused field, so that the
452   // sizeof this struct is always 1.
453   uint8_t private_impl;
454 } wuffs_base__utility;
455 
456 typedef struct wuffs_base__vtable__struct {
457   const char* vtable_name;
458   const void* function_pointers;
459 } wuffs_base__vtable;
460 
461 // --------
462 
463 // See https://github.com/google/wuffs/blob/main/doc/note/statuses.md
464 typedef struct wuffs_base__status__struct {
465   const char* repr;
466 
467 #ifdef __cplusplus
468   inline bool is_complete() const;
469   inline bool is_error() const;
470   inline bool is_note() const;
471   inline bool is_ok() const;
472   inline bool is_suspension() const;
473   inline bool is_truncated_input_error() const;
474   inline const char* message() const;
475 #endif  // __cplusplus
476 
477 } wuffs_base__status;
478 
479 extern const char wuffs_base__note__i_o_redirect[];
480 extern const char wuffs_base__note__end_of_data[];
481 extern const char wuffs_base__note__metadata_reported[];
482 extern const char wuffs_base__suspension__even_more_information[];
483 extern const char wuffs_base__suspension__mispositioned_read[];
484 extern const char wuffs_base__suspension__mispositioned_write[];
485 extern const char wuffs_base__suspension__short_read[];
486 extern const char wuffs_base__suspension__short_write[];
487 extern const char wuffs_base__error__bad_i_o_position[];
488 extern const char wuffs_base__error__bad_argument_length_too_short[];
489 extern const char wuffs_base__error__bad_argument[];
490 extern const char wuffs_base__error__bad_call_sequence[];
491 extern const char wuffs_base__error__bad_data[];
492 extern const char wuffs_base__error__bad_receiver[];
493 extern const char wuffs_base__error__bad_restart[];
494 extern const char wuffs_base__error__bad_sizeof_receiver[];
495 extern const char wuffs_base__error__bad_vtable[];
496 extern const char wuffs_base__error__bad_workbuf_length[];
497 extern const char wuffs_base__error__bad_wuffs_version[];
498 extern const char wuffs_base__error__cannot_return_a_suspension[];
499 extern const char wuffs_base__error__disabled_by_previous_error[];
500 extern const char wuffs_base__error__initialize_falsely_claimed_already_zeroed[];
501 extern const char wuffs_base__error__initialize_not_called[];
502 extern const char wuffs_base__error__interleaved_coroutine_calls[];
503 extern const char wuffs_base__error__no_more_information[];
504 extern const char wuffs_base__error__not_enough_data[];
505 extern const char wuffs_base__error__out_of_bounds[];
506 extern const char wuffs_base__error__unsupported_image_dimension[];
507 extern const char wuffs_base__error__unsupported_method[];
508 extern const char wuffs_base__error__unsupported_option[];
509 extern const char wuffs_base__error__unsupported_pixel_swizzler_option[];
510 extern const char wuffs_base__error__too_much_data[];
511 
512 static inline wuffs_base__status  //
wuffs_base__make_status(const char * repr)513 wuffs_base__make_status(const char* repr) {
514   wuffs_base__status z;
515   z.repr = repr;
516   return z;
517 }
518 
519 static inline bool  //
wuffs_base__status__is_complete(const wuffs_base__status * z)520 wuffs_base__status__is_complete(const wuffs_base__status* z) {
521   return (z->repr == NULL) || ((*z->repr != '$') && (*z->repr != '#'));
522 }
523 
524 static inline bool  //
wuffs_base__status__is_error(const wuffs_base__status * z)525 wuffs_base__status__is_error(const wuffs_base__status* z) {
526   return z->repr && (*z->repr == '#');
527 }
528 
529 static inline bool  //
wuffs_base__status__is_note(const wuffs_base__status * z)530 wuffs_base__status__is_note(const wuffs_base__status* z) {
531   return z->repr && (*z->repr != '$') && (*z->repr != '#');
532 }
533 
534 static inline bool  //
wuffs_base__status__is_ok(const wuffs_base__status * z)535 wuffs_base__status__is_ok(const wuffs_base__status* z) {
536   return z->repr == NULL;
537 }
538 
539 static inline bool  //
wuffs_base__status__is_suspension(const wuffs_base__status * z)540 wuffs_base__status__is_suspension(const wuffs_base__status* z) {
541   return z->repr && (*z->repr == '$');
542 }
543 
544 static inline bool  //
wuffs_base__status__is_truncated_input_error(const wuffs_base__status * z)545 wuffs_base__status__is_truncated_input_error(const wuffs_base__status* z) {
546   const char* p = z->repr;
547   if (!p || (*p != '#')) {
548     return false;
549   }
550   p++;
551   while (1) {
552     if (*p == 0) {
553       return false;
554     } else if (*p++ == ':') {
555       break;
556     }
557   }
558   return strcmp(p, " truncated input") == 0;
559 }
560 
561 // wuffs_base__status__message strips the leading '$', '#' or '@'.
562 static inline const char*  //
wuffs_base__status__message(const wuffs_base__status * z)563 wuffs_base__status__message(const wuffs_base__status* z) {
564   if (z->repr) {
565     if ((*z->repr == '$') || (*z->repr == '#') || (*z->repr == '@')) {
566       return z->repr + 1;
567     }
568   }
569   return z->repr;
570 }
571 
572 #ifdef __cplusplus
573 
574 inline bool  //
is_complete()575 wuffs_base__status::is_complete() const {
576   return wuffs_base__status__is_complete(this);
577 }
578 
579 inline bool  //
is_error()580 wuffs_base__status::is_error() const {
581   return wuffs_base__status__is_error(this);
582 }
583 
584 inline bool  //
is_note()585 wuffs_base__status::is_note() const {
586   return wuffs_base__status__is_note(this);
587 }
588 
589 inline bool  //
is_ok()590 wuffs_base__status::is_ok() const {
591   return wuffs_base__status__is_ok(this);
592 }
593 
594 inline bool  //
is_suspension()595 wuffs_base__status::is_suspension() const {
596   return wuffs_base__status__is_suspension(this);
597 }
598 
599 inline bool  //
is_truncated_input_error()600 wuffs_base__status::is_truncated_input_error() const {
601   return wuffs_base__status__is_truncated_input_error(this);
602 }
603 
604 inline const char*  //
message()605 wuffs_base__status::message() const {
606   return wuffs_base__status__message(this);
607 }
608 
609 #endif  // __cplusplus
610 
611 // --------
612 
613 // WUFFS_BASE__RESULT is a result type: either a status (an error) or a value.
614 //
615 // A result with all fields NULL or zero is as valid as a zero-valued T.
616 #define WUFFS_BASE__RESULT(T)  \
617   struct {                     \
618     wuffs_base__status status; \
619     T value;                   \
620   }
621 
622 typedef WUFFS_BASE__RESULT(double) wuffs_base__result_f64;
623 typedef WUFFS_BASE__RESULT(int64_t) wuffs_base__result_i64;
624 typedef WUFFS_BASE__RESULT(uint64_t) wuffs_base__result_u64;
625 
626 // --------
627 
628 // wuffs_base__transform__output is the result of transforming from a src slice
629 // to a dst slice.
630 typedef struct wuffs_base__transform__output__struct {
631   wuffs_base__status status;
632   size_t num_dst;
633   size_t num_src;
634 } wuffs_base__transform__output;
635 
636 // --------
637 
638 // FourCC constants. Four Character Codes are literally four ASCII characters
639 // (sometimes padded with ' ' spaces) that pack neatly into a signed or
640 // unsigned 32-bit integer. ASCII letters are conventionally upper case.
641 //
642 // They are often used to identify video codecs (e.g. "H265") and pixel formats
643 // (e.g. "YV12"). Wuffs uses them for that but also generally for naming
644 // various things: compression formats (e.g. "BZ2 "), image metadata (e.g.
645 // "EXIF"), file formats (e.g. "HTML"), etc.
646 //
647 // Wuffs' u32 values are big-endian ("JPEG" is 0x4A504547 not 0x4745504A) to
648 // preserve ordering: "JPEG" < "MP3 " and 0x4A504547 < 0x4D503320.
649 
650 // Background Color.
651 #define WUFFS_BASE__FOURCC__BGCL 0x4247434C
652 
653 // Bitmap.
654 #define WUFFS_BASE__FOURCC__BMP 0x424D5020
655 
656 // Brotli.
657 #define WUFFS_BASE__FOURCC__BRTL 0x4252544C
658 
659 // Bzip2.
660 #define WUFFS_BASE__FOURCC__BZ2 0x425A3220
661 
662 // Concise Binary Object Representation.
663 #define WUFFS_BASE__FOURCC__CBOR 0x43424F52
664 
665 // Primary Chromaticities and White Point.
666 #define WUFFS_BASE__FOURCC__CHRM 0x4348524D
667 
668 // Cascading Style Sheets.
669 #define WUFFS_BASE__FOURCC__CSS 0x43535320
670 
671 // Encapsulated PostScript.
672 #define WUFFS_BASE__FOURCC__EPS 0x45505320
673 
674 // Exchangeable Image File Format.
675 #define WUFFS_BASE__FOURCC__EXIF 0x45584946
676 
677 // Free Lossless Audio Codec.
678 #define WUFFS_BASE__FOURCC__FLAC 0x464C4143
679 
680 // Gamma Correction.
681 #define WUFFS_BASE__FOURCC__GAMA 0x47414D41
682 
683 // Graphics Interchange Format.
684 #define WUFFS_BASE__FOURCC__GIF 0x47494620
685 
686 // GNU Zip.
687 #define WUFFS_BASE__FOURCC__GZ 0x475A2020
688 
689 // High Efficiency Image File.
690 #define WUFFS_BASE__FOURCC__HEIF 0x48454946
691 
692 // Hypertext Markup Language.
693 #define WUFFS_BASE__FOURCC__HTML 0x48544D4C
694 
695 // International Color Consortium Profile.
696 #define WUFFS_BASE__FOURCC__ICCP 0x49434350
697 
698 // Icon.
699 #define WUFFS_BASE__FOURCC__ICO 0x49434F20
700 
701 // Icon Vector Graphics.
702 #define WUFFS_BASE__FOURCC__ICVG 0x49435647
703 
704 // Initialization.
705 #define WUFFS_BASE__FOURCC__INI 0x494E4920
706 
707 // Joint Photographic Experts Group.
708 #define WUFFS_BASE__FOURCC__JPEG 0x4A504547
709 
710 // JavaScript.
711 #define WUFFS_BASE__FOURCC__JS 0x4A532020
712 
713 // JavaScript Object Notation.
714 #define WUFFS_BASE__FOURCC__JSON 0x4A534F4E
715 
716 // JSON With Commas and Comments.
717 #define WUFFS_BASE__FOURCC__JWCC 0x4A574343
718 
719 // Key-Value Pair.
720 #define WUFFS_BASE__FOURCC__KVP 0x4B565020
721 
722 // Key-Value Pair (Key).
723 #define WUFFS_BASE__FOURCC__KVPK 0x4B56504B
724 
725 // Key-Value Pair (Value).
726 #define WUFFS_BASE__FOURCC__KVPV 0x4B565056
727 
728 // Lempel–Ziv 4.
729 #define WUFFS_BASE__FOURCC__LZ4 0x4C5A3420
730 
731 // Lempel–Ziv Markov-chain Algorithm.
732 #define WUFFS_BASE__FOURCC__LZMA 0x4C5A4D41
733 
734 // Markdown.
735 #define WUFFS_BASE__FOURCC__MD 0x4D442020
736 
737 // Modification Time.
738 #define WUFFS_BASE__FOURCC__MTIM 0x4D54494D
739 
740 // MPEG-1 Audio Layer III.
741 #define WUFFS_BASE__FOURCC__MP3 0x4D503320
742 
743 // Naive Image.
744 #define WUFFS_BASE__FOURCC__NIE 0x4E494520
745 
746 // Netpbm (Portable Anymap).
747 #define WUFFS_BASE__FOURCC__NPBM 0x4E50424D
748 
749 // Offset (2-Dimensional).
750 #define WUFFS_BASE__FOURCC__OFS2 0x4F465332
751 
752 // Open Type Format.
753 #define WUFFS_BASE__FOURCC__OTF 0x4F544620
754 
755 // Portable Document Format.
756 #define WUFFS_BASE__FOURCC__PDF 0x50444620
757 
758 // Physical Dimensions.
759 #define WUFFS_BASE__FOURCC__PHYD 0x50485944
760 
761 // Portable Network Graphics.
762 #define WUFFS_BASE__FOURCC__PNG 0x504E4720
763 
764 // PostScript.
765 #define WUFFS_BASE__FOURCC__PS 0x50532020
766 
767 // Quite OK Image.
768 #define WUFFS_BASE__FOURCC__QOI 0x514F4920
769 
770 // Random Access Compression.
771 #define WUFFS_BASE__FOURCC__RAC 0x52414320
772 
773 // Raw.
774 #define WUFFS_BASE__FOURCC__RAW 0x52415720
775 
776 // Resource Interchange File Format.
777 #define WUFFS_BASE__FOURCC__RIFF 0x52494646
778 
779 // Riegeli Records.
780 #define WUFFS_BASE__FOURCC__RIGL 0x5249474C
781 
782 // Snappy.
783 #define WUFFS_BASE__FOURCC__SNPY 0x534E5059
784 
785 // Standard Red Green Blue (Rendering Intent).
786 #define WUFFS_BASE__FOURCC__SRGB 0x53524742
787 
788 // Scalable Vector Graphics.
789 #define WUFFS_BASE__FOURCC__SVG 0x53564720
790 
791 // Tape Archive.
792 #define WUFFS_BASE__FOURCC__TAR 0x54415220
793 
794 // Text.
795 #define WUFFS_BASE__FOURCC__TEXT 0x54455854
796 
797 // Truevision Advanced Raster Graphics Adapter.
798 #define WUFFS_BASE__FOURCC__TGA 0x54474120
799 
800 // Tagged Image File Format.
801 #define WUFFS_BASE__FOURCC__TIFF 0x54494646
802 
803 // Tom's Obvious Minimal Language.
804 #define WUFFS_BASE__FOURCC__TOML 0x544F4D4C
805 
806 // Waveform.
807 #define WUFFS_BASE__FOURCC__WAVE 0x57415645
808 
809 // Wireless Bitmap.
810 #define WUFFS_BASE__FOURCC__WBMP 0x57424D50
811 
812 // Web Picture.
813 #define WUFFS_BASE__FOURCC__WEBP 0x57454250
814 
815 // Web Open Font Format.
816 #define WUFFS_BASE__FOURCC__WOFF 0x574F4646
817 
818 // Extensible Markup Language.
819 #define WUFFS_BASE__FOURCC__XML 0x584D4C20
820 
821 // Extensible Metadata Platform.
822 #define WUFFS_BASE__FOURCC__XMP 0x584D5020
823 
824 // Xz.
825 #define WUFFS_BASE__FOURCC__XZ 0x585A2020
826 
827 // Zip.
828 #define WUFFS_BASE__FOURCC__ZIP 0x5A495020
829 
830 // Zlib.
831 #define WUFFS_BASE__FOURCC__ZLIB 0x5A4C4942
832 
833 // Zstandard.
834 #define WUFFS_BASE__FOURCC__ZSTD 0x5A535444
835 
836 // --------
837 
838 // Quirks.
839 
840 #define WUFFS_BASE__QUIRK_IGNORE_CHECKSUM 1
841 
842 // --------
843 
844 // Flicks are a unit of time. One flick (frame-tick) is 1 / 705_600_000 of a
845 // second. See https://github.com/OculusVR/Flicks
846 typedef int64_t wuffs_base__flicks;
847 
848 #define WUFFS_BASE__FLICKS_PER_SECOND ((uint64_t)705600000)
849 #define WUFFS_BASE__FLICKS_PER_MILLISECOND ((uint64_t)705600)
850 
851 // ---------------- Numeric Types
852 
853 // The helpers below are functions, instead of macros, because their arguments
854 // can be an expression that we shouldn't evaluate more than once.
855 //
856 // They are static, so that linking multiple wuffs .o files won't complain about
857 // duplicate function definitions.
858 //
859 // They are explicitly marked inline, even if modern compilers don't use the
860 // inline attribute to guide optimizations such as inlining, to avoid the
861 // -Wunused-function warning, and we like to compile with -Wall -Werror.
862 
863 static inline int8_t  //
wuffs_base__i8__min(int8_t x,int8_t y)864 wuffs_base__i8__min(int8_t x, int8_t y) {
865   return x < y ? x : y;
866 }
867 
868 static inline int8_t  //
wuffs_base__i8__max(int8_t x,int8_t y)869 wuffs_base__i8__max(int8_t x, int8_t y) {
870   return x > y ? x : y;
871 }
872 
873 static inline int16_t  //
wuffs_base__i16__min(int16_t x,int16_t y)874 wuffs_base__i16__min(int16_t x, int16_t y) {
875   return x < y ? x : y;
876 }
877 
878 static inline int16_t  //
wuffs_base__i16__max(int16_t x,int16_t y)879 wuffs_base__i16__max(int16_t x, int16_t y) {
880   return x > y ? x : y;
881 }
882 
883 static inline int32_t  //
wuffs_base__i32__min(int32_t x,int32_t y)884 wuffs_base__i32__min(int32_t x, int32_t y) {
885   return x < y ? x : y;
886 }
887 
888 static inline int32_t  //
wuffs_base__i32__max(int32_t x,int32_t y)889 wuffs_base__i32__max(int32_t x, int32_t y) {
890   return x > y ? x : y;
891 }
892 
893 static inline int64_t  //
wuffs_base__i64__min(int64_t x,int64_t y)894 wuffs_base__i64__min(int64_t x, int64_t y) {
895   return x < y ? x : y;
896 }
897 
898 static inline int64_t  //
wuffs_base__i64__max(int64_t x,int64_t y)899 wuffs_base__i64__max(int64_t x, int64_t y) {
900   return x > y ? x : y;
901 }
902 
903 static inline uint8_t  //
wuffs_base__u8__min(uint8_t x,uint8_t y)904 wuffs_base__u8__min(uint8_t x, uint8_t y) {
905   return x < y ? x : y;
906 }
907 
908 static inline uint8_t  //
wuffs_base__u8__max(uint8_t x,uint8_t y)909 wuffs_base__u8__max(uint8_t x, uint8_t y) {
910   return x > y ? x : y;
911 }
912 
913 static inline uint16_t  //
wuffs_base__u16__min(uint16_t x,uint16_t y)914 wuffs_base__u16__min(uint16_t x, uint16_t y) {
915   return x < y ? x : y;
916 }
917 
918 static inline uint16_t  //
wuffs_base__u16__max(uint16_t x,uint16_t y)919 wuffs_base__u16__max(uint16_t x, uint16_t y) {
920   return x > y ? x : y;
921 }
922 
923 static inline uint32_t  //
wuffs_base__u32__min(uint32_t x,uint32_t y)924 wuffs_base__u32__min(uint32_t x, uint32_t y) {
925   return x < y ? x : y;
926 }
927 
928 static inline uint32_t  //
wuffs_base__u32__max(uint32_t x,uint32_t y)929 wuffs_base__u32__max(uint32_t x, uint32_t y) {
930   return x > y ? x : y;
931 }
932 
933 static inline uint64_t  //
wuffs_base__u64__min(uint64_t x,uint64_t y)934 wuffs_base__u64__min(uint64_t x, uint64_t y) {
935   return x < y ? x : y;
936 }
937 
938 static inline uint64_t  //
wuffs_base__u64__max(uint64_t x,uint64_t y)939 wuffs_base__u64__max(uint64_t x, uint64_t y) {
940   return x > y ? x : y;
941 }
942 
943 // --------
944 
945 static inline uint8_t  //
wuffs_base__u8__rotate_left(uint8_t x,uint32_t n)946 wuffs_base__u8__rotate_left(uint8_t x, uint32_t n) {
947   n &= 7;
948   return ((uint8_t)(x << n)) | ((uint8_t)(x >> (8 - n)));
949 }
950 
951 static inline uint8_t  //
wuffs_base__u8__rotate_right(uint8_t x,uint32_t n)952 wuffs_base__u8__rotate_right(uint8_t x, uint32_t n) {
953   n &= 7;
954   return ((uint8_t)(x >> n)) | ((uint8_t)(x << (8 - n)));
955 }
956 
957 static inline uint16_t  //
wuffs_base__u16__rotate_left(uint16_t x,uint32_t n)958 wuffs_base__u16__rotate_left(uint16_t x, uint32_t n) {
959   n &= 15;
960   return ((uint16_t)(x << n)) | ((uint16_t)(x >> (16 - n)));
961 }
962 
963 static inline uint16_t  //
wuffs_base__u16__rotate_right(uint16_t x,uint32_t n)964 wuffs_base__u16__rotate_right(uint16_t x, uint32_t n) {
965   n &= 15;
966   return ((uint16_t)(x >> n)) | ((uint16_t)(x << (16 - n)));
967 }
968 
969 static inline uint32_t  //
wuffs_base__u32__rotate_left(uint32_t x,uint32_t n)970 wuffs_base__u32__rotate_left(uint32_t x, uint32_t n) {
971   n &= 31;
972   return ((uint32_t)(x << n)) | ((uint32_t)(x >> (32 - n)));
973 }
974 
975 static inline uint32_t  //
wuffs_base__u32__rotate_right(uint32_t x,uint32_t n)976 wuffs_base__u32__rotate_right(uint32_t x, uint32_t n) {
977   n &= 31;
978   return ((uint32_t)(x >> n)) | ((uint32_t)(x << (32 - n)));
979 }
980 
981 static inline uint64_t  //
wuffs_base__u64__rotate_left(uint64_t x,uint32_t n)982 wuffs_base__u64__rotate_left(uint64_t x, uint32_t n) {
983   n &= 63;
984   return ((uint64_t)(x << n)) | ((uint64_t)(x >> (64 - n)));
985 }
986 
987 static inline uint64_t  //
wuffs_base__u64__rotate_right(uint64_t x,uint32_t n)988 wuffs_base__u64__rotate_right(uint64_t x, uint32_t n) {
989   n &= 63;
990   return ((uint64_t)(x >> n)) | ((uint64_t)(x << (64 - n)));
991 }
992 
993 // --------
994 
995 // Saturating arithmetic (sat_add, sat_sub) branchless bit-twiddling algorithms
996 // are per https://locklessinc.com/articles/sat_arithmetic/
997 //
998 // It is important that the underlying types are unsigned integers, as signed
999 // integer arithmetic overflow is undefined behavior in C.
1000 
1001 static inline uint8_t  //
wuffs_base__u8__sat_add(uint8_t x,uint8_t y)1002 wuffs_base__u8__sat_add(uint8_t x, uint8_t y) {
1003   uint8_t res = (uint8_t)(x + y);
1004   res |= (uint8_t)(-(res < x));
1005   return res;
1006 }
1007 
1008 static inline uint8_t  //
wuffs_base__u8__sat_sub(uint8_t x,uint8_t y)1009 wuffs_base__u8__sat_sub(uint8_t x, uint8_t y) {
1010   uint8_t res = (uint8_t)(x - y);
1011   res &= (uint8_t)(-(res <= x));
1012   return res;
1013 }
1014 
1015 static inline uint16_t  //
wuffs_base__u16__sat_add(uint16_t x,uint16_t y)1016 wuffs_base__u16__sat_add(uint16_t x, uint16_t y) {
1017   uint16_t res = (uint16_t)(x + y);
1018   res |= (uint16_t)(-(res < x));
1019   return res;
1020 }
1021 
1022 static inline uint16_t  //
wuffs_base__u16__sat_sub(uint16_t x,uint16_t y)1023 wuffs_base__u16__sat_sub(uint16_t x, uint16_t y) {
1024   uint16_t res = (uint16_t)(x - y);
1025   res &= (uint16_t)(-(res <= x));
1026   return res;
1027 }
1028 
1029 static inline uint32_t  //
wuffs_base__u32__sat_add(uint32_t x,uint32_t y)1030 wuffs_base__u32__sat_add(uint32_t x, uint32_t y) {
1031   uint32_t res = (uint32_t)(x + y);
1032   res |= (uint32_t)(-(res < x));
1033   return res;
1034 }
1035 
1036 static inline uint32_t  //
wuffs_base__u32__sat_sub(uint32_t x,uint32_t y)1037 wuffs_base__u32__sat_sub(uint32_t x, uint32_t y) {
1038   uint32_t res = (uint32_t)(x - y);
1039   res &= (uint32_t)(-(res <= x));
1040   return res;
1041 }
1042 
1043 static inline uint64_t  //
wuffs_base__u64__sat_add(uint64_t x,uint64_t y)1044 wuffs_base__u64__sat_add(uint64_t x, uint64_t y) {
1045   uint64_t res = (uint64_t)(x + y);
1046   res |= (uint64_t)(-(res < x));
1047   return res;
1048 }
1049 
1050 static inline uint64_t  //
wuffs_base__u64__sat_sub(uint64_t x,uint64_t y)1051 wuffs_base__u64__sat_sub(uint64_t x, uint64_t y) {
1052   uint64_t res = (uint64_t)(x - y);
1053   res &= (uint64_t)(-(res <= x));
1054   return res;
1055 }
1056 
1057 // --------
1058 
1059 typedef struct wuffs_base__multiply_u64__output__struct {
1060   uint64_t lo;
1061   uint64_t hi;
1062 } wuffs_base__multiply_u64__output;
1063 
1064 // wuffs_base__multiply_u64 returns x*y as a 128-bit value.
1065 //
1066 // The maximum inclusive output hi_lo is 0xFFFFFFFFFFFFFFFE_0000000000000001.
1067 static inline wuffs_base__multiply_u64__output  //
wuffs_base__multiply_u64(uint64_t x,uint64_t y)1068 wuffs_base__multiply_u64(uint64_t x, uint64_t y) {
1069 #if defined(__SIZEOF_INT128__)
1070   __uint128_t z = ((__uint128_t)x) * ((__uint128_t)y);
1071   wuffs_base__multiply_u64__output o;
1072   o.lo = ((uint64_t)(z));
1073   o.hi = ((uint64_t)(z >> 64));
1074   return o;
1075 #else
1076   // TODO: consider using the _mul128 intrinsic if defined(_MSC_VER).
1077   uint64_t x0 = x & 0xFFFFFFFF;
1078   uint64_t x1 = x >> 32;
1079   uint64_t y0 = y & 0xFFFFFFFF;
1080   uint64_t y1 = y >> 32;
1081   uint64_t w0 = x0 * y0;
1082   uint64_t t = (x1 * y0) + (w0 >> 32);
1083   uint64_t w1 = t & 0xFFFFFFFF;
1084   uint64_t w2 = t >> 32;
1085   w1 += x0 * y1;
1086   wuffs_base__multiply_u64__output o;
1087   o.lo = x * y;
1088   o.hi = (x1 * y1) + w2 + (w1 >> 32);
1089   return o;
1090 #endif
1091 }
1092 
1093 // --------
1094 
1095 // The "defined(__clang__)" isn't redundant. While vanilla clang defines
1096 // __GNUC__, clang-cl (which mimics MSVC's cl.exe) does not.
1097 #if (defined(__GNUC__) || defined(__clang__)) && (__SIZEOF_LONG__ == 8)
1098 
1099 static inline uint32_t  //
wuffs_base__count_leading_zeroes_u64(uint64_t u)1100 wuffs_base__count_leading_zeroes_u64(uint64_t u) {
1101   return u ? ((uint32_t)(__builtin_clzl(u))) : 64u;
1102 }
1103 
1104 #else
1105 // TODO: consider using the _BitScanReverse intrinsic if defined(_MSC_VER).
1106 
1107 static inline uint32_t  //
wuffs_base__count_leading_zeroes_u64(uint64_t u)1108 wuffs_base__count_leading_zeroes_u64(uint64_t u) {
1109   if (u == 0) {
1110     return 64;
1111   }
1112 
1113   uint32_t n = 0;
1114   if ((u >> 32) == 0) {
1115     n |= 32;
1116     u <<= 32;
1117   }
1118   if ((u >> 48) == 0) {
1119     n |= 16;
1120     u <<= 16;
1121   }
1122   if ((u >> 56) == 0) {
1123     n |= 8;
1124     u <<= 8;
1125   }
1126   if ((u >> 60) == 0) {
1127     n |= 4;
1128     u <<= 4;
1129   }
1130   if ((u >> 62) == 0) {
1131     n |= 2;
1132     u <<= 2;
1133   }
1134   if ((u >> 63) == 0) {
1135     n |= 1;
1136     u <<= 1;
1137   }
1138   return n;
1139 }
1140 
1141 #endif  // (defined(__GNUC__) || defined(__clang__)) && (__SIZEOF_LONG__ == 8)
1142 
1143 // --------
1144 
1145 // Normally, the wuffs_base__peek_etc and wuffs_base__poke_etc implementations
1146 // are both (1) correct regardless of CPU endianness and (2) very fast (e.g. an
1147 // inlined wuffs_base__peek_u32le__no_bounds_check call, in an optimized clang
1148 // or gcc build, is a single MOV instruction on x86_64).
1149 //
1150 // However, the endian-agnostic implementations are slow on Microsoft's C
1151 // compiler (MSC). Alternative memcpy-based implementations restore speed, but
1152 // they are only correct on little-endian CPU architectures. Defining
1153 // WUFFS_BASE__USE_MEMCPY_LE_PEEK_POKE opts in to these implementations.
1154 //
1155 // https://godbolt.org/z/q4MfjzTPh
1156 #if defined(_MSC_VER) && !defined(__clang__) && \
1157     (defined(_M_ARM64) || defined(_M_X64))
1158 #define WUFFS_BASE__USE_MEMCPY_LE_PEEK_POKE
1159 #endif
1160 
1161 #define wuffs_base__peek_u8be__no_bounds_check \
1162   wuffs_base__peek_u8__no_bounds_check
1163 #define wuffs_base__peek_u8le__no_bounds_check \
1164   wuffs_base__peek_u8__no_bounds_check
1165 
1166 static inline uint8_t  //
wuffs_base__peek_u8__no_bounds_check(const uint8_t * p)1167 wuffs_base__peek_u8__no_bounds_check(const uint8_t* p) {
1168   return p[0];
1169 }
1170 
1171 static inline uint16_t  //
wuffs_base__peek_u16be__no_bounds_check(const uint8_t * p)1172 wuffs_base__peek_u16be__no_bounds_check(const uint8_t* p) {
1173 #if defined(WUFFS_BASE__USE_MEMCPY_LE_PEEK_POKE)
1174   uint16_t x;
1175   memcpy(&x, p, 2);
1176   return _byteswap_ushort(x);
1177 #else
1178   return (uint16_t)(((uint16_t)(p[0]) << 8) | ((uint16_t)(p[1]) << 0));
1179 #endif
1180 }
1181 
1182 static inline uint16_t  //
wuffs_base__peek_u16le__no_bounds_check(const uint8_t * p)1183 wuffs_base__peek_u16le__no_bounds_check(const uint8_t* p) {
1184 #if defined(WUFFS_BASE__USE_MEMCPY_LE_PEEK_POKE)
1185   uint16_t x;
1186   memcpy(&x, p, 2);
1187   return x;
1188 #else
1189   return (uint16_t)(((uint16_t)(p[0]) << 0) | ((uint16_t)(p[1]) << 8));
1190 #endif
1191 }
1192 
1193 static inline uint32_t  //
wuffs_base__peek_u24be__no_bounds_check(const uint8_t * p)1194 wuffs_base__peek_u24be__no_bounds_check(const uint8_t* p) {
1195   return ((uint32_t)(p[0]) << 16) | ((uint32_t)(p[1]) << 8) |
1196          ((uint32_t)(p[2]) << 0);
1197 }
1198 
1199 static inline uint32_t  //
wuffs_base__peek_u24le__no_bounds_check(const uint8_t * p)1200 wuffs_base__peek_u24le__no_bounds_check(const uint8_t* p) {
1201   return ((uint32_t)(p[0]) << 0) | ((uint32_t)(p[1]) << 8) |
1202          ((uint32_t)(p[2]) << 16);
1203 }
1204 
1205 static inline uint32_t  //
wuffs_base__peek_u32be__no_bounds_check(const uint8_t * p)1206 wuffs_base__peek_u32be__no_bounds_check(const uint8_t* p) {
1207 #if defined(WUFFS_BASE__USE_MEMCPY_LE_PEEK_POKE)
1208   uint32_t x;
1209   memcpy(&x, p, 4);
1210   return _byteswap_ulong(x);
1211 #else
1212   return ((uint32_t)(p[0]) << 24) | ((uint32_t)(p[1]) << 16) |
1213          ((uint32_t)(p[2]) << 8) | ((uint32_t)(p[3]) << 0);
1214 #endif
1215 }
1216 
1217 static inline uint32_t  //
wuffs_base__peek_u32le__no_bounds_check(const uint8_t * p)1218 wuffs_base__peek_u32le__no_bounds_check(const uint8_t* p) {
1219 #if defined(WUFFS_BASE__USE_MEMCPY_LE_PEEK_POKE)
1220   uint32_t x;
1221   memcpy(&x, p, 4);
1222   return x;
1223 #else
1224   return ((uint32_t)(p[0]) << 0) | ((uint32_t)(p[1]) << 8) |
1225          ((uint32_t)(p[2]) << 16) | ((uint32_t)(p[3]) << 24);
1226 #endif
1227 }
1228 
1229 static inline uint64_t  //
wuffs_base__peek_u40be__no_bounds_check(const uint8_t * p)1230 wuffs_base__peek_u40be__no_bounds_check(const uint8_t* p) {
1231   return ((uint64_t)(p[0]) << 32) | ((uint64_t)(p[1]) << 24) |
1232          ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 8) |
1233          ((uint64_t)(p[4]) << 0);
1234 }
1235 
1236 static inline uint64_t  //
wuffs_base__peek_u40le__no_bounds_check(const uint8_t * p)1237 wuffs_base__peek_u40le__no_bounds_check(const uint8_t* p) {
1238   return ((uint64_t)(p[0]) << 0) | ((uint64_t)(p[1]) << 8) |
1239          ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
1240          ((uint64_t)(p[4]) << 32);
1241 }
1242 
1243 static inline uint64_t  //
wuffs_base__peek_u48be__no_bounds_check(const uint8_t * p)1244 wuffs_base__peek_u48be__no_bounds_check(const uint8_t* p) {
1245   return ((uint64_t)(p[0]) << 40) | ((uint64_t)(p[1]) << 32) |
1246          ((uint64_t)(p[2]) << 24) | ((uint64_t)(p[3]) << 16) |
1247          ((uint64_t)(p[4]) << 8) | ((uint64_t)(p[5]) << 0);
1248 }
1249 
1250 static inline uint64_t  //
wuffs_base__peek_u48le__no_bounds_check(const uint8_t * p)1251 wuffs_base__peek_u48le__no_bounds_check(const uint8_t* p) {
1252   return ((uint64_t)(p[0]) << 0) | ((uint64_t)(p[1]) << 8) |
1253          ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
1254          ((uint64_t)(p[4]) << 32) | ((uint64_t)(p[5]) << 40);
1255 }
1256 
1257 static inline uint64_t  //
wuffs_base__peek_u56be__no_bounds_check(const uint8_t * p)1258 wuffs_base__peek_u56be__no_bounds_check(const uint8_t* p) {
1259   return ((uint64_t)(p[0]) << 48) | ((uint64_t)(p[1]) << 40) |
1260          ((uint64_t)(p[2]) << 32) | ((uint64_t)(p[3]) << 24) |
1261          ((uint64_t)(p[4]) << 16) | ((uint64_t)(p[5]) << 8) |
1262          ((uint64_t)(p[6]) << 0);
1263 }
1264 
1265 static inline uint64_t  //
wuffs_base__peek_u56le__no_bounds_check(const uint8_t * p)1266 wuffs_base__peek_u56le__no_bounds_check(const uint8_t* p) {
1267   return ((uint64_t)(p[0]) << 0) | ((uint64_t)(p[1]) << 8) |
1268          ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
1269          ((uint64_t)(p[4]) << 32) | ((uint64_t)(p[5]) << 40) |
1270          ((uint64_t)(p[6]) << 48);
1271 }
1272 
1273 static inline uint64_t  //
wuffs_base__peek_u64be__no_bounds_check(const uint8_t * p)1274 wuffs_base__peek_u64be__no_bounds_check(const uint8_t* p) {
1275 #if defined(WUFFS_BASE__USE_MEMCPY_LE_PEEK_POKE)
1276   uint64_t x;
1277   memcpy(&x, p, 8);
1278   return _byteswap_uint64(x);
1279 #else
1280   return ((uint64_t)(p[0]) << 56) | ((uint64_t)(p[1]) << 48) |
1281          ((uint64_t)(p[2]) << 40) | ((uint64_t)(p[3]) << 32) |
1282          ((uint64_t)(p[4]) << 24) | ((uint64_t)(p[5]) << 16) |
1283          ((uint64_t)(p[6]) << 8) | ((uint64_t)(p[7]) << 0);
1284 #endif
1285 }
1286 
1287 static inline uint64_t  //
wuffs_base__peek_u64le__no_bounds_check(const uint8_t * p)1288 wuffs_base__peek_u64le__no_bounds_check(const uint8_t* p) {
1289 #if defined(WUFFS_BASE__USE_MEMCPY_LE_PEEK_POKE)
1290   uint64_t x;
1291   memcpy(&x, p, 8);
1292   return x;
1293 #else
1294   return ((uint64_t)(p[0]) << 0) | ((uint64_t)(p[1]) << 8) |
1295          ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
1296          ((uint64_t)(p[4]) << 32) | ((uint64_t)(p[5]) << 40) |
1297          ((uint64_t)(p[6]) << 48) | ((uint64_t)(p[7]) << 56);
1298 #endif
1299 }
1300 
1301 // --------
1302 
1303 #define wuffs_base__poke_u8be__no_bounds_check \
1304   wuffs_base__poke_u8__no_bounds_check
1305 #define wuffs_base__poke_u8le__no_bounds_check \
1306   wuffs_base__poke_u8__no_bounds_check
1307 
1308 static inline void  //
wuffs_base__poke_u8__no_bounds_check(uint8_t * p,uint8_t x)1309 wuffs_base__poke_u8__no_bounds_check(uint8_t* p, uint8_t x) {
1310   p[0] = x;
1311 }
1312 
1313 static inline void  //
wuffs_base__poke_u16be__no_bounds_check(uint8_t * p,uint16_t x)1314 wuffs_base__poke_u16be__no_bounds_check(uint8_t* p, uint16_t x) {
1315   p[0] = (uint8_t)(x >> 8);
1316   p[1] = (uint8_t)(x >> 0);
1317 }
1318 
1319 static inline void  //
wuffs_base__poke_u16le__no_bounds_check(uint8_t * p,uint16_t x)1320 wuffs_base__poke_u16le__no_bounds_check(uint8_t* p, uint16_t x) {
1321 #if defined(WUFFS_BASE__USE_MEMCPY_LE_PEEK_POKE) || \
1322     (defined(__GNUC__) && !defined(__clang__) && defined(__x86_64__))
1323   // This seems to perform better on gcc 10 (but not clang 9). Clang also
1324   // defines "__GNUC__".
1325   memcpy(p, &x, 2);
1326 #else
1327   p[0] = (uint8_t)(x >> 0);
1328   p[1] = (uint8_t)(x >> 8);
1329 #endif
1330 }
1331 
1332 static inline void  //
wuffs_base__poke_u24be__no_bounds_check(uint8_t * p,uint32_t x)1333 wuffs_base__poke_u24be__no_bounds_check(uint8_t* p, uint32_t x) {
1334   p[0] = (uint8_t)(x >> 16);
1335   p[1] = (uint8_t)(x >> 8);
1336   p[2] = (uint8_t)(x >> 0);
1337 }
1338 
1339 static inline void  //
wuffs_base__poke_u24le__no_bounds_check(uint8_t * p,uint32_t x)1340 wuffs_base__poke_u24le__no_bounds_check(uint8_t* p, uint32_t x) {
1341   p[0] = (uint8_t)(x >> 0);
1342   p[1] = (uint8_t)(x >> 8);
1343   p[2] = (uint8_t)(x >> 16);
1344 }
1345 
1346 static inline void  //
wuffs_base__poke_u32be__no_bounds_check(uint8_t * p,uint32_t x)1347 wuffs_base__poke_u32be__no_bounds_check(uint8_t* p, uint32_t x) {
1348   p[0] = (uint8_t)(x >> 24);
1349   p[1] = (uint8_t)(x >> 16);
1350   p[2] = (uint8_t)(x >> 8);
1351   p[3] = (uint8_t)(x >> 0);
1352 }
1353 
1354 static inline void  //
wuffs_base__poke_u32le__no_bounds_check(uint8_t * p,uint32_t x)1355 wuffs_base__poke_u32le__no_bounds_check(uint8_t* p, uint32_t x) {
1356 #if defined(WUFFS_BASE__USE_MEMCPY_LE_PEEK_POKE) || \
1357     (defined(__GNUC__) && !defined(__clang__) && defined(__x86_64__))
1358   // This seems to perform better on gcc 10 (but not clang 9). Clang also
1359   // defines "__GNUC__".
1360   memcpy(p, &x, 4);
1361 #else
1362   p[0] = (uint8_t)(x >> 0);
1363   p[1] = (uint8_t)(x >> 8);
1364   p[2] = (uint8_t)(x >> 16);
1365   p[3] = (uint8_t)(x >> 24);
1366 #endif
1367 }
1368 
1369 static inline void  //
wuffs_base__poke_u40be__no_bounds_check(uint8_t * p,uint64_t x)1370 wuffs_base__poke_u40be__no_bounds_check(uint8_t* p, uint64_t x) {
1371   p[0] = (uint8_t)(x >> 32);
1372   p[1] = (uint8_t)(x >> 24);
1373   p[2] = (uint8_t)(x >> 16);
1374   p[3] = (uint8_t)(x >> 8);
1375   p[4] = (uint8_t)(x >> 0);
1376 }
1377 
1378 static inline void  //
wuffs_base__poke_u40le__no_bounds_check(uint8_t * p,uint64_t x)1379 wuffs_base__poke_u40le__no_bounds_check(uint8_t* p, uint64_t x) {
1380   p[0] = (uint8_t)(x >> 0);
1381   p[1] = (uint8_t)(x >> 8);
1382   p[2] = (uint8_t)(x >> 16);
1383   p[3] = (uint8_t)(x >> 24);
1384   p[4] = (uint8_t)(x >> 32);
1385 }
1386 
1387 static inline void  //
wuffs_base__poke_u48be__no_bounds_check(uint8_t * p,uint64_t x)1388 wuffs_base__poke_u48be__no_bounds_check(uint8_t* p, uint64_t x) {
1389   p[0] = (uint8_t)(x >> 40);
1390   p[1] = (uint8_t)(x >> 32);
1391   p[2] = (uint8_t)(x >> 24);
1392   p[3] = (uint8_t)(x >> 16);
1393   p[4] = (uint8_t)(x >> 8);
1394   p[5] = (uint8_t)(x >> 0);
1395 }
1396 
1397 static inline void  //
wuffs_base__poke_u48le__no_bounds_check(uint8_t * p,uint64_t x)1398 wuffs_base__poke_u48le__no_bounds_check(uint8_t* p, uint64_t x) {
1399   p[0] = (uint8_t)(x >> 0);
1400   p[1] = (uint8_t)(x >> 8);
1401   p[2] = (uint8_t)(x >> 16);
1402   p[3] = (uint8_t)(x >> 24);
1403   p[4] = (uint8_t)(x >> 32);
1404   p[5] = (uint8_t)(x >> 40);
1405 }
1406 
1407 static inline void  //
wuffs_base__poke_u56be__no_bounds_check(uint8_t * p,uint64_t x)1408 wuffs_base__poke_u56be__no_bounds_check(uint8_t* p, uint64_t x) {
1409   p[0] = (uint8_t)(x >> 48);
1410   p[1] = (uint8_t)(x >> 40);
1411   p[2] = (uint8_t)(x >> 32);
1412   p[3] = (uint8_t)(x >> 24);
1413   p[4] = (uint8_t)(x >> 16);
1414   p[5] = (uint8_t)(x >> 8);
1415   p[6] = (uint8_t)(x >> 0);
1416 }
1417 
1418 static inline void  //
wuffs_base__poke_u56le__no_bounds_check(uint8_t * p,uint64_t x)1419 wuffs_base__poke_u56le__no_bounds_check(uint8_t* p, uint64_t x) {
1420   p[0] = (uint8_t)(x >> 0);
1421   p[1] = (uint8_t)(x >> 8);
1422   p[2] = (uint8_t)(x >> 16);
1423   p[3] = (uint8_t)(x >> 24);
1424   p[4] = (uint8_t)(x >> 32);
1425   p[5] = (uint8_t)(x >> 40);
1426   p[6] = (uint8_t)(x >> 48);
1427 }
1428 
1429 static inline void  //
wuffs_base__poke_u64be__no_bounds_check(uint8_t * p,uint64_t x)1430 wuffs_base__poke_u64be__no_bounds_check(uint8_t* p, uint64_t x) {
1431   p[0] = (uint8_t)(x >> 56);
1432   p[1] = (uint8_t)(x >> 48);
1433   p[2] = (uint8_t)(x >> 40);
1434   p[3] = (uint8_t)(x >> 32);
1435   p[4] = (uint8_t)(x >> 24);
1436   p[5] = (uint8_t)(x >> 16);
1437   p[6] = (uint8_t)(x >> 8);
1438   p[7] = (uint8_t)(x >> 0);
1439 }
1440 
1441 static inline void  //
wuffs_base__poke_u64le__no_bounds_check(uint8_t * p,uint64_t x)1442 wuffs_base__poke_u64le__no_bounds_check(uint8_t* p, uint64_t x) {
1443 #if defined(WUFFS_BASE__USE_MEMCPY_LE_PEEK_POKE) || \
1444     (defined(__GNUC__) && !defined(__clang__) && defined(__x86_64__))
1445   // This seems to perform better on gcc 10 (but not clang 9). Clang also
1446   // defines "__GNUC__".
1447   memcpy(p, &x, 8);
1448 #else
1449   p[0] = (uint8_t)(x >> 0);
1450   p[1] = (uint8_t)(x >> 8);
1451   p[2] = (uint8_t)(x >> 16);
1452   p[3] = (uint8_t)(x >> 24);
1453   p[4] = (uint8_t)(x >> 32);
1454   p[5] = (uint8_t)(x >> 40);
1455   p[6] = (uint8_t)(x >> 48);
1456   p[7] = (uint8_t)(x >> 56);
1457 #endif
1458 }
1459 
1460 // ---------------- Slices and Tables
1461 
1462 // WUFFS_BASE__SLICE is a 1-dimensional buffer.
1463 //
1464 // len measures a number of elements, not necessarily a size in bytes.
1465 //
1466 // A value with all fields NULL or zero is a valid, empty slice.
1467 #define WUFFS_BASE__SLICE(T) \
1468   struct {                   \
1469     T* ptr;                  \
1470     size_t len;              \
1471   }
1472 
1473 // WUFFS_BASE__TABLE is a 2-dimensional buffer.
1474 //
1475 // width, height and stride measure a number of elements, not necessarily a
1476 // size in bytes.
1477 //
1478 // A value with all fields NULL or zero is a valid, empty table.
1479 #define WUFFS_BASE__TABLE(T) \
1480   struct {                   \
1481     T* ptr;                  \
1482     size_t width;            \
1483     size_t height;           \
1484     size_t stride;           \
1485   }
1486 
1487 typedef WUFFS_BASE__SLICE(uint8_t) wuffs_base__slice_u8;
1488 typedef WUFFS_BASE__SLICE(uint16_t) wuffs_base__slice_u16;
1489 typedef WUFFS_BASE__SLICE(uint32_t) wuffs_base__slice_u32;
1490 typedef WUFFS_BASE__SLICE(uint64_t) wuffs_base__slice_u64;
1491 
1492 typedef WUFFS_BASE__TABLE(uint8_t) wuffs_base__table_u8;
1493 typedef WUFFS_BASE__TABLE(uint16_t) wuffs_base__table_u16;
1494 typedef WUFFS_BASE__TABLE(uint32_t) wuffs_base__table_u32;
1495 typedef WUFFS_BASE__TABLE(uint64_t) wuffs_base__table_u64;
1496 
1497 static inline wuffs_base__slice_u8  //
wuffs_base__make_slice_u8(uint8_t * ptr,size_t len)1498 wuffs_base__make_slice_u8(uint8_t* ptr, size_t len) {
1499   wuffs_base__slice_u8 ret;
1500   ret.ptr = ptr;
1501   ret.len = len;
1502   return ret;
1503 }
1504 
1505 static inline wuffs_base__slice_u16  //
wuffs_base__make_slice_u16(uint16_t * ptr,size_t len)1506 wuffs_base__make_slice_u16(uint16_t* ptr, size_t len) {
1507   wuffs_base__slice_u16 ret;
1508   ret.ptr = ptr;
1509   ret.len = len;
1510   return ret;
1511 }
1512 
1513 static inline wuffs_base__slice_u32  //
wuffs_base__make_slice_u32(uint32_t * ptr,size_t len)1514 wuffs_base__make_slice_u32(uint32_t* ptr, size_t len) {
1515   wuffs_base__slice_u32 ret;
1516   ret.ptr = ptr;
1517   ret.len = len;
1518   return ret;
1519 }
1520 
1521 static inline wuffs_base__slice_u64  //
wuffs_base__make_slice_u64(uint64_t * ptr,size_t len)1522 wuffs_base__make_slice_u64(uint64_t* ptr, size_t len) {
1523   wuffs_base__slice_u64 ret;
1524   ret.ptr = ptr;
1525   ret.len = len;
1526   return ret;
1527 }
1528 
1529 static inline wuffs_base__slice_u8  //
wuffs_base__make_slice_u8_ij(uint8_t * ptr,size_t i,size_t j)1530 wuffs_base__make_slice_u8_ij(uint8_t* ptr, size_t i, size_t j) {
1531   wuffs_base__slice_u8 ret;
1532   ret.ptr = ptr + i;
1533   ret.len = (j >= i) ? (j - i) : 0;
1534   return ret;
1535 }
1536 
1537 static inline wuffs_base__slice_u16  //
wuffs_base__make_slice_u16_ij(uint16_t * ptr,size_t i,size_t j)1538 wuffs_base__make_slice_u16_ij(uint16_t* ptr, size_t i, size_t j) {
1539   wuffs_base__slice_u16 ret;
1540   ret.ptr = ptr + i;
1541   ret.len = (j >= i) ? (j - i) : 0;
1542   return ret;
1543 }
1544 
1545 static inline wuffs_base__slice_u32  //
wuffs_base__make_slice_u32_ij(uint32_t * ptr,size_t i,size_t j)1546 wuffs_base__make_slice_u32_ij(uint32_t* ptr, size_t i, size_t j) {
1547   wuffs_base__slice_u32 ret;
1548   ret.ptr = ptr + i;
1549   ret.len = (j >= i) ? (j - i) : 0;
1550   return ret;
1551 }
1552 
1553 static inline wuffs_base__slice_u64  //
wuffs_base__make_slice_u64_ij(uint64_t * ptr,size_t i,size_t j)1554 wuffs_base__make_slice_u64_ij(uint64_t* ptr, size_t i, size_t j) {
1555   wuffs_base__slice_u64 ret;
1556   ret.ptr = ptr + i;
1557   ret.len = (j >= i) ? (j - i) : 0;
1558   return ret;
1559 }
1560 
1561 static inline wuffs_base__slice_u8  //
wuffs_base__empty_slice_u8(void)1562 wuffs_base__empty_slice_u8(void) {
1563   wuffs_base__slice_u8 ret;
1564   ret.ptr = NULL;
1565   ret.len = 0;
1566   return ret;
1567 }
1568 
1569 static inline wuffs_base__slice_u16  //
wuffs_base__empty_slice_u16(void)1570 wuffs_base__empty_slice_u16(void) {
1571   wuffs_base__slice_u16 ret;
1572   ret.ptr = NULL;
1573   ret.len = 0;
1574   return ret;
1575 }
1576 
1577 static inline wuffs_base__slice_u32  //
wuffs_base__empty_slice_u32(void)1578 wuffs_base__empty_slice_u32(void) {
1579   wuffs_base__slice_u32 ret;
1580   ret.ptr = NULL;
1581   ret.len = 0;
1582   return ret;
1583 }
1584 
1585 static inline wuffs_base__slice_u64  //
wuffs_base__empty_slice_u64(void)1586 wuffs_base__empty_slice_u64(void) {
1587   wuffs_base__slice_u64 ret;
1588   ret.ptr = NULL;
1589   ret.len = 0;
1590   return ret;
1591 }
1592 
1593 static inline wuffs_base__table_u8  //
wuffs_base__make_table_u8(uint8_t * ptr,size_t width,size_t height,size_t stride)1594 wuffs_base__make_table_u8(uint8_t* ptr,
1595                           size_t width,
1596                           size_t height,
1597                           size_t stride) {
1598   wuffs_base__table_u8 ret;
1599   ret.ptr = ptr;
1600   ret.width = width;
1601   ret.height = height;
1602   ret.stride = stride;
1603   return ret;
1604 }
1605 
1606 static inline wuffs_base__table_u16  //
wuffs_base__make_table_u16(uint16_t * ptr,size_t width,size_t height,size_t stride)1607 wuffs_base__make_table_u16(uint16_t* ptr,
1608                            size_t width,
1609                            size_t height,
1610                            size_t stride) {
1611   wuffs_base__table_u16 ret;
1612   ret.ptr = ptr;
1613   ret.width = width;
1614   ret.height = height;
1615   ret.stride = stride;
1616   return ret;
1617 }
1618 
1619 static inline wuffs_base__table_u32  //
wuffs_base__make_table_u32(uint32_t * ptr,size_t width,size_t height,size_t stride)1620 wuffs_base__make_table_u32(uint32_t* ptr,
1621                            size_t width,
1622                            size_t height,
1623                            size_t stride) {
1624   wuffs_base__table_u32 ret;
1625   ret.ptr = ptr;
1626   ret.width = width;
1627   ret.height = height;
1628   ret.stride = stride;
1629   return ret;
1630 }
1631 
1632 static inline wuffs_base__table_u64  //
wuffs_base__make_table_u64(uint64_t * ptr,size_t width,size_t height,size_t stride)1633 wuffs_base__make_table_u64(uint64_t* ptr,
1634                            size_t width,
1635                            size_t height,
1636                            size_t stride) {
1637   wuffs_base__table_u64 ret;
1638   ret.ptr = ptr;
1639   ret.width = width;
1640   ret.height = height;
1641   ret.stride = stride;
1642   return ret;
1643 }
1644 
1645 static inline wuffs_base__table_u8  //
wuffs_base__empty_table_u8(void)1646 wuffs_base__empty_table_u8(void) {
1647   wuffs_base__table_u8 ret;
1648   ret.ptr = NULL;
1649   ret.width = 0;
1650   ret.height = 0;
1651   ret.stride = 0;
1652   return ret;
1653 }
1654 
1655 static inline wuffs_base__table_u16  //
wuffs_base__empty_table_u16(void)1656 wuffs_base__empty_table_u16(void) {
1657   wuffs_base__table_u16 ret;
1658   ret.ptr = NULL;
1659   ret.width = 0;
1660   ret.height = 0;
1661   ret.stride = 0;
1662   return ret;
1663 }
1664 
1665 static inline wuffs_base__table_u32  //
wuffs_base__empty_table_u32(void)1666 wuffs_base__empty_table_u32(void) {
1667   wuffs_base__table_u32 ret;
1668   ret.ptr = NULL;
1669   ret.width = 0;
1670   ret.height = 0;
1671   ret.stride = 0;
1672   return ret;
1673 }
1674 
1675 static inline wuffs_base__table_u64  //
wuffs_base__empty_table_u64(void)1676 wuffs_base__empty_table_u64(void) {
1677   wuffs_base__table_u64 ret;
1678   ret.ptr = NULL;
1679   ret.width = 0;
1680   ret.height = 0;
1681   ret.stride = 0;
1682   return ret;
1683 }
1684 
1685 static inline bool  //
wuffs_base__slice_u8__overlaps(wuffs_base__slice_u8 s,wuffs_base__slice_u8 t)1686 wuffs_base__slice_u8__overlaps(wuffs_base__slice_u8 s, wuffs_base__slice_u8 t) {
1687   return ((s.ptr <= t.ptr) && (t.ptr < (s.ptr + s.len))) ||
1688          ((t.ptr <= s.ptr) && (s.ptr < (t.ptr + t.len)));
1689 }
1690 
1691 // wuffs_base__slice_u8__subslice_i returns s[i:].
1692 //
1693 // It returns an empty slice if i is out of bounds.
1694 static inline wuffs_base__slice_u8  //
wuffs_base__slice_u8__subslice_i(wuffs_base__slice_u8 s,uint64_t i)1695 wuffs_base__slice_u8__subslice_i(wuffs_base__slice_u8 s, uint64_t i) {
1696   if ((i <= SIZE_MAX) && (i <= s.len)) {
1697     return wuffs_base__make_slice_u8(s.ptr + i, ((size_t)(s.len - i)));
1698   }
1699   return wuffs_base__make_slice_u8(NULL, 0);
1700 }
1701 
1702 // wuffs_base__slice_u8__subslice_j returns s[:j].
1703 //
1704 // It returns an empty slice if j is out of bounds.
1705 static inline wuffs_base__slice_u8  //
wuffs_base__slice_u8__subslice_j(wuffs_base__slice_u8 s,uint64_t j)1706 wuffs_base__slice_u8__subslice_j(wuffs_base__slice_u8 s, uint64_t j) {
1707   if ((j <= SIZE_MAX) && (j <= s.len)) {
1708     return wuffs_base__make_slice_u8(s.ptr, ((size_t)j));
1709   }
1710   return wuffs_base__make_slice_u8(NULL, 0);
1711 }
1712 
1713 // wuffs_base__slice_u8__subslice_ij returns s[i:j].
1714 //
1715 // It returns an empty slice if i or j is out of bounds.
1716 static inline wuffs_base__slice_u8  //
wuffs_base__slice_u8__subslice_ij(wuffs_base__slice_u8 s,uint64_t i,uint64_t j)1717 wuffs_base__slice_u8__subslice_ij(wuffs_base__slice_u8 s,
1718                                   uint64_t i,
1719                                   uint64_t j) {
1720   if ((i <= j) && (j <= SIZE_MAX) && (j <= s.len)) {
1721     return wuffs_base__make_slice_u8(s.ptr + i, ((size_t)(j - i)));
1722   }
1723   return wuffs_base__make_slice_u8(NULL, 0);
1724 }
1725 
1726 // wuffs_base__table_u8__subtable_ij returns t[ix:jx, iy:jy].
1727 //
1728 // It returns an empty table if i or j is out of bounds.
1729 static inline wuffs_base__table_u8  //
wuffs_base__table_u8__subtable_ij(wuffs_base__table_u8 t,uint64_t ix,uint64_t iy,uint64_t jx,uint64_t jy)1730 wuffs_base__table_u8__subtable_ij(wuffs_base__table_u8 t,
1731                                   uint64_t ix,
1732                                   uint64_t iy,
1733                                   uint64_t jx,
1734                                   uint64_t jy) {
1735   if ((ix <= jx) && (jx <= SIZE_MAX) && (jx <= t.width) &&  //
1736       (iy <= jy) && (jy <= SIZE_MAX) && (jy <= t.height)) {
1737     return wuffs_base__make_table_u8(t.ptr + ix + (iy * t.stride),  //
1738                                      ((size_t)(jx - ix)),           //
1739                                      ((size_t)(jy - iy)),           //
1740                                      t.stride);                     //
1741   }
1742   return wuffs_base__make_table_u8(NULL, 0, 0, 0);
1743 }
1744 
1745 // wuffs_base__table__flattened_length returns the number of elements covered
1746 // by the 1-dimensional span that backs a 2-dimensional table. This counts the
1747 // elements inside the table and, when width != stride, the elements outside
1748 // the table but between its rows.
1749 //
1750 // For example, consider a width 10, height 4, stride 10 table. Mark its first
1751 // and last (inclusive) elements with 'a' and 'z'. This function returns 40.
1752 //
1753 //    a123456789
1754 //    0123456789
1755 //    0123456789
1756 //    012345678z
1757 //
1758 // Now consider the sub-table of that from (2, 1) inclusive to (8, 4) exclusive.
1759 //
1760 //    a123456789
1761 //    01iiiiiioo
1762 //    ooiiiiiioo
1763 //    ooiiiiii8z
1764 //
1765 // This function (called with width 6, height 3, stride 10) returns 26: 18 'i'
1766 // inside elements plus 8 'o' outside elements. Note that 26 is less than a
1767 // naive (height * stride = 30) computation. Indeed, advancing 29 elements from
1768 // the first 'i' would venture past 'z', out of bounds of the original table.
1769 //
1770 // It does not check for overflow, but if the arguments come from a table that
1771 // exists in memory and each element occupies a positive number of bytes then
1772 // the result should be bounded by the amount of allocatable memory (which
1773 // shouldn't overflow SIZE_MAX).
1774 static inline size_t  //
wuffs_base__table__flattened_length(size_t width,size_t height,size_t stride)1775 wuffs_base__table__flattened_length(size_t width,
1776                                     size_t height,
1777                                     size_t stride) {
1778   if (height == 0) {
1779     return 0;
1780   }
1781   return ((height - 1) * stride) + width;
1782 }
1783 
1784 // ---------------- Magic Numbers
1785 
1786 // wuffs_base__magic_number_guess_fourcc guesses the file format of some data,
1787 // given its starting bytes (the prefix_data argument) and whether or not there
1788 // may be further bytes (the prefix_closed argument; true means that
1789 // prefix_data is the entire data).
1790 //
1791 // It returns a positive FourCC value on success.
1792 //
1793 // It returns zero if nothing matches its hard-coded list of 'magic numbers'.
1794 //
1795 // It returns a negative value if prefix_closed is false and a longer prefix is
1796 // required for a conclusive result. For example, a single 'B' byte (without
1797 // further data) is not enough to discriminate the BMP and BPG image file
1798 // formats. Similarly, a single '\xFF' byte might be the start of JPEG data or
1799 // it might be the start of some other binary data.
1800 //
1801 // It does not do a full validity check. Like any guess made from a short
1802 // prefix of the data, it may return false positives. Data that starts with 99
1803 // bytes of valid JPEG followed by corruption or truncation is an invalid JPEG
1804 // image overall, but this function will still return WUFFS_BASE__FOURCC__JPEG.
1805 //
1806 // Another source of false positives is that some 'magic numbers' are valid
1807 // ASCII data. A file starting with "GIF87a and GIF89a are the two versions of
1808 // GIF" will match GIF's 'magic number' even if it's plain text, not an image.
1809 //
1810 // For modular builds that divide the base module into sub-modules, using this
1811 // function requires the WUFFS_CONFIG__MODULE__BASE__MAGIC sub-module, not just
1812 // WUFFS_CONFIG__MODULE__BASE__CORE.
1813 WUFFS_BASE__MAYBE_STATIC int32_t  //
1814 wuffs_base__magic_number_guess_fourcc(wuffs_base__slice_u8 prefix_data,
1815                                       bool prefix_closed);
1816 
1817 // ---------------- Ranges and Rects
1818 
1819 // See https://github.com/google/wuffs/blob/main/doc/note/ranges-and-rects.md
1820 
1821 typedef struct wuffs_base__range_ii_u32__struct {
1822   uint32_t min_incl;
1823   uint32_t max_incl;
1824 
1825 #ifdef __cplusplus
1826   inline bool is_empty() const;
1827   inline bool equals(wuffs_base__range_ii_u32__struct s) const;
1828   inline wuffs_base__range_ii_u32__struct intersect(
1829       wuffs_base__range_ii_u32__struct s) const;
1830   inline wuffs_base__range_ii_u32__struct unite(
1831       wuffs_base__range_ii_u32__struct s) const;
1832   inline bool contains(uint32_t x) const;
1833   inline bool contains_range(wuffs_base__range_ii_u32__struct s) const;
1834 #endif  // __cplusplus
1835 
1836 } wuffs_base__range_ii_u32;
1837 
1838 static inline wuffs_base__range_ii_u32  //
wuffs_base__empty_range_ii_u32(void)1839 wuffs_base__empty_range_ii_u32(void) {
1840   wuffs_base__range_ii_u32 ret;
1841   ret.min_incl = 0;
1842   ret.max_incl = 0;
1843   return ret;
1844 }
1845 
1846 static inline wuffs_base__range_ii_u32  //
wuffs_base__make_range_ii_u32(uint32_t min_incl,uint32_t max_incl)1847 wuffs_base__make_range_ii_u32(uint32_t min_incl, uint32_t max_incl) {
1848   wuffs_base__range_ii_u32 ret;
1849   ret.min_incl = min_incl;
1850   ret.max_incl = max_incl;
1851   return ret;
1852 }
1853 
1854 static inline bool  //
wuffs_base__range_ii_u32__is_empty(const wuffs_base__range_ii_u32 * r)1855 wuffs_base__range_ii_u32__is_empty(const wuffs_base__range_ii_u32* r) {
1856   return r->min_incl > r->max_incl;
1857 }
1858 
1859 static inline bool  //
wuffs_base__range_ii_u32__equals(const wuffs_base__range_ii_u32 * r,wuffs_base__range_ii_u32 s)1860 wuffs_base__range_ii_u32__equals(const wuffs_base__range_ii_u32* r,
1861                                  wuffs_base__range_ii_u32 s) {
1862   return (r->min_incl == s.min_incl && r->max_incl == s.max_incl) ||
1863          (wuffs_base__range_ii_u32__is_empty(r) &&
1864           wuffs_base__range_ii_u32__is_empty(&s));
1865 }
1866 
1867 static inline wuffs_base__range_ii_u32  //
wuffs_base__range_ii_u32__intersect(const wuffs_base__range_ii_u32 * r,wuffs_base__range_ii_u32 s)1868 wuffs_base__range_ii_u32__intersect(const wuffs_base__range_ii_u32* r,
1869                                     wuffs_base__range_ii_u32 s) {
1870   wuffs_base__range_ii_u32 t;
1871   t.min_incl = wuffs_base__u32__max(r->min_incl, s.min_incl);
1872   t.max_incl = wuffs_base__u32__min(r->max_incl, s.max_incl);
1873   return t;
1874 }
1875 
1876 static inline wuffs_base__range_ii_u32  //
wuffs_base__range_ii_u32__unite(const wuffs_base__range_ii_u32 * r,wuffs_base__range_ii_u32 s)1877 wuffs_base__range_ii_u32__unite(const wuffs_base__range_ii_u32* r,
1878                                 wuffs_base__range_ii_u32 s) {
1879   if (wuffs_base__range_ii_u32__is_empty(r)) {
1880     return s;
1881   }
1882   if (wuffs_base__range_ii_u32__is_empty(&s)) {
1883     return *r;
1884   }
1885   wuffs_base__range_ii_u32 t;
1886   t.min_incl = wuffs_base__u32__min(r->min_incl, s.min_incl);
1887   t.max_incl = wuffs_base__u32__max(r->max_incl, s.max_incl);
1888   return t;
1889 }
1890 
1891 static inline bool  //
wuffs_base__range_ii_u32__contains(const wuffs_base__range_ii_u32 * r,uint32_t x)1892 wuffs_base__range_ii_u32__contains(const wuffs_base__range_ii_u32* r,
1893                                    uint32_t x) {
1894   return (r->min_incl <= x) && (x <= r->max_incl);
1895 }
1896 
1897 static inline bool  //
wuffs_base__range_ii_u32__contains_range(const wuffs_base__range_ii_u32 * r,wuffs_base__range_ii_u32 s)1898 wuffs_base__range_ii_u32__contains_range(const wuffs_base__range_ii_u32* r,
1899                                          wuffs_base__range_ii_u32 s) {
1900   return wuffs_base__range_ii_u32__equals(
1901       &s, wuffs_base__range_ii_u32__intersect(r, s));
1902 }
1903 
1904 #ifdef __cplusplus
1905 
1906 inline bool  //
is_empty()1907 wuffs_base__range_ii_u32::is_empty() const {
1908   return wuffs_base__range_ii_u32__is_empty(this);
1909 }
1910 
1911 inline bool  //
equals(wuffs_base__range_ii_u32 s)1912 wuffs_base__range_ii_u32::equals(wuffs_base__range_ii_u32 s) const {
1913   return wuffs_base__range_ii_u32__equals(this, s);
1914 }
1915 
1916 inline wuffs_base__range_ii_u32  //
intersect(wuffs_base__range_ii_u32 s)1917 wuffs_base__range_ii_u32::intersect(wuffs_base__range_ii_u32 s) const {
1918   return wuffs_base__range_ii_u32__intersect(this, s);
1919 }
1920 
1921 inline wuffs_base__range_ii_u32  //
unite(wuffs_base__range_ii_u32 s)1922 wuffs_base__range_ii_u32::unite(wuffs_base__range_ii_u32 s) const {
1923   return wuffs_base__range_ii_u32__unite(this, s);
1924 }
1925 
1926 inline bool  //
contains(uint32_t x)1927 wuffs_base__range_ii_u32::contains(uint32_t x) const {
1928   return wuffs_base__range_ii_u32__contains(this, x);
1929 }
1930 
1931 inline bool  //
contains_range(wuffs_base__range_ii_u32 s)1932 wuffs_base__range_ii_u32::contains_range(wuffs_base__range_ii_u32 s) const {
1933   return wuffs_base__range_ii_u32__contains_range(this, s);
1934 }
1935 
1936 #endif  // __cplusplus
1937 
1938 // --------
1939 
1940 typedef struct wuffs_base__range_ie_u32__struct {
1941   uint32_t min_incl;
1942   uint32_t max_excl;
1943 
1944 #ifdef __cplusplus
1945   inline bool is_empty() const;
1946   inline bool equals(wuffs_base__range_ie_u32__struct s) const;
1947   inline wuffs_base__range_ie_u32__struct intersect(
1948       wuffs_base__range_ie_u32__struct s) const;
1949   inline wuffs_base__range_ie_u32__struct unite(
1950       wuffs_base__range_ie_u32__struct s) const;
1951   inline bool contains(uint32_t x) const;
1952   inline bool contains_range(wuffs_base__range_ie_u32__struct s) const;
1953   inline uint32_t length() const;
1954 #endif  // __cplusplus
1955 
1956 } wuffs_base__range_ie_u32;
1957 
1958 static inline wuffs_base__range_ie_u32  //
wuffs_base__empty_range_ie_u32(void)1959 wuffs_base__empty_range_ie_u32(void) {
1960   wuffs_base__range_ie_u32 ret;
1961   ret.min_incl = 0;
1962   ret.max_excl = 0;
1963   return ret;
1964 }
1965 
1966 static inline wuffs_base__range_ie_u32  //
wuffs_base__make_range_ie_u32(uint32_t min_incl,uint32_t max_excl)1967 wuffs_base__make_range_ie_u32(uint32_t min_incl, uint32_t max_excl) {
1968   wuffs_base__range_ie_u32 ret;
1969   ret.min_incl = min_incl;
1970   ret.max_excl = max_excl;
1971   return ret;
1972 }
1973 
1974 static inline bool  //
wuffs_base__range_ie_u32__is_empty(const wuffs_base__range_ie_u32 * r)1975 wuffs_base__range_ie_u32__is_empty(const wuffs_base__range_ie_u32* r) {
1976   return r->min_incl >= r->max_excl;
1977 }
1978 
1979 static inline bool  //
wuffs_base__range_ie_u32__equals(const wuffs_base__range_ie_u32 * r,wuffs_base__range_ie_u32 s)1980 wuffs_base__range_ie_u32__equals(const wuffs_base__range_ie_u32* r,
1981                                  wuffs_base__range_ie_u32 s) {
1982   return (r->min_incl == s.min_incl && r->max_excl == s.max_excl) ||
1983          (wuffs_base__range_ie_u32__is_empty(r) &&
1984           wuffs_base__range_ie_u32__is_empty(&s));
1985 }
1986 
1987 static inline wuffs_base__range_ie_u32  //
wuffs_base__range_ie_u32__intersect(const wuffs_base__range_ie_u32 * r,wuffs_base__range_ie_u32 s)1988 wuffs_base__range_ie_u32__intersect(const wuffs_base__range_ie_u32* r,
1989                                     wuffs_base__range_ie_u32 s) {
1990   wuffs_base__range_ie_u32 t;
1991   t.min_incl = wuffs_base__u32__max(r->min_incl, s.min_incl);
1992   t.max_excl = wuffs_base__u32__min(r->max_excl, s.max_excl);
1993   return t;
1994 }
1995 
1996 static inline wuffs_base__range_ie_u32  //
wuffs_base__range_ie_u32__unite(const wuffs_base__range_ie_u32 * r,wuffs_base__range_ie_u32 s)1997 wuffs_base__range_ie_u32__unite(const wuffs_base__range_ie_u32* r,
1998                                 wuffs_base__range_ie_u32 s) {
1999   if (wuffs_base__range_ie_u32__is_empty(r)) {
2000     return s;
2001   }
2002   if (wuffs_base__range_ie_u32__is_empty(&s)) {
2003     return *r;
2004   }
2005   wuffs_base__range_ie_u32 t;
2006   t.min_incl = wuffs_base__u32__min(r->min_incl, s.min_incl);
2007   t.max_excl = wuffs_base__u32__max(r->max_excl, s.max_excl);
2008   return t;
2009 }
2010 
2011 static inline bool  //
wuffs_base__range_ie_u32__contains(const wuffs_base__range_ie_u32 * r,uint32_t x)2012 wuffs_base__range_ie_u32__contains(const wuffs_base__range_ie_u32* r,
2013                                    uint32_t x) {
2014   return (r->min_incl <= x) && (x < r->max_excl);
2015 }
2016 
2017 static inline bool  //
wuffs_base__range_ie_u32__contains_range(const wuffs_base__range_ie_u32 * r,wuffs_base__range_ie_u32 s)2018 wuffs_base__range_ie_u32__contains_range(const wuffs_base__range_ie_u32* r,
2019                                          wuffs_base__range_ie_u32 s) {
2020   return wuffs_base__range_ie_u32__equals(
2021       &s, wuffs_base__range_ie_u32__intersect(r, s));
2022 }
2023 
2024 static inline uint32_t  //
wuffs_base__range_ie_u32__length(const wuffs_base__range_ie_u32 * r)2025 wuffs_base__range_ie_u32__length(const wuffs_base__range_ie_u32* r) {
2026   return wuffs_base__u32__sat_sub(r->max_excl, r->min_incl);
2027 }
2028 
2029 #ifdef __cplusplus
2030 
2031 inline bool  //
is_empty()2032 wuffs_base__range_ie_u32::is_empty() const {
2033   return wuffs_base__range_ie_u32__is_empty(this);
2034 }
2035 
2036 inline bool  //
equals(wuffs_base__range_ie_u32 s)2037 wuffs_base__range_ie_u32::equals(wuffs_base__range_ie_u32 s) const {
2038   return wuffs_base__range_ie_u32__equals(this, s);
2039 }
2040 
2041 inline wuffs_base__range_ie_u32  //
intersect(wuffs_base__range_ie_u32 s)2042 wuffs_base__range_ie_u32::intersect(wuffs_base__range_ie_u32 s) const {
2043   return wuffs_base__range_ie_u32__intersect(this, s);
2044 }
2045 
2046 inline wuffs_base__range_ie_u32  //
unite(wuffs_base__range_ie_u32 s)2047 wuffs_base__range_ie_u32::unite(wuffs_base__range_ie_u32 s) const {
2048   return wuffs_base__range_ie_u32__unite(this, s);
2049 }
2050 
2051 inline bool  //
contains(uint32_t x)2052 wuffs_base__range_ie_u32::contains(uint32_t x) const {
2053   return wuffs_base__range_ie_u32__contains(this, x);
2054 }
2055 
2056 inline bool  //
contains_range(wuffs_base__range_ie_u32 s)2057 wuffs_base__range_ie_u32::contains_range(wuffs_base__range_ie_u32 s) const {
2058   return wuffs_base__range_ie_u32__contains_range(this, s);
2059 }
2060 
2061 inline uint32_t  //
length()2062 wuffs_base__range_ie_u32::length() const {
2063   return wuffs_base__range_ie_u32__length(this);
2064 }
2065 
2066 #endif  // __cplusplus
2067 
2068 // --------
2069 
2070 typedef struct wuffs_base__range_ii_u64__struct {
2071   uint64_t min_incl;
2072   uint64_t max_incl;
2073 
2074 #ifdef __cplusplus
2075   inline bool is_empty() const;
2076   inline bool equals(wuffs_base__range_ii_u64__struct s) const;
2077   inline wuffs_base__range_ii_u64__struct intersect(
2078       wuffs_base__range_ii_u64__struct s) const;
2079   inline wuffs_base__range_ii_u64__struct unite(
2080       wuffs_base__range_ii_u64__struct s) const;
2081   inline bool contains(uint64_t x) const;
2082   inline bool contains_range(wuffs_base__range_ii_u64__struct s) const;
2083 #endif  // __cplusplus
2084 
2085 } wuffs_base__range_ii_u64;
2086 
2087 static inline wuffs_base__range_ii_u64  //
wuffs_base__empty_range_ii_u64(void)2088 wuffs_base__empty_range_ii_u64(void) {
2089   wuffs_base__range_ii_u64 ret;
2090   ret.min_incl = 0;
2091   ret.max_incl = 0;
2092   return ret;
2093 }
2094 
2095 static inline wuffs_base__range_ii_u64  //
wuffs_base__make_range_ii_u64(uint64_t min_incl,uint64_t max_incl)2096 wuffs_base__make_range_ii_u64(uint64_t min_incl, uint64_t max_incl) {
2097   wuffs_base__range_ii_u64 ret;
2098   ret.min_incl = min_incl;
2099   ret.max_incl = max_incl;
2100   return ret;
2101 }
2102 
2103 static inline bool  //
wuffs_base__range_ii_u64__is_empty(const wuffs_base__range_ii_u64 * r)2104 wuffs_base__range_ii_u64__is_empty(const wuffs_base__range_ii_u64* r) {
2105   return r->min_incl > r->max_incl;
2106 }
2107 
2108 static inline bool  //
wuffs_base__range_ii_u64__equals(const wuffs_base__range_ii_u64 * r,wuffs_base__range_ii_u64 s)2109 wuffs_base__range_ii_u64__equals(const wuffs_base__range_ii_u64* r,
2110                                  wuffs_base__range_ii_u64 s) {
2111   return (r->min_incl == s.min_incl && r->max_incl == s.max_incl) ||
2112          (wuffs_base__range_ii_u64__is_empty(r) &&
2113           wuffs_base__range_ii_u64__is_empty(&s));
2114 }
2115 
2116 static inline wuffs_base__range_ii_u64  //
wuffs_base__range_ii_u64__intersect(const wuffs_base__range_ii_u64 * r,wuffs_base__range_ii_u64 s)2117 wuffs_base__range_ii_u64__intersect(const wuffs_base__range_ii_u64* r,
2118                                     wuffs_base__range_ii_u64 s) {
2119   wuffs_base__range_ii_u64 t;
2120   t.min_incl = wuffs_base__u64__max(r->min_incl, s.min_incl);
2121   t.max_incl = wuffs_base__u64__min(r->max_incl, s.max_incl);
2122   return t;
2123 }
2124 
2125 static inline wuffs_base__range_ii_u64  //
wuffs_base__range_ii_u64__unite(const wuffs_base__range_ii_u64 * r,wuffs_base__range_ii_u64 s)2126 wuffs_base__range_ii_u64__unite(const wuffs_base__range_ii_u64* r,
2127                                 wuffs_base__range_ii_u64 s) {
2128   if (wuffs_base__range_ii_u64__is_empty(r)) {
2129     return s;
2130   }
2131   if (wuffs_base__range_ii_u64__is_empty(&s)) {
2132     return *r;
2133   }
2134   wuffs_base__range_ii_u64 t;
2135   t.min_incl = wuffs_base__u64__min(r->min_incl, s.min_incl);
2136   t.max_incl = wuffs_base__u64__max(r->max_incl, s.max_incl);
2137   return t;
2138 }
2139 
2140 static inline bool  //
wuffs_base__range_ii_u64__contains(const wuffs_base__range_ii_u64 * r,uint64_t x)2141 wuffs_base__range_ii_u64__contains(const wuffs_base__range_ii_u64* r,
2142                                    uint64_t x) {
2143   return (r->min_incl <= x) && (x <= r->max_incl);
2144 }
2145 
2146 static inline bool  //
wuffs_base__range_ii_u64__contains_range(const wuffs_base__range_ii_u64 * r,wuffs_base__range_ii_u64 s)2147 wuffs_base__range_ii_u64__contains_range(const wuffs_base__range_ii_u64* r,
2148                                          wuffs_base__range_ii_u64 s) {
2149   return wuffs_base__range_ii_u64__equals(
2150       &s, wuffs_base__range_ii_u64__intersect(r, s));
2151 }
2152 
2153 #ifdef __cplusplus
2154 
2155 inline bool  //
is_empty()2156 wuffs_base__range_ii_u64::is_empty() const {
2157   return wuffs_base__range_ii_u64__is_empty(this);
2158 }
2159 
2160 inline bool  //
equals(wuffs_base__range_ii_u64 s)2161 wuffs_base__range_ii_u64::equals(wuffs_base__range_ii_u64 s) const {
2162   return wuffs_base__range_ii_u64__equals(this, s);
2163 }
2164 
2165 inline wuffs_base__range_ii_u64  //
intersect(wuffs_base__range_ii_u64 s)2166 wuffs_base__range_ii_u64::intersect(wuffs_base__range_ii_u64 s) const {
2167   return wuffs_base__range_ii_u64__intersect(this, s);
2168 }
2169 
2170 inline wuffs_base__range_ii_u64  //
unite(wuffs_base__range_ii_u64 s)2171 wuffs_base__range_ii_u64::unite(wuffs_base__range_ii_u64 s) const {
2172   return wuffs_base__range_ii_u64__unite(this, s);
2173 }
2174 
2175 inline bool  //
contains(uint64_t x)2176 wuffs_base__range_ii_u64::contains(uint64_t x) const {
2177   return wuffs_base__range_ii_u64__contains(this, x);
2178 }
2179 
2180 inline bool  //
contains_range(wuffs_base__range_ii_u64 s)2181 wuffs_base__range_ii_u64::contains_range(wuffs_base__range_ii_u64 s) const {
2182   return wuffs_base__range_ii_u64__contains_range(this, s);
2183 }
2184 
2185 #endif  // __cplusplus
2186 
2187 // --------
2188 
2189 typedef struct wuffs_base__range_ie_u64__struct {
2190   uint64_t min_incl;
2191   uint64_t max_excl;
2192 
2193 #ifdef __cplusplus
2194   inline bool is_empty() const;
2195   inline bool equals(wuffs_base__range_ie_u64__struct s) const;
2196   inline wuffs_base__range_ie_u64__struct intersect(
2197       wuffs_base__range_ie_u64__struct s) const;
2198   inline wuffs_base__range_ie_u64__struct unite(
2199       wuffs_base__range_ie_u64__struct s) const;
2200   inline bool contains(uint64_t x) const;
2201   inline bool contains_range(wuffs_base__range_ie_u64__struct s) const;
2202   inline uint64_t length() const;
2203 #endif  // __cplusplus
2204 
2205 } wuffs_base__range_ie_u64;
2206 
2207 static inline wuffs_base__range_ie_u64  //
wuffs_base__empty_range_ie_u64(void)2208 wuffs_base__empty_range_ie_u64(void) {
2209   wuffs_base__range_ie_u64 ret;
2210   ret.min_incl = 0;
2211   ret.max_excl = 0;
2212   return ret;
2213 }
2214 
2215 static inline wuffs_base__range_ie_u64  //
wuffs_base__make_range_ie_u64(uint64_t min_incl,uint64_t max_excl)2216 wuffs_base__make_range_ie_u64(uint64_t min_incl, uint64_t max_excl) {
2217   wuffs_base__range_ie_u64 ret;
2218   ret.min_incl = min_incl;
2219   ret.max_excl = max_excl;
2220   return ret;
2221 }
2222 
2223 static inline bool  //
wuffs_base__range_ie_u64__is_empty(const wuffs_base__range_ie_u64 * r)2224 wuffs_base__range_ie_u64__is_empty(const wuffs_base__range_ie_u64* r) {
2225   return r->min_incl >= r->max_excl;
2226 }
2227 
2228 static inline bool  //
wuffs_base__range_ie_u64__equals(const wuffs_base__range_ie_u64 * r,wuffs_base__range_ie_u64 s)2229 wuffs_base__range_ie_u64__equals(const wuffs_base__range_ie_u64* r,
2230                                  wuffs_base__range_ie_u64 s) {
2231   return (r->min_incl == s.min_incl && r->max_excl == s.max_excl) ||
2232          (wuffs_base__range_ie_u64__is_empty(r) &&
2233           wuffs_base__range_ie_u64__is_empty(&s));
2234 }
2235 
2236 static inline wuffs_base__range_ie_u64  //
wuffs_base__range_ie_u64__intersect(const wuffs_base__range_ie_u64 * r,wuffs_base__range_ie_u64 s)2237 wuffs_base__range_ie_u64__intersect(const wuffs_base__range_ie_u64* r,
2238                                     wuffs_base__range_ie_u64 s) {
2239   wuffs_base__range_ie_u64 t;
2240   t.min_incl = wuffs_base__u64__max(r->min_incl, s.min_incl);
2241   t.max_excl = wuffs_base__u64__min(r->max_excl, s.max_excl);
2242   return t;
2243 }
2244 
2245 static inline wuffs_base__range_ie_u64  //
wuffs_base__range_ie_u64__unite(const wuffs_base__range_ie_u64 * r,wuffs_base__range_ie_u64 s)2246 wuffs_base__range_ie_u64__unite(const wuffs_base__range_ie_u64* r,
2247                                 wuffs_base__range_ie_u64 s) {
2248   if (wuffs_base__range_ie_u64__is_empty(r)) {
2249     return s;
2250   }
2251   if (wuffs_base__range_ie_u64__is_empty(&s)) {
2252     return *r;
2253   }
2254   wuffs_base__range_ie_u64 t;
2255   t.min_incl = wuffs_base__u64__min(r->min_incl, s.min_incl);
2256   t.max_excl = wuffs_base__u64__max(r->max_excl, s.max_excl);
2257   return t;
2258 }
2259 
2260 static inline bool  //
wuffs_base__range_ie_u64__contains(const wuffs_base__range_ie_u64 * r,uint64_t x)2261 wuffs_base__range_ie_u64__contains(const wuffs_base__range_ie_u64* r,
2262                                    uint64_t x) {
2263   return (r->min_incl <= x) && (x < r->max_excl);
2264 }
2265 
2266 static inline bool  //
wuffs_base__range_ie_u64__contains_range(const wuffs_base__range_ie_u64 * r,wuffs_base__range_ie_u64 s)2267 wuffs_base__range_ie_u64__contains_range(const wuffs_base__range_ie_u64* r,
2268                                          wuffs_base__range_ie_u64 s) {
2269   return wuffs_base__range_ie_u64__equals(
2270       &s, wuffs_base__range_ie_u64__intersect(r, s));
2271 }
2272 
2273 static inline uint64_t  //
wuffs_base__range_ie_u64__length(const wuffs_base__range_ie_u64 * r)2274 wuffs_base__range_ie_u64__length(const wuffs_base__range_ie_u64* r) {
2275   return wuffs_base__u64__sat_sub(r->max_excl, r->min_incl);
2276 }
2277 
2278 #ifdef __cplusplus
2279 
2280 inline bool  //
is_empty()2281 wuffs_base__range_ie_u64::is_empty() const {
2282   return wuffs_base__range_ie_u64__is_empty(this);
2283 }
2284 
2285 inline bool  //
equals(wuffs_base__range_ie_u64 s)2286 wuffs_base__range_ie_u64::equals(wuffs_base__range_ie_u64 s) const {
2287   return wuffs_base__range_ie_u64__equals(this, s);
2288 }
2289 
2290 inline wuffs_base__range_ie_u64  //
intersect(wuffs_base__range_ie_u64 s)2291 wuffs_base__range_ie_u64::intersect(wuffs_base__range_ie_u64 s) const {
2292   return wuffs_base__range_ie_u64__intersect(this, s);
2293 }
2294 
2295 inline wuffs_base__range_ie_u64  //
unite(wuffs_base__range_ie_u64 s)2296 wuffs_base__range_ie_u64::unite(wuffs_base__range_ie_u64 s) const {
2297   return wuffs_base__range_ie_u64__unite(this, s);
2298 }
2299 
2300 inline bool  //
contains(uint64_t x)2301 wuffs_base__range_ie_u64::contains(uint64_t x) const {
2302   return wuffs_base__range_ie_u64__contains(this, x);
2303 }
2304 
2305 inline bool  //
contains_range(wuffs_base__range_ie_u64 s)2306 wuffs_base__range_ie_u64::contains_range(wuffs_base__range_ie_u64 s) const {
2307   return wuffs_base__range_ie_u64__contains_range(this, s);
2308 }
2309 
2310 inline uint64_t  //
length()2311 wuffs_base__range_ie_u64::length() const {
2312   return wuffs_base__range_ie_u64__length(this);
2313 }
2314 
2315 #endif  // __cplusplus
2316 
2317 // --------
2318 
2319 typedef struct wuffs_base__rect_ii_u32__struct {
2320   uint32_t min_incl_x;
2321   uint32_t min_incl_y;
2322   uint32_t max_incl_x;
2323   uint32_t max_incl_y;
2324 
2325 #ifdef __cplusplus
2326   inline bool is_empty() const;
2327   inline bool equals(wuffs_base__rect_ii_u32__struct s) const;
2328   inline wuffs_base__rect_ii_u32__struct intersect(
2329       wuffs_base__rect_ii_u32__struct s) const;
2330   inline wuffs_base__rect_ii_u32__struct unite(
2331       wuffs_base__rect_ii_u32__struct s) const;
2332   inline bool contains(uint32_t x, uint32_t y) const;
2333   inline bool contains_rect(wuffs_base__rect_ii_u32__struct s) const;
2334 #endif  // __cplusplus
2335 
2336 } wuffs_base__rect_ii_u32;
2337 
2338 static inline wuffs_base__rect_ii_u32  //
wuffs_base__empty_rect_ii_u32(void)2339 wuffs_base__empty_rect_ii_u32(void) {
2340   wuffs_base__rect_ii_u32 ret;
2341   ret.min_incl_x = 0;
2342   ret.min_incl_y = 0;
2343   ret.max_incl_x = 0;
2344   ret.max_incl_y = 0;
2345   return ret;
2346 }
2347 
2348 static inline wuffs_base__rect_ii_u32  //
wuffs_base__make_rect_ii_u32(uint32_t min_incl_x,uint32_t min_incl_y,uint32_t max_incl_x,uint32_t max_incl_y)2349 wuffs_base__make_rect_ii_u32(uint32_t min_incl_x,
2350                              uint32_t min_incl_y,
2351                              uint32_t max_incl_x,
2352                              uint32_t max_incl_y) {
2353   wuffs_base__rect_ii_u32 ret;
2354   ret.min_incl_x = min_incl_x;
2355   ret.min_incl_y = min_incl_y;
2356   ret.max_incl_x = max_incl_x;
2357   ret.max_incl_y = max_incl_y;
2358   return ret;
2359 }
2360 
2361 static inline bool  //
wuffs_base__rect_ii_u32__is_empty(const wuffs_base__rect_ii_u32 * r)2362 wuffs_base__rect_ii_u32__is_empty(const wuffs_base__rect_ii_u32* r) {
2363   return (r->min_incl_x > r->max_incl_x) || (r->min_incl_y > r->max_incl_y);
2364 }
2365 
2366 static inline bool  //
wuffs_base__rect_ii_u32__equals(const wuffs_base__rect_ii_u32 * r,wuffs_base__rect_ii_u32 s)2367 wuffs_base__rect_ii_u32__equals(const wuffs_base__rect_ii_u32* r,
2368                                 wuffs_base__rect_ii_u32 s) {
2369   return (r->min_incl_x == s.min_incl_x && r->min_incl_y == s.min_incl_y &&
2370           r->max_incl_x == s.max_incl_x && r->max_incl_y == s.max_incl_y) ||
2371          (wuffs_base__rect_ii_u32__is_empty(r) &&
2372           wuffs_base__rect_ii_u32__is_empty(&s));
2373 }
2374 
2375 static inline wuffs_base__rect_ii_u32  //
wuffs_base__rect_ii_u32__intersect(const wuffs_base__rect_ii_u32 * r,wuffs_base__rect_ii_u32 s)2376 wuffs_base__rect_ii_u32__intersect(const wuffs_base__rect_ii_u32* r,
2377                                    wuffs_base__rect_ii_u32 s) {
2378   wuffs_base__rect_ii_u32 t;
2379   t.min_incl_x = wuffs_base__u32__max(r->min_incl_x, s.min_incl_x);
2380   t.min_incl_y = wuffs_base__u32__max(r->min_incl_y, s.min_incl_y);
2381   t.max_incl_x = wuffs_base__u32__min(r->max_incl_x, s.max_incl_x);
2382   t.max_incl_y = wuffs_base__u32__min(r->max_incl_y, s.max_incl_y);
2383   return t;
2384 }
2385 
2386 static inline wuffs_base__rect_ii_u32  //
wuffs_base__rect_ii_u32__unite(const wuffs_base__rect_ii_u32 * r,wuffs_base__rect_ii_u32 s)2387 wuffs_base__rect_ii_u32__unite(const wuffs_base__rect_ii_u32* r,
2388                                wuffs_base__rect_ii_u32 s) {
2389   if (wuffs_base__rect_ii_u32__is_empty(r)) {
2390     return s;
2391   }
2392   if (wuffs_base__rect_ii_u32__is_empty(&s)) {
2393     return *r;
2394   }
2395   wuffs_base__rect_ii_u32 t;
2396   t.min_incl_x = wuffs_base__u32__min(r->min_incl_x, s.min_incl_x);
2397   t.min_incl_y = wuffs_base__u32__min(r->min_incl_y, s.min_incl_y);
2398   t.max_incl_x = wuffs_base__u32__max(r->max_incl_x, s.max_incl_x);
2399   t.max_incl_y = wuffs_base__u32__max(r->max_incl_y, s.max_incl_y);
2400   return t;
2401 }
2402 
2403 static inline bool  //
wuffs_base__rect_ii_u32__contains(const wuffs_base__rect_ii_u32 * r,uint32_t x,uint32_t y)2404 wuffs_base__rect_ii_u32__contains(const wuffs_base__rect_ii_u32* r,
2405                                   uint32_t x,
2406                                   uint32_t y) {
2407   return (r->min_incl_x <= x) && (x <= r->max_incl_x) && (r->min_incl_y <= y) &&
2408          (y <= r->max_incl_y);
2409 }
2410 
2411 static inline bool  //
wuffs_base__rect_ii_u32__contains_rect(const wuffs_base__rect_ii_u32 * r,wuffs_base__rect_ii_u32 s)2412 wuffs_base__rect_ii_u32__contains_rect(const wuffs_base__rect_ii_u32* r,
2413                                        wuffs_base__rect_ii_u32 s) {
2414   return wuffs_base__rect_ii_u32__equals(
2415       &s, wuffs_base__rect_ii_u32__intersect(r, s));
2416 }
2417 
2418 #ifdef __cplusplus
2419 
2420 inline bool  //
is_empty()2421 wuffs_base__rect_ii_u32::is_empty() const {
2422   return wuffs_base__rect_ii_u32__is_empty(this);
2423 }
2424 
2425 inline bool  //
equals(wuffs_base__rect_ii_u32 s)2426 wuffs_base__rect_ii_u32::equals(wuffs_base__rect_ii_u32 s) const {
2427   return wuffs_base__rect_ii_u32__equals(this, s);
2428 }
2429 
2430 inline wuffs_base__rect_ii_u32  //
intersect(wuffs_base__rect_ii_u32 s)2431 wuffs_base__rect_ii_u32::intersect(wuffs_base__rect_ii_u32 s) const {
2432   return wuffs_base__rect_ii_u32__intersect(this, s);
2433 }
2434 
2435 inline wuffs_base__rect_ii_u32  //
unite(wuffs_base__rect_ii_u32 s)2436 wuffs_base__rect_ii_u32::unite(wuffs_base__rect_ii_u32 s) const {
2437   return wuffs_base__rect_ii_u32__unite(this, s);
2438 }
2439 
2440 inline bool  //
contains(uint32_t x,uint32_t y)2441 wuffs_base__rect_ii_u32::contains(uint32_t x, uint32_t y) const {
2442   return wuffs_base__rect_ii_u32__contains(this, x, y);
2443 }
2444 
2445 inline bool  //
contains_rect(wuffs_base__rect_ii_u32 s)2446 wuffs_base__rect_ii_u32::contains_rect(wuffs_base__rect_ii_u32 s) const {
2447   return wuffs_base__rect_ii_u32__contains_rect(this, s);
2448 }
2449 
2450 #endif  // __cplusplus
2451 
2452 // --------
2453 
2454 typedef struct wuffs_base__rect_ie_u32__struct {
2455   uint32_t min_incl_x;
2456   uint32_t min_incl_y;
2457   uint32_t max_excl_x;
2458   uint32_t max_excl_y;
2459 
2460 #ifdef __cplusplus
2461   inline bool is_empty() const;
2462   inline bool equals(wuffs_base__rect_ie_u32__struct s) const;
2463   inline wuffs_base__rect_ie_u32__struct intersect(
2464       wuffs_base__rect_ie_u32__struct s) const;
2465   inline wuffs_base__rect_ie_u32__struct unite(
2466       wuffs_base__rect_ie_u32__struct s) const;
2467   inline bool contains(uint32_t x, uint32_t y) const;
2468   inline bool contains_rect(wuffs_base__rect_ie_u32__struct s) const;
2469   inline uint32_t width() const;
2470   inline uint32_t height() const;
2471 #endif  // __cplusplus
2472 
2473 } wuffs_base__rect_ie_u32;
2474 
2475 static inline wuffs_base__rect_ie_u32  //
wuffs_base__empty_rect_ie_u32(void)2476 wuffs_base__empty_rect_ie_u32(void) {
2477   wuffs_base__rect_ie_u32 ret;
2478   ret.min_incl_x = 0;
2479   ret.min_incl_y = 0;
2480   ret.max_excl_x = 0;
2481   ret.max_excl_y = 0;
2482   return ret;
2483 }
2484 
2485 static inline wuffs_base__rect_ie_u32  //
wuffs_base__make_rect_ie_u32(uint32_t min_incl_x,uint32_t min_incl_y,uint32_t max_excl_x,uint32_t max_excl_y)2486 wuffs_base__make_rect_ie_u32(uint32_t min_incl_x,
2487                              uint32_t min_incl_y,
2488                              uint32_t max_excl_x,
2489                              uint32_t max_excl_y) {
2490   wuffs_base__rect_ie_u32 ret;
2491   ret.min_incl_x = min_incl_x;
2492   ret.min_incl_y = min_incl_y;
2493   ret.max_excl_x = max_excl_x;
2494   ret.max_excl_y = max_excl_y;
2495   return ret;
2496 }
2497 
2498 static inline bool  //
wuffs_base__rect_ie_u32__is_empty(const wuffs_base__rect_ie_u32 * r)2499 wuffs_base__rect_ie_u32__is_empty(const wuffs_base__rect_ie_u32* r) {
2500   return (r->min_incl_x >= r->max_excl_x) || (r->min_incl_y >= r->max_excl_y);
2501 }
2502 
2503 static inline bool  //
wuffs_base__rect_ie_u32__equals(const wuffs_base__rect_ie_u32 * r,wuffs_base__rect_ie_u32 s)2504 wuffs_base__rect_ie_u32__equals(const wuffs_base__rect_ie_u32* r,
2505                                 wuffs_base__rect_ie_u32 s) {
2506   return (r->min_incl_x == s.min_incl_x && r->min_incl_y == s.min_incl_y &&
2507           r->max_excl_x == s.max_excl_x && r->max_excl_y == s.max_excl_y) ||
2508          (wuffs_base__rect_ie_u32__is_empty(r) &&
2509           wuffs_base__rect_ie_u32__is_empty(&s));
2510 }
2511 
2512 static inline wuffs_base__rect_ie_u32  //
wuffs_base__rect_ie_u32__intersect(const wuffs_base__rect_ie_u32 * r,wuffs_base__rect_ie_u32 s)2513 wuffs_base__rect_ie_u32__intersect(const wuffs_base__rect_ie_u32* r,
2514                                    wuffs_base__rect_ie_u32 s) {
2515   wuffs_base__rect_ie_u32 t;
2516   t.min_incl_x = wuffs_base__u32__max(r->min_incl_x, s.min_incl_x);
2517   t.min_incl_y = wuffs_base__u32__max(r->min_incl_y, s.min_incl_y);
2518   t.max_excl_x = wuffs_base__u32__min(r->max_excl_x, s.max_excl_x);
2519   t.max_excl_y = wuffs_base__u32__min(r->max_excl_y, s.max_excl_y);
2520   return t;
2521 }
2522 
2523 static inline wuffs_base__rect_ie_u32  //
wuffs_base__rect_ie_u32__unite(const wuffs_base__rect_ie_u32 * r,wuffs_base__rect_ie_u32 s)2524 wuffs_base__rect_ie_u32__unite(const wuffs_base__rect_ie_u32* r,
2525                                wuffs_base__rect_ie_u32 s) {
2526   if (wuffs_base__rect_ie_u32__is_empty(r)) {
2527     return s;
2528   }
2529   if (wuffs_base__rect_ie_u32__is_empty(&s)) {
2530     return *r;
2531   }
2532   wuffs_base__rect_ie_u32 t;
2533   t.min_incl_x = wuffs_base__u32__min(r->min_incl_x, s.min_incl_x);
2534   t.min_incl_y = wuffs_base__u32__min(r->min_incl_y, s.min_incl_y);
2535   t.max_excl_x = wuffs_base__u32__max(r->max_excl_x, s.max_excl_x);
2536   t.max_excl_y = wuffs_base__u32__max(r->max_excl_y, s.max_excl_y);
2537   return t;
2538 }
2539 
2540 static inline bool  //
wuffs_base__rect_ie_u32__contains(const wuffs_base__rect_ie_u32 * r,uint32_t x,uint32_t y)2541 wuffs_base__rect_ie_u32__contains(const wuffs_base__rect_ie_u32* r,
2542                                   uint32_t x,
2543                                   uint32_t y) {
2544   return (r->min_incl_x <= x) && (x < r->max_excl_x) && (r->min_incl_y <= y) &&
2545          (y < r->max_excl_y);
2546 }
2547 
2548 static inline bool  //
wuffs_base__rect_ie_u32__contains_rect(const wuffs_base__rect_ie_u32 * r,wuffs_base__rect_ie_u32 s)2549 wuffs_base__rect_ie_u32__contains_rect(const wuffs_base__rect_ie_u32* r,
2550                                        wuffs_base__rect_ie_u32 s) {
2551   return wuffs_base__rect_ie_u32__equals(
2552       &s, wuffs_base__rect_ie_u32__intersect(r, s));
2553 }
2554 
2555 static inline uint32_t  //
wuffs_base__rect_ie_u32__width(const wuffs_base__rect_ie_u32 * r)2556 wuffs_base__rect_ie_u32__width(const wuffs_base__rect_ie_u32* r) {
2557   return wuffs_base__u32__sat_sub(r->max_excl_x, r->min_incl_x);
2558 }
2559 
2560 static inline uint32_t  //
wuffs_base__rect_ie_u32__height(const wuffs_base__rect_ie_u32 * r)2561 wuffs_base__rect_ie_u32__height(const wuffs_base__rect_ie_u32* r) {
2562   return wuffs_base__u32__sat_sub(r->max_excl_y, r->min_incl_y);
2563 }
2564 
2565 #ifdef __cplusplus
2566 
2567 inline bool  //
is_empty()2568 wuffs_base__rect_ie_u32::is_empty() const {
2569   return wuffs_base__rect_ie_u32__is_empty(this);
2570 }
2571 
2572 inline bool  //
equals(wuffs_base__rect_ie_u32 s)2573 wuffs_base__rect_ie_u32::equals(wuffs_base__rect_ie_u32 s) const {
2574   return wuffs_base__rect_ie_u32__equals(this, s);
2575 }
2576 
2577 inline wuffs_base__rect_ie_u32  //
intersect(wuffs_base__rect_ie_u32 s)2578 wuffs_base__rect_ie_u32::intersect(wuffs_base__rect_ie_u32 s) const {
2579   return wuffs_base__rect_ie_u32__intersect(this, s);
2580 }
2581 
2582 inline wuffs_base__rect_ie_u32  //
unite(wuffs_base__rect_ie_u32 s)2583 wuffs_base__rect_ie_u32::unite(wuffs_base__rect_ie_u32 s) const {
2584   return wuffs_base__rect_ie_u32__unite(this, s);
2585 }
2586 
2587 inline bool  //
contains(uint32_t x,uint32_t y)2588 wuffs_base__rect_ie_u32::contains(uint32_t x, uint32_t y) const {
2589   return wuffs_base__rect_ie_u32__contains(this, x, y);
2590 }
2591 
2592 inline bool  //
contains_rect(wuffs_base__rect_ie_u32 s)2593 wuffs_base__rect_ie_u32::contains_rect(wuffs_base__rect_ie_u32 s) const {
2594   return wuffs_base__rect_ie_u32__contains_rect(this, s);
2595 }
2596 
2597 inline uint32_t  //
width()2598 wuffs_base__rect_ie_u32::width() const {
2599   return wuffs_base__rect_ie_u32__width(this);
2600 }
2601 
2602 inline uint32_t  //
height()2603 wuffs_base__rect_ie_u32::height() const {
2604   return wuffs_base__rect_ie_u32__height(this);
2605 }
2606 
2607 #endif  // __cplusplus
2608 
2609 // ---------------- More Information
2610 
2611 // wuffs_base__more_information holds additional fields, typically when a Wuffs
2612 // method returns a [note status](/doc/note/statuses.md).
2613 //
2614 // The flavor field follows the base38 namespace
2615 // convention](/doc/note/base38-and-fourcc.md). The other fields' semantics
2616 // depends on the flavor.
2617 typedef struct wuffs_base__more_information__struct {
2618   uint32_t flavor;
2619   uint32_t w;
2620   uint64_t x;
2621   uint64_t y;
2622   uint64_t z;
2623 
2624 #ifdef __cplusplus
2625   inline void set(uint32_t flavor_arg,
2626                   uint32_t w_arg,
2627                   uint64_t x_arg,
2628                   uint64_t y_arg,
2629                   uint64_t z_arg);
2630   inline uint32_t io_redirect__fourcc() const;
2631   inline wuffs_base__range_ie_u64 io_redirect__range() const;
2632   inline uint64_t io_seek__position() const;
2633   inline uint32_t metadata__fourcc() const;
2634   inline wuffs_base__range_ie_u64 metadata_raw_passthrough__range() const;
2635   inline int32_t metadata_parsed__chrm(uint32_t component) const;
2636   inline uint32_t metadata_parsed__gama() const;
2637   inline uint32_t metadata_parsed__srgb() const;
2638 #endif  // __cplusplus
2639 
2640 } wuffs_base__more_information;
2641 
2642 #define WUFFS_BASE__MORE_INFORMATION__FLAVOR__IO_REDIRECT 1
2643 #define WUFFS_BASE__MORE_INFORMATION__FLAVOR__IO_SEEK 2
2644 #define WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_RAW_PASSTHROUGH 3
2645 #define WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_RAW_TRANSFORM 4
2646 #define WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_PARSED 5
2647 
2648 static inline wuffs_base__more_information  //
wuffs_base__empty_more_information(void)2649 wuffs_base__empty_more_information(void) {
2650   wuffs_base__more_information ret;
2651   ret.flavor = 0;
2652   ret.w = 0;
2653   ret.x = 0;
2654   ret.y = 0;
2655   ret.z = 0;
2656   return ret;
2657 }
2658 
2659 static inline void  //
wuffs_base__more_information__set(wuffs_base__more_information * m,uint32_t flavor,uint32_t w,uint64_t x,uint64_t y,uint64_t z)2660 wuffs_base__more_information__set(wuffs_base__more_information* m,
2661                                   uint32_t flavor,
2662                                   uint32_t w,
2663                                   uint64_t x,
2664                                   uint64_t y,
2665                                   uint64_t z) {
2666   if (!m) {
2667     return;
2668   }
2669   m->flavor = flavor;
2670   m->w = w;
2671   m->x = x;
2672   m->y = y;
2673   m->z = z;
2674 }
2675 
2676 static inline uint32_t  //
wuffs_base__more_information__io_redirect__fourcc(const wuffs_base__more_information * m)2677 wuffs_base__more_information__io_redirect__fourcc(
2678     const wuffs_base__more_information* m) {
2679   return m->w;
2680 }
2681 
2682 static inline wuffs_base__range_ie_u64  //
wuffs_base__more_information__io_redirect__range(const wuffs_base__more_information * m)2683 wuffs_base__more_information__io_redirect__range(
2684     const wuffs_base__more_information* m) {
2685   wuffs_base__range_ie_u64 ret;
2686   ret.min_incl = m->y;
2687   ret.max_excl = m->z;
2688   return ret;
2689 }
2690 
2691 static inline uint64_t  //
wuffs_base__more_information__io_seek__position(const wuffs_base__more_information * m)2692 wuffs_base__more_information__io_seek__position(
2693     const wuffs_base__more_information* m) {
2694   return m->x;
2695 }
2696 
2697 static inline uint32_t  //
wuffs_base__more_information__metadata__fourcc(const wuffs_base__more_information * m)2698 wuffs_base__more_information__metadata__fourcc(
2699     const wuffs_base__more_information* m) {
2700   return m->w;
2701 }
2702 
2703 static inline wuffs_base__range_ie_u64  //
wuffs_base__more_information__metadata_raw_passthrough__range(const wuffs_base__more_information * m)2704 wuffs_base__more_information__metadata_raw_passthrough__range(
2705     const wuffs_base__more_information* m) {
2706   wuffs_base__range_ie_u64 ret;
2707   ret.min_incl = m->y;
2708   ret.max_excl = m->z;
2709   return ret;
2710 }
2711 
2712 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__WHITE_X 0
2713 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__WHITE_Y 1
2714 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__RED_X 2
2715 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__RED_Y 3
2716 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__GREEN_X 4
2717 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__GREEN_Y 5
2718 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__BLUE_X 6
2719 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__BLUE_Y 7
2720 
2721 // wuffs_base__more_information__metadata_parsed__chrm returns chromaticity
2722 // values (scaled by 100000) like the PNG "cHRM" chunk. For example, the sRGB
2723 // color space corresponds to:
2724 //  - ETC__CHRM__WHITE_X 31270
2725 //  - ETC__CHRM__WHITE_Y 32900
2726 //  - ETC__CHRM__RED_X   64000
2727 //  - ETC__CHRM__RED_Y   33000
2728 //  - ETC__CHRM__GREEN_X 30000
2729 //  - ETC__CHRM__GREEN_Y 60000
2730 //  - ETC__CHRM__BLUE_X  15000
2731 //  - ETC__CHRM__BLUE_Y   6000
2732 //
2733 // See
2734 // https://ciechanow.ski/color-spaces/#chromaticity-and-white-point-coordinates
2735 static inline int32_t  //
wuffs_base__more_information__metadata_parsed__chrm(const wuffs_base__more_information * m,uint32_t component)2736 wuffs_base__more_information__metadata_parsed__chrm(
2737     const wuffs_base__more_information* m,
2738     uint32_t component) {
2739   // After the flavor and the w field (holding a FourCC), a
2740   // wuffs_base__more_information holds 24 bytes of data in three uint64_t
2741   // typed fields (x, y and z). We pack the eight chromaticity values (wx, wy,
2742   // rx, ..., by), basically int24_t values, into 24 bytes like this:
2743   //  -    LSB                 MSB
2744   //  - x: wx wx wx wy wy wy rx rx
2745   //  - y: rx ry ry ry gx gx gx gy
2746   //  - z: gy gy bx bx bx by by by
2747   uint32_t u = 0;
2748   switch (component & 7) {
2749     case 0:
2750       u = ((uint32_t)(m->x >> 0));
2751       break;
2752     case 1:
2753       u = ((uint32_t)(m->x >> 24));
2754       break;
2755     case 2:
2756       u = ((uint32_t)((m->x >> 48) | (m->y << 16)));
2757       break;
2758     case 3:
2759       u = ((uint32_t)(m->y >> 8));
2760       break;
2761     case 4:
2762       u = ((uint32_t)(m->y >> 32));
2763       break;
2764     case 5:
2765       u = ((uint32_t)((m->y >> 56) | (m->z << 8)));
2766       break;
2767     case 6:
2768       u = ((uint32_t)(m->z >> 16));
2769       break;
2770     case 7:
2771       u = ((uint32_t)(m->z >> 40));
2772       break;
2773   }
2774   // The left-right shifts sign-extend from 24-bit to 32-bit integers.
2775   return ((int32_t)(u << 8)) >> 8;
2776 }
2777 
2778 // wuffs_base__more_information__metadata_parsed__gama returns inverse gamma
2779 // correction values (scaled by 100000) like the PNG "gAMA" chunk. For example,
2780 // for gamma = 2.2, this returns 45455 (approximating 100000 / 2.2).
2781 static inline uint32_t  //
wuffs_base__more_information__metadata_parsed__gama(const wuffs_base__more_information * m)2782 wuffs_base__more_information__metadata_parsed__gama(
2783     const wuffs_base__more_information* m) {
2784   return ((uint32_t)(m->x));
2785 }
2786 
2787 #define WUFFS_BASE__SRGB_RENDERING_INTENT__PERCEPTUAL 0
2788 #define WUFFS_BASE__SRGB_RENDERING_INTENT__RELATIVE_COLORIMETRIC 1
2789 #define WUFFS_BASE__SRGB_RENDERING_INTENT__SATURATION 2
2790 #define WUFFS_BASE__SRGB_RENDERING_INTENT__ABSOLUTE_COLORIMETRIC 3
2791 
2792 // wuffs_base__more_information__metadata_parsed__srgb returns the sRGB
2793 // rendering intent like the PNG "sRGB" chunk.
2794 static inline uint32_t  //
wuffs_base__more_information__metadata_parsed__srgb(const wuffs_base__more_information * m)2795 wuffs_base__more_information__metadata_parsed__srgb(
2796     const wuffs_base__more_information* m) {
2797   return m->x & 3;
2798 }
2799 
2800 #ifdef __cplusplus
2801 
2802 inline void  //
set(uint32_t flavor_arg,uint32_t w_arg,uint64_t x_arg,uint64_t y_arg,uint64_t z_arg)2803 wuffs_base__more_information::set(uint32_t flavor_arg,
2804                                   uint32_t w_arg,
2805                                   uint64_t x_arg,
2806                                   uint64_t y_arg,
2807                                   uint64_t z_arg) {
2808   wuffs_base__more_information__set(this, flavor_arg, w_arg, x_arg, y_arg,
2809                                     z_arg);
2810 }
2811 
2812 inline uint32_t  //
io_redirect__fourcc()2813 wuffs_base__more_information::io_redirect__fourcc() const {
2814   return wuffs_base__more_information__io_redirect__fourcc(this);
2815 }
2816 
2817 inline wuffs_base__range_ie_u64  //
io_redirect__range()2818 wuffs_base__more_information::io_redirect__range() const {
2819   return wuffs_base__more_information__io_redirect__range(this);
2820 }
2821 
2822 inline uint64_t  //
io_seek__position()2823 wuffs_base__more_information::io_seek__position() const {
2824   return wuffs_base__more_information__io_seek__position(this);
2825 }
2826 
2827 inline uint32_t  //
metadata__fourcc()2828 wuffs_base__more_information::metadata__fourcc() const {
2829   return wuffs_base__more_information__metadata__fourcc(this);
2830 }
2831 
2832 inline wuffs_base__range_ie_u64  //
metadata_raw_passthrough__range()2833 wuffs_base__more_information::metadata_raw_passthrough__range() const {
2834   return wuffs_base__more_information__metadata_raw_passthrough__range(this);
2835 }
2836 
2837 inline int32_t  //
metadata_parsed__chrm(uint32_t component)2838 wuffs_base__more_information::metadata_parsed__chrm(uint32_t component) const {
2839   return wuffs_base__more_information__metadata_parsed__chrm(this, component);
2840 }
2841 
2842 inline uint32_t  //
metadata_parsed__gama()2843 wuffs_base__more_information::metadata_parsed__gama() const {
2844   return wuffs_base__more_information__metadata_parsed__gama(this);
2845 }
2846 
2847 inline uint32_t  //
metadata_parsed__srgb()2848 wuffs_base__more_information::metadata_parsed__srgb() const {
2849   return wuffs_base__more_information__metadata_parsed__srgb(this);
2850 }
2851 
2852 #endif  // __cplusplus
2853 
2854 // ---------------- I/O
2855 //
2856 // See (/doc/note/io-input-output.md).
2857 
2858 // wuffs_base__io_buffer_meta is the metadata for a wuffs_base__io_buffer's
2859 // data.
2860 typedef struct wuffs_base__io_buffer_meta__struct {
2861   size_t wi;     // Write index. Invariant: wi <= len.
2862   size_t ri;     // Read  index. Invariant: ri <= wi.
2863   uint64_t pos;  // Buffer position (relative to the start of stream).
2864   bool closed;   // No further writes are expected.
2865 } wuffs_base__io_buffer_meta;
2866 
2867 // wuffs_base__io_buffer is a 1-dimensional buffer (a pointer and length) plus
2868 // additional metadata.
2869 //
2870 // A value with all fields zero is a valid, empty buffer.
2871 typedef struct wuffs_base__io_buffer__struct {
2872   wuffs_base__slice_u8 data;
2873   wuffs_base__io_buffer_meta meta;
2874 
2875 #ifdef __cplusplus
2876   inline bool is_valid() const;
2877   inline void compact();
2878   inline void compact_retaining(uint64_t history_retain_length);
2879   inline size_t reader_length() const;
2880   inline uint8_t* reader_pointer() const;
2881   inline uint64_t reader_position() const;
2882   inline wuffs_base__slice_u8 reader_slice() const;
2883   inline size_t writer_length() const;
2884   inline uint8_t* writer_pointer() const;
2885   inline uint64_t writer_position() const;
2886   inline wuffs_base__slice_u8 writer_slice() const;
2887 #endif  // __cplusplus
2888 
2889 } wuffs_base__io_buffer;
2890 
2891 static inline wuffs_base__io_buffer  //
wuffs_base__make_io_buffer(wuffs_base__slice_u8 data,wuffs_base__io_buffer_meta meta)2892 wuffs_base__make_io_buffer(wuffs_base__slice_u8 data,
2893                            wuffs_base__io_buffer_meta meta) {
2894   wuffs_base__io_buffer ret;
2895   ret.data = data;
2896   ret.meta = meta;
2897   return ret;
2898 }
2899 
2900 static inline wuffs_base__io_buffer_meta  //
wuffs_base__make_io_buffer_meta(size_t wi,size_t ri,uint64_t pos,bool closed)2901 wuffs_base__make_io_buffer_meta(size_t wi,
2902                                 size_t ri,
2903                                 uint64_t pos,
2904                                 bool closed) {
2905   wuffs_base__io_buffer_meta ret;
2906   ret.wi = wi;
2907   ret.ri = ri;
2908   ret.pos = pos;
2909   ret.closed = closed;
2910   return ret;
2911 }
2912 
2913 static inline wuffs_base__io_buffer  //
wuffs_base__ptr_u8__reader(uint8_t * ptr,size_t len,bool closed)2914 wuffs_base__ptr_u8__reader(uint8_t* ptr, size_t len, bool closed) {
2915   wuffs_base__io_buffer ret;
2916   ret.data.ptr = ptr;
2917   ret.data.len = len;
2918   ret.meta.wi = len;
2919   ret.meta.ri = 0;
2920   ret.meta.pos = 0;
2921   ret.meta.closed = closed;
2922   return ret;
2923 }
2924 
2925 static inline wuffs_base__io_buffer  //
wuffs_base__ptr_u8__writer(uint8_t * ptr,size_t len)2926 wuffs_base__ptr_u8__writer(uint8_t* ptr, size_t len) {
2927   wuffs_base__io_buffer ret;
2928   ret.data.ptr = ptr;
2929   ret.data.len = len;
2930   ret.meta.wi = 0;
2931   ret.meta.ri = 0;
2932   ret.meta.pos = 0;
2933   ret.meta.closed = false;
2934   return ret;
2935 }
2936 
2937 static inline wuffs_base__io_buffer  //
wuffs_base__slice_u8__reader(wuffs_base__slice_u8 s,bool closed)2938 wuffs_base__slice_u8__reader(wuffs_base__slice_u8 s, bool closed) {
2939   wuffs_base__io_buffer ret;
2940   ret.data.ptr = s.ptr;
2941   ret.data.len = s.len;
2942   ret.meta.wi = s.len;
2943   ret.meta.ri = 0;
2944   ret.meta.pos = 0;
2945   ret.meta.closed = closed;
2946   return ret;
2947 }
2948 
2949 static inline wuffs_base__io_buffer  //
wuffs_base__slice_u8__writer(wuffs_base__slice_u8 s)2950 wuffs_base__slice_u8__writer(wuffs_base__slice_u8 s) {
2951   wuffs_base__io_buffer ret;
2952   ret.data.ptr = s.ptr;
2953   ret.data.len = s.len;
2954   ret.meta.wi = 0;
2955   ret.meta.ri = 0;
2956   ret.meta.pos = 0;
2957   ret.meta.closed = false;
2958   return ret;
2959 }
2960 
2961 static inline wuffs_base__io_buffer  //
wuffs_base__empty_io_buffer(void)2962 wuffs_base__empty_io_buffer(void) {
2963   wuffs_base__io_buffer ret;
2964   ret.data.ptr = NULL;
2965   ret.data.len = 0;
2966   ret.meta.wi = 0;
2967   ret.meta.ri = 0;
2968   ret.meta.pos = 0;
2969   ret.meta.closed = false;
2970   return ret;
2971 }
2972 
2973 static inline wuffs_base__io_buffer_meta  //
wuffs_base__empty_io_buffer_meta(void)2974 wuffs_base__empty_io_buffer_meta(void) {
2975   wuffs_base__io_buffer_meta ret;
2976   ret.wi = 0;
2977   ret.ri = 0;
2978   ret.pos = 0;
2979   ret.closed = false;
2980   return ret;
2981 }
2982 
2983 static inline bool  //
wuffs_base__io_buffer__is_valid(const wuffs_base__io_buffer * buf)2984 wuffs_base__io_buffer__is_valid(const wuffs_base__io_buffer* buf) {
2985   if (buf) {
2986     if (buf->data.ptr) {
2987       return (buf->meta.ri <= buf->meta.wi) && (buf->meta.wi <= buf->data.len);
2988     } else {
2989       return (buf->meta.ri == 0) && (buf->meta.wi == 0) && (buf->data.len == 0);
2990     }
2991   }
2992   return false;
2993 }
2994 
2995 // wuffs_base__io_buffer__compact moves any written but unread bytes to the
2996 // start of the buffer.
2997 static inline void  //
wuffs_base__io_buffer__compact(wuffs_base__io_buffer * buf)2998 wuffs_base__io_buffer__compact(wuffs_base__io_buffer* buf) {
2999   if (!buf || (buf->meta.ri == 0)) {
3000     return;
3001   }
3002   buf->meta.pos = wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.ri);
3003   size_t new_wi = buf->meta.wi - buf->meta.ri;
3004   if (new_wi != 0) {
3005     memmove(buf->data.ptr, buf->data.ptr + buf->meta.ri, new_wi);
3006   }
3007   buf->meta.wi = new_wi;
3008   buf->meta.ri = 0;
3009 }
3010 
3011 // wuffs_base__io_buffer__compact_retaining moves any written but unread bytes
3012 // closer to the start of the buffer. It retains H bytes of history (the most
3013 // recently read bytes), where H is min(buf->meta.ri, history_retain_length).
3014 // A postcondition is that buf->meta.ri == H.
3015 //
3016 // wuffs_base__io_buffer__compact_retaining(0) is equivalent to
3017 // wuffs_base__io_buffer__compact().
3018 //
3019 // For example, if buf started like this:
3020 //
3021 //        +--- ri = 3
3022 //        v
3023 //     abcdefgh??    len = 10, pos = 900
3024 //             ^
3025 //             +--- wi = 8
3026 //
3027 // Then, depending on history_retain_length, the resultant buf would be:
3028 //
3029 // HRL = 0     defgh?????    ri = 0    wi = 5    pos = 903
3030 // HRL = 1     cdefgh????    ri = 1    wi = 6    pos = 902
3031 // HRL = 2     bcdefgh???    ri = 2    wi = 7    pos = 901
3032 // HRL = 3     abcdefgh??    ri = 3    wi = 8    pos = 900
3033 // HRL = 4+    abcdefgh??    ri = 3    wi = 8    pos = 900
3034 static inline void  //
wuffs_base__io_buffer__compact_retaining(wuffs_base__io_buffer * buf,uint64_t history_retain_length)3035 wuffs_base__io_buffer__compact_retaining(wuffs_base__io_buffer* buf,
3036                                          uint64_t history_retain_length) {
3037   if (!buf || (buf->meta.ri == 0)) {
3038     return;
3039   }
3040   size_t old_ri = buf->meta.ri;
3041   size_t new_ri = (size_t)(wuffs_base__u64__min(old_ri, history_retain_length));
3042   size_t memmove_start = old_ri - new_ri;
3043   buf->meta.pos = wuffs_base__u64__sat_add(buf->meta.pos, memmove_start);
3044   size_t new_wi = buf->meta.wi - memmove_start;
3045   if ((new_wi != 0) && (memmove_start != 0)) {
3046     memmove(buf->data.ptr, buf->data.ptr + memmove_start, new_wi);
3047   }
3048   buf->meta.wi = new_wi;
3049   buf->meta.ri = new_ri;
3050 }
3051 
3052 static inline size_t  //
wuffs_base__io_buffer__reader_length(const wuffs_base__io_buffer * buf)3053 wuffs_base__io_buffer__reader_length(const wuffs_base__io_buffer* buf) {
3054   return buf ? buf->meta.wi - buf->meta.ri : 0;
3055 }
3056 
3057 static inline uint8_t*  //
wuffs_base__io_buffer__reader_pointer(const wuffs_base__io_buffer * buf)3058 wuffs_base__io_buffer__reader_pointer(const wuffs_base__io_buffer* buf) {
3059   return buf ? (buf->data.ptr + buf->meta.ri) : NULL;
3060 }
3061 
3062 static inline uint64_t  //
wuffs_base__io_buffer__reader_position(const wuffs_base__io_buffer * buf)3063 wuffs_base__io_buffer__reader_position(const wuffs_base__io_buffer* buf) {
3064   return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.ri) : 0;
3065 }
3066 
3067 static inline wuffs_base__slice_u8  //
wuffs_base__io_buffer__reader_slice(const wuffs_base__io_buffer * buf)3068 wuffs_base__io_buffer__reader_slice(const wuffs_base__io_buffer* buf) {
3069   return buf ? wuffs_base__make_slice_u8(buf->data.ptr + buf->meta.ri,
3070                                          buf->meta.wi - buf->meta.ri)
3071              : wuffs_base__empty_slice_u8();
3072 }
3073 
3074 static inline size_t  //
wuffs_base__io_buffer__writer_length(const wuffs_base__io_buffer * buf)3075 wuffs_base__io_buffer__writer_length(const wuffs_base__io_buffer* buf) {
3076   return buf ? buf->data.len - buf->meta.wi : 0;
3077 }
3078 
3079 static inline uint8_t*  //
wuffs_base__io_buffer__writer_pointer(const wuffs_base__io_buffer * buf)3080 wuffs_base__io_buffer__writer_pointer(const wuffs_base__io_buffer* buf) {
3081   return buf ? (buf->data.ptr + buf->meta.wi) : NULL;
3082 }
3083 
3084 static inline uint64_t  //
wuffs_base__io_buffer__writer_position(const wuffs_base__io_buffer * buf)3085 wuffs_base__io_buffer__writer_position(const wuffs_base__io_buffer* buf) {
3086   return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.wi) : 0;
3087 }
3088 
3089 static inline wuffs_base__slice_u8  //
wuffs_base__io_buffer__writer_slice(const wuffs_base__io_buffer * buf)3090 wuffs_base__io_buffer__writer_slice(const wuffs_base__io_buffer* buf) {
3091   return buf ? wuffs_base__make_slice_u8(buf->data.ptr + buf->meta.wi,
3092                                          buf->data.len - buf->meta.wi)
3093              : wuffs_base__empty_slice_u8();
3094 }
3095 
3096 #ifdef __cplusplus
3097 
3098 inline bool  //
is_valid()3099 wuffs_base__io_buffer::is_valid() const {
3100   return wuffs_base__io_buffer__is_valid(this);
3101 }
3102 
3103 inline void  //
compact()3104 wuffs_base__io_buffer::compact() {
3105   wuffs_base__io_buffer__compact(this);
3106 }
3107 
3108 inline void  //
compact_retaining(uint64_t history_retain_length)3109 wuffs_base__io_buffer::compact_retaining(uint64_t history_retain_length) {
3110   wuffs_base__io_buffer__compact_retaining(this, history_retain_length);
3111 }
3112 
3113 inline size_t  //
reader_length()3114 wuffs_base__io_buffer::reader_length() const {
3115   return wuffs_base__io_buffer__reader_length(this);
3116 }
3117 
3118 inline uint8_t*  //
reader_pointer()3119 wuffs_base__io_buffer::reader_pointer() const {
3120   return wuffs_base__io_buffer__reader_pointer(this);
3121 }
3122 
3123 inline uint64_t  //
reader_position()3124 wuffs_base__io_buffer::reader_position() const {
3125   return wuffs_base__io_buffer__reader_position(this);
3126 }
3127 
3128 inline wuffs_base__slice_u8  //
reader_slice()3129 wuffs_base__io_buffer::reader_slice() const {
3130   return wuffs_base__io_buffer__reader_slice(this);
3131 }
3132 
3133 inline size_t  //
writer_length()3134 wuffs_base__io_buffer::writer_length() const {
3135   return wuffs_base__io_buffer__writer_length(this);
3136 }
3137 
3138 inline uint8_t*  //
writer_pointer()3139 wuffs_base__io_buffer::writer_pointer() const {
3140   return wuffs_base__io_buffer__writer_pointer(this);
3141 }
3142 
3143 inline uint64_t  //
writer_position()3144 wuffs_base__io_buffer::writer_position() const {
3145   return wuffs_base__io_buffer__writer_position(this);
3146 }
3147 
3148 inline wuffs_base__slice_u8  //
writer_slice()3149 wuffs_base__io_buffer::writer_slice() const {
3150   return wuffs_base__io_buffer__writer_slice(this);
3151 }
3152 
3153 #endif  // __cplusplus
3154 
3155 // ---------------- Tokens
3156 
3157 // wuffs_base__token is an element of a byte stream's tokenization.
3158 //
3159 // See https://github.com/google/wuffs/blob/main/doc/note/tokens.md
3160 typedef struct wuffs_base__token__struct {
3161   uint64_t repr;
3162 
3163 #ifdef __cplusplus
3164   inline int64_t value() const;
3165   inline int64_t value_extension() const;
3166   inline int64_t value_major() const;
3167   inline int64_t value_base_category() const;
3168   inline uint64_t value_minor() const;
3169   inline uint64_t value_base_detail() const;
3170   inline int64_t value_base_detail__sign_extended() const;
3171   inline bool continued() const;
3172   inline uint64_t length() const;
3173 #endif  // __cplusplus
3174 
3175 } wuffs_base__token;
3176 
3177 static inline wuffs_base__token  //
wuffs_base__make_token(uint64_t repr)3178 wuffs_base__make_token(uint64_t repr) {
3179   wuffs_base__token ret;
3180   ret.repr = repr;
3181   return ret;
3182 }
3183 
3184 // --------
3185 
3186 #define WUFFS_BASE__TOKEN__LENGTH__MAX_INCL 0xFFFF
3187 
3188 #define WUFFS_BASE__TOKEN__VALUE__SHIFT 17
3189 #define WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT 17
3190 #define WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT 42
3191 #define WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT 17
3192 #define WUFFS_BASE__TOKEN__VALUE_BASE_CATEGORY__SHIFT 38
3193 #define WUFFS_BASE__TOKEN__VALUE_BASE_DETAIL__SHIFT 17
3194 #define WUFFS_BASE__TOKEN__CONTINUED__SHIFT 16
3195 #define WUFFS_BASE__TOKEN__LENGTH__SHIFT 0
3196 
3197 #define WUFFS_BASE__TOKEN__VALUE_EXTENSION__NUM_BITS 46
3198 
3199 // --------
3200 
3201 #define WUFFS_BASE__TOKEN__VBC__FILLER 0
3202 #define WUFFS_BASE__TOKEN__VBC__STRUCTURE 1
3203 #define WUFFS_BASE__TOKEN__VBC__STRING 2
3204 #define WUFFS_BASE__TOKEN__VBC__UNICODE_CODE_POINT 3
3205 #define WUFFS_BASE__TOKEN__VBC__LITERAL 4
3206 #define WUFFS_BASE__TOKEN__VBC__NUMBER 5
3207 #define WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_SIGNED 6
3208 #define WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_UNSIGNED 7
3209 
3210 // --------
3211 
3212 #define WUFFS_BASE__TOKEN__VBD__FILLER__PUNCTUATION 0x00001
3213 #define WUFFS_BASE__TOKEN__VBD__FILLER__COMMENT_BLOCK 0x00002
3214 #define WUFFS_BASE__TOKEN__VBD__FILLER__COMMENT_LINE 0x00004
3215 
3216 // COMMENT_ANY is a bit-wise or of COMMENT_BLOCK AND COMMENT_LINE.
3217 #define WUFFS_BASE__TOKEN__VBD__FILLER__COMMENT_ANY 0x00006
3218 
3219 // --------
3220 
3221 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH 0x00001
3222 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__POP 0x00002
3223 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_NONE 0x00010
3224 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_LIST 0x00020
3225 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_DICT 0x00040
3226 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_NONE 0x01000
3227 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_LIST 0x02000
3228 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_DICT 0x04000
3229 
3230 // --------
3231 
3232 // DEFINITELY_FOO means that the destination bytes (and also the source bytes,
3233 // for 1_DST_1_SRC_COPY) are in the FOO format. Definitely means that the lack
3234 // of the bit means "maybe FOO". It does not necessarily mean "not FOO".
3235 //
3236 // CHAIN_ETC means that decoding the entire token chain forms a UTF-8 or ASCII
3237 // string, not just this current token. CHAIN_ETC_UTF_8 therefore distinguishes
3238 // Unicode (UTF-8) strings from byte strings. MUST means that the the token
3239 // producer (e.g. parser) must verify this. SHOULD means that the token
3240 // consumer (e.g. renderer) should verify this.
3241 //
3242 // When a CHAIN_ETC_UTF_8 bit is set, the parser must ensure that non-ASCII
3243 // code points (with multi-byte UTF-8 encodings) do not straddle token
3244 // boundaries. Checking UTF-8 validity can inspect each token separately.
3245 //
3246 // The lack of any particular bit is conservative: it is valid for all-ASCII
3247 // strings, in a single- or multi-token chain, to have none of these bits set.
3248 #define WUFFS_BASE__TOKEN__VBD__STRING__DEFINITELY_UTF_8 0x00001
3249 #define WUFFS_BASE__TOKEN__VBD__STRING__CHAIN_MUST_BE_UTF_8 0x00002
3250 #define WUFFS_BASE__TOKEN__VBD__STRING__CHAIN_SHOULD_BE_UTF_8 0x00004
3251 #define WUFFS_BASE__TOKEN__VBD__STRING__DEFINITELY_ASCII 0x00010
3252 #define WUFFS_BASE__TOKEN__VBD__STRING__CHAIN_MUST_BE_ASCII 0x00020
3253 #define WUFFS_BASE__TOKEN__VBD__STRING__CHAIN_SHOULD_BE_ASCII 0x00040
3254 
3255 // CONVERT_D_DST_S_SRC means that multiples of S source bytes (possibly padded)
3256 // produces multiples of D destination bytes. For example,
3257 // CONVERT_1_DST_4_SRC_BACKSLASH_X means a source like "\\x23\\x67\\xAB", where
3258 // 12 src bytes encode 3 dst bytes.
3259 //
3260 // Post-processing may further transform those D destination bytes (e.g. treat
3261 // "\\xFF" as the Unicode code point U+00FF instead of the byte 0xFF), but that
3262 // is out of scope of this VBD's semantics.
3263 //
3264 // When src is the empty string, multiple conversion algorithms are applicable
3265 // (so these bits are not necessarily mutually exclusive), all producing the
3266 // same empty dst string.
3267 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_0_DST_1_SRC_DROP 0x00100
3268 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_1_SRC_COPY 0x00200
3269 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_2_SRC_HEXADECIMAL 0x00400
3270 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_4_SRC_BACKSLASH_X 0x00800
3271 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_3_DST_4_SRC_BASE_64_STD 0x01000
3272 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_3_DST_4_SRC_BASE_64_URL 0x02000
3273 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_4_DST_5_SRC_ASCII_85 0x04000
3274 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_5_DST_8_SRC_BASE_32_HEX 0x08000
3275 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_5_DST_8_SRC_BASE_32_STD 0x10000
3276 
3277 // --------
3278 
3279 #define WUFFS_BASE__TOKEN__VBD__LITERAL__UNDEFINED 0x00001
3280 #define WUFFS_BASE__TOKEN__VBD__LITERAL__NULL 0x00002
3281 #define WUFFS_BASE__TOKEN__VBD__LITERAL__FALSE 0x00004
3282 #define WUFFS_BASE__TOKEN__VBD__LITERAL__TRUE 0x00008
3283 
3284 // --------
3285 
3286 // For a source string of "123" or "0x9A", it is valid for a tokenizer to
3287 // return any combination of:
3288 //  - WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_FLOATING_POINT.
3289 //  - WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_SIGNED.
3290 //  - WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_UNSIGNED.
3291 //
3292 // For a source string of "+123" or "-0x9A", only the first two are valid.
3293 //
3294 // For a source string of "123.", only the first one is valid.
3295 #define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_FLOATING_POINT 0x00001
3296 #define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_SIGNED 0x00002
3297 #define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_UNSIGNED 0x00004
3298 
3299 #define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_NEG_INF 0x00010
3300 #define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_POS_INF 0x00020
3301 #define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_NEG_NAN 0x00040
3302 #define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_POS_NAN 0x00080
3303 
3304 // The number 300 might be represented as "\x01\x2C", "\x2C\x01\x00\x00" or
3305 // "300", which are big-endian, little-endian or text. For binary formats, the
3306 // token length (after adjusting for FORMAT_IGNORE_ETC) discriminates
3307 // e.g. u16 little-endian vs u32 little-endian.
3308 #define WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_BINARY_BIG_ENDIAN 0x00100
3309 #define WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_BINARY_LITTLE_ENDIAN 0x00200
3310 #define WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_TEXT 0x00400
3311 
3312 #define WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_IGNORE_FIRST_BYTE 0x01000
3313 
3314 // --------
3315 
3316 // wuffs_base__token__value returns the token's high 46 bits, sign-extended. A
3317 // negative value means an extended token, non-negative means a simple token.
3318 static inline int64_t  //
wuffs_base__token__value(const wuffs_base__token * t)3319 wuffs_base__token__value(const wuffs_base__token* t) {
3320   return ((int64_t)(t->repr)) >> WUFFS_BASE__TOKEN__VALUE__SHIFT;
3321 }
3322 
3323 // wuffs_base__token__value_extension returns a negative value if the token was
3324 // not an extended token.
3325 static inline int64_t  //
wuffs_base__token__value_extension(const wuffs_base__token * t)3326 wuffs_base__token__value_extension(const wuffs_base__token* t) {
3327   return (~(int64_t)(t->repr)) >> WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT;
3328 }
3329 
3330 // wuffs_base__token__value_major returns a negative value if the token was not
3331 // a simple token.
3332 static inline int64_t  //
wuffs_base__token__value_major(const wuffs_base__token * t)3333 wuffs_base__token__value_major(const wuffs_base__token* t) {
3334   return ((int64_t)(t->repr)) >> WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT;
3335 }
3336 
3337 // wuffs_base__token__value_base_category returns a negative value if the token
3338 // was not a simple token.
3339 static inline int64_t  //
wuffs_base__token__value_base_category(const wuffs_base__token * t)3340 wuffs_base__token__value_base_category(const wuffs_base__token* t) {
3341   return ((int64_t)(t->repr)) >> WUFFS_BASE__TOKEN__VALUE_BASE_CATEGORY__SHIFT;
3342 }
3343 
3344 static inline uint64_t  //
wuffs_base__token__value_minor(const wuffs_base__token * t)3345 wuffs_base__token__value_minor(const wuffs_base__token* t) {
3346   return (t->repr >> WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) & 0x1FFFFFF;
3347 }
3348 
3349 static inline uint64_t  //
wuffs_base__token__value_base_detail(const wuffs_base__token * t)3350 wuffs_base__token__value_base_detail(const wuffs_base__token* t) {
3351   return (t->repr >> WUFFS_BASE__TOKEN__VALUE_BASE_DETAIL__SHIFT) & 0x1FFFFF;
3352 }
3353 
3354 static inline int64_t  //
wuffs_base__token__value_base_detail__sign_extended(const wuffs_base__token * t)3355 wuffs_base__token__value_base_detail__sign_extended(
3356     const wuffs_base__token* t) {
3357   // The VBD is 21 bits in the middle of t->repr. Left shift the high (64 - 21
3358   // - ETC__SHIFT) bits off, then right shift (sign-extending) back down.
3359   uint64_t u = t->repr << (43 - WUFFS_BASE__TOKEN__VALUE_BASE_DETAIL__SHIFT);
3360   return ((int64_t)u) >> 43;
3361 }
3362 
3363 static inline bool  //
wuffs_base__token__continued(const wuffs_base__token * t)3364 wuffs_base__token__continued(const wuffs_base__token* t) {
3365   return t->repr & 0x10000;
3366 }
3367 
3368 static inline uint64_t  //
wuffs_base__token__length(const wuffs_base__token * t)3369 wuffs_base__token__length(const wuffs_base__token* t) {
3370   return (t->repr >> WUFFS_BASE__TOKEN__LENGTH__SHIFT) & 0xFFFF;
3371 }
3372 
3373 #ifdef __cplusplus
3374 
3375 inline int64_t  //
value()3376 wuffs_base__token::value() const {
3377   return wuffs_base__token__value(this);
3378 }
3379 
3380 inline int64_t  //
value_extension()3381 wuffs_base__token::value_extension() const {
3382   return wuffs_base__token__value_extension(this);
3383 }
3384 
3385 inline int64_t  //
value_major()3386 wuffs_base__token::value_major() const {
3387   return wuffs_base__token__value_major(this);
3388 }
3389 
3390 inline int64_t  //
value_base_category()3391 wuffs_base__token::value_base_category() const {
3392   return wuffs_base__token__value_base_category(this);
3393 }
3394 
3395 inline uint64_t  //
value_minor()3396 wuffs_base__token::value_minor() const {
3397   return wuffs_base__token__value_minor(this);
3398 }
3399 
3400 inline uint64_t  //
value_base_detail()3401 wuffs_base__token::value_base_detail() const {
3402   return wuffs_base__token__value_base_detail(this);
3403 }
3404 
3405 inline int64_t  //
value_base_detail__sign_extended()3406 wuffs_base__token::value_base_detail__sign_extended() const {
3407   return wuffs_base__token__value_base_detail__sign_extended(this);
3408 }
3409 
3410 inline bool  //
continued()3411 wuffs_base__token::continued() const {
3412   return wuffs_base__token__continued(this);
3413 }
3414 
3415 inline uint64_t  //
length()3416 wuffs_base__token::length() const {
3417   return wuffs_base__token__length(this);
3418 }
3419 
3420 #endif  // __cplusplus
3421 
3422 // --------
3423 
3424 typedef WUFFS_BASE__SLICE(wuffs_base__token) wuffs_base__slice_token;
3425 
3426 static inline wuffs_base__slice_token  //
wuffs_base__make_slice_token(wuffs_base__token * ptr,size_t len)3427 wuffs_base__make_slice_token(wuffs_base__token* ptr, size_t len) {
3428   wuffs_base__slice_token ret;
3429   ret.ptr = ptr;
3430   ret.len = len;
3431   return ret;
3432 }
3433 
3434 static inline wuffs_base__slice_token  //
wuffs_base__empty_slice_token(void)3435 wuffs_base__empty_slice_token(void) {
3436   wuffs_base__slice_token ret;
3437   ret.ptr = NULL;
3438   ret.len = 0;
3439   return ret;
3440 }
3441 
3442 // --------
3443 
3444 // wuffs_base__token_buffer_meta is the metadata for a
3445 // wuffs_base__token_buffer's data.
3446 typedef struct wuffs_base__token_buffer_meta__struct {
3447   size_t wi;     // Write index. Invariant: wi <= len.
3448   size_t ri;     // Read  index. Invariant: ri <= wi.
3449   uint64_t pos;  // Position of the buffer start relative to the stream start.
3450   bool closed;   // No further writes are expected.
3451 } wuffs_base__token_buffer_meta;
3452 
3453 // wuffs_base__token_buffer is a 1-dimensional buffer (a pointer and length)
3454 // plus additional metadata.
3455 //
3456 // A value with all fields zero is a valid, empty buffer.
3457 typedef struct wuffs_base__token_buffer__struct {
3458   wuffs_base__slice_token data;
3459   wuffs_base__token_buffer_meta meta;
3460 
3461 #ifdef __cplusplus
3462   inline bool is_valid() const;
3463   inline void compact();
3464   inline void compact_retaining(uint64_t history_retain_length);
3465   inline uint64_t reader_length() const;
3466   inline wuffs_base__token* reader_pointer() const;
3467   inline wuffs_base__slice_token reader_slice() const;
3468   inline uint64_t reader_token_position() const;
3469   inline uint64_t writer_length() const;
3470   inline uint64_t writer_token_position() const;
3471   inline wuffs_base__token* writer_pointer() const;
3472   inline wuffs_base__slice_token writer_slice() const;
3473 #endif  // __cplusplus
3474 
3475 } wuffs_base__token_buffer;
3476 
3477 static inline wuffs_base__token_buffer  //
wuffs_base__make_token_buffer(wuffs_base__slice_token data,wuffs_base__token_buffer_meta meta)3478 wuffs_base__make_token_buffer(wuffs_base__slice_token data,
3479                               wuffs_base__token_buffer_meta meta) {
3480   wuffs_base__token_buffer ret;
3481   ret.data = data;
3482   ret.meta = meta;
3483   return ret;
3484 }
3485 
3486 static inline wuffs_base__token_buffer_meta  //
wuffs_base__make_token_buffer_meta(size_t wi,size_t ri,uint64_t pos,bool closed)3487 wuffs_base__make_token_buffer_meta(size_t wi,
3488                                    size_t ri,
3489                                    uint64_t pos,
3490                                    bool closed) {
3491   wuffs_base__token_buffer_meta ret;
3492   ret.wi = wi;
3493   ret.ri = ri;
3494   ret.pos = pos;
3495   ret.closed = closed;
3496   return ret;
3497 }
3498 
3499 static inline wuffs_base__token_buffer  //
wuffs_base__slice_token__reader(wuffs_base__slice_token s,bool closed)3500 wuffs_base__slice_token__reader(wuffs_base__slice_token s, bool closed) {
3501   wuffs_base__token_buffer ret;
3502   ret.data.ptr = s.ptr;
3503   ret.data.len = s.len;
3504   ret.meta.wi = s.len;
3505   ret.meta.ri = 0;
3506   ret.meta.pos = 0;
3507   ret.meta.closed = closed;
3508   return ret;
3509 }
3510 
3511 static inline wuffs_base__token_buffer  //
wuffs_base__slice_token__writer(wuffs_base__slice_token s)3512 wuffs_base__slice_token__writer(wuffs_base__slice_token s) {
3513   wuffs_base__token_buffer ret;
3514   ret.data.ptr = s.ptr;
3515   ret.data.len = s.len;
3516   ret.meta.wi = 0;
3517   ret.meta.ri = 0;
3518   ret.meta.pos = 0;
3519   ret.meta.closed = false;
3520   return ret;
3521 }
3522 
3523 static inline wuffs_base__token_buffer  //
wuffs_base__empty_token_buffer(void)3524 wuffs_base__empty_token_buffer(void) {
3525   wuffs_base__token_buffer ret;
3526   ret.data.ptr = NULL;
3527   ret.data.len = 0;
3528   ret.meta.wi = 0;
3529   ret.meta.ri = 0;
3530   ret.meta.pos = 0;
3531   ret.meta.closed = false;
3532   return ret;
3533 }
3534 
3535 static inline wuffs_base__token_buffer_meta  //
wuffs_base__empty_token_buffer_meta(void)3536 wuffs_base__empty_token_buffer_meta(void) {
3537   wuffs_base__token_buffer_meta ret;
3538   ret.wi = 0;
3539   ret.ri = 0;
3540   ret.pos = 0;
3541   ret.closed = false;
3542   return ret;
3543 }
3544 
3545 static inline bool  //
wuffs_base__token_buffer__is_valid(const wuffs_base__token_buffer * buf)3546 wuffs_base__token_buffer__is_valid(const wuffs_base__token_buffer* buf) {
3547   if (buf) {
3548     if (buf->data.ptr) {
3549       return (buf->meta.ri <= buf->meta.wi) && (buf->meta.wi <= buf->data.len);
3550     } else {
3551       return (buf->meta.ri == 0) && (buf->meta.wi == 0) && (buf->data.len == 0);
3552     }
3553   }
3554   return false;
3555 }
3556 
3557 // wuffs_base__token_buffer__compact moves any written but unread tokens to the
3558 // start of the buffer.
3559 static inline void  //
wuffs_base__token_buffer__compact(wuffs_base__token_buffer * buf)3560 wuffs_base__token_buffer__compact(wuffs_base__token_buffer* buf) {
3561   if (!buf || (buf->meta.ri == 0)) {
3562     return;
3563   }
3564   buf->meta.pos = wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.ri);
3565   size_t new_wi = buf->meta.wi - buf->meta.ri;
3566   if (new_wi != 0) {
3567     memmove(buf->data.ptr, buf->data.ptr + buf->meta.ri,
3568             new_wi * sizeof(wuffs_base__token));
3569   }
3570   buf->meta.wi = new_wi;
3571   buf->meta.ri = 0;
3572 }
3573 
3574 // wuffs_base__token_buffer__compact_retaining moves any written but unread
3575 // tokens closer to the start of the buffer. It retains H tokens of history
3576 // (the most recently read tokens), where H is min(buf->meta.ri,
3577 // history_retain_length). A postcondition is that buf->meta.ri == H.
3578 //
3579 // wuffs_base__token_buffer__compact_retaining(0) is equivalent to
3580 // wuffs_base__token_buffer__compact().
3581 //
3582 // For example, if buf started like this:
3583 //
3584 //        +--- ri = 3
3585 //        v
3586 //     abcdefgh??    len = 10, pos = 900
3587 //             ^
3588 //             +--- wi = 8
3589 //
3590 // Then, depending on history_retain_length, the resultant buf would be:
3591 //
3592 // HRL = 0     defgh?????    ri = 0    wi = 5    pos = 903
3593 // HRL = 1     cdefgh????    ri = 1    wi = 6    pos = 902
3594 // HRL = 2     bcdefgh???    ri = 2    wi = 7    pos = 901
3595 // HRL = 3     abcdefgh??    ri = 3    wi = 8    pos = 900
3596 // HRL = 4+    abcdefgh??    ri = 3    wi = 8    pos = 900
3597 static inline void  //
wuffs_base__token_buffer__compact_retaining(wuffs_base__token_buffer * buf,uint64_t history_retain_length)3598 wuffs_base__token_buffer__compact_retaining(wuffs_base__token_buffer* buf,
3599                                             uint64_t history_retain_length) {
3600   if (!buf || (buf->meta.ri == 0)) {
3601     return;
3602   }
3603   size_t old_ri = buf->meta.ri;
3604   size_t new_ri = (size_t)(wuffs_base__u64__min(old_ri, history_retain_length));
3605   size_t memmove_start = old_ri - new_ri;
3606   buf->meta.pos = wuffs_base__u64__sat_add(buf->meta.pos, memmove_start);
3607   size_t new_wi = buf->meta.wi - memmove_start;
3608   if ((new_wi != 0) && (memmove_start != 0)) {
3609     memmove(buf->data.ptr, buf->data.ptr + memmove_start,
3610             new_wi * sizeof(wuffs_base__token));
3611   }
3612   buf->meta.wi = new_wi;
3613   buf->meta.ri = new_ri;
3614 }
3615 
3616 static inline uint64_t  //
wuffs_base__token_buffer__reader_length(const wuffs_base__token_buffer * buf)3617 wuffs_base__token_buffer__reader_length(const wuffs_base__token_buffer* buf) {
3618   return buf ? buf->meta.wi - buf->meta.ri : 0;
3619 }
3620 
3621 static inline wuffs_base__token*  //
wuffs_base__token_buffer__reader_pointer(const wuffs_base__token_buffer * buf)3622 wuffs_base__token_buffer__reader_pointer(const wuffs_base__token_buffer* buf) {
3623   return buf ? (buf->data.ptr + buf->meta.ri) : NULL;
3624 }
3625 
3626 static inline wuffs_base__slice_token  //
wuffs_base__token_buffer__reader_slice(const wuffs_base__token_buffer * buf)3627 wuffs_base__token_buffer__reader_slice(const wuffs_base__token_buffer* buf) {
3628   return buf ? wuffs_base__make_slice_token(buf->data.ptr + buf->meta.ri,
3629                                             buf->meta.wi - buf->meta.ri)
3630              : wuffs_base__empty_slice_token();
3631 }
3632 
3633 static inline uint64_t  //
wuffs_base__token_buffer__reader_token_position(const wuffs_base__token_buffer * buf)3634 wuffs_base__token_buffer__reader_token_position(
3635     const wuffs_base__token_buffer* buf) {
3636   return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.ri) : 0;
3637 }
3638 
3639 static inline uint64_t  //
wuffs_base__token_buffer__writer_length(const wuffs_base__token_buffer * buf)3640 wuffs_base__token_buffer__writer_length(const wuffs_base__token_buffer* buf) {
3641   return buf ? buf->data.len - buf->meta.wi : 0;
3642 }
3643 
3644 static inline wuffs_base__token*  //
wuffs_base__token_buffer__writer_pointer(const wuffs_base__token_buffer * buf)3645 wuffs_base__token_buffer__writer_pointer(const wuffs_base__token_buffer* buf) {
3646   return buf ? (buf->data.ptr + buf->meta.wi) : NULL;
3647 }
3648 
3649 static inline wuffs_base__slice_token  //
wuffs_base__token_buffer__writer_slice(const wuffs_base__token_buffer * buf)3650 wuffs_base__token_buffer__writer_slice(const wuffs_base__token_buffer* buf) {
3651   return buf ? wuffs_base__make_slice_token(buf->data.ptr + buf->meta.wi,
3652                                             buf->data.len - buf->meta.wi)
3653              : wuffs_base__empty_slice_token();
3654 }
3655 
3656 static inline uint64_t  //
wuffs_base__token_buffer__writer_token_position(const wuffs_base__token_buffer * buf)3657 wuffs_base__token_buffer__writer_token_position(
3658     const wuffs_base__token_buffer* buf) {
3659   return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.wi) : 0;
3660 }
3661 
3662 #ifdef __cplusplus
3663 
3664 inline bool  //
is_valid()3665 wuffs_base__token_buffer::is_valid() const {
3666   return wuffs_base__token_buffer__is_valid(this);
3667 }
3668 
3669 inline void  //
compact()3670 wuffs_base__token_buffer::compact() {
3671   wuffs_base__token_buffer__compact(this);
3672 }
3673 
3674 inline void  //
compact_retaining(uint64_t history_retain_length)3675 wuffs_base__token_buffer::compact_retaining(uint64_t history_retain_length) {
3676   wuffs_base__token_buffer__compact_retaining(this, history_retain_length);
3677 }
3678 
3679 inline uint64_t  //
reader_length()3680 wuffs_base__token_buffer::reader_length() const {
3681   return wuffs_base__token_buffer__reader_length(this);
3682 }
3683 
3684 inline wuffs_base__token*  //
reader_pointer()3685 wuffs_base__token_buffer::reader_pointer() const {
3686   return wuffs_base__token_buffer__reader_pointer(this);
3687 }
3688 
3689 inline wuffs_base__slice_token  //
reader_slice()3690 wuffs_base__token_buffer::reader_slice() const {
3691   return wuffs_base__token_buffer__reader_slice(this);
3692 }
3693 
3694 inline uint64_t  //
reader_token_position()3695 wuffs_base__token_buffer::reader_token_position() const {
3696   return wuffs_base__token_buffer__reader_token_position(this);
3697 }
3698 
3699 inline uint64_t  //
writer_length()3700 wuffs_base__token_buffer::writer_length() const {
3701   return wuffs_base__token_buffer__writer_length(this);
3702 }
3703 
3704 inline wuffs_base__token*  //
writer_pointer()3705 wuffs_base__token_buffer::writer_pointer() const {
3706   return wuffs_base__token_buffer__writer_pointer(this);
3707 }
3708 
3709 inline wuffs_base__slice_token  //
writer_slice()3710 wuffs_base__token_buffer::writer_slice() const {
3711   return wuffs_base__token_buffer__writer_slice(this);
3712 }
3713 
3714 inline uint64_t  //
writer_token_position()3715 wuffs_base__token_buffer::writer_token_position() const {
3716   return wuffs_base__token_buffer__writer_token_position(this);
3717 }
3718 
3719 #endif  // __cplusplus
3720 
3721 // ---------------- Memory Allocation
3722 
3723 // The memory allocation related functions in this section aren't used by Wuffs
3724 // per se, but they may be helpful to the code that uses Wuffs.
3725 
3726 // wuffs_base__malloc_slice_uxx wraps calling a malloc-like function, except
3727 // that it takes a uint64_t number of elements instead of a size_t size in
3728 // bytes, and it returns a slice (a pointer and a length) instead of just a
3729 // pointer.
3730 //
3731 // You can pass the C stdlib's malloc as the malloc_func.
3732 //
3733 // It returns an empty slice (containing a NULL ptr field) if (num_uxx *
3734 // sizeof(uintxx_t)) would overflow SIZE_MAX.
3735 
3736 static inline wuffs_base__slice_u8  //
wuffs_base__malloc_slice_u8(void * (* malloc_func)(size_t),uint64_t num_u8)3737 wuffs_base__malloc_slice_u8(void* (*malloc_func)(size_t), uint64_t num_u8) {
3738   if (malloc_func && (num_u8 <= (SIZE_MAX / sizeof(uint8_t)))) {
3739     void* p = (*malloc_func)((size_t)(num_u8 * sizeof(uint8_t)));
3740     if (p) {
3741       return wuffs_base__make_slice_u8((uint8_t*)(p), (size_t)num_u8);
3742     }
3743   }
3744   return wuffs_base__make_slice_u8(NULL, 0);
3745 }
3746 
3747 static inline wuffs_base__slice_u16  //
wuffs_base__malloc_slice_u16(void * (* malloc_func)(size_t),uint64_t num_u16)3748 wuffs_base__malloc_slice_u16(void* (*malloc_func)(size_t), uint64_t num_u16) {
3749   if (malloc_func && (num_u16 <= (SIZE_MAX / sizeof(uint16_t)))) {
3750     void* p = (*malloc_func)((size_t)(num_u16 * sizeof(uint16_t)));
3751     if (p) {
3752       return wuffs_base__make_slice_u16((uint16_t*)(p), (size_t)num_u16);
3753     }
3754   }
3755   return wuffs_base__make_slice_u16(NULL, 0);
3756 }
3757 
3758 static inline wuffs_base__slice_u32  //
wuffs_base__malloc_slice_u32(void * (* malloc_func)(size_t),uint64_t num_u32)3759 wuffs_base__malloc_slice_u32(void* (*malloc_func)(size_t), uint64_t num_u32) {
3760   if (malloc_func && (num_u32 <= (SIZE_MAX / sizeof(uint32_t)))) {
3761     void* p = (*malloc_func)((size_t)(num_u32 * sizeof(uint32_t)));
3762     if (p) {
3763       return wuffs_base__make_slice_u32((uint32_t*)(p), (size_t)num_u32);
3764     }
3765   }
3766   return wuffs_base__make_slice_u32(NULL, 0);
3767 }
3768 
3769 static inline wuffs_base__slice_u64  //
wuffs_base__malloc_slice_u64(void * (* malloc_func)(size_t),uint64_t num_u64)3770 wuffs_base__malloc_slice_u64(void* (*malloc_func)(size_t), uint64_t num_u64) {
3771   if (malloc_func && (num_u64 <= (SIZE_MAX / sizeof(uint64_t)))) {
3772     void* p = (*malloc_func)((size_t)(num_u64 * sizeof(uint64_t)));
3773     if (p) {
3774       return wuffs_base__make_slice_u64((uint64_t*)(p), (size_t)num_u64);
3775     }
3776   }
3777   return wuffs_base__make_slice_u64(NULL, 0);
3778 }
3779 
3780 // ---------------- Images
3781 
3782 #define WUFFS_BASE__IMAGE__DIMENSION_MAX_INCL 0xFFFFFF
3783 
3784 // wuffs_base__color_u32_argb_premul is an 8 bit per channel premultiplied
3785 // Alpha, Red, Green, Blue color, as a uint32_t value. Its value is always
3786 // 0xAARRGGBB (Alpha most significant, Blue least), regardless of endianness.
3787 typedef uint32_t wuffs_base__color_u32_argb_premul;
3788 
3789 // wuffs_base__color_u32_argb_premul__is_valid returns whether c's Red, Green
3790 // and Blue channels are all less than or equal to its Alpha channel. c uses
3791 // premultiplied alpha, so 50% opaque 100% saturated red is 0x7F7F_0000 and a
3792 // value like 0x7F80_0000 is invalid.
3793 static inline bool  //
wuffs_base__color_u32_argb_premul__is_valid(wuffs_base__color_u32_argb_premul c)3794 wuffs_base__color_u32_argb_premul__is_valid(
3795     wuffs_base__color_u32_argb_premul c) {
3796   uint32_t a = 0xFF & (c >> 24);
3797   uint32_t r = 0xFF & (c >> 16);
3798   uint32_t g = 0xFF & (c >> 8);
3799   uint32_t b = 0xFF & (c >> 0);
3800   return (a >= r) && (a >= g) && (a >= b);
3801 }
3802 
3803 static inline uint16_t  //
wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(wuffs_base__color_u32_argb_premul c)3804 wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
3805     wuffs_base__color_u32_argb_premul c) {
3806   uint32_t r5 = 0xF800 & (c >> 8);
3807   uint32_t g6 = 0x07E0 & (c >> 5);
3808   uint32_t b5 = 0x001F & (c >> 3);
3809   return (uint16_t)(r5 | g6 | b5);
3810 }
3811 
3812 static inline wuffs_base__color_u32_argb_premul  //
wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(uint16_t rgb_565)3813 wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(uint16_t rgb_565) {
3814   uint32_t b5 = 0x1F & (rgb_565 >> 0);
3815   uint32_t b = (b5 << 3) | (b5 >> 2);
3816   uint32_t g6 = 0x3F & (rgb_565 >> 5);
3817   uint32_t g = (g6 << 2) | (g6 >> 4);
3818   uint32_t r5 = 0x1F & (rgb_565 >> 11);
3819   uint32_t r = (r5 << 3) | (r5 >> 2);
3820   return 0xFF000000 | (r << 16) | (g << 8) | (b << 0);
3821 }
3822 
3823 static inline uint8_t  //
wuffs_base__color_u32_argb_premul__as__color_u8_gray(wuffs_base__color_u32_argb_premul c)3824 wuffs_base__color_u32_argb_premul__as__color_u8_gray(
3825     wuffs_base__color_u32_argb_premul c) {
3826   // Work in 16-bit color.
3827   uint32_t cr = 0x101 * (0xFF & (c >> 16));
3828   uint32_t cg = 0x101 * (0xFF & (c >> 8));
3829   uint32_t cb = 0x101 * (0xFF & (c >> 0));
3830 
3831   // These coefficients (the fractions 0.299, 0.587 and 0.114) are the same
3832   // as those given by the JFIF specification.
3833   //
3834   // Note that 19595 + 38470 + 7471 equals 65536, also known as (1 << 16). We
3835   // shift by 24, not just by 16, because the return value is 8-bit color, not
3836   // 16-bit color.
3837   uint32_t weighted_average = (19595 * cr) + (38470 * cg) + (7471 * cb) + 32768;
3838   return (uint8_t)(weighted_average >> 24);
3839 }
3840 
3841 static inline uint16_t  //
wuffs_base__color_u32_argb_premul__as__color_u16_gray(wuffs_base__color_u32_argb_premul c)3842 wuffs_base__color_u32_argb_premul__as__color_u16_gray(
3843     wuffs_base__color_u32_argb_premul c) {
3844   // Work in 16-bit color.
3845   uint32_t cr = 0x101 * (0xFF & (c >> 16));
3846   uint32_t cg = 0x101 * (0xFF & (c >> 8));
3847   uint32_t cb = 0x101 * (0xFF & (c >> 0));
3848 
3849   // These coefficients (the fractions 0.299, 0.587 and 0.114) are the same
3850   // as those given by the JFIF specification.
3851   //
3852   // Note that 19595 + 38470 + 7471 equals 65536, also known as (1 << 16).
3853   uint32_t weighted_average = (19595 * cr) + (38470 * cg) + (7471 * cb) + 32768;
3854   return (uint16_t)(weighted_average >> 16);
3855 }
3856 
3857 // wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul converts
3858 // from non-premultiplied alpha to premultiplied alpha.
3859 static inline wuffs_base__color_u32_argb_premul  //
wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(uint32_t argb_nonpremul)3860 wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
3861     uint32_t argb_nonpremul) {
3862   // Multiplying by 0x101 (twice, once for alpha and once for color) converts
3863   // from 8-bit to 16-bit color. Shifting right by 8 undoes that.
3864   //
3865   // Working in the higher bit depth can produce slightly different (and
3866   // arguably slightly more accurate) results. For example, given 8-bit blue
3867   // and alpha of 0x80 and 0x81:
3868   //
3869   //  - ((0x80   * 0x81  ) / 0xFF  )      = 0x40        = 0x40
3870   //  - ((0x8080 * 0x8181) / 0xFFFF) >> 8 = 0x4101 >> 8 = 0x41
3871   uint32_t a = 0xFF & (argb_nonpremul >> 24);
3872   uint32_t a16 = a * (0x101 * 0x101);
3873 
3874   uint32_t r = 0xFF & (argb_nonpremul >> 16);
3875   r = ((r * a16) / 0xFFFF) >> 8;
3876   uint32_t g = 0xFF & (argb_nonpremul >> 8);
3877   g = ((g * a16) / 0xFFFF) >> 8;
3878   uint32_t b = 0xFF & (argb_nonpremul >> 0);
3879   b = ((b * a16) / 0xFFFF) >> 8;
3880 
3881   return (a << 24) | (r << 16) | (g << 8) | (b << 0);
3882 }
3883 
3884 // wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul converts
3885 // from premultiplied alpha to non-premultiplied alpha.
3886 static inline uint32_t  //
wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(wuffs_base__color_u32_argb_premul c)3887 wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
3888     wuffs_base__color_u32_argb_premul c) {
3889   uint32_t a = 0xFF & (c >> 24);
3890   if (a == 0xFF) {
3891     return c;
3892   } else if (a == 0) {
3893     return 0;
3894   }
3895   uint32_t a16 = a * 0x101;
3896 
3897   uint32_t r = 0xFF & (c >> 16);
3898   r = ((r * (0x101 * 0xFFFF)) / a16) >> 8;
3899   uint32_t g = 0xFF & (c >> 8);
3900   g = ((g * (0x101 * 0xFFFF)) / a16) >> 8;
3901   uint32_t b = 0xFF & (c >> 0);
3902   b = ((b * (0x101 * 0xFFFF)) / a16) >> 8;
3903 
3904   return (a << 24) | (r << 16) | (g << 8) | (b << 0);
3905 }
3906 
3907 // wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul converts
3908 // from 4x16LE non-premultiplied alpha to 4x8 premultiplied alpha.
3909 static inline wuffs_base__color_u32_argb_premul  //
wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(uint64_t argb_nonpremul)3910 wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(
3911     uint64_t argb_nonpremul) {
3912   uint32_t a16 = ((uint32_t)(0xFFFF & (argb_nonpremul >> 48)));
3913 
3914   uint32_t r16 = ((uint32_t)(0xFFFF & (argb_nonpremul >> 32)));
3915   r16 = (r16 * a16) / 0xFFFF;
3916   uint32_t g16 = ((uint32_t)(0xFFFF & (argb_nonpremul >> 16)));
3917   g16 = (g16 * a16) / 0xFFFF;
3918   uint32_t b16 = ((uint32_t)(0xFFFF & (argb_nonpremul >> 0)));
3919   b16 = (b16 * a16) / 0xFFFF;
3920 
3921   return ((a16 >> 8) << 24) | ((r16 >> 8) << 16) | ((g16 >> 8) << 8) |
3922          ((b16 >> 8) << 0);
3923 }
3924 
3925 // wuffs_base__color_u32_argb_premul__as__color_u64_argb_nonpremul converts
3926 // from 4x8 premultiplied alpha to 4x16LE non-premultiplied alpha.
3927 static inline uint64_t  //
wuffs_base__color_u32_argb_premul__as__color_u64_argb_nonpremul(wuffs_base__color_u32_argb_premul c)3928 wuffs_base__color_u32_argb_premul__as__color_u64_argb_nonpremul(
3929     wuffs_base__color_u32_argb_premul c) {
3930   uint32_t a = 0xFF & (c >> 24);
3931   if (a == 0xFF) {
3932     uint64_t r16 = 0x101 * (0xFF & (c >> 16));
3933     uint64_t g16 = 0x101 * (0xFF & (c >> 8));
3934     uint64_t b16 = 0x101 * (0xFF & (c >> 0));
3935     return 0xFFFF000000000000u | (r16 << 32) | (g16 << 16) | (b16 << 0);
3936   } else if (a == 0) {
3937     return 0;
3938   }
3939   uint64_t a16 = a * 0x101;
3940 
3941   uint64_t r = 0xFF & (c >> 16);
3942   uint64_t r16 = (r * (0x101 * 0xFFFF)) / a16;
3943   uint64_t g = 0xFF & (c >> 8);
3944   uint64_t g16 = (g * (0x101 * 0xFFFF)) / a16;
3945   uint64_t b = 0xFF & (c >> 0);
3946   uint64_t b16 = (b * (0x101 * 0xFFFF)) / a16;
3947 
3948   return (a16 << 48) | (r16 << 32) | (g16 << 16) | (b16 << 0);
3949 }
3950 
3951 static inline uint64_t  //
wuffs_base__color_u32__as__color_u64(uint32_t c)3952 wuffs_base__color_u32__as__color_u64(uint32_t c) {
3953   uint64_t a16 = 0x101 * (0xFF & (c >> 24));
3954   uint64_t r16 = 0x101 * (0xFF & (c >> 16));
3955   uint64_t g16 = 0x101 * (0xFF & (c >> 8));
3956   uint64_t b16 = 0x101 * (0xFF & (c >> 0));
3957   return (a16 << 48) | (r16 << 32) | (g16 << 16) | (b16 << 0);
3958 }
3959 
3960 static inline uint32_t  //
wuffs_base__color_u64__as__color_u32(uint64_t c)3961 wuffs_base__color_u64__as__color_u32(uint64_t c) {
3962   uint32_t a = ((uint32_t)(0xFF & (c >> 56)));
3963   uint32_t r = ((uint32_t)(0xFF & (c >> 40)));
3964   uint32_t g = ((uint32_t)(0xFF & (c >> 24)));
3965   uint32_t b = ((uint32_t)(0xFF & (c >> 8)));
3966   return (a << 24) | (r << 16) | (g << 8) | (b << 0);
3967 }
3968 
3969 // wuffs_base__color_ycc__as__color_u32 converts from YCbCr to 0xAARRGGBB. The
3970 // alpha bits are always 0xFF.
3971 static inline wuffs_base__color_u32_argb_premul  //
wuffs_base__color_ycc__as__color_u32(uint8_t yy,uint8_t cb,uint8_t cr)3972 wuffs_base__color_ycc__as__color_u32(uint8_t yy, uint8_t cb, uint8_t cr) {
3973   // Work in 16.16 fixed point arithmetic (so that 'one half' is (1 << 15)) and
3974   // bias the chroma values by 0x80.
3975   uint32_t yy32 = (((uint32_t)yy) << 16) | (1 << 15);
3976   uint32_t cb32 = (((uint32_t)cb) - 0x80);
3977   uint32_t cr32 = (((uint32_t)cr) - 0x80);
3978 
3979   // The formulae:
3980   //
3981   //  R = Y                + 1.40200 * Cr
3982   //  G = Y - 0.34414 * Cb - 0.71414 * Cr
3983   //  B = Y + 1.77200 * Cb
3984   //
3985   // When scaled by 1<<16:
3986   //
3987   //  0.34414 becomes 0x0581A =  22554.
3988   //  0.71414 becomes 0x0B6D2 =  46802.
3989   //  1.40200 becomes 0x166E9 =  91881.
3990   //  1.77200 becomes 0x1C5A2 = 116130.
3991   //
3992   // Since we're working in 16.16 fixed point arithmetic, masking by 0x00FF0000
3993   // (possibly followed by a shift) gives the relevant 8 bits per channel.
3994   //
3995   // However, we need to saturate for overflow (above 0x00FFFFFF, but not so
3996   // high that the MSB Most Significant Bit is set) or for underflow (below
3997   // 0x00000000 as int32_t, which means that the MSB is set as uint32_t). In
3998   // both cases, some of the high 8 bits (bits 24 ..= 31) will be set.
3999   //
4000   // "((uint32_t)(((int32_t)x) >> 31))" just replicates x's MSB across all 32
4001   // bits. Prepending that with "~" inverts those bits. Thus, "~(etc)" is
4002   // either 0xFFFFFFFF (for overflow) or 0x00000000 (for underflow).
4003   uint32_t rr32 = yy32 + (0x166E9 * cr32);
4004   uint32_t gg32 = yy32 - (0x0581A * cb32) - (0x0B6D2 * cr32);
4005   uint32_t bb32 = yy32 + (0x1C5A2 * cb32);
4006   if (rr32 >> 24) {
4007     rr32 = ~((uint32_t)(((int32_t)rr32) >> 31));
4008   }
4009   if (gg32 >> 24) {
4010     gg32 = ~((uint32_t)(((int32_t)gg32) >> 31));
4011   }
4012   if (bb32 >> 24) {
4013     bb32 = ~((uint32_t)(((int32_t)bb32) >> 31));
4014   }
4015   return 0xFF000000 |                  //
4016          ((0x00FF0000 & rr32) >> 0) |  //
4017          ((0x00FF0000 & gg32) >> 8) |  //
4018          ((0x00FF0000 & bb32) >> 16);
4019 }
4020 
4021 // wuffs_base__color_ycc__as__color_u32_abgr is like
4022 // wuffs_base__color_ycc__as__color_u32 but the uint32_t returned is in
4023 // 0xAABBGGRR order, not 0xAARRGGBB.
4024 static inline uint32_t  //
wuffs_base__color_ycc__as__color_u32_abgr(uint8_t yy,uint8_t cb,uint8_t cr)4025 wuffs_base__color_ycc__as__color_u32_abgr(uint8_t yy, uint8_t cb, uint8_t cr) {
4026   uint32_t yy32 = (((uint32_t)yy) << 16) | (1 << 15);
4027   uint32_t cb32 = (((uint32_t)cb) - 0x80);
4028   uint32_t cr32 = (((uint32_t)cr) - 0x80);
4029   uint32_t rr32 = yy32 + (0x166E9 * cr32);
4030   uint32_t gg32 = yy32 - (0x0581A * cb32) - (0x0B6D2 * cr32);
4031   uint32_t bb32 = yy32 + (0x1C5A2 * cb32);
4032   if (rr32 >> 24) {
4033     rr32 = ~((uint32_t)(((int32_t)rr32) >> 31));
4034   }
4035   if (gg32 >> 24) {
4036     gg32 = ~((uint32_t)(((int32_t)gg32) >> 31));
4037   }
4038   if (bb32 >> 24) {
4039     bb32 = ~((uint32_t)(((int32_t)bb32) >> 31));
4040   }
4041   return 0xFF000000 |                  //
4042          ((0x00FF0000 & bb32) >> 0) |  //
4043          ((0x00FF0000 & gg32) >> 8) |  //
4044          ((0x00FF0000 & rr32) >> 16);
4045 }
4046 
4047 // --------
4048 
4049 typedef uint8_t wuffs_base__pixel_blend;
4050 
4051 // wuffs_base__pixel_blend encodes how to blend source and destination pixels,
4052 // accounting for transparency. It encompasses the Porter-Duff compositing
4053 // operators as well as the other blending modes defined by PDF.
4054 //
4055 // TODO: implement the other modes.
4056 #define WUFFS_BASE__PIXEL_BLEND__SRC ((wuffs_base__pixel_blend)0)
4057 #define WUFFS_BASE__PIXEL_BLEND__SRC_OVER ((wuffs_base__pixel_blend)1)
4058 
4059 // --------
4060 
4061 // wuffs_base__pixel_alpha_transparency is a pixel format's alpha channel
4062 // model. It is a property of the pixel format in general, not of a specific
4063 // pixel. An RGBA pixel format (with alpha) can still have fully opaque pixels.
4064 typedef uint32_t wuffs_base__pixel_alpha_transparency;
4065 
4066 #define WUFFS_BASE__PIXEL_ALPHA_TRANSPARENCY__OPAQUE 0
4067 #define WUFFS_BASE__PIXEL_ALPHA_TRANSPARENCY__NONPREMULTIPLIED_ALPHA 1
4068 #define WUFFS_BASE__PIXEL_ALPHA_TRANSPARENCY__PREMULTIPLIED_ALPHA 2
4069 #define WUFFS_BASE__PIXEL_ALPHA_TRANSPARENCY__BINARY_ALPHA 3
4070 
4071 // --------
4072 
4073 // Deprecated: use WUFFS_BASE__PIXEL_FORMAT__NUM_PLANES_MAX_INCL.
4074 #define WUFFS_BASE__PIXEL_FORMAT__NUM_PLANES_MAX 4
4075 
4076 #define WUFFS_BASE__PIXEL_FORMAT__NUM_PLANES_MAX_INCL 4
4077 
4078 #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__INDEX_PLANE 0
4079 #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE 3
4080 
4081 // A palette is 256 entries × 4 bytes per entry (e.g. BGRA).
4082 #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH 1024
4083 
4084 // wuffs_base__pixel_format encodes the format of the bytes that constitute an
4085 // image frame's pixel data.
4086 //
4087 // See https://github.com/google/wuffs/blob/main/doc/note/pixel-formats.md
4088 //
4089 // Do not manipulate its bits directly; they are private implementation
4090 // details. Use methods such as wuffs_base__pixel_format__num_planes instead.
4091 typedef struct wuffs_base__pixel_format__struct {
4092   uint32_t repr;
4093 
4094 #ifdef __cplusplus
4095   inline bool is_valid() const;
4096   inline uint32_t bits_per_pixel() const;
4097   inline bool is_direct() const;
4098   inline bool is_indexed() const;
4099   inline bool is_interleaved() const;
4100   inline bool is_planar() const;
4101   inline uint32_t num_planes() const;
4102   inline wuffs_base__pixel_alpha_transparency transparency() const;
4103 #endif  // __cplusplus
4104 
4105 } wuffs_base__pixel_format;
4106 
4107 static inline wuffs_base__pixel_format  //
wuffs_base__make_pixel_format(uint32_t repr)4108 wuffs_base__make_pixel_format(uint32_t repr) {
4109   wuffs_base__pixel_format f;
4110   f.repr = repr;
4111   return f;
4112 }
4113 
4114 // Common 8-bit-depth pixel formats. This list is not exhaustive; not all valid
4115 // wuffs_base__pixel_format values are present.
4116 
4117 #define WUFFS_BASE__PIXEL_FORMAT__INVALID 0x00000000
4118 
4119 #define WUFFS_BASE__PIXEL_FORMAT__A 0x02000008
4120 
4121 #define WUFFS_BASE__PIXEL_FORMAT__Y 0x20000008
4122 #define WUFFS_BASE__PIXEL_FORMAT__Y_16LE 0x2000000B
4123 #define WUFFS_BASE__PIXEL_FORMAT__Y_16BE 0x2010000B
4124 #define WUFFS_BASE__PIXEL_FORMAT__YA_NONPREMUL 0x21000008
4125 #define WUFFS_BASE__PIXEL_FORMAT__YA_PREMUL 0x22000008
4126 
4127 #define WUFFS_BASE__PIXEL_FORMAT__YCBCR 0x40020888
4128 #define WUFFS_BASE__PIXEL_FORMAT__YCBCRA_NONPREMUL 0x41038888
4129 #define WUFFS_BASE__PIXEL_FORMAT__YCBCRK 0x50038888
4130 
4131 #define WUFFS_BASE__PIXEL_FORMAT__YCOCG 0x60020888
4132 #define WUFFS_BASE__PIXEL_FORMAT__YCOCGA_NONPREMUL 0x61038888
4133 #define WUFFS_BASE__PIXEL_FORMAT__YCOCGK 0x70038888
4134 
4135 #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL 0x81040008
4136 #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL 0x82040008
4137 #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY 0x83040008
4138 
4139 #define WUFFS_BASE__PIXEL_FORMAT__BGR_565 0x80000565
4140 #define WUFFS_BASE__PIXEL_FORMAT__BGR 0x80000888
4141 #define WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL 0x81008888
4142 #define WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE 0x8100BBBB
4143 #define WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL 0x82008888
4144 #define WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE 0x8200BBBB
4145 #define WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY 0x83008888
4146 #define WUFFS_BASE__PIXEL_FORMAT__BGRX 0x90008888
4147 
4148 #define WUFFS_BASE__PIXEL_FORMAT__RGB 0xA0000888
4149 #define WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL 0xA1008888
4150 #define WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL_4X16LE 0xA100BBBB
4151 #define WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL 0xA2008888
4152 #define WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL_4X16LE 0xA200BBBB
4153 #define WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY 0xA3008888
4154 #define WUFFS_BASE__PIXEL_FORMAT__RGBX 0xB0008888
4155 
4156 #define WUFFS_BASE__PIXEL_FORMAT__CMY 0xC0020888
4157 #define WUFFS_BASE__PIXEL_FORMAT__CMYK 0xD0038888
4158 
4159 extern const uint32_t wuffs_base__pixel_format__bits_per_channel[16];
4160 
4161 static inline bool  //
wuffs_base__pixel_format__is_valid(const wuffs_base__pixel_format * f)4162 wuffs_base__pixel_format__is_valid(const wuffs_base__pixel_format* f) {
4163   return f->repr != 0;
4164 }
4165 
4166 // wuffs_base__pixel_format__bits_per_pixel returns the number of bits per
4167 // pixel for interleaved pixel formats, and returns 0 for planar pixel formats.
4168 static inline uint32_t  //
wuffs_base__pixel_format__bits_per_pixel(const wuffs_base__pixel_format * f)4169 wuffs_base__pixel_format__bits_per_pixel(const wuffs_base__pixel_format* f) {
4170   if (((f->repr >> 16) & 0x03) != 0) {
4171     return 0;
4172   }
4173   return wuffs_base__pixel_format__bits_per_channel[0x0F & (f->repr >> 0)] +
4174          wuffs_base__pixel_format__bits_per_channel[0x0F & (f->repr >> 4)] +
4175          wuffs_base__pixel_format__bits_per_channel[0x0F & (f->repr >> 8)] +
4176          wuffs_base__pixel_format__bits_per_channel[0x0F & (f->repr >> 12)];
4177 }
4178 
4179 static inline bool  //
wuffs_base__pixel_format__is_direct(const wuffs_base__pixel_format * f)4180 wuffs_base__pixel_format__is_direct(const wuffs_base__pixel_format* f) {
4181   return ((f->repr >> 18) & 0x01) == 0;
4182 }
4183 
4184 static inline bool  //
wuffs_base__pixel_format__is_indexed(const wuffs_base__pixel_format * f)4185 wuffs_base__pixel_format__is_indexed(const wuffs_base__pixel_format* f) {
4186   return ((f->repr >> 18) & 0x01) != 0;
4187 }
4188 
4189 static inline bool  //
wuffs_base__pixel_format__is_interleaved(const wuffs_base__pixel_format * f)4190 wuffs_base__pixel_format__is_interleaved(const wuffs_base__pixel_format* f) {
4191   return ((f->repr >> 16) & 0x03) == 0;
4192 }
4193 
4194 static inline bool  //
wuffs_base__pixel_format__is_planar(const wuffs_base__pixel_format * f)4195 wuffs_base__pixel_format__is_planar(const wuffs_base__pixel_format* f) {
4196   return ((f->repr >> 16) & 0x03) != 0;
4197 }
4198 
4199 static inline uint32_t  //
wuffs_base__pixel_format__num_planes(const wuffs_base__pixel_format * f)4200 wuffs_base__pixel_format__num_planes(const wuffs_base__pixel_format* f) {
4201   return ((f->repr >> 16) & 0x03) + 1;
4202 }
4203 
4204 static inline wuffs_base__pixel_alpha_transparency  //
wuffs_base__pixel_format__transparency(const wuffs_base__pixel_format * f)4205 wuffs_base__pixel_format__transparency(const wuffs_base__pixel_format* f) {
4206   return (wuffs_base__pixel_alpha_transparency)((f->repr >> 24) & 0x03);
4207 }
4208 
4209 #ifdef __cplusplus
4210 
4211 inline bool  //
is_valid()4212 wuffs_base__pixel_format::is_valid() const {
4213   return wuffs_base__pixel_format__is_valid(this);
4214 }
4215 
4216 inline uint32_t  //
bits_per_pixel()4217 wuffs_base__pixel_format::bits_per_pixel() const {
4218   return wuffs_base__pixel_format__bits_per_pixel(this);
4219 }
4220 
4221 inline bool  //
is_direct()4222 wuffs_base__pixel_format::is_direct() const {
4223   return wuffs_base__pixel_format__is_direct(this);
4224 }
4225 
4226 inline bool  //
is_indexed()4227 wuffs_base__pixel_format::is_indexed() const {
4228   return wuffs_base__pixel_format__is_indexed(this);
4229 }
4230 
4231 inline bool  //
is_interleaved()4232 wuffs_base__pixel_format::is_interleaved() const {
4233   return wuffs_base__pixel_format__is_interleaved(this);
4234 }
4235 
4236 inline bool  //
is_planar()4237 wuffs_base__pixel_format::is_planar() const {
4238   return wuffs_base__pixel_format__is_planar(this);
4239 }
4240 
4241 inline uint32_t  //
num_planes()4242 wuffs_base__pixel_format::num_planes() const {
4243   return wuffs_base__pixel_format__num_planes(this);
4244 }
4245 
4246 inline wuffs_base__pixel_alpha_transparency  //
transparency()4247 wuffs_base__pixel_format::transparency() const {
4248   return wuffs_base__pixel_format__transparency(this);
4249 }
4250 
4251 #endif  // __cplusplus
4252 
4253 // --------
4254 
4255 // wuffs_base__pixel_subsampling encodes whether sample values cover one pixel
4256 // or cover multiple pixels.
4257 //
4258 // See https://github.com/google/wuffs/blob/main/doc/note/pixel-subsampling.md
4259 //
4260 // Do not manipulate its bits directly; they are private implementation
4261 // details. Use methods such as wuffs_base__pixel_subsampling__bias_x instead.
4262 typedef struct wuffs_base__pixel_subsampling__struct {
4263   uint32_t repr;
4264 
4265 #ifdef __cplusplus
4266   inline uint32_t bias_x(uint32_t plane) const;
4267   inline uint32_t denominator_x(uint32_t plane) const;
4268   inline uint32_t bias_y(uint32_t plane) const;
4269   inline uint32_t denominator_y(uint32_t plane) const;
4270 #endif  // __cplusplus
4271 
4272 } wuffs_base__pixel_subsampling;
4273 
4274 static inline wuffs_base__pixel_subsampling  //
wuffs_base__make_pixel_subsampling(uint32_t repr)4275 wuffs_base__make_pixel_subsampling(uint32_t repr) {
4276   wuffs_base__pixel_subsampling s;
4277   s.repr = repr;
4278   return s;
4279 }
4280 
4281 #define WUFFS_BASE__PIXEL_SUBSAMPLING__NONE 0x00000000
4282 
4283 #define WUFFS_BASE__PIXEL_SUBSAMPLING__444 0x000000
4284 #define WUFFS_BASE__PIXEL_SUBSAMPLING__440 0x010100
4285 #define WUFFS_BASE__PIXEL_SUBSAMPLING__422 0x101000
4286 #define WUFFS_BASE__PIXEL_SUBSAMPLING__420 0x111100
4287 #define WUFFS_BASE__PIXEL_SUBSAMPLING__411 0x303000
4288 #define WUFFS_BASE__PIXEL_SUBSAMPLING__410 0x313100
4289 
4290 static inline uint32_t  //
wuffs_base__pixel_subsampling__bias_x(const wuffs_base__pixel_subsampling * s,uint32_t plane)4291 wuffs_base__pixel_subsampling__bias_x(const wuffs_base__pixel_subsampling* s,
4292                                       uint32_t plane) {
4293   uint32_t shift = ((plane & 0x03) * 8) + 6;
4294   return (s->repr >> shift) & 0x03;
4295 }
4296 
4297 static inline uint32_t  //
wuffs_base__pixel_subsampling__denominator_x(const wuffs_base__pixel_subsampling * s,uint32_t plane)4298 wuffs_base__pixel_subsampling__denominator_x(
4299     const wuffs_base__pixel_subsampling* s,
4300     uint32_t plane) {
4301   uint32_t shift = ((plane & 0x03) * 8) + 4;
4302   return ((s->repr >> shift) & 0x03) + 1;
4303 }
4304 
4305 static inline uint32_t  //
wuffs_base__pixel_subsampling__bias_y(const wuffs_base__pixel_subsampling * s,uint32_t plane)4306 wuffs_base__pixel_subsampling__bias_y(const wuffs_base__pixel_subsampling* s,
4307                                       uint32_t plane) {
4308   uint32_t shift = ((plane & 0x03) * 8) + 2;
4309   return (s->repr >> shift) & 0x03;
4310 }
4311 
4312 static inline uint32_t  //
wuffs_base__pixel_subsampling__denominator_y(const wuffs_base__pixel_subsampling * s,uint32_t plane)4313 wuffs_base__pixel_subsampling__denominator_y(
4314     const wuffs_base__pixel_subsampling* s,
4315     uint32_t plane) {
4316   uint32_t shift = ((plane & 0x03) * 8) + 0;
4317   return ((s->repr >> shift) & 0x03) + 1;
4318 }
4319 
4320 #ifdef __cplusplus
4321 
4322 inline uint32_t  //
bias_x(uint32_t plane)4323 wuffs_base__pixel_subsampling::bias_x(uint32_t plane) const {
4324   return wuffs_base__pixel_subsampling__bias_x(this, plane);
4325 }
4326 
4327 inline uint32_t  //
denominator_x(uint32_t plane)4328 wuffs_base__pixel_subsampling::denominator_x(uint32_t plane) const {
4329   return wuffs_base__pixel_subsampling__denominator_x(this, plane);
4330 }
4331 
4332 inline uint32_t  //
bias_y(uint32_t plane)4333 wuffs_base__pixel_subsampling::bias_y(uint32_t plane) const {
4334   return wuffs_base__pixel_subsampling__bias_y(this, plane);
4335 }
4336 
4337 inline uint32_t  //
denominator_y(uint32_t plane)4338 wuffs_base__pixel_subsampling::denominator_y(uint32_t plane) const {
4339   return wuffs_base__pixel_subsampling__denominator_y(this, plane);
4340 }
4341 
4342 #endif  // __cplusplus
4343 
4344 // --------
4345 
4346 typedef struct wuffs_base__pixel_config__struct {
4347   // Do not access the private_impl's fields directly. There is no API/ABI
4348   // compatibility or safety guarantee if you do so.
4349   struct {
4350     wuffs_base__pixel_format pixfmt;
4351     wuffs_base__pixel_subsampling pixsub;
4352     uint32_t width;
4353     uint32_t height;
4354   } private_impl;
4355 
4356 #ifdef __cplusplus
4357   inline void set(uint32_t pixfmt_repr,
4358                   uint32_t pixsub_repr,
4359                   uint32_t width,
4360                   uint32_t height);
4361   inline void invalidate();
4362   inline bool is_valid() const;
4363   inline wuffs_base__pixel_format pixel_format() const;
4364   inline wuffs_base__pixel_subsampling pixel_subsampling() const;
4365   inline wuffs_base__rect_ie_u32 bounds() const;
4366   inline uint32_t width() const;
4367   inline uint32_t height() const;
4368   inline uint64_t pixbuf_len() const;
4369 #endif  // __cplusplus
4370 
4371 } wuffs_base__pixel_config;
4372 
4373 static inline wuffs_base__pixel_config  //
wuffs_base__null_pixel_config(void)4374 wuffs_base__null_pixel_config(void) {
4375   wuffs_base__pixel_config ret;
4376   ret.private_impl.pixfmt.repr = 0;
4377   ret.private_impl.pixsub.repr = 0;
4378   ret.private_impl.width = 0;
4379   ret.private_impl.height = 0;
4380   return ret;
4381 }
4382 
4383 // TODO: Should this function return bool? An error type?
4384 static inline void  //
wuffs_base__pixel_config__set(wuffs_base__pixel_config * c,uint32_t pixfmt_repr,uint32_t pixsub_repr,uint32_t width,uint32_t height)4385 wuffs_base__pixel_config__set(wuffs_base__pixel_config* c,
4386                               uint32_t pixfmt_repr,
4387                               uint32_t pixsub_repr,
4388                               uint32_t width,
4389                               uint32_t height) {
4390   if (!c) {
4391     return;
4392   }
4393   if (pixfmt_repr) {
4394     uint64_t wh = ((uint64_t)width) * ((uint64_t)height);
4395     // TODO: handle things other than 1 byte per pixel.
4396     if (wh <= ((uint64_t)SIZE_MAX)) {
4397       c->private_impl.pixfmt.repr = pixfmt_repr;
4398       c->private_impl.pixsub.repr = pixsub_repr;
4399       c->private_impl.width = width;
4400       c->private_impl.height = height;
4401       return;
4402     }
4403   }
4404 
4405   c->private_impl.pixfmt.repr = 0;
4406   c->private_impl.pixsub.repr = 0;
4407   c->private_impl.width = 0;
4408   c->private_impl.height = 0;
4409 }
4410 
4411 static inline void  //
wuffs_base__pixel_config__invalidate(wuffs_base__pixel_config * c)4412 wuffs_base__pixel_config__invalidate(wuffs_base__pixel_config* c) {
4413   if (c) {
4414     c->private_impl.pixfmt.repr = 0;
4415     c->private_impl.pixsub.repr = 0;
4416     c->private_impl.width = 0;
4417     c->private_impl.height = 0;
4418   }
4419 }
4420 
4421 static inline bool  //
wuffs_base__pixel_config__is_valid(const wuffs_base__pixel_config * c)4422 wuffs_base__pixel_config__is_valid(const wuffs_base__pixel_config* c) {
4423   return c && c->private_impl.pixfmt.repr;
4424 }
4425 
4426 static inline wuffs_base__pixel_format  //
wuffs_base__pixel_config__pixel_format(const wuffs_base__pixel_config * c)4427 wuffs_base__pixel_config__pixel_format(const wuffs_base__pixel_config* c) {
4428   return c ? c->private_impl.pixfmt : wuffs_base__make_pixel_format(0);
4429 }
4430 
4431 static inline wuffs_base__pixel_subsampling  //
wuffs_base__pixel_config__pixel_subsampling(const wuffs_base__pixel_config * c)4432 wuffs_base__pixel_config__pixel_subsampling(const wuffs_base__pixel_config* c) {
4433   return c ? c->private_impl.pixsub : wuffs_base__make_pixel_subsampling(0);
4434 }
4435 
4436 static inline wuffs_base__rect_ie_u32  //
wuffs_base__pixel_config__bounds(const wuffs_base__pixel_config * c)4437 wuffs_base__pixel_config__bounds(const wuffs_base__pixel_config* c) {
4438   if (c) {
4439     wuffs_base__rect_ie_u32 ret;
4440     ret.min_incl_x = 0;
4441     ret.min_incl_y = 0;
4442     ret.max_excl_x = c->private_impl.width;
4443     ret.max_excl_y = c->private_impl.height;
4444     return ret;
4445   }
4446 
4447   wuffs_base__rect_ie_u32 ret;
4448   ret.min_incl_x = 0;
4449   ret.min_incl_y = 0;
4450   ret.max_excl_x = 0;
4451   ret.max_excl_y = 0;
4452   return ret;
4453 }
4454 
4455 static inline uint32_t  //
wuffs_base__pixel_config__width(const wuffs_base__pixel_config * c)4456 wuffs_base__pixel_config__width(const wuffs_base__pixel_config* c) {
4457   return c ? c->private_impl.width : 0;
4458 }
4459 
4460 static inline uint32_t  //
wuffs_base__pixel_config__height(const wuffs_base__pixel_config * c)4461 wuffs_base__pixel_config__height(const wuffs_base__pixel_config* c) {
4462   return c ? c->private_impl.height : 0;
4463 }
4464 
4465 // TODO: this is the right API for planar (not interleaved) pixbufs? Should it
4466 // allow decoding into a color model different from the format's intrinsic one?
4467 // For example, decoding a JPEG image straight to RGBA instead of to YCbCr?
4468 static inline uint64_t  //
wuffs_base__pixel_config__pixbuf_len(const wuffs_base__pixel_config * c)4469 wuffs_base__pixel_config__pixbuf_len(const wuffs_base__pixel_config* c) {
4470   if (!c) {
4471     return 0;
4472   }
4473   if (wuffs_base__pixel_format__is_planar(&c->private_impl.pixfmt)) {
4474     // TODO: support planar pixel formats, concious of pixel subsampling.
4475     return 0;
4476   }
4477   uint32_t bits_per_pixel =
4478       wuffs_base__pixel_format__bits_per_pixel(&c->private_impl.pixfmt);
4479   if ((bits_per_pixel == 0) || ((bits_per_pixel % 8) != 0)) {
4480     // TODO: support fraction-of-byte pixels, e.g. 1 bit per pixel?
4481     return 0;
4482   }
4483   uint64_t bytes_per_pixel = bits_per_pixel / 8;
4484 
4485   uint64_t n =
4486       ((uint64_t)c->private_impl.width) * ((uint64_t)c->private_impl.height);
4487   if (n > (UINT64_MAX / bytes_per_pixel)) {
4488     return 0;
4489   }
4490   n *= bytes_per_pixel;
4491 
4492   if (wuffs_base__pixel_format__is_indexed(&c->private_impl.pixfmt)) {
4493     if (n >
4494         (UINT64_MAX - WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH)) {
4495       return 0;
4496     }
4497     n += WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
4498   }
4499 
4500   return n;
4501 }
4502 
4503 #ifdef __cplusplus
4504 
4505 inline void  //
set(uint32_t pixfmt_repr,uint32_t pixsub_repr,uint32_t width,uint32_t height)4506 wuffs_base__pixel_config::set(uint32_t pixfmt_repr,
4507                               uint32_t pixsub_repr,
4508                               uint32_t width,
4509                               uint32_t height) {
4510   wuffs_base__pixel_config__set(this, pixfmt_repr, pixsub_repr, width, height);
4511 }
4512 
4513 inline void  //
invalidate()4514 wuffs_base__pixel_config::invalidate() {
4515   wuffs_base__pixel_config__invalidate(this);
4516 }
4517 
4518 inline bool  //
is_valid()4519 wuffs_base__pixel_config::is_valid() const {
4520   return wuffs_base__pixel_config__is_valid(this);
4521 }
4522 
4523 inline wuffs_base__pixel_format  //
pixel_format()4524 wuffs_base__pixel_config::pixel_format() const {
4525   return wuffs_base__pixel_config__pixel_format(this);
4526 }
4527 
4528 inline wuffs_base__pixel_subsampling  //
pixel_subsampling()4529 wuffs_base__pixel_config::pixel_subsampling() const {
4530   return wuffs_base__pixel_config__pixel_subsampling(this);
4531 }
4532 
4533 inline wuffs_base__rect_ie_u32  //
bounds()4534 wuffs_base__pixel_config::bounds() const {
4535   return wuffs_base__pixel_config__bounds(this);
4536 }
4537 
4538 inline uint32_t  //
width()4539 wuffs_base__pixel_config::width() const {
4540   return wuffs_base__pixel_config__width(this);
4541 }
4542 
4543 inline uint32_t  //
height()4544 wuffs_base__pixel_config::height() const {
4545   return wuffs_base__pixel_config__height(this);
4546 }
4547 
4548 inline uint64_t  //
pixbuf_len()4549 wuffs_base__pixel_config::pixbuf_len() const {
4550   return wuffs_base__pixel_config__pixbuf_len(this);
4551 }
4552 
4553 #endif  // __cplusplus
4554 
4555 // --------
4556 
4557 typedef struct wuffs_base__image_config__struct {
4558   wuffs_base__pixel_config pixcfg;
4559 
4560   // Do not access the private_impl's fields directly. There is no API/ABI
4561   // compatibility or safety guarantee if you do so.
4562   struct {
4563     uint64_t first_frame_io_position;
4564     bool first_frame_is_opaque;
4565   } private_impl;
4566 
4567 #ifdef __cplusplus
4568   inline void set(uint32_t pixfmt_repr,
4569                   uint32_t pixsub_repr,
4570                   uint32_t width,
4571                   uint32_t height,
4572                   uint64_t first_frame_io_position,
4573                   bool first_frame_is_opaque);
4574   inline void invalidate();
4575   inline bool is_valid() const;
4576   inline uint64_t first_frame_io_position() const;
4577   inline bool first_frame_is_opaque() const;
4578 #endif  // __cplusplus
4579 
4580 } wuffs_base__image_config;
4581 
4582 static inline wuffs_base__image_config  //
wuffs_base__null_image_config(void)4583 wuffs_base__null_image_config(void) {
4584   wuffs_base__image_config ret;
4585   ret.pixcfg = wuffs_base__null_pixel_config();
4586   ret.private_impl.first_frame_io_position = 0;
4587   ret.private_impl.first_frame_is_opaque = false;
4588   return ret;
4589 }
4590 
4591 // TODO: Should this function return bool? An error type?
4592 static inline void  //
wuffs_base__image_config__set(wuffs_base__image_config * c,uint32_t pixfmt_repr,uint32_t pixsub_repr,uint32_t width,uint32_t height,uint64_t first_frame_io_position,bool first_frame_is_opaque)4593 wuffs_base__image_config__set(wuffs_base__image_config* c,
4594                               uint32_t pixfmt_repr,
4595                               uint32_t pixsub_repr,
4596                               uint32_t width,
4597                               uint32_t height,
4598                               uint64_t first_frame_io_position,
4599                               bool first_frame_is_opaque) {
4600   if (!c) {
4601     return;
4602   }
4603   if (pixfmt_repr) {
4604     c->pixcfg.private_impl.pixfmt.repr = pixfmt_repr;
4605     c->pixcfg.private_impl.pixsub.repr = pixsub_repr;
4606     c->pixcfg.private_impl.width = width;
4607     c->pixcfg.private_impl.height = height;
4608     c->private_impl.first_frame_io_position = first_frame_io_position;
4609     c->private_impl.first_frame_is_opaque = first_frame_is_opaque;
4610     return;
4611   }
4612 
4613   c->pixcfg.private_impl.pixfmt.repr = 0;
4614   c->pixcfg.private_impl.pixsub.repr = 0;
4615   c->pixcfg.private_impl.width = 0;
4616   c->pixcfg.private_impl.height = 0;
4617   c->private_impl.first_frame_io_position = 0;
4618   c->private_impl.first_frame_is_opaque = 0;
4619 }
4620 
4621 static inline void  //
wuffs_base__image_config__invalidate(wuffs_base__image_config * c)4622 wuffs_base__image_config__invalidate(wuffs_base__image_config* c) {
4623   if (c) {
4624     c->pixcfg.private_impl.pixfmt.repr = 0;
4625     c->pixcfg.private_impl.pixsub.repr = 0;
4626     c->pixcfg.private_impl.width = 0;
4627     c->pixcfg.private_impl.height = 0;
4628     c->private_impl.first_frame_io_position = 0;
4629     c->private_impl.first_frame_is_opaque = 0;
4630   }
4631 }
4632 
4633 static inline bool  //
wuffs_base__image_config__is_valid(const wuffs_base__image_config * c)4634 wuffs_base__image_config__is_valid(const wuffs_base__image_config* c) {
4635   return c && wuffs_base__pixel_config__is_valid(&(c->pixcfg));
4636 }
4637 
4638 static inline uint64_t  //
wuffs_base__image_config__first_frame_io_position(const wuffs_base__image_config * c)4639 wuffs_base__image_config__first_frame_io_position(
4640     const wuffs_base__image_config* c) {
4641   return c ? c->private_impl.first_frame_io_position : 0;
4642 }
4643 
4644 static inline bool  //
wuffs_base__image_config__first_frame_is_opaque(const wuffs_base__image_config * c)4645 wuffs_base__image_config__first_frame_is_opaque(
4646     const wuffs_base__image_config* c) {
4647   return c ? c->private_impl.first_frame_is_opaque : false;
4648 }
4649 
4650 #ifdef __cplusplus
4651 
4652 inline void  //
set(uint32_t pixfmt_repr,uint32_t pixsub_repr,uint32_t width,uint32_t height,uint64_t first_frame_io_position,bool first_frame_is_opaque)4653 wuffs_base__image_config::set(uint32_t pixfmt_repr,
4654                               uint32_t pixsub_repr,
4655                               uint32_t width,
4656                               uint32_t height,
4657                               uint64_t first_frame_io_position,
4658                               bool first_frame_is_opaque) {
4659   wuffs_base__image_config__set(this, pixfmt_repr, pixsub_repr, width, height,
4660                                 first_frame_io_position, first_frame_is_opaque);
4661 }
4662 
4663 inline void  //
invalidate()4664 wuffs_base__image_config::invalidate() {
4665   wuffs_base__image_config__invalidate(this);
4666 }
4667 
4668 inline bool  //
is_valid()4669 wuffs_base__image_config::is_valid() const {
4670   return wuffs_base__image_config__is_valid(this);
4671 }
4672 
4673 inline uint64_t  //
first_frame_io_position()4674 wuffs_base__image_config::first_frame_io_position() const {
4675   return wuffs_base__image_config__first_frame_io_position(this);
4676 }
4677 
4678 inline bool  //
first_frame_is_opaque()4679 wuffs_base__image_config::first_frame_is_opaque() const {
4680   return wuffs_base__image_config__first_frame_is_opaque(this);
4681 }
4682 
4683 #endif  // __cplusplus
4684 
4685 // --------
4686 
4687 // wuffs_base__animation_disposal encodes, for an animated image, how to
4688 // dispose of a frame after displaying it:
4689 //  - None means to draw the next frame on top of this one.
4690 //  - Restore Background means to clear the frame's dirty rectangle to "the
4691 //    background color" (in practice, this means transparent black) before
4692 //    drawing the next frame.
4693 //  - Restore Previous means to undo the current frame, so that the next frame
4694 //    is drawn on top of the previous one.
4695 typedef uint8_t wuffs_base__animation_disposal;
4696 
4697 #define WUFFS_BASE__ANIMATION_DISPOSAL__NONE ((wuffs_base__animation_disposal)0)
4698 #define WUFFS_BASE__ANIMATION_DISPOSAL__RESTORE_BACKGROUND \
4699   ((wuffs_base__animation_disposal)1)
4700 #define WUFFS_BASE__ANIMATION_DISPOSAL__RESTORE_PREVIOUS \
4701   ((wuffs_base__animation_disposal)2)
4702 
4703 // --------
4704 
4705 typedef struct wuffs_base__frame_config__struct {
4706   // Do not access the private_impl's fields directly. There is no API/ABI
4707   // compatibility or safety guarantee if you do so.
4708   struct {
4709     wuffs_base__rect_ie_u32 bounds;
4710     wuffs_base__flicks duration;
4711     uint64_t index;
4712     uint64_t io_position;
4713     wuffs_base__animation_disposal disposal;
4714     bool opaque_within_bounds;
4715     bool overwrite_instead_of_blend;
4716     wuffs_base__color_u32_argb_premul background_color;
4717   } private_impl;
4718 
4719 #ifdef __cplusplus
4720   inline void set(wuffs_base__rect_ie_u32 bounds,
4721                   wuffs_base__flicks duration,
4722                   uint64_t index,
4723                   uint64_t io_position,
4724                   wuffs_base__animation_disposal disposal,
4725                   bool opaque_within_bounds,
4726                   bool overwrite_instead_of_blend,
4727                   wuffs_base__color_u32_argb_premul background_color);
4728   inline wuffs_base__rect_ie_u32 bounds() const;
4729   inline uint32_t width() const;
4730   inline uint32_t height() const;
4731   inline wuffs_base__flicks duration() const;
4732   inline uint64_t index() const;
4733   inline uint64_t io_position() const;
4734   inline wuffs_base__animation_disposal disposal() const;
4735   inline bool opaque_within_bounds() const;
4736   inline bool overwrite_instead_of_blend() const;
4737   inline wuffs_base__color_u32_argb_premul background_color() const;
4738 #endif  // __cplusplus
4739 
4740 } wuffs_base__frame_config;
4741 
4742 static inline wuffs_base__frame_config  //
wuffs_base__null_frame_config(void)4743 wuffs_base__null_frame_config(void) {
4744   wuffs_base__frame_config ret;
4745   ret.private_impl.bounds = wuffs_base__make_rect_ie_u32(0, 0, 0, 0);
4746   ret.private_impl.duration = 0;
4747   ret.private_impl.index = 0;
4748   ret.private_impl.io_position = 0;
4749   ret.private_impl.disposal = 0;
4750   ret.private_impl.opaque_within_bounds = false;
4751   ret.private_impl.overwrite_instead_of_blend = false;
4752   return ret;
4753 }
4754 
4755 static inline void  //
wuffs_base__frame_config__set(wuffs_base__frame_config * c,wuffs_base__rect_ie_u32 bounds,wuffs_base__flicks duration,uint64_t index,uint64_t io_position,wuffs_base__animation_disposal disposal,bool opaque_within_bounds,bool overwrite_instead_of_blend,wuffs_base__color_u32_argb_premul background_color)4756 wuffs_base__frame_config__set(
4757     wuffs_base__frame_config* c,
4758     wuffs_base__rect_ie_u32 bounds,
4759     wuffs_base__flicks duration,
4760     uint64_t index,
4761     uint64_t io_position,
4762     wuffs_base__animation_disposal disposal,
4763     bool opaque_within_bounds,
4764     bool overwrite_instead_of_blend,
4765     wuffs_base__color_u32_argb_premul background_color) {
4766   if (!c) {
4767     return;
4768   }
4769 
4770   c->private_impl.bounds = bounds;
4771   c->private_impl.duration = duration;
4772   c->private_impl.index = index;
4773   c->private_impl.io_position = io_position;
4774   c->private_impl.disposal = disposal;
4775   c->private_impl.opaque_within_bounds = opaque_within_bounds;
4776   c->private_impl.overwrite_instead_of_blend = overwrite_instead_of_blend;
4777   c->private_impl.background_color = background_color;
4778 }
4779 
4780 static inline wuffs_base__rect_ie_u32  //
wuffs_base__frame_config__bounds(const wuffs_base__frame_config * c)4781 wuffs_base__frame_config__bounds(const wuffs_base__frame_config* c) {
4782   if (c) {
4783     return c->private_impl.bounds;
4784   }
4785 
4786   wuffs_base__rect_ie_u32 ret;
4787   ret.min_incl_x = 0;
4788   ret.min_incl_y = 0;
4789   ret.max_excl_x = 0;
4790   ret.max_excl_y = 0;
4791   return ret;
4792 }
4793 
4794 static inline uint32_t  //
wuffs_base__frame_config__width(const wuffs_base__frame_config * c)4795 wuffs_base__frame_config__width(const wuffs_base__frame_config* c) {
4796   return c ? wuffs_base__rect_ie_u32__width(&c->private_impl.bounds) : 0;
4797 }
4798 
4799 static inline uint32_t  //
wuffs_base__frame_config__height(const wuffs_base__frame_config * c)4800 wuffs_base__frame_config__height(const wuffs_base__frame_config* c) {
4801   return c ? wuffs_base__rect_ie_u32__height(&c->private_impl.bounds) : 0;
4802 }
4803 
4804 // wuffs_base__frame_config__duration returns the amount of time to display
4805 // this frame. Zero means to display forever - a still (non-animated) image.
4806 static inline wuffs_base__flicks  //
wuffs_base__frame_config__duration(const wuffs_base__frame_config * c)4807 wuffs_base__frame_config__duration(const wuffs_base__frame_config* c) {
4808   return c ? c->private_impl.duration : 0;
4809 }
4810 
4811 // wuffs_base__frame_config__index returns the index of this frame. The first
4812 // frame in an image has index 0, the second frame has index 1, and so on.
4813 static inline uint64_t  //
wuffs_base__frame_config__index(const wuffs_base__frame_config * c)4814 wuffs_base__frame_config__index(const wuffs_base__frame_config* c) {
4815   return c ? c->private_impl.index : 0;
4816 }
4817 
4818 // wuffs_base__frame_config__io_position returns the I/O stream position before
4819 // the frame config.
4820 static inline uint64_t  //
wuffs_base__frame_config__io_position(const wuffs_base__frame_config * c)4821 wuffs_base__frame_config__io_position(const wuffs_base__frame_config* c) {
4822   return c ? c->private_impl.io_position : 0;
4823 }
4824 
4825 // wuffs_base__frame_config__disposal returns, for an animated image, how to
4826 // dispose of this frame after displaying it.
4827 static inline wuffs_base__animation_disposal  //
wuffs_base__frame_config__disposal(const wuffs_base__frame_config * c)4828 wuffs_base__frame_config__disposal(const wuffs_base__frame_config* c) {
4829   return c ? c->private_impl.disposal : 0;
4830 }
4831 
4832 // wuffs_base__frame_config__opaque_within_bounds returns whether all pixels
4833 // within the frame's bounds are fully opaque. It makes no claim about pixels
4834 // outside the frame bounds but still inside the overall image. The two
4835 // bounding rectangles can differ for animated images.
4836 //
4837 // Its semantics are conservative. It is valid for a fully opaque frame to have
4838 // this value be false: a false negative.
4839 //
4840 // If true, drawing the frame with WUFFS_BASE__PIXEL_BLEND__SRC and
4841 // WUFFS_BASE__PIXEL_BLEND__SRC_OVER should be equivalent, in terms of
4842 // resultant pixels, but the former may be faster.
4843 static inline bool  //
wuffs_base__frame_config__opaque_within_bounds(const wuffs_base__frame_config * c)4844 wuffs_base__frame_config__opaque_within_bounds(
4845     const wuffs_base__frame_config* c) {
4846   return c && c->private_impl.opaque_within_bounds;
4847 }
4848 
4849 // wuffs_base__frame_config__overwrite_instead_of_blend returns, for an
4850 // animated image, whether to ignore the previous image state (within the frame
4851 // bounds) when drawing this incremental frame. Equivalently, whether to use
4852 // WUFFS_BASE__PIXEL_BLEND__SRC instead of WUFFS_BASE__PIXEL_BLEND__SRC_OVER.
4853 //
4854 // The WebP spec (https://developers.google.com/speed/webp/docs/riff_container)
4855 // calls this the "Blending method" bit. WebP's "Do not blend" corresponds to
4856 // Wuffs' "overwrite_instead_of_blend".
4857 static inline bool  //
wuffs_base__frame_config__overwrite_instead_of_blend(const wuffs_base__frame_config * c)4858 wuffs_base__frame_config__overwrite_instead_of_blend(
4859     const wuffs_base__frame_config* c) {
4860   return c && c->private_impl.overwrite_instead_of_blend;
4861 }
4862 
4863 static inline wuffs_base__color_u32_argb_premul  //
wuffs_base__frame_config__background_color(const wuffs_base__frame_config * c)4864 wuffs_base__frame_config__background_color(const wuffs_base__frame_config* c) {
4865   return c ? c->private_impl.background_color : 0;
4866 }
4867 
4868 #ifdef __cplusplus
4869 
4870 inline void  //
set(wuffs_base__rect_ie_u32 bounds,wuffs_base__flicks duration,uint64_t index,uint64_t io_position,wuffs_base__animation_disposal disposal,bool opaque_within_bounds,bool overwrite_instead_of_blend,wuffs_base__color_u32_argb_premul background_color)4871 wuffs_base__frame_config::set(
4872     wuffs_base__rect_ie_u32 bounds,
4873     wuffs_base__flicks duration,
4874     uint64_t index,
4875     uint64_t io_position,
4876     wuffs_base__animation_disposal disposal,
4877     bool opaque_within_bounds,
4878     bool overwrite_instead_of_blend,
4879     wuffs_base__color_u32_argb_premul background_color) {
4880   wuffs_base__frame_config__set(this, bounds, duration, index, io_position,
4881                                 disposal, opaque_within_bounds,
4882                                 overwrite_instead_of_blend, background_color);
4883 }
4884 
4885 inline wuffs_base__rect_ie_u32  //
bounds()4886 wuffs_base__frame_config::bounds() const {
4887   return wuffs_base__frame_config__bounds(this);
4888 }
4889 
4890 inline uint32_t  //
width()4891 wuffs_base__frame_config::width() const {
4892   return wuffs_base__frame_config__width(this);
4893 }
4894 
4895 inline uint32_t  //
height()4896 wuffs_base__frame_config::height() const {
4897   return wuffs_base__frame_config__height(this);
4898 }
4899 
4900 inline wuffs_base__flicks  //
duration()4901 wuffs_base__frame_config::duration() const {
4902   return wuffs_base__frame_config__duration(this);
4903 }
4904 
4905 inline uint64_t  //
index()4906 wuffs_base__frame_config::index() const {
4907   return wuffs_base__frame_config__index(this);
4908 }
4909 
4910 inline uint64_t  //
io_position()4911 wuffs_base__frame_config::io_position() const {
4912   return wuffs_base__frame_config__io_position(this);
4913 }
4914 
4915 inline wuffs_base__animation_disposal  //
disposal()4916 wuffs_base__frame_config::disposal() const {
4917   return wuffs_base__frame_config__disposal(this);
4918 }
4919 
4920 inline bool  //
opaque_within_bounds()4921 wuffs_base__frame_config::opaque_within_bounds() const {
4922   return wuffs_base__frame_config__opaque_within_bounds(this);
4923 }
4924 
4925 inline bool  //
overwrite_instead_of_blend()4926 wuffs_base__frame_config::overwrite_instead_of_blend() const {
4927   return wuffs_base__frame_config__overwrite_instead_of_blend(this);
4928 }
4929 
4930 inline wuffs_base__color_u32_argb_premul  //
background_color()4931 wuffs_base__frame_config::background_color() const {
4932   return wuffs_base__frame_config__background_color(this);
4933 }
4934 
4935 #endif  // __cplusplus
4936 
4937 // --------
4938 
4939 typedef struct wuffs_base__pixel_buffer__struct {
4940   wuffs_base__pixel_config pixcfg;
4941 
4942   // Do not access the private_impl's fields directly. There is no API/ABI
4943   // compatibility or safety guarantee if you do so.
4944   struct {
4945     wuffs_base__table_u8 planes[WUFFS_BASE__PIXEL_FORMAT__NUM_PLANES_MAX_INCL];
4946     // TODO: color spaces.
4947   } private_impl;
4948 
4949 #ifdef __cplusplus
4950   inline wuffs_base__status set_interleaved(
4951       const wuffs_base__pixel_config* pixcfg,
4952       wuffs_base__table_u8 primary_memory,
4953       wuffs_base__slice_u8 palette_memory);
4954   inline wuffs_base__status set_from_slice(
4955       const wuffs_base__pixel_config* pixcfg,
4956       wuffs_base__slice_u8 pixbuf_memory);
4957   inline wuffs_base__slice_u8 palette();
4958   inline wuffs_base__slice_u8 palette_or_else(wuffs_base__slice_u8 fallback);
4959   inline wuffs_base__pixel_format pixel_format() const;
4960   inline wuffs_base__table_u8 plane(uint32_t p);
4961   inline wuffs_base__color_u32_argb_premul color_u32_at(uint32_t x,
4962                                                         uint32_t y) const;
4963   inline wuffs_base__status set_color_u32_at(
4964       uint32_t x,
4965       uint32_t y,
4966       wuffs_base__color_u32_argb_premul color);
4967   inline wuffs_base__status set_color_u32_fill_rect(
4968       wuffs_base__rect_ie_u32 rect,
4969       wuffs_base__color_u32_argb_premul color);
4970 #endif  // __cplusplus
4971 
4972 } wuffs_base__pixel_buffer;
4973 
4974 static inline wuffs_base__pixel_buffer  //
wuffs_base__null_pixel_buffer(void)4975 wuffs_base__null_pixel_buffer(void) {
4976   wuffs_base__pixel_buffer ret;
4977   ret.pixcfg = wuffs_base__null_pixel_config();
4978   ret.private_impl.planes[0] = wuffs_base__empty_table_u8();
4979   ret.private_impl.planes[1] = wuffs_base__empty_table_u8();
4980   ret.private_impl.planes[2] = wuffs_base__empty_table_u8();
4981   ret.private_impl.planes[3] = wuffs_base__empty_table_u8();
4982   return ret;
4983 }
4984 
4985 static inline wuffs_base__status  //
wuffs_base__pixel_buffer__set_interleaved(wuffs_base__pixel_buffer * pb,const wuffs_base__pixel_config * pixcfg,wuffs_base__table_u8 primary_memory,wuffs_base__slice_u8 palette_memory)4986 wuffs_base__pixel_buffer__set_interleaved(
4987     wuffs_base__pixel_buffer* pb,
4988     const wuffs_base__pixel_config* pixcfg,
4989     wuffs_base__table_u8 primary_memory,
4990     wuffs_base__slice_u8 palette_memory) {
4991   if (!pb) {
4992     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
4993   }
4994   memset(pb, 0, sizeof(*pb));
4995   if (!pixcfg ||
4996       wuffs_base__pixel_format__is_planar(&pixcfg->private_impl.pixfmt)) {
4997     return wuffs_base__make_status(wuffs_base__error__bad_argument);
4998   }
4999   if (wuffs_base__pixel_format__is_indexed(&pixcfg->private_impl.pixfmt) &&
5000       (palette_memory.len <
5001        WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH)) {
5002     return wuffs_base__make_status(
5003         wuffs_base__error__bad_argument_length_too_short);
5004   }
5005   uint32_t bits_per_pixel =
5006       wuffs_base__pixel_format__bits_per_pixel(&pixcfg->private_impl.pixfmt);
5007   if ((bits_per_pixel == 0) || ((bits_per_pixel % 8) != 0)) {
5008     // TODO: support fraction-of-byte pixels, e.g. 1 bit per pixel?
5009     return wuffs_base__make_status(wuffs_base__error__unsupported_option);
5010   }
5011   uint64_t bytes_per_pixel = bits_per_pixel / 8;
5012 
5013   uint64_t width_in_bytes =
5014       ((uint64_t)pixcfg->private_impl.width) * bytes_per_pixel;
5015   if ((width_in_bytes > primary_memory.width) ||
5016       (pixcfg->private_impl.height > primary_memory.height)) {
5017     return wuffs_base__make_status(wuffs_base__error__bad_argument);
5018   }
5019 
5020   pb->pixcfg = *pixcfg;
5021   pb->private_impl.planes[0] = primary_memory;
5022   if (wuffs_base__pixel_format__is_indexed(&pixcfg->private_impl.pixfmt)) {
5023     wuffs_base__table_u8* tab =
5024         &pb->private_impl
5025              .planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE];
5026     tab->ptr = palette_memory.ptr;
5027     tab->width = WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
5028     tab->height = 1;
5029     tab->stride = WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
5030   }
5031   return wuffs_base__make_status(NULL);
5032 }
5033 
5034 static inline wuffs_base__status  //
wuffs_base__pixel_buffer__set_from_slice(wuffs_base__pixel_buffer * pb,const wuffs_base__pixel_config * pixcfg,wuffs_base__slice_u8 pixbuf_memory)5035 wuffs_base__pixel_buffer__set_from_slice(wuffs_base__pixel_buffer* pb,
5036                                          const wuffs_base__pixel_config* pixcfg,
5037                                          wuffs_base__slice_u8 pixbuf_memory) {
5038   if (!pb) {
5039     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
5040   }
5041   memset(pb, 0, sizeof(*pb));
5042   if (!pixcfg) {
5043     return wuffs_base__make_status(wuffs_base__error__bad_argument);
5044   }
5045   if (wuffs_base__pixel_format__is_planar(&pixcfg->private_impl.pixfmt)) {
5046     // TODO: support planar pixel formats, concious of pixel subsampling.
5047     return wuffs_base__make_status(wuffs_base__error__unsupported_option);
5048   }
5049   uint32_t bits_per_pixel =
5050       wuffs_base__pixel_format__bits_per_pixel(&pixcfg->private_impl.pixfmt);
5051   if ((bits_per_pixel == 0) || ((bits_per_pixel % 8) != 0)) {
5052     // TODO: support fraction-of-byte pixels, e.g. 1 bit per pixel?
5053     return wuffs_base__make_status(wuffs_base__error__unsupported_option);
5054   }
5055   uint64_t bytes_per_pixel = bits_per_pixel / 8;
5056 
5057   uint8_t* ptr = pixbuf_memory.ptr;
5058   uint64_t len = pixbuf_memory.len;
5059   if (wuffs_base__pixel_format__is_indexed(&pixcfg->private_impl.pixfmt)) {
5060     // Split a WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH byte
5061     // chunk (1024 bytes = 256 palette entries × 4 bytes per entry) from the
5062     // start of pixbuf_memory. We split from the start, not the end, so that
5063     // the both chunks' pointers have the same alignment as the original
5064     // pointer, up to an alignment of 1024.
5065     if (len < WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
5066       return wuffs_base__make_status(
5067           wuffs_base__error__bad_argument_length_too_short);
5068     }
5069     wuffs_base__table_u8* tab =
5070         &pb->private_impl
5071              .planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE];
5072     tab->ptr = ptr;
5073     tab->width = WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
5074     tab->height = 1;
5075     tab->stride = WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
5076     ptr += WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
5077     len -= WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
5078   }
5079 
5080   uint64_t wh = ((uint64_t)pixcfg->private_impl.width) *
5081                 ((uint64_t)pixcfg->private_impl.height);
5082   size_t width = (size_t)(pixcfg->private_impl.width);
5083   if ((wh > (UINT64_MAX / bytes_per_pixel)) ||
5084       (width > (SIZE_MAX / bytes_per_pixel))) {
5085     return wuffs_base__make_status(wuffs_base__error__bad_argument);
5086   }
5087   wh *= bytes_per_pixel;
5088   width = ((size_t)(width * bytes_per_pixel));
5089   if (wh > len) {
5090     return wuffs_base__make_status(
5091         wuffs_base__error__bad_argument_length_too_short);
5092   }
5093 
5094   pb->pixcfg = *pixcfg;
5095   wuffs_base__table_u8* tab = &pb->private_impl.planes[0];
5096   tab->ptr = ptr;
5097   tab->width = width;
5098   tab->height = pixcfg->private_impl.height;
5099   tab->stride = width;
5100   return wuffs_base__make_status(NULL);
5101 }
5102 
5103 // wuffs_base__pixel_buffer__palette returns the palette color data. If
5104 // non-empty, it will have length
5105 // WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH.
5106 static inline wuffs_base__slice_u8  //
wuffs_base__pixel_buffer__palette(wuffs_base__pixel_buffer * pb)5107 wuffs_base__pixel_buffer__palette(wuffs_base__pixel_buffer* pb) {
5108   if (pb &&
5109       wuffs_base__pixel_format__is_indexed(&pb->pixcfg.private_impl.pixfmt)) {
5110     wuffs_base__table_u8* tab =
5111         &pb->private_impl
5112              .planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE];
5113     if ((tab->width ==
5114          WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) &&
5115         (tab->height == 1)) {
5116       return wuffs_base__make_slice_u8(
5117           tab->ptr, WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH);
5118     }
5119   }
5120   return wuffs_base__make_slice_u8(NULL, 0);
5121 }
5122 
5123 static inline wuffs_base__slice_u8  //
wuffs_base__pixel_buffer__palette_or_else(wuffs_base__pixel_buffer * pb,wuffs_base__slice_u8 fallback)5124 wuffs_base__pixel_buffer__palette_or_else(wuffs_base__pixel_buffer* pb,
5125                                           wuffs_base__slice_u8 fallback) {
5126   if (pb &&
5127       wuffs_base__pixel_format__is_indexed(&pb->pixcfg.private_impl.pixfmt)) {
5128     wuffs_base__table_u8* tab =
5129         &pb->private_impl
5130              .planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE];
5131     if ((tab->width ==
5132          WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) &&
5133         (tab->height == 1)) {
5134       return wuffs_base__make_slice_u8(
5135           tab->ptr, WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH);
5136     }
5137   }
5138   return fallback;
5139 }
5140 
5141 static inline wuffs_base__pixel_format  //
wuffs_base__pixel_buffer__pixel_format(const wuffs_base__pixel_buffer * pb)5142 wuffs_base__pixel_buffer__pixel_format(const wuffs_base__pixel_buffer* pb) {
5143   if (pb) {
5144     return pb->pixcfg.private_impl.pixfmt;
5145   }
5146   return wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__INVALID);
5147 }
5148 
5149 static inline wuffs_base__table_u8  //
wuffs_base__pixel_buffer__plane(wuffs_base__pixel_buffer * pb,uint32_t p)5150 wuffs_base__pixel_buffer__plane(wuffs_base__pixel_buffer* pb, uint32_t p) {
5151   if (pb && (p < WUFFS_BASE__PIXEL_FORMAT__NUM_PLANES_MAX_INCL)) {
5152     return pb->private_impl.planes[p];
5153   }
5154 
5155   wuffs_base__table_u8 ret;
5156   ret.ptr = NULL;
5157   ret.width = 0;
5158   ret.height = 0;
5159   ret.stride = 0;
5160   return ret;
5161 }
5162 
5163 WUFFS_BASE__MAYBE_STATIC wuffs_base__color_u32_argb_premul  //
5164 wuffs_base__pixel_buffer__color_u32_at(const wuffs_base__pixel_buffer* pb,
5165                                        uint32_t x,
5166                                        uint32_t y);
5167 
5168 WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
5169 wuffs_base__pixel_buffer__set_color_u32_at(
5170     wuffs_base__pixel_buffer* pb,
5171     uint32_t x,
5172     uint32_t y,
5173     wuffs_base__color_u32_argb_premul color);
5174 
5175 WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
5176 wuffs_base__pixel_buffer__set_color_u32_fill_rect(
5177     wuffs_base__pixel_buffer* pb,
5178     wuffs_base__rect_ie_u32 rect,
5179     wuffs_base__color_u32_argb_premul color);
5180 
5181 #ifdef __cplusplus
5182 
5183 inline wuffs_base__status  //
set_interleaved(const wuffs_base__pixel_config * pixcfg_arg,wuffs_base__table_u8 primary_memory,wuffs_base__slice_u8 palette_memory)5184 wuffs_base__pixel_buffer::set_interleaved(
5185     const wuffs_base__pixel_config* pixcfg_arg,
5186     wuffs_base__table_u8 primary_memory,
5187     wuffs_base__slice_u8 palette_memory) {
5188   return wuffs_base__pixel_buffer__set_interleaved(
5189       this, pixcfg_arg, primary_memory, palette_memory);
5190 }
5191 
5192 inline wuffs_base__status  //
set_from_slice(const wuffs_base__pixel_config * pixcfg_arg,wuffs_base__slice_u8 pixbuf_memory)5193 wuffs_base__pixel_buffer::set_from_slice(
5194     const wuffs_base__pixel_config* pixcfg_arg,
5195     wuffs_base__slice_u8 pixbuf_memory) {
5196   return wuffs_base__pixel_buffer__set_from_slice(this, pixcfg_arg,
5197                                                   pixbuf_memory);
5198 }
5199 
5200 inline wuffs_base__slice_u8  //
palette()5201 wuffs_base__pixel_buffer::palette() {
5202   return wuffs_base__pixel_buffer__palette(this);
5203 }
5204 
5205 inline wuffs_base__slice_u8  //
palette_or_else(wuffs_base__slice_u8 fallback)5206 wuffs_base__pixel_buffer::palette_or_else(wuffs_base__slice_u8 fallback) {
5207   return wuffs_base__pixel_buffer__palette_or_else(this, fallback);
5208 }
5209 
5210 inline wuffs_base__pixel_format  //
pixel_format()5211 wuffs_base__pixel_buffer::pixel_format() const {
5212   return wuffs_base__pixel_buffer__pixel_format(this);
5213 }
5214 
5215 inline wuffs_base__table_u8  //
plane(uint32_t p)5216 wuffs_base__pixel_buffer::plane(uint32_t p) {
5217   return wuffs_base__pixel_buffer__plane(this, p);
5218 }
5219 
5220 inline wuffs_base__color_u32_argb_premul  //
color_u32_at(uint32_t x,uint32_t y)5221 wuffs_base__pixel_buffer::color_u32_at(uint32_t x, uint32_t y) const {
5222   return wuffs_base__pixel_buffer__color_u32_at(this, x, y);
5223 }
5224 
5225 inline wuffs_base__status  //
set_color_u32_at(uint32_t x,uint32_t y,wuffs_base__color_u32_argb_premul color)5226 wuffs_base__pixel_buffer::set_color_u32_at(
5227     uint32_t x,
5228     uint32_t y,
5229     wuffs_base__color_u32_argb_premul color) {
5230   return wuffs_base__pixel_buffer__set_color_u32_at(this, x, y, color);
5231 }
5232 
5233 inline wuffs_base__status  //
set_color_u32_fill_rect(wuffs_base__rect_ie_u32 rect,wuffs_base__color_u32_argb_premul color)5234 wuffs_base__pixel_buffer::set_color_u32_fill_rect(
5235     wuffs_base__rect_ie_u32 rect,
5236     wuffs_base__color_u32_argb_premul color) {
5237   return wuffs_base__pixel_buffer__set_color_u32_fill_rect(this, rect, color);
5238 }
5239 
5240 #endif  // __cplusplus
5241 
5242 // --------
5243 
5244 typedef struct wuffs_base__decode_frame_options__struct {
5245   // Do not access the private_impl's fields directly. There is no API/ABI
5246   // compatibility or safety guarantee if you do so.
5247   struct {
5248     uint8_t TODO;
5249   } private_impl;
5250 
5251 #ifdef __cplusplus
5252 #endif  // __cplusplus
5253 
5254 } wuffs_base__decode_frame_options;
5255 
5256 #ifdef __cplusplus
5257 
5258 #endif  // __cplusplus
5259 
5260 // --------
5261 
5262 // wuffs_base__pixel_palette__closest_element returns the index of the palette
5263 // element that minimizes the sum of squared differences of the four ARGB
5264 // channels, working in premultiplied alpha. Ties favor the smaller index.
5265 //
5266 // The palette_slice.len may equal (N*4), for N less than 256, which means that
5267 // only the first N palette elements are considered. It returns 0 when N is 0.
5268 //
5269 // Applying this function on a per-pixel basis will not produce whole-of-image
5270 // dithering.
5271 WUFFS_BASE__MAYBE_STATIC uint8_t  //
5272 wuffs_base__pixel_palette__closest_element(
5273     wuffs_base__slice_u8 palette_slice,
5274     wuffs_base__pixel_format palette_format,
5275     wuffs_base__color_u32_argb_premul c);
5276 
5277 // --------
5278 
5279 // TODO: should the func type take restrict pointers?
5280 typedef uint64_t (*wuffs_base__pixel_swizzler__func)(uint8_t* dst_ptr,
5281                                                      size_t dst_len,
5282                                                      uint8_t* dst_palette_ptr,
5283                                                      size_t dst_palette_len,
5284                                                      const uint8_t* src_ptr,
5285                                                      size_t src_len);
5286 
5287 typedef uint64_t (*wuffs_base__pixel_swizzler__transparent_black_func)(
5288     uint8_t* dst_ptr,
5289     size_t dst_len,
5290     uint8_t* dst_palette_ptr,
5291     size_t dst_palette_len,
5292     uint64_t num_pixels,
5293     uint32_t dst_pixfmt_bytes_per_pixel);
5294 
5295 typedef struct wuffs_base__pixel_swizzler__struct {
5296   // Do not access the private_impl's fields directly. There is no API/ABI
5297   // compatibility or safety guarantee if you do so.
5298   struct {
5299     wuffs_base__pixel_swizzler__func func;
5300     wuffs_base__pixel_swizzler__transparent_black_func transparent_black_func;
5301     uint32_t dst_pixfmt_bytes_per_pixel;
5302     uint32_t src_pixfmt_bytes_per_pixel;
5303   } private_impl;
5304 
5305 #ifdef __cplusplus
5306   inline wuffs_base__status prepare(wuffs_base__pixel_format dst_pixfmt,
5307                                     wuffs_base__slice_u8 dst_palette,
5308                                     wuffs_base__pixel_format src_pixfmt,
5309                                     wuffs_base__slice_u8 src_palette,
5310                                     wuffs_base__pixel_blend blend);
5311   inline uint64_t swizzle_interleaved_from_slice(
5312       wuffs_base__slice_u8 dst,
5313       wuffs_base__slice_u8 dst_palette,
5314       wuffs_base__slice_u8 src) const;
5315 #endif  // __cplusplus
5316 
5317 } wuffs_base__pixel_swizzler;
5318 
5319 // wuffs_base__pixel_swizzler__prepare readies the pixel swizzler so that its
5320 // other methods may be called.
5321 //
5322 // For modular builds that divide the base module into sub-modules, using this
5323 // function requires the WUFFS_CONFIG__MODULE__BASE__PIXCONV sub-module, not
5324 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5325 WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
5326 wuffs_base__pixel_swizzler__prepare(wuffs_base__pixel_swizzler* p,
5327                                     wuffs_base__pixel_format dst_pixfmt,
5328                                     wuffs_base__slice_u8 dst_palette,
5329                                     wuffs_base__pixel_format src_pixfmt,
5330                                     wuffs_base__slice_u8 src_palette,
5331                                     wuffs_base__pixel_blend blend);
5332 
5333 // wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice converts pixels
5334 // from a source format to a destination format.
5335 //
5336 // For modular builds that divide the base module into sub-modules, using this
5337 // function requires the WUFFS_CONFIG__MODULE__BASE__PIXCONV sub-module, not
5338 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5339 WUFFS_BASE__MAYBE_STATIC uint64_t  //
5340 wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(
5341     const wuffs_base__pixel_swizzler* p,
5342     wuffs_base__slice_u8 dst,
5343     wuffs_base__slice_u8 dst_palette,
5344     wuffs_base__slice_u8 src);
5345 
5346 #ifdef __cplusplus
5347 
5348 inline wuffs_base__status  //
prepare(wuffs_base__pixel_format dst_pixfmt,wuffs_base__slice_u8 dst_palette,wuffs_base__pixel_format src_pixfmt,wuffs_base__slice_u8 src_palette,wuffs_base__pixel_blend blend)5349 wuffs_base__pixel_swizzler::prepare(wuffs_base__pixel_format dst_pixfmt,
5350                                     wuffs_base__slice_u8 dst_palette,
5351                                     wuffs_base__pixel_format src_pixfmt,
5352                                     wuffs_base__slice_u8 src_palette,
5353                                     wuffs_base__pixel_blend blend) {
5354   return wuffs_base__pixel_swizzler__prepare(this, dst_pixfmt, dst_palette,
5355                                              src_pixfmt, src_palette, blend);
5356 }
5357 
5358 uint64_t  //
swizzle_interleaved_from_slice(wuffs_base__slice_u8 dst,wuffs_base__slice_u8 dst_palette,wuffs_base__slice_u8 src)5359 wuffs_base__pixel_swizzler::swizzle_interleaved_from_slice(
5360     wuffs_base__slice_u8 dst,
5361     wuffs_base__slice_u8 dst_palette,
5362     wuffs_base__slice_u8 src) const {
5363   return wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(
5364       this, dst, dst_palette, src);
5365 }
5366 
5367 #endif  // __cplusplus
5368 
5369 // ---------------- String Conversions
5370 
5371 // Options (bitwise or'ed together) for wuffs_base__parse_number_xxx
5372 // functions. The XXX options apply to both integer and floating point. The FXX
5373 // options apply only to floating point.
5374 
5375 #define WUFFS_BASE__PARSE_NUMBER_XXX__DEFAULT_OPTIONS ((uint32_t)0x00000000)
5376 
5377 // WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_MULTIPLE_LEADING_ZEROES means to accept
5378 // inputs like "00", "0644" and "00.7". By default, they are rejected.
5379 #define WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_MULTIPLE_LEADING_ZEROES \
5380   ((uint32_t)0x00000001)
5381 
5382 // WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES means to accept inputs like
5383 // "1__2" and "_3.141_592". By default, they are rejected.
5384 #define WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES ((uint32_t)0x00000002)
5385 
5386 // WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA means to accept
5387 // "1,5" and not "1.5" as one-and-a-half.
5388 //
5389 // If the caller wants to accept either, it is responsible for canonicalizing
5390 // the input before calling wuffs_base__parse_number_fxx. The caller also has
5391 // more context on e.g. exactly how to treat something like "$1,234".
5392 #define WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA \
5393   ((uint32_t)0x00000010)
5394 
5395 // WUFFS_BASE__PARSE_NUMBER_FXX__REJECT_INF_AND_NAN means to reject inputs that
5396 // would lead to infinite or Not-a-Number floating point values. By default,
5397 // they are accepted.
5398 //
5399 // This affects the literal "inf" as input, but also affects inputs like
5400 // "1e999" that would overflow double-precision floating point.
5401 #define WUFFS_BASE__PARSE_NUMBER_FXX__REJECT_INF_AND_NAN ((uint32_t)0x00000020)
5402 
5403 // --------
5404 
5405 // Options (bitwise or'ed together) for wuffs_base__render_number_xxx
5406 // functions. The XXX options apply to both integer and floating point. The FXX
5407 // options apply only to floating point.
5408 
5409 #define WUFFS_BASE__RENDER_NUMBER_XXX__DEFAULT_OPTIONS ((uint32_t)0x00000000)
5410 
5411 // WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT means to render to the right side
5412 // (higher indexes) of the destination slice, leaving any untouched bytes on
5413 // the left side (lower indexes). The default is vice versa: rendering on the
5414 // left with slack on the right.
5415 #define WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT ((uint32_t)0x00000100)
5416 
5417 // WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN means to render the leading
5418 // "+" for non-negative numbers: "+0" and "+12.3" instead of "0" and "12.3".
5419 #define WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN ((uint32_t)0x00000200)
5420 
5421 // WUFFS_BASE__RENDER_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA means to render
5422 // one-and-a-half as "1,5" instead of "1.5".
5423 #define WUFFS_BASE__RENDER_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA \
5424   ((uint32_t)0x00001000)
5425 
5426 // WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_ETC means whether to never
5427 // (EXPONENT_ABSENT, equivalent to printf's "%f") or to always
5428 // (EXPONENT_PRESENT, equivalent to printf's "%e") render a floating point
5429 // number as "1.23e+05" instead of "123000".
5430 //
5431 // Having both bits set is the same has having neither bit set, where the
5432 // notation used depends on whether the exponent is sufficiently large: "0.5"
5433 // is preferred over "5e-01" but "5e-09" is preferred over "0.000000005".
5434 #define WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_ABSENT ((uint32_t)0x00002000)
5435 #define WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_PRESENT ((uint32_t)0x00004000)
5436 
5437 // WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION means to render the
5438 // smallest number of digits so that parsing the resultant string will recover
5439 // the same double-precision floating point number.
5440 //
5441 // For example, double-precision cannot distinguish between 0.3 and
5442 // 0.299999999999999988897769753748434595763683319091796875, so when this bit
5443 // is set, rendering the latter will produce "0.3" but rendering
5444 // 0.3000000000000000444089209850062616169452667236328125 will produce
5445 // "0.30000000000000004".
5446 #define WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION \
5447   ((uint32_t)0x00008000)
5448 
5449 // ---------------- IEEE 754 Floating Point
5450 
5451 // wuffs_base__ieee_754_bit_representation__etc converts between a double
5452 // precision numerical value and its IEEE 754 representations:
5453 //  - 16-bit: 1 sign bit,  5 exponent bits, 10 explicit significand bits.
5454 //  - 32-bit: 1 sign bit,  8 exponent bits, 23 explicit significand bits.
5455 //  - 64-bit: 1 sign bit, 11 exponent bits, 52 explicit significand bits.
5456 //
5457 // For example, it converts between:
5458 //  - +1.0 and 0x3C00, 0x3F80_0000 or 0x3FF0_0000_0000_0000.
5459 //  - +5.5 and 0x4580, 0x40B0_0000 or 0x4016_0000_0000_0000.
5460 //  - -inf and 0xFC00, 0xFF80_0000 or 0xFFF0_0000_0000_0000.
5461 //
5462 // Converting from f64 to shorter formats (f16 or f32, represented in C as
5463 // uint16_t and uint32_t) may be lossy. Such functions have names that look
5464 // like etc_truncate, as converting finite numbers produce equal or smaller
5465 // (closer-to-zero) finite numbers. For example, 1048576.0 is a perfectly valid
5466 // f64 number, but converting it to a f16 (with truncation) produces 65504.0,
5467 // the largest finite f16 number. Truncating a f64-typed value d to f32 does
5468 // not always produce the same result as the C-style cast ((float)d), as
5469 // casting can convert from finite numbers to infinite ones.
5470 //
5471 // Converting infinities or NaNs produces infinities or NaNs and always report
5472 // no loss, even though there a multiple NaN representations so that round-
5473 // tripping a f64-typed NaN may produce a different 64 bits. Nonetheless, the
5474 // etc_truncate functions preserve a NaN's "quiet vs signaling" bit.
5475 //
5476 // See https://en.wikipedia.org/wiki/Double-precision_floating-point_format
5477 
5478 typedef struct wuffs_base__lossy_value_u16__struct {
5479   uint16_t value;
5480   bool lossy;
5481 } wuffs_base__lossy_value_u16;
5482 
5483 typedef struct wuffs_base__lossy_value_u32__struct {
5484   uint32_t value;
5485   bool lossy;
5486 } wuffs_base__lossy_value_u32;
5487 
5488 WUFFS_BASE__MAYBE_STATIC wuffs_base__lossy_value_u16  //
5489 wuffs_base__ieee_754_bit_representation__from_f64_to_u16_truncate(double f);
5490 
5491 WUFFS_BASE__MAYBE_STATIC wuffs_base__lossy_value_u32  //
5492 wuffs_base__ieee_754_bit_representation__from_f64_to_u32_truncate(double f);
5493 
5494 static inline uint64_t  //
wuffs_base__ieee_754_bit_representation__from_f64_to_u64(double f)5495 wuffs_base__ieee_754_bit_representation__from_f64_to_u64(double f) {
5496   uint64_t u = 0;
5497   if (sizeof(uint64_t) == sizeof(double)) {
5498     memcpy(&u, &f, sizeof(uint64_t));
5499   }
5500   return u;
5501 }
5502 
5503 static inline double  //
wuffs_base__ieee_754_bit_representation__from_u16_to_f64(uint16_t u)5504 wuffs_base__ieee_754_bit_representation__from_u16_to_f64(uint16_t u) {
5505   uint64_t v = ((uint64_t)(u & 0x8000)) << 48;
5506 
5507   do {
5508     uint64_t exp = (u >> 10) & 0x1F;
5509     uint64_t man = u & 0x3FF;
5510     if (exp == 0x1F) {  // Infinity or NaN.
5511       exp = 2047;
5512     } else if (exp != 0) {  // Normal.
5513       exp += 1008;          // 1008 = 1023 - 15, the difference in biases.
5514     } else if (man != 0) {  // Subnormal but non-zero.
5515       uint32_t clz = wuffs_base__count_leading_zeroes_u64(man);
5516       exp = 1062 - clz;  // 1062 = 1008 + 64 - 10.
5517       man = 0x3FF & (man << (clz - 53));
5518     } else {  // Zero.
5519       break;
5520     }
5521     v |= (exp << 52) | (man << 42);
5522   } while (0);
5523 
5524   double f = 0;
5525   if (sizeof(uint64_t) == sizeof(double)) {
5526     memcpy(&f, &v, sizeof(uint64_t));
5527   }
5528   return f;
5529 }
5530 
5531 static inline double  //
wuffs_base__ieee_754_bit_representation__from_u32_to_f64(uint32_t u)5532 wuffs_base__ieee_754_bit_representation__from_u32_to_f64(uint32_t u) {
5533   float f = 0;
5534   if (sizeof(uint32_t) == sizeof(float)) {
5535     memcpy(&f, &u, sizeof(uint32_t));
5536   }
5537   return (double)f;
5538 }
5539 
5540 static inline double  //
wuffs_base__ieee_754_bit_representation__from_u64_to_f64(uint64_t u)5541 wuffs_base__ieee_754_bit_representation__from_u64_to_f64(uint64_t u) {
5542   double f = 0;
5543   if (sizeof(uint64_t) == sizeof(double)) {
5544     memcpy(&f, &u, sizeof(uint64_t));
5545   }
5546   return f;
5547 }
5548 
5549 // ---------------- Parsing and Rendering Numbers
5550 
5551 // wuffs_base__parse_number_f64 parses the floating point number in s. For
5552 // example, if s contains the bytes "1.5" then it will return the double 1.5.
5553 //
5554 // It returns an error if s does not contain a floating point number.
5555 //
5556 // It does not necessarily return an error if the conversion is lossy, e.g. if
5557 // s is "0.3", which double-precision floating point cannot represent exactly.
5558 //
5559 // Similarly, the returned value may be infinite (and no error returned) even
5560 // if s was not "inf", when the input is nominally finite but sufficiently
5561 // larger than DBL_MAX, about 1.8e+308.
5562 //
5563 // It is similar to the C standard library's strtod function, but:
5564 //  - Errors are returned in-band (in a result type), not out-of-band (errno).
5565 //  - It takes a slice (a pointer and length), not a NUL-terminated C string.
5566 //  - It does not take an optional endptr argument. It does not allow a partial
5567 //    parse: it returns an error unless all of s is consumed.
5568 //  - It does not allow whitespace, leading or otherwise.
5569 //  - It does not allow hexadecimal floating point numbers.
5570 //  - It is not affected by i18n / l10n settings such as environment variables.
5571 //
5572 // The options argument can change these, but by default, it:
5573 //  - Allows "inf", "+Infinity" and "-NAN", case insensitive. Similarly,
5574 //    without an explicit opt-out, it would successfully parse "1e999" as
5575 //    infinity, even though it overflows double-precision floating point.
5576 //  - Rejects underscores. With an explicit opt-in, "_3.141_592" would
5577 //    successfully parse as an approximation to π.
5578 //  - Rejects unnecessary leading zeroes: "00", "0644" and "00.7".
5579 //  - Uses a dot '1.5' instead of a comma '1,5' for the decimal separator.
5580 //
5581 // For modular builds that divide the base module into sub-modules, using this
5582 // function requires the WUFFS_CONFIG__MODULE__BASE__FLOATCONV sub-module, not
5583 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5584 WUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64  //
5585 wuffs_base__parse_number_f64(wuffs_base__slice_u8 s, uint32_t options);
5586 
5587 // wuffs_base__parse_number_i64 parses the ASCII integer in s. For example, if
5588 // s contains the bytes "-123" then it will return the int64_t -123.
5589 //
5590 // It returns an error if s does not contain an integer or if the integer
5591 // within would overflow an int64_t.
5592 //
5593 // It is similar to wuffs_base__parse_number_u64 but it returns a signed
5594 // integer, not an unsigned integer. It also allows a leading '+' or '-'.
5595 //
5596 // For modular builds that divide the base module into sub-modules, using this
5597 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5598 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5599 WUFFS_BASE__MAYBE_STATIC wuffs_base__result_i64  //
5600 wuffs_base__parse_number_i64(wuffs_base__slice_u8 s, uint32_t options);
5601 
5602 // wuffs_base__parse_number_u64 parses the ASCII integer in s. For example, if
5603 // s contains the bytes "123" then it will return the uint64_t 123.
5604 //
5605 // It returns an error if s does not contain an integer or if the integer
5606 // within would overflow a uint64_t.
5607 //
5608 // It is similar to the C standard library's strtoull function, but:
5609 //  - Errors are returned in-band (in a result type), not out-of-band (errno).
5610 //  - It takes a slice (a pointer and length), not a NUL-terminated C string.
5611 //  - It does not take an optional endptr argument. It does not allow a partial
5612 //    parse: it returns an error unless all of s is consumed.
5613 //  - It does not allow whitespace, leading or otherwise.
5614 //  - It does not allow a leading '+' or '-'.
5615 //  - It does not take a base argument (e.g. base 10 vs base 16). Instead, it
5616 //    always accepts both decimal (e.g "1234", "0d5678") and hexadecimal (e.g.
5617 //    "0x9aBC"). The caller is responsible for prior filtering of e.g. hex
5618 //    numbers if they are unwanted. For example, Wuffs' JSON decoder will only
5619 //    produce a wuffs_base__token for decimal numbers, not hexadecimal.
5620 //  - It is not affected by i18n / l10n settings such as environment variables.
5621 //
5622 // The options argument can change these, but by default, it:
5623 //  - Rejects underscores. With an explicit opt-in, "__0D_1_002" would
5624 //    successfully parse as "one thousand and two". Underscores are still
5625 //    rejected inside the optional 2-byte opening "0d" or "0X" that denotes
5626 //    base-10 or base-16.
5627 //  - Rejects unnecessary leading zeroes: "00" and "0644".
5628 //
5629 // For modular builds that divide the base module into sub-modules, using this
5630 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5631 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5632 WUFFS_BASE__MAYBE_STATIC wuffs_base__result_u64  //
5633 wuffs_base__parse_number_u64(wuffs_base__slice_u8 s, uint32_t options);
5634 
5635 // --------
5636 
5637 // WUFFS_BASE__I64__BYTE_LENGTH__MAX_INCL is the string length of
5638 // "-9223372036854775808" and "+9223372036854775807", INT64_MIN and INT64_MAX.
5639 #define WUFFS_BASE__I64__BYTE_LENGTH__MAX_INCL 20
5640 
5641 // WUFFS_BASE__U64__BYTE_LENGTH__MAX_INCL is the string length of
5642 // "+18446744073709551615", UINT64_MAX.
5643 #define WUFFS_BASE__U64__BYTE_LENGTH__MAX_INCL 21
5644 
5645 // wuffs_base__render_number_f64 writes the decimal encoding of x to dst and
5646 // returns the number of bytes written. If dst is shorter than the entire
5647 // encoding, it returns 0 (and no bytes are written).
5648 //
5649 // For those familiar with C's printf or Go's fmt.Printf functions:
5650 //  - "%e" means the WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_PRESENT option.
5651 //  - "%f" means the WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_ABSENT  option.
5652 //  - "%g" means neither or both bits are set.
5653 //
5654 // The precision argument controls the number of digits rendered, excluding the
5655 // exponent (the "e+05" in "1.23e+05"):
5656 //  - for "%e" and "%f" it is the number of digits after the decimal separator,
5657 //  - for "%g" it is the number of significant digits (and trailing zeroes are
5658 //    removed).
5659 //
5660 // A precision of 6 gives similar output to printf's defaults.
5661 //
5662 // A precision greater than 4095 is equivalent to 4095.
5663 //
5664 // The precision argument is ignored when the
5665 // WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION option is set. This is
5666 // similar to Go's strconv.FormatFloat with a negative (i.e. non-sensical)
5667 // precision, but there is no corresponding feature in C's printf.
5668 //
5669 // Extreme values of x will be rendered as "NaN", "Inf" (or "+Inf" if the
5670 // WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN option is set) or "-Inf".
5671 //
5672 // For modular builds that divide the base module into sub-modules, using this
5673 // function requires the WUFFS_CONFIG__MODULE__BASE__FLOATCONV sub-module, not
5674 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5675 WUFFS_BASE__MAYBE_STATIC size_t  //
5676 wuffs_base__render_number_f64(wuffs_base__slice_u8 dst,
5677                               double x,
5678                               uint32_t precision,
5679                               uint32_t options);
5680 
5681 // wuffs_base__render_number_i64 writes the decimal encoding of x to dst and
5682 // returns the number of bytes written. If dst is shorter than the entire
5683 // encoding, it returns 0 (and no bytes are written).
5684 //
5685 // dst will never be too short if its length is at least 20, also known as
5686 // WUFFS_BASE__I64__BYTE_LENGTH__MAX_INCL.
5687 //
5688 // For modular builds that divide the base module into sub-modules, using this
5689 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5690 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5691 WUFFS_BASE__MAYBE_STATIC size_t  //
5692 wuffs_base__render_number_i64(wuffs_base__slice_u8 dst,
5693                               int64_t x,
5694                               uint32_t options);
5695 
5696 // wuffs_base__render_number_u64 writes the decimal encoding of x to dst and
5697 // returns the number of bytes written. If dst is shorter than the entire
5698 // encoding, it returns 0 (and no bytes are written).
5699 //
5700 // dst will never be too short if its length is at least 21, also known as
5701 // WUFFS_BASE__U64__BYTE_LENGTH__MAX_INCL.
5702 //
5703 // For modular builds that divide the base module into sub-modules, using this
5704 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5705 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5706 WUFFS_BASE__MAYBE_STATIC size_t  //
5707 wuffs_base__render_number_u64(wuffs_base__slice_u8 dst,
5708                               uint64_t x,
5709                               uint32_t options);
5710 
5711 // ---------------- Base-16
5712 
5713 // Options (bitwise or'ed together) for wuffs_base__base_16__xxx functions.
5714 
5715 #define WUFFS_BASE__BASE_16__DEFAULT_OPTIONS ((uint32_t)0x00000000)
5716 
5717 // wuffs_base__base_16__decode2 converts "6A6b" to "jk", where e.g. 'j' is
5718 // U+006A. There are 2 src bytes for every dst byte.
5719 //
5720 // It assumes that the src bytes are two hexadecimal digits (0-9, A-F, a-f),
5721 // repeated. It may write nonsense bytes if not, although it will not read or
5722 // write out of bounds.
5723 //
5724 // For modular builds that divide the base module into sub-modules, using this
5725 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5726 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5727 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output  //
5728 wuffs_base__base_16__decode2(wuffs_base__slice_u8 dst,
5729                              wuffs_base__slice_u8 src,
5730                              bool src_closed,
5731                              uint32_t options);
5732 
5733 // wuffs_base__base_16__decode4 converts both "\\x6A\\x6b" and "??6a??6B" to
5734 // "jk", where e.g. 'j' is U+006A. There are 4 src bytes for every dst byte.
5735 //
5736 // It assumes that the src bytes are two ignored bytes and then two hexadecimal
5737 // digits (0-9, A-F, a-f), repeated. It may write nonsense bytes if not,
5738 // although it will not read or write out of bounds.
5739 //
5740 // For modular builds that divide the base module into sub-modules, using this
5741 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5742 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5743 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output  //
5744 wuffs_base__base_16__decode4(wuffs_base__slice_u8 dst,
5745                              wuffs_base__slice_u8 src,
5746                              bool src_closed,
5747                              uint32_t options);
5748 
5749 // wuffs_base__base_16__encode2 converts "jk" to "6A6B", where e.g. 'j' is
5750 // U+006A. There are 2 dst bytes for every src byte.
5751 //
5752 // For modular builds that divide the base module into sub-modules, using this
5753 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5754 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5755 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output  //
5756 wuffs_base__base_16__encode2(wuffs_base__slice_u8 dst,
5757                              wuffs_base__slice_u8 src,
5758                              bool src_closed,
5759                              uint32_t options);
5760 
5761 // wuffs_base__base_16__encode4 converts "jk" to "\\x6A\\x6B", where e.g. 'j'
5762 // is U+006A. There are 4 dst bytes for every src byte.
5763 //
5764 // For modular builds that divide the base module into sub-modules, using this
5765 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5766 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5767 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output  //
5768 wuffs_base__base_16__encode4(wuffs_base__slice_u8 dst,
5769                              wuffs_base__slice_u8 src,
5770                              bool src_closed,
5771                              uint32_t options);
5772 
5773 // ---------------- Base-64
5774 
5775 // Options (bitwise or'ed together) for wuffs_base__base_64__xxx functions.
5776 
5777 #define WUFFS_BASE__BASE_64__DEFAULT_OPTIONS ((uint32_t)0x00000000)
5778 
5779 // WUFFS_BASE__BASE_64__DECODE_ALLOW_PADDING means that, when decoding base-64,
5780 // the input may (but does not need to) be padded with '=' bytes so that the
5781 // overall encoded length in bytes is a multiple of 4. A successful decoding
5782 // will return a num_src that includes those padding bytes.
5783 //
5784 // Excess padding (e.g. three final '='s) will be rejected as bad data.
5785 #define WUFFS_BASE__BASE_64__DECODE_ALLOW_PADDING ((uint32_t)0x00000001)
5786 
5787 // WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING means that, when encoding base-64,
5788 // the output will be padded with '=' bytes so that the overall encoded length
5789 // in bytes is a multiple of 4.
5790 #define WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING ((uint32_t)0x00000002)
5791 
5792 // WUFFS_BASE__BASE_64__URL_ALPHABET means that, for base-64, the URL-friendly
5793 // and file-name-friendly alphabet be used, as per RFC 4648 section 5. When
5794 // this option bit is off, the standard alphabet from section 4 is used.
5795 #define WUFFS_BASE__BASE_64__URL_ALPHABET ((uint32_t)0x00000100)
5796 
5797 // wuffs_base__base_64__decode transforms base-64 encoded bytes from src to
5798 // arbitrary bytes in dst.
5799 //
5800 // It will not permit line breaks or other whitespace in src. Filtering those
5801 // out is the responsibility of the caller.
5802 //
5803 // For modular builds that divide the base module into sub-modules, using this
5804 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5805 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5806 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output  //
5807 wuffs_base__base_64__decode(wuffs_base__slice_u8 dst,
5808                             wuffs_base__slice_u8 src,
5809                             bool src_closed,
5810                             uint32_t options);
5811 
5812 // wuffs_base__base_64__encode transforms arbitrary bytes from src to base-64
5813 // encoded bytes in dst.
5814 //
5815 // For modular builds that divide the base module into sub-modules, using this
5816 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5817 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5818 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output  //
5819 wuffs_base__base_64__encode(wuffs_base__slice_u8 dst,
5820                             wuffs_base__slice_u8 src,
5821                             bool src_closed,
5822                             uint32_t options);
5823 
5824 // ---------------- Unicode and UTF-8
5825 
5826 #define WUFFS_BASE__UNICODE_CODE_POINT__MIN_INCL 0x00000000
5827 #define WUFFS_BASE__UNICODE_CODE_POINT__MAX_INCL 0x0010FFFF
5828 
5829 #define WUFFS_BASE__UNICODE_REPLACEMENT_CHARACTER 0x0000FFFD
5830 
5831 #define WUFFS_BASE__UNICODE_SURROGATE__MIN_INCL 0x0000D800
5832 #define WUFFS_BASE__UNICODE_SURROGATE__MAX_INCL 0x0000DFFF
5833 
5834 #define WUFFS_BASE__ASCII__MIN_INCL 0x00
5835 #define WUFFS_BASE__ASCII__MAX_INCL 0x7F
5836 
5837 #define WUFFS_BASE__UTF_8__BYTE_LENGTH__MIN_INCL 1
5838 #define WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL 4
5839 
5840 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_1__CODE_POINT__MIN_INCL 0x00000000
5841 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_1__CODE_POINT__MAX_INCL 0x0000007F
5842 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_2__CODE_POINT__MIN_INCL 0x00000080
5843 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_2__CODE_POINT__MAX_INCL 0x000007FF
5844 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_3__CODE_POINT__MIN_INCL 0x00000800
5845 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_3__CODE_POINT__MAX_INCL 0x0000FFFF
5846 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_4__CODE_POINT__MIN_INCL 0x00010000
5847 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_4__CODE_POINT__MAX_INCL 0x0010FFFF
5848 
5849 // --------
5850 
5851 // wuffs_base__utf_8__next__output is the type returned by
5852 // wuffs_base__utf_8__next.
5853 typedef struct wuffs_base__utf_8__next__output__struct {
5854   uint32_t code_point;
5855   uint32_t byte_length;
5856 
5857 #ifdef __cplusplus
5858   inline bool is_valid() const;
5859 #endif  // __cplusplus
5860 
5861 } wuffs_base__utf_8__next__output;
5862 
5863 static inline wuffs_base__utf_8__next__output  //
wuffs_base__make_utf_8__next__output(uint32_t code_point,uint32_t byte_length)5864 wuffs_base__make_utf_8__next__output(uint32_t code_point,
5865                                      uint32_t byte_length) {
5866   wuffs_base__utf_8__next__output ret;
5867   ret.code_point = code_point;
5868   ret.byte_length = byte_length;
5869   return ret;
5870 }
5871 
5872 static inline bool  //
wuffs_base__utf_8__next__output__is_valid(const wuffs_base__utf_8__next__output * o)5873 wuffs_base__utf_8__next__output__is_valid(
5874     const wuffs_base__utf_8__next__output* o) {
5875   if (o) {
5876     uint32_t cp = o->code_point;
5877     switch (o->byte_length) {
5878       case 1:
5879         return (cp <= 0x7F);
5880       case 2:
5881         return (0x080 <= cp) && (cp <= 0x7FF);
5882       case 3:
5883         // Avoid the 0xD800 ..= 0xDFFF surrogate range.
5884         return ((0x0800 <= cp) && (cp <= 0xD7FF)) ||
5885                ((0xE000 <= cp) && (cp <= 0xFFFF));
5886       case 4:
5887         return (0x00010000 <= cp) && (cp <= 0x0010FFFF);
5888     }
5889   }
5890   return false;
5891 }
5892 
5893 #ifdef __cplusplus
5894 
5895 inline bool  //
is_valid()5896 wuffs_base__utf_8__next__output::is_valid() const {
5897   return wuffs_base__utf_8__next__output__is_valid(this);
5898 }
5899 
5900 #endif  // __cplusplus
5901 
5902 // --------
5903 
5904 // wuffs_base__utf_8__encode writes the UTF-8 encoding of code_point to s and
5905 // returns the number of bytes written. If code_point is invalid, or if s is
5906 // shorter than the entire encoding, it returns 0 (and no bytes are written).
5907 //
5908 // s will never be too short if its length is at least 4, also known as
5909 // WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL.
5910 //
5911 // For modular builds that divide the base module into sub-modules, using this
5912 // function requires the WUFFS_CONFIG__MODULE__BASE__UTF8 sub-module, not just
5913 // WUFFS_CONFIG__MODULE__BASE__CORE.
5914 WUFFS_BASE__MAYBE_STATIC size_t  //
5915 wuffs_base__utf_8__encode(wuffs_base__slice_u8 dst, uint32_t code_point);
5916 
5917 // wuffs_base__utf_8__next returns the next UTF-8 code point (and that code
5918 // point's byte length) at the start of the read-only slice (s_ptr, s_len).
5919 //
5920 // There are exactly two cases in which this function returns something where
5921 // wuffs_base__utf_8__next__output__is_valid is false:
5922 //  - If s is empty then it returns {.code_point=0, .byte_length=0}.
5923 //  - If s is non-empty and starts with invalid UTF-8 then it returns
5924 //    {.code_point=WUFFS_BASE__UNICODE_REPLACEMENT_CHARACTER, .byte_length=1}.
5925 //
5926 // Otherwise, it returns something where
5927 // wuffs_base__utf_8__next__output__is_valid is true.
5928 //
5929 // In any case, it always returns an output that satisfies both of:
5930 //  - (output.code_point  <= WUFFS_BASE__UNICODE_CODE_POINT__MAX_INCL).
5931 //  - (output.byte_length <= s_len).
5932 //
5933 // If s is a sub-slice of a larger slice of valid UTF-8, but that sub-slice
5934 // boundary occurs in the middle of a multi-byte UTF-8 encoding of a single
5935 // code point, then this function may return something invalid. It is the
5936 // caller's responsibility to split on or otherwise manage UTF-8 boundaries.
5937 //
5938 // For modular builds that divide the base module into sub-modules, using this
5939 // function requires the WUFFS_CONFIG__MODULE__BASE__UTF8 sub-module, not just
5940 // WUFFS_CONFIG__MODULE__BASE__CORE.
5941 WUFFS_BASE__MAYBE_STATIC wuffs_base__utf_8__next__output  //
5942 wuffs_base__utf_8__next(const uint8_t* s_ptr, size_t s_len);
5943 
5944 // wuffs_base__utf_8__next_from_end is like wuffs_base__utf_8__next except that
5945 // it looks at the end of (s_ptr, s_len) instead of the start.
5946 //
5947 // For modular builds that divide the base module into sub-modules, using this
5948 // function requires the WUFFS_CONFIG__MODULE__BASE__UTF8 sub-module, not just
5949 // WUFFS_CONFIG__MODULE__BASE__CORE.
5950 WUFFS_BASE__MAYBE_STATIC wuffs_base__utf_8__next__output  //
5951 wuffs_base__utf_8__next_from_end(const uint8_t* s_ptr, size_t s_len);
5952 
5953 // wuffs_base__utf_8__longest_valid_prefix returns the largest n such that the
5954 // sub-slice s[..n] is valid UTF-8, where s is the read-only slice (s_ptr,
5955 // s_len).
5956 //
5957 // In particular, it returns s_len if and only if all of s is valid UTF-8.
5958 //
5959 // If s is a sub-slice of a larger slice of valid UTF-8, but that sub-slice
5960 // boundary occurs in the middle of a multi-byte UTF-8 encoding of a single
5961 // code point, then this function will return less than s_len. It is the
5962 // caller's responsibility to split on or otherwise manage UTF-8 boundaries.
5963 //
5964 // For modular builds that divide the base module into sub-modules, using this
5965 // function requires the WUFFS_CONFIG__MODULE__BASE__UTF8 sub-module, not just
5966 // WUFFS_CONFIG__MODULE__BASE__CORE.
5967 WUFFS_BASE__MAYBE_STATIC size_t  //
5968 wuffs_base__utf_8__longest_valid_prefix(const uint8_t* s_ptr, size_t s_len);
5969 
5970 // wuffs_base__ascii__longest_valid_prefix returns the largest n such that the
5971 // sub-slice s[..n] is valid ASCII, where s is the read-only slice (s_ptr,
5972 // s_len).
5973 //
5974 // In particular, it returns s_len if and only if all of s is valid ASCII.
5975 // Equivalently, when none of the bytes in s have the 0x80 high bit set.
5976 //
5977 // For modular builds that divide the base module into sub-modules, using this
5978 // function requires the WUFFS_CONFIG__MODULE__BASE__UTF8 sub-module, not just
5979 // WUFFS_CONFIG__MODULE__BASE__CORE.
5980 WUFFS_BASE__MAYBE_STATIC size_t  //
5981 wuffs_base__ascii__longest_valid_prefix(const uint8_t* s_ptr, size_t s_len);
5982 
5983 // ---------------- Interface Declarations.
5984 
5985 // For modular builds that divide the base module into sub-modules, using these
5986 // functions require the WUFFS_CONFIG__MODULE__BASE__INTERFACES sub-module, not
5987 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5988 
5989 // --------
5990 
5991 extern const char wuffs_base__hasher_u32__vtable_name[];
5992 
5993 typedef struct wuffs_base__hasher_u32__func_ptrs__struct {
5994   uint32_t (*checksum_u32)(
5995     const void* self);
5996   uint64_t (*get_quirk)(
5997     const void* self,
5998     uint32_t a_key);
5999   wuffs_base__status (*set_quirk)(
6000     void* self,
6001     uint32_t a_key,
6002     uint64_t a_value);
6003   wuffs_base__empty_struct (*update)(
6004     void* self,
6005     wuffs_base__slice_u8 a_x);
6006   uint32_t (*update_u32)(
6007     void* self,
6008     wuffs_base__slice_u8 a_x);
6009 } wuffs_base__hasher_u32__func_ptrs;
6010 
6011 typedef struct wuffs_base__hasher_u32__struct wuffs_base__hasher_u32;
6012 
6013 WUFFS_BASE__GENERATED_C_CODE
6014 WUFFS_BASE__MAYBE_STATIC uint32_t
6015 wuffs_base__hasher_u32__checksum_u32(
6016     const wuffs_base__hasher_u32* self);
6017 
6018 WUFFS_BASE__GENERATED_C_CODE
6019 WUFFS_BASE__MAYBE_STATIC uint64_t
6020 wuffs_base__hasher_u32__get_quirk(
6021     const wuffs_base__hasher_u32* self,
6022     uint32_t a_key);
6023 
6024 WUFFS_BASE__GENERATED_C_CODE
6025 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6026 wuffs_base__hasher_u32__set_quirk(
6027     wuffs_base__hasher_u32* self,
6028     uint32_t a_key,
6029     uint64_t a_value);
6030 
6031 WUFFS_BASE__GENERATED_C_CODE
6032 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
6033 wuffs_base__hasher_u32__update(
6034     wuffs_base__hasher_u32* self,
6035     wuffs_base__slice_u8 a_x);
6036 
6037 WUFFS_BASE__GENERATED_C_CODE
6038 WUFFS_BASE__MAYBE_STATIC uint32_t
6039 wuffs_base__hasher_u32__update_u32(
6040     wuffs_base__hasher_u32* self,
6041     wuffs_base__slice_u8 a_x);
6042 
6043 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6044 
6045 struct wuffs_base__hasher_u32__struct {
6046   struct {
6047     uint32_t magic;
6048     uint32_t active_coroutine;
6049     wuffs_base__vtable first_vtable;
6050   } private_impl;
6051 
6052 #ifdef __cplusplus
6053 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6054   using unique_ptr = std::unique_ptr<wuffs_base__hasher_u32, wuffs_unique_ptr_deleter>;
6055 #endif
6056 
6057   inline uint32_t
checksum_u32wuffs_base__hasher_u32__struct6058   checksum_u32() const {
6059     return wuffs_base__hasher_u32__checksum_u32(this);
6060   }
6061 
6062   inline uint64_t
get_quirkwuffs_base__hasher_u32__struct6063   get_quirk(
6064       uint32_t a_key) const {
6065     return wuffs_base__hasher_u32__get_quirk(
6066         this, a_key);
6067   }
6068 
6069   inline wuffs_base__status
set_quirkwuffs_base__hasher_u32__struct6070   set_quirk(
6071       uint32_t a_key,
6072       uint64_t a_value) {
6073     return wuffs_base__hasher_u32__set_quirk(
6074         this, a_key, a_value);
6075   }
6076 
6077   inline wuffs_base__empty_struct
updatewuffs_base__hasher_u32__struct6078   update(
6079       wuffs_base__slice_u8 a_x) {
6080     return wuffs_base__hasher_u32__update(
6081         this, a_x);
6082   }
6083 
6084   inline uint32_t
update_u32wuffs_base__hasher_u32__struct6085   update_u32(
6086       wuffs_base__slice_u8 a_x) {
6087     return wuffs_base__hasher_u32__update_u32(
6088         this, a_x);
6089   }
6090 
6091 #endif  // __cplusplus
6092 };  // struct wuffs_base__hasher_u32__struct
6093 
6094 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6095 
6096 // --------
6097 
6098 extern const char wuffs_base__hasher_u64__vtable_name[];
6099 
6100 typedef struct wuffs_base__hasher_u64__func_ptrs__struct {
6101   uint64_t (*checksum_u64)(
6102     const void* self);
6103   uint64_t (*get_quirk)(
6104     const void* self,
6105     uint32_t a_key);
6106   wuffs_base__status (*set_quirk)(
6107     void* self,
6108     uint32_t a_key,
6109     uint64_t a_value);
6110   wuffs_base__empty_struct (*update)(
6111     void* self,
6112     wuffs_base__slice_u8 a_x);
6113   uint64_t (*update_u64)(
6114     void* self,
6115     wuffs_base__slice_u8 a_x);
6116 } wuffs_base__hasher_u64__func_ptrs;
6117 
6118 typedef struct wuffs_base__hasher_u64__struct wuffs_base__hasher_u64;
6119 
6120 WUFFS_BASE__GENERATED_C_CODE
6121 WUFFS_BASE__MAYBE_STATIC uint64_t
6122 wuffs_base__hasher_u64__checksum_u64(
6123     const wuffs_base__hasher_u64* self);
6124 
6125 WUFFS_BASE__GENERATED_C_CODE
6126 WUFFS_BASE__MAYBE_STATIC uint64_t
6127 wuffs_base__hasher_u64__get_quirk(
6128     const wuffs_base__hasher_u64* self,
6129     uint32_t a_key);
6130 
6131 WUFFS_BASE__GENERATED_C_CODE
6132 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6133 wuffs_base__hasher_u64__set_quirk(
6134     wuffs_base__hasher_u64* self,
6135     uint32_t a_key,
6136     uint64_t a_value);
6137 
6138 WUFFS_BASE__GENERATED_C_CODE
6139 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
6140 wuffs_base__hasher_u64__update(
6141     wuffs_base__hasher_u64* self,
6142     wuffs_base__slice_u8 a_x);
6143 
6144 WUFFS_BASE__GENERATED_C_CODE
6145 WUFFS_BASE__MAYBE_STATIC uint64_t
6146 wuffs_base__hasher_u64__update_u64(
6147     wuffs_base__hasher_u64* self,
6148     wuffs_base__slice_u8 a_x);
6149 
6150 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6151 
6152 struct wuffs_base__hasher_u64__struct {
6153   struct {
6154     uint32_t magic;
6155     uint32_t active_coroutine;
6156     wuffs_base__vtable first_vtable;
6157   } private_impl;
6158 
6159 #ifdef __cplusplus
6160 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6161   using unique_ptr = std::unique_ptr<wuffs_base__hasher_u64, wuffs_unique_ptr_deleter>;
6162 #endif
6163 
6164   inline uint64_t
checksum_u64wuffs_base__hasher_u64__struct6165   checksum_u64() const {
6166     return wuffs_base__hasher_u64__checksum_u64(this);
6167   }
6168 
6169   inline uint64_t
get_quirkwuffs_base__hasher_u64__struct6170   get_quirk(
6171       uint32_t a_key) const {
6172     return wuffs_base__hasher_u64__get_quirk(
6173         this, a_key);
6174   }
6175 
6176   inline wuffs_base__status
set_quirkwuffs_base__hasher_u64__struct6177   set_quirk(
6178       uint32_t a_key,
6179       uint64_t a_value) {
6180     return wuffs_base__hasher_u64__set_quirk(
6181         this, a_key, a_value);
6182   }
6183 
6184   inline wuffs_base__empty_struct
updatewuffs_base__hasher_u64__struct6185   update(
6186       wuffs_base__slice_u8 a_x) {
6187     return wuffs_base__hasher_u64__update(
6188         this, a_x);
6189   }
6190 
6191   inline uint64_t
update_u64wuffs_base__hasher_u64__struct6192   update_u64(
6193       wuffs_base__slice_u8 a_x) {
6194     return wuffs_base__hasher_u64__update_u64(
6195         this, a_x);
6196   }
6197 
6198 #endif  // __cplusplus
6199 };  // struct wuffs_base__hasher_u64__struct
6200 
6201 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6202 
6203 // --------
6204 
6205 extern const char wuffs_base__image_decoder__vtable_name[];
6206 
6207 typedef struct wuffs_base__image_decoder__func_ptrs__struct {
6208   wuffs_base__status (*decode_frame)(
6209     void* self,
6210     wuffs_base__pixel_buffer* a_dst,
6211     wuffs_base__io_buffer* a_src,
6212     wuffs_base__pixel_blend a_blend,
6213     wuffs_base__slice_u8 a_workbuf,
6214     wuffs_base__decode_frame_options* a_opts);
6215   wuffs_base__status (*decode_frame_config)(
6216     void* self,
6217     wuffs_base__frame_config* a_dst,
6218     wuffs_base__io_buffer* a_src);
6219   wuffs_base__status (*decode_image_config)(
6220     void* self,
6221     wuffs_base__image_config* a_dst,
6222     wuffs_base__io_buffer* a_src);
6223   wuffs_base__rect_ie_u32 (*frame_dirty_rect)(
6224     const void* self);
6225   uint64_t (*get_quirk)(
6226     const void* self,
6227     uint32_t a_key);
6228   uint64_t (*history_retain_length)(
6229     const void* self);
6230   uint32_t (*num_animation_loops)(
6231     const void* self);
6232   uint64_t (*num_decoded_frame_configs)(
6233     const void* self);
6234   uint64_t (*num_decoded_frames)(
6235     const void* self);
6236   wuffs_base__status (*restart_frame)(
6237     void* self,
6238     uint64_t a_index,
6239     uint64_t a_io_position);
6240   wuffs_base__status (*set_quirk)(
6241     void* self,
6242     uint32_t a_key,
6243     uint64_t a_value);
6244   wuffs_base__empty_struct (*set_report_metadata)(
6245     void* self,
6246     uint32_t a_fourcc,
6247     bool a_report);
6248   wuffs_base__status (*tell_me_more)(
6249     void* self,
6250     wuffs_base__io_buffer* a_dst,
6251     wuffs_base__more_information* a_minfo,
6252     wuffs_base__io_buffer* a_src);
6253   wuffs_base__range_ii_u64 (*workbuf_len)(
6254     const void* self);
6255 } wuffs_base__image_decoder__func_ptrs;
6256 
6257 typedef struct wuffs_base__image_decoder__struct wuffs_base__image_decoder;
6258 
6259 WUFFS_BASE__GENERATED_C_CODE
6260 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6261 wuffs_base__image_decoder__decode_frame(
6262     wuffs_base__image_decoder* self,
6263     wuffs_base__pixel_buffer* a_dst,
6264     wuffs_base__io_buffer* a_src,
6265     wuffs_base__pixel_blend a_blend,
6266     wuffs_base__slice_u8 a_workbuf,
6267     wuffs_base__decode_frame_options* a_opts);
6268 
6269 WUFFS_BASE__GENERATED_C_CODE
6270 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6271 wuffs_base__image_decoder__decode_frame_config(
6272     wuffs_base__image_decoder* self,
6273     wuffs_base__frame_config* a_dst,
6274     wuffs_base__io_buffer* a_src);
6275 
6276 WUFFS_BASE__GENERATED_C_CODE
6277 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6278 wuffs_base__image_decoder__decode_image_config(
6279     wuffs_base__image_decoder* self,
6280     wuffs_base__image_config* a_dst,
6281     wuffs_base__io_buffer* a_src);
6282 
6283 WUFFS_BASE__GENERATED_C_CODE
6284 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
6285 wuffs_base__image_decoder__frame_dirty_rect(
6286     const wuffs_base__image_decoder* self);
6287 
6288 WUFFS_BASE__GENERATED_C_CODE
6289 WUFFS_BASE__MAYBE_STATIC uint64_t
6290 wuffs_base__image_decoder__get_quirk(
6291     const wuffs_base__image_decoder* self,
6292     uint32_t a_key);
6293 
6294 WUFFS_BASE__GENERATED_C_CODE
6295 WUFFS_BASE__MAYBE_STATIC uint64_t
6296 wuffs_base__image_decoder__history_retain_length(
6297     const wuffs_base__image_decoder* self);
6298 
6299 WUFFS_BASE__GENERATED_C_CODE
6300 WUFFS_BASE__MAYBE_STATIC uint32_t
6301 wuffs_base__image_decoder__num_animation_loops(
6302     const wuffs_base__image_decoder* self);
6303 
6304 WUFFS_BASE__GENERATED_C_CODE
6305 WUFFS_BASE__MAYBE_STATIC uint64_t
6306 wuffs_base__image_decoder__num_decoded_frame_configs(
6307     const wuffs_base__image_decoder* self);
6308 
6309 WUFFS_BASE__GENERATED_C_CODE
6310 WUFFS_BASE__MAYBE_STATIC uint64_t
6311 wuffs_base__image_decoder__num_decoded_frames(
6312     const wuffs_base__image_decoder* self);
6313 
6314 WUFFS_BASE__GENERATED_C_CODE
6315 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6316 wuffs_base__image_decoder__restart_frame(
6317     wuffs_base__image_decoder* self,
6318     uint64_t a_index,
6319     uint64_t a_io_position);
6320 
6321 WUFFS_BASE__GENERATED_C_CODE
6322 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6323 wuffs_base__image_decoder__set_quirk(
6324     wuffs_base__image_decoder* self,
6325     uint32_t a_key,
6326     uint64_t a_value);
6327 
6328 WUFFS_BASE__GENERATED_C_CODE
6329 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
6330 wuffs_base__image_decoder__set_report_metadata(
6331     wuffs_base__image_decoder* self,
6332     uint32_t a_fourcc,
6333     bool a_report);
6334 
6335 WUFFS_BASE__GENERATED_C_CODE
6336 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6337 wuffs_base__image_decoder__tell_me_more(
6338     wuffs_base__image_decoder* self,
6339     wuffs_base__io_buffer* a_dst,
6340     wuffs_base__more_information* a_minfo,
6341     wuffs_base__io_buffer* a_src);
6342 
6343 WUFFS_BASE__GENERATED_C_CODE
6344 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
6345 wuffs_base__image_decoder__workbuf_len(
6346     const wuffs_base__image_decoder* self);
6347 
6348 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6349 
6350 struct wuffs_base__image_decoder__struct {
6351   struct {
6352     uint32_t magic;
6353     uint32_t active_coroutine;
6354     wuffs_base__vtable first_vtable;
6355   } private_impl;
6356 
6357 #ifdef __cplusplus
6358 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6359   using unique_ptr = std::unique_ptr<wuffs_base__image_decoder, wuffs_unique_ptr_deleter>;
6360 #endif
6361 
6362   inline wuffs_base__status
decode_framewuffs_base__image_decoder__struct6363   decode_frame(
6364       wuffs_base__pixel_buffer* a_dst,
6365       wuffs_base__io_buffer* a_src,
6366       wuffs_base__pixel_blend a_blend,
6367       wuffs_base__slice_u8 a_workbuf,
6368       wuffs_base__decode_frame_options* a_opts) {
6369     return wuffs_base__image_decoder__decode_frame(
6370         this, a_dst, a_src, a_blend, a_workbuf, a_opts);
6371   }
6372 
6373   inline wuffs_base__status
decode_frame_configwuffs_base__image_decoder__struct6374   decode_frame_config(
6375       wuffs_base__frame_config* a_dst,
6376       wuffs_base__io_buffer* a_src) {
6377     return wuffs_base__image_decoder__decode_frame_config(
6378         this, a_dst, a_src);
6379   }
6380 
6381   inline wuffs_base__status
decode_image_configwuffs_base__image_decoder__struct6382   decode_image_config(
6383       wuffs_base__image_config* a_dst,
6384       wuffs_base__io_buffer* a_src) {
6385     return wuffs_base__image_decoder__decode_image_config(
6386         this, a_dst, a_src);
6387   }
6388 
6389   inline wuffs_base__rect_ie_u32
frame_dirty_rectwuffs_base__image_decoder__struct6390   frame_dirty_rect() const {
6391     return wuffs_base__image_decoder__frame_dirty_rect(this);
6392   }
6393 
6394   inline uint64_t
get_quirkwuffs_base__image_decoder__struct6395   get_quirk(
6396       uint32_t a_key) const {
6397     return wuffs_base__image_decoder__get_quirk(
6398         this, a_key);
6399   }
6400 
6401   inline uint64_t
history_retain_lengthwuffs_base__image_decoder__struct6402   history_retain_length() const {
6403     return wuffs_base__image_decoder__history_retain_length(this);
6404   }
6405 
6406   inline uint32_t
num_animation_loopswuffs_base__image_decoder__struct6407   num_animation_loops() const {
6408     return wuffs_base__image_decoder__num_animation_loops(this);
6409   }
6410 
6411   inline uint64_t
num_decoded_frame_configswuffs_base__image_decoder__struct6412   num_decoded_frame_configs() const {
6413     return wuffs_base__image_decoder__num_decoded_frame_configs(this);
6414   }
6415 
6416   inline uint64_t
num_decoded_frameswuffs_base__image_decoder__struct6417   num_decoded_frames() const {
6418     return wuffs_base__image_decoder__num_decoded_frames(this);
6419   }
6420 
6421   inline wuffs_base__status
restart_framewuffs_base__image_decoder__struct6422   restart_frame(
6423       uint64_t a_index,
6424       uint64_t a_io_position) {
6425     return wuffs_base__image_decoder__restart_frame(
6426         this, a_index, a_io_position);
6427   }
6428 
6429   inline wuffs_base__status
set_quirkwuffs_base__image_decoder__struct6430   set_quirk(
6431       uint32_t a_key,
6432       uint64_t a_value) {
6433     return wuffs_base__image_decoder__set_quirk(
6434         this, a_key, a_value);
6435   }
6436 
6437   inline wuffs_base__empty_struct
set_report_metadatawuffs_base__image_decoder__struct6438   set_report_metadata(
6439       uint32_t a_fourcc,
6440       bool a_report) {
6441     return wuffs_base__image_decoder__set_report_metadata(
6442         this, a_fourcc, a_report);
6443   }
6444 
6445   inline wuffs_base__status
tell_me_morewuffs_base__image_decoder__struct6446   tell_me_more(
6447       wuffs_base__io_buffer* a_dst,
6448       wuffs_base__more_information* a_minfo,
6449       wuffs_base__io_buffer* a_src) {
6450     return wuffs_base__image_decoder__tell_me_more(
6451         this, a_dst, a_minfo, a_src);
6452   }
6453 
6454   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_base__image_decoder__struct6455   workbuf_len() const {
6456     return wuffs_base__image_decoder__workbuf_len(this);
6457   }
6458 
6459 #endif  // __cplusplus
6460 };  // struct wuffs_base__image_decoder__struct
6461 
6462 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6463 
6464 // --------
6465 
6466 extern const char wuffs_base__io_transformer__vtable_name[];
6467 
6468 typedef struct wuffs_base__io_transformer__func_ptrs__struct {
6469   uint64_t (*get_quirk)(
6470     const void* self,
6471     uint32_t a_key);
6472   uint64_t (*history_retain_length)(
6473     const void* self);
6474   wuffs_base__status (*set_quirk)(
6475     void* self,
6476     uint32_t a_key,
6477     uint64_t a_value);
6478   wuffs_base__status (*transform_io)(
6479     void* self,
6480     wuffs_base__io_buffer* a_dst,
6481     wuffs_base__io_buffer* a_src,
6482     wuffs_base__slice_u8 a_workbuf);
6483   wuffs_base__range_ii_u64 (*workbuf_len)(
6484     const void* self);
6485 } wuffs_base__io_transformer__func_ptrs;
6486 
6487 typedef struct wuffs_base__io_transformer__struct wuffs_base__io_transformer;
6488 
6489 WUFFS_BASE__GENERATED_C_CODE
6490 WUFFS_BASE__MAYBE_STATIC uint64_t
6491 wuffs_base__io_transformer__get_quirk(
6492     const wuffs_base__io_transformer* self,
6493     uint32_t a_key);
6494 
6495 WUFFS_BASE__GENERATED_C_CODE
6496 WUFFS_BASE__MAYBE_STATIC uint64_t
6497 wuffs_base__io_transformer__history_retain_length(
6498     const wuffs_base__io_transformer* self);
6499 
6500 WUFFS_BASE__GENERATED_C_CODE
6501 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6502 wuffs_base__io_transformer__set_quirk(
6503     wuffs_base__io_transformer* self,
6504     uint32_t a_key,
6505     uint64_t a_value);
6506 
6507 WUFFS_BASE__GENERATED_C_CODE
6508 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6509 wuffs_base__io_transformer__transform_io(
6510     wuffs_base__io_transformer* self,
6511     wuffs_base__io_buffer* a_dst,
6512     wuffs_base__io_buffer* a_src,
6513     wuffs_base__slice_u8 a_workbuf);
6514 
6515 WUFFS_BASE__GENERATED_C_CODE
6516 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
6517 wuffs_base__io_transformer__workbuf_len(
6518     const wuffs_base__io_transformer* self);
6519 
6520 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6521 
6522 struct wuffs_base__io_transformer__struct {
6523   struct {
6524     uint32_t magic;
6525     uint32_t active_coroutine;
6526     wuffs_base__vtable first_vtable;
6527   } private_impl;
6528 
6529 #ifdef __cplusplus
6530 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6531   using unique_ptr = std::unique_ptr<wuffs_base__io_transformer, wuffs_unique_ptr_deleter>;
6532 #endif
6533 
6534   inline uint64_t
get_quirkwuffs_base__io_transformer__struct6535   get_quirk(
6536       uint32_t a_key) const {
6537     return wuffs_base__io_transformer__get_quirk(
6538         this, a_key);
6539   }
6540 
6541   inline uint64_t
history_retain_lengthwuffs_base__io_transformer__struct6542   history_retain_length() const {
6543     return wuffs_base__io_transformer__history_retain_length(this);
6544   }
6545 
6546   inline wuffs_base__status
set_quirkwuffs_base__io_transformer__struct6547   set_quirk(
6548       uint32_t a_key,
6549       uint64_t a_value) {
6550     return wuffs_base__io_transformer__set_quirk(
6551         this, a_key, a_value);
6552   }
6553 
6554   inline wuffs_base__status
transform_iowuffs_base__io_transformer__struct6555   transform_io(
6556       wuffs_base__io_buffer* a_dst,
6557       wuffs_base__io_buffer* a_src,
6558       wuffs_base__slice_u8 a_workbuf) {
6559     return wuffs_base__io_transformer__transform_io(
6560         this, a_dst, a_src, a_workbuf);
6561   }
6562 
6563   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_base__io_transformer__struct6564   workbuf_len() const {
6565     return wuffs_base__io_transformer__workbuf_len(this);
6566   }
6567 
6568 #endif  // __cplusplus
6569 };  // struct wuffs_base__io_transformer__struct
6570 
6571 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6572 
6573 // --------
6574 
6575 extern const char wuffs_base__token_decoder__vtable_name[];
6576 
6577 typedef struct wuffs_base__token_decoder__func_ptrs__struct {
6578   wuffs_base__status (*decode_tokens)(
6579     void* self,
6580     wuffs_base__token_buffer* a_dst,
6581     wuffs_base__io_buffer* a_src,
6582     wuffs_base__slice_u8 a_workbuf);
6583   uint64_t (*get_quirk)(
6584     const void* self,
6585     uint32_t a_key);
6586   uint64_t (*history_retain_length)(
6587     const void* self);
6588   wuffs_base__status (*set_quirk)(
6589     void* self,
6590     uint32_t a_key,
6591     uint64_t a_value);
6592   wuffs_base__range_ii_u64 (*workbuf_len)(
6593     const void* self);
6594 } wuffs_base__token_decoder__func_ptrs;
6595 
6596 typedef struct wuffs_base__token_decoder__struct wuffs_base__token_decoder;
6597 
6598 WUFFS_BASE__GENERATED_C_CODE
6599 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6600 wuffs_base__token_decoder__decode_tokens(
6601     wuffs_base__token_decoder* self,
6602     wuffs_base__token_buffer* a_dst,
6603     wuffs_base__io_buffer* a_src,
6604     wuffs_base__slice_u8 a_workbuf);
6605 
6606 WUFFS_BASE__GENERATED_C_CODE
6607 WUFFS_BASE__MAYBE_STATIC uint64_t
6608 wuffs_base__token_decoder__get_quirk(
6609     const wuffs_base__token_decoder* self,
6610     uint32_t a_key);
6611 
6612 WUFFS_BASE__GENERATED_C_CODE
6613 WUFFS_BASE__MAYBE_STATIC uint64_t
6614 wuffs_base__token_decoder__history_retain_length(
6615     const wuffs_base__token_decoder* self);
6616 
6617 WUFFS_BASE__GENERATED_C_CODE
6618 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6619 wuffs_base__token_decoder__set_quirk(
6620     wuffs_base__token_decoder* self,
6621     uint32_t a_key,
6622     uint64_t a_value);
6623 
6624 WUFFS_BASE__GENERATED_C_CODE
6625 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
6626 wuffs_base__token_decoder__workbuf_len(
6627     const wuffs_base__token_decoder* self);
6628 
6629 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6630 
6631 struct wuffs_base__token_decoder__struct {
6632   struct {
6633     uint32_t magic;
6634     uint32_t active_coroutine;
6635     wuffs_base__vtable first_vtable;
6636   } private_impl;
6637 
6638 #ifdef __cplusplus
6639 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6640   using unique_ptr = std::unique_ptr<wuffs_base__token_decoder, wuffs_unique_ptr_deleter>;
6641 #endif
6642 
6643   inline wuffs_base__status
decode_tokenswuffs_base__token_decoder__struct6644   decode_tokens(
6645       wuffs_base__token_buffer* a_dst,
6646       wuffs_base__io_buffer* a_src,
6647       wuffs_base__slice_u8 a_workbuf) {
6648     return wuffs_base__token_decoder__decode_tokens(
6649         this, a_dst, a_src, a_workbuf);
6650   }
6651 
6652   inline uint64_t
get_quirkwuffs_base__token_decoder__struct6653   get_quirk(
6654       uint32_t a_key) const {
6655     return wuffs_base__token_decoder__get_quirk(
6656         this, a_key);
6657   }
6658 
6659   inline uint64_t
history_retain_lengthwuffs_base__token_decoder__struct6660   history_retain_length() const {
6661     return wuffs_base__token_decoder__history_retain_length(this);
6662   }
6663 
6664   inline wuffs_base__status
set_quirkwuffs_base__token_decoder__struct6665   set_quirk(
6666       uint32_t a_key,
6667       uint64_t a_value) {
6668     return wuffs_base__token_decoder__set_quirk(
6669         this, a_key, a_value);
6670   }
6671 
6672   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_base__token_decoder__struct6673   workbuf_len() const {
6674     return wuffs_base__token_decoder__workbuf_len(this);
6675   }
6676 
6677 #endif  // __cplusplus
6678 };  // struct wuffs_base__token_decoder__struct
6679 
6680 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6681 
6682 // ----------------
6683 
6684 #ifdef __cplusplus
6685 }  // extern "C"
6686 #endif
6687 
6688 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ADLER32) || defined(WUFFS_NONMONOLITHIC)
6689 
6690 // ---------------- Status Codes
6691 
6692 // ---------------- Public Consts
6693 
6694 // ---------------- Struct Declarations
6695 
6696 typedef struct wuffs_adler32__hasher__struct wuffs_adler32__hasher;
6697 
6698 #ifdef __cplusplus
6699 extern "C" {
6700 #endif
6701 
6702 // ---------------- Public Initializer Prototypes
6703 
6704 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
6705 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
6706 //
6707 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
6708 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
6709 
6710 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
6711 wuffs_adler32__hasher__initialize(
6712     wuffs_adler32__hasher* self,
6713     size_t sizeof_star_self,
6714     uint64_t wuffs_version,
6715     uint32_t options);
6716 
6717 size_t
6718 sizeof__wuffs_adler32__hasher(void);
6719 
6720 // ---------------- Allocs
6721 
6722 // These functions allocate and initialize Wuffs structs. They return NULL if
6723 // memory allocation fails. If they return non-NULL, there is no need to call
6724 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
6725 // calling free on the returned pointer. That pointer is effectively a C++
6726 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
6727 
6728 wuffs_adler32__hasher*
6729 wuffs_adler32__hasher__alloc(void);
6730 
6731 static inline wuffs_base__hasher_u32*
wuffs_adler32__hasher__alloc_as__wuffs_base__hasher_u32(void)6732 wuffs_adler32__hasher__alloc_as__wuffs_base__hasher_u32(void) {
6733   return (wuffs_base__hasher_u32*)(wuffs_adler32__hasher__alloc());
6734 }
6735 
6736 // ---------------- Upcasts
6737 
6738 static inline wuffs_base__hasher_u32*
wuffs_adler32__hasher__upcast_as__wuffs_base__hasher_u32(wuffs_adler32__hasher * p)6739 wuffs_adler32__hasher__upcast_as__wuffs_base__hasher_u32(
6740     wuffs_adler32__hasher* p) {
6741   return (wuffs_base__hasher_u32*)p;
6742 }
6743 
6744 // ---------------- Public Function Prototypes
6745 
6746 WUFFS_BASE__GENERATED_C_CODE
6747 WUFFS_BASE__MAYBE_STATIC uint64_t
6748 wuffs_adler32__hasher__get_quirk(
6749     const wuffs_adler32__hasher* self,
6750     uint32_t a_key);
6751 
6752 WUFFS_BASE__GENERATED_C_CODE
6753 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6754 wuffs_adler32__hasher__set_quirk(
6755     wuffs_adler32__hasher* self,
6756     uint32_t a_key,
6757     uint64_t a_value);
6758 
6759 WUFFS_BASE__GENERATED_C_CODE
6760 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
6761 wuffs_adler32__hasher__update(
6762     wuffs_adler32__hasher* self,
6763     wuffs_base__slice_u8 a_x);
6764 
6765 WUFFS_BASE__GENERATED_C_CODE
6766 WUFFS_BASE__MAYBE_STATIC uint32_t
6767 wuffs_adler32__hasher__update_u32(
6768     wuffs_adler32__hasher* self,
6769     wuffs_base__slice_u8 a_x);
6770 
6771 WUFFS_BASE__GENERATED_C_CODE
6772 WUFFS_BASE__MAYBE_STATIC uint32_t
6773 wuffs_adler32__hasher__checksum_u32(
6774     const wuffs_adler32__hasher* self);
6775 
6776 #ifdef __cplusplus
6777 }  // extern "C"
6778 #endif
6779 
6780 // ---------------- Struct Definitions
6781 
6782 // These structs' fields, and the sizeof them, are private implementation
6783 // details that aren't guaranteed to be stable across Wuffs versions.
6784 //
6785 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
6786 
6787 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6788 
6789 struct wuffs_adler32__hasher__struct {
6790   // Do not access the private_impl's or private_data's fields directly. There
6791   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
6792   // the wuffs_foo__bar__baz functions.
6793   //
6794   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
6795   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
6796 
6797   struct {
6798     uint32_t magic;
6799     uint32_t active_coroutine;
6800     wuffs_base__vtable vtable_for__wuffs_base__hasher_u32;
6801     wuffs_base__vtable null_vtable;
6802 
6803     uint32_t f_state;
6804     bool f_started;
6805 
6806     wuffs_base__empty_struct (*choosy_up)(
6807         wuffs_adler32__hasher* self,
6808         wuffs_base__slice_u8 a_x);
6809   } private_impl;
6810 
6811 #ifdef __cplusplus
6812 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6813   using unique_ptr = std::unique_ptr<wuffs_adler32__hasher, wuffs_unique_ptr_deleter>;
6814 
6815   // On failure, the alloc_etc functions return nullptr. They don't throw.
6816 
6817   static inline unique_ptr
allocwuffs_adler32__hasher__struct6818   alloc() {
6819     return unique_ptr(wuffs_adler32__hasher__alloc());
6820   }
6821 
6822   static inline wuffs_base__hasher_u32::unique_ptr
alloc_as__wuffs_base__hasher_u32wuffs_adler32__hasher__struct6823   alloc_as__wuffs_base__hasher_u32() {
6824     return wuffs_base__hasher_u32::unique_ptr(
6825         wuffs_adler32__hasher__alloc_as__wuffs_base__hasher_u32());
6826   }
6827 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6828 
6829 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
6830   // Disallow constructing or copying an object via standard C++ mechanisms,
6831   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
6832   // size and field layout is not part of the public, stable, memory-safe API.
6833   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
6834   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
6835   // their first argument) rather than tweaking bar.private_impl.qux fields.
6836   //
6837   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
6838   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
6839   // order to provide convenience methods. These forward on "this", so that you
6840   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
6841   wuffs_adler32__hasher__struct() = delete;
6842   wuffs_adler32__hasher__struct(const wuffs_adler32__hasher__struct&) = delete;
6843   wuffs_adler32__hasher__struct& operator=(
6844       const wuffs_adler32__hasher__struct&) = delete;
6845 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
6846 
6847 #if !defined(WUFFS_IMPLEMENTATION)
6848   // As above, the size of the struct is not part of the public API, and unless
6849   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
6850   // allocated, not stack allocated. Its size is not intended to be known at
6851   // compile time, but it is unfortunately divulged as a side effect of
6852   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
6853   // instead of "sizeof T", invoking the operator. To make the two values
6854   // different, so that passing the latter will be rejected by the initialize
6855   // function, we add an arbitrary amount of dead weight.
6856   uint8_t dead_weight[123000000];  // 123 MB.
6857 #endif  // !defined(WUFFS_IMPLEMENTATION)
6858 
6859   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_adler32__hasher__struct6860   initialize(
6861       size_t sizeof_star_self,
6862       uint64_t wuffs_version,
6863       uint32_t options) {
6864     return wuffs_adler32__hasher__initialize(
6865         this, sizeof_star_self, wuffs_version, options);
6866   }
6867 
6868   inline wuffs_base__hasher_u32*
upcast_as__wuffs_base__hasher_u32wuffs_adler32__hasher__struct6869   upcast_as__wuffs_base__hasher_u32() {
6870     return (wuffs_base__hasher_u32*)this;
6871   }
6872 
6873   inline uint64_t
get_quirkwuffs_adler32__hasher__struct6874   get_quirk(
6875       uint32_t a_key) const {
6876     return wuffs_adler32__hasher__get_quirk(this, a_key);
6877   }
6878 
6879   inline wuffs_base__status
set_quirkwuffs_adler32__hasher__struct6880   set_quirk(
6881       uint32_t a_key,
6882       uint64_t a_value) {
6883     return wuffs_adler32__hasher__set_quirk(this, a_key, a_value);
6884   }
6885 
6886   inline wuffs_base__empty_struct
updatewuffs_adler32__hasher__struct6887   update(
6888       wuffs_base__slice_u8 a_x) {
6889     return wuffs_adler32__hasher__update(this, a_x);
6890   }
6891 
6892   inline uint32_t
update_u32wuffs_adler32__hasher__struct6893   update_u32(
6894       wuffs_base__slice_u8 a_x) {
6895     return wuffs_adler32__hasher__update_u32(this, a_x);
6896   }
6897 
6898   inline uint32_t
checksum_u32wuffs_adler32__hasher__struct6899   checksum_u32() const {
6900     return wuffs_adler32__hasher__checksum_u32(this);
6901   }
6902 
6903 #endif  // __cplusplus
6904 };  // struct wuffs_adler32__hasher__struct
6905 
6906 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6907 
6908 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ADLER32) || defined(WUFFS_NONMONOLITHIC)
6909 
6910 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BMP) || defined(WUFFS_NONMONOLITHIC)
6911 
6912 // ---------------- Status Codes
6913 
6914 extern const char wuffs_bmp__error__bad_header[];
6915 extern const char wuffs_bmp__error__bad_rle_compression[];
6916 extern const char wuffs_bmp__error__truncated_input[];
6917 extern const char wuffs_bmp__error__unsupported_bmp_file[];
6918 
6919 // ---------------- Public Consts
6920 
6921 #define WUFFS_BMP__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0
6922 
6923 #define WUFFS_BMP__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
6924 
6925 // ---------------- Struct Declarations
6926 
6927 typedef struct wuffs_bmp__decoder__struct wuffs_bmp__decoder;
6928 
6929 #ifdef __cplusplus
6930 extern "C" {
6931 #endif
6932 
6933 // ---------------- Public Initializer Prototypes
6934 
6935 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
6936 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
6937 //
6938 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
6939 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
6940 
6941 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
6942 wuffs_bmp__decoder__initialize(
6943     wuffs_bmp__decoder* self,
6944     size_t sizeof_star_self,
6945     uint64_t wuffs_version,
6946     uint32_t options);
6947 
6948 size_t
6949 sizeof__wuffs_bmp__decoder(void);
6950 
6951 // ---------------- Allocs
6952 
6953 // These functions allocate and initialize Wuffs structs. They return NULL if
6954 // memory allocation fails. If they return non-NULL, there is no need to call
6955 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
6956 // calling free on the returned pointer. That pointer is effectively a C++
6957 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
6958 
6959 wuffs_bmp__decoder*
6960 wuffs_bmp__decoder__alloc(void);
6961 
6962 static inline wuffs_base__image_decoder*
wuffs_bmp__decoder__alloc_as__wuffs_base__image_decoder(void)6963 wuffs_bmp__decoder__alloc_as__wuffs_base__image_decoder(void) {
6964   return (wuffs_base__image_decoder*)(wuffs_bmp__decoder__alloc());
6965 }
6966 
6967 // ---------------- Upcasts
6968 
6969 static inline wuffs_base__image_decoder*
wuffs_bmp__decoder__upcast_as__wuffs_base__image_decoder(wuffs_bmp__decoder * p)6970 wuffs_bmp__decoder__upcast_as__wuffs_base__image_decoder(
6971     wuffs_bmp__decoder* p) {
6972   return (wuffs_base__image_decoder*)p;
6973 }
6974 
6975 // ---------------- Public Function Prototypes
6976 
6977 WUFFS_BASE__GENERATED_C_CODE
6978 WUFFS_BASE__MAYBE_STATIC uint64_t
6979 wuffs_bmp__decoder__get_quirk(
6980     const wuffs_bmp__decoder* self,
6981     uint32_t a_key);
6982 
6983 WUFFS_BASE__GENERATED_C_CODE
6984 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6985 wuffs_bmp__decoder__set_quirk(
6986     wuffs_bmp__decoder* self,
6987     uint32_t a_key,
6988     uint64_t a_value);
6989 
6990 WUFFS_BASE__GENERATED_C_CODE
6991 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6992 wuffs_bmp__decoder__decode_image_config(
6993     wuffs_bmp__decoder* self,
6994     wuffs_base__image_config* a_dst,
6995     wuffs_base__io_buffer* a_src);
6996 
6997 WUFFS_BASE__GENERATED_C_CODE
6998 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6999 wuffs_bmp__decoder__decode_frame_config(
7000     wuffs_bmp__decoder* self,
7001     wuffs_base__frame_config* a_dst,
7002     wuffs_base__io_buffer* a_src);
7003 
7004 WUFFS_BASE__GENERATED_C_CODE
7005 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7006 wuffs_bmp__decoder__decode_frame(
7007     wuffs_bmp__decoder* self,
7008     wuffs_base__pixel_buffer* a_dst,
7009     wuffs_base__io_buffer* a_src,
7010     wuffs_base__pixel_blend a_blend,
7011     wuffs_base__slice_u8 a_workbuf,
7012     wuffs_base__decode_frame_options* a_opts);
7013 
7014 WUFFS_BASE__GENERATED_C_CODE
7015 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
7016 wuffs_bmp__decoder__frame_dirty_rect(
7017     const wuffs_bmp__decoder* self);
7018 
7019 WUFFS_BASE__GENERATED_C_CODE
7020 WUFFS_BASE__MAYBE_STATIC uint32_t
7021 wuffs_bmp__decoder__num_animation_loops(
7022     const wuffs_bmp__decoder* self);
7023 
7024 WUFFS_BASE__GENERATED_C_CODE
7025 WUFFS_BASE__MAYBE_STATIC uint64_t
7026 wuffs_bmp__decoder__num_decoded_frame_configs(
7027     const wuffs_bmp__decoder* self);
7028 
7029 WUFFS_BASE__GENERATED_C_CODE
7030 WUFFS_BASE__MAYBE_STATIC uint64_t
7031 wuffs_bmp__decoder__num_decoded_frames(
7032     const wuffs_bmp__decoder* self);
7033 
7034 WUFFS_BASE__GENERATED_C_CODE
7035 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7036 wuffs_bmp__decoder__restart_frame(
7037     wuffs_bmp__decoder* self,
7038     uint64_t a_index,
7039     uint64_t a_io_position);
7040 
7041 WUFFS_BASE__GENERATED_C_CODE
7042 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
7043 wuffs_bmp__decoder__set_report_metadata(
7044     wuffs_bmp__decoder* self,
7045     uint32_t a_fourcc,
7046     bool a_report);
7047 
7048 WUFFS_BASE__GENERATED_C_CODE
7049 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7050 wuffs_bmp__decoder__tell_me_more(
7051     wuffs_bmp__decoder* self,
7052     wuffs_base__io_buffer* a_dst,
7053     wuffs_base__more_information* a_minfo,
7054     wuffs_base__io_buffer* a_src);
7055 
7056 WUFFS_BASE__GENERATED_C_CODE
7057 WUFFS_BASE__MAYBE_STATIC uint64_t
7058 wuffs_bmp__decoder__history_retain_length(
7059     const wuffs_bmp__decoder* self);
7060 
7061 WUFFS_BASE__GENERATED_C_CODE
7062 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
7063 wuffs_bmp__decoder__workbuf_len(
7064     const wuffs_bmp__decoder* self);
7065 
7066 #ifdef __cplusplus
7067 }  // extern "C"
7068 #endif
7069 
7070 // ---------------- Struct Definitions
7071 
7072 // These structs' fields, and the sizeof them, are private implementation
7073 // details that aren't guaranteed to be stable across Wuffs versions.
7074 //
7075 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
7076 
7077 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7078 
7079 struct wuffs_bmp__decoder__struct {
7080   // Do not access the private_impl's or private_data's fields directly. There
7081   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
7082   // the wuffs_foo__bar__baz functions.
7083   //
7084   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
7085   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
7086 
7087   struct {
7088     uint32_t magic;
7089     uint32_t active_coroutine;
7090     wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
7091     wuffs_base__vtable null_vtable;
7092 
7093     uint32_t f_width;
7094     uint32_t f_height;
7095     uint8_t f_call_sequence;
7096     bool f_top_down;
7097     uint32_t f_pad_per_row;
7098     uint32_t f_src_pixfmt;
7099     uint32_t f_io_redirect_fourcc;
7100     uint64_t f_io_redirect_pos;
7101     uint64_t f_frame_config_io_position;
7102     uint32_t f_bitmap_info_len;
7103     uint32_t f_padding;
7104     uint32_t f_bits_per_pixel;
7105     uint32_t f_compression;
7106     uint32_t f_channel_masks[4];
7107     uint8_t f_channel_shifts[4];
7108     uint8_t f_channel_num_bits[4];
7109     uint32_t f_dst_x;
7110     uint32_t f_dst_y;
7111     uint32_t f_dst_y_inc;
7112     uint32_t f_pending_pad;
7113     uint32_t f_rle_state;
7114     uint32_t f_rle_length;
7115     uint8_t f_rle_delta_x;
7116     bool f_rle_padded;
7117     wuffs_base__pixel_swizzler f_swizzler;
7118 
7119     uint32_t p_decode_image_config[1];
7120     uint32_t p_do_decode_image_config[1];
7121     uint32_t p_decode_frame_config[1];
7122     uint32_t p_do_decode_frame_config[1];
7123     uint32_t p_decode_frame[1];
7124     uint32_t p_do_decode_frame[1];
7125     uint32_t p_tell_me_more[1];
7126     uint32_t p_read_palette[1];
7127   } private_impl;
7128 
7129   struct {
7130     uint8_t f_scratch[2048];
7131     uint8_t f_src_palette[1024];
7132 
7133     struct {
7134       uint64_t scratch;
7135     } s_do_decode_image_config[1];
7136     struct {
7137       uint64_t scratch;
7138     } s_do_decode_frame[1];
7139     struct {
7140       uint32_t v_i;
7141       uint64_t scratch;
7142     } s_read_palette[1];
7143   } private_data;
7144 
7145 #ifdef __cplusplus
7146 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
7147   using unique_ptr = std::unique_ptr<wuffs_bmp__decoder, wuffs_unique_ptr_deleter>;
7148 
7149   // On failure, the alloc_etc functions return nullptr. They don't throw.
7150 
7151   static inline unique_ptr
allocwuffs_bmp__decoder__struct7152   alloc() {
7153     return unique_ptr(wuffs_bmp__decoder__alloc());
7154   }
7155 
7156   static inline wuffs_base__image_decoder::unique_ptr
alloc_as__wuffs_base__image_decoderwuffs_bmp__decoder__struct7157   alloc_as__wuffs_base__image_decoder() {
7158     return wuffs_base__image_decoder::unique_ptr(
7159         wuffs_bmp__decoder__alloc_as__wuffs_base__image_decoder());
7160   }
7161 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
7162 
7163 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
7164   // Disallow constructing or copying an object via standard C++ mechanisms,
7165   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
7166   // size and field layout is not part of the public, stable, memory-safe API.
7167   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
7168   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
7169   // their first argument) rather than tweaking bar.private_impl.qux fields.
7170   //
7171   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
7172   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
7173   // order to provide convenience methods. These forward on "this", so that you
7174   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
7175   wuffs_bmp__decoder__struct() = delete;
7176   wuffs_bmp__decoder__struct(const wuffs_bmp__decoder__struct&) = delete;
7177   wuffs_bmp__decoder__struct& operator=(
7178       const wuffs_bmp__decoder__struct&) = delete;
7179 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
7180 
7181 #if !defined(WUFFS_IMPLEMENTATION)
7182   // As above, the size of the struct is not part of the public API, and unless
7183   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
7184   // allocated, not stack allocated. Its size is not intended to be known at
7185   // compile time, but it is unfortunately divulged as a side effect of
7186   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
7187   // instead of "sizeof T", invoking the operator. To make the two values
7188   // different, so that passing the latter will be rejected by the initialize
7189   // function, we add an arbitrary amount of dead weight.
7190   uint8_t dead_weight[123000000];  // 123 MB.
7191 #endif  // !defined(WUFFS_IMPLEMENTATION)
7192 
7193   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_bmp__decoder__struct7194   initialize(
7195       size_t sizeof_star_self,
7196       uint64_t wuffs_version,
7197       uint32_t options) {
7198     return wuffs_bmp__decoder__initialize(
7199         this, sizeof_star_self, wuffs_version, options);
7200   }
7201 
7202   inline wuffs_base__image_decoder*
upcast_as__wuffs_base__image_decoderwuffs_bmp__decoder__struct7203   upcast_as__wuffs_base__image_decoder() {
7204     return (wuffs_base__image_decoder*)this;
7205   }
7206 
7207   inline uint64_t
get_quirkwuffs_bmp__decoder__struct7208   get_quirk(
7209       uint32_t a_key) const {
7210     return wuffs_bmp__decoder__get_quirk(this, a_key);
7211   }
7212 
7213   inline wuffs_base__status
set_quirkwuffs_bmp__decoder__struct7214   set_quirk(
7215       uint32_t a_key,
7216       uint64_t a_value) {
7217     return wuffs_bmp__decoder__set_quirk(this, a_key, a_value);
7218   }
7219 
7220   inline wuffs_base__status
decode_image_configwuffs_bmp__decoder__struct7221   decode_image_config(
7222       wuffs_base__image_config* a_dst,
7223       wuffs_base__io_buffer* a_src) {
7224     return wuffs_bmp__decoder__decode_image_config(this, a_dst, a_src);
7225   }
7226 
7227   inline wuffs_base__status
decode_frame_configwuffs_bmp__decoder__struct7228   decode_frame_config(
7229       wuffs_base__frame_config* a_dst,
7230       wuffs_base__io_buffer* a_src) {
7231     return wuffs_bmp__decoder__decode_frame_config(this, a_dst, a_src);
7232   }
7233 
7234   inline wuffs_base__status
decode_framewuffs_bmp__decoder__struct7235   decode_frame(
7236       wuffs_base__pixel_buffer* a_dst,
7237       wuffs_base__io_buffer* a_src,
7238       wuffs_base__pixel_blend a_blend,
7239       wuffs_base__slice_u8 a_workbuf,
7240       wuffs_base__decode_frame_options* a_opts) {
7241     return wuffs_bmp__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
7242   }
7243 
7244   inline wuffs_base__rect_ie_u32
frame_dirty_rectwuffs_bmp__decoder__struct7245   frame_dirty_rect() const {
7246     return wuffs_bmp__decoder__frame_dirty_rect(this);
7247   }
7248 
7249   inline uint32_t
num_animation_loopswuffs_bmp__decoder__struct7250   num_animation_loops() const {
7251     return wuffs_bmp__decoder__num_animation_loops(this);
7252   }
7253 
7254   inline uint64_t
num_decoded_frame_configswuffs_bmp__decoder__struct7255   num_decoded_frame_configs() const {
7256     return wuffs_bmp__decoder__num_decoded_frame_configs(this);
7257   }
7258 
7259   inline uint64_t
num_decoded_frameswuffs_bmp__decoder__struct7260   num_decoded_frames() const {
7261     return wuffs_bmp__decoder__num_decoded_frames(this);
7262   }
7263 
7264   inline wuffs_base__status
restart_framewuffs_bmp__decoder__struct7265   restart_frame(
7266       uint64_t a_index,
7267       uint64_t a_io_position) {
7268     return wuffs_bmp__decoder__restart_frame(this, a_index, a_io_position);
7269   }
7270 
7271   inline wuffs_base__empty_struct
set_report_metadatawuffs_bmp__decoder__struct7272   set_report_metadata(
7273       uint32_t a_fourcc,
7274       bool a_report) {
7275     return wuffs_bmp__decoder__set_report_metadata(this, a_fourcc, a_report);
7276   }
7277 
7278   inline wuffs_base__status
tell_me_morewuffs_bmp__decoder__struct7279   tell_me_more(
7280       wuffs_base__io_buffer* a_dst,
7281       wuffs_base__more_information* a_minfo,
7282       wuffs_base__io_buffer* a_src) {
7283     return wuffs_bmp__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
7284   }
7285 
7286   inline uint64_t
history_retain_lengthwuffs_bmp__decoder__struct7287   history_retain_length() const {
7288     return wuffs_bmp__decoder__history_retain_length(this);
7289   }
7290 
7291   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_bmp__decoder__struct7292   workbuf_len() const {
7293     return wuffs_bmp__decoder__workbuf_len(this);
7294   }
7295 
7296 #endif  // __cplusplus
7297 };  // struct wuffs_bmp__decoder__struct
7298 
7299 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7300 
7301 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BMP) || defined(WUFFS_NONMONOLITHIC)
7302 
7303 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BZIP2) || defined(WUFFS_NONMONOLITHIC)
7304 
7305 // ---------------- Status Codes
7306 
7307 extern const char wuffs_bzip2__error__bad_huffman_code_over_subscribed[];
7308 extern const char wuffs_bzip2__error__bad_huffman_code_under_subscribed[];
7309 extern const char wuffs_bzip2__error__bad_block_header[];
7310 extern const char wuffs_bzip2__error__bad_block_length[];
7311 extern const char wuffs_bzip2__error__bad_checksum[];
7312 extern const char wuffs_bzip2__error__bad_header[];
7313 extern const char wuffs_bzip2__error__bad_number_of_sections[];
7314 extern const char wuffs_bzip2__error__truncated_input[];
7315 extern const char wuffs_bzip2__error__unsupported_block_randomization[];
7316 
7317 // ---------------- Public Consts
7318 
7319 #define WUFFS_BZIP2__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0
7320 
7321 #define WUFFS_BZIP2__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
7322 
7323 // ---------------- Struct Declarations
7324 
7325 typedef struct wuffs_bzip2__decoder__struct wuffs_bzip2__decoder;
7326 
7327 #ifdef __cplusplus
7328 extern "C" {
7329 #endif
7330 
7331 // ---------------- Public Initializer Prototypes
7332 
7333 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
7334 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
7335 //
7336 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
7337 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
7338 
7339 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
7340 wuffs_bzip2__decoder__initialize(
7341     wuffs_bzip2__decoder* self,
7342     size_t sizeof_star_self,
7343     uint64_t wuffs_version,
7344     uint32_t options);
7345 
7346 size_t
7347 sizeof__wuffs_bzip2__decoder(void);
7348 
7349 // ---------------- Allocs
7350 
7351 // These functions allocate and initialize Wuffs structs. They return NULL if
7352 // memory allocation fails. If they return non-NULL, there is no need to call
7353 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
7354 // calling free on the returned pointer. That pointer is effectively a C++
7355 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
7356 
7357 wuffs_bzip2__decoder*
7358 wuffs_bzip2__decoder__alloc(void);
7359 
7360 static inline wuffs_base__io_transformer*
wuffs_bzip2__decoder__alloc_as__wuffs_base__io_transformer(void)7361 wuffs_bzip2__decoder__alloc_as__wuffs_base__io_transformer(void) {
7362   return (wuffs_base__io_transformer*)(wuffs_bzip2__decoder__alloc());
7363 }
7364 
7365 // ---------------- Upcasts
7366 
7367 static inline wuffs_base__io_transformer*
wuffs_bzip2__decoder__upcast_as__wuffs_base__io_transformer(wuffs_bzip2__decoder * p)7368 wuffs_bzip2__decoder__upcast_as__wuffs_base__io_transformer(
7369     wuffs_bzip2__decoder* p) {
7370   return (wuffs_base__io_transformer*)p;
7371 }
7372 
7373 // ---------------- Public Function Prototypes
7374 
7375 WUFFS_BASE__GENERATED_C_CODE
7376 WUFFS_BASE__MAYBE_STATIC uint64_t
7377 wuffs_bzip2__decoder__get_quirk(
7378     const wuffs_bzip2__decoder* self,
7379     uint32_t a_key);
7380 
7381 WUFFS_BASE__GENERATED_C_CODE
7382 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7383 wuffs_bzip2__decoder__set_quirk(
7384     wuffs_bzip2__decoder* self,
7385     uint32_t a_key,
7386     uint64_t a_value);
7387 
7388 WUFFS_BASE__GENERATED_C_CODE
7389 WUFFS_BASE__MAYBE_STATIC uint64_t
7390 wuffs_bzip2__decoder__history_retain_length(
7391     const wuffs_bzip2__decoder* self);
7392 
7393 WUFFS_BASE__GENERATED_C_CODE
7394 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
7395 wuffs_bzip2__decoder__workbuf_len(
7396     const wuffs_bzip2__decoder* self);
7397 
7398 WUFFS_BASE__GENERATED_C_CODE
7399 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7400 wuffs_bzip2__decoder__transform_io(
7401     wuffs_bzip2__decoder* self,
7402     wuffs_base__io_buffer* a_dst,
7403     wuffs_base__io_buffer* a_src,
7404     wuffs_base__slice_u8 a_workbuf);
7405 
7406 #ifdef __cplusplus
7407 }  // extern "C"
7408 #endif
7409 
7410 // ---------------- Struct Definitions
7411 
7412 // These structs' fields, and the sizeof them, are private implementation
7413 // details that aren't guaranteed to be stable across Wuffs versions.
7414 //
7415 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
7416 
7417 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7418 
7419 struct wuffs_bzip2__decoder__struct {
7420   // Do not access the private_impl's or private_data's fields directly. There
7421   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
7422   // the wuffs_foo__bar__baz functions.
7423   //
7424   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
7425   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
7426 
7427   struct {
7428     uint32_t magic;
7429     uint32_t active_coroutine;
7430     wuffs_base__vtable vtable_for__wuffs_base__io_transformer;
7431     wuffs_base__vtable null_vtable;
7432 
7433     uint32_t f_bits;
7434     uint32_t f_n_bits;
7435     uint32_t f_max_incl_block_size;
7436     uint32_t f_block_size;
7437     bool f_decode_huffman_finished;
7438     uint8_t f_decode_huffman_which;
7439     uint32_t f_decode_huffman_ticks;
7440     uint32_t f_decode_huffman_section;
7441     uint32_t f_decode_huffman_run_shift;
7442     uint32_t f_flush_pointer;
7443     uint32_t f_flush_repeat_count;
7444     uint8_t f_flush_prev;
7445     bool f_ignore_checksum;
7446     uint32_t f_final_checksum_have;
7447     uint32_t f_block_checksum_have;
7448     uint32_t f_block_checksum_want;
7449     uint32_t f_original_pointer;
7450     uint32_t f_num_symbols;
7451     uint32_t f_num_huffman_codes;
7452     uint32_t f_num_sections;
7453     uint32_t f_code_lengths_bitmask;
7454 
7455     uint32_t p_transform_io[1];
7456     uint32_t p_do_transform_io[1];
7457     uint32_t p_prepare_block[1];
7458     uint32_t p_read_code_lengths[1];
7459     uint32_t p_flush_slow[1];
7460     uint32_t p_decode_huffman_slow[1];
7461   } private_impl;
7462 
7463   struct {
7464     uint32_t f_scratch;
7465     uint32_t f_letter_counts[256];
7466     uint8_t f_presence[256];
7467     uint8_t f_mtft[256];
7468     uint8_t f_huffman_selectors[32768];
7469     uint16_t f_huffman_trees[6][257][2];
7470     uint16_t f_huffman_tables[6][256];
7471     uint32_t f_bwt[1048576];
7472 
7473     struct {
7474       uint32_t v_i;
7475       uint64_t v_tag;
7476       uint32_t v_final_checksum_want;
7477     } s_do_transform_io[1];
7478     struct {
7479       uint32_t v_i;
7480       uint32_t v_selector;
7481     } s_prepare_block[1];
7482     struct {
7483       uint32_t v_i;
7484       uint32_t v_code_length;
7485     } s_read_code_lengths[1];
7486     struct {
7487       uint32_t v_flush_pointer;
7488       uint32_t v_flush_repeat_count;
7489       uint8_t v_flush_prev;
7490       uint32_t v_block_checksum_have;
7491       uint32_t v_block_size;
7492       uint8_t v_curr;
7493       uint64_t scratch;
7494     } s_flush_slow[1];
7495     struct {
7496       uint32_t v_node_index;
7497     } s_decode_huffman_slow[1];
7498   } private_data;
7499 
7500 #ifdef __cplusplus
7501 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
7502   using unique_ptr = std::unique_ptr<wuffs_bzip2__decoder, wuffs_unique_ptr_deleter>;
7503 
7504   // On failure, the alloc_etc functions return nullptr. They don't throw.
7505 
7506   static inline unique_ptr
allocwuffs_bzip2__decoder__struct7507   alloc() {
7508     return unique_ptr(wuffs_bzip2__decoder__alloc());
7509   }
7510 
7511   static inline wuffs_base__io_transformer::unique_ptr
alloc_as__wuffs_base__io_transformerwuffs_bzip2__decoder__struct7512   alloc_as__wuffs_base__io_transformer() {
7513     return wuffs_base__io_transformer::unique_ptr(
7514         wuffs_bzip2__decoder__alloc_as__wuffs_base__io_transformer());
7515   }
7516 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
7517 
7518 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
7519   // Disallow constructing or copying an object via standard C++ mechanisms,
7520   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
7521   // size and field layout is not part of the public, stable, memory-safe API.
7522   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
7523   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
7524   // their first argument) rather than tweaking bar.private_impl.qux fields.
7525   //
7526   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
7527   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
7528   // order to provide convenience methods. These forward on "this", so that you
7529   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
7530   wuffs_bzip2__decoder__struct() = delete;
7531   wuffs_bzip2__decoder__struct(const wuffs_bzip2__decoder__struct&) = delete;
7532   wuffs_bzip2__decoder__struct& operator=(
7533       const wuffs_bzip2__decoder__struct&) = delete;
7534 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
7535 
7536 #if !defined(WUFFS_IMPLEMENTATION)
7537   // As above, the size of the struct is not part of the public API, and unless
7538   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
7539   // allocated, not stack allocated. Its size is not intended to be known at
7540   // compile time, but it is unfortunately divulged as a side effect of
7541   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
7542   // instead of "sizeof T", invoking the operator. To make the two values
7543   // different, so that passing the latter will be rejected by the initialize
7544   // function, we add an arbitrary amount of dead weight.
7545   uint8_t dead_weight[123000000];  // 123 MB.
7546 #endif  // !defined(WUFFS_IMPLEMENTATION)
7547 
7548   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_bzip2__decoder__struct7549   initialize(
7550       size_t sizeof_star_self,
7551       uint64_t wuffs_version,
7552       uint32_t options) {
7553     return wuffs_bzip2__decoder__initialize(
7554         this, sizeof_star_self, wuffs_version, options);
7555   }
7556 
7557   inline wuffs_base__io_transformer*
upcast_as__wuffs_base__io_transformerwuffs_bzip2__decoder__struct7558   upcast_as__wuffs_base__io_transformer() {
7559     return (wuffs_base__io_transformer*)this;
7560   }
7561 
7562   inline uint64_t
get_quirkwuffs_bzip2__decoder__struct7563   get_quirk(
7564       uint32_t a_key) const {
7565     return wuffs_bzip2__decoder__get_quirk(this, a_key);
7566   }
7567 
7568   inline wuffs_base__status
set_quirkwuffs_bzip2__decoder__struct7569   set_quirk(
7570       uint32_t a_key,
7571       uint64_t a_value) {
7572     return wuffs_bzip2__decoder__set_quirk(this, a_key, a_value);
7573   }
7574 
7575   inline uint64_t
history_retain_lengthwuffs_bzip2__decoder__struct7576   history_retain_length() const {
7577     return wuffs_bzip2__decoder__history_retain_length(this);
7578   }
7579 
7580   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_bzip2__decoder__struct7581   workbuf_len() const {
7582     return wuffs_bzip2__decoder__workbuf_len(this);
7583   }
7584 
7585   inline wuffs_base__status
transform_iowuffs_bzip2__decoder__struct7586   transform_io(
7587       wuffs_base__io_buffer* a_dst,
7588       wuffs_base__io_buffer* a_src,
7589       wuffs_base__slice_u8 a_workbuf) {
7590     return wuffs_bzip2__decoder__transform_io(this, a_dst, a_src, a_workbuf);
7591   }
7592 
7593 #endif  // __cplusplus
7594 };  // struct wuffs_bzip2__decoder__struct
7595 
7596 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7597 
7598 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BZIP2) || defined(WUFFS_NONMONOLITHIC)
7599 
7600 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CBOR) || defined(WUFFS_NONMONOLITHIC)
7601 
7602 // ---------------- Status Codes
7603 
7604 extern const char wuffs_cbor__error__bad_input[];
7605 extern const char wuffs_cbor__error__unsupported_recursion_depth[];
7606 
7607 // ---------------- Public Consts
7608 
7609 #define WUFFS_CBOR__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0
7610 
7611 #define WUFFS_CBOR__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
7612 
7613 #define WUFFS_CBOR__DECODER_DEPTH_MAX_INCL 1024
7614 
7615 #define WUFFS_CBOR__DECODER_DST_TOKEN_BUFFER_LENGTH_MIN_INCL 2
7616 
7617 #define WUFFS_CBOR__DECODER_SRC_IO_BUFFER_LENGTH_MIN_INCL 9
7618 
7619 #define WUFFS_CBOR__TOKEN_VALUE_MAJOR 787997
7620 
7621 #define WUFFS_CBOR__TOKEN_VALUE_MINOR__DETAIL_MASK 262143
7622 
7623 #define WUFFS_CBOR__TOKEN_VALUE_MINOR__MINUS_1_MINUS_X 16777216
7624 
7625 #define WUFFS_CBOR__TOKEN_VALUE_MINOR__SIMPLE_VALUE 8388608
7626 
7627 #define WUFFS_CBOR__TOKEN_VALUE_MINOR__TAG 4194304
7628 
7629 // ---------------- Struct Declarations
7630 
7631 typedef struct wuffs_cbor__decoder__struct wuffs_cbor__decoder;
7632 
7633 #ifdef __cplusplus
7634 extern "C" {
7635 #endif
7636 
7637 // ---------------- Public Initializer Prototypes
7638 
7639 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
7640 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
7641 //
7642 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
7643 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
7644 
7645 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
7646 wuffs_cbor__decoder__initialize(
7647     wuffs_cbor__decoder* self,
7648     size_t sizeof_star_self,
7649     uint64_t wuffs_version,
7650     uint32_t options);
7651 
7652 size_t
7653 sizeof__wuffs_cbor__decoder(void);
7654 
7655 // ---------------- Allocs
7656 
7657 // These functions allocate and initialize Wuffs structs. They return NULL if
7658 // memory allocation fails. If they return non-NULL, there is no need to call
7659 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
7660 // calling free on the returned pointer. That pointer is effectively a C++
7661 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
7662 
7663 wuffs_cbor__decoder*
7664 wuffs_cbor__decoder__alloc(void);
7665 
7666 static inline wuffs_base__token_decoder*
wuffs_cbor__decoder__alloc_as__wuffs_base__token_decoder(void)7667 wuffs_cbor__decoder__alloc_as__wuffs_base__token_decoder(void) {
7668   return (wuffs_base__token_decoder*)(wuffs_cbor__decoder__alloc());
7669 }
7670 
7671 // ---------------- Upcasts
7672 
7673 static inline wuffs_base__token_decoder*
wuffs_cbor__decoder__upcast_as__wuffs_base__token_decoder(wuffs_cbor__decoder * p)7674 wuffs_cbor__decoder__upcast_as__wuffs_base__token_decoder(
7675     wuffs_cbor__decoder* p) {
7676   return (wuffs_base__token_decoder*)p;
7677 }
7678 
7679 // ---------------- Public Function Prototypes
7680 
7681 WUFFS_BASE__GENERATED_C_CODE
7682 WUFFS_BASE__MAYBE_STATIC uint64_t
7683 wuffs_cbor__decoder__get_quirk(
7684     const wuffs_cbor__decoder* self,
7685     uint32_t a_key);
7686 
7687 WUFFS_BASE__GENERATED_C_CODE
7688 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7689 wuffs_cbor__decoder__set_quirk(
7690     wuffs_cbor__decoder* self,
7691     uint32_t a_key,
7692     uint64_t a_value);
7693 
7694 WUFFS_BASE__GENERATED_C_CODE
7695 WUFFS_BASE__MAYBE_STATIC uint64_t
7696 wuffs_cbor__decoder__history_retain_length(
7697     const wuffs_cbor__decoder* self);
7698 
7699 WUFFS_BASE__GENERATED_C_CODE
7700 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
7701 wuffs_cbor__decoder__workbuf_len(
7702     const wuffs_cbor__decoder* self);
7703 
7704 WUFFS_BASE__GENERATED_C_CODE
7705 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7706 wuffs_cbor__decoder__decode_tokens(
7707     wuffs_cbor__decoder* self,
7708     wuffs_base__token_buffer* a_dst,
7709     wuffs_base__io_buffer* a_src,
7710     wuffs_base__slice_u8 a_workbuf);
7711 
7712 #ifdef __cplusplus
7713 }  // extern "C"
7714 #endif
7715 
7716 // ---------------- Struct Definitions
7717 
7718 // These structs' fields, and the sizeof them, are private implementation
7719 // details that aren't guaranteed to be stable across Wuffs versions.
7720 //
7721 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
7722 
7723 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7724 
7725 struct wuffs_cbor__decoder__struct {
7726   // Do not access the private_impl's or private_data's fields directly. There
7727   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
7728   // the wuffs_foo__bar__baz functions.
7729   //
7730   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
7731   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
7732 
7733   struct {
7734     uint32_t magic;
7735     uint32_t active_coroutine;
7736     wuffs_base__vtable vtable_for__wuffs_base__token_decoder;
7737     wuffs_base__vtable null_vtable;
7738 
7739     bool f_end_of_data;
7740 
7741     uint32_t p_decode_tokens[1];
7742   } private_impl;
7743 
7744   struct {
7745     uint32_t f_stack[64];
7746     uint64_t f_container_num_remaining[1024];
7747 
7748     struct {
7749       uint64_t v_string_length;
7750       uint32_t v_depth;
7751       bool v_tagged;
7752       uint8_t v_indefinite_string_major_type;
7753     } s_decode_tokens[1];
7754   } private_data;
7755 
7756 #ifdef __cplusplus
7757 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
7758   using unique_ptr = std::unique_ptr<wuffs_cbor__decoder, wuffs_unique_ptr_deleter>;
7759 
7760   // On failure, the alloc_etc functions return nullptr. They don't throw.
7761 
7762   static inline unique_ptr
allocwuffs_cbor__decoder__struct7763   alloc() {
7764     return unique_ptr(wuffs_cbor__decoder__alloc());
7765   }
7766 
7767   static inline wuffs_base__token_decoder::unique_ptr
alloc_as__wuffs_base__token_decoderwuffs_cbor__decoder__struct7768   alloc_as__wuffs_base__token_decoder() {
7769     return wuffs_base__token_decoder::unique_ptr(
7770         wuffs_cbor__decoder__alloc_as__wuffs_base__token_decoder());
7771   }
7772 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
7773 
7774 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
7775   // Disallow constructing or copying an object via standard C++ mechanisms,
7776   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
7777   // size and field layout is not part of the public, stable, memory-safe API.
7778   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
7779   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
7780   // their first argument) rather than tweaking bar.private_impl.qux fields.
7781   //
7782   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
7783   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
7784   // order to provide convenience methods. These forward on "this", so that you
7785   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
7786   wuffs_cbor__decoder__struct() = delete;
7787   wuffs_cbor__decoder__struct(const wuffs_cbor__decoder__struct&) = delete;
7788   wuffs_cbor__decoder__struct& operator=(
7789       const wuffs_cbor__decoder__struct&) = delete;
7790 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
7791 
7792 #if !defined(WUFFS_IMPLEMENTATION)
7793   // As above, the size of the struct is not part of the public API, and unless
7794   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
7795   // allocated, not stack allocated. Its size is not intended to be known at
7796   // compile time, but it is unfortunately divulged as a side effect of
7797   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
7798   // instead of "sizeof T", invoking the operator. To make the two values
7799   // different, so that passing the latter will be rejected by the initialize
7800   // function, we add an arbitrary amount of dead weight.
7801   uint8_t dead_weight[123000000];  // 123 MB.
7802 #endif  // !defined(WUFFS_IMPLEMENTATION)
7803 
7804   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_cbor__decoder__struct7805   initialize(
7806       size_t sizeof_star_self,
7807       uint64_t wuffs_version,
7808       uint32_t options) {
7809     return wuffs_cbor__decoder__initialize(
7810         this, sizeof_star_self, wuffs_version, options);
7811   }
7812 
7813   inline wuffs_base__token_decoder*
upcast_as__wuffs_base__token_decoderwuffs_cbor__decoder__struct7814   upcast_as__wuffs_base__token_decoder() {
7815     return (wuffs_base__token_decoder*)this;
7816   }
7817 
7818   inline uint64_t
get_quirkwuffs_cbor__decoder__struct7819   get_quirk(
7820       uint32_t a_key) const {
7821     return wuffs_cbor__decoder__get_quirk(this, a_key);
7822   }
7823 
7824   inline wuffs_base__status
set_quirkwuffs_cbor__decoder__struct7825   set_quirk(
7826       uint32_t a_key,
7827       uint64_t a_value) {
7828     return wuffs_cbor__decoder__set_quirk(this, a_key, a_value);
7829   }
7830 
7831   inline uint64_t
history_retain_lengthwuffs_cbor__decoder__struct7832   history_retain_length() const {
7833     return wuffs_cbor__decoder__history_retain_length(this);
7834   }
7835 
7836   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_cbor__decoder__struct7837   workbuf_len() const {
7838     return wuffs_cbor__decoder__workbuf_len(this);
7839   }
7840 
7841   inline wuffs_base__status
decode_tokenswuffs_cbor__decoder__struct7842   decode_tokens(
7843       wuffs_base__token_buffer* a_dst,
7844       wuffs_base__io_buffer* a_src,
7845       wuffs_base__slice_u8 a_workbuf) {
7846     return wuffs_cbor__decoder__decode_tokens(this, a_dst, a_src, a_workbuf);
7847   }
7848 
7849 #endif  // __cplusplus
7850 };  // struct wuffs_cbor__decoder__struct
7851 
7852 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7853 
7854 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CBOR) || defined(WUFFS_NONMONOLITHIC)
7855 
7856 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CRC32) || defined(WUFFS_NONMONOLITHIC)
7857 
7858 // ---------------- Status Codes
7859 
7860 // ---------------- Public Consts
7861 
7862 // ---------------- Struct Declarations
7863 
7864 typedef struct wuffs_crc32__ieee_hasher__struct wuffs_crc32__ieee_hasher;
7865 
7866 #ifdef __cplusplus
7867 extern "C" {
7868 #endif
7869 
7870 // ---------------- Public Initializer Prototypes
7871 
7872 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
7873 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
7874 //
7875 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
7876 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
7877 
7878 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
7879 wuffs_crc32__ieee_hasher__initialize(
7880     wuffs_crc32__ieee_hasher* self,
7881     size_t sizeof_star_self,
7882     uint64_t wuffs_version,
7883     uint32_t options);
7884 
7885 size_t
7886 sizeof__wuffs_crc32__ieee_hasher(void);
7887 
7888 // ---------------- Allocs
7889 
7890 // These functions allocate and initialize Wuffs structs. They return NULL if
7891 // memory allocation fails. If they return non-NULL, there is no need to call
7892 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
7893 // calling free on the returned pointer. That pointer is effectively a C++
7894 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
7895 
7896 wuffs_crc32__ieee_hasher*
7897 wuffs_crc32__ieee_hasher__alloc(void);
7898 
7899 static inline wuffs_base__hasher_u32*
wuffs_crc32__ieee_hasher__alloc_as__wuffs_base__hasher_u32(void)7900 wuffs_crc32__ieee_hasher__alloc_as__wuffs_base__hasher_u32(void) {
7901   return (wuffs_base__hasher_u32*)(wuffs_crc32__ieee_hasher__alloc());
7902 }
7903 
7904 // ---------------- Upcasts
7905 
7906 static inline wuffs_base__hasher_u32*
wuffs_crc32__ieee_hasher__upcast_as__wuffs_base__hasher_u32(wuffs_crc32__ieee_hasher * p)7907 wuffs_crc32__ieee_hasher__upcast_as__wuffs_base__hasher_u32(
7908     wuffs_crc32__ieee_hasher* p) {
7909   return (wuffs_base__hasher_u32*)p;
7910 }
7911 
7912 // ---------------- Public Function Prototypes
7913 
7914 WUFFS_BASE__GENERATED_C_CODE
7915 WUFFS_BASE__MAYBE_STATIC uint64_t
7916 wuffs_crc32__ieee_hasher__get_quirk(
7917     const wuffs_crc32__ieee_hasher* self,
7918     uint32_t a_key);
7919 
7920 WUFFS_BASE__GENERATED_C_CODE
7921 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7922 wuffs_crc32__ieee_hasher__set_quirk(
7923     wuffs_crc32__ieee_hasher* self,
7924     uint32_t a_key,
7925     uint64_t a_value);
7926 
7927 WUFFS_BASE__GENERATED_C_CODE
7928 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
7929 wuffs_crc32__ieee_hasher__update(
7930     wuffs_crc32__ieee_hasher* self,
7931     wuffs_base__slice_u8 a_x);
7932 
7933 WUFFS_BASE__GENERATED_C_CODE
7934 WUFFS_BASE__MAYBE_STATIC uint32_t
7935 wuffs_crc32__ieee_hasher__update_u32(
7936     wuffs_crc32__ieee_hasher* self,
7937     wuffs_base__slice_u8 a_x);
7938 
7939 WUFFS_BASE__GENERATED_C_CODE
7940 WUFFS_BASE__MAYBE_STATIC uint32_t
7941 wuffs_crc32__ieee_hasher__checksum_u32(
7942     const wuffs_crc32__ieee_hasher* self);
7943 
7944 #ifdef __cplusplus
7945 }  // extern "C"
7946 #endif
7947 
7948 // ---------------- Struct Definitions
7949 
7950 // These structs' fields, and the sizeof them, are private implementation
7951 // details that aren't guaranteed to be stable across Wuffs versions.
7952 //
7953 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
7954 
7955 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7956 
7957 struct wuffs_crc32__ieee_hasher__struct {
7958   // Do not access the private_impl's or private_data's fields directly. There
7959   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
7960   // the wuffs_foo__bar__baz functions.
7961   //
7962   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
7963   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
7964 
7965   struct {
7966     uint32_t magic;
7967     uint32_t active_coroutine;
7968     wuffs_base__vtable vtable_for__wuffs_base__hasher_u32;
7969     wuffs_base__vtable null_vtable;
7970 
7971     uint32_t f_state;
7972 
7973     wuffs_base__empty_struct (*choosy_up)(
7974         wuffs_crc32__ieee_hasher* self,
7975         wuffs_base__slice_u8 a_x);
7976   } private_impl;
7977 
7978 #ifdef __cplusplus
7979 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
7980   using unique_ptr = std::unique_ptr<wuffs_crc32__ieee_hasher, wuffs_unique_ptr_deleter>;
7981 
7982   // On failure, the alloc_etc functions return nullptr. They don't throw.
7983 
7984   static inline unique_ptr
allocwuffs_crc32__ieee_hasher__struct7985   alloc() {
7986     return unique_ptr(wuffs_crc32__ieee_hasher__alloc());
7987   }
7988 
7989   static inline wuffs_base__hasher_u32::unique_ptr
alloc_as__wuffs_base__hasher_u32wuffs_crc32__ieee_hasher__struct7990   alloc_as__wuffs_base__hasher_u32() {
7991     return wuffs_base__hasher_u32::unique_ptr(
7992         wuffs_crc32__ieee_hasher__alloc_as__wuffs_base__hasher_u32());
7993   }
7994 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
7995 
7996 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
7997   // Disallow constructing or copying an object via standard C++ mechanisms,
7998   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
7999   // size and field layout is not part of the public, stable, memory-safe API.
8000   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
8001   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
8002   // their first argument) rather than tweaking bar.private_impl.qux fields.
8003   //
8004   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
8005   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
8006   // order to provide convenience methods. These forward on "this", so that you
8007   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
8008   wuffs_crc32__ieee_hasher__struct() = delete;
8009   wuffs_crc32__ieee_hasher__struct(const wuffs_crc32__ieee_hasher__struct&) = delete;
8010   wuffs_crc32__ieee_hasher__struct& operator=(
8011       const wuffs_crc32__ieee_hasher__struct&) = delete;
8012 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
8013 
8014 #if !defined(WUFFS_IMPLEMENTATION)
8015   // As above, the size of the struct is not part of the public API, and unless
8016   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
8017   // allocated, not stack allocated. Its size is not intended to be known at
8018   // compile time, but it is unfortunately divulged as a side effect of
8019   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
8020   // instead of "sizeof T", invoking the operator. To make the two values
8021   // different, so that passing the latter will be rejected by the initialize
8022   // function, we add an arbitrary amount of dead weight.
8023   uint8_t dead_weight[123000000];  // 123 MB.
8024 #endif  // !defined(WUFFS_IMPLEMENTATION)
8025 
8026   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_crc32__ieee_hasher__struct8027   initialize(
8028       size_t sizeof_star_self,
8029       uint64_t wuffs_version,
8030       uint32_t options) {
8031     return wuffs_crc32__ieee_hasher__initialize(
8032         this, sizeof_star_self, wuffs_version, options);
8033   }
8034 
8035   inline wuffs_base__hasher_u32*
upcast_as__wuffs_base__hasher_u32wuffs_crc32__ieee_hasher__struct8036   upcast_as__wuffs_base__hasher_u32() {
8037     return (wuffs_base__hasher_u32*)this;
8038   }
8039 
8040   inline uint64_t
get_quirkwuffs_crc32__ieee_hasher__struct8041   get_quirk(
8042       uint32_t a_key) const {
8043     return wuffs_crc32__ieee_hasher__get_quirk(this, a_key);
8044   }
8045 
8046   inline wuffs_base__status
set_quirkwuffs_crc32__ieee_hasher__struct8047   set_quirk(
8048       uint32_t a_key,
8049       uint64_t a_value) {
8050     return wuffs_crc32__ieee_hasher__set_quirk(this, a_key, a_value);
8051   }
8052 
8053   inline wuffs_base__empty_struct
updatewuffs_crc32__ieee_hasher__struct8054   update(
8055       wuffs_base__slice_u8 a_x) {
8056     return wuffs_crc32__ieee_hasher__update(this, a_x);
8057   }
8058 
8059   inline uint32_t
update_u32wuffs_crc32__ieee_hasher__struct8060   update_u32(
8061       wuffs_base__slice_u8 a_x) {
8062     return wuffs_crc32__ieee_hasher__update_u32(this, a_x);
8063   }
8064 
8065   inline uint32_t
checksum_u32wuffs_crc32__ieee_hasher__struct8066   checksum_u32() const {
8067     return wuffs_crc32__ieee_hasher__checksum_u32(this);
8068   }
8069 
8070 #endif  // __cplusplus
8071 };  // struct wuffs_crc32__ieee_hasher__struct
8072 
8073 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
8074 
8075 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CRC32) || defined(WUFFS_NONMONOLITHIC)
8076 
8077 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__DEFLATE) || defined(WUFFS_NONMONOLITHIC)
8078 
8079 // ---------------- Status Codes
8080 
8081 extern const char wuffs_deflate__error__bad_huffman_code_over_subscribed[];
8082 extern const char wuffs_deflate__error__bad_huffman_code_under_subscribed[];
8083 extern const char wuffs_deflate__error__bad_huffman_code_length_count[];
8084 extern const char wuffs_deflate__error__bad_huffman_code_length_repetition[];
8085 extern const char wuffs_deflate__error__bad_huffman_code[];
8086 extern const char wuffs_deflate__error__bad_huffman_minimum_code_length[];
8087 extern const char wuffs_deflate__error__bad_block[];
8088 extern const char wuffs_deflate__error__bad_distance[];
8089 extern const char wuffs_deflate__error__bad_distance_code_count[];
8090 extern const char wuffs_deflate__error__bad_literal_length_code_count[];
8091 extern const char wuffs_deflate__error__inconsistent_stored_block_length[];
8092 extern const char wuffs_deflate__error__missing_end_of_block_code[];
8093 extern const char wuffs_deflate__error__no_huffman_codes[];
8094 extern const char wuffs_deflate__error__truncated_input[];
8095 
8096 // ---------------- Public Consts
8097 
8098 #define WUFFS_DEFLATE__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0
8099 
8100 #define WUFFS_DEFLATE__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 1
8101 
8102 // ---------------- Struct Declarations
8103 
8104 typedef struct wuffs_deflate__decoder__struct wuffs_deflate__decoder;
8105 
8106 #ifdef __cplusplus
8107 extern "C" {
8108 #endif
8109 
8110 // ---------------- Public Initializer Prototypes
8111 
8112 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
8113 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
8114 //
8115 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
8116 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
8117 
8118 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
8119 wuffs_deflate__decoder__initialize(
8120     wuffs_deflate__decoder* self,
8121     size_t sizeof_star_self,
8122     uint64_t wuffs_version,
8123     uint32_t options);
8124 
8125 size_t
8126 sizeof__wuffs_deflate__decoder(void);
8127 
8128 // ---------------- Allocs
8129 
8130 // These functions allocate and initialize Wuffs structs. They return NULL if
8131 // memory allocation fails. If they return non-NULL, there is no need to call
8132 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
8133 // calling free on the returned pointer. That pointer is effectively a C++
8134 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
8135 
8136 wuffs_deflate__decoder*
8137 wuffs_deflate__decoder__alloc(void);
8138 
8139 static inline wuffs_base__io_transformer*
wuffs_deflate__decoder__alloc_as__wuffs_base__io_transformer(void)8140 wuffs_deflate__decoder__alloc_as__wuffs_base__io_transformer(void) {
8141   return (wuffs_base__io_transformer*)(wuffs_deflate__decoder__alloc());
8142 }
8143 
8144 // ---------------- Upcasts
8145 
8146 static inline wuffs_base__io_transformer*
wuffs_deflate__decoder__upcast_as__wuffs_base__io_transformer(wuffs_deflate__decoder * p)8147 wuffs_deflate__decoder__upcast_as__wuffs_base__io_transformer(
8148     wuffs_deflate__decoder* p) {
8149   return (wuffs_base__io_transformer*)p;
8150 }
8151 
8152 // ---------------- Public Function Prototypes
8153 
8154 WUFFS_BASE__GENERATED_C_CODE
8155 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
8156 wuffs_deflate__decoder__add_history(
8157     wuffs_deflate__decoder* self,
8158     wuffs_base__slice_u8 a_hist);
8159 
8160 WUFFS_BASE__GENERATED_C_CODE
8161 WUFFS_BASE__MAYBE_STATIC uint64_t
8162 wuffs_deflate__decoder__get_quirk(
8163     const wuffs_deflate__decoder* self,
8164     uint32_t a_key);
8165 
8166 WUFFS_BASE__GENERATED_C_CODE
8167 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8168 wuffs_deflate__decoder__set_quirk(
8169     wuffs_deflate__decoder* self,
8170     uint32_t a_key,
8171     uint64_t a_value);
8172 
8173 WUFFS_BASE__GENERATED_C_CODE
8174 WUFFS_BASE__MAYBE_STATIC uint64_t
8175 wuffs_deflate__decoder__history_retain_length(
8176     const wuffs_deflate__decoder* self);
8177 
8178 WUFFS_BASE__GENERATED_C_CODE
8179 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
8180 wuffs_deflate__decoder__workbuf_len(
8181     const wuffs_deflate__decoder* self);
8182 
8183 WUFFS_BASE__GENERATED_C_CODE
8184 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8185 wuffs_deflate__decoder__transform_io(
8186     wuffs_deflate__decoder* self,
8187     wuffs_base__io_buffer* a_dst,
8188     wuffs_base__io_buffer* a_src,
8189     wuffs_base__slice_u8 a_workbuf);
8190 
8191 #ifdef __cplusplus
8192 }  // extern "C"
8193 #endif
8194 
8195 // ---------------- Struct Definitions
8196 
8197 // These structs' fields, and the sizeof them, are private implementation
8198 // details that aren't guaranteed to be stable across Wuffs versions.
8199 //
8200 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
8201 
8202 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
8203 
8204 struct wuffs_deflate__decoder__struct {
8205   // Do not access the private_impl's or private_data's fields directly. There
8206   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
8207   // the wuffs_foo__bar__baz functions.
8208   //
8209   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
8210   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
8211 
8212   struct {
8213     uint32_t magic;
8214     uint32_t active_coroutine;
8215     wuffs_base__vtable vtable_for__wuffs_base__io_transformer;
8216     wuffs_base__vtable null_vtable;
8217 
8218     uint32_t f_bits;
8219     uint32_t f_n_bits;
8220     uint64_t f_transformed_history_count;
8221     uint32_t f_history_index;
8222     uint32_t f_n_huffs_bits[2];
8223     bool f_end_of_block;
8224 
8225     uint32_t p_transform_io[1];
8226     uint32_t p_do_transform_io[1];
8227     uint32_t p_decode_blocks[1];
8228     uint32_t p_decode_uncompressed[1];
8229     uint32_t p_init_dynamic_huffman[1];
8230     wuffs_base__status (*choosy_decode_huffman_fast64)(
8231         wuffs_deflate__decoder* self,
8232         wuffs_base__io_buffer* a_dst,
8233         wuffs_base__io_buffer* a_src);
8234     uint32_t p_decode_huffman_slow[1];
8235   } private_impl;
8236 
8237   struct {
8238     uint32_t f_huffs[2][1024];
8239     uint8_t f_history[33025];
8240     uint8_t f_code_lengths[320];
8241 
8242     struct {
8243       uint32_t v_final;
8244     } s_decode_blocks[1];
8245     struct {
8246       uint32_t v_length;
8247       uint64_t scratch;
8248     } s_decode_uncompressed[1];
8249     struct {
8250       uint32_t v_bits;
8251       uint32_t v_n_bits;
8252       uint32_t v_n_lit;
8253       uint32_t v_n_dist;
8254       uint32_t v_n_clen;
8255       uint32_t v_i;
8256       uint32_t v_mask;
8257       uint32_t v_n_extra_bits;
8258       uint8_t v_rep_symbol;
8259       uint32_t v_rep_count;
8260     } s_init_dynamic_huffman[1];
8261     struct {
8262       uint32_t v_bits;
8263       uint32_t v_n_bits;
8264       uint32_t v_table_entry_n_bits;
8265       uint32_t v_lmask;
8266       uint32_t v_dmask;
8267       uint32_t v_redir_top;
8268       uint32_t v_redir_mask;
8269       uint32_t v_length;
8270       uint32_t v_dist_minus_1;
8271       uint64_t scratch;
8272     } s_decode_huffman_slow[1];
8273   } private_data;
8274 
8275 #ifdef __cplusplus
8276 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
8277   using unique_ptr = std::unique_ptr<wuffs_deflate__decoder, wuffs_unique_ptr_deleter>;
8278 
8279   // On failure, the alloc_etc functions return nullptr. They don't throw.
8280 
8281   static inline unique_ptr
allocwuffs_deflate__decoder__struct8282   alloc() {
8283     return unique_ptr(wuffs_deflate__decoder__alloc());
8284   }
8285 
8286   static inline wuffs_base__io_transformer::unique_ptr
alloc_as__wuffs_base__io_transformerwuffs_deflate__decoder__struct8287   alloc_as__wuffs_base__io_transformer() {
8288     return wuffs_base__io_transformer::unique_ptr(
8289         wuffs_deflate__decoder__alloc_as__wuffs_base__io_transformer());
8290   }
8291 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
8292 
8293 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
8294   // Disallow constructing or copying an object via standard C++ mechanisms,
8295   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
8296   // size and field layout is not part of the public, stable, memory-safe API.
8297   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
8298   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
8299   // their first argument) rather than tweaking bar.private_impl.qux fields.
8300   //
8301   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
8302   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
8303   // order to provide convenience methods. These forward on "this", so that you
8304   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
8305   wuffs_deflate__decoder__struct() = delete;
8306   wuffs_deflate__decoder__struct(const wuffs_deflate__decoder__struct&) = delete;
8307   wuffs_deflate__decoder__struct& operator=(
8308       const wuffs_deflate__decoder__struct&) = delete;
8309 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
8310 
8311 #if !defined(WUFFS_IMPLEMENTATION)
8312   // As above, the size of the struct is not part of the public API, and unless
8313   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
8314   // allocated, not stack allocated. Its size is not intended to be known at
8315   // compile time, but it is unfortunately divulged as a side effect of
8316   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
8317   // instead of "sizeof T", invoking the operator. To make the two values
8318   // different, so that passing the latter will be rejected by the initialize
8319   // function, we add an arbitrary amount of dead weight.
8320   uint8_t dead_weight[123000000];  // 123 MB.
8321 #endif  // !defined(WUFFS_IMPLEMENTATION)
8322 
8323   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_deflate__decoder__struct8324   initialize(
8325       size_t sizeof_star_self,
8326       uint64_t wuffs_version,
8327       uint32_t options) {
8328     return wuffs_deflate__decoder__initialize(
8329         this, sizeof_star_self, wuffs_version, options);
8330   }
8331 
8332   inline wuffs_base__io_transformer*
upcast_as__wuffs_base__io_transformerwuffs_deflate__decoder__struct8333   upcast_as__wuffs_base__io_transformer() {
8334     return (wuffs_base__io_transformer*)this;
8335   }
8336 
8337   inline wuffs_base__empty_struct
add_historywuffs_deflate__decoder__struct8338   add_history(
8339       wuffs_base__slice_u8 a_hist) {
8340     return wuffs_deflate__decoder__add_history(this, a_hist);
8341   }
8342 
8343   inline uint64_t
get_quirkwuffs_deflate__decoder__struct8344   get_quirk(
8345       uint32_t a_key) const {
8346     return wuffs_deflate__decoder__get_quirk(this, a_key);
8347   }
8348 
8349   inline wuffs_base__status
set_quirkwuffs_deflate__decoder__struct8350   set_quirk(
8351       uint32_t a_key,
8352       uint64_t a_value) {
8353     return wuffs_deflate__decoder__set_quirk(this, a_key, a_value);
8354   }
8355 
8356   inline uint64_t
history_retain_lengthwuffs_deflate__decoder__struct8357   history_retain_length() const {
8358     return wuffs_deflate__decoder__history_retain_length(this);
8359   }
8360 
8361   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_deflate__decoder__struct8362   workbuf_len() const {
8363     return wuffs_deflate__decoder__workbuf_len(this);
8364   }
8365 
8366   inline wuffs_base__status
transform_iowuffs_deflate__decoder__struct8367   transform_io(
8368       wuffs_base__io_buffer* a_dst,
8369       wuffs_base__io_buffer* a_src,
8370       wuffs_base__slice_u8 a_workbuf) {
8371     return wuffs_deflate__decoder__transform_io(this, a_dst, a_src, a_workbuf);
8372   }
8373 
8374 #endif  // __cplusplus
8375 };  // struct wuffs_deflate__decoder__struct
8376 
8377 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
8378 
8379 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__DEFLATE) || defined(WUFFS_NONMONOLITHIC)
8380 
8381 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GIF) || defined(WUFFS_NONMONOLITHIC)
8382 
8383 // ---------------- Status Codes
8384 
8385 extern const char wuffs_gif__error__bad_lzw_code[];
8386 extern const char wuffs_gif__error__bad_extension_label[];
8387 extern const char wuffs_gif__error__bad_frame_size[];
8388 extern const char wuffs_gif__error__bad_graphic_control[];
8389 extern const char wuffs_gif__error__bad_header[];
8390 extern const char wuffs_gif__error__bad_literal_width[];
8391 extern const char wuffs_gif__error__bad_palette[];
8392 extern const char wuffs_gif__error__truncated_input[];
8393 
8394 // ---------------- Public Consts
8395 
8396 #define WUFFS_GIF__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0
8397 
8398 #define WUFFS_GIF__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
8399 
8400 #define WUFFS_GIF__QUIRK_DELAY_NUM_DECODED_FRAMES 1041635328
8401 
8402 #define WUFFS_GIF__QUIRK_FIRST_FRAME_LOCAL_PALETTE_MEANS_BLACK_BACKGROUND 1041635329
8403 
8404 #define WUFFS_GIF__QUIRK_HONOR_BACKGROUND_COLOR 1041635330
8405 
8406 #define WUFFS_GIF__QUIRK_IGNORE_TOO_MUCH_PIXEL_DATA 1041635331
8407 
8408 #define WUFFS_GIF__QUIRK_IMAGE_BOUNDS_ARE_STRICT 1041635332
8409 
8410 #define WUFFS_GIF__QUIRK_REJECT_EMPTY_FRAME 1041635333
8411 
8412 #define WUFFS_GIF__QUIRK_REJECT_EMPTY_PALETTE 1041635334
8413 
8414 // ---------------- Struct Declarations
8415 
8416 typedef struct wuffs_gif__decoder__struct wuffs_gif__decoder;
8417 
8418 #ifdef __cplusplus
8419 extern "C" {
8420 #endif
8421 
8422 // ---------------- Public Initializer Prototypes
8423 
8424 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
8425 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
8426 //
8427 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
8428 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
8429 
8430 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
8431 wuffs_gif__decoder__initialize(
8432     wuffs_gif__decoder* self,
8433     size_t sizeof_star_self,
8434     uint64_t wuffs_version,
8435     uint32_t options);
8436 
8437 size_t
8438 sizeof__wuffs_gif__decoder(void);
8439 
8440 // ---------------- Allocs
8441 
8442 // These functions allocate and initialize Wuffs structs. They return NULL if
8443 // memory allocation fails. If they return non-NULL, there is no need to call
8444 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
8445 // calling free on the returned pointer. That pointer is effectively a C++
8446 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
8447 
8448 wuffs_gif__decoder*
8449 wuffs_gif__decoder__alloc(void);
8450 
8451 static inline wuffs_base__image_decoder*
wuffs_gif__decoder__alloc_as__wuffs_base__image_decoder(void)8452 wuffs_gif__decoder__alloc_as__wuffs_base__image_decoder(void) {
8453   return (wuffs_base__image_decoder*)(wuffs_gif__decoder__alloc());
8454 }
8455 
8456 // ---------------- Upcasts
8457 
8458 static inline wuffs_base__image_decoder*
wuffs_gif__decoder__upcast_as__wuffs_base__image_decoder(wuffs_gif__decoder * p)8459 wuffs_gif__decoder__upcast_as__wuffs_base__image_decoder(
8460     wuffs_gif__decoder* p) {
8461   return (wuffs_base__image_decoder*)p;
8462 }
8463 
8464 // ---------------- Public Function Prototypes
8465 
8466 WUFFS_BASE__GENERATED_C_CODE
8467 WUFFS_BASE__MAYBE_STATIC uint64_t
8468 wuffs_gif__decoder__get_quirk(
8469     const wuffs_gif__decoder* self,
8470     uint32_t a_key);
8471 
8472 WUFFS_BASE__GENERATED_C_CODE
8473 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8474 wuffs_gif__decoder__set_quirk(
8475     wuffs_gif__decoder* self,
8476     uint32_t a_key,
8477     uint64_t a_value);
8478 
8479 WUFFS_BASE__GENERATED_C_CODE
8480 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8481 wuffs_gif__decoder__decode_image_config(
8482     wuffs_gif__decoder* self,
8483     wuffs_base__image_config* a_dst,
8484     wuffs_base__io_buffer* a_src);
8485 
8486 WUFFS_BASE__GENERATED_C_CODE
8487 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
8488 wuffs_gif__decoder__set_report_metadata(
8489     wuffs_gif__decoder* self,
8490     uint32_t a_fourcc,
8491     bool a_report);
8492 
8493 WUFFS_BASE__GENERATED_C_CODE
8494 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8495 wuffs_gif__decoder__tell_me_more(
8496     wuffs_gif__decoder* self,
8497     wuffs_base__io_buffer* a_dst,
8498     wuffs_base__more_information* a_minfo,
8499     wuffs_base__io_buffer* a_src);
8500 
8501 WUFFS_BASE__GENERATED_C_CODE
8502 WUFFS_BASE__MAYBE_STATIC uint32_t
8503 wuffs_gif__decoder__num_animation_loops(
8504     const wuffs_gif__decoder* self);
8505 
8506 WUFFS_BASE__GENERATED_C_CODE
8507 WUFFS_BASE__MAYBE_STATIC uint64_t
8508 wuffs_gif__decoder__num_decoded_frame_configs(
8509     const wuffs_gif__decoder* self);
8510 
8511 WUFFS_BASE__GENERATED_C_CODE
8512 WUFFS_BASE__MAYBE_STATIC uint64_t
8513 wuffs_gif__decoder__num_decoded_frames(
8514     const wuffs_gif__decoder* self);
8515 
8516 WUFFS_BASE__GENERATED_C_CODE
8517 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
8518 wuffs_gif__decoder__frame_dirty_rect(
8519     const wuffs_gif__decoder* self);
8520 
8521 WUFFS_BASE__GENERATED_C_CODE
8522 WUFFS_BASE__MAYBE_STATIC uint64_t
8523 wuffs_gif__decoder__history_retain_length(
8524     const wuffs_gif__decoder* self);
8525 
8526 WUFFS_BASE__GENERATED_C_CODE
8527 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
8528 wuffs_gif__decoder__workbuf_len(
8529     const wuffs_gif__decoder* self);
8530 
8531 WUFFS_BASE__GENERATED_C_CODE
8532 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8533 wuffs_gif__decoder__restart_frame(
8534     wuffs_gif__decoder* self,
8535     uint64_t a_index,
8536     uint64_t a_io_position);
8537 
8538 WUFFS_BASE__GENERATED_C_CODE
8539 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8540 wuffs_gif__decoder__decode_frame_config(
8541     wuffs_gif__decoder* self,
8542     wuffs_base__frame_config* a_dst,
8543     wuffs_base__io_buffer* a_src);
8544 
8545 WUFFS_BASE__GENERATED_C_CODE
8546 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8547 wuffs_gif__decoder__decode_frame(
8548     wuffs_gif__decoder* self,
8549     wuffs_base__pixel_buffer* a_dst,
8550     wuffs_base__io_buffer* a_src,
8551     wuffs_base__pixel_blend a_blend,
8552     wuffs_base__slice_u8 a_workbuf,
8553     wuffs_base__decode_frame_options* a_opts);
8554 
8555 #ifdef __cplusplus
8556 }  // extern "C"
8557 #endif
8558 
8559 // ---------------- Struct Definitions
8560 
8561 // These structs' fields, and the sizeof them, are private implementation
8562 // details that aren't guaranteed to be stable across Wuffs versions.
8563 //
8564 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
8565 
8566 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
8567 
8568 struct wuffs_gif__decoder__struct {
8569   // Do not access the private_impl's or private_data's fields directly. There
8570   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
8571   // the wuffs_foo__bar__baz functions.
8572   //
8573   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
8574   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
8575 
8576   struct {
8577     uint32_t magic;
8578     uint32_t active_coroutine;
8579     wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
8580     wuffs_base__vtable null_vtable;
8581 
8582     uint32_t f_width;
8583     uint32_t f_height;
8584     uint8_t f_call_sequence;
8585     bool f_report_metadata_iccp;
8586     bool f_report_metadata_xmp;
8587     uint32_t f_metadata_fourcc;
8588     uint64_t f_metadata_io_position;
8589     bool f_quirks[7];
8590     bool f_delayed_num_decoded_frames;
8591     bool f_seen_header;
8592     bool f_ignored_but_affects_benchmarks;
8593     bool f_has_global_palette;
8594     uint8_t f_interlace;
8595     bool f_seen_num_animation_loops_value;
8596     uint32_t f_num_animation_loops_value;
8597     uint32_t f_background_color_u32_argb_premul;
8598     uint32_t f_black_color_u32_argb_premul;
8599     bool f_gc_has_transparent_index;
8600     uint8_t f_gc_transparent_index;
8601     uint8_t f_gc_disposal;
8602     uint64_t f_gc_duration;
8603     uint64_t f_frame_config_io_position;
8604     uint64_t f_num_decoded_frame_configs_value;
8605     uint64_t f_num_decoded_frames_value;
8606     uint32_t f_frame_rect_x0;
8607     uint32_t f_frame_rect_y0;
8608     uint32_t f_frame_rect_x1;
8609     uint32_t f_frame_rect_y1;
8610     uint32_t f_dst_x;
8611     uint32_t f_dst_y;
8612     uint32_t f_dirty_max_excl_y;
8613     uint64_t f_compressed_ri;
8614     uint64_t f_compressed_wi;
8615     wuffs_base__pixel_swizzler f_swizzler;
8616     uint32_t f_lzw_pending_literal_width_plus_one;
8617     uint32_t f_lzw_literal_width;
8618     uint32_t f_lzw_clear_code;
8619     uint32_t f_lzw_end_code;
8620     uint32_t f_lzw_save_code;
8621     uint32_t f_lzw_prev_code;
8622     uint32_t f_lzw_width;
8623     uint32_t f_lzw_bits;
8624     uint32_t f_lzw_n_bits;
8625     uint32_t f_lzw_output_ri;
8626     uint32_t f_lzw_output_wi;
8627     uint32_t f_lzw_read_from_return_value;
8628     uint16_t f_lzw_prefixes[4096];
8629 
8630     uint32_t p_decode_image_config[1];
8631     uint32_t p_do_decode_image_config[1];
8632     uint32_t p_tell_me_more[1];
8633     uint32_t p_do_tell_me_more[1];
8634     uint32_t p_decode_frame_config[1];
8635     uint32_t p_do_decode_frame_config[1];
8636     uint32_t p_skip_frame[1];
8637     uint32_t p_decode_frame[1];
8638     uint32_t p_do_decode_frame[1];
8639     uint32_t p_decode_up_to_id_part1[1];
8640     uint32_t p_decode_header[1];
8641     uint32_t p_decode_lsd[1];
8642     uint32_t p_decode_extension[1];
8643     uint32_t p_skip_blocks[1];
8644     uint32_t p_decode_ae[1];
8645     uint32_t p_decode_gc[1];
8646     uint32_t p_decode_id_part0[1];
8647     uint32_t p_decode_id_part1[1];
8648     uint32_t p_decode_id_part2[1];
8649   } private_impl;
8650 
8651   struct {
8652     uint8_t f_compressed[4096];
8653     uint8_t f_palettes[2][1024];
8654     uint8_t f_dst_palette[1024];
8655     uint8_t f_lzw_suffixes[4096][8];
8656     uint16_t f_lzw_lm1s[4096];
8657     uint8_t f_lzw_output[8199];
8658 
8659     struct {
8660       uint32_t v_background_color;
8661     } s_do_decode_frame_config[1];
8662     struct {
8663       uint64_t scratch;
8664     } s_skip_frame[1];
8665     struct {
8666       uint8_t v_c[6];
8667       uint32_t v_i;
8668     } s_decode_header[1];
8669     struct {
8670       uint8_t v_flags;
8671       uint8_t v_background_color_index;
8672       uint32_t v_num_palette_entries;
8673       uint32_t v_i;
8674       uint64_t scratch;
8675     } s_decode_lsd[1];
8676     struct {
8677       uint64_t scratch;
8678     } s_skip_blocks[1];
8679     struct {
8680       uint8_t v_block_size;
8681       bool v_is_animexts;
8682       bool v_is_netscape;
8683       bool v_is_iccp;
8684       bool v_is_xmp;
8685       uint64_t scratch;
8686     } s_decode_ae[1];
8687     struct {
8688       uint64_t scratch;
8689     } s_decode_gc[1];
8690     struct {
8691       uint64_t scratch;
8692     } s_decode_id_part0[1];
8693     struct {
8694       uint8_t v_which_palette;
8695       uint32_t v_num_palette_entries;
8696       uint32_t v_i;
8697       uint64_t scratch;
8698     } s_decode_id_part1[1];
8699     struct {
8700       uint64_t v_block_size;
8701       bool v_need_block_size;
8702       uint64_t scratch;
8703     } s_decode_id_part2[1];
8704   } private_data;
8705 
8706 #ifdef __cplusplus
8707 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
8708   using unique_ptr = std::unique_ptr<wuffs_gif__decoder, wuffs_unique_ptr_deleter>;
8709 
8710   // On failure, the alloc_etc functions return nullptr. They don't throw.
8711 
8712   static inline unique_ptr
allocwuffs_gif__decoder__struct8713   alloc() {
8714     return unique_ptr(wuffs_gif__decoder__alloc());
8715   }
8716 
8717   static inline wuffs_base__image_decoder::unique_ptr
alloc_as__wuffs_base__image_decoderwuffs_gif__decoder__struct8718   alloc_as__wuffs_base__image_decoder() {
8719     return wuffs_base__image_decoder::unique_ptr(
8720         wuffs_gif__decoder__alloc_as__wuffs_base__image_decoder());
8721   }
8722 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
8723 
8724 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
8725   // Disallow constructing or copying an object via standard C++ mechanisms,
8726   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
8727   // size and field layout is not part of the public, stable, memory-safe API.
8728   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
8729   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
8730   // their first argument) rather than tweaking bar.private_impl.qux fields.
8731   //
8732   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
8733   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
8734   // order to provide convenience methods. These forward on "this", so that you
8735   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
8736   wuffs_gif__decoder__struct() = delete;
8737   wuffs_gif__decoder__struct(const wuffs_gif__decoder__struct&) = delete;
8738   wuffs_gif__decoder__struct& operator=(
8739       const wuffs_gif__decoder__struct&) = delete;
8740 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
8741 
8742 #if !defined(WUFFS_IMPLEMENTATION)
8743   // As above, the size of the struct is not part of the public API, and unless
8744   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
8745   // allocated, not stack allocated. Its size is not intended to be known at
8746   // compile time, but it is unfortunately divulged as a side effect of
8747   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
8748   // instead of "sizeof T", invoking the operator. To make the two values
8749   // different, so that passing the latter will be rejected by the initialize
8750   // function, we add an arbitrary amount of dead weight.
8751   uint8_t dead_weight[123000000];  // 123 MB.
8752 #endif  // !defined(WUFFS_IMPLEMENTATION)
8753 
8754   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_gif__decoder__struct8755   initialize(
8756       size_t sizeof_star_self,
8757       uint64_t wuffs_version,
8758       uint32_t options) {
8759     return wuffs_gif__decoder__initialize(
8760         this, sizeof_star_self, wuffs_version, options);
8761   }
8762 
8763   inline wuffs_base__image_decoder*
upcast_as__wuffs_base__image_decoderwuffs_gif__decoder__struct8764   upcast_as__wuffs_base__image_decoder() {
8765     return (wuffs_base__image_decoder*)this;
8766   }
8767 
8768   inline uint64_t
get_quirkwuffs_gif__decoder__struct8769   get_quirk(
8770       uint32_t a_key) const {
8771     return wuffs_gif__decoder__get_quirk(this, a_key);
8772   }
8773 
8774   inline wuffs_base__status
set_quirkwuffs_gif__decoder__struct8775   set_quirk(
8776       uint32_t a_key,
8777       uint64_t a_value) {
8778     return wuffs_gif__decoder__set_quirk(this, a_key, a_value);
8779   }
8780 
8781   inline wuffs_base__status
decode_image_configwuffs_gif__decoder__struct8782   decode_image_config(
8783       wuffs_base__image_config* a_dst,
8784       wuffs_base__io_buffer* a_src) {
8785     return wuffs_gif__decoder__decode_image_config(this, a_dst, a_src);
8786   }
8787 
8788   inline wuffs_base__empty_struct
set_report_metadatawuffs_gif__decoder__struct8789   set_report_metadata(
8790       uint32_t a_fourcc,
8791       bool a_report) {
8792     return wuffs_gif__decoder__set_report_metadata(this, a_fourcc, a_report);
8793   }
8794 
8795   inline wuffs_base__status
tell_me_morewuffs_gif__decoder__struct8796   tell_me_more(
8797       wuffs_base__io_buffer* a_dst,
8798       wuffs_base__more_information* a_minfo,
8799       wuffs_base__io_buffer* a_src) {
8800     return wuffs_gif__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
8801   }
8802 
8803   inline uint32_t
num_animation_loopswuffs_gif__decoder__struct8804   num_animation_loops() const {
8805     return wuffs_gif__decoder__num_animation_loops(this);
8806   }
8807 
8808   inline uint64_t
num_decoded_frame_configswuffs_gif__decoder__struct8809   num_decoded_frame_configs() const {
8810     return wuffs_gif__decoder__num_decoded_frame_configs(this);
8811   }
8812 
8813   inline uint64_t
num_decoded_frameswuffs_gif__decoder__struct8814   num_decoded_frames() const {
8815     return wuffs_gif__decoder__num_decoded_frames(this);
8816   }
8817 
8818   inline wuffs_base__rect_ie_u32
frame_dirty_rectwuffs_gif__decoder__struct8819   frame_dirty_rect() const {
8820     return wuffs_gif__decoder__frame_dirty_rect(this);
8821   }
8822 
8823   inline uint64_t
history_retain_lengthwuffs_gif__decoder__struct8824   history_retain_length() const {
8825     return wuffs_gif__decoder__history_retain_length(this);
8826   }
8827 
8828   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_gif__decoder__struct8829   workbuf_len() const {
8830     return wuffs_gif__decoder__workbuf_len(this);
8831   }
8832 
8833   inline wuffs_base__status
restart_framewuffs_gif__decoder__struct8834   restart_frame(
8835       uint64_t a_index,
8836       uint64_t a_io_position) {
8837     return wuffs_gif__decoder__restart_frame(this, a_index, a_io_position);
8838   }
8839 
8840   inline wuffs_base__status
decode_frame_configwuffs_gif__decoder__struct8841   decode_frame_config(
8842       wuffs_base__frame_config* a_dst,
8843       wuffs_base__io_buffer* a_src) {
8844     return wuffs_gif__decoder__decode_frame_config(this, a_dst, a_src);
8845   }
8846 
8847   inline wuffs_base__status
decode_framewuffs_gif__decoder__struct8848   decode_frame(
8849       wuffs_base__pixel_buffer* a_dst,
8850       wuffs_base__io_buffer* a_src,
8851       wuffs_base__pixel_blend a_blend,
8852       wuffs_base__slice_u8 a_workbuf,
8853       wuffs_base__decode_frame_options* a_opts) {
8854     return wuffs_gif__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
8855   }
8856 
8857 #endif  // __cplusplus
8858 };  // struct wuffs_gif__decoder__struct
8859 
8860 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
8861 
8862 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GIF) || defined(WUFFS_NONMONOLITHIC)
8863 
8864 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GZIP) || defined(WUFFS_NONMONOLITHIC)
8865 
8866 // ---------------- Status Codes
8867 
8868 extern const char wuffs_gzip__error__bad_checksum[];
8869 extern const char wuffs_gzip__error__bad_compression_method[];
8870 extern const char wuffs_gzip__error__bad_encoding_flags[];
8871 extern const char wuffs_gzip__error__bad_header[];
8872 extern const char wuffs_gzip__error__truncated_input[];
8873 
8874 // ---------------- Public Consts
8875 
8876 #define WUFFS_GZIP__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0
8877 
8878 #define WUFFS_GZIP__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 1
8879 
8880 // ---------------- Struct Declarations
8881 
8882 typedef struct wuffs_gzip__decoder__struct wuffs_gzip__decoder;
8883 
8884 #ifdef __cplusplus
8885 extern "C" {
8886 #endif
8887 
8888 // ---------------- Public Initializer Prototypes
8889 
8890 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
8891 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
8892 //
8893 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
8894 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
8895 
8896 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
8897 wuffs_gzip__decoder__initialize(
8898     wuffs_gzip__decoder* self,
8899     size_t sizeof_star_self,
8900     uint64_t wuffs_version,
8901     uint32_t options);
8902 
8903 size_t
8904 sizeof__wuffs_gzip__decoder(void);
8905 
8906 // ---------------- Allocs
8907 
8908 // These functions allocate and initialize Wuffs structs. They return NULL if
8909 // memory allocation fails. If they return non-NULL, there is no need to call
8910 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
8911 // calling free on the returned pointer. That pointer is effectively a C++
8912 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
8913 
8914 wuffs_gzip__decoder*
8915 wuffs_gzip__decoder__alloc(void);
8916 
8917 static inline wuffs_base__io_transformer*
wuffs_gzip__decoder__alloc_as__wuffs_base__io_transformer(void)8918 wuffs_gzip__decoder__alloc_as__wuffs_base__io_transformer(void) {
8919   return (wuffs_base__io_transformer*)(wuffs_gzip__decoder__alloc());
8920 }
8921 
8922 // ---------------- Upcasts
8923 
8924 static inline wuffs_base__io_transformer*
wuffs_gzip__decoder__upcast_as__wuffs_base__io_transformer(wuffs_gzip__decoder * p)8925 wuffs_gzip__decoder__upcast_as__wuffs_base__io_transformer(
8926     wuffs_gzip__decoder* p) {
8927   return (wuffs_base__io_transformer*)p;
8928 }
8929 
8930 // ---------------- Public Function Prototypes
8931 
8932 WUFFS_BASE__GENERATED_C_CODE
8933 WUFFS_BASE__MAYBE_STATIC uint64_t
8934 wuffs_gzip__decoder__get_quirk(
8935     const wuffs_gzip__decoder* self,
8936     uint32_t a_key);
8937 
8938 WUFFS_BASE__GENERATED_C_CODE
8939 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8940 wuffs_gzip__decoder__set_quirk(
8941     wuffs_gzip__decoder* self,
8942     uint32_t a_key,
8943     uint64_t a_value);
8944 
8945 WUFFS_BASE__GENERATED_C_CODE
8946 WUFFS_BASE__MAYBE_STATIC uint64_t
8947 wuffs_gzip__decoder__history_retain_length(
8948     const wuffs_gzip__decoder* self);
8949 
8950 WUFFS_BASE__GENERATED_C_CODE
8951 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
8952 wuffs_gzip__decoder__workbuf_len(
8953     const wuffs_gzip__decoder* self);
8954 
8955 WUFFS_BASE__GENERATED_C_CODE
8956 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8957 wuffs_gzip__decoder__transform_io(
8958     wuffs_gzip__decoder* self,
8959     wuffs_base__io_buffer* a_dst,
8960     wuffs_base__io_buffer* a_src,
8961     wuffs_base__slice_u8 a_workbuf);
8962 
8963 #ifdef __cplusplus
8964 }  // extern "C"
8965 #endif
8966 
8967 // ---------------- Struct Definitions
8968 
8969 // These structs' fields, and the sizeof them, are private implementation
8970 // details that aren't guaranteed to be stable across Wuffs versions.
8971 //
8972 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
8973 
8974 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
8975 
8976 struct wuffs_gzip__decoder__struct {
8977   // Do not access the private_impl's or private_data's fields directly. There
8978   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
8979   // the wuffs_foo__bar__baz functions.
8980   //
8981   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
8982   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
8983 
8984   struct {
8985     uint32_t magic;
8986     uint32_t active_coroutine;
8987     wuffs_base__vtable vtable_for__wuffs_base__io_transformer;
8988     wuffs_base__vtable null_vtable;
8989 
8990     bool f_ignore_checksum;
8991 
8992     uint32_t p_transform_io[1];
8993     uint32_t p_do_transform_io[1];
8994   } private_impl;
8995 
8996   struct {
8997     wuffs_crc32__ieee_hasher f_checksum;
8998     wuffs_deflate__decoder f_flate;
8999 
9000     struct {
9001       uint8_t v_flags;
9002       uint32_t v_checksum_got;
9003       uint32_t v_decoded_length_got;
9004       uint32_t v_checksum_want;
9005       uint64_t scratch;
9006     } s_do_transform_io[1];
9007   } private_data;
9008 
9009 #ifdef __cplusplus
9010 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
9011   using unique_ptr = std::unique_ptr<wuffs_gzip__decoder, wuffs_unique_ptr_deleter>;
9012 
9013   // On failure, the alloc_etc functions return nullptr. They don't throw.
9014 
9015   static inline unique_ptr
allocwuffs_gzip__decoder__struct9016   alloc() {
9017     return unique_ptr(wuffs_gzip__decoder__alloc());
9018   }
9019 
9020   static inline wuffs_base__io_transformer::unique_ptr
alloc_as__wuffs_base__io_transformerwuffs_gzip__decoder__struct9021   alloc_as__wuffs_base__io_transformer() {
9022     return wuffs_base__io_transformer::unique_ptr(
9023         wuffs_gzip__decoder__alloc_as__wuffs_base__io_transformer());
9024   }
9025 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
9026 
9027 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
9028   // Disallow constructing or copying an object via standard C++ mechanisms,
9029   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
9030   // size and field layout is not part of the public, stable, memory-safe API.
9031   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
9032   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
9033   // their first argument) rather than tweaking bar.private_impl.qux fields.
9034   //
9035   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
9036   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
9037   // order to provide convenience methods. These forward on "this", so that you
9038   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
9039   wuffs_gzip__decoder__struct() = delete;
9040   wuffs_gzip__decoder__struct(const wuffs_gzip__decoder__struct&) = delete;
9041   wuffs_gzip__decoder__struct& operator=(
9042       const wuffs_gzip__decoder__struct&) = delete;
9043 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
9044 
9045 #if !defined(WUFFS_IMPLEMENTATION)
9046   // As above, the size of the struct is not part of the public API, and unless
9047   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
9048   // allocated, not stack allocated. Its size is not intended to be known at
9049   // compile time, but it is unfortunately divulged as a side effect of
9050   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
9051   // instead of "sizeof T", invoking the operator. To make the two values
9052   // different, so that passing the latter will be rejected by the initialize
9053   // function, we add an arbitrary amount of dead weight.
9054   uint8_t dead_weight[123000000];  // 123 MB.
9055 #endif  // !defined(WUFFS_IMPLEMENTATION)
9056 
9057   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_gzip__decoder__struct9058   initialize(
9059       size_t sizeof_star_self,
9060       uint64_t wuffs_version,
9061       uint32_t options) {
9062     return wuffs_gzip__decoder__initialize(
9063         this, sizeof_star_self, wuffs_version, options);
9064   }
9065 
9066   inline wuffs_base__io_transformer*
upcast_as__wuffs_base__io_transformerwuffs_gzip__decoder__struct9067   upcast_as__wuffs_base__io_transformer() {
9068     return (wuffs_base__io_transformer*)this;
9069   }
9070 
9071   inline uint64_t
get_quirkwuffs_gzip__decoder__struct9072   get_quirk(
9073       uint32_t a_key) const {
9074     return wuffs_gzip__decoder__get_quirk(this, a_key);
9075   }
9076 
9077   inline wuffs_base__status
set_quirkwuffs_gzip__decoder__struct9078   set_quirk(
9079       uint32_t a_key,
9080       uint64_t a_value) {
9081     return wuffs_gzip__decoder__set_quirk(this, a_key, a_value);
9082   }
9083 
9084   inline uint64_t
history_retain_lengthwuffs_gzip__decoder__struct9085   history_retain_length() const {
9086     return wuffs_gzip__decoder__history_retain_length(this);
9087   }
9088 
9089   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_gzip__decoder__struct9090   workbuf_len() const {
9091     return wuffs_gzip__decoder__workbuf_len(this);
9092   }
9093 
9094   inline wuffs_base__status
transform_iowuffs_gzip__decoder__struct9095   transform_io(
9096       wuffs_base__io_buffer* a_dst,
9097       wuffs_base__io_buffer* a_src,
9098       wuffs_base__slice_u8 a_workbuf) {
9099     return wuffs_gzip__decoder__transform_io(this, a_dst, a_src, a_workbuf);
9100   }
9101 
9102 #endif  // __cplusplus
9103 };  // struct wuffs_gzip__decoder__struct
9104 
9105 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
9106 
9107 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GZIP) || defined(WUFFS_NONMONOLITHIC)
9108 
9109 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JPEG) || defined(WUFFS_NONMONOLITHIC)
9110 
9111 // ---------------- Status Codes
9112 
9113 extern const char wuffs_jpeg__error__bad_dht_marker[];
9114 extern const char wuffs_jpeg__error__bad_dqt_marker[];
9115 extern const char wuffs_jpeg__error__bad_dri_marker[];
9116 extern const char wuffs_jpeg__error__bad_sof_marker[];
9117 extern const char wuffs_jpeg__error__bad_sos_marker[];
9118 extern const char wuffs_jpeg__error__bad_header[];
9119 extern const char wuffs_jpeg__error__bad_marker[];
9120 extern const char wuffs_jpeg__error__missing_huffman_table[];
9121 extern const char wuffs_jpeg__error__missing_quantization_table[];
9122 extern const char wuffs_jpeg__error__truncated_input[];
9123 extern const char wuffs_jpeg__error__unsupported_arithmetic_coding[];
9124 extern const char wuffs_jpeg__error__unsupported_color_model[];
9125 extern const char wuffs_jpeg__error__unsupported_fractional_sampling[];
9126 extern const char wuffs_jpeg__error__unsupported_hierarchical_coding[];
9127 extern const char wuffs_jpeg__error__unsupported_implicit_height[];
9128 extern const char wuffs_jpeg__error__unsupported_lossless_coding[];
9129 extern const char wuffs_jpeg__error__unsupported_marker[];
9130 extern const char wuffs_jpeg__error__unsupported_precision_12_bits[];
9131 extern const char wuffs_jpeg__error__unsupported_precision_16_bits[];
9132 extern const char wuffs_jpeg__error__unsupported_precision[];
9133 extern const char wuffs_jpeg__error__unsupported_scan_count[];
9134 
9135 // ---------------- Public Consts
9136 
9137 #define WUFFS_JPEG__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0
9138 
9139 #define WUFFS_JPEG__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 51552191232
9140 
9141 // ---------------- Struct Declarations
9142 
9143 typedef struct wuffs_jpeg__decoder__struct wuffs_jpeg__decoder;
9144 
9145 #ifdef __cplusplus
9146 extern "C" {
9147 #endif
9148 
9149 // ---------------- Public Initializer Prototypes
9150 
9151 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
9152 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
9153 //
9154 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
9155 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
9156 
9157 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
9158 wuffs_jpeg__decoder__initialize(
9159     wuffs_jpeg__decoder* self,
9160     size_t sizeof_star_self,
9161     uint64_t wuffs_version,
9162     uint32_t options);
9163 
9164 size_t
9165 sizeof__wuffs_jpeg__decoder(void);
9166 
9167 // ---------------- Allocs
9168 
9169 // These functions allocate and initialize Wuffs structs. They return NULL if
9170 // memory allocation fails. If they return non-NULL, there is no need to call
9171 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
9172 // calling free on the returned pointer. That pointer is effectively a C++
9173 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
9174 
9175 wuffs_jpeg__decoder*
9176 wuffs_jpeg__decoder__alloc(void);
9177 
9178 static inline wuffs_base__image_decoder*
wuffs_jpeg__decoder__alloc_as__wuffs_base__image_decoder(void)9179 wuffs_jpeg__decoder__alloc_as__wuffs_base__image_decoder(void) {
9180   return (wuffs_base__image_decoder*)(wuffs_jpeg__decoder__alloc());
9181 }
9182 
9183 // ---------------- Upcasts
9184 
9185 static inline wuffs_base__image_decoder*
wuffs_jpeg__decoder__upcast_as__wuffs_base__image_decoder(wuffs_jpeg__decoder * p)9186 wuffs_jpeg__decoder__upcast_as__wuffs_base__image_decoder(
9187     wuffs_jpeg__decoder* p) {
9188   return (wuffs_base__image_decoder*)p;
9189 }
9190 
9191 // ---------------- Public Function Prototypes
9192 
9193 WUFFS_BASE__GENERATED_C_CODE
9194 WUFFS_BASE__MAYBE_STATIC uint64_t
9195 wuffs_jpeg__decoder__get_quirk(
9196     const wuffs_jpeg__decoder* self,
9197     uint32_t a_key);
9198 
9199 WUFFS_BASE__GENERATED_C_CODE
9200 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9201 wuffs_jpeg__decoder__set_quirk(
9202     wuffs_jpeg__decoder* self,
9203     uint32_t a_key,
9204     uint64_t a_value);
9205 
9206 WUFFS_BASE__GENERATED_C_CODE
9207 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9208 wuffs_jpeg__decoder__decode_image_config(
9209     wuffs_jpeg__decoder* self,
9210     wuffs_base__image_config* a_dst,
9211     wuffs_base__io_buffer* a_src);
9212 
9213 WUFFS_BASE__GENERATED_C_CODE
9214 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9215 wuffs_jpeg__decoder__decode_frame_config(
9216     wuffs_jpeg__decoder* self,
9217     wuffs_base__frame_config* a_dst,
9218     wuffs_base__io_buffer* a_src);
9219 
9220 WUFFS_BASE__GENERATED_C_CODE
9221 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9222 wuffs_jpeg__decoder__decode_frame(
9223     wuffs_jpeg__decoder* self,
9224     wuffs_base__pixel_buffer* a_dst,
9225     wuffs_base__io_buffer* a_src,
9226     wuffs_base__pixel_blend a_blend,
9227     wuffs_base__slice_u8 a_workbuf,
9228     wuffs_base__decode_frame_options* a_opts);
9229 
9230 WUFFS_BASE__GENERATED_C_CODE
9231 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
9232 wuffs_jpeg__decoder__frame_dirty_rect(
9233     const wuffs_jpeg__decoder* self);
9234 
9235 WUFFS_BASE__GENERATED_C_CODE
9236 WUFFS_BASE__MAYBE_STATIC uint32_t
9237 wuffs_jpeg__decoder__num_animation_loops(
9238     const wuffs_jpeg__decoder* self);
9239 
9240 WUFFS_BASE__GENERATED_C_CODE
9241 WUFFS_BASE__MAYBE_STATIC uint64_t
9242 wuffs_jpeg__decoder__num_decoded_frame_configs(
9243     const wuffs_jpeg__decoder* self);
9244 
9245 WUFFS_BASE__GENERATED_C_CODE
9246 WUFFS_BASE__MAYBE_STATIC uint64_t
9247 wuffs_jpeg__decoder__num_decoded_frames(
9248     const wuffs_jpeg__decoder* self);
9249 
9250 WUFFS_BASE__GENERATED_C_CODE
9251 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9252 wuffs_jpeg__decoder__restart_frame(
9253     wuffs_jpeg__decoder* self,
9254     uint64_t a_index,
9255     uint64_t a_io_position);
9256 
9257 WUFFS_BASE__GENERATED_C_CODE
9258 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
9259 wuffs_jpeg__decoder__set_report_metadata(
9260     wuffs_jpeg__decoder* self,
9261     uint32_t a_fourcc,
9262     bool a_report);
9263 
9264 WUFFS_BASE__GENERATED_C_CODE
9265 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9266 wuffs_jpeg__decoder__tell_me_more(
9267     wuffs_jpeg__decoder* self,
9268     wuffs_base__io_buffer* a_dst,
9269     wuffs_base__more_information* a_minfo,
9270     wuffs_base__io_buffer* a_src);
9271 
9272 WUFFS_BASE__GENERATED_C_CODE
9273 WUFFS_BASE__MAYBE_STATIC uint64_t
9274 wuffs_jpeg__decoder__history_retain_length(
9275     const wuffs_jpeg__decoder* self);
9276 
9277 WUFFS_BASE__GENERATED_C_CODE
9278 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
9279 wuffs_jpeg__decoder__workbuf_len(
9280     const wuffs_jpeg__decoder* self);
9281 
9282 #ifdef __cplusplus
9283 }  // extern "C"
9284 #endif
9285 
9286 // ---------------- Struct Definitions
9287 
9288 // These structs' fields, and the sizeof them, are private implementation
9289 // details that aren't guaranteed to be stable across Wuffs versions.
9290 //
9291 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
9292 
9293 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
9294 
9295 struct wuffs_jpeg__decoder__struct {
9296   // Do not access the private_impl's or private_data's fields directly. There
9297   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
9298   // the wuffs_foo__bar__baz functions.
9299   //
9300   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
9301   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
9302 
9303   struct {
9304     uint32_t magic;
9305     uint32_t active_coroutine;
9306     wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
9307     wuffs_base__vtable null_vtable;
9308 
9309     uint32_t f_width;
9310     uint32_t f_height;
9311     uint32_t f_width_in_mcus;
9312     uint32_t f_height_in_mcus;
9313     uint8_t f_call_sequence;
9314     bool f_test_only_interrupt_decode_mcu;
9315     bool f_is_jfif;
9316     uint8_t f_is_adobe;
9317     bool f_is_rgb_or_cmyk;
9318     uint8_t f_sof_marker;
9319     uint8_t f_next_restart_marker;
9320     uint8_t f_max_incl_components_h;
9321     uint8_t f_max_incl_components_v;
9322     uint32_t f_num_components;
9323     uint8_t f_components_c[4];
9324     uint8_t f_components_h[4];
9325     uint8_t f_components_v[4];
9326     uint8_t f_components_tq[4];
9327     uint32_t f_components_workbuf_widths[4];
9328     uint32_t f_components_workbuf_heights[4];
9329     uint64_t f_components_workbuf_offsets[9];
9330     uint32_t f_scan_count;
9331     uint32_t f_scan_num_components;
9332     uint8_t f_scan_comps_cselector[4];
9333     uint8_t f_scan_comps_td[4];
9334     uint8_t f_scan_comps_ta[4];
9335     uint8_t f_scan_ss;
9336     uint8_t f_scan_se;
9337     uint8_t f_scan_ah;
9338     uint8_t f_scan_al;
9339     uint32_t f_scan_width_in_mcus;
9340     uint32_t f_scan_height_in_mcus;
9341     uint8_t f_scan_comps_bx_offset[16];
9342     uint8_t f_scan_comps_by_offset[16];
9343     uint32_t f_mcu_num_blocks;
9344     uint32_t f_mcu_current_block;
9345     uint32_t f_mcu_zig_index;
9346     uint8_t f_mcu_blocks_sselector[16];
9347     uint64_t f_mcu_blocks_offset[10];
9348     uint32_t f_mcu_blocks_mx_mul[10];
9349     uint32_t f_mcu_blocks_my_mul[10];
9350     uint8_t f_mcu_blocks_dc_hselector[10];
9351     uint8_t f_mcu_blocks_ac_hselector[10];
9352     uint16_t f_mcu_previous_dc_values[4];
9353     uint8_t f_block_smoothing_lowest_scan_al[4][10];
9354     uint16_t f_block_smoothing_dc_values[5][5];
9355     uint32_t f_block_smoothing_mx_max_incl;
9356     uint32_t f_block_smoothing_my_max_incl;
9357     uint16_t f_restart_interval;
9358     uint16_t f_saved_restart_interval;
9359     uint16_t f_restarts_remaining;
9360     uint16_t f_eob_run;
9361     uint64_t f_frame_config_io_position;
9362     uint32_t f_payload_length;
9363     bool f_seen_dqt[4];
9364     bool f_saved_seen_dqt[4];
9365     bool f_seen_dht[8];
9366     uint64_t f_bitstream_bits;
9367     uint32_t f_bitstream_n_bits;
9368     uint32_t f_bitstream_ri;
9369     uint32_t f_bitstream_wi;
9370     bool f_bitstream_is_closed;
9371     uint32_t f_bitstream_padding;
9372     uint16_t f_quant_tables[4][64];
9373     uint16_t f_saved_quant_tables[4][64];
9374     uint8_t f_huff_tables_symbols[8][256];
9375     uint32_t f_huff_tables_slow[8][16];
9376     uint16_t f_huff_tables_fast[8][256];
9377     wuffs_base__pixel_swizzler f_swizzler;
9378 
9379     wuffs_base__empty_struct (*choosy_decode_idct)(
9380         wuffs_jpeg__decoder* self,
9381         wuffs_base__slice_u8 a_dst_buffer,
9382         uint64_t a_dst_stride,
9383         uint32_t a_q);
9384     uint32_t p_decode_image_config[1];
9385     uint32_t p_do_decode_image_config[1];
9386     uint32_t p_decode_dqt[1];
9387     uint32_t p_decode_dri[1];
9388     uint32_t p_decode_appn[1];
9389     uint32_t p_decode_sof[1];
9390     uint32_t p_decode_frame_config[1];
9391     uint32_t p_do_decode_frame_config[1];
9392     uint32_t p_decode_frame[1];
9393     uint32_t p_do_decode_frame[1];
9394     uint32_t p_decode_dht[1];
9395     uint32_t p_decode_sos[1];
9396     uint32_t p_prepare_scan[1];
9397     wuffs_base__empty_struct (*choosy_load_mcu_blocks_for_single_component)(
9398         wuffs_jpeg__decoder* self,
9399         uint32_t a_mx,
9400         uint32_t a_my,
9401         wuffs_base__slice_u8 a_workbuf,
9402         uint32_t a_csel);
9403     uint32_t p_skip_past_the_next_restart_marker[1];
9404     uint32_t (*choosy_decode_mcu)(
9405         wuffs_jpeg__decoder* self,
9406         wuffs_base__slice_u8 a_workbuf,
9407         uint32_t a_mx,
9408         uint32_t a_my);
9409   } private_impl;
9410 
9411   struct {
9412     uint8_t f_bitstream_buffer[2048];
9413     uint16_t f_mcu_blocks[10][64];
9414     uint8_t f_swizzle_ycck_scratch_buffer_2k[2048];
9415     uint8_t f_dht_temp_counts[16];
9416     uint8_t f_dht_temp_bit_lengths[256];
9417     uint16_t f_dht_temp_bit_strings[256];
9418     uint8_t f_dst_palette[1024];
9419 
9420     struct {
9421       uint8_t v_marker;
9422       uint64_t scratch;
9423     } s_do_decode_image_config[1];
9424     struct {
9425       uint8_t v_q;
9426       uint32_t v_i;
9427     } s_decode_dqt[1];
9428     struct {
9429       uint64_t scratch;
9430     } s_decode_dri[1];
9431     struct {
9432       uint64_t scratch;
9433     } s_decode_appn[1];
9434     struct {
9435       uint32_t v_i;
9436       uint64_t scratch;
9437     } s_decode_sof[1];
9438     struct {
9439       uint8_t v_marker;
9440       uint64_t scratch;
9441     } s_do_decode_frame[1];
9442     struct {
9443       uint8_t v_tc4_th;
9444       uint32_t v_total_count;
9445       uint32_t v_i;
9446     } s_decode_dht[1];
9447     struct {
9448       uint32_t v_my;
9449       uint32_t v_mx;
9450     } s_decode_sos[1];
9451     struct {
9452       uint32_t v_i;
9453       uint64_t scratch;
9454     } s_prepare_scan[1];
9455   } private_data;
9456 
9457 #ifdef __cplusplus
9458 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
9459   using unique_ptr = std::unique_ptr<wuffs_jpeg__decoder, wuffs_unique_ptr_deleter>;
9460 
9461   // On failure, the alloc_etc functions return nullptr. They don't throw.
9462 
9463   static inline unique_ptr
allocwuffs_jpeg__decoder__struct9464   alloc() {
9465     return unique_ptr(wuffs_jpeg__decoder__alloc());
9466   }
9467 
9468   static inline wuffs_base__image_decoder::unique_ptr
alloc_as__wuffs_base__image_decoderwuffs_jpeg__decoder__struct9469   alloc_as__wuffs_base__image_decoder() {
9470     return wuffs_base__image_decoder::unique_ptr(
9471         wuffs_jpeg__decoder__alloc_as__wuffs_base__image_decoder());
9472   }
9473 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
9474 
9475 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
9476   // Disallow constructing or copying an object via standard C++ mechanisms,
9477   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
9478   // size and field layout is not part of the public, stable, memory-safe API.
9479   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
9480   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
9481   // their first argument) rather than tweaking bar.private_impl.qux fields.
9482   //
9483   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
9484   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
9485   // order to provide convenience methods. These forward on "this", so that you
9486   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
9487   wuffs_jpeg__decoder__struct() = delete;
9488   wuffs_jpeg__decoder__struct(const wuffs_jpeg__decoder__struct&) = delete;
9489   wuffs_jpeg__decoder__struct& operator=(
9490       const wuffs_jpeg__decoder__struct&) = delete;
9491 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
9492 
9493 #if !defined(WUFFS_IMPLEMENTATION)
9494   // As above, the size of the struct is not part of the public API, and unless
9495   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
9496   // allocated, not stack allocated. Its size is not intended to be known at
9497   // compile time, but it is unfortunately divulged as a side effect of
9498   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
9499   // instead of "sizeof T", invoking the operator. To make the two values
9500   // different, so that passing the latter will be rejected by the initialize
9501   // function, we add an arbitrary amount of dead weight.
9502   uint8_t dead_weight[123000000];  // 123 MB.
9503 #endif  // !defined(WUFFS_IMPLEMENTATION)
9504 
9505   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_jpeg__decoder__struct9506   initialize(
9507       size_t sizeof_star_self,
9508       uint64_t wuffs_version,
9509       uint32_t options) {
9510     return wuffs_jpeg__decoder__initialize(
9511         this, sizeof_star_self, wuffs_version, options);
9512   }
9513 
9514   inline wuffs_base__image_decoder*
upcast_as__wuffs_base__image_decoderwuffs_jpeg__decoder__struct9515   upcast_as__wuffs_base__image_decoder() {
9516     return (wuffs_base__image_decoder*)this;
9517   }
9518 
9519   inline uint64_t
get_quirkwuffs_jpeg__decoder__struct9520   get_quirk(
9521       uint32_t a_key) const {
9522     return wuffs_jpeg__decoder__get_quirk(this, a_key);
9523   }
9524 
9525   inline wuffs_base__status
set_quirkwuffs_jpeg__decoder__struct9526   set_quirk(
9527       uint32_t a_key,
9528       uint64_t a_value) {
9529     return wuffs_jpeg__decoder__set_quirk(this, a_key, a_value);
9530   }
9531 
9532   inline wuffs_base__status
decode_image_configwuffs_jpeg__decoder__struct9533   decode_image_config(
9534       wuffs_base__image_config* a_dst,
9535       wuffs_base__io_buffer* a_src) {
9536     return wuffs_jpeg__decoder__decode_image_config(this, a_dst, a_src);
9537   }
9538 
9539   inline wuffs_base__status
decode_frame_configwuffs_jpeg__decoder__struct9540   decode_frame_config(
9541       wuffs_base__frame_config* a_dst,
9542       wuffs_base__io_buffer* a_src) {
9543     return wuffs_jpeg__decoder__decode_frame_config(this, a_dst, a_src);
9544   }
9545 
9546   inline wuffs_base__status
decode_framewuffs_jpeg__decoder__struct9547   decode_frame(
9548       wuffs_base__pixel_buffer* a_dst,
9549       wuffs_base__io_buffer* a_src,
9550       wuffs_base__pixel_blend a_blend,
9551       wuffs_base__slice_u8 a_workbuf,
9552       wuffs_base__decode_frame_options* a_opts) {
9553     return wuffs_jpeg__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
9554   }
9555 
9556   inline wuffs_base__rect_ie_u32
frame_dirty_rectwuffs_jpeg__decoder__struct9557   frame_dirty_rect() const {
9558     return wuffs_jpeg__decoder__frame_dirty_rect(this);
9559   }
9560 
9561   inline uint32_t
num_animation_loopswuffs_jpeg__decoder__struct9562   num_animation_loops() const {
9563     return wuffs_jpeg__decoder__num_animation_loops(this);
9564   }
9565 
9566   inline uint64_t
num_decoded_frame_configswuffs_jpeg__decoder__struct9567   num_decoded_frame_configs() const {
9568     return wuffs_jpeg__decoder__num_decoded_frame_configs(this);
9569   }
9570 
9571   inline uint64_t
num_decoded_frameswuffs_jpeg__decoder__struct9572   num_decoded_frames() const {
9573     return wuffs_jpeg__decoder__num_decoded_frames(this);
9574   }
9575 
9576   inline wuffs_base__status
restart_framewuffs_jpeg__decoder__struct9577   restart_frame(
9578       uint64_t a_index,
9579       uint64_t a_io_position) {
9580     return wuffs_jpeg__decoder__restart_frame(this, a_index, a_io_position);
9581   }
9582 
9583   inline wuffs_base__empty_struct
set_report_metadatawuffs_jpeg__decoder__struct9584   set_report_metadata(
9585       uint32_t a_fourcc,
9586       bool a_report) {
9587     return wuffs_jpeg__decoder__set_report_metadata(this, a_fourcc, a_report);
9588   }
9589 
9590   inline wuffs_base__status
tell_me_morewuffs_jpeg__decoder__struct9591   tell_me_more(
9592       wuffs_base__io_buffer* a_dst,
9593       wuffs_base__more_information* a_minfo,
9594       wuffs_base__io_buffer* a_src) {
9595     return wuffs_jpeg__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
9596   }
9597 
9598   inline uint64_t
history_retain_lengthwuffs_jpeg__decoder__struct9599   history_retain_length() const {
9600     return wuffs_jpeg__decoder__history_retain_length(this);
9601   }
9602 
9603   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_jpeg__decoder__struct9604   workbuf_len() const {
9605     return wuffs_jpeg__decoder__workbuf_len(this);
9606   }
9607 
9608 #endif  // __cplusplus
9609 };  // struct wuffs_jpeg__decoder__struct
9610 
9611 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
9612 
9613 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JPEG) || defined(WUFFS_NONMONOLITHIC)
9614 
9615 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JSON) || defined(WUFFS_NONMONOLITHIC)
9616 
9617 // ---------------- Status Codes
9618 
9619 extern const char wuffs_json__error__bad_c0_control_code[];
9620 extern const char wuffs_json__error__bad_utf_8[];
9621 extern const char wuffs_json__error__bad_backslash_escape[];
9622 extern const char wuffs_json__error__bad_input[];
9623 extern const char wuffs_json__error__bad_new_line_in_a_string[];
9624 extern const char wuffs_json__error__bad_quirk_combination[];
9625 extern const char wuffs_json__error__unsupported_number_length[];
9626 extern const char wuffs_json__error__unsupported_recursion_depth[];
9627 
9628 // ---------------- Public Consts
9629 
9630 #define WUFFS_JSON__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0
9631 
9632 #define WUFFS_JSON__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
9633 
9634 #define WUFFS_JSON__DECODER_DEPTH_MAX_INCL 1024
9635 
9636 #define WUFFS_JSON__DECODER_DST_TOKEN_BUFFER_LENGTH_MIN_INCL 1
9637 
9638 #define WUFFS_JSON__DECODER_SRC_IO_BUFFER_LENGTH_MIN_INCL 100
9639 
9640 #define WUFFS_JSON__QUIRK_ALLOW_ASCII_CONTROL_CODES 1225364480
9641 
9642 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_A 1225364481
9643 
9644 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_CAPITAL_U 1225364482
9645 
9646 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_E 1225364483
9647 
9648 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_NEW_LINE 1225364484
9649 
9650 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_QUESTION_MARK 1225364485
9651 
9652 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_SINGLE_QUOTE 1225364486
9653 
9654 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_V 1225364487
9655 
9656 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_X_AS_CODE_POINTS 1225364489
9657 
9658 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_ZERO 1225364490
9659 
9660 #define WUFFS_JSON__QUIRK_ALLOW_COMMENT_BLOCK 1225364491
9661 
9662 #define WUFFS_JSON__QUIRK_ALLOW_COMMENT_LINE 1225364492
9663 
9664 #define WUFFS_JSON__QUIRK_ALLOW_EXTRA_COMMA 1225364493
9665 
9666 #define WUFFS_JSON__QUIRK_ALLOW_INF_NAN_NUMBERS 1225364494
9667 
9668 #define WUFFS_JSON__QUIRK_ALLOW_LEADING_ASCII_RECORD_SEPARATOR 1225364495
9669 
9670 #define WUFFS_JSON__QUIRK_ALLOW_LEADING_UNICODE_BYTE_ORDER_MARK 1225364496
9671 
9672 #define WUFFS_JSON__QUIRK_ALLOW_TRAILING_FILLER 1225364497
9673 
9674 #define WUFFS_JSON__QUIRK_EXPECT_TRAILING_NEW_LINE_OR_EOF 1225364498
9675 
9676 #define WUFFS_JSON__QUIRK_JSON_POINTER_ALLOW_TILDE_N_TILDE_R_TILDE_T 1225364499
9677 
9678 #define WUFFS_JSON__QUIRK_REPLACE_INVALID_UNICODE 1225364500
9679 
9680 // ---------------- Struct Declarations
9681 
9682 typedef struct wuffs_json__decoder__struct wuffs_json__decoder;
9683 
9684 #ifdef __cplusplus
9685 extern "C" {
9686 #endif
9687 
9688 // ---------------- Public Initializer Prototypes
9689 
9690 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
9691 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
9692 //
9693 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
9694 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
9695 
9696 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
9697 wuffs_json__decoder__initialize(
9698     wuffs_json__decoder* self,
9699     size_t sizeof_star_self,
9700     uint64_t wuffs_version,
9701     uint32_t options);
9702 
9703 size_t
9704 sizeof__wuffs_json__decoder(void);
9705 
9706 // ---------------- Allocs
9707 
9708 // These functions allocate and initialize Wuffs structs. They return NULL if
9709 // memory allocation fails. If they return non-NULL, there is no need to call
9710 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
9711 // calling free on the returned pointer. That pointer is effectively a C++
9712 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
9713 
9714 wuffs_json__decoder*
9715 wuffs_json__decoder__alloc(void);
9716 
9717 static inline wuffs_base__token_decoder*
wuffs_json__decoder__alloc_as__wuffs_base__token_decoder(void)9718 wuffs_json__decoder__alloc_as__wuffs_base__token_decoder(void) {
9719   return (wuffs_base__token_decoder*)(wuffs_json__decoder__alloc());
9720 }
9721 
9722 // ---------------- Upcasts
9723 
9724 static inline wuffs_base__token_decoder*
wuffs_json__decoder__upcast_as__wuffs_base__token_decoder(wuffs_json__decoder * p)9725 wuffs_json__decoder__upcast_as__wuffs_base__token_decoder(
9726     wuffs_json__decoder* p) {
9727   return (wuffs_base__token_decoder*)p;
9728 }
9729 
9730 // ---------------- Public Function Prototypes
9731 
9732 WUFFS_BASE__GENERATED_C_CODE
9733 WUFFS_BASE__MAYBE_STATIC uint64_t
9734 wuffs_json__decoder__get_quirk(
9735     const wuffs_json__decoder* self,
9736     uint32_t a_key);
9737 
9738 WUFFS_BASE__GENERATED_C_CODE
9739 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9740 wuffs_json__decoder__set_quirk(
9741     wuffs_json__decoder* self,
9742     uint32_t a_key,
9743     uint64_t a_value);
9744 
9745 WUFFS_BASE__GENERATED_C_CODE
9746 WUFFS_BASE__MAYBE_STATIC uint64_t
9747 wuffs_json__decoder__history_retain_length(
9748     const wuffs_json__decoder* self);
9749 
9750 WUFFS_BASE__GENERATED_C_CODE
9751 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
9752 wuffs_json__decoder__workbuf_len(
9753     const wuffs_json__decoder* self);
9754 
9755 WUFFS_BASE__GENERATED_C_CODE
9756 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9757 wuffs_json__decoder__decode_tokens(
9758     wuffs_json__decoder* self,
9759     wuffs_base__token_buffer* a_dst,
9760     wuffs_base__io_buffer* a_src,
9761     wuffs_base__slice_u8 a_workbuf);
9762 
9763 #ifdef __cplusplus
9764 }  // extern "C"
9765 #endif
9766 
9767 // ---------------- Struct Definitions
9768 
9769 // These structs' fields, and the sizeof them, are private implementation
9770 // details that aren't guaranteed to be stable across Wuffs versions.
9771 //
9772 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
9773 
9774 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
9775 
9776 struct wuffs_json__decoder__struct {
9777   // Do not access the private_impl's or private_data's fields directly. There
9778   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
9779   // the wuffs_foo__bar__baz functions.
9780   //
9781   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
9782   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
9783 
9784   struct {
9785     uint32_t magic;
9786     uint32_t active_coroutine;
9787     wuffs_base__vtable vtable_for__wuffs_base__token_decoder;
9788     wuffs_base__vtable null_vtable;
9789 
9790     bool f_quirks[21];
9791     bool f_allow_leading_ars;
9792     bool f_allow_leading_ubom;
9793     bool f_end_of_data;
9794     uint8_t f_trailer_stop;
9795     uint8_t f_comment_type;
9796 
9797     uint32_t p_decode_tokens[1];
9798     uint32_t p_decode_leading[1];
9799     uint32_t p_decode_comment[1];
9800     uint32_t p_decode_inf_nan[1];
9801     uint32_t p_decode_trailer[1];
9802   } private_impl;
9803 
9804   struct {
9805     uint32_t f_stack[32];
9806 
9807     struct {
9808       uint32_t v_depth;
9809       uint32_t v_expect;
9810       uint32_t v_expect_after_value;
9811     } s_decode_tokens[1];
9812   } private_data;
9813 
9814 #ifdef __cplusplus
9815 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
9816   using unique_ptr = std::unique_ptr<wuffs_json__decoder, wuffs_unique_ptr_deleter>;
9817 
9818   // On failure, the alloc_etc functions return nullptr. They don't throw.
9819 
9820   static inline unique_ptr
allocwuffs_json__decoder__struct9821   alloc() {
9822     return unique_ptr(wuffs_json__decoder__alloc());
9823   }
9824 
9825   static inline wuffs_base__token_decoder::unique_ptr
alloc_as__wuffs_base__token_decoderwuffs_json__decoder__struct9826   alloc_as__wuffs_base__token_decoder() {
9827     return wuffs_base__token_decoder::unique_ptr(
9828         wuffs_json__decoder__alloc_as__wuffs_base__token_decoder());
9829   }
9830 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
9831 
9832 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
9833   // Disallow constructing or copying an object via standard C++ mechanisms,
9834   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
9835   // size and field layout is not part of the public, stable, memory-safe API.
9836   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
9837   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
9838   // their first argument) rather than tweaking bar.private_impl.qux fields.
9839   //
9840   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
9841   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
9842   // order to provide convenience methods. These forward on "this", so that you
9843   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
9844   wuffs_json__decoder__struct() = delete;
9845   wuffs_json__decoder__struct(const wuffs_json__decoder__struct&) = delete;
9846   wuffs_json__decoder__struct& operator=(
9847       const wuffs_json__decoder__struct&) = delete;
9848 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
9849 
9850 #if !defined(WUFFS_IMPLEMENTATION)
9851   // As above, the size of the struct is not part of the public API, and unless
9852   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
9853   // allocated, not stack allocated. Its size is not intended to be known at
9854   // compile time, but it is unfortunately divulged as a side effect of
9855   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
9856   // instead of "sizeof T", invoking the operator. To make the two values
9857   // different, so that passing the latter will be rejected by the initialize
9858   // function, we add an arbitrary amount of dead weight.
9859   uint8_t dead_weight[123000000];  // 123 MB.
9860 #endif  // !defined(WUFFS_IMPLEMENTATION)
9861 
9862   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_json__decoder__struct9863   initialize(
9864       size_t sizeof_star_self,
9865       uint64_t wuffs_version,
9866       uint32_t options) {
9867     return wuffs_json__decoder__initialize(
9868         this, sizeof_star_self, wuffs_version, options);
9869   }
9870 
9871   inline wuffs_base__token_decoder*
upcast_as__wuffs_base__token_decoderwuffs_json__decoder__struct9872   upcast_as__wuffs_base__token_decoder() {
9873     return (wuffs_base__token_decoder*)this;
9874   }
9875 
9876   inline uint64_t
get_quirkwuffs_json__decoder__struct9877   get_quirk(
9878       uint32_t a_key) const {
9879     return wuffs_json__decoder__get_quirk(this, a_key);
9880   }
9881 
9882   inline wuffs_base__status
set_quirkwuffs_json__decoder__struct9883   set_quirk(
9884       uint32_t a_key,
9885       uint64_t a_value) {
9886     return wuffs_json__decoder__set_quirk(this, a_key, a_value);
9887   }
9888 
9889   inline uint64_t
history_retain_lengthwuffs_json__decoder__struct9890   history_retain_length() const {
9891     return wuffs_json__decoder__history_retain_length(this);
9892   }
9893 
9894   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_json__decoder__struct9895   workbuf_len() const {
9896     return wuffs_json__decoder__workbuf_len(this);
9897   }
9898 
9899   inline wuffs_base__status
decode_tokenswuffs_json__decoder__struct9900   decode_tokens(
9901       wuffs_base__token_buffer* a_dst,
9902       wuffs_base__io_buffer* a_src,
9903       wuffs_base__slice_u8 a_workbuf) {
9904     return wuffs_json__decoder__decode_tokens(this, a_dst, a_src, a_workbuf);
9905   }
9906 
9907 #endif  // __cplusplus
9908 };  // struct wuffs_json__decoder__struct
9909 
9910 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
9911 
9912 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JSON) || defined(WUFFS_NONMONOLITHIC)
9913 
9914 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZW) || defined(WUFFS_NONMONOLITHIC)
9915 
9916 // ---------------- Status Codes
9917 
9918 extern const char wuffs_lzw__error__bad_code[];
9919 extern const char wuffs_lzw__error__truncated_input[];
9920 
9921 // ---------------- Public Consts
9922 
9923 #define WUFFS_LZW__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0
9924 
9925 #define WUFFS_LZW__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
9926 
9927 #define WUFFS_LZW__QUIRK_LITERAL_WIDTH_PLUS_ONE 1348378624
9928 
9929 // ---------------- Struct Declarations
9930 
9931 typedef struct wuffs_lzw__decoder__struct wuffs_lzw__decoder;
9932 
9933 #ifdef __cplusplus
9934 extern "C" {
9935 #endif
9936 
9937 // ---------------- Public Initializer Prototypes
9938 
9939 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
9940 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
9941 //
9942 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
9943 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
9944 
9945 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
9946 wuffs_lzw__decoder__initialize(
9947     wuffs_lzw__decoder* self,
9948     size_t sizeof_star_self,
9949     uint64_t wuffs_version,
9950     uint32_t options);
9951 
9952 size_t
9953 sizeof__wuffs_lzw__decoder(void);
9954 
9955 // ---------------- Allocs
9956 
9957 // These functions allocate and initialize Wuffs structs. They return NULL if
9958 // memory allocation fails. If they return non-NULL, there is no need to call
9959 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
9960 // calling free on the returned pointer. That pointer is effectively a C++
9961 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
9962 
9963 wuffs_lzw__decoder*
9964 wuffs_lzw__decoder__alloc(void);
9965 
9966 static inline wuffs_base__io_transformer*
wuffs_lzw__decoder__alloc_as__wuffs_base__io_transformer(void)9967 wuffs_lzw__decoder__alloc_as__wuffs_base__io_transformer(void) {
9968   return (wuffs_base__io_transformer*)(wuffs_lzw__decoder__alloc());
9969 }
9970 
9971 // ---------------- Upcasts
9972 
9973 static inline wuffs_base__io_transformer*
wuffs_lzw__decoder__upcast_as__wuffs_base__io_transformer(wuffs_lzw__decoder * p)9974 wuffs_lzw__decoder__upcast_as__wuffs_base__io_transformer(
9975     wuffs_lzw__decoder* p) {
9976   return (wuffs_base__io_transformer*)p;
9977 }
9978 
9979 // ---------------- Public Function Prototypes
9980 
9981 WUFFS_BASE__GENERATED_C_CODE
9982 WUFFS_BASE__MAYBE_STATIC uint64_t
9983 wuffs_lzw__decoder__get_quirk(
9984     const wuffs_lzw__decoder* self,
9985     uint32_t a_key);
9986 
9987 WUFFS_BASE__GENERATED_C_CODE
9988 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9989 wuffs_lzw__decoder__set_quirk(
9990     wuffs_lzw__decoder* self,
9991     uint32_t a_key,
9992     uint64_t a_value);
9993 
9994 WUFFS_BASE__GENERATED_C_CODE
9995 WUFFS_BASE__MAYBE_STATIC uint64_t
9996 wuffs_lzw__decoder__history_retain_length(
9997     const wuffs_lzw__decoder* self);
9998 
9999 WUFFS_BASE__GENERATED_C_CODE
10000 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
10001 wuffs_lzw__decoder__workbuf_len(
10002     const wuffs_lzw__decoder* self);
10003 
10004 WUFFS_BASE__GENERATED_C_CODE
10005 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
10006 wuffs_lzw__decoder__transform_io(
10007     wuffs_lzw__decoder* self,
10008     wuffs_base__io_buffer* a_dst,
10009     wuffs_base__io_buffer* a_src,
10010     wuffs_base__slice_u8 a_workbuf);
10011 
10012 WUFFS_BASE__GENERATED_C_CODE
10013 WUFFS_BASE__MAYBE_STATIC wuffs_base__slice_u8
10014 wuffs_lzw__decoder__flush(
10015     wuffs_lzw__decoder* self);
10016 
10017 #ifdef __cplusplus
10018 }  // extern "C"
10019 #endif
10020 
10021 // ---------------- Struct Definitions
10022 
10023 // These structs' fields, and the sizeof them, are private implementation
10024 // details that aren't guaranteed to be stable across Wuffs versions.
10025 //
10026 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
10027 
10028 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
10029 
10030 struct wuffs_lzw__decoder__struct {
10031   // Do not access the private_impl's or private_data's fields directly. There
10032   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
10033   // the wuffs_foo__bar__baz functions.
10034   //
10035   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
10036   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
10037 
10038   struct {
10039     uint32_t magic;
10040     uint32_t active_coroutine;
10041     wuffs_base__vtable vtable_for__wuffs_base__io_transformer;
10042     wuffs_base__vtable null_vtable;
10043 
10044     uint32_t f_pending_literal_width_plus_one;
10045     uint32_t f_literal_width;
10046     uint32_t f_clear_code;
10047     uint32_t f_end_code;
10048     uint32_t f_save_code;
10049     uint32_t f_prev_code;
10050     uint32_t f_width;
10051     uint32_t f_bits;
10052     uint32_t f_n_bits;
10053     uint32_t f_output_ri;
10054     uint32_t f_output_wi;
10055     uint32_t f_read_from_return_value;
10056     uint16_t f_prefixes[4096];
10057 
10058     uint32_t p_transform_io[1];
10059     uint32_t p_write_to[1];
10060   } private_impl;
10061 
10062   struct {
10063     uint8_t f_suffixes[4096][8];
10064     uint16_t f_lm1s[4096];
10065     uint8_t f_output[8199];
10066   } private_data;
10067 
10068 #ifdef __cplusplus
10069 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
10070   using unique_ptr = std::unique_ptr<wuffs_lzw__decoder, wuffs_unique_ptr_deleter>;
10071 
10072   // On failure, the alloc_etc functions return nullptr. They don't throw.
10073 
10074   static inline unique_ptr
allocwuffs_lzw__decoder__struct10075   alloc() {
10076     return unique_ptr(wuffs_lzw__decoder__alloc());
10077   }
10078 
10079   static inline wuffs_base__io_transformer::unique_ptr
alloc_as__wuffs_base__io_transformerwuffs_lzw__decoder__struct10080   alloc_as__wuffs_base__io_transformer() {
10081     return wuffs_base__io_transformer::unique_ptr(
10082         wuffs_lzw__decoder__alloc_as__wuffs_base__io_transformer());
10083   }
10084 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
10085 
10086 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
10087   // Disallow constructing or copying an object via standard C++ mechanisms,
10088   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
10089   // size and field layout is not part of the public, stable, memory-safe API.
10090   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
10091   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
10092   // their first argument) rather than tweaking bar.private_impl.qux fields.
10093   //
10094   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
10095   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
10096   // order to provide convenience methods. These forward on "this", so that you
10097   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
10098   wuffs_lzw__decoder__struct() = delete;
10099   wuffs_lzw__decoder__struct(const wuffs_lzw__decoder__struct&) = delete;
10100   wuffs_lzw__decoder__struct& operator=(
10101       const wuffs_lzw__decoder__struct&) = delete;
10102 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
10103 
10104 #if !defined(WUFFS_IMPLEMENTATION)
10105   // As above, the size of the struct is not part of the public API, and unless
10106   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
10107   // allocated, not stack allocated. Its size is not intended to be known at
10108   // compile time, but it is unfortunately divulged as a side effect of
10109   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
10110   // instead of "sizeof T", invoking the operator. To make the two values
10111   // different, so that passing the latter will be rejected by the initialize
10112   // function, we add an arbitrary amount of dead weight.
10113   uint8_t dead_weight[123000000];  // 123 MB.
10114 #endif  // !defined(WUFFS_IMPLEMENTATION)
10115 
10116   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_lzw__decoder__struct10117   initialize(
10118       size_t sizeof_star_self,
10119       uint64_t wuffs_version,
10120       uint32_t options) {
10121     return wuffs_lzw__decoder__initialize(
10122         this, sizeof_star_self, wuffs_version, options);
10123   }
10124 
10125   inline wuffs_base__io_transformer*
upcast_as__wuffs_base__io_transformerwuffs_lzw__decoder__struct10126   upcast_as__wuffs_base__io_transformer() {
10127     return (wuffs_base__io_transformer*)this;
10128   }
10129 
10130   inline uint64_t
get_quirkwuffs_lzw__decoder__struct10131   get_quirk(
10132       uint32_t a_key) const {
10133     return wuffs_lzw__decoder__get_quirk(this, a_key);
10134   }
10135 
10136   inline wuffs_base__status
set_quirkwuffs_lzw__decoder__struct10137   set_quirk(
10138       uint32_t a_key,
10139       uint64_t a_value) {
10140     return wuffs_lzw__decoder__set_quirk(this, a_key, a_value);
10141   }
10142 
10143   inline uint64_t
history_retain_lengthwuffs_lzw__decoder__struct10144   history_retain_length() const {
10145     return wuffs_lzw__decoder__history_retain_length(this);
10146   }
10147 
10148   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_lzw__decoder__struct10149   workbuf_len() const {
10150     return wuffs_lzw__decoder__workbuf_len(this);
10151   }
10152 
10153   inline wuffs_base__status
transform_iowuffs_lzw__decoder__struct10154   transform_io(
10155       wuffs_base__io_buffer* a_dst,
10156       wuffs_base__io_buffer* a_src,
10157       wuffs_base__slice_u8 a_workbuf) {
10158     return wuffs_lzw__decoder__transform_io(this, a_dst, a_src, a_workbuf);
10159   }
10160 
10161   inline wuffs_base__slice_u8
flushwuffs_lzw__decoder__struct10162   flush() {
10163     return wuffs_lzw__decoder__flush(this);
10164   }
10165 
10166 #endif  // __cplusplus
10167 };  // struct wuffs_lzw__decoder__struct
10168 
10169 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
10170 
10171 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZW) || defined(WUFFS_NONMONOLITHIC)
10172 
10173 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NETPBM) || defined(WUFFS_NONMONOLITHIC)
10174 
10175 // ---------------- Status Codes
10176 
10177 extern const char wuffs_netpbm__error__bad_header[];
10178 extern const char wuffs_netpbm__error__truncated_input[];
10179 extern const char wuffs_netpbm__error__unsupported_netpbm_file[];
10180 
10181 // ---------------- Public Consts
10182 
10183 #define WUFFS_NETPBM__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0
10184 
10185 #define WUFFS_NETPBM__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
10186 
10187 // ---------------- Struct Declarations
10188 
10189 typedef struct wuffs_netpbm__decoder__struct wuffs_netpbm__decoder;
10190 
10191 #ifdef __cplusplus
10192 extern "C" {
10193 #endif
10194 
10195 // ---------------- Public Initializer Prototypes
10196 
10197 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
10198 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
10199 //
10200 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
10201 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
10202 
10203 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
10204 wuffs_netpbm__decoder__initialize(
10205     wuffs_netpbm__decoder* self,
10206     size_t sizeof_star_self,
10207     uint64_t wuffs_version,
10208     uint32_t options);
10209 
10210 size_t
10211 sizeof__wuffs_netpbm__decoder(void);
10212 
10213 // ---------------- Allocs
10214 
10215 // These functions allocate and initialize Wuffs structs. They return NULL if
10216 // memory allocation fails. If they return non-NULL, there is no need to call
10217 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
10218 // calling free on the returned pointer. That pointer is effectively a C++
10219 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
10220 
10221 wuffs_netpbm__decoder*
10222 wuffs_netpbm__decoder__alloc(void);
10223 
10224 static inline wuffs_base__image_decoder*
wuffs_netpbm__decoder__alloc_as__wuffs_base__image_decoder(void)10225 wuffs_netpbm__decoder__alloc_as__wuffs_base__image_decoder(void) {
10226   return (wuffs_base__image_decoder*)(wuffs_netpbm__decoder__alloc());
10227 }
10228 
10229 // ---------------- Upcasts
10230 
10231 static inline wuffs_base__image_decoder*
wuffs_netpbm__decoder__upcast_as__wuffs_base__image_decoder(wuffs_netpbm__decoder * p)10232 wuffs_netpbm__decoder__upcast_as__wuffs_base__image_decoder(
10233     wuffs_netpbm__decoder* p) {
10234   return (wuffs_base__image_decoder*)p;
10235 }
10236 
10237 // ---------------- Public Function Prototypes
10238 
10239 WUFFS_BASE__GENERATED_C_CODE
10240 WUFFS_BASE__MAYBE_STATIC uint64_t
10241 wuffs_netpbm__decoder__get_quirk(
10242     const wuffs_netpbm__decoder* self,
10243     uint32_t a_key);
10244 
10245 WUFFS_BASE__GENERATED_C_CODE
10246 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
10247 wuffs_netpbm__decoder__set_quirk(
10248     wuffs_netpbm__decoder* self,
10249     uint32_t a_key,
10250     uint64_t a_value);
10251 
10252 WUFFS_BASE__GENERATED_C_CODE
10253 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
10254 wuffs_netpbm__decoder__decode_image_config(
10255     wuffs_netpbm__decoder* self,
10256     wuffs_base__image_config* a_dst,
10257     wuffs_base__io_buffer* a_src);
10258 
10259 WUFFS_BASE__GENERATED_C_CODE
10260 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
10261 wuffs_netpbm__decoder__decode_frame_config(
10262     wuffs_netpbm__decoder* self,
10263     wuffs_base__frame_config* a_dst,
10264     wuffs_base__io_buffer* a_src);
10265 
10266 WUFFS_BASE__GENERATED_C_CODE
10267 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
10268 wuffs_netpbm__decoder__decode_frame(
10269     wuffs_netpbm__decoder* self,
10270     wuffs_base__pixel_buffer* a_dst,
10271     wuffs_base__io_buffer* a_src,
10272     wuffs_base__pixel_blend a_blend,
10273     wuffs_base__slice_u8 a_workbuf,
10274     wuffs_base__decode_frame_options* a_opts);
10275 
10276 WUFFS_BASE__GENERATED_C_CODE
10277 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
10278 wuffs_netpbm__decoder__frame_dirty_rect(
10279     const wuffs_netpbm__decoder* self);
10280 
10281 WUFFS_BASE__GENERATED_C_CODE
10282 WUFFS_BASE__MAYBE_STATIC uint32_t
10283 wuffs_netpbm__decoder__num_animation_loops(
10284     const wuffs_netpbm__decoder* self);
10285 
10286 WUFFS_BASE__GENERATED_C_CODE
10287 WUFFS_BASE__MAYBE_STATIC uint64_t
10288 wuffs_netpbm__decoder__num_decoded_frame_configs(
10289     const wuffs_netpbm__decoder* self);
10290 
10291 WUFFS_BASE__GENERATED_C_CODE
10292 WUFFS_BASE__MAYBE_STATIC uint64_t
10293 wuffs_netpbm__decoder__num_decoded_frames(
10294     const wuffs_netpbm__decoder* self);
10295 
10296 WUFFS_BASE__GENERATED_C_CODE
10297 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
10298 wuffs_netpbm__decoder__restart_frame(
10299     wuffs_netpbm__decoder* self,
10300     uint64_t a_index,
10301     uint64_t a_io_position);
10302 
10303 WUFFS_BASE__GENERATED_C_CODE
10304 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
10305 wuffs_netpbm__decoder__set_report_metadata(
10306     wuffs_netpbm__decoder* self,
10307     uint32_t a_fourcc,
10308     bool a_report);
10309 
10310 WUFFS_BASE__GENERATED_C_CODE
10311 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
10312 wuffs_netpbm__decoder__tell_me_more(
10313     wuffs_netpbm__decoder* self,
10314     wuffs_base__io_buffer* a_dst,
10315     wuffs_base__more_information* a_minfo,
10316     wuffs_base__io_buffer* a_src);
10317 
10318 WUFFS_BASE__GENERATED_C_CODE
10319 WUFFS_BASE__MAYBE_STATIC uint64_t
10320 wuffs_netpbm__decoder__history_retain_length(
10321     const wuffs_netpbm__decoder* self);
10322 
10323 WUFFS_BASE__GENERATED_C_CODE
10324 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
10325 wuffs_netpbm__decoder__workbuf_len(
10326     const wuffs_netpbm__decoder* self);
10327 
10328 #ifdef __cplusplus
10329 }  // extern "C"
10330 #endif
10331 
10332 // ---------------- Struct Definitions
10333 
10334 // These structs' fields, and the sizeof them, are private implementation
10335 // details that aren't guaranteed to be stable across Wuffs versions.
10336 //
10337 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
10338 
10339 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
10340 
10341 struct wuffs_netpbm__decoder__struct {
10342   // Do not access the private_impl's or private_data's fields directly. There
10343   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
10344   // the wuffs_foo__bar__baz functions.
10345   //
10346   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
10347   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
10348 
10349   struct {
10350     uint32_t magic;
10351     uint32_t active_coroutine;
10352     wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
10353     wuffs_base__vtable null_vtable;
10354 
10355     uint32_t f_pixfmt;
10356     uint32_t f_width;
10357     uint32_t f_height;
10358     uint32_t f_max_value;
10359     uint8_t f_call_sequence;
10360     uint64_t f_frame_config_io_position;
10361     uint32_t f_dst_x;
10362     uint32_t f_dst_y;
10363     wuffs_base__pixel_swizzler f_swizzler;
10364 
10365     uint32_t p_decode_image_config[1];
10366     uint32_t p_do_decode_image_config[1];
10367     uint32_t p_decode_frame_config[1];
10368     uint32_t p_do_decode_frame_config[1];
10369     uint32_t p_decode_frame[1];
10370     uint32_t p_do_decode_frame[1];
10371   } private_impl;
10372 
10373 #ifdef __cplusplus
10374 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
10375   using unique_ptr = std::unique_ptr<wuffs_netpbm__decoder, wuffs_unique_ptr_deleter>;
10376 
10377   // On failure, the alloc_etc functions return nullptr. They don't throw.
10378 
10379   static inline unique_ptr
allocwuffs_netpbm__decoder__struct10380   alloc() {
10381     return unique_ptr(wuffs_netpbm__decoder__alloc());
10382   }
10383 
10384   static inline wuffs_base__image_decoder::unique_ptr
alloc_as__wuffs_base__image_decoderwuffs_netpbm__decoder__struct10385   alloc_as__wuffs_base__image_decoder() {
10386     return wuffs_base__image_decoder::unique_ptr(
10387         wuffs_netpbm__decoder__alloc_as__wuffs_base__image_decoder());
10388   }
10389 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
10390 
10391 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
10392   // Disallow constructing or copying an object via standard C++ mechanisms,
10393   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
10394   // size and field layout is not part of the public, stable, memory-safe API.
10395   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
10396   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
10397   // their first argument) rather than tweaking bar.private_impl.qux fields.
10398   //
10399   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
10400   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
10401   // order to provide convenience methods. These forward on "this", so that you
10402   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
10403   wuffs_netpbm__decoder__struct() = delete;
10404   wuffs_netpbm__decoder__struct(const wuffs_netpbm__decoder__struct&) = delete;
10405   wuffs_netpbm__decoder__struct& operator=(
10406       const wuffs_netpbm__decoder__struct&) = delete;
10407 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
10408 
10409 #if !defined(WUFFS_IMPLEMENTATION)
10410   // As above, the size of the struct is not part of the public API, and unless
10411   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
10412   // allocated, not stack allocated. Its size is not intended to be known at
10413   // compile time, but it is unfortunately divulged as a side effect of
10414   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
10415   // instead of "sizeof T", invoking the operator. To make the two values
10416   // different, so that passing the latter will be rejected by the initialize
10417   // function, we add an arbitrary amount of dead weight.
10418   uint8_t dead_weight[123000000];  // 123 MB.
10419 #endif  // !defined(WUFFS_IMPLEMENTATION)
10420 
10421   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_netpbm__decoder__struct10422   initialize(
10423       size_t sizeof_star_self,
10424       uint64_t wuffs_version,
10425       uint32_t options) {
10426     return wuffs_netpbm__decoder__initialize(
10427         this, sizeof_star_self, wuffs_version, options);
10428   }
10429 
10430   inline wuffs_base__image_decoder*
upcast_as__wuffs_base__image_decoderwuffs_netpbm__decoder__struct10431   upcast_as__wuffs_base__image_decoder() {
10432     return (wuffs_base__image_decoder*)this;
10433   }
10434 
10435   inline uint64_t
get_quirkwuffs_netpbm__decoder__struct10436   get_quirk(
10437       uint32_t a_key) const {
10438     return wuffs_netpbm__decoder__get_quirk(this, a_key);
10439   }
10440 
10441   inline wuffs_base__status
set_quirkwuffs_netpbm__decoder__struct10442   set_quirk(
10443       uint32_t a_key,
10444       uint64_t a_value) {
10445     return wuffs_netpbm__decoder__set_quirk(this, a_key, a_value);
10446   }
10447 
10448   inline wuffs_base__status
decode_image_configwuffs_netpbm__decoder__struct10449   decode_image_config(
10450       wuffs_base__image_config* a_dst,
10451       wuffs_base__io_buffer* a_src) {
10452     return wuffs_netpbm__decoder__decode_image_config(this, a_dst, a_src);
10453   }
10454 
10455   inline wuffs_base__status
decode_frame_configwuffs_netpbm__decoder__struct10456   decode_frame_config(
10457       wuffs_base__frame_config* a_dst,
10458       wuffs_base__io_buffer* a_src) {
10459     return wuffs_netpbm__decoder__decode_frame_config(this, a_dst, a_src);
10460   }
10461 
10462   inline wuffs_base__status
decode_framewuffs_netpbm__decoder__struct10463   decode_frame(
10464       wuffs_base__pixel_buffer* a_dst,
10465       wuffs_base__io_buffer* a_src,
10466       wuffs_base__pixel_blend a_blend,
10467       wuffs_base__slice_u8 a_workbuf,
10468       wuffs_base__decode_frame_options* a_opts) {
10469     return wuffs_netpbm__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
10470   }
10471 
10472   inline wuffs_base__rect_ie_u32
frame_dirty_rectwuffs_netpbm__decoder__struct10473   frame_dirty_rect() const {
10474     return wuffs_netpbm__decoder__frame_dirty_rect(this);
10475   }
10476 
10477   inline uint32_t
num_animation_loopswuffs_netpbm__decoder__struct10478   num_animation_loops() const {
10479     return wuffs_netpbm__decoder__num_animation_loops(this);
10480   }
10481 
10482   inline uint64_t
num_decoded_frame_configswuffs_netpbm__decoder__struct10483   num_decoded_frame_configs() const {
10484     return wuffs_netpbm__decoder__num_decoded_frame_configs(this);
10485   }
10486 
10487   inline uint64_t
num_decoded_frameswuffs_netpbm__decoder__struct10488   num_decoded_frames() const {
10489     return wuffs_netpbm__decoder__num_decoded_frames(this);
10490   }
10491 
10492   inline wuffs_base__status
restart_framewuffs_netpbm__decoder__struct10493   restart_frame(
10494       uint64_t a_index,
10495       uint64_t a_io_position) {
10496     return wuffs_netpbm__decoder__restart_frame(this, a_index, a_io_position);
10497   }
10498 
10499   inline wuffs_base__empty_struct
set_report_metadatawuffs_netpbm__decoder__struct10500   set_report_metadata(
10501       uint32_t a_fourcc,
10502       bool a_report) {
10503     return wuffs_netpbm__decoder__set_report_metadata(this, a_fourcc, a_report);
10504   }
10505 
10506   inline wuffs_base__status
tell_me_morewuffs_netpbm__decoder__struct10507   tell_me_more(
10508       wuffs_base__io_buffer* a_dst,
10509       wuffs_base__more_information* a_minfo,
10510       wuffs_base__io_buffer* a_src) {
10511     return wuffs_netpbm__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
10512   }
10513 
10514   inline uint64_t
history_retain_lengthwuffs_netpbm__decoder__struct10515   history_retain_length() const {
10516     return wuffs_netpbm__decoder__history_retain_length(this);
10517   }
10518 
10519   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_netpbm__decoder__struct10520   workbuf_len() const {
10521     return wuffs_netpbm__decoder__workbuf_len(this);
10522   }
10523 
10524 #endif  // __cplusplus
10525 };  // struct wuffs_netpbm__decoder__struct
10526 
10527 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
10528 
10529 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NETPBM) || defined(WUFFS_NONMONOLITHIC)
10530 
10531 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NIE) || defined(WUFFS_NONMONOLITHIC)
10532 
10533 // ---------------- Status Codes
10534 
10535 extern const char wuffs_nie__error__bad_header[];
10536 extern const char wuffs_nie__error__truncated_input[];
10537 extern const char wuffs_nie__error__unsupported_nie_file[];
10538 
10539 // ---------------- Public Consts
10540 
10541 #define WUFFS_NIE__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0
10542 
10543 #define WUFFS_NIE__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
10544 
10545 // ---------------- Struct Declarations
10546 
10547 typedef struct wuffs_nie__decoder__struct wuffs_nie__decoder;
10548 
10549 #ifdef __cplusplus
10550 extern "C" {
10551 #endif
10552 
10553 // ---------------- Public Initializer Prototypes
10554 
10555 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
10556 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
10557 //
10558 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
10559 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
10560 
10561 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
10562 wuffs_nie__decoder__initialize(
10563     wuffs_nie__decoder* self,
10564     size_t sizeof_star_self,
10565     uint64_t wuffs_version,
10566     uint32_t options);
10567 
10568 size_t
10569 sizeof__wuffs_nie__decoder(void);
10570 
10571 // ---------------- Allocs
10572 
10573 // These functions allocate and initialize Wuffs structs. They return NULL if
10574 // memory allocation fails. If they return non-NULL, there is no need to call
10575 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
10576 // calling free on the returned pointer. That pointer is effectively a C++
10577 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
10578 
10579 wuffs_nie__decoder*
10580 wuffs_nie__decoder__alloc(void);
10581 
10582 static inline wuffs_base__image_decoder*
wuffs_nie__decoder__alloc_as__wuffs_base__image_decoder(void)10583 wuffs_nie__decoder__alloc_as__wuffs_base__image_decoder(void) {
10584   return (wuffs_base__image_decoder*)(wuffs_nie__decoder__alloc());
10585 }
10586 
10587 // ---------------- Upcasts
10588 
10589 static inline wuffs_base__image_decoder*
wuffs_nie__decoder__upcast_as__wuffs_base__image_decoder(wuffs_nie__decoder * p)10590 wuffs_nie__decoder__upcast_as__wuffs_base__image_decoder(
10591     wuffs_nie__decoder* p) {
10592   return (wuffs_base__image_decoder*)p;
10593 }
10594 
10595 // ---------------- Public Function Prototypes
10596 
10597 WUFFS_BASE__GENERATED_C_CODE
10598 WUFFS_BASE__MAYBE_STATIC uint64_t
10599 wuffs_nie__decoder__get_quirk(
10600     const wuffs_nie__decoder* self,
10601     uint32_t a_key);
10602 
10603 WUFFS_BASE__GENERATED_C_CODE
10604 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
10605 wuffs_nie__decoder__set_quirk(
10606     wuffs_nie__decoder* self,
10607     uint32_t a_key,
10608     uint64_t a_value);
10609 
10610 WUFFS_BASE__GENERATED_C_CODE
10611 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
10612 wuffs_nie__decoder__decode_image_config(
10613     wuffs_nie__decoder* self,
10614     wuffs_base__image_config* a_dst,
10615     wuffs_base__io_buffer* a_src);
10616 
10617 WUFFS_BASE__GENERATED_C_CODE
10618 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
10619 wuffs_nie__decoder__decode_frame_config(
10620     wuffs_nie__decoder* self,
10621     wuffs_base__frame_config* a_dst,
10622     wuffs_base__io_buffer* a_src);
10623 
10624 WUFFS_BASE__GENERATED_C_CODE
10625 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
10626 wuffs_nie__decoder__decode_frame(
10627     wuffs_nie__decoder* self,
10628     wuffs_base__pixel_buffer* a_dst,
10629     wuffs_base__io_buffer* a_src,
10630     wuffs_base__pixel_blend a_blend,
10631     wuffs_base__slice_u8 a_workbuf,
10632     wuffs_base__decode_frame_options* a_opts);
10633 
10634 WUFFS_BASE__GENERATED_C_CODE
10635 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
10636 wuffs_nie__decoder__frame_dirty_rect(
10637     const wuffs_nie__decoder* self);
10638 
10639 WUFFS_BASE__GENERATED_C_CODE
10640 WUFFS_BASE__MAYBE_STATIC uint32_t
10641 wuffs_nie__decoder__num_animation_loops(
10642     const wuffs_nie__decoder* self);
10643 
10644 WUFFS_BASE__GENERATED_C_CODE
10645 WUFFS_BASE__MAYBE_STATIC uint64_t
10646 wuffs_nie__decoder__num_decoded_frame_configs(
10647     const wuffs_nie__decoder* self);
10648 
10649 WUFFS_BASE__GENERATED_C_CODE
10650 WUFFS_BASE__MAYBE_STATIC uint64_t
10651 wuffs_nie__decoder__num_decoded_frames(
10652     const wuffs_nie__decoder* self);
10653 
10654 WUFFS_BASE__GENERATED_C_CODE
10655 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
10656 wuffs_nie__decoder__restart_frame(
10657     wuffs_nie__decoder* self,
10658     uint64_t a_index,
10659     uint64_t a_io_position);
10660 
10661 WUFFS_BASE__GENERATED_C_CODE
10662 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
10663 wuffs_nie__decoder__set_report_metadata(
10664     wuffs_nie__decoder* self,
10665     uint32_t a_fourcc,
10666     bool a_report);
10667 
10668 WUFFS_BASE__GENERATED_C_CODE
10669 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
10670 wuffs_nie__decoder__tell_me_more(
10671     wuffs_nie__decoder* self,
10672     wuffs_base__io_buffer* a_dst,
10673     wuffs_base__more_information* a_minfo,
10674     wuffs_base__io_buffer* a_src);
10675 
10676 WUFFS_BASE__GENERATED_C_CODE
10677 WUFFS_BASE__MAYBE_STATIC uint64_t
10678 wuffs_nie__decoder__history_retain_length(
10679     const wuffs_nie__decoder* self);
10680 
10681 WUFFS_BASE__GENERATED_C_CODE
10682 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
10683 wuffs_nie__decoder__workbuf_len(
10684     const wuffs_nie__decoder* self);
10685 
10686 #ifdef __cplusplus
10687 }  // extern "C"
10688 #endif
10689 
10690 // ---------------- Struct Definitions
10691 
10692 // These structs' fields, and the sizeof them, are private implementation
10693 // details that aren't guaranteed to be stable across Wuffs versions.
10694 //
10695 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
10696 
10697 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
10698 
10699 struct wuffs_nie__decoder__struct {
10700   // Do not access the private_impl's or private_data's fields directly. There
10701   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
10702   // the wuffs_foo__bar__baz functions.
10703   //
10704   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
10705   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
10706 
10707   struct {
10708     uint32_t magic;
10709     uint32_t active_coroutine;
10710     wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
10711     wuffs_base__vtable null_vtable;
10712 
10713     uint32_t f_pixfmt;
10714     uint32_t f_width;
10715     uint32_t f_height;
10716     uint8_t f_call_sequence;
10717     uint32_t f_dst_x;
10718     uint32_t f_dst_y;
10719     wuffs_base__pixel_swizzler f_swizzler;
10720 
10721     uint32_t p_decode_image_config[1];
10722     uint32_t p_do_decode_image_config[1];
10723     uint32_t p_decode_frame_config[1];
10724     uint32_t p_do_decode_frame_config[1];
10725     uint32_t p_decode_frame[1];
10726     uint32_t p_do_decode_frame[1];
10727   } private_impl;
10728 
10729   struct {
10730     struct {
10731       uint64_t scratch;
10732     } s_do_decode_image_config[1];
10733   } private_data;
10734 
10735 #ifdef __cplusplus
10736 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
10737   using unique_ptr = std::unique_ptr<wuffs_nie__decoder, wuffs_unique_ptr_deleter>;
10738 
10739   // On failure, the alloc_etc functions return nullptr. They don't throw.
10740 
10741   static inline unique_ptr
allocwuffs_nie__decoder__struct10742   alloc() {
10743     return unique_ptr(wuffs_nie__decoder__alloc());
10744   }
10745 
10746   static inline wuffs_base__image_decoder::unique_ptr
alloc_as__wuffs_base__image_decoderwuffs_nie__decoder__struct10747   alloc_as__wuffs_base__image_decoder() {
10748     return wuffs_base__image_decoder::unique_ptr(
10749         wuffs_nie__decoder__alloc_as__wuffs_base__image_decoder());
10750   }
10751 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
10752 
10753 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
10754   // Disallow constructing or copying an object via standard C++ mechanisms,
10755   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
10756   // size and field layout is not part of the public, stable, memory-safe API.
10757   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
10758   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
10759   // their first argument) rather than tweaking bar.private_impl.qux fields.
10760   //
10761   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
10762   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
10763   // order to provide convenience methods. These forward on "this", so that you
10764   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
10765   wuffs_nie__decoder__struct() = delete;
10766   wuffs_nie__decoder__struct(const wuffs_nie__decoder__struct&) = delete;
10767   wuffs_nie__decoder__struct& operator=(
10768       const wuffs_nie__decoder__struct&) = delete;
10769 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
10770 
10771 #if !defined(WUFFS_IMPLEMENTATION)
10772   // As above, the size of the struct is not part of the public API, and unless
10773   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
10774   // allocated, not stack allocated. Its size is not intended to be known at
10775   // compile time, but it is unfortunately divulged as a side effect of
10776   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
10777   // instead of "sizeof T", invoking the operator. To make the two values
10778   // different, so that passing the latter will be rejected by the initialize
10779   // function, we add an arbitrary amount of dead weight.
10780   uint8_t dead_weight[123000000];  // 123 MB.
10781 #endif  // !defined(WUFFS_IMPLEMENTATION)
10782 
10783   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_nie__decoder__struct10784   initialize(
10785       size_t sizeof_star_self,
10786       uint64_t wuffs_version,
10787       uint32_t options) {
10788     return wuffs_nie__decoder__initialize(
10789         this, sizeof_star_self, wuffs_version, options);
10790   }
10791 
10792   inline wuffs_base__image_decoder*
upcast_as__wuffs_base__image_decoderwuffs_nie__decoder__struct10793   upcast_as__wuffs_base__image_decoder() {
10794     return (wuffs_base__image_decoder*)this;
10795   }
10796 
10797   inline uint64_t
get_quirkwuffs_nie__decoder__struct10798   get_quirk(
10799       uint32_t a_key) const {
10800     return wuffs_nie__decoder__get_quirk(this, a_key);
10801   }
10802 
10803   inline wuffs_base__status
set_quirkwuffs_nie__decoder__struct10804   set_quirk(
10805       uint32_t a_key,
10806       uint64_t a_value) {
10807     return wuffs_nie__decoder__set_quirk(this, a_key, a_value);
10808   }
10809 
10810   inline wuffs_base__status
decode_image_configwuffs_nie__decoder__struct10811   decode_image_config(
10812       wuffs_base__image_config* a_dst,
10813       wuffs_base__io_buffer* a_src) {
10814     return wuffs_nie__decoder__decode_image_config(this, a_dst, a_src);
10815   }
10816 
10817   inline wuffs_base__status
decode_frame_configwuffs_nie__decoder__struct10818   decode_frame_config(
10819       wuffs_base__frame_config* a_dst,
10820       wuffs_base__io_buffer* a_src) {
10821     return wuffs_nie__decoder__decode_frame_config(this, a_dst, a_src);
10822   }
10823 
10824   inline wuffs_base__status
decode_framewuffs_nie__decoder__struct10825   decode_frame(
10826       wuffs_base__pixel_buffer* a_dst,
10827       wuffs_base__io_buffer* a_src,
10828       wuffs_base__pixel_blend a_blend,
10829       wuffs_base__slice_u8 a_workbuf,
10830       wuffs_base__decode_frame_options* a_opts) {
10831     return wuffs_nie__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
10832   }
10833 
10834   inline wuffs_base__rect_ie_u32
frame_dirty_rectwuffs_nie__decoder__struct10835   frame_dirty_rect() const {
10836     return wuffs_nie__decoder__frame_dirty_rect(this);
10837   }
10838 
10839   inline uint32_t
num_animation_loopswuffs_nie__decoder__struct10840   num_animation_loops() const {
10841     return wuffs_nie__decoder__num_animation_loops(this);
10842   }
10843 
10844   inline uint64_t
num_decoded_frame_configswuffs_nie__decoder__struct10845   num_decoded_frame_configs() const {
10846     return wuffs_nie__decoder__num_decoded_frame_configs(this);
10847   }
10848 
10849   inline uint64_t
num_decoded_frameswuffs_nie__decoder__struct10850   num_decoded_frames() const {
10851     return wuffs_nie__decoder__num_decoded_frames(this);
10852   }
10853 
10854   inline wuffs_base__status
restart_framewuffs_nie__decoder__struct10855   restart_frame(
10856       uint64_t a_index,
10857       uint64_t a_io_position) {
10858     return wuffs_nie__decoder__restart_frame(this, a_index, a_io_position);
10859   }
10860 
10861   inline wuffs_base__empty_struct
set_report_metadatawuffs_nie__decoder__struct10862   set_report_metadata(
10863       uint32_t a_fourcc,
10864       bool a_report) {
10865     return wuffs_nie__decoder__set_report_metadata(this, a_fourcc, a_report);
10866   }
10867 
10868   inline wuffs_base__status
tell_me_morewuffs_nie__decoder__struct10869   tell_me_more(
10870       wuffs_base__io_buffer* a_dst,
10871       wuffs_base__more_information* a_minfo,
10872       wuffs_base__io_buffer* a_src) {
10873     return wuffs_nie__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
10874   }
10875 
10876   inline uint64_t
history_retain_lengthwuffs_nie__decoder__struct10877   history_retain_length() const {
10878     return wuffs_nie__decoder__history_retain_length(this);
10879   }
10880 
10881   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_nie__decoder__struct10882   workbuf_len() const {
10883     return wuffs_nie__decoder__workbuf_len(this);
10884   }
10885 
10886 #endif  // __cplusplus
10887 };  // struct wuffs_nie__decoder__struct
10888 
10889 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
10890 
10891 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NIE) || defined(WUFFS_NONMONOLITHIC)
10892 
10893 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ZLIB) || defined(WUFFS_NONMONOLITHIC)
10894 
10895 // ---------------- Status Codes
10896 
10897 extern const char wuffs_zlib__note__dictionary_required[];
10898 extern const char wuffs_zlib__error__bad_checksum[];
10899 extern const char wuffs_zlib__error__bad_compression_method[];
10900 extern const char wuffs_zlib__error__bad_compression_window_size[];
10901 extern const char wuffs_zlib__error__bad_parity_check[];
10902 extern const char wuffs_zlib__error__incorrect_dictionary[];
10903 extern const char wuffs_zlib__error__truncated_input[];
10904 
10905 // ---------------- Public Consts
10906 
10907 #define WUFFS_ZLIB__QUIRK_JUST_RAW_DEFLATE 2113790976
10908 
10909 #define WUFFS_ZLIB__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0
10910 
10911 #define WUFFS_ZLIB__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 1
10912 
10913 // ---------------- Struct Declarations
10914 
10915 typedef struct wuffs_zlib__decoder__struct wuffs_zlib__decoder;
10916 
10917 #ifdef __cplusplus
10918 extern "C" {
10919 #endif
10920 
10921 // ---------------- Public Initializer Prototypes
10922 
10923 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
10924 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
10925 //
10926 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
10927 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
10928 
10929 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
10930 wuffs_zlib__decoder__initialize(
10931     wuffs_zlib__decoder* self,
10932     size_t sizeof_star_self,
10933     uint64_t wuffs_version,
10934     uint32_t options);
10935 
10936 size_t
10937 sizeof__wuffs_zlib__decoder(void);
10938 
10939 // ---------------- Allocs
10940 
10941 // These functions allocate and initialize Wuffs structs. They return NULL if
10942 // memory allocation fails. If they return non-NULL, there is no need to call
10943 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
10944 // calling free on the returned pointer. That pointer is effectively a C++
10945 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
10946 
10947 wuffs_zlib__decoder*
10948 wuffs_zlib__decoder__alloc(void);
10949 
10950 static inline wuffs_base__io_transformer*
wuffs_zlib__decoder__alloc_as__wuffs_base__io_transformer(void)10951 wuffs_zlib__decoder__alloc_as__wuffs_base__io_transformer(void) {
10952   return (wuffs_base__io_transformer*)(wuffs_zlib__decoder__alloc());
10953 }
10954 
10955 // ---------------- Upcasts
10956 
10957 static inline wuffs_base__io_transformer*
wuffs_zlib__decoder__upcast_as__wuffs_base__io_transformer(wuffs_zlib__decoder * p)10958 wuffs_zlib__decoder__upcast_as__wuffs_base__io_transformer(
10959     wuffs_zlib__decoder* p) {
10960   return (wuffs_base__io_transformer*)p;
10961 }
10962 
10963 // ---------------- Public Function Prototypes
10964 
10965 WUFFS_BASE__GENERATED_C_CODE
10966 WUFFS_BASE__MAYBE_STATIC uint32_t
10967 wuffs_zlib__decoder__dictionary_id(
10968     const wuffs_zlib__decoder* self);
10969 
10970 WUFFS_BASE__GENERATED_C_CODE
10971 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
10972 wuffs_zlib__decoder__add_dictionary(
10973     wuffs_zlib__decoder* self,
10974     wuffs_base__slice_u8 a_dict);
10975 
10976 WUFFS_BASE__GENERATED_C_CODE
10977 WUFFS_BASE__MAYBE_STATIC uint64_t
10978 wuffs_zlib__decoder__get_quirk(
10979     const wuffs_zlib__decoder* self,
10980     uint32_t a_key);
10981 
10982 WUFFS_BASE__GENERATED_C_CODE
10983 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
10984 wuffs_zlib__decoder__set_quirk(
10985     wuffs_zlib__decoder* self,
10986     uint32_t a_key,
10987     uint64_t a_value);
10988 
10989 WUFFS_BASE__GENERATED_C_CODE
10990 WUFFS_BASE__MAYBE_STATIC uint64_t
10991 wuffs_zlib__decoder__history_retain_length(
10992     const wuffs_zlib__decoder* self);
10993 
10994 WUFFS_BASE__GENERATED_C_CODE
10995 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
10996 wuffs_zlib__decoder__workbuf_len(
10997     const wuffs_zlib__decoder* self);
10998 
10999 WUFFS_BASE__GENERATED_C_CODE
11000 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
11001 wuffs_zlib__decoder__transform_io(
11002     wuffs_zlib__decoder* self,
11003     wuffs_base__io_buffer* a_dst,
11004     wuffs_base__io_buffer* a_src,
11005     wuffs_base__slice_u8 a_workbuf);
11006 
11007 #ifdef __cplusplus
11008 }  // extern "C"
11009 #endif
11010 
11011 // ---------------- Struct Definitions
11012 
11013 // These structs' fields, and the sizeof them, are private implementation
11014 // details that aren't guaranteed to be stable across Wuffs versions.
11015 //
11016 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
11017 
11018 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
11019 
11020 struct wuffs_zlib__decoder__struct {
11021   // Do not access the private_impl's or private_data's fields directly. There
11022   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
11023   // the wuffs_foo__bar__baz functions.
11024   //
11025   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
11026   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
11027 
11028   struct {
11029     uint32_t magic;
11030     uint32_t active_coroutine;
11031     wuffs_base__vtable vtable_for__wuffs_base__io_transformer;
11032     wuffs_base__vtable null_vtable;
11033 
11034     bool f_bad_call_sequence;
11035     bool f_header_complete;
11036     bool f_got_dictionary;
11037     bool f_want_dictionary;
11038     bool f_quirks[1];
11039     bool f_ignore_checksum;
11040     uint32_t f_dict_id_got;
11041     uint32_t f_dict_id_want;
11042 
11043     uint32_t p_transform_io[1];
11044     uint32_t p_do_transform_io[1];
11045   } private_impl;
11046 
11047   struct {
11048     wuffs_adler32__hasher f_checksum;
11049     wuffs_adler32__hasher f_dict_id_hasher;
11050     wuffs_deflate__decoder f_flate;
11051 
11052     struct {
11053       uint32_t v_checksum_got;
11054       uint64_t scratch;
11055     } s_do_transform_io[1];
11056   } private_data;
11057 
11058 #ifdef __cplusplus
11059 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
11060   using unique_ptr = std::unique_ptr<wuffs_zlib__decoder, wuffs_unique_ptr_deleter>;
11061 
11062   // On failure, the alloc_etc functions return nullptr. They don't throw.
11063 
11064   static inline unique_ptr
allocwuffs_zlib__decoder__struct11065   alloc() {
11066     return unique_ptr(wuffs_zlib__decoder__alloc());
11067   }
11068 
11069   static inline wuffs_base__io_transformer::unique_ptr
alloc_as__wuffs_base__io_transformerwuffs_zlib__decoder__struct11070   alloc_as__wuffs_base__io_transformer() {
11071     return wuffs_base__io_transformer::unique_ptr(
11072         wuffs_zlib__decoder__alloc_as__wuffs_base__io_transformer());
11073   }
11074 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
11075 
11076 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
11077   // Disallow constructing or copying an object via standard C++ mechanisms,
11078   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
11079   // size and field layout is not part of the public, stable, memory-safe API.
11080   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
11081   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
11082   // their first argument) rather than tweaking bar.private_impl.qux fields.
11083   //
11084   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
11085   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
11086   // order to provide convenience methods. These forward on "this", so that you
11087   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
11088   wuffs_zlib__decoder__struct() = delete;
11089   wuffs_zlib__decoder__struct(const wuffs_zlib__decoder__struct&) = delete;
11090   wuffs_zlib__decoder__struct& operator=(
11091       const wuffs_zlib__decoder__struct&) = delete;
11092 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
11093 
11094 #if !defined(WUFFS_IMPLEMENTATION)
11095   // As above, the size of the struct is not part of the public API, and unless
11096   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
11097   // allocated, not stack allocated. Its size is not intended to be known at
11098   // compile time, but it is unfortunately divulged as a side effect of
11099   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
11100   // instead of "sizeof T", invoking the operator. To make the two values
11101   // different, so that passing the latter will be rejected by the initialize
11102   // function, we add an arbitrary amount of dead weight.
11103   uint8_t dead_weight[123000000];  // 123 MB.
11104 #endif  // !defined(WUFFS_IMPLEMENTATION)
11105 
11106   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_zlib__decoder__struct11107   initialize(
11108       size_t sizeof_star_self,
11109       uint64_t wuffs_version,
11110       uint32_t options) {
11111     return wuffs_zlib__decoder__initialize(
11112         this, sizeof_star_self, wuffs_version, options);
11113   }
11114 
11115   inline wuffs_base__io_transformer*
upcast_as__wuffs_base__io_transformerwuffs_zlib__decoder__struct11116   upcast_as__wuffs_base__io_transformer() {
11117     return (wuffs_base__io_transformer*)this;
11118   }
11119 
11120   inline uint32_t
dictionary_idwuffs_zlib__decoder__struct11121   dictionary_id() const {
11122     return wuffs_zlib__decoder__dictionary_id(this);
11123   }
11124 
11125   inline wuffs_base__empty_struct
add_dictionarywuffs_zlib__decoder__struct11126   add_dictionary(
11127       wuffs_base__slice_u8 a_dict) {
11128     return wuffs_zlib__decoder__add_dictionary(this, a_dict);
11129   }
11130 
11131   inline uint64_t
get_quirkwuffs_zlib__decoder__struct11132   get_quirk(
11133       uint32_t a_key) const {
11134     return wuffs_zlib__decoder__get_quirk(this, a_key);
11135   }
11136 
11137   inline wuffs_base__status
set_quirkwuffs_zlib__decoder__struct11138   set_quirk(
11139       uint32_t a_key,
11140       uint64_t a_value) {
11141     return wuffs_zlib__decoder__set_quirk(this, a_key, a_value);
11142   }
11143 
11144   inline uint64_t
history_retain_lengthwuffs_zlib__decoder__struct11145   history_retain_length() const {
11146     return wuffs_zlib__decoder__history_retain_length(this);
11147   }
11148 
11149   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_zlib__decoder__struct11150   workbuf_len() const {
11151     return wuffs_zlib__decoder__workbuf_len(this);
11152   }
11153 
11154   inline wuffs_base__status
transform_iowuffs_zlib__decoder__struct11155   transform_io(
11156       wuffs_base__io_buffer* a_dst,
11157       wuffs_base__io_buffer* a_src,
11158       wuffs_base__slice_u8 a_workbuf) {
11159     return wuffs_zlib__decoder__transform_io(this, a_dst, a_src, a_workbuf);
11160   }
11161 
11162 #endif  // __cplusplus
11163 };  // struct wuffs_zlib__decoder__struct
11164 
11165 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
11166 
11167 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ZLIB) || defined(WUFFS_NONMONOLITHIC)
11168 
11169 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__PNG) || defined(WUFFS_NONMONOLITHIC)
11170 
11171 // ---------------- Status Codes
11172 
11173 extern const char wuffs_png__error__bad_animation_sequence_number[];
11174 extern const char wuffs_png__error__bad_checksum[];
11175 extern const char wuffs_png__error__bad_chunk[];
11176 extern const char wuffs_png__error__bad_filter[];
11177 extern const char wuffs_png__error__bad_header[];
11178 extern const char wuffs_png__error__bad_text_chunk_not_latin_1[];
11179 extern const char wuffs_png__error__missing_palette[];
11180 extern const char wuffs_png__error__truncated_input[];
11181 extern const char wuffs_png__error__unsupported_cgbi_extension[];
11182 extern const char wuffs_png__error__unsupported_png_compression_method[];
11183 extern const char wuffs_png__error__unsupported_png_file[];
11184 
11185 // ---------------- Public Consts
11186 
11187 #define WUFFS_PNG__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0
11188 
11189 #define WUFFS_PNG__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 2251799562027015
11190 
11191 #define WUFFS_PNG__DECODER_SRC_IO_BUFFER_LENGTH_MIN_INCL 8
11192 
11193 // ---------------- Struct Declarations
11194 
11195 typedef struct wuffs_png__decoder__struct wuffs_png__decoder;
11196 
11197 #ifdef __cplusplus
11198 extern "C" {
11199 #endif
11200 
11201 // ---------------- Public Initializer Prototypes
11202 
11203 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
11204 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
11205 //
11206 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
11207 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
11208 
11209 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
11210 wuffs_png__decoder__initialize(
11211     wuffs_png__decoder* self,
11212     size_t sizeof_star_self,
11213     uint64_t wuffs_version,
11214     uint32_t options);
11215 
11216 size_t
11217 sizeof__wuffs_png__decoder(void);
11218 
11219 // ---------------- Allocs
11220 
11221 // These functions allocate and initialize Wuffs structs. They return NULL if
11222 // memory allocation fails. If they return non-NULL, there is no need to call
11223 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
11224 // calling free on the returned pointer. That pointer is effectively a C++
11225 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
11226 
11227 wuffs_png__decoder*
11228 wuffs_png__decoder__alloc(void);
11229 
11230 static inline wuffs_base__image_decoder*
wuffs_png__decoder__alloc_as__wuffs_base__image_decoder(void)11231 wuffs_png__decoder__alloc_as__wuffs_base__image_decoder(void) {
11232   return (wuffs_base__image_decoder*)(wuffs_png__decoder__alloc());
11233 }
11234 
11235 // ---------------- Upcasts
11236 
11237 static inline wuffs_base__image_decoder*
wuffs_png__decoder__upcast_as__wuffs_base__image_decoder(wuffs_png__decoder * p)11238 wuffs_png__decoder__upcast_as__wuffs_base__image_decoder(
11239     wuffs_png__decoder* p) {
11240   return (wuffs_base__image_decoder*)p;
11241 }
11242 
11243 // ---------------- Public Function Prototypes
11244 
11245 WUFFS_BASE__GENERATED_C_CODE
11246 WUFFS_BASE__MAYBE_STATIC uint64_t
11247 wuffs_png__decoder__get_quirk(
11248     const wuffs_png__decoder* self,
11249     uint32_t a_key);
11250 
11251 WUFFS_BASE__GENERATED_C_CODE
11252 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
11253 wuffs_png__decoder__set_quirk(
11254     wuffs_png__decoder* self,
11255     uint32_t a_key,
11256     uint64_t a_value);
11257 
11258 WUFFS_BASE__GENERATED_C_CODE
11259 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
11260 wuffs_png__decoder__decode_image_config(
11261     wuffs_png__decoder* self,
11262     wuffs_base__image_config* a_dst,
11263     wuffs_base__io_buffer* a_src);
11264 
11265 WUFFS_BASE__GENERATED_C_CODE
11266 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
11267 wuffs_png__decoder__decode_frame_config(
11268     wuffs_png__decoder* self,
11269     wuffs_base__frame_config* a_dst,
11270     wuffs_base__io_buffer* a_src);
11271 
11272 WUFFS_BASE__GENERATED_C_CODE
11273 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
11274 wuffs_png__decoder__decode_frame(
11275     wuffs_png__decoder* self,
11276     wuffs_base__pixel_buffer* a_dst,
11277     wuffs_base__io_buffer* a_src,
11278     wuffs_base__pixel_blend a_blend,
11279     wuffs_base__slice_u8 a_workbuf,
11280     wuffs_base__decode_frame_options* a_opts);
11281 
11282 WUFFS_BASE__GENERATED_C_CODE
11283 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
11284 wuffs_png__decoder__frame_dirty_rect(
11285     const wuffs_png__decoder* self);
11286 
11287 WUFFS_BASE__GENERATED_C_CODE
11288 WUFFS_BASE__MAYBE_STATIC uint32_t
11289 wuffs_png__decoder__num_animation_loops(
11290     const wuffs_png__decoder* self);
11291 
11292 WUFFS_BASE__GENERATED_C_CODE
11293 WUFFS_BASE__MAYBE_STATIC uint64_t
11294 wuffs_png__decoder__num_decoded_frame_configs(
11295     const wuffs_png__decoder* self);
11296 
11297 WUFFS_BASE__GENERATED_C_CODE
11298 WUFFS_BASE__MAYBE_STATIC uint64_t
11299 wuffs_png__decoder__num_decoded_frames(
11300     const wuffs_png__decoder* self);
11301 
11302 WUFFS_BASE__GENERATED_C_CODE
11303 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
11304 wuffs_png__decoder__restart_frame(
11305     wuffs_png__decoder* self,
11306     uint64_t a_index,
11307     uint64_t a_io_position);
11308 
11309 WUFFS_BASE__GENERATED_C_CODE
11310 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
11311 wuffs_png__decoder__set_report_metadata(
11312     wuffs_png__decoder* self,
11313     uint32_t a_fourcc,
11314     bool a_report);
11315 
11316 WUFFS_BASE__GENERATED_C_CODE
11317 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
11318 wuffs_png__decoder__tell_me_more(
11319     wuffs_png__decoder* self,
11320     wuffs_base__io_buffer* a_dst,
11321     wuffs_base__more_information* a_minfo,
11322     wuffs_base__io_buffer* a_src);
11323 
11324 WUFFS_BASE__GENERATED_C_CODE
11325 WUFFS_BASE__MAYBE_STATIC uint64_t
11326 wuffs_png__decoder__history_retain_length(
11327     const wuffs_png__decoder* self);
11328 
11329 WUFFS_BASE__GENERATED_C_CODE
11330 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
11331 wuffs_png__decoder__workbuf_len(
11332     const wuffs_png__decoder* self);
11333 
11334 #ifdef __cplusplus
11335 }  // extern "C"
11336 #endif
11337 
11338 // ---------------- Struct Definitions
11339 
11340 // These structs' fields, and the sizeof them, are private implementation
11341 // details that aren't guaranteed to be stable across Wuffs versions.
11342 //
11343 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
11344 
11345 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
11346 
11347 struct wuffs_png__decoder__struct {
11348   // Do not access the private_impl's or private_data's fields directly. There
11349   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
11350   // the wuffs_foo__bar__baz functions.
11351   //
11352   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
11353   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
11354 
11355   struct {
11356     uint32_t magic;
11357     uint32_t active_coroutine;
11358     wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
11359     wuffs_base__vtable null_vtable;
11360 
11361     uint32_t f_width;
11362     uint32_t f_height;
11363     uint64_t f_pass_bytes_per_row;
11364     uint64_t f_workbuf_wi;
11365     uint64_t f_workbuf_hist_pos_base;
11366     uint64_t f_overall_workbuf_length;
11367     uint64_t f_pass_workbuf_length;
11368     uint8_t f_call_sequence;
11369     bool f_report_metadata_chrm;
11370     bool f_report_metadata_exif;
11371     bool f_report_metadata_gama;
11372     bool f_report_metadata_iccp;
11373     bool f_report_metadata_kvp;
11374     bool f_report_metadata_srgb;
11375     bool f_ignore_checksum;
11376     uint8_t f_depth;
11377     uint8_t f_color_type;
11378     uint8_t f_filter_distance;
11379     uint8_t f_interlace_pass;
11380     bool f_seen_actl;
11381     bool f_seen_chrm;
11382     bool f_seen_fctl;
11383     bool f_seen_exif;
11384     bool f_seen_gama;
11385     bool f_seen_iccp;
11386     bool f_seen_idat;
11387     bool f_seen_ihdr;
11388     bool f_seen_plte;
11389     bool f_seen_srgb;
11390     bool f_seen_trns;
11391     bool f_metadata_is_zlib_compressed;
11392     bool f_zlib_is_dirty;
11393     uint32_t f_chunk_type;
11394     uint8_t f_chunk_type_array[4];
11395     uint32_t f_chunk_length;
11396     uint64_t f_remap_transparency;
11397     uint32_t f_dst_pixfmt;
11398     uint32_t f_src_pixfmt;
11399     uint32_t f_num_animation_frames_value;
11400     uint32_t f_num_animation_loops_value;
11401     uint32_t f_num_decoded_frame_configs_value;
11402     uint32_t f_num_decoded_frames_value;
11403     uint32_t f_frame_rect_x0;
11404     uint32_t f_frame_rect_y0;
11405     uint32_t f_frame_rect_x1;
11406     uint32_t f_frame_rect_y1;
11407     uint32_t f_first_rect_x0;
11408     uint32_t f_first_rect_y0;
11409     uint32_t f_first_rect_x1;
11410     uint32_t f_first_rect_y1;
11411     uint64_t f_frame_config_io_position;
11412     uint64_t f_first_config_io_position;
11413     uint64_t f_frame_duration;
11414     uint64_t f_first_duration;
11415     uint8_t f_frame_disposal;
11416     uint8_t f_first_disposal;
11417     bool f_frame_overwrite_instead_of_blend;
11418     bool f_first_overwrite_instead_of_blend;
11419     uint32_t f_next_animation_seq_num;
11420     uint32_t f_metadata_flavor;
11421     uint32_t f_metadata_fourcc;
11422     uint64_t f_metadata_x;
11423     uint64_t f_metadata_y;
11424     uint64_t f_metadata_z;
11425     uint32_t f_ztxt_ri;
11426     uint32_t f_ztxt_wi;
11427     uint64_t f_ztxt_hist_pos;
11428     wuffs_base__pixel_swizzler f_swizzler;
11429 
11430     wuffs_base__empty_struct (*choosy_filter_1)(
11431         wuffs_png__decoder* self,
11432         wuffs_base__slice_u8 a_curr);
11433     wuffs_base__empty_struct (*choosy_filter_3)(
11434         wuffs_png__decoder* self,
11435         wuffs_base__slice_u8 a_curr,
11436         wuffs_base__slice_u8 a_prev);
11437     wuffs_base__empty_struct (*choosy_filter_4)(
11438         wuffs_png__decoder* self,
11439         wuffs_base__slice_u8 a_curr,
11440         wuffs_base__slice_u8 a_prev);
11441     uint32_t p_decode_image_config[1];
11442     uint32_t p_do_decode_image_config[1];
11443     uint32_t p_decode_ihdr[1];
11444     uint32_t p_decode_other_chunk[1];
11445     uint32_t p_decode_actl[1];
11446     uint32_t p_decode_chrm[1];
11447     uint32_t p_decode_fctl[1];
11448     uint32_t p_decode_gama[1];
11449     uint32_t p_decode_iccp[1];
11450     uint32_t p_decode_plte[1];
11451     uint32_t p_decode_srgb[1];
11452     uint32_t p_decode_trns[1];
11453     uint32_t p_decode_frame_config[1];
11454     uint32_t p_do_decode_frame_config[1];
11455     uint32_t p_skip_frame[1];
11456     uint32_t p_decode_frame[1];
11457     uint32_t p_do_decode_frame[1];
11458     uint32_t p_decode_pass[1];
11459     uint32_t p_tell_me_more[1];
11460     uint32_t p_do_tell_me_more[1];
11461     wuffs_base__status (*choosy_filter_and_swizzle)(
11462         wuffs_png__decoder* self,
11463         wuffs_base__pixel_buffer* a_dst,
11464         wuffs_base__slice_u8 a_workbuf);
11465   } private_impl;
11466 
11467   struct {
11468     wuffs_crc32__ieee_hasher f_crc32;
11469     wuffs_zlib__decoder f_zlib;
11470     uint8_t f_dst_palette[1024];
11471     uint8_t f_src_palette[1024];
11472 
11473     struct {
11474       uint32_t v_checksum_have;
11475       uint64_t scratch;
11476     } s_do_decode_image_config[1];
11477     struct {
11478       uint64_t scratch;
11479     } s_decode_ihdr[1];
11480     struct {
11481       uint64_t scratch;
11482     } s_decode_other_chunk[1];
11483     struct {
11484       uint64_t scratch;
11485     } s_decode_actl[1];
11486     struct {
11487       uint64_t scratch;
11488     } s_decode_chrm[1];
11489     struct {
11490       uint32_t v_x0;
11491       uint32_t v_x1;
11492       uint32_t v_y1;
11493       uint64_t scratch;
11494     } s_decode_fctl[1];
11495     struct {
11496       uint64_t scratch;
11497     } s_decode_gama[1];
11498     struct {
11499       uint32_t v_num_entries;
11500       uint32_t v_i;
11501       uint64_t scratch;
11502     } s_decode_plte[1];
11503     struct {
11504       uint32_t v_i;
11505       uint32_t v_n;
11506       uint64_t scratch;
11507     } s_decode_trns[1];
11508     struct {
11509       uint64_t scratch;
11510     } s_do_decode_frame_config[1];
11511     struct {
11512       uint64_t scratch;
11513     } s_skip_frame[1];
11514     struct {
11515       uint64_t scratch;
11516     } s_do_decode_frame[1];
11517     struct {
11518       uint64_t scratch;
11519     } s_decode_pass[1];
11520     struct {
11521       wuffs_base__status v_zlib_status;
11522       uint64_t scratch;
11523     } s_do_tell_me_more[1];
11524   } private_data;
11525 
11526 #ifdef __cplusplus
11527 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
11528   using unique_ptr = std::unique_ptr<wuffs_png__decoder, wuffs_unique_ptr_deleter>;
11529 
11530   // On failure, the alloc_etc functions return nullptr. They don't throw.
11531 
11532   static inline unique_ptr
allocwuffs_png__decoder__struct11533   alloc() {
11534     return unique_ptr(wuffs_png__decoder__alloc());
11535   }
11536 
11537   static inline wuffs_base__image_decoder::unique_ptr
alloc_as__wuffs_base__image_decoderwuffs_png__decoder__struct11538   alloc_as__wuffs_base__image_decoder() {
11539     return wuffs_base__image_decoder::unique_ptr(
11540         wuffs_png__decoder__alloc_as__wuffs_base__image_decoder());
11541   }
11542 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
11543 
11544 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
11545   // Disallow constructing or copying an object via standard C++ mechanisms,
11546   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
11547   // size and field layout is not part of the public, stable, memory-safe API.
11548   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
11549   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
11550   // their first argument) rather than tweaking bar.private_impl.qux fields.
11551   //
11552   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
11553   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
11554   // order to provide convenience methods. These forward on "this", so that you
11555   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
11556   wuffs_png__decoder__struct() = delete;
11557   wuffs_png__decoder__struct(const wuffs_png__decoder__struct&) = delete;
11558   wuffs_png__decoder__struct& operator=(
11559       const wuffs_png__decoder__struct&) = delete;
11560 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
11561 
11562 #if !defined(WUFFS_IMPLEMENTATION)
11563   // As above, the size of the struct is not part of the public API, and unless
11564   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
11565   // allocated, not stack allocated. Its size is not intended to be known at
11566   // compile time, but it is unfortunately divulged as a side effect of
11567   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
11568   // instead of "sizeof T", invoking the operator. To make the two values
11569   // different, so that passing the latter will be rejected by the initialize
11570   // function, we add an arbitrary amount of dead weight.
11571   uint8_t dead_weight[123000000];  // 123 MB.
11572 #endif  // !defined(WUFFS_IMPLEMENTATION)
11573 
11574   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_png__decoder__struct11575   initialize(
11576       size_t sizeof_star_self,
11577       uint64_t wuffs_version,
11578       uint32_t options) {
11579     return wuffs_png__decoder__initialize(
11580         this, sizeof_star_self, wuffs_version, options);
11581   }
11582 
11583   inline wuffs_base__image_decoder*
upcast_as__wuffs_base__image_decoderwuffs_png__decoder__struct11584   upcast_as__wuffs_base__image_decoder() {
11585     return (wuffs_base__image_decoder*)this;
11586   }
11587 
11588   inline uint64_t
get_quirkwuffs_png__decoder__struct11589   get_quirk(
11590       uint32_t a_key) const {
11591     return wuffs_png__decoder__get_quirk(this, a_key);
11592   }
11593 
11594   inline wuffs_base__status
set_quirkwuffs_png__decoder__struct11595   set_quirk(
11596       uint32_t a_key,
11597       uint64_t a_value) {
11598     return wuffs_png__decoder__set_quirk(this, a_key, a_value);
11599   }
11600 
11601   inline wuffs_base__status
decode_image_configwuffs_png__decoder__struct11602   decode_image_config(
11603       wuffs_base__image_config* a_dst,
11604       wuffs_base__io_buffer* a_src) {
11605     return wuffs_png__decoder__decode_image_config(this, a_dst, a_src);
11606   }
11607 
11608   inline wuffs_base__status
decode_frame_configwuffs_png__decoder__struct11609   decode_frame_config(
11610       wuffs_base__frame_config* a_dst,
11611       wuffs_base__io_buffer* a_src) {
11612     return wuffs_png__decoder__decode_frame_config(this, a_dst, a_src);
11613   }
11614 
11615   inline wuffs_base__status
decode_framewuffs_png__decoder__struct11616   decode_frame(
11617       wuffs_base__pixel_buffer* a_dst,
11618       wuffs_base__io_buffer* a_src,
11619       wuffs_base__pixel_blend a_blend,
11620       wuffs_base__slice_u8 a_workbuf,
11621       wuffs_base__decode_frame_options* a_opts) {
11622     return wuffs_png__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
11623   }
11624 
11625   inline wuffs_base__rect_ie_u32
frame_dirty_rectwuffs_png__decoder__struct11626   frame_dirty_rect() const {
11627     return wuffs_png__decoder__frame_dirty_rect(this);
11628   }
11629 
11630   inline uint32_t
num_animation_loopswuffs_png__decoder__struct11631   num_animation_loops() const {
11632     return wuffs_png__decoder__num_animation_loops(this);
11633   }
11634 
11635   inline uint64_t
num_decoded_frame_configswuffs_png__decoder__struct11636   num_decoded_frame_configs() const {
11637     return wuffs_png__decoder__num_decoded_frame_configs(this);
11638   }
11639 
11640   inline uint64_t
num_decoded_frameswuffs_png__decoder__struct11641   num_decoded_frames() const {
11642     return wuffs_png__decoder__num_decoded_frames(this);
11643   }
11644 
11645   inline wuffs_base__status
restart_framewuffs_png__decoder__struct11646   restart_frame(
11647       uint64_t a_index,
11648       uint64_t a_io_position) {
11649     return wuffs_png__decoder__restart_frame(this, a_index, a_io_position);
11650   }
11651 
11652   inline wuffs_base__empty_struct
set_report_metadatawuffs_png__decoder__struct11653   set_report_metadata(
11654       uint32_t a_fourcc,
11655       bool a_report) {
11656     return wuffs_png__decoder__set_report_metadata(this, a_fourcc, a_report);
11657   }
11658 
11659   inline wuffs_base__status
tell_me_morewuffs_png__decoder__struct11660   tell_me_more(
11661       wuffs_base__io_buffer* a_dst,
11662       wuffs_base__more_information* a_minfo,
11663       wuffs_base__io_buffer* a_src) {
11664     return wuffs_png__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
11665   }
11666 
11667   inline uint64_t
history_retain_lengthwuffs_png__decoder__struct11668   history_retain_length() const {
11669     return wuffs_png__decoder__history_retain_length(this);
11670   }
11671 
11672   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_png__decoder__struct11673   workbuf_len() const {
11674     return wuffs_png__decoder__workbuf_len(this);
11675   }
11676 
11677 #endif  // __cplusplus
11678 };  // struct wuffs_png__decoder__struct
11679 
11680 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
11681 
11682 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__PNG) || defined(WUFFS_NONMONOLITHIC)
11683 
11684 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__TGA) || defined(WUFFS_NONMONOLITHIC)
11685 
11686 // ---------------- Status Codes
11687 
11688 extern const char wuffs_tga__error__bad_header[];
11689 extern const char wuffs_tga__error__bad_run_length_encoding[];
11690 extern const char wuffs_tga__error__truncated_input[];
11691 extern const char wuffs_tga__error__unsupported_tga_file[];
11692 
11693 // ---------------- Public Consts
11694 
11695 #define WUFFS_TGA__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0
11696 
11697 #define WUFFS_TGA__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
11698 
11699 // ---------------- Struct Declarations
11700 
11701 typedef struct wuffs_tga__decoder__struct wuffs_tga__decoder;
11702 
11703 #ifdef __cplusplus
11704 extern "C" {
11705 #endif
11706 
11707 // ---------------- Public Initializer Prototypes
11708 
11709 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
11710 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
11711 //
11712 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
11713 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
11714 
11715 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
11716 wuffs_tga__decoder__initialize(
11717     wuffs_tga__decoder* self,
11718     size_t sizeof_star_self,
11719     uint64_t wuffs_version,
11720     uint32_t options);
11721 
11722 size_t
11723 sizeof__wuffs_tga__decoder(void);
11724 
11725 // ---------------- Allocs
11726 
11727 // These functions allocate and initialize Wuffs structs. They return NULL if
11728 // memory allocation fails. If they return non-NULL, there is no need to call
11729 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
11730 // calling free on the returned pointer. That pointer is effectively a C++
11731 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
11732 
11733 wuffs_tga__decoder*
11734 wuffs_tga__decoder__alloc(void);
11735 
11736 static inline wuffs_base__image_decoder*
wuffs_tga__decoder__alloc_as__wuffs_base__image_decoder(void)11737 wuffs_tga__decoder__alloc_as__wuffs_base__image_decoder(void) {
11738   return (wuffs_base__image_decoder*)(wuffs_tga__decoder__alloc());
11739 }
11740 
11741 // ---------------- Upcasts
11742 
11743 static inline wuffs_base__image_decoder*
wuffs_tga__decoder__upcast_as__wuffs_base__image_decoder(wuffs_tga__decoder * p)11744 wuffs_tga__decoder__upcast_as__wuffs_base__image_decoder(
11745     wuffs_tga__decoder* p) {
11746   return (wuffs_base__image_decoder*)p;
11747 }
11748 
11749 // ---------------- Public Function Prototypes
11750 
11751 WUFFS_BASE__GENERATED_C_CODE
11752 WUFFS_BASE__MAYBE_STATIC uint64_t
11753 wuffs_tga__decoder__get_quirk(
11754     const wuffs_tga__decoder* self,
11755     uint32_t a_key);
11756 
11757 WUFFS_BASE__GENERATED_C_CODE
11758 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
11759 wuffs_tga__decoder__set_quirk(
11760     wuffs_tga__decoder* self,
11761     uint32_t a_key,
11762     uint64_t a_value);
11763 
11764 WUFFS_BASE__GENERATED_C_CODE
11765 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
11766 wuffs_tga__decoder__decode_image_config(
11767     wuffs_tga__decoder* self,
11768     wuffs_base__image_config* a_dst,
11769     wuffs_base__io_buffer* a_src);
11770 
11771 WUFFS_BASE__GENERATED_C_CODE
11772 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
11773 wuffs_tga__decoder__decode_frame_config(
11774     wuffs_tga__decoder* self,
11775     wuffs_base__frame_config* a_dst,
11776     wuffs_base__io_buffer* a_src);
11777 
11778 WUFFS_BASE__GENERATED_C_CODE
11779 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
11780 wuffs_tga__decoder__decode_frame(
11781     wuffs_tga__decoder* self,
11782     wuffs_base__pixel_buffer* a_dst,
11783     wuffs_base__io_buffer* a_src,
11784     wuffs_base__pixel_blend a_blend,
11785     wuffs_base__slice_u8 a_workbuf,
11786     wuffs_base__decode_frame_options* a_opts);
11787 
11788 WUFFS_BASE__GENERATED_C_CODE
11789 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
11790 wuffs_tga__decoder__frame_dirty_rect(
11791     const wuffs_tga__decoder* self);
11792 
11793 WUFFS_BASE__GENERATED_C_CODE
11794 WUFFS_BASE__MAYBE_STATIC uint32_t
11795 wuffs_tga__decoder__num_animation_loops(
11796     const wuffs_tga__decoder* self);
11797 
11798 WUFFS_BASE__GENERATED_C_CODE
11799 WUFFS_BASE__MAYBE_STATIC uint64_t
11800 wuffs_tga__decoder__num_decoded_frame_configs(
11801     const wuffs_tga__decoder* self);
11802 
11803 WUFFS_BASE__GENERATED_C_CODE
11804 WUFFS_BASE__MAYBE_STATIC uint64_t
11805 wuffs_tga__decoder__num_decoded_frames(
11806     const wuffs_tga__decoder* self);
11807 
11808 WUFFS_BASE__GENERATED_C_CODE
11809 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
11810 wuffs_tga__decoder__restart_frame(
11811     wuffs_tga__decoder* self,
11812     uint64_t a_index,
11813     uint64_t a_io_position);
11814 
11815 WUFFS_BASE__GENERATED_C_CODE
11816 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
11817 wuffs_tga__decoder__set_report_metadata(
11818     wuffs_tga__decoder* self,
11819     uint32_t a_fourcc,
11820     bool a_report);
11821 
11822 WUFFS_BASE__GENERATED_C_CODE
11823 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
11824 wuffs_tga__decoder__tell_me_more(
11825     wuffs_tga__decoder* self,
11826     wuffs_base__io_buffer* a_dst,
11827     wuffs_base__more_information* a_minfo,
11828     wuffs_base__io_buffer* a_src);
11829 
11830 WUFFS_BASE__GENERATED_C_CODE
11831 WUFFS_BASE__MAYBE_STATIC uint64_t
11832 wuffs_tga__decoder__history_retain_length(
11833     const wuffs_tga__decoder* self);
11834 
11835 WUFFS_BASE__GENERATED_C_CODE
11836 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
11837 wuffs_tga__decoder__workbuf_len(
11838     const wuffs_tga__decoder* self);
11839 
11840 #ifdef __cplusplus
11841 }  // extern "C"
11842 #endif
11843 
11844 // ---------------- Struct Definitions
11845 
11846 // These structs' fields, and the sizeof them, are private implementation
11847 // details that aren't guaranteed to be stable across Wuffs versions.
11848 //
11849 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
11850 
11851 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
11852 
11853 struct wuffs_tga__decoder__struct {
11854   // Do not access the private_impl's or private_data's fields directly. There
11855   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
11856   // the wuffs_foo__bar__baz functions.
11857   //
11858   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
11859   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
11860 
11861   struct {
11862     uint32_t magic;
11863     uint32_t active_coroutine;
11864     wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
11865     wuffs_base__vtable null_vtable;
11866 
11867     uint32_t f_width;
11868     uint32_t f_height;
11869     uint8_t f_call_sequence;
11870     uint8_t f_header_id_length;
11871     uint8_t f_header_color_map_type;
11872     uint8_t f_header_image_type;
11873     uint16_t f_header_color_map_first_entry_index;
11874     uint16_t f_header_color_map_length;
11875     uint8_t f_header_color_map_entry_size;
11876     uint8_t f_header_pixel_depth;
11877     uint8_t f_header_image_descriptor;
11878     bool f_opaque;
11879     uint32_t f_scratch_bytes_per_pixel;
11880     uint32_t f_src_bytes_per_pixel;
11881     uint32_t f_src_pixfmt;
11882     uint64_t f_frame_config_io_position;
11883     wuffs_base__pixel_swizzler f_swizzler;
11884 
11885     uint32_t p_decode_image_config[1];
11886     uint32_t p_do_decode_image_config[1];
11887     uint32_t p_decode_frame_config[1];
11888     uint32_t p_do_decode_frame_config[1];
11889     uint32_t p_decode_frame[1];
11890     uint32_t p_do_decode_frame[1];
11891   } private_impl;
11892 
11893   struct {
11894     uint8_t f_dst_palette[1024];
11895     uint8_t f_src_palette[1024];
11896     uint8_t f_scratch[4];
11897 
11898     struct {
11899       uint32_t v_i;
11900       uint64_t scratch;
11901     } s_do_decode_image_config[1];
11902     struct {
11903       uint64_t v_dst_bytes_per_pixel;
11904       uint32_t v_dst_x;
11905       uint32_t v_dst_y;
11906       uint64_t v_mark;
11907       uint32_t v_num_pixels32;
11908       uint32_t v_lit_length;
11909       uint32_t v_run_length;
11910       uint64_t v_num_dst_bytes;
11911       uint64_t scratch;
11912     } s_do_decode_frame[1];
11913   } private_data;
11914 
11915 #ifdef __cplusplus
11916 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
11917   using unique_ptr = std::unique_ptr<wuffs_tga__decoder, wuffs_unique_ptr_deleter>;
11918 
11919   // On failure, the alloc_etc functions return nullptr. They don't throw.
11920 
11921   static inline unique_ptr
allocwuffs_tga__decoder__struct11922   alloc() {
11923     return unique_ptr(wuffs_tga__decoder__alloc());
11924   }
11925 
11926   static inline wuffs_base__image_decoder::unique_ptr
alloc_as__wuffs_base__image_decoderwuffs_tga__decoder__struct11927   alloc_as__wuffs_base__image_decoder() {
11928     return wuffs_base__image_decoder::unique_ptr(
11929         wuffs_tga__decoder__alloc_as__wuffs_base__image_decoder());
11930   }
11931 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
11932 
11933 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
11934   // Disallow constructing or copying an object via standard C++ mechanisms,
11935   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
11936   // size and field layout is not part of the public, stable, memory-safe API.
11937   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
11938   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
11939   // their first argument) rather than tweaking bar.private_impl.qux fields.
11940   //
11941   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
11942   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
11943   // order to provide convenience methods. These forward on "this", so that you
11944   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
11945   wuffs_tga__decoder__struct() = delete;
11946   wuffs_tga__decoder__struct(const wuffs_tga__decoder__struct&) = delete;
11947   wuffs_tga__decoder__struct& operator=(
11948       const wuffs_tga__decoder__struct&) = delete;
11949 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
11950 
11951 #if !defined(WUFFS_IMPLEMENTATION)
11952   // As above, the size of the struct is not part of the public API, and unless
11953   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
11954   // allocated, not stack allocated. Its size is not intended to be known at
11955   // compile time, but it is unfortunately divulged as a side effect of
11956   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
11957   // instead of "sizeof T", invoking the operator. To make the two values
11958   // different, so that passing the latter will be rejected by the initialize
11959   // function, we add an arbitrary amount of dead weight.
11960   uint8_t dead_weight[123000000];  // 123 MB.
11961 #endif  // !defined(WUFFS_IMPLEMENTATION)
11962 
11963   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_tga__decoder__struct11964   initialize(
11965       size_t sizeof_star_self,
11966       uint64_t wuffs_version,
11967       uint32_t options) {
11968     return wuffs_tga__decoder__initialize(
11969         this, sizeof_star_self, wuffs_version, options);
11970   }
11971 
11972   inline wuffs_base__image_decoder*
upcast_as__wuffs_base__image_decoderwuffs_tga__decoder__struct11973   upcast_as__wuffs_base__image_decoder() {
11974     return (wuffs_base__image_decoder*)this;
11975   }
11976 
11977   inline uint64_t
get_quirkwuffs_tga__decoder__struct11978   get_quirk(
11979       uint32_t a_key) const {
11980     return wuffs_tga__decoder__get_quirk(this, a_key);
11981   }
11982 
11983   inline wuffs_base__status
set_quirkwuffs_tga__decoder__struct11984   set_quirk(
11985       uint32_t a_key,
11986       uint64_t a_value) {
11987     return wuffs_tga__decoder__set_quirk(this, a_key, a_value);
11988   }
11989 
11990   inline wuffs_base__status
decode_image_configwuffs_tga__decoder__struct11991   decode_image_config(
11992       wuffs_base__image_config* a_dst,
11993       wuffs_base__io_buffer* a_src) {
11994     return wuffs_tga__decoder__decode_image_config(this, a_dst, a_src);
11995   }
11996 
11997   inline wuffs_base__status
decode_frame_configwuffs_tga__decoder__struct11998   decode_frame_config(
11999       wuffs_base__frame_config* a_dst,
12000       wuffs_base__io_buffer* a_src) {
12001     return wuffs_tga__decoder__decode_frame_config(this, a_dst, a_src);
12002   }
12003 
12004   inline wuffs_base__status
decode_framewuffs_tga__decoder__struct12005   decode_frame(
12006       wuffs_base__pixel_buffer* a_dst,
12007       wuffs_base__io_buffer* a_src,
12008       wuffs_base__pixel_blend a_blend,
12009       wuffs_base__slice_u8 a_workbuf,
12010       wuffs_base__decode_frame_options* a_opts) {
12011     return wuffs_tga__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
12012   }
12013 
12014   inline wuffs_base__rect_ie_u32
frame_dirty_rectwuffs_tga__decoder__struct12015   frame_dirty_rect() const {
12016     return wuffs_tga__decoder__frame_dirty_rect(this);
12017   }
12018 
12019   inline uint32_t
num_animation_loopswuffs_tga__decoder__struct12020   num_animation_loops() const {
12021     return wuffs_tga__decoder__num_animation_loops(this);
12022   }
12023 
12024   inline uint64_t
num_decoded_frame_configswuffs_tga__decoder__struct12025   num_decoded_frame_configs() const {
12026     return wuffs_tga__decoder__num_decoded_frame_configs(this);
12027   }
12028 
12029   inline uint64_t
num_decoded_frameswuffs_tga__decoder__struct12030   num_decoded_frames() const {
12031     return wuffs_tga__decoder__num_decoded_frames(this);
12032   }
12033 
12034   inline wuffs_base__status
restart_framewuffs_tga__decoder__struct12035   restart_frame(
12036       uint64_t a_index,
12037       uint64_t a_io_position) {
12038     return wuffs_tga__decoder__restart_frame(this, a_index, a_io_position);
12039   }
12040 
12041   inline wuffs_base__empty_struct
set_report_metadatawuffs_tga__decoder__struct12042   set_report_metadata(
12043       uint32_t a_fourcc,
12044       bool a_report) {
12045     return wuffs_tga__decoder__set_report_metadata(this, a_fourcc, a_report);
12046   }
12047 
12048   inline wuffs_base__status
tell_me_morewuffs_tga__decoder__struct12049   tell_me_more(
12050       wuffs_base__io_buffer* a_dst,
12051       wuffs_base__more_information* a_minfo,
12052       wuffs_base__io_buffer* a_src) {
12053     return wuffs_tga__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
12054   }
12055 
12056   inline uint64_t
history_retain_lengthwuffs_tga__decoder__struct12057   history_retain_length() const {
12058     return wuffs_tga__decoder__history_retain_length(this);
12059   }
12060 
12061   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_tga__decoder__struct12062   workbuf_len() const {
12063     return wuffs_tga__decoder__workbuf_len(this);
12064   }
12065 
12066 #endif  // __cplusplus
12067 };  // struct wuffs_tga__decoder__struct
12068 
12069 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
12070 
12071 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__TGA) || defined(WUFFS_NONMONOLITHIC)
12072 
12073 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP) || defined(WUFFS_NONMONOLITHIC)
12074 
12075 // ---------------- Status Codes
12076 
12077 extern const char wuffs_wbmp__error__bad_header[];
12078 extern const char wuffs_wbmp__error__truncated_input[];
12079 
12080 // ---------------- Public Consts
12081 
12082 #define WUFFS_WBMP__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0
12083 
12084 #define WUFFS_WBMP__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
12085 
12086 // ---------------- Struct Declarations
12087 
12088 typedef struct wuffs_wbmp__decoder__struct wuffs_wbmp__decoder;
12089 
12090 #ifdef __cplusplus
12091 extern "C" {
12092 #endif
12093 
12094 // ---------------- Public Initializer Prototypes
12095 
12096 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
12097 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
12098 //
12099 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
12100 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
12101 
12102 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
12103 wuffs_wbmp__decoder__initialize(
12104     wuffs_wbmp__decoder* self,
12105     size_t sizeof_star_self,
12106     uint64_t wuffs_version,
12107     uint32_t options);
12108 
12109 size_t
12110 sizeof__wuffs_wbmp__decoder(void);
12111 
12112 // ---------------- Allocs
12113 
12114 // These functions allocate and initialize Wuffs structs. They return NULL if
12115 // memory allocation fails. If they return non-NULL, there is no need to call
12116 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
12117 // calling free on the returned pointer. That pointer is effectively a C++
12118 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
12119 
12120 wuffs_wbmp__decoder*
12121 wuffs_wbmp__decoder__alloc(void);
12122 
12123 static inline wuffs_base__image_decoder*
wuffs_wbmp__decoder__alloc_as__wuffs_base__image_decoder(void)12124 wuffs_wbmp__decoder__alloc_as__wuffs_base__image_decoder(void) {
12125   return (wuffs_base__image_decoder*)(wuffs_wbmp__decoder__alloc());
12126 }
12127 
12128 // ---------------- Upcasts
12129 
12130 static inline wuffs_base__image_decoder*
wuffs_wbmp__decoder__upcast_as__wuffs_base__image_decoder(wuffs_wbmp__decoder * p)12131 wuffs_wbmp__decoder__upcast_as__wuffs_base__image_decoder(
12132     wuffs_wbmp__decoder* p) {
12133   return (wuffs_base__image_decoder*)p;
12134 }
12135 
12136 // ---------------- Public Function Prototypes
12137 
12138 WUFFS_BASE__GENERATED_C_CODE
12139 WUFFS_BASE__MAYBE_STATIC uint64_t
12140 wuffs_wbmp__decoder__get_quirk(
12141     const wuffs_wbmp__decoder* self,
12142     uint32_t a_key);
12143 
12144 WUFFS_BASE__GENERATED_C_CODE
12145 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
12146 wuffs_wbmp__decoder__set_quirk(
12147     wuffs_wbmp__decoder* self,
12148     uint32_t a_key,
12149     uint64_t a_value);
12150 
12151 WUFFS_BASE__GENERATED_C_CODE
12152 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
12153 wuffs_wbmp__decoder__decode_image_config(
12154     wuffs_wbmp__decoder* self,
12155     wuffs_base__image_config* a_dst,
12156     wuffs_base__io_buffer* a_src);
12157 
12158 WUFFS_BASE__GENERATED_C_CODE
12159 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
12160 wuffs_wbmp__decoder__decode_frame_config(
12161     wuffs_wbmp__decoder* self,
12162     wuffs_base__frame_config* a_dst,
12163     wuffs_base__io_buffer* a_src);
12164 
12165 WUFFS_BASE__GENERATED_C_CODE
12166 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
12167 wuffs_wbmp__decoder__decode_frame(
12168     wuffs_wbmp__decoder* self,
12169     wuffs_base__pixel_buffer* a_dst,
12170     wuffs_base__io_buffer* a_src,
12171     wuffs_base__pixel_blend a_blend,
12172     wuffs_base__slice_u8 a_workbuf,
12173     wuffs_base__decode_frame_options* a_opts);
12174 
12175 WUFFS_BASE__GENERATED_C_CODE
12176 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
12177 wuffs_wbmp__decoder__frame_dirty_rect(
12178     const wuffs_wbmp__decoder* self);
12179 
12180 WUFFS_BASE__GENERATED_C_CODE
12181 WUFFS_BASE__MAYBE_STATIC uint32_t
12182 wuffs_wbmp__decoder__num_animation_loops(
12183     const wuffs_wbmp__decoder* self);
12184 
12185 WUFFS_BASE__GENERATED_C_CODE
12186 WUFFS_BASE__MAYBE_STATIC uint64_t
12187 wuffs_wbmp__decoder__num_decoded_frame_configs(
12188     const wuffs_wbmp__decoder* self);
12189 
12190 WUFFS_BASE__GENERATED_C_CODE
12191 WUFFS_BASE__MAYBE_STATIC uint64_t
12192 wuffs_wbmp__decoder__num_decoded_frames(
12193     const wuffs_wbmp__decoder* self);
12194 
12195 WUFFS_BASE__GENERATED_C_CODE
12196 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
12197 wuffs_wbmp__decoder__restart_frame(
12198     wuffs_wbmp__decoder* self,
12199     uint64_t a_index,
12200     uint64_t a_io_position);
12201 
12202 WUFFS_BASE__GENERATED_C_CODE
12203 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
12204 wuffs_wbmp__decoder__set_report_metadata(
12205     wuffs_wbmp__decoder* self,
12206     uint32_t a_fourcc,
12207     bool a_report);
12208 
12209 WUFFS_BASE__GENERATED_C_CODE
12210 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
12211 wuffs_wbmp__decoder__tell_me_more(
12212     wuffs_wbmp__decoder* self,
12213     wuffs_base__io_buffer* a_dst,
12214     wuffs_base__more_information* a_minfo,
12215     wuffs_base__io_buffer* a_src);
12216 
12217 WUFFS_BASE__GENERATED_C_CODE
12218 WUFFS_BASE__MAYBE_STATIC uint64_t
12219 wuffs_wbmp__decoder__history_retain_length(
12220     const wuffs_wbmp__decoder* self);
12221 
12222 WUFFS_BASE__GENERATED_C_CODE
12223 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
12224 wuffs_wbmp__decoder__workbuf_len(
12225     const wuffs_wbmp__decoder* self);
12226 
12227 #ifdef __cplusplus
12228 }  // extern "C"
12229 #endif
12230 
12231 // ---------------- Struct Definitions
12232 
12233 // These structs' fields, and the sizeof them, are private implementation
12234 // details that aren't guaranteed to be stable across Wuffs versions.
12235 //
12236 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
12237 
12238 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
12239 
12240 struct wuffs_wbmp__decoder__struct {
12241   // Do not access the private_impl's or private_data's fields directly. There
12242   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
12243   // the wuffs_foo__bar__baz functions.
12244   //
12245   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
12246   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
12247 
12248   struct {
12249     uint32_t magic;
12250     uint32_t active_coroutine;
12251     wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
12252     wuffs_base__vtable null_vtable;
12253 
12254     uint32_t f_width;
12255     uint32_t f_height;
12256     uint8_t f_call_sequence;
12257     uint64_t f_frame_config_io_position;
12258     wuffs_base__pixel_swizzler f_swizzler;
12259 
12260     uint32_t p_decode_image_config[1];
12261     uint32_t p_do_decode_image_config[1];
12262     uint32_t p_decode_frame_config[1];
12263     uint32_t p_do_decode_frame_config[1];
12264     uint32_t p_decode_frame[1];
12265     uint32_t p_do_decode_frame[1];
12266   } private_impl;
12267 
12268   struct {
12269     struct {
12270       uint32_t v_i;
12271       uint32_t v_p;
12272     } s_do_decode_image_config[1];
12273     struct {
12274       uint64_t v_dst_bytes_per_pixel;
12275       uint32_t v_dst_x;
12276       uint32_t v_dst_y;
12277       uint8_t v_src[1];
12278       uint8_t v_c;
12279     } s_do_decode_frame[1];
12280   } private_data;
12281 
12282 #ifdef __cplusplus
12283 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
12284   using unique_ptr = std::unique_ptr<wuffs_wbmp__decoder, wuffs_unique_ptr_deleter>;
12285 
12286   // On failure, the alloc_etc functions return nullptr. They don't throw.
12287 
12288   static inline unique_ptr
allocwuffs_wbmp__decoder__struct12289   alloc() {
12290     return unique_ptr(wuffs_wbmp__decoder__alloc());
12291   }
12292 
12293   static inline wuffs_base__image_decoder::unique_ptr
alloc_as__wuffs_base__image_decoderwuffs_wbmp__decoder__struct12294   alloc_as__wuffs_base__image_decoder() {
12295     return wuffs_base__image_decoder::unique_ptr(
12296         wuffs_wbmp__decoder__alloc_as__wuffs_base__image_decoder());
12297   }
12298 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
12299 
12300 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
12301   // Disallow constructing or copying an object via standard C++ mechanisms,
12302   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
12303   // size and field layout is not part of the public, stable, memory-safe API.
12304   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
12305   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
12306   // their first argument) rather than tweaking bar.private_impl.qux fields.
12307   //
12308   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
12309   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
12310   // order to provide convenience methods. These forward on "this", so that you
12311   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
12312   wuffs_wbmp__decoder__struct() = delete;
12313   wuffs_wbmp__decoder__struct(const wuffs_wbmp__decoder__struct&) = delete;
12314   wuffs_wbmp__decoder__struct& operator=(
12315       const wuffs_wbmp__decoder__struct&) = delete;
12316 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
12317 
12318 #if !defined(WUFFS_IMPLEMENTATION)
12319   // As above, the size of the struct is not part of the public API, and unless
12320   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
12321   // allocated, not stack allocated. Its size is not intended to be known at
12322   // compile time, but it is unfortunately divulged as a side effect of
12323   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
12324   // instead of "sizeof T", invoking the operator. To make the two values
12325   // different, so that passing the latter will be rejected by the initialize
12326   // function, we add an arbitrary amount of dead weight.
12327   uint8_t dead_weight[123000000];  // 123 MB.
12328 #endif  // !defined(WUFFS_IMPLEMENTATION)
12329 
12330   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_wbmp__decoder__struct12331   initialize(
12332       size_t sizeof_star_self,
12333       uint64_t wuffs_version,
12334       uint32_t options) {
12335     return wuffs_wbmp__decoder__initialize(
12336         this, sizeof_star_self, wuffs_version, options);
12337   }
12338 
12339   inline wuffs_base__image_decoder*
upcast_as__wuffs_base__image_decoderwuffs_wbmp__decoder__struct12340   upcast_as__wuffs_base__image_decoder() {
12341     return (wuffs_base__image_decoder*)this;
12342   }
12343 
12344   inline uint64_t
get_quirkwuffs_wbmp__decoder__struct12345   get_quirk(
12346       uint32_t a_key) const {
12347     return wuffs_wbmp__decoder__get_quirk(this, a_key);
12348   }
12349 
12350   inline wuffs_base__status
set_quirkwuffs_wbmp__decoder__struct12351   set_quirk(
12352       uint32_t a_key,
12353       uint64_t a_value) {
12354     return wuffs_wbmp__decoder__set_quirk(this, a_key, a_value);
12355   }
12356 
12357   inline wuffs_base__status
decode_image_configwuffs_wbmp__decoder__struct12358   decode_image_config(
12359       wuffs_base__image_config* a_dst,
12360       wuffs_base__io_buffer* a_src) {
12361     return wuffs_wbmp__decoder__decode_image_config(this, a_dst, a_src);
12362   }
12363 
12364   inline wuffs_base__status
decode_frame_configwuffs_wbmp__decoder__struct12365   decode_frame_config(
12366       wuffs_base__frame_config* a_dst,
12367       wuffs_base__io_buffer* a_src) {
12368     return wuffs_wbmp__decoder__decode_frame_config(this, a_dst, a_src);
12369   }
12370 
12371   inline wuffs_base__status
decode_framewuffs_wbmp__decoder__struct12372   decode_frame(
12373       wuffs_base__pixel_buffer* a_dst,
12374       wuffs_base__io_buffer* a_src,
12375       wuffs_base__pixel_blend a_blend,
12376       wuffs_base__slice_u8 a_workbuf,
12377       wuffs_base__decode_frame_options* a_opts) {
12378     return wuffs_wbmp__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
12379   }
12380 
12381   inline wuffs_base__rect_ie_u32
frame_dirty_rectwuffs_wbmp__decoder__struct12382   frame_dirty_rect() const {
12383     return wuffs_wbmp__decoder__frame_dirty_rect(this);
12384   }
12385 
12386   inline uint32_t
num_animation_loopswuffs_wbmp__decoder__struct12387   num_animation_loops() const {
12388     return wuffs_wbmp__decoder__num_animation_loops(this);
12389   }
12390 
12391   inline uint64_t
num_decoded_frame_configswuffs_wbmp__decoder__struct12392   num_decoded_frame_configs() const {
12393     return wuffs_wbmp__decoder__num_decoded_frame_configs(this);
12394   }
12395 
12396   inline uint64_t
num_decoded_frameswuffs_wbmp__decoder__struct12397   num_decoded_frames() const {
12398     return wuffs_wbmp__decoder__num_decoded_frames(this);
12399   }
12400 
12401   inline wuffs_base__status
restart_framewuffs_wbmp__decoder__struct12402   restart_frame(
12403       uint64_t a_index,
12404       uint64_t a_io_position) {
12405     return wuffs_wbmp__decoder__restart_frame(this, a_index, a_io_position);
12406   }
12407 
12408   inline wuffs_base__empty_struct
set_report_metadatawuffs_wbmp__decoder__struct12409   set_report_metadata(
12410       uint32_t a_fourcc,
12411       bool a_report) {
12412     return wuffs_wbmp__decoder__set_report_metadata(this, a_fourcc, a_report);
12413   }
12414 
12415   inline wuffs_base__status
tell_me_morewuffs_wbmp__decoder__struct12416   tell_me_more(
12417       wuffs_base__io_buffer* a_dst,
12418       wuffs_base__more_information* a_minfo,
12419       wuffs_base__io_buffer* a_src) {
12420     return wuffs_wbmp__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
12421   }
12422 
12423   inline uint64_t
history_retain_lengthwuffs_wbmp__decoder__struct12424   history_retain_length() const {
12425     return wuffs_wbmp__decoder__history_retain_length(this);
12426   }
12427 
12428   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_wbmp__decoder__struct12429   workbuf_len() const {
12430     return wuffs_wbmp__decoder__workbuf_len(this);
12431   }
12432 
12433 #endif  // __cplusplus
12434 };  // struct wuffs_wbmp__decoder__struct
12435 
12436 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
12437 
12438 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP) || defined(WUFFS_NONMONOLITHIC)
12439 
12440 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH32) || defined(WUFFS_NONMONOLITHIC)
12441 
12442 // ---------------- Status Codes
12443 
12444 // ---------------- Public Consts
12445 
12446 // ---------------- Struct Declarations
12447 
12448 typedef struct wuffs_xxhash32__hasher__struct wuffs_xxhash32__hasher;
12449 
12450 #ifdef __cplusplus
12451 extern "C" {
12452 #endif
12453 
12454 // ---------------- Public Initializer Prototypes
12455 
12456 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
12457 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
12458 //
12459 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
12460 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
12461 
12462 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
12463 wuffs_xxhash32__hasher__initialize(
12464     wuffs_xxhash32__hasher* self,
12465     size_t sizeof_star_self,
12466     uint64_t wuffs_version,
12467     uint32_t options);
12468 
12469 size_t
12470 sizeof__wuffs_xxhash32__hasher(void);
12471 
12472 // ---------------- Allocs
12473 
12474 // These functions allocate and initialize Wuffs structs. They return NULL if
12475 // memory allocation fails. If they return non-NULL, there is no need to call
12476 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
12477 // calling free on the returned pointer. That pointer is effectively a C++
12478 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
12479 
12480 wuffs_xxhash32__hasher*
12481 wuffs_xxhash32__hasher__alloc(void);
12482 
12483 static inline wuffs_base__hasher_u32*
wuffs_xxhash32__hasher__alloc_as__wuffs_base__hasher_u32(void)12484 wuffs_xxhash32__hasher__alloc_as__wuffs_base__hasher_u32(void) {
12485   return (wuffs_base__hasher_u32*)(wuffs_xxhash32__hasher__alloc());
12486 }
12487 
12488 // ---------------- Upcasts
12489 
12490 static inline wuffs_base__hasher_u32*
wuffs_xxhash32__hasher__upcast_as__wuffs_base__hasher_u32(wuffs_xxhash32__hasher * p)12491 wuffs_xxhash32__hasher__upcast_as__wuffs_base__hasher_u32(
12492     wuffs_xxhash32__hasher* p) {
12493   return (wuffs_base__hasher_u32*)p;
12494 }
12495 
12496 // ---------------- Public Function Prototypes
12497 
12498 WUFFS_BASE__GENERATED_C_CODE
12499 WUFFS_BASE__MAYBE_STATIC uint64_t
12500 wuffs_xxhash32__hasher__get_quirk(
12501     const wuffs_xxhash32__hasher* self,
12502     uint32_t a_key);
12503 
12504 WUFFS_BASE__GENERATED_C_CODE
12505 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
12506 wuffs_xxhash32__hasher__set_quirk(
12507     wuffs_xxhash32__hasher* self,
12508     uint32_t a_key,
12509     uint64_t a_value);
12510 
12511 WUFFS_BASE__GENERATED_C_CODE
12512 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
12513 wuffs_xxhash32__hasher__update(
12514     wuffs_xxhash32__hasher* self,
12515     wuffs_base__slice_u8 a_x);
12516 
12517 WUFFS_BASE__GENERATED_C_CODE
12518 WUFFS_BASE__MAYBE_STATIC uint32_t
12519 wuffs_xxhash32__hasher__update_u32(
12520     wuffs_xxhash32__hasher* self,
12521     wuffs_base__slice_u8 a_x);
12522 
12523 WUFFS_BASE__GENERATED_C_CODE
12524 WUFFS_BASE__MAYBE_STATIC uint32_t
12525 wuffs_xxhash32__hasher__checksum_u32(
12526     const wuffs_xxhash32__hasher* self);
12527 
12528 #ifdef __cplusplus
12529 }  // extern "C"
12530 #endif
12531 
12532 // ---------------- Struct Definitions
12533 
12534 // These structs' fields, and the sizeof them, are private implementation
12535 // details that aren't guaranteed to be stable across Wuffs versions.
12536 //
12537 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
12538 
12539 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
12540 
12541 struct wuffs_xxhash32__hasher__struct {
12542   // Do not access the private_impl's or private_data's fields directly. There
12543   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
12544   // the wuffs_foo__bar__baz functions.
12545   //
12546   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
12547   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
12548 
12549   struct {
12550     uint32_t magic;
12551     uint32_t active_coroutine;
12552     wuffs_base__vtable vtable_for__wuffs_base__hasher_u32;
12553     wuffs_base__vtable null_vtable;
12554 
12555     uint32_t f_length_modulo_u32;
12556     bool f_length_overflows_u32;
12557     uint8_t f_padding0;
12558     uint8_t f_padding1;
12559     uint8_t f_buf_len;
12560     uint8_t f_buf_data[16];
12561     uint32_t f_v0;
12562     uint32_t f_v1;
12563     uint32_t f_v2;
12564     uint32_t f_v3;
12565   } private_impl;
12566 
12567 #ifdef __cplusplus
12568 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
12569   using unique_ptr = std::unique_ptr<wuffs_xxhash32__hasher, wuffs_unique_ptr_deleter>;
12570 
12571   // On failure, the alloc_etc functions return nullptr. They don't throw.
12572 
12573   static inline unique_ptr
allocwuffs_xxhash32__hasher__struct12574   alloc() {
12575     return unique_ptr(wuffs_xxhash32__hasher__alloc());
12576   }
12577 
12578   static inline wuffs_base__hasher_u32::unique_ptr
alloc_as__wuffs_base__hasher_u32wuffs_xxhash32__hasher__struct12579   alloc_as__wuffs_base__hasher_u32() {
12580     return wuffs_base__hasher_u32::unique_ptr(
12581         wuffs_xxhash32__hasher__alloc_as__wuffs_base__hasher_u32());
12582   }
12583 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
12584 
12585 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
12586   // Disallow constructing or copying an object via standard C++ mechanisms,
12587   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
12588   // size and field layout is not part of the public, stable, memory-safe API.
12589   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
12590   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
12591   // their first argument) rather than tweaking bar.private_impl.qux fields.
12592   //
12593   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
12594   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
12595   // order to provide convenience methods. These forward on "this", so that you
12596   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
12597   wuffs_xxhash32__hasher__struct() = delete;
12598   wuffs_xxhash32__hasher__struct(const wuffs_xxhash32__hasher__struct&) = delete;
12599   wuffs_xxhash32__hasher__struct& operator=(
12600       const wuffs_xxhash32__hasher__struct&) = delete;
12601 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
12602 
12603 #if !defined(WUFFS_IMPLEMENTATION)
12604   // As above, the size of the struct is not part of the public API, and unless
12605   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
12606   // allocated, not stack allocated. Its size is not intended to be known at
12607   // compile time, but it is unfortunately divulged as a side effect of
12608   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
12609   // instead of "sizeof T", invoking the operator. To make the two values
12610   // different, so that passing the latter will be rejected by the initialize
12611   // function, we add an arbitrary amount of dead weight.
12612   uint8_t dead_weight[123000000];  // 123 MB.
12613 #endif  // !defined(WUFFS_IMPLEMENTATION)
12614 
12615   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_xxhash32__hasher__struct12616   initialize(
12617       size_t sizeof_star_self,
12618       uint64_t wuffs_version,
12619       uint32_t options) {
12620     return wuffs_xxhash32__hasher__initialize(
12621         this, sizeof_star_self, wuffs_version, options);
12622   }
12623 
12624   inline wuffs_base__hasher_u32*
upcast_as__wuffs_base__hasher_u32wuffs_xxhash32__hasher__struct12625   upcast_as__wuffs_base__hasher_u32() {
12626     return (wuffs_base__hasher_u32*)this;
12627   }
12628 
12629   inline uint64_t
get_quirkwuffs_xxhash32__hasher__struct12630   get_quirk(
12631       uint32_t a_key) const {
12632     return wuffs_xxhash32__hasher__get_quirk(this, a_key);
12633   }
12634 
12635   inline wuffs_base__status
set_quirkwuffs_xxhash32__hasher__struct12636   set_quirk(
12637       uint32_t a_key,
12638       uint64_t a_value) {
12639     return wuffs_xxhash32__hasher__set_quirk(this, a_key, a_value);
12640   }
12641 
12642   inline wuffs_base__empty_struct
updatewuffs_xxhash32__hasher__struct12643   update(
12644       wuffs_base__slice_u8 a_x) {
12645     return wuffs_xxhash32__hasher__update(this, a_x);
12646   }
12647 
12648   inline uint32_t
update_u32wuffs_xxhash32__hasher__struct12649   update_u32(
12650       wuffs_base__slice_u8 a_x) {
12651     return wuffs_xxhash32__hasher__update_u32(this, a_x);
12652   }
12653 
12654   inline uint32_t
checksum_u32wuffs_xxhash32__hasher__struct12655   checksum_u32() const {
12656     return wuffs_xxhash32__hasher__checksum_u32(this);
12657   }
12658 
12659 #endif  // __cplusplus
12660 };  // struct wuffs_xxhash32__hasher__struct
12661 
12662 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
12663 
12664 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH32) || defined(WUFFS_NONMONOLITHIC)
12665 
12666 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH64) || defined(WUFFS_NONMONOLITHIC)
12667 
12668 // ---------------- Status Codes
12669 
12670 // ---------------- Public Consts
12671 
12672 // ---------------- Struct Declarations
12673 
12674 typedef struct wuffs_xxhash64__hasher__struct wuffs_xxhash64__hasher;
12675 
12676 #ifdef __cplusplus
12677 extern "C" {
12678 #endif
12679 
12680 // ---------------- Public Initializer Prototypes
12681 
12682 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
12683 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
12684 //
12685 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
12686 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
12687 
12688 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
12689 wuffs_xxhash64__hasher__initialize(
12690     wuffs_xxhash64__hasher* self,
12691     size_t sizeof_star_self,
12692     uint64_t wuffs_version,
12693     uint32_t options);
12694 
12695 size_t
12696 sizeof__wuffs_xxhash64__hasher(void);
12697 
12698 // ---------------- Allocs
12699 
12700 // These functions allocate and initialize Wuffs structs. They return NULL if
12701 // memory allocation fails. If they return non-NULL, there is no need to call
12702 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
12703 // calling free on the returned pointer. That pointer is effectively a C++
12704 // std::unique_ptr<T, wuffs_unique_ptr_deleter>.
12705 
12706 wuffs_xxhash64__hasher*
12707 wuffs_xxhash64__hasher__alloc(void);
12708 
12709 static inline wuffs_base__hasher_u64*
wuffs_xxhash64__hasher__alloc_as__wuffs_base__hasher_u64(void)12710 wuffs_xxhash64__hasher__alloc_as__wuffs_base__hasher_u64(void) {
12711   return (wuffs_base__hasher_u64*)(wuffs_xxhash64__hasher__alloc());
12712 }
12713 
12714 // ---------------- Upcasts
12715 
12716 static inline wuffs_base__hasher_u64*
wuffs_xxhash64__hasher__upcast_as__wuffs_base__hasher_u64(wuffs_xxhash64__hasher * p)12717 wuffs_xxhash64__hasher__upcast_as__wuffs_base__hasher_u64(
12718     wuffs_xxhash64__hasher* p) {
12719   return (wuffs_base__hasher_u64*)p;
12720 }
12721 
12722 // ---------------- Public Function Prototypes
12723 
12724 WUFFS_BASE__GENERATED_C_CODE
12725 WUFFS_BASE__MAYBE_STATIC uint64_t
12726 wuffs_xxhash64__hasher__get_quirk(
12727     const wuffs_xxhash64__hasher* self,
12728     uint32_t a_key);
12729 
12730 WUFFS_BASE__GENERATED_C_CODE
12731 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
12732 wuffs_xxhash64__hasher__set_quirk(
12733     wuffs_xxhash64__hasher* self,
12734     uint32_t a_key,
12735     uint64_t a_value);
12736 
12737 WUFFS_BASE__GENERATED_C_CODE
12738 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
12739 wuffs_xxhash64__hasher__update(
12740     wuffs_xxhash64__hasher* self,
12741     wuffs_base__slice_u8 a_x);
12742 
12743 WUFFS_BASE__GENERATED_C_CODE
12744 WUFFS_BASE__MAYBE_STATIC uint64_t
12745 wuffs_xxhash64__hasher__update_u64(
12746     wuffs_xxhash64__hasher* self,
12747     wuffs_base__slice_u8 a_x);
12748 
12749 WUFFS_BASE__GENERATED_C_CODE
12750 WUFFS_BASE__MAYBE_STATIC uint64_t
12751 wuffs_xxhash64__hasher__checksum_u64(
12752     const wuffs_xxhash64__hasher* self);
12753 
12754 #ifdef __cplusplus
12755 }  // extern "C"
12756 #endif
12757 
12758 // ---------------- Struct Definitions
12759 
12760 // These structs' fields, and the sizeof them, are private implementation
12761 // details that aren't guaranteed to be stable across Wuffs versions.
12762 //
12763 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
12764 
12765 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
12766 
12767 struct wuffs_xxhash64__hasher__struct {
12768   // Do not access the private_impl's or private_data's fields directly. There
12769   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
12770   // the wuffs_foo__bar__baz functions.
12771   //
12772   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
12773   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
12774 
12775   struct {
12776     uint32_t magic;
12777     uint32_t active_coroutine;
12778     wuffs_base__vtable vtable_for__wuffs_base__hasher_u64;
12779     wuffs_base__vtable null_vtable;
12780 
12781     uint64_t f_length_modulo_u64;
12782     bool f_length_overflows_u64;
12783     uint8_t f_padding0;
12784     uint8_t f_padding1;
12785     uint8_t f_padding2;
12786     uint32_t f_buf_len;
12787     uint8_t f_buf_data[32];
12788     uint64_t f_v0;
12789     uint64_t f_v1;
12790     uint64_t f_v2;
12791     uint64_t f_v3;
12792   } private_impl;
12793 
12794 #ifdef __cplusplus
12795 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
12796   using unique_ptr = std::unique_ptr<wuffs_xxhash64__hasher, wuffs_unique_ptr_deleter>;
12797 
12798   // On failure, the alloc_etc functions return nullptr. They don't throw.
12799 
12800   static inline unique_ptr
allocwuffs_xxhash64__hasher__struct12801   alloc() {
12802     return unique_ptr(wuffs_xxhash64__hasher__alloc());
12803   }
12804 
12805   static inline wuffs_base__hasher_u64::unique_ptr
alloc_as__wuffs_base__hasher_u64wuffs_xxhash64__hasher__struct12806   alloc_as__wuffs_base__hasher_u64() {
12807     return wuffs_base__hasher_u64::unique_ptr(
12808         wuffs_xxhash64__hasher__alloc_as__wuffs_base__hasher_u64());
12809   }
12810 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
12811 
12812 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
12813   // Disallow constructing or copying an object via standard C++ mechanisms,
12814   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
12815   // size and field layout is not part of the public, stable, memory-safe API.
12816   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
12817   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
12818   // their first argument) rather than tweaking bar.private_impl.qux fields.
12819   //
12820   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
12821   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
12822   // order to provide convenience methods. These forward on "this", so that you
12823   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
12824   wuffs_xxhash64__hasher__struct() = delete;
12825   wuffs_xxhash64__hasher__struct(const wuffs_xxhash64__hasher__struct&) = delete;
12826   wuffs_xxhash64__hasher__struct& operator=(
12827       const wuffs_xxhash64__hasher__struct&) = delete;
12828 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
12829 
12830 #if !defined(WUFFS_IMPLEMENTATION)
12831   // As above, the size of the struct is not part of the public API, and unless
12832   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
12833   // allocated, not stack allocated. Its size is not intended to be known at
12834   // compile time, but it is unfortunately divulged as a side effect of
12835   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
12836   // instead of "sizeof T", invoking the operator. To make the two values
12837   // different, so that passing the latter will be rejected by the initialize
12838   // function, we add an arbitrary amount of dead weight.
12839   uint8_t dead_weight[123000000];  // 123 MB.
12840 #endif  // !defined(WUFFS_IMPLEMENTATION)
12841 
12842   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_xxhash64__hasher__struct12843   initialize(
12844       size_t sizeof_star_self,
12845       uint64_t wuffs_version,
12846       uint32_t options) {
12847     return wuffs_xxhash64__hasher__initialize(
12848         this, sizeof_star_self, wuffs_version, options);
12849   }
12850 
12851   inline wuffs_base__hasher_u64*
upcast_as__wuffs_base__hasher_u64wuffs_xxhash64__hasher__struct12852   upcast_as__wuffs_base__hasher_u64() {
12853     return (wuffs_base__hasher_u64*)this;
12854   }
12855 
12856   inline uint64_t
get_quirkwuffs_xxhash64__hasher__struct12857   get_quirk(
12858       uint32_t a_key) const {
12859     return wuffs_xxhash64__hasher__get_quirk(this, a_key);
12860   }
12861 
12862   inline wuffs_base__status
set_quirkwuffs_xxhash64__hasher__struct12863   set_quirk(
12864       uint32_t a_key,
12865       uint64_t a_value) {
12866     return wuffs_xxhash64__hasher__set_quirk(this, a_key, a_value);
12867   }
12868 
12869   inline wuffs_base__empty_struct
updatewuffs_xxhash64__hasher__struct12870   update(
12871       wuffs_base__slice_u8 a_x) {
12872     return wuffs_xxhash64__hasher__update(this, a_x);
12873   }
12874 
12875   inline uint64_t
update_u64wuffs_xxhash64__hasher__struct12876   update_u64(
12877       wuffs_base__slice_u8 a_x) {
12878     return wuffs_xxhash64__hasher__update_u64(this, a_x);
12879   }
12880 
12881   inline uint64_t
checksum_u64wuffs_xxhash64__hasher__struct12882   checksum_u64() const {
12883     return wuffs_xxhash64__hasher__checksum_u64(this);
12884   }
12885 
12886 #endif  // __cplusplus
12887 };  // struct wuffs_xxhash64__hasher__struct
12888 
12889 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
12890 
12891 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH64) || defined(WUFFS_NONMONOLITHIC)
12892 
12893 #if defined(__cplusplus) && defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
12894 
12895 // ---------------- Auxiliary - Base
12896 
12897 // Auxiliary code is discussed at
12898 // https://github.com/google/wuffs/blob/main/doc/note/auxiliary-code.md
12899 
12900 #include <stdio.h>
12901 
12902 #include <string>
12903 
12904 namespace wuffs_aux {
12905 
12906 using IOBuffer = wuffs_base__io_buffer;
12907 
12908 // MemOwner represents ownership of some memory. Dynamically allocated memory
12909 // (e.g. from malloc or new) is typically paired with free or delete, invoked
12910 // when the std::unique_ptr is destroyed. Statically allocated memory might use
12911 // MemOwner(nullptr, &free), even if that statically allocated memory is not
12912 // nullptr, since calling free(nullptr) is a no-op.
12913 using MemOwner = std::unique_ptr<void, decltype(&free)>;
12914 
12915 namespace sync_io {
12916 
12917 // --------
12918 
12919 // DynIOBuffer is an IOBuffer that is backed by a dynamically sized byte array.
12920 // It owns that backing array and will free it in its destructor.
12921 //
12922 // The array size can be explicitly extended (by calling the grow method) but,
12923 // unlike a C++ std::vector, there is no implicit extension (e.g. by calling
12924 // std::vector::insert) and its maximum size is capped by the max_incl
12925 // constructor argument.
12926 //
12927 // It contains an IOBuffer-typed field whose reader side provides access to
12928 // previously written bytes and whose writer side provides access to the
12929 // allocated but not-yet-written-to slack space. For Go programmers, this slack
12930 // space is roughly analogous to the s[len(s):cap(s)] space of a slice s.
12931 class DynIOBuffer {
12932  public:
12933   enum GrowResult {
12934     OK = 0,
12935     FailedMaxInclExceeded = 1,
12936     FailedOutOfMemory = 2,
12937   };
12938 
12939   // m_buf holds the dynamically sized byte array and its read/write indexes:
12940   //  - m_buf.meta.wi  is roughly analogous to a Go slice's length.
12941   //  - m_buf.data.len is roughly analogous to a Go slice's capacity. It is
12942   //    also equal to the m_buf.data.ptr malloc/realloc size.
12943   //
12944   // Users should not modify the m_buf.data.ptr or m_buf.data.len fields (as
12945   // they are conceptually private to this class), but they can modify the
12946   // bytes referenced by that pointer-length pair (e.g. compactions).
12947   IOBuffer m_buf;
12948 
12949   // m_max_incl is an inclusive upper bound on the backing array size.
12950   const uint64_t m_max_incl;
12951 
12952   // Constructor and destructor.
12953   explicit DynIOBuffer(uint64_t max_incl);
12954   ~DynIOBuffer();
12955 
12956   // Drop frees the byte array and resets m_buf. The DynIOBuffer can still be
12957   // used after a drop call. It just restarts from zero.
12958   void drop();
12959 
12960   // grow ensures that the byte array size is at least min_incl and at most
12961   // max_incl. It returns FailedMaxInclExceeded if that would require
12962   // allocating more than max_incl bytes, including the case where (min_incl >
12963   // max_incl). It returns FailedOutOfMemory if memory allocation failed.
12964   GrowResult grow(uint64_t min_incl);
12965 
12966  private:
12967   // Delete the copy and assign constructors.
12968   DynIOBuffer(const DynIOBuffer&) = delete;
12969   DynIOBuffer& operator=(const DynIOBuffer&) = delete;
12970 
12971   static uint64_t round_up(uint64_t min_incl, uint64_t max_incl);
12972 };
12973 
12974 // --------
12975 
12976 class Input {
12977  public:
12978   virtual ~Input();
12979 
12980   virtual IOBuffer* BringsItsOwnIOBuffer();
12981   virtual std::string CopyIn(IOBuffer* dst, uint64_t history_retain_length) = 0;
12982 };
12983 
12984 // --------
12985 
12986 // FileInput is an Input that reads from a file source.
12987 //
12988 // It does not take responsibility for closing the file when done.
12989 class FileInput : public Input {
12990  public:
12991   FileInput(FILE* f);
12992 
12993   virtual std::string CopyIn(IOBuffer* dst, uint64_t history_retain_length);
12994 
12995  private:
12996   FILE* m_f;
12997 
12998   // Delete the copy and assign constructors.
12999   FileInput(const FileInput&) = delete;
13000   FileInput& operator=(const FileInput&) = delete;
13001 };
13002 
13003 // --------
13004 
13005 // MemoryInput is an Input that reads from an in-memory source.
13006 //
13007 // It does not take responsibility for freeing the memory when done.
13008 class MemoryInput : public Input {
13009  public:
13010   MemoryInput(const char* ptr, size_t len);
13011   MemoryInput(const uint8_t* ptr, size_t len);
13012 
13013   virtual IOBuffer* BringsItsOwnIOBuffer();
13014   virtual std::string CopyIn(IOBuffer* dst, uint64_t history_retain_length);
13015 
13016  private:
13017   IOBuffer m_io;
13018 
13019   // Delete the copy and assign constructors.
13020   MemoryInput(const MemoryInput&) = delete;
13021   MemoryInput& operator=(const MemoryInput&) = delete;
13022 };
13023 
13024 // --------
13025 
13026 }  // namespace sync_io
13027 
13028 }  // namespace wuffs_aux
13029 
13030 // ---------------- Auxiliary - CBOR
13031 
13032 namespace wuffs_aux {
13033 
13034 struct DecodeCborResult {
13035   DecodeCborResult(std::string&& error_message0, uint64_t cursor_position0);
13036 
13037   std::string error_message;
13038   uint64_t cursor_position;
13039 };
13040 
13041 class DecodeCborCallbacks {
13042  public:
13043   virtual ~DecodeCborCallbacks();
13044 
13045   // AppendXxx are called for leaf nodes: literals, numbers, strings, etc.
13046 
13047   virtual std::string AppendNull() = 0;
13048   virtual std::string AppendUndefined() = 0;
13049   virtual std::string AppendBool(bool val) = 0;
13050   virtual std::string AppendF64(double val) = 0;
13051   virtual std::string AppendI64(int64_t val) = 0;
13052   virtual std::string AppendU64(uint64_t val) = 0;
13053   virtual std::string AppendByteString(std::string&& val) = 0;
13054   virtual std::string AppendTextString(std::string&& val) = 0;
13055   virtual std::string AppendMinus1MinusX(uint64_t val) = 0;
13056   virtual std::string AppendCborSimpleValue(uint8_t val) = 0;
13057   virtual std::string AppendCborTag(uint64_t val) = 0;
13058 
13059   // Push and Pop are called for container nodes: CBOR arrays (lists) and CBOR
13060   // maps (dictionaries).
13061   //
13062   // The flags bits combine exactly one of:
13063   //  - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_NONE
13064   //  - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_LIST
13065   //  - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_DICT
13066   // and exactly one of:
13067   //  - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_NONE
13068   //  - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_LIST
13069   //  - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_DICT
13070 
13071   virtual std::string Push(uint32_t flags) = 0;
13072   virtual std::string Pop(uint32_t flags) = 0;
13073 
13074   // Done is always the last Callback method called by DecodeCbor, whether or
13075   // not parsing the input as CBOR encountered an error. Even when successful,
13076   // trailing data may remain in input and buffer.
13077   //
13078   // Do not keep a reference to buffer or buffer.data.ptr after Done returns,
13079   // as DecodeCbor may then de-allocate the backing array.
13080   //
13081   // The default Done implementation is a no-op.
13082   virtual void  //
13083   Done(DecodeCborResult& result, sync_io::Input& input, IOBuffer& buffer);
13084 };
13085 
13086 // The FooArgBar types add structure to Foo's optional arguments. They wrap
13087 // inner representations for several reasons:
13088 //  - It provides a home for the DefaultValue static method, for Foo callers
13089 //    that want to override some but not all optional arguments.
13090 //  - It provides the "Bar" name at Foo call sites, which can help self-
13091 //    document Foo calls with many arguemnts.
13092 //  - It provides some type safety against accidentally transposing or omitting
13093 //    adjacent fundamentally-numeric-typed optional arguments.
13094 
13095 // DecodeCborArgQuirks wraps an optional argument to DecodeCbor.
13096 struct DecodeCborArgQuirks {
13097   explicit DecodeCborArgQuirks(wuffs_base__slice_u32 repr0);
13098   explicit DecodeCborArgQuirks(uint32_t* ptr, size_t len);
13099 
13100   // DefaultValue returns an empty slice.
13101   static DecodeCborArgQuirks DefaultValue();
13102 
13103   wuffs_base__slice_u32 repr;
13104 };
13105 
13106 // DecodeCbor calls callbacks based on the CBOR-formatted data in input.
13107 //
13108 // On success, the returned error_message is empty and cursor_position counts
13109 // the number of bytes consumed. On failure, error_message is non-empty and
13110 // cursor_position is the location of the error. That error may be a content
13111 // error (invalid CBOR) or an input error (e.g. network failure).
13112 DecodeCborResult  //
13113 DecodeCbor(DecodeCborCallbacks& callbacks,
13114            sync_io::Input& input,
13115            DecodeCborArgQuirks quirks = DecodeCborArgQuirks::DefaultValue());
13116 
13117 }  // namespace wuffs_aux
13118 
13119 // ---------------- Auxiliary - Image
13120 
13121 namespace wuffs_aux {
13122 
13123 struct DecodeImageResult {
13124   DecodeImageResult(MemOwner&& pixbuf_mem_owner0,
13125                     wuffs_base__pixel_buffer pixbuf0,
13126                     std::string&& error_message0);
13127   DecodeImageResult(std::string&& error_message0);
13128 
13129   MemOwner pixbuf_mem_owner;
13130   wuffs_base__pixel_buffer pixbuf;
13131   std::string error_message;
13132 };
13133 
13134 // DecodeImageCallbacks are the callbacks given to DecodeImage. They are always
13135 // called in this order:
13136 //  1. SelectDecoder
13137 //  2. HandleMetadata
13138 //  3. SelectPixfmt
13139 //  4. AllocPixbuf
13140 //  5. AllocWorkbuf
13141 //  6. Done
13142 //
13143 // It may return early - the third callback might not be invoked if the second
13144 // one fails - but the final callback (Done) is always invoked.
13145 class DecodeImageCallbacks {
13146  public:
13147   // AllocPixbufResult holds a memory allocation (the result of malloc or new,
13148   // a statically allocated pointer, etc), or an error message. The memory is
13149   // de-allocated when mem_owner goes out of scope and is destroyed.
13150   struct AllocPixbufResult {
13151     AllocPixbufResult(MemOwner&& mem_owner0, wuffs_base__pixel_buffer pixbuf0);
13152     AllocPixbufResult(std::string&& error_message0);
13153 
13154     MemOwner mem_owner;
13155     wuffs_base__pixel_buffer pixbuf;
13156     std::string error_message;
13157   };
13158 
13159   // AllocWorkbufResult holds a memory allocation (the result of malloc or new,
13160   // a statically allocated pointer, etc), or an error message. The memory is
13161   // de-allocated when mem_owner goes out of scope and is destroyed.
13162   struct AllocWorkbufResult {
13163     AllocWorkbufResult(MemOwner&& mem_owner0, wuffs_base__slice_u8 workbuf0);
13164     AllocWorkbufResult(std::string&& error_message0);
13165 
13166     MemOwner mem_owner;
13167     wuffs_base__slice_u8 workbuf;
13168     std::string error_message;
13169   };
13170 
13171   virtual ~DecodeImageCallbacks();
13172 
13173   // SelectDecoder returns the image decoder for the input data's file format.
13174   // Returning a nullptr means failure (DecodeImage_UnsupportedImageFormat).
13175   //
13176   // Common formats will have a FourCC value in the range [1 ..= 0x7FFF_FFFF],
13177   // such as WUFFS_BASE__FOURCC__JPEG. A zero FourCC value means that Wuffs'
13178   // standard library did not recognize the image format but if SelectDecoder
13179   // was overridden, it may examine the input data's starting bytes and still
13180   // provide its own image decoder, e.g. for an exotic image file format that's
13181   // not in Wuffs' standard library. The prefix_etc fields have the same
13182   // meaning as wuffs_base__magic_number_guess_fourcc arguments. SelectDecoder
13183   // implementations should not modify prefix_data's contents.
13184   //
13185   // SelectDecoder might be called more than once, since some image file
13186   // formats can wrap others. For example, a nominal BMP file can actually
13187   // contain a JPEG or a PNG.
13188   //
13189   // The default SelectDecoder accepts the FOURCC codes listed below. For
13190   // modular builds (i.e. when #define'ing WUFFS_CONFIG__MODULES), acceptance
13191   // of the ETC file format is optional (for each value of ETC) and depends on
13192   // the corresponding module to be enabled at compile time (i.e. #define'ing
13193   // WUFFS_CONFIG__MODULE__ETC).
13194   //  - WUFFS_BASE__FOURCC__BMP
13195   //  - WUFFS_BASE__FOURCC__GIF
13196   //  - WUFFS_BASE__FOURCC__JPEG
13197   //  - WUFFS_BASE__FOURCC__NIE
13198   //  - WUFFS_BASE__FOURCC__NPBM
13199   //  - WUFFS_BASE__FOURCC__PNG
13200   //  - WUFFS_BASE__FOURCC__TGA
13201   //  - WUFFS_BASE__FOURCC__WBMP
13202   virtual wuffs_base__image_decoder::unique_ptr  //
13203   SelectDecoder(uint32_t fourcc,
13204                 wuffs_base__slice_u8 prefix_data,
13205                 bool prefix_closed);
13206 
13207   // HandleMetadata acknowledges image metadata. minfo.flavor will be one of:
13208   //  - WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_RAW_PASSTHROUGH
13209   //  - WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_PARSED
13210   // If it is ETC__METADATA_RAW_ETC then raw contains the metadata bytes. Those
13211   // bytes should not be retained beyond the the HandleMetadata call.
13212   //
13213   // minfo.metadata__fourcc() will typically match one of the
13214   // DecodeImageArgFlags bits. For example, if (REPORT_METADATA_CHRM |
13215   // REPORT_METADATA_GAMA) was passed to DecodeImage then the metadata FourCC
13216   // will be either WUFFS_BASE__FOURCC__CHRM or WUFFS_BASE__FOURCC__GAMA.
13217   //
13218   // It returns an error message, or an empty string on success.
13219   virtual std::string  //
13220   HandleMetadata(const wuffs_base__more_information& minfo,
13221                  wuffs_base__slice_u8 raw);
13222 
13223   // SelectPixfmt returns the destination pixel format for AllocPixbuf. It
13224   // should return wuffs_base__make_pixel_format(etc) called with one of:
13225   //  - WUFFS_BASE__PIXEL_FORMAT__BGR_565
13226   //  - WUFFS_BASE__PIXEL_FORMAT__BGR
13227   //  - WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL
13228   //  - WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE
13229   //  - WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL
13230   //  - WUFFS_BASE__PIXEL_FORMAT__RGB
13231   //  - WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL
13232   //  - WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL
13233   // or return image_config.pixcfg.pixel_format(). The latter means to use the
13234   // image file's natural pixel format. For example, GIF images' natural pixel
13235   // format is an indexed one.
13236   //
13237   // Returning otherwise means failure (DecodeImage_UnsupportedPixelFormat).
13238   //
13239   // The default SelectPixfmt implementation returns
13240   // wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL) which
13241   // is 4 bytes per pixel (8 bits per channel × 4 channels).
13242   virtual wuffs_base__pixel_format  //
13243   SelectPixfmt(const wuffs_base__image_config& image_config);
13244 
13245   // AllocPixbuf allocates the pixel buffer.
13246   //
13247   // allow_uninitialized_memory will be true if a valid background_color was
13248   // passed to DecodeImage, since the pixel buffer's contents will be
13249   // overwritten with that color after AllocPixbuf returns.
13250   //
13251   // The default AllocPixbuf implementation allocates either uninitialized or
13252   // zeroed memory. Zeroed memory typically corresponds to filling with opaque
13253   // black or transparent black, depending on the pixel format.
13254   virtual AllocPixbufResult  //
13255   AllocPixbuf(const wuffs_base__image_config& image_config,
13256               bool allow_uninitialized_memory);
13257 
13258   // AllocWorkbuf allocates the work buffer. The allocated buffer's length
13259   // should be at least len_range.min_incl, but larger allocations (up to
13260   // len_range.max_incl) may have better performance (by using more memory).
13261   //
13262   // The default AllocWorkbuf implementation allocates len_range.max_incl bytes
13263   // of either uninitialized or zeroed memory.
13264   virtual AllocWorkbufResult  //
13265   AllocWorkbuf(wuffs_base__range_ii_u64 len_range,
13266                bool allow_uninitialized_memory);
13267 
13268   // Done is always the last Callback method called by DecodeImage, whether or
13269   // not parsing the input encountered an error. Even when successful, trailing
13270   // data may remain in input and buffer.
13271   //
13272   // The image_decoder is the one returned by SelectDecoder (if SelectDecoder
13273   // was successful), or a no-op unique_ptr otherwise. Like any unique_ptr,
13274   // ownership moves to the Done implementation.
13275   //
13276   // Do not keep a reference to buffer or buffer.data.ptr after Done returns,
13277   // as DecodeImage may then de-allocate the backing array.
13278   //
13279   // The default Done implementation is a no-op, other than running the
13280   // image_decoder unique_ptr destructor.
13281   virtual void  //
13282   Done(DecodeImageResult& result,
13283        sync_io::Input& input,
13284        IOBuffer& buffer,
13285        wuffs_base__image_decoder::unique_ptr image_decoder);
13286 };
13287 
13288 extern const char DecodeImage_BufferIsTooShort[];
13289 extern const char DecodeImage_MaxInclDimensionExceeded[];
13290 extern const char DecodeImage_MaxInclMetadataLengthExceeded[];
13291 extern const char DecodeImage_OutOfMemory[];
13292 extern const char DecodeImage_UnexpectedEndOfFile[];
13293 extern const char DecodeImage_UnsupportedImageFormat[];
13294 extern const char DecodeImage_UnsupportedMetadata[];
13295 extern const char DecodeImage_UnsupportedPixelBlend[];
13296 extern const char DecodeImage_UnsupportedPixelConfiguration[];
13297 extern const char DecodeImage_UnsupportedPixelFormat[];
13298 
13299 // The FooArgBar types add structure to Foo's optional arguments. They wrap
13300 // inner representations for several reasons:
13301 //  - It provides a home for the DefaultValue static method, for Foo callers
13302 //    that want to override some but not all optional arguments.
13303 //  - It provides the "Bar" name at Foo call sites, which can help self-
13304 //    document Foo calls with many arguemnts.
13305 //  - It provides some type safety against accidentally transposing or omitting
13306 //    adjacent fundamentally-numeric-typed optional arguments.
13307 
13308 // DecodeImageArgQuirks wraps an optional argument to DecodeImage.
13309 struct DecodeImageArgQuirks {
13310   explicit DecodeImageArgQuirks(wuffs_base__slice_u32 repr0);
13311   explicit DecodeImageArgQuirks(uint32_t* ptr, size_t len);
13312 
13313   // DefaultValue returns an empty slice.
13314   static DecodeImageArgQuirks DefaultValue();
13315 
13316   wuffs_base__slice_u32 repr;
13317 };
13318 
13319 // DecodeImageArgFlags wraps an optional argument to DecodeImage.
13320 struct DecodeImageArgFlags {
13321   explicit DecodeImageArgFlags(uint64_t repr0);
13322 
13323   // DefaultValue returns 0.
13324   static DecodeImageArgFlags DefaultValue();
13325 
13326   // TODO: support all of the REPORT_METADATA_ETC flags, not just CHRM, EXIF,
13327   // GAMA, ICCP, KVP, SRGB and XMP.
13328 
13329   // Background Color.
13330   static constexpr uint64_t REPORT_METADATA_BGCL = 0x0001;
13331   // Primary Chromaticities and White Point.
13332   static constexpr uint64_t REPORT_METADATA_CHRM = 0x0002;
13333   // Exchangeable Image File Format.
13334   static constexpr uint64_t REPORT_METADATA_EXIF = 0x0004;
13335   // Gamma Correction.
13336   static constexpr uint64_t REPORT_METADATA_GAMA = 0x0008;
13337   // International Color Consortium Profile.
13338   static constexpr uint64_t REPORT_METADATA_ICCP = 0x0010;
13339   // Key-Value Pair.
13340   //
13341   // For PNG files, this includes iTXt, tEXt and zTXt chunks. In the
13342   // HandleMetadata callback, the raw argument contains UTF-8 strings.
13343   static constexpr uint64_t REPORT_METADATA_KVP = 0x0020;
13344   // Modification Time.
13345   static constexpr uint64_t REPORT_METADATA_MTIM = 0x0040;
13346   // Offset (2-Dimensional).
13347   static constexpr uint64_t REPORT_METADATA_OFS2 = 0x0080;
13348   // Physical Dimensions.
13349   static constexpr uint64_t REPORT_METADATA_PHYD = 0x0100;
13350   // Standard Red Green Blue (Rendering Intent).
13351   static constexpr uint64_t REPORT_METADATA_SRGB = 0x0200;
13352   // Extensible Metadata Platform.
13353   static constexpr uint64_t REPORT_METADATA_XMP = 0x0400;
13354 
13355   uint64_t repr;
13356 };
13357 
13358 // DecodeImageArgPixelBlend wraps an optional argument to DecodeImage.
13359 struct DecodeImageArgPixelBlend {
13360   explicit DecodeImageArgPixelBlend(wuffs_base__pixel_blend repr0);
13361 
13362   // DefaultValue returns WUFFS_BASE__PIXEL_BLEND__SRC.
13363   static DecodeImageArgPixelBlend DefaultValue();
13364 
13365   wuffs_base__pixel_blend repr;
13366 };
13367 
13368 // DecodeImageArgBackgroundColor wraps an optional argument to DecodeImage.
13369 struct DecodeImageArgBackgroundColor {
13370   explicit DecodeImageArgBackgroundColor(
13371       wuffs_base__color_u32_argb_premul repr0);
13372 
13373   // DefaultValue returns 1, an invalid wuffs_base__color_u32_argb_premul.
13374   static DecodeImageArgBackgroundColor DefaultValue();
13375 
13376   wuffs_base__color_u32_argb_premul repr;
13377 };
13378 
13379 // DecodeImageArgMaxInclDimension wraps an optional argument to DecodeImage.
13380 struct DecodeImageArgMaxInclDimension {
13381   explicit DecodeImageArgMaxInclDimension(uint32_t repr0);
13382 
13383   // DefaultValue returns 1048575 = 0x000F_FFFF, more than 1 million pixels.
13384   static DecodeImageArgMaxInclDimension DefaultValue();
13385 
13386   uint32_t repr;
13387 };
13388 
13389 // DecodeImageArgMaxInclMetadataLength wraps an optional argument to
13390 // DecodeImage.
13391 struct DecodeImageArgMaxInclMetadataLength {
13392   explicit DecodeImageArgMaxInclMetadataLength(uint64_t repr0);
13393 
13394   // DefaultValue returns 16777215 = 0x00FF_FFFF, one less than 16 MiB.
13395   static DecodeImageArgMaxInclMetadataLength DefaultValue();
13396 
13397   uint64_t repr;
13398 };
13399 
13400 // DecodeImage decodes the image data in input. A variety of image file formats
13401 // can be decoded, depending on what callbacks.SelectDecoder returns.
13402 //
13403 // For animated formats, only the first frame is returned, since the API is
13404 // simpler for synchronous I/O and having DecodeImage only return when
13405 // completely done, but rendering animation often involves handling other
13406 // events in between animation frames. To decode multiple frames of animated
13407 // images, or for asynchronous I/O (e.g. when decoding an image streamed over
13408 // the network), use Wuffs' lower level C API instead of its higher level,
13409 // simplified C++ API (the wuffs_aux API).
13410 //
13411 // The DecodeImageResult's fields depend on whether decoding succeeded:
13412 //  - On total success, the error_message is empty and pixbuf.pixcfg.is_valid()
13413 //    is true.
13414 //  - On partial success (e.g. the input file was truncated but we are still
13415 //    able to decode some of the pixels), error_message is non-empty but
13416 //    pixbuf.pixcfg.is_valid() is still true. It is up to the caller whether to
13417 //    accept or reject partial success.
13418 //  - On failure, the error_message is non_empty and pixbuf.pixcfg.is_valid()
13419 //    is false.
13420 //
13421 // The callbacks allocate the pixel buffer memory and work buffer memory. On
13422 // success, pixel buffer memory ownership is passed to the DecodeImage caller
13423 // as the returned pixbuf_mem_owner. Regardless of success or failure, the work
13424 // buffer memory is deleted.
13425 //
13426 // The pixel_blend (one of the constants listed below) determines how to
13427 // composite the decoded image over the pixel buffer's original pixels (as
13428 // returned by callbacks.AllocPixbuf):
13429 //  - WUFFS_BASE__PIXEL_BLEND__SRC
13430 //  - WUFFS_BASE__PIXEL_BLEND__SRC_OVER
13431 //
13432 // The background_color is used to fill the pixel buffer after
13433 // callbacks.AllocPixbuf returns, if it is valid in the
13434 // wuffs_base__color_u32_argb_premul__is_valid sense. The default value,
13435 // 0x0000_0001, is not valid since its Blue channel value (0x01) is greater
13436 // than its Alpha channel value (0x00). A valid background_color will typically
13437 // be overwritten when pixel_blend is WUFFS_BASE__PIXEL_BLEND__SRC, but might
13438 // still be visible on partial (not total) success or when pixel_blend is
13439 // WUFFS_BASE__PIXEL_BLEND__SRC_OVER and the decoded image is not fully opaque.
13440 //
13441 // Decoding fails (with DecodeImage_MaxInclDimensionExceeded) if the image's
13442 // width or height is greater than max_incl_dimension or if any opted-in (via
13443 // flags bits) metadata is longer than max_incl_metadata_length.
13444 DecodeImageResult  //
13445 DecodeImage(DecodeImageCallbacks& callbacks,
13446             sync_io::Input& input,
13447             DecodeImageArgQuirks quirks = DecodeImageArgQuirks::DefaultValue(),
13448             DecodeImageArgFlags flags = DecodeImageArgFlags::DefaultValue(),
13449             DecodeImageArgPixelBlend pixel_blend =
13450                 DecodeImageArgPixelBlend::DefaultValue(),
13451             DecodeImageArgBackgroundColor background_color =
13452                 DecodeImageArgBackgroundColor::DefaultValue(),
13453             DecodeImageArgMaxInclDimension max_incl_dimension =
13454                 DecodeImageArgMaxInclDimension::DefaultValue(),
13455             DecodeImageArgMaxInclMetadataLength max_incl_metadata_length =
13456                 DecodeImageArgMaxInclMetadataLength::DefaultValue());
13457 
13458 }  // namespace wuffs_aux
13459 
13460 // ---------------- Auxiliary - JSON
13461 
13462 namespace wuffs_aux {
13463 
13464 struct DecodeJsonResult {
13465   DecodeJsonResult(std::string&& error_message0, uint64_t cursor_position0);
13466 
13467   std::string error_message;
13468   uint64_t cursor_position;
13469 };
13470 
13471 class DecodeJsonCallbacks {
13472  public:
13473   virtual ~DecodeJsonCallbacks();
13474 
13475   // AppendXxx are called for leaf nodes: literals, numbers and strings. For
13476   // strings, the Callbacks implementation is responsible for tracking map keys
13477   // versus other values.
13478 
13479   virtual std::string AppendNull() = 0;
13480   virtual std::string AppendBool(bool val) = 0;
13481   virtual std::string AppendF64(double val) = 0;
13482   virtual std::string AppendI64(int64_t val) = 0;
13483   virtual std::string AppendTextString(std::string&& val) = 0;
13484 
13485   // Push and Pop are called for container nodes: JSON arrays (lists) and JSON
13486   // objects (dictionaries).
13487   //
13488   // The flags bits combine exactly one of:
13489   //  - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_NONE
13490   //  - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_LIST
13491   //  - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_DICT
13492   // and exactly one of:
13493   //  - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_NONE
13494   //  - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_LIST
13495   //  - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_DICT
13496 
13497   virtual std::string Push(uint32_t flags) = 0;
13498   virtual std::string Pop(uint32_t flags) = 0;
13499 
13500   // Done is always the last Callback method called by DecodeJson, whether or
13501   // not parsing the input as JSON encountered an error. Even when successful,
13502   // trailing data may remain in input and buffer. See "Unintuitive JSON
13503   // Parsing" (https://nullprogram.com/blog/2019/12/28/) which discusses JSON
13504   // parsing and when it stops.
13505   //
13506   // Do not keep a reference to buffer or buffer.data.ptr after Done returns,
13507   // as DecodeJson may then de-allocate the backing array.
13508   //
13509   // The default Done implementation is a no-op.
13510   virtual void  //
13511   Done(DecodeJsonResult& result, sync_io::Input& input, IOBuffer& buffer);
13512 };
13513 
13514 extern const char DecodeJson_BadJsonPointer[];
13515 extern const char DecodeJson_NoMatch[];
13516 
13517 // The FooArgBar types add structure to Foo's optional arguments. They wrap
13518 // inner representations for several reasons:
13519 //  - It provides a home for the DefaultValue static method, for Foo callers
13520 //    that want to override some but not all optional arguments.
13521 //  - It provides the "Bar" name at Foo call sites, which can help self-
13522 //    document Foo calls with many arguemnts.
13523 //  - It provides some type safety against accidentally transposing or omitting
13524 //    adjacent fundamentally-numeric-typed optional arguments.
13525 
13526 // DecodeJsonArgQuirks wraps an optional argument to DecodeJson.
13527 struct DecodeJsonArgQuirks {
13528   explicit DecodeJsonArgQuirks(wuffs_base__slice_u32 repr0);
13529   explicit DecodeJsonArgQuirks(uint32_t* ptr, size_t len);
13530 
13531   // DefaultValue returns an empty slice.
13532   static DecodeJsonArgQuirks DefaultValue();
13533 
13534   wuffs_base__slice_u32 repr;
13535 };
13536 
13537 // DecodeJsonArgJsonPointer wraps an optional argument to DecodeJson.
13538 struct DecodeJsonArgJsonPointer {
13539   explicit DecodeJsonArgJsonPointer(std::string repr0);
13540 
13541   // DefaultValue returns an empty string.
13542   static DecodeJsonArgJsonPointer DefaultValue();
13543 
13544   std::string repr;
13545 };
13546 
13547 // DecodeJson calls callbacks based on the JSON-formatted data in input.
13548 //
13549 // On success, the returned error_message is empty and cursor_position counts
13550 // the number of bytes consumed. On failure, error_message is non-empty and
13551 // cursor_position is the location of the error. That error may be a content
13552 // error (invalid JSON) or an input error (e.g. network failure).
13553 //
13554 // json_pointer is a query in the JSON Pointer (RFC 6901) syntax. The callbacks
13555 // run for the input's sub-node that matches the query. DecodeJson_NoMatch is
13556 // returned if no matching sub-node was found. The empty query matches the
13557 // input's root node, consistent with JSON Pointer semantics.
13558 //
13559 // The JSON Pointer implementation is greedy: duplicate keys are not rejected
13560 // but only the first match for each '/'-separated fragment is followed.
13561 DecodeJsonResult  //
13562 DecodeJson(DecodeJsonCallbacks& callbacks,
13563            sync_io::Input& input,
13564            DecodeJsonArgQuirks quirks = DecodeJsonArgQuirks::DefaultValue(),
13565            DecodeJsonArgJsonPointer json_pointer =
13566                DecodeJsonArgJsonPointer::DefaultValue());
13567 
13568 }  // namespace wuffs_aux
13569 
13570 #endif  // defined(__cplusplus) && defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
13571 
13572 // ‼ WUFFS C HEADER ENDS HERE.
13573 #ifdef WUFFS_IMPLEMENTATION
13574 
13575 #ifdef __cplusplus
13576 extern "C" {
13577 #endif
13578 
13579 // ---------------- Fundamentals
13580 
13581 // WUFFS_BASE__MAGIC is a magic number to check that initializers are called.
13582 // It's not foolproof, given C doesn't automatically zero memory before use,
13583 // but it should catch 99.99% of cases.
13584 //
13585 // Its (non-zero) value is arbitrary, based on md5sum("wuffs").
13586 #define WUFFS_BASE__MAGIC ((uint32_t)0x3CCB6C71)
13587 
13588 // WUFFS_BASE__DISABLED is a magic number to indicate that a non-recoverable
13589 // error was previously encountered.
13590 //
13591 // Its (non-zero) value is arbitrary, based on md5sum("disabled").
13592 #define WUFFS_BASE__DISABLED ((uint32_t)0x075AE3D2)
13593 
13594 // Use switch cases for coroutine suspension points, similar to the technique
13595 // in https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
13596 //
13597 // The implicit fallthrough is intentional.
13598 //
13599 // We use trivial macros instead of an explicit assignment and case statement
13600 // so that clang-format doesn't get confused by the unusual "case"s.
13601 #define WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0 case 0:;
13602 #define WUFFS_BASE__COROUTINE_SUSPENSION_POINT(n) \
13603   coro_susp_point = n;                            \
13604   case n:;
13605 
13606 #define WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(n) \
13607   if (!status.repr) {                                           \
13608     goto ok;                                                    \
13609   } else if (*status.repr != '$') {                             \
13610     goto exit;                                                  \
13611   }                                                             \
13612   coro_susp_point = n;                                          \
13613   goto suspend;                                                 \
13614   case n:;
13615 
13616 // The "defined(__clang__)" isn't redundant. While vanilla clang defines
13617 // __GNUC__, clang-cl (which mimics MSVC's cl.exe) does not.
13618 #if defined(__GNUC__) || defined(__clang__)
13619 #define WUFFS_BASE__LIKELY(expr) (__builtin_expect(!!(expr), 1))
13620 #define WUFFS_BASE__UNLIKELY(expr) (__builtin_expect(!!(expr), 0))
13621 #else
13622 #define WUFFS_BASE__LIKELY(expr) (expr)
13623 #define WUFFS_BASE__UNLIKELY(expr) (expr)
13624 #endif
13625 
13626 // --------
13627 
13628 #if defined(__GNUC__)
13629 #pragma GCC diagnostic push
13630 #pragma GCC diagnostic ignored "-Wcast-qual"
13631 #endif
13632 static inline uint8_t*  //
wuffs_base__strip_const_from_u8_ptr(const uint8_t * ptr)13633 wuffs_base__strip_const_from_u8_ptr(const uint8_t* ptr) {
13634   return (uint8_t*)ptr;
13635 }
13636 #if defined(__GNUC__)
13637 #pragma GCC diagnostic pop
13638 #endif
13639 
13640 // --------
13641 
13642 static inline wuffs_base__empty_struct  //
wuffs_base__ignore_status(wuffs_base__status z)13643 wuffs_base__ignore_status(wuffs_base__status z) {
13644   return wuffs_base__make_empty_struct();
13645 }
13646 
13647 static inline wuffs_base__status  //
wuffs_base__status__ensure_not_a_suspension(wuffs_base__status z)13648 wuffs_base__status__ensure_not_a_suspension(wuffs_base__status z) {
13649   if (z.repr && (*z.repr == '$')) {
13650     z.repr = wuffs_base__error__cannot_return_a_suspension;
13651   }
13652   return z;
13653 }
13654 
13655 // --------
13656 
13657 // wuffs_base__iterate_total_advance returns the exclusive pointer-offset at
13658 // which iteration should stop. The overall slice has length total_len, each
13659 // iteration's sub-slice has length iter_len and are placed iter_advance apart.
13660 //
13661 // The iter_advance may not be larger than iter_len. The iter_advance may be
13662 // smaller than iter_len, in which case the sub-slices will overlap.
13663 //
13664 // The return value r satisfies ((0 <= r) && (r <= total_len)).
13665 //
13666 // For example, if total_len = 15, iter_len = 5 and iter_advance = 3, there are
13667 // four iterations at offsets 0, 3, 6 and 9. This function returns 12.
13668 //
13669 // 0123456789012345
13670 // [....]
13671 //    [....]
13672 //       [....]
13673 //          [....]
13674 //             $
13675 // 0123456789012345
13676 //
13677 // For example, if total_len = 15, iter_len = 5 and iter_advance = 5, there are
13678 // three iterations at offsets 0, 5 and 10. This function returns 15.
13679 //
13680 // 0123456789012345
13681 // [....]
13682 //      [....]
13683 //           [....]
13684 //                $
13685 // 0123456789012345
13686 static inline size_t  //
wuffs_base__iterate_total_advance(size_t total_len,size_t iter_len,size_t iter_advance)13687 wuffs_base__iterate_total_advance(size_t total_len,
13688                                   size_t iter_len,
13689                                   size_t iter_advance) {
13690   if (total_len >= iter_len) {
13691     size_t n = total_len - iter_len;
13692     return ((n / iter_advance) * iter_advance) + iter_advance;
13693   }
13694   return 0;
13695 }
13696 
13697 // ---------------- Numeric Types
13698 
13699 extern const uint8_t wuffs_base__low_bits_mask__u8[8];
13700 extern const uint16_t wuffs_base__low_bits_mask__u16[16];
13701 extern const uint32_t wuffs_base__low_bits_mask__u32[32];
13702 extern const uint64_t wuffs_base__low_bits_mask__u64[64];
13703 
13704 #define WUFFS_BASE__LOW_BITS_MASK__U8(n) (wuffs_base__low_bits_mask__u8[n])
13705 #define WUFFS_BASE__LOW_BITS_MASK__U16(n) (wuffs_base__low_bits_mask__u16[n])
13706 #define WUFFS_BASE__LOW_BITS_MASK__U32(n) (wuffs_base__low_bits_mask__u32[n])
13707 #define WUFFS_BASE__LOW_BITS_MASK__U64(n) (wuffs_base__low_bits_mask__u64[n])
13708 
13709 // --------
13710 
13711 static inline void  //
wuffs_base__u8__sat_add_indirect(uint8_t * x,uint8_t y)13712 wuffs_base__u8__sat_add_indirect(uint8_t* x, uint8_t y) {
13713   *x = wuffs_base__u8__sat_add(*x, y);
13714 }
13715 
13716 static inline void  //
wuffs_base__u8__sat_sub_indirect(uint8_t * x,uint8_t y)13717 wuffs_base__u8__sat_sub_indirect(uint8_t* x, uint8_t y) {
13718   *x = wuffs_base__u8__sat_sub(*x, y);
13719 }
13720 
13721 static inline void  //
wuffs_base__u16__sat_add_indirect(uint16_t * x,uint16_t y)13722 wuffs_base__u16__sat_add_indirect(uint16_t* x, uint16_t y) {
13723   *x = wuffs_base__u16__sat_add(*x, y);
13724 }
13725 
13726 static inline void  //
wuffs_base__u16__sat_sub_indirect(uint16_t * x,uint16_t y)13727 wuffs_base__u16__sat_sub_indirect(uint16_t* x, uint16_t y) {
13728   *x = wuffs_base__u16__sat_sub(*x, y);
13729 }
13730 
13731 static inline void  //
wuffs_base__u32__sat_add_indirect(uint32_t * x,uint32_t y)13732 wuffs_base__u32__sat_add_indirect(uint32_t* x, uint32_t y) {
13733   *x = wuffs_base__u32__sat_add(*x, y);
13734 }
13735 
13736 static inline void  //
wuffs_base__u32__sat_sub_indirect(uint32_t * x,uint32_t y)13737 wuffs_base__u32__sat_sub_indirect(uint32_t* x, uint32_t y) {
13738   *x = wuffs_base__u32__sat_sub(*x, y);
13739 }
13740 
13741 static inline void  //
wuffs_base__u64__sat_add_indirect(uint64_t * x,uint64_t y)13742 wuffs_base__u64__sat_add_indirect(uint64_t* x, uint64_t y) {
13743   *x = wuffs_base__u64__sat_add(*x, y);
13744 }
13745 
13746 static inline void  //
wuffs_base__u64__sat_sub_indirect(uint64_t * x,uint64_t y)13747 wuffs_base__u64__sat_sub_indirect(uint64_t* x, uint64_t y) {
13748   *x = wuffs_base__u64__sat_sub(*x, y);
13749 }
13750 
13751 // ---------------- Numeric Types (Utility)
13752 
13753 #define wuffs_base__utility__sign_extend_convert_u16_u32(a) \
13754   ((uint32_t)(int32_t)(int16_t)(a))
13755 
13756 #define wuffs_base__utility__sign_extend_rshift_u32(a, n) \
13757   ((uint32_t)(((int32_t)(a)) >> (n)))
13758 
13759 #define wuffs_base__utility__sign_extend_rshift_u64(a, n) \
13760   ((uint64_t)(((int64_t)(a)) >> (n)))
13761 
13762 // ---------------- Slices and Tables
13763 
13764 // wuffs_base__slice_u8__prefix returns up to the first up_to bytes of s.
13765 static inline wuffs_base__slice_u8  //
wuffs_base__slice_u8__prefix(wuffs_base__slice_u8 s,uint64_t up_to)13766 wuffs_base__slice_u8__prefix(wuffs_base__slice_u8 s, uint64_t up_to) {
13767   if (((uint64_t)(s.len)) > up_to) {
13768     s.len = ((size_t)up_to);
13769   }
13770   return s;
13771 }
13772 
13773 // wuffs_base__slice_u8__suffix returns up to the last up_to bytes of s.
13774 static inline wuffs_base__slice_u8  //
wuffs_base__slice_u8__suffix(wuffs_base__slice_u8 s,uint64_t up_to)13775 wuffs_base__slice_u8__suffix(wuffs_base__slice_u8 s, uint64_t up_to) {
13776   if (((uint64_t)(s.len)) > up_to) {
13777     s.ptr += ((uint64_t)(s.len)) - up_to;
13778     s.len = ((size_t)up_to);
13779   }
13780   return s;
13781 }
13782 
13783 // wuffs_base__slice_u8__copy_from_slice calls memmove(dst.ptr, src.ptr, len)
13784 // where len is the minimum of dst.len and src.len.
13785 //
13786 // Passing a wuffs_base__slice_u8 with all fields NULL or zero (a valid, empty
13787 // slice) is valid and results in a no-op.
13788 static inline uint64_t  //
wuffs_base__slice_u8__copy_from_slice(wuffs_base__slice_u8 dst,wuffs_base__slice_u8 src)13789 wuffs_base__slice_u8__copy_from_slice(wuffs_base__slice_u8 dst,
13790                                       wuffs_base__slice_u8 src) {
13791   size_t len = dst.len < src.len ? dst.len : src.len;
13792   if (len > 0) {
13793     memmove(dst.ptr, src.ptr, len);
13794   }
13795   return len;
13796 }
13797 
13798 static inline wuffs_base__empty_struct  //
wuffs_base__bulk_load_host_endian(void * ptr,size_t len,wuffs_base__slice_u8 src)13799 wuffs_base__bulk_load_host_endian(void* ptr,
13800                                   size_t len,
13801                                   wuffs_base__slice_u8 src) {
13802   if (len && (len <= src.len)) {
13803     memmove(ptr, src.ptr, len);
13804   }
13805   return wuffs_base__make_empty_struct();
13806 }
13807 
13808 static inline wuffs_base__empty_struct  //
wuffs_base__bulk_memset(void * ptr,size_t len,uint8_t byte_value)13809 wuffs_base__bulk_memset(void* ptr, size_t len, uint8_t byte_value) {
13810   if (len) {
13811     memset(ptr, byte_value, len);
13812   }
13813   return wuffs_base__make_empty_struct();
13814 }
13815 
13816 static inline wuffs_base__empty_struct  //
wuffs_base__bulk_save_host_endian(void * ptr,size_t len,wuffs_base__slice_u8 dst)13817 wuffs_base__bulk_save_host_endian(void* ptr,
13818                                   size_t len,
13819                                   wuffs_base__slice_u8 dst) {
13820   if (len && (len <= dst.len)) {
13821     memmove(dst.ptr, ptr, len);
13822   }
13823   return wuffs_base__make_empty_struct();
13824 }
13825 
13826 // --------
13827 
13828 static inline wuffs_base__slice_u8  //
wuffs_base__table_u8__row_u32(wuffs_base__table_u8 t,uint32_t y)13829 wuffs_base__table_u8__row_u32(wuffs_base__table_u8 t, uint32_t y) {
13830   if (y < t.height) {
13831     return wuffs_base__make_slice_u8(t.ptr + (t.stride * y), t.width);
13832   }
13833   return wuffs_base__make_slice_u8(NULL, 0);
13834 }
13835 
13836 // ---------------- Slices and Tables (Utility)
13837 
13838 #define wuffs_base__utility__empty_slice_u8 wuffs_base__empty_slice_u8
13839 
13840 // ---------------- Ranges and Rects
13841 
13842 static inline uint32_t  //
wuffs_base__range_ii_u32__get_min_incl(const wuffs_base__range_ii_u32 * r)13843 wuffs_base__range_ii_u32__get_min_incl(const wuffs_base__range_ii_u32* r) {
13844   return r->min_incl;
13845 }
13846 
13847 static inline uint32_t  //
wuffs_base__range_ii_u32__get_max_incl(const wuffs_base__range_ii_u32 * r)13848 wuffs_base__range_ii_u32__get_max_incl(const wuffs_base__range_ii_u32* r) {
13849   return r->max_incl;
13850 }
13851 
13852 static inline uint32_t  //
wuffs_base__range_ie_u32__get_min_incl(const wuffs_base__range_ie_u32 * r)13853 wuffs_base__range_ie_u32__get_min_incl(const wuffs_base__range_ie_u32* r) {
13854   return r->min_incl;
13855 }
13856 
13857 static inline uint32_t  //
wuffs_base__range_ie_u32__get_max_excl(const wuffs_base__range_ie_u32 * r)13858 wuffs_base__range_ie_u32__get_max_excl(const wuffs_base__range_ie_u32* r) {
13859   return r->max_excl;
13860 }
13861 
13862 static inline uint64_t  //
wuffs_base__range_ii_u64__get_min_incl(const wuffs_base__range_ii_u64 * r)13863 wuffs_base__range_ii_u64__get_min_incl(const wuffs_base__range_ii_u64* r) {
13864   return r->min_incl;
13865 }
13866 
13867 static inline uint64_t  //
wuffs_base__range_ii_u64__get_max_incl(const wuffs_base__range_ii_u64 * r)13868 wuffs_base__range_ii_u64__get_max_incl(const wuffs_base__range_ii_u64* r) {
13869   return r->max_incl;
13870 }
13871 
13872 static inline uint64_t  //
wuffs_base__range_ie_u64__get_min_incl(const wuffs_base__range_ie_u64 * r)13873 wuffs_base__range_ie_u64__get_min_incl(const wuffs_base__range_ie_u64* r) {
13874   return r->min_incl;
13875 }
13876 
13877 static inline uint64_t  //
wuffs_base__range_ie_u64__get_max_excl(const wuffs_base__range_ie_u64 * r)13878 wuffs_base__range_ie_u64__get_max_excl(const wuffs_base__range_ie_u64* r) {
13879   return r->max_excl;
13880 }
13881 
13882 // ---------------- Ranges and Rects (Utility)
13883 
13884 #define wuffs_base__utility__empty_range_ii_u32 wuffs_base__empty_range_ii_u32
13885 #define wuffs_base__utility__empty_range_ie_u32 wuffs_base__empty_range_ie_u32
13886 #define wuffs_base__utility__empty_range_ii_u64 wuffs_base__empty_range_ii_u64
13887 #define wuffs_base__utility__empty_range_ie_u64 wuffs_base__empty_range_ie_u64
13888 #define wuffs_base__utility__empty_rect_ii_u32 wuffs_base__empty_rect_ii_u32
13889 #define wuffs_base__utility__empty_rect_ie_u32 wuffs_base__empty_rect_ie_u32
13890 #define wuffs_base__utility__make_range_ii_u32 wuffs_base__make_range_ii_u32
13891 #define wuffs_base__utility__make_range_ie_u32 wuffs_base__make_range_ie_u32
13892 #define wuffs_base__utility__make_range_ii_u64 wuffs_base__make_range_ii_u64
13893 #define wuffs_base__utility__make_range_ie_u64 wuffs_base__make_range_ie_u64
13894 #define wuffs_base__utility__make_rect_ii_u32 wuffs_base__make_rect_ii_u32
13895 #define wuffs_base__utility__make_rect_ie_u32 wuffs_base__make_rect_ie_u32
13896 
13897 // ---------------- I/O
13898 
13899 static inline uint64_t  //
wuffs_base__io__count_since(uint64_t mark,uint64_t index)13900 wuffs_base__io__count_since(uint64_t mark, uint64_t index) {
13901   if (index >= mark) {
13902     return index - mark;
13903   }
13904   return 0;
13905 }
13906 
13907 // TODO: drop the "const" in "const uint8_t* ptr". Some though required about
13908 // the base.io_reader.since method returning a mutable "slice base.u8".
13909 #if defined(__GNUC__)
13910 #pragma GCC diagnostic push
13911 #pragma GCC diagnostic ignored "-Wcast-qual"
13912 #endif
13913 static inline wuffs_base__slice_u8  //
wuffs_base__io__since(uint64_t mark,uint64_t index,const uint8_t * ptr)13914 wuffs_base__io__since(uint64_t mark, uint64_t index, const uint8_t* ptr) {
13915   if (index >= mark) {
13916     return wuffs_base__make_slice_u8(((uint8_t*)ptr) + mark,
13917                                      ((size_t)(index - mark)));
13918   }
13919   return wuffs_base__make_slice_u8(NULL, 0);
13920 }
13921 #if defined(__GNUC__)
13922 #pragma GCC diagnostic pop
13923 #endif
13924 
13925 // --------
13926 
13927 static inline void  //
wuffs_base__io_reader__limit(const uint8_t ** ptr_io2_r,const uint8_t * iop_r,uint64_t limit)13928 wuffs_base__io_reader__limit(const uint8_t** ptr_io2_r,
13929                              const uint8_t* iop_r,
13930                              uint64_t limit) {
13931   if (((uint64_t)(*ptr_io2_r - iop_r)) > limit) {
13932     *ptr_io2_r = iop_r + limit;
13933   }
13934 }
13935 
13936 static inline uint32_t  //
wuffs_base__io_reader__limited_copy_u32_to_slice(const uint8_t ** ptr_iop_r,const uint8_t * io2_r,uint32_t length,wuffs_base__slice_u8 dst)13937 wuffs_base__io_reader__limited_copy_u32_to_slice(const uint8_t** ptr_iop_r,
13938                                                  const uint8_t* io2_r,
13939                                                  uint32_t length,
13940                                                  wuffs_base__slice_u8 dst) {
13941   const uint8_t* iop_r = *ptr_iop_r;
13942   size_t n = dst.len;
13943   if (n > length) {
13944     n = length;
13945   }
13946   if (n > ((size_t)(io2_r - iop_r))) {
13947     n = (size_t)(io2_r - iop_r);
13948   }
13949   if (n > 0) {
13950     memmove(dst.ptr, iop_r, n);
13951     *ptr_iop_r += n;
13952   }
13953   return (uint32_t)(n);
13954 }
13955 
13956 // wuffs_base__io_reader__match7 returns whether the io_reader's upcoming bytes
13957 // start with the given prefix (up to 7 bytes long). It is peek-like, not
13958 // read-like, in that there are no side-effects.
13959 //
13960 // The low 3 bits of a hold the prefix length, n.
13961 //
13962 // The high 56 bits of a hold the prefix itself, in little-endian order. The
13963 // first prefix byte is in bits 8..=15, the second prefix byte is in bits
13964 // 16..=23, etc. The high (8 * (7 - n)) bits are ignored.
13965 //
13966 // There are three possible return values:
13967 //  - 0 means success.
13968 //  - 1 means inconclusive, equivalent to "$short read".
13969 //  - 2 means failure.
13970 static inline uint32_t  //
wuffs_base__io_reader__match7(const uint8_t * iop_r,const uint8_t * io2_r,wuffs_base__io_buffer * r,uint64_t a)13971 wuffs_base__io_reader__match7(const uint8_t* iop_r,
13972                               const uint8_t* io2_r,
13973                               wuffs_base__io_buffer* r,
13974                               uint64_t a) {
13975   uint32_t n = a & 7;
13976   a >>= 8;
13977   if ((io2_r - iop_r) >= 8) {
13978     uint64_t x = wuffs_base__peek_u64le__no_bounds_check(iop_r);
13979     uint32_t shift = 8 * (8 - n);
13980     return ((a << shift) == (x << shift)) ? 0 : 2;
13981   }
13982   for (; n > 0; n--) {
13983     if (iop_r >= io2_r) {
13984       return (r && r->meta.closed) ? 2 : 1;
13985     } else if (*iop_r != ((uint8_t)(a))) {
13986       return 2;
13987     }
13988     iop_r++;
13989     a >>= 8;
13990   }
13991   return 0;
13992 }
13993 
13994 static inline wuffs_base__io_buffer*  //
wuffs_base__io_reader__set(wuffs_base__io_buffer * b,const uint8_t ** ptr_iop_r,const uint8_t ** ptr_io0_r,const uint8_t ** ptr_io1_r,const uint8_t ** ptr_io2_r,wuffs_base__slice_u8 data,uint64_t history_position)13995 wuffs_base__io_reader__set(wuffs_base__io_buffer* b,
13996                            const uint8_t** ptr_iop_r,
13997                            const uint8_t** ptr_io0_r,
13998                            const uint8_t** ptr_io1_r,
13999                            const uint8_t** ptr_io2_r,
14000                            wuffs_base__slice_u8 data,
14001                            uint64_t history_position) {
14002   b->data = data;
14003   b->meta.wi = data.len;
14004   b->meta.ri = 0;
14005   b->meta.pos = history_position;
14006   b->meta.closed = false;
14007 
14008   *ptr_iop_r = data.ptr;
14009   *ptr_io0_r = data.ptr;
14010   *ptr_io1_r = data.ptr;
14011   *ptr_io2_r = data.ptr + data.len;
14012 
14013   return b;
14014 }
14015 
14016 // --------
14017 
14018 static inline uint64_t  //
wuffs_base__io_writer__copy_from_slice(uint8_t ** ptr_iop_w,uint8_t * io2_w,wuffs_base__slice_u8 src)14019 wuffs_base__io_writer__copy_from_slice(uint8_t** ptr_iop_w,
14020                                        uint8_t* io2_w,
14021                                        wuffs_base__slice_u8 src) {
14022   uint8_t* iop_w = *ptr_iop_w;
14023   size_t n = src.len;
14024   if (n > ((size_t)(io2_w - iop_w))) {
14025     n = (size_t)(io2_w - iop_w);
14026   }
14027   if (n > 0) {
14028     memmove(iop_w, src.ptr, n);
14029     *ptr_iop_w += n;
14030   }
14031   return (uint64_t)(n);
14032 }
14033 
14034 static inline void  //
wuffs_base__io_writer__limit(uint8_t ** ptr_io2_w,uint8_t * iop_w,uint64_t limit)14035 wuffs_base__io_writer__limit(uint8_t** ptr_io2_w,
14036                              uint8_t* iop_w,
14037                              uint64_t limit) {
14038   if (((uint64_t)(*ptr_io2_w - iop_w)) > limit) {
14039     *ptr_io2_w = iop_w + limit;
14040   }
14041 }
14042 
14043 static inline uint32_t  //
wuffs_base__io_writer__limited_copy_u32_from_history(uint8_t ** ptr_iop_w,uint8_t * io0_w,uint8_t * io2_w,uint32_t length,uint32_t distance)14044 wuffs_base__io_writer__limited_copy_u32_from_history(uint8_t** ptr_iop_w,
14045                                                      uint8_t* io0_w,
14046                                                      uint8_t* io2_w,
14047                                                      uint32_t length,
14048                                                      uint32_t distance) {
14049   if (!distance) {
14050     return 0;
14051   }
14052   uint8_t* p = *ptr_iop_w;
14053   if ((size_t)(p - io0_w) < (size_t)(distance)) {
14054     return 0;
14055   }
14056   uint8_t* q = p - distance;
14057   size_t n = (size_t)(io2_w - p);
14058   if ((size_t)(length) > n) {
14059     length = (uint32_t)(n);
14060   } else {
14061     n = (size_t)(length);
14062   }
14063   // TODO: unrolling by 3 seems best for the std/deflate benchmarks, but that
14064   // is mostly because 3 is the minimum length for the deflate format. This
14065   // function implementation shouldn't overfit to that one format. Perhaps the
14066   // limited_copy_u32_from_history Wuffs method should also take an unroll hint
14067   // argument, and the cgen can look if that argument is the constant
14068   // expression '3'.
14069   //
14070   // See also wuffs_base__io_writer__limited_copy_u32_from_history_fast below.
14071   for (; n >= 3; n -= 3) {
14072     *p++ = *q++;
14073     *p++ = *q++;
14074     *p++ = *q++;
14075   }
14076   for (; n; n--) {
14077     *p++ = *q++;
14078   }
14079   *ptr_iop_w = p;
14080   return length;
14081 }
14082 
14083 // wuffs_base__io_writer__limited_copy_u32_from_history_fast is like the
14084 // wuffs_base__io_writer__limited_copy_u32_from_history function above, but has
14085 // stronger pre-conditions.
14086 //
14087 // The caller needs to prove that:
14088 //  - length   <= (io2_w      - *ptr_iop_w)
14089 //  - distance >= 1
14090 //  - distance <= (*ptr_iop_w - io0_w)
14091 static inline uint32_t  //
wuffs_base__io_writer__limited_copy_u32_from_history_fast(uint8_t ** ptr_iop_w,uint8_t * io0_w,uint8_t * io2_w,uint32_t length,uint32_t distance)14092 wuffs_base__io_writer__limited_copy_u32_from_history_fast(uint8_t** ptr_iop_w,
14093                                                           uint8_t* io0_w,
14094                                                           uint8_t* io2_w,
14095                                                           uint32_t length,
14096                                                           uint32_t distance) {
14097   uint8_t* p = *ptr_iop_w;
14098   uint8_t* q = p - distance;
14099   uint32_t n = length;
14100   for (; n >= 3; n -= 3) {
14101     *p++ = *q++;
14102     *p++ = *q++;
14103     *p++ = *q++;
14104   }
14105   for (; n; n--) {
14106     *p++ = *q++;
14107   }
14108   *ptr_iop_w = p;
14109   return length;
14110 }
14111 
14112 // wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast
14113 // copies the previous byte (the one immediately before *ptr_iop_w), copying 8
14114 // byte chunks at a time. Each chunk contains 8 repetitions of the same byte.
14115 //
14116 // In terms of number of bytes copied, length is rounded up to a multiple of 8.
14117 // As a special case, a zero length rounds up to 8 (even though 0 is already a
14118 // multiple of 8), since there is always at least one 8 byte chunk copied.
14119 //
14120 // In terms of advancing *ptr_iop_w, length is not rounded up.
14121 //
14122 // The caller needs to prove that:
14123 //  - (length + 8) <= (io2_w      - *ptr_iop_w)
14124 //  - distance     == 1
14125 //  - distance     <= (*ptr_iop_w - io0_w)
14126 static inline uint32_t  //
wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast(uint8_t ** ptr_iop_w,uint8_t * io0_w,uint8_t * io2_w,uint32_t length,uint32_t distance)14127 wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast(
14128     uint8_t** ptr_iop_w,
14129     uint8_t* io0_w,
14130     uint8_t* io2_w,
14131     uint32_t length,
14132     uint32_t distance) {
14133   uint8_t* p = *ptr_iop_w;
14134   uint64_t x = p[-1];
14135   x |= x << 8;
14136   x |= x << 16;
14137   x |= x << 32;
14138   uint32_t n = length;
14139   while (1) {
14140     wuffs_base__poke_u64le__no_bounds_check(p, x);
14141     if (n <= 8) {
14142       p += n;
14143       break;
14144     }
14145     p += 8;
14146     n -= 8;
14147   }
14148   *ptr_iop_w = p;
14149   return length;
14150 }
14151 
14152 // wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast is
14153 // like the wuffs_base__io_writer__limited_copy_u32_from_history_fast function
14154 // above, but copies 8 byte chunks at a time.
14155 //
14156 // In terms of number of bytes copied, length is rounded up to a multiple of 8.
14157 // As a special case, a zero length rounds up to 8 (even though 0 is already a
14158 // multiple of 8), since there is always at least one 8 byte chunk copied.
14159 //
14160 // In terms of advancing *ptr_iop_w, length is not rounded up.
14161 //
14162 // The caller needs to prove that:
14163 //  - (length + 8) <= (io2_w      - *ptr_iop_w)
14164 //  - distance     >= 8
14165 //  - distance     <= (*ptr_iop_w - io0_w)
14166 static inline uint32_t  //
wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast(uint8_t ** ptr_iop_w,uint8_t * io0_w,uint8_t * io2_w,uint32_t length,uint32_t distance)14167 wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast(
14168     uint8_t** ptr_iop_w,
14169     uint8_t* io0_w,
14170     uint8_t* io2_w,
14171     uint32_t length,
14172     uint32_t distance) {
14173   uint8_t* p = *ptr_iop_w;
14174   uint8_t* q = p - distance;
14175   uint32_t n = length;
14176   while (1) {
14177     memcpy(p, q, 8);
14178     if (n <= 8) {
14179       p += n;
14180       break;
14181     }
14182     p += 8;
14183     q += 8;
14184     n -= 8;
14185   }
14186   *ptr_iop_w = p;
14187   return length;
14188 }
14189 
14190 static inline uint32_t  //
wuffs_base__io_writer__limited_copy_u32_from_reader(uint8_t ** ptr_iop_w,uint8_t * io2_w,uint32_t length,const uint8_t ** ptr_iop_r,const uint8_t * io2_r)14191 wuffs_base__io_writer__limited_copy_u32_from_reader(uint8_t** ptr_iop_w,
14192                                                     uint8_t* io2_w,
14193                                                     uint32_t length,
14194                                                     const uint8_t** ptr_iop_r,
14195                                                     const uint8_t* io2_r) {
14196   uint8_t* iop_w = *ptr_iop_w;
14197   size_t n = length;
14198   if (n > ((size_t)(io2_w - iop_w))) {
14199     n = (size_t)(io2_w - iop_w);
14200   }
14201   const uint8_t* iop_r = *ptr_iop_r;
14202   if (n > ((size_t)(io2_r - iop_r))) {
14203     n = (size_t)(io2_r - iop_r);
14204   }
14205   if (n > 0) {
14206     memmove(iop_w, iop_r, n);
14207     *ptr_iop_w += n;
14208     *ptr_iop_r += n;
14209   }
14210   return (uint32_t)(n);
14211 }
14212 
14213 static inline uint32_t  //
wuffs_base__io_writer__limited_copy_u32_from_slice(uint8_t ** ptr_iop_w,uint8_t * io2_w,uint32_t length,wuffs_base__slice_u8 src)14214 wuffs_base__io_writer__limited_copy_u32_from_slice(uint8_t** ptr_iop_w,
14215                                                    uint8_t* io2_w,
14216                                                    uint32_t length,
14217                                                    wuffs_base__slice_u8 src) {
14218   uint8_t* iop_w = *ptr_iop_w;
14219   size_t n = src.len;
14220   if (n > length) {
14221     n = length;
14222   }
14223   if (n > ((size_t)(io2_w - iop_w))) {
14224     n = (size_t)(io2_w - iop_w);
14225   }
14226   if (n > 0) {
14227     memmove(iop_w, src.ptr, n);
14228     *ptr_iop_w += n;
14229   }
14230   return (uint32_t)(n);
14231 }
14232 
14233 static inline wuffs_base__io_buffer*  //
wuffs_base__io_writer__set(wuffs_base__io_buffer * b,uint8_t ** ptr_iop_w,uint8_t ** ptr_io0_w,uint8_t ** ptr_io1_w,uint8_t ** ptr_io2_w,wuffs_base__slice_u8 data,uint64_t history_position)14234 wuffs_base__io_writer__set(wuffs_base__io_buffer* b,
14235                            uint8_t** ptr_iop_w,
14236                            uint8_t** ptr_io0_w,
14237                            uint8_t** ptr_io1_w,
14238                            uint8_t** ptr_io2_w,
14239                            wuffs_base__slice_u8 data,
14240                            uint64_t history_position) {
14241   b->data = data;
14242   b->meta.wi = 0;
14243   b->meta.ri = 0;
14244   b->meta.pos = history_position;
14245   b->meta.closed = false;
14246 
14247   *ptr_iop_w = data.ptr;
14248   *ptr_io0_w = data.ptr;
14249   *ptr_io1_w = data.ptr;
14250   *ptr_io2_w = data.ptr + data.len;
14251 
14252   return b;
14253 }
14254 
14255 // ---------------- I/O (Utility)
14256 
14257 #define wuffs_base__utility__empty_io_reader wuffs_base__empty_io_reader
14258 #define wuffs_base__utility__empty_io_writer wuffs_base__empty_io_writer
14259 
14260 // ---------------- Tokens
14261 
14262 // ---------------- Tokens (Utility)
14263 
14264 // ---------------- Memory Allocation
14265 
14266 // ---------------- Images
14267 
14268 WUFFS_BASE__MAYBE_STATIC uint64_t  //
14269 wuffs_base__pixel_swizzler__limited_swizzle_u32_interleaved_from_reader(
14270     const wuffs_base__pixel_swizzler* p,
14271     uint32_t up_to_num_pixels,
14272     wuffs_base__slice_u8 dst,
14273     wuffs_base__slice_u8 dst_palette,
14274     const uint8_t** ptr_iop_r,
14275     const uint8_t* io2_r);
14276 
14277 WUFFS_BASE__MAYBE_STATIC uint64_t  //
14278 wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(
14279     const wuffs_base__pixel_swizzler* p,
14280     wuffs_base__slice_u8 dst,
14281     wuffs_base__slice_u8 dst_palette,
14282     const uint8_t** ptr_iop_r,
14283     const uint8_t* io2_r);
14284 
14285 WUFFS_BASE__MAYBE_STATIC uint64_t  //
14286 wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(
14287     const wuffs_base__pixel_swizzler* p,
14288     wuffs_base__slice_u8 dst,
14289     wuffs_base__slice_u8 dst_palette,
14290     uint64_t num_pixels);
14291 
14292 WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
14293 wuffs_base__pixel_swizzler__swizzle_ycck(
14294     const wuffs_base__pixel_swizzler* p,
14295     wuffs_base__pixel_buffer* dst,
14296     wuffs_base__slice_u8 dst_palette,
14297     uint32_t width,
14298     uint32_t height,
14299     wuffs_base__slice_u8 src0,
14300     wuffs_base__slice_u8 src1,
14301     wuffs_base__slice_u8 src2,
14302     wuffs_base__slice_u8 src3,
14303     uint32_t width0,
14304     uint32_t width1,
14305     uint32_t width2,
14306     uint32_t width3,
14307     uint32_t height0,
14308     uint32_t height1,
14309     uint32_t height2,
14310     uint32_t height3,
14311     uint32_t stride0,
14312     uint32_t stride1,
14313     uint32_t stride2,
14314     uint32_t stride3,
14315     uint8_t h0,
14316     uint8_t h1,
14317     uint8_t h2,
14318     uint8_t h3,
14319     uint8_t v0,
14320     uint8_t v1,
14321     uint8_t v2,
14322     uint8_t v3,
14323     bool is_rgb_or_cmyk,
14324     bool triangle_filter_for_2to1,
14325     wuffs_base__slice_u8 scratch_buffer_2k);
14326 
14327 // ---------------- Images (Utility)
14328 
14329 #define wuffs_base__utility__make_pixel_format wuffs_base__make_pixel_format
14330 
14331 // ---------------- String Conversions
14332 
14333 // ---------------- Unicode and UTF-8
14334 
14335 // ----------------
14336 
14337 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
14338     defined(WUFFS_CONFIG__MODULE__BASE__CORE)
14339 
14340 const uint8_t wuffs_base__low_bits_mask__u8[8] = {
14341     0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F,
14342 };
14343 
14344 const uint16_t wuffs_base__low_bits_mask__u16[16] = {
14345     0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F,
14346     0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF,
14347 };
14348 
14349 const uint32_t wuffs_base__low_bits_mask__u32[32] = {
14350     0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000F, 0x0000001F,
14351     0x0000003F, 0x0000007F, 0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF,
14352     0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF, 0x0001FFFF,
14353     0x0003FFFF, 0x0007FFFF, 0x000FFFFF, 0x001FFFFF, 0x003FFFFF, 0x007FFFFF,
14354     0x00FFFFFF, 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF, 0x1FFFFFFF,
14355     0x3FFFFFFF, 0x7FFFFFFF,
14356 };
14357 
14358 const uint64_t wuffs_base__low_bits_mask__u64[64] = {
14359     0x0000000000000000, 0x0000000000000001, 0x0000000000000003,
14360     0x0000000000000007, 0x000000000000000F, 0x000000000000001F,
14361     0x000000000000003F, 0x000000000000007F, 0x00000000000000FF,
14362     0x00000000000001FF, 0x00000000000003FF, 0x00000000000007FF,
14363     0x0000000000000FFF, 0x0000000000001FFF, 0x0000000000003FFF,
14364     0x0000000000007FFF, 0x000000000000FFFF, 0x000000000001FFFF,
14365     0x000000000003FFFF, 0x000000000007FFFF, 0x00000000000FFFFF,
14366     0x00000000001FFFFF, 0x00000000003FFFFF, 0x00000000007FFFFF,
14367     0x0000000000FFFFFF, 0x0000000001FFFFFF, 0x0000000003FFFFFF,
14368     0x0000000007FFFFFF, 0x000000000FFFFFFF, 0x000000001FFFFFFF,
14369     0x000000003FFFFFFF, 0x000000007FFFFFFF, 0x00000000FFFFFFFF,
14370     0x00000001FFFFFFFF, 0x00000003FFFFFFFF, 0x00000007FFFFFFFF,
14371     0x0000000FFFFFFFFF, 0x0000001FFFFFFFFF, 0x0000003FFFFFFFFF,
14372     0x0000007FFFFFFFFF, 0x000000FFFFFFFFFF, 0x000001FFFFFFFFFF,
14373     0x000003FFFFFFFFFF, 0x000007FFFFFFFFFF, 0x00000FFFFFFFFFFF,
14374     0x00001FFFFFFFFFFF, 0x00003FFFFFFFFFFF, 0x00007FFFFFFFFFFF,
14375     0x0000FFFFFFFFFFFF, 0x0001FFFFFFFFFFFF, 0x0003FFFFFFFFFFFF,
14376     0x0007FFFFFFFFFFFF, 0x000FFFFFFFFFFFFF, 0x001FFFFFFFFFFFFF,
14377     0x003FFFFFFFFFFFFF, 0x007FFFFFFFFFFFFF, 0x00FFFFFFFFFFFFFF,
14378     0x01FFFFFFFFFFFFFF, 0x03FFFFFFFFFFFFFF, 0x07FFFFFFFFFFFFFF,
14379     0x0FFFFFFFFFFFFFFF, 0x1FFFFFFFFFFFFFFF, 0x3FFFFFFFFFFFFFFF,
14380     0x7FFFFFFFFFFFFFFF,
14381 };
14382 
14383 const uint32_t wuffs_base__pixel_format__bits_per_channel[16] = {
14384     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
14385     0x08, 0x0A, 0x0C, 0x10, 0x18, 0x20, 0x30, 0x40,
14386 };
14387 
14388 const char wuffs_base__note__i_o_redirect[] = "@base: I/O redirect";
14389 const char wuffs_base__note__end_of_data[] = "@base: end of data";
14390 const char wuffs_base__note__metadata_reported[] = "@base: metadata reported";
14391 const char wuffs_base__suspension__even_more_information[] = "$base: even more information";
14392 const char wuffs_base__suspension__mispositioned_read[] = "$base: mispositioned read";
14393 const char wuffs_base__suspension__mispositioned_write[] = "$base: mispositioned write";
14394 const char wuffs_base__suspension__short_read[] = "$base: short read";
14395 const char wuffs_base__suspension__short_write[] = "$base: short write";
14396 const char wuffs_base__error__bad_i_o_position[] = "#base: bad I/O position";
14397 const char wuffs_base__error__bad_argument_length_too_short[] = "#base: bad argument (length too short)";
14398 const char wuffs_base__error__bad_argument[] = "#base: bad argument";
14399 const char wuffs_base__error__bad_call_sequence[] = "#base: bad call sequence";
14400 const char wuffs_base__error__bad_data[] = "#base: bad data";
14401 const char wuffs_base__error__bad_receiver[] = "#base: bad receiver";
14402 const char wuffs_base__error__bad_restart[] = "#base: bad restart";
14403 const char wuffs_base__error__bad_sizeof_receiver[] = "#base: bad sizeof receiver";
14404 const char wuffs_base__error__bad_vtable[] = "#base: bad vtable";
14405 const char wuffs_base__error__bad_workbuf_length[] = "#base: bad workbuf length";
14406 const char wuffs_base__error__bad_wuffs_version[] = "#base: bad wuffs version";
14407 const char wuffs_base__error__cannot_return_a_suspension[] = "#base: cannot return a suspension";
14408 const char wuffs_base__error__disabled_by_previous_error[] = "#base: disabled by previous error";
14409 const char wuffs_base__error__initialize_falsely_claimed_already_zeroed[] = "#base: initialize falsely claimed already zeroed";
14410 const char wuffs_base__error__initialize_not_called[] = "#base: initialize not called";
14411 const char wuffs_base__error__interleaved_coroutine_calls[] = "#base: interleaved coroutine calls";
14412 const char wuffs_base__error__no_more_information[] = "#base: no more information";
14413 const char wuffs_base__error__not_enough_data[] = "#base: not enough data";
14414 const char wuffs_base__error__out_of_bounds[] = "#base: out of bounds";
14415 const char wuffs_base__error__unsupported_image_dimension[] = "#base: unsupported image dimension";
14416 const char wuffs_base__error__unsupported_method[] = "#base: unsupported method";
14417 const char wuffs_base__error__unsupported_option[] = "#base: unsupported option";
14418 const char wuffs_base__error__unsupported_pixel_swizzler_option[] = "#base: unsupported pixel swizzler option";
14419 const char wuffs_base__error__too_much_data[] = "#base: too much data";
14420 
14421 const char wuffs_base__hasher_u32__vtable_name[] = "{vtable}wuffs_base__hasher_u32";
14422 const char wuffs_base__hasher_u64__vtable_name[] = "{vtable}wuffs_base__hasher_u64";
14423 const char wuffs_base__image_decoder__vtable_name[] = "{vtable}wuffs_base__image_decoder";
14424 const char wuffs_base__io_transformer__vtable_name[] = "{vtable}wuffs_base__io_transformer";
14425 const char wuffs_base__token_decoder__vtable_name[] = "{vtable}wuffs_base__token_decoder";
14426 
14427 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
14428         // defined(WUFFS_CONFIG__MODULE__BASE)  ||
14429         // defined(WUFFS_CONFIG__MODULE__BASE__CORE)
14430 
14431 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
14432     defined(WUFFS_CONFIG__MODULE__BASE__INTERFACES)
14433 
14434 // ---------------- Interface Definitions.
14435 
14436 WUFFS_BASE__GENERATED_C_CODE
14437 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_base__hasher_u32__checksum_u32(const wuffs_base__hasher_u32 * self)14438 wuffs_base__hasher_u32__checksum_u32(
14439     const wuffs_base__hasher_u32* self) {
14440   if (!self) {
14441     return 0;
14442   }
14443   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
14444       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
14445     return 0;
14446   }
14447 
14448   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
14449   int i;
14450   for (i = 0; i < 63; i++) {
14451     if (v->vtable_name == wuffs_base__hasher_u32__vtable_name) {
14452       const wuffs_base__hasher_u32__func_ptrs* func_ptrs =
14453           (const wuffs_base__hasher_u32__func_ptrs*)(v->function_pointers);
14454       return (*func_ptrs->checksum_u32)(self);
14455     } else if (v->vtable_name == NULL) {
14456       break;
14457     }
14458     v++;
14459   }
14460 
14461   return 0;
14462 }
14463 
14464 WUFFS_BASE__GENERATED_C_CODE
14465 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_base__hasher_u32__get_quirk(const wuffs_base__hasher_u32 * self,uint32_t a_key)14466 wuffs_base__hasher_u32__get_quirk(
14467     const wuffs_base__hasher_u32* self,
14468     uint32_t a_key) {
14469   if (!self) {
14470     return 0;
14471   }
14472   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
14473       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
14474     return 0;
14475   }
14476 
14477   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
14478   int i;
14479   for (i = 0; i < 63; i++) {
14480     if (v->vtable_name == wuffs_base__hasher_u32__vtable_name) {
14481       const wuffs_base__hasher_u32__func_ptrs* func_ptrs =
14482           (const wuffs_base__hasher_u32__func_ptrs*)(v->function_pointers);
14483       return (*func_ptrs->get_quirk)(self, a_key);
14484     } else if (v->vtable_name == NULL) {
14485       break;
14486     }
14487     v++;
14488   }
14489 
14490   return 0;
14491 }
14492 
14493 WUFFS_BASE__GENERATED_C_CODE
14494 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_base__hasher_u32__set_quirk(wuffs_base__hasher_u32 * self,uint32_t a_key,uint64_t a_value)14495 wuffs_base__hasher_u32__set_quirk(
14496     wuffs_base__hasher_u32* self,
14497     uint32_t a_key,
14498     uint64_t a_value) {
14499   if (!self) {
14500     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
14501   }
14502   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
14503     return wuffs_base__make_status(
14504         (self->private_impl.magic == WUFFS_BASE__DISABLED)
14505             ? wuffs_base__error__disabled_by_previous_error
14506             : wuffs_base__error__initialize_not_called);
14507   }
14508 
14509   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
14510   int i;
14511   for (i = 0; i < 63; i++) {
14512     if (v->vtable_name == wuffs_base__hasher_u32__vtable_name) {
14513       const wuffs_base__hasher_u32__func_ptrs* func_ptrs =
14514           (const wuffs_base__hasher_u32__func_ptrs*)(v->function_pointers);
14515       return (*func_ptrs->set_quirk)(self, a_key, a_value);
14516     } else if (v->vtable_name == NULL) {
14517       break;
14518     }
14519     v++;
14520   }
14521 
14522   return wuffs_base__make_status(wuffs_base__error__bad_vtable);
14523 }
14524 
14525 WUFFS_BASE__GENERATED_C_CODE
14526 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_base__hasher_u32__update(wuffs_base__hasher_u32 * self,wuffs_base__slice_u8 a_x)14527 wuffs_base__hasher_u32__update(
14528     wuffs_base__hasher_u32* self,
14529     wuffs_base__slice_u8 a_x) {
14530   if (!self) {
14531     return wuffs_base__make_empty_struct();
14532   }
14533   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
14534     return wuffs_base__make_empty_struct();
14535   }
14536 
14537   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
14538   int i;
14539   for (i = 0; i < 63; i++) {
14540     if (v->vtable_name == wuffs_base__hasher_u32__vtable_name) {
14541       const wuffs_base__hasher_u32__func_ptrs* func_ptrs =
14542           (const wuffs_base__hasher_u32__func_ptrs*)(v->function_pointers);
14543       return (*func_ptrs->update)(self, a_x);
14544     } else if (v->vtable_name == NULL) {
14545       break;
14546     }
14547     v++;
14548   }
14549 
14550   return wuffs_base__make_empty_struct();
14551 }
14552 
14553 WUFFS_BASE__GENERATED_C_CODE
14554 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_base__hasher_u32__update_u32(wuffs_base__hasher_u32 * self,wuffs_base__slice_u8 a_x)14555 wuffs_base__hasher_u32__update_u32(
14556     wuffs_base__hasher_u32* self,
14557     wuffs_base__slice_u8 a_x) {
14558   if (!self) {
14559     return 0;
14560   }
14561   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
14562     return 0;
14563   }
14564 
14565   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
14566   int i;
14567   for (i = 0; i < 63; i++) {
14568     if (v->vtable_name == wuffs_base__hasher_u32__vtable_name) {
14569       const wuffs_base__hasher_u32__func_ptrs* func_ptrs =
14570           (const wuffs_base__hasher_u32__func_ptrs*)(v->function_pointers);
14571       return (*func_ptrs->update_u32)(self, a_x);
14572     } else if (v->vtable_name == NULL) {
14573       break;
14574     }
14575     v++;
14576   }
14577 
14578   return 0;
14579 }
14580 
14581 // --------
14582 
14583 WUFFS_BASE__GENERATED_C_CODE
14584 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_base__hasher_u64__checksum_u64(const wuffs_base__hasher_u64 * self)14585 wuffs_base__hasher_u64__checksum_u64(
14586     const wuffs_base__hasher_u64* self) {
14587   if (!self) {
14588     return 0;
14589   }
14590   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
14591       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
14592     return 0;
14593   }
14594 
14595   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
14596   int i;
14597   for (i = 0; i < 63; i++) {
14598     if (v->vtable_name == wuffs_base__hasher_u64__vtable_name) {
14599       const wuffs_base__hasher_u64__func_ptrs* func_ptrs =
14600           (const wuffs_base__hasher_u64__func_ptrs*)(v->function_pointers);
14601       return (*func_ptrs->checksum_u64)(self);
14602     } else if (v->vtable_name == NULL) {
14603       break;
14604     }
14605     v++;
14606   }
14607 
14608   return 0;
14609 }
14610 
14611 WUFFS_BASE__GENERATED_C_CODE
14612 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_base__hasher_u64__get_quirk(const wuffs_base__hasher_u64 * self,uint32_t a_key)14613 wuffs_base__hasher_u64__get_quirk(
14614     const wuffs_base__hasher_u64* self,
14615     uint32_t a_key) {
14616   if (!self) {
14617     return 0;
14618   }
14619   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
14620       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
14621     return 0;
14622   }
14623 
14624   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
14625   int i;
14626   for (i = 0; i < 63; i++) {
14627     if (v->vtable_name == wuffs_base__hasher_u64__vtable_name) {
14628       const wuffs_base__hasher_u64__func_ptrs* func_ptrs =
14629           (const wuffs_base__hasher_u64__func_ptrs*)(v->function_pointers);
14630       return (*func_ptrs->get_quirk)(self, a_key);
14631     } else if (v->vtable_name == NULL) {
14632       break;
14633     }
14634     v++;
14635   }
14636 
14637   return 0;
14638 }
14639 
14640 WUFFS_BASE__GENERATED_C_CODE
14641 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_base__hasher_u64__set_quirk(wuffs_base__hasher_u64 * self,uint32_t a_key,uint64_t a_value)14642 wuffs_base__hasher_u64__set_quirk(
14643     wuffs_base__hasher_u64* self,
14644     uint32_t a_key,
14645     uint64_t a_value) {
14646   if (!self) {
14647     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
14648   }
14649   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
14650     return wuffs_base__make_status(
14651         (self->private_impl.magic == WUFFS_BASE__DISABLED)
14652             ? wuffs_base__error__disabled_by_previous_error
14653             : wuffs_base__error__initialize_not_called);
14654   }
14655 
14656   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
14657   int i;
14658   for (i = 0; i < 63; i++) {
14659     if (v->vtable_name == wuffs_base__hasher_u64__vtable_name) {
14660       const wuffs_base__hasher_u64__func_ptrs* func_ptrs =
14661           (const wuffs_base__hasher_u64__func_ptrs*)(v->function_pointers);
14662       return (*func_ptrs->set_quirk)(self, a_key, a_value);
14663     } else if (v->vtable_name == NULL) {
14664       break;
14665     }
14666     v++;
14667   }
14668 
14669   return wuffs_base__make_status(wuffs_base__error__bad_vtable);
14670 }
14671 
14672 WUFFS_BASE__GENERATED_C_CODE
14673 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_base__hasher_u64__update(wuffs_base__hasher_u64 * self,wuffs_base__slice_u8 a_x)14674 wuffs_base__hasher_u64__update(
14675     wuffs_base__hasher_u64* self,
14676     wuffs_base__slice_u8 a_x) {
14677   if (!self) {
14678     return wuffs_base__make_empty_struct();
14679   }
14680   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
14681     return wuffs_base__make_empty_struct();
14682   }
14683 
14684   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
14685   int i;
14686   for (i = 0; i < 63; i++) {
14687     if (v->vtable_name == wuffs_base__hasher_u64__vtable_name) {
14688       const wuffs_base__hasher_u64__func_ptrs* func_ptrs =
14689           (const wuffs_base__hasher_u64__func_ptrs*)(v->function_pointers);
14690       return (*func_ptrs->update)(self, a_x);
14691     } else if (v->vtable_name == NULL) {
14692       break;
14693     }
14694     v++;
14695   }
14696 
14697   return wuffs_base__make_empty_struct();
14698 }
14699 
14700 WUFFS_BASE__GENERATED_C_CODE
14701 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_base__hasher_u64__update_u64(wuffs_base__hasher_u64 * self,wuffs_base__slice_u8 a_x)14702 wuffs_base__hasher_u64__update_u64(
14703     wuffs_base__hasher_u64* self,
14704     wuffs_base__slice_u8 a_x) {
14705   if (!self) {
14706     return 0;
14707   }
14708   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
14709     return 0;
14710   }
14711 
14712   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
14713   int i;
14714   for (i = 0; i < 63; i++) {
14715     if (v->vtable_name == wuffs_base__hasher_u64__vtable_name) {
14716       const wuffs_base__hasher_u64__func_ptrs* func_ptrs =
14717           (const wuffs_base__hasher_u64__func_ptrs*)(v->function_pointers);
14718       return (*func_ptrs->update_u64)(self, a_x);
14719     } else if (v->vtable_name == NULL) {
14720       break;
14721     }
14722     v++;
14723   }
14724 
14725   return 0;
14726 }
14727 
14728 // --------
14729 
14730 WUFFS_BASE__GENERATED_C_CODE
14731 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_base__image_decoder__decode_frame(wuffs_base__image_decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__pixel_blend a_blend,wuffs_base__slice_u8 a_workbuf,wuffs_base__decode_frame_options * a_opts)14732 wuffs_base__image_decoder__decode_frame(
14733     wuffs_base__image_decoder* self,
14734     wuffs_base__pixel_buffer* a_dst,
14735     wuffs_base__io_buffer* a_src,
14736     wuffs_base__pixel_blend a_blend,
14737     wuffs_base__slice_u8 a_workbuf,
14738     wuffs_base__decode_frame_options* a_opts) {
14739   if (!self) {
14740     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
14741   }
14742   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
14743     return wuffs_base__make_status(
14744         (self->private_impl.magic == WUFFS_BASE__DISABLED)
14745             ? wuffs_base__error__disabled_by_previous_error
14746             : wuffs_base__error__initialize_not_called);
14747   }
14748 
14749   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
14750   int i;
14751   for (i = 0; i < 63; i++) {
14752     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
14753       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
14754           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
14755       return (*func_ptrs->decode_frame)(self, a_dst, a_src, a_blend, a_workbuf, a_opts);
14756     } else if (v->vtable_name == NULL) {
14757       break;
14758     }
14759     v++;
14760   }
14761 
14762   return wuffs_base__make_status(wuffs_base__error__bad_vtable);
14763 }
14764 
14765 WUFFS_BASE__GENERATED_C_CODE
14766 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_base__image_decoder__decode_frame_config(wuffs_base__image_decoder * self,wuffs_base__frame_config * a_dst,wuffs_base__io_buffer * a_src)14767 wuffs_base__image_decoder__decode_frame_config(
14768     wuffs_base__image_decoder* self,
14769     wuffs_base__frame_config* a_dst,
14770     wuffs_base__io_buffer* a_src) {
14771   if (!self) {
14772     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
14773   }
14774   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
14775     return wuffs_base__make_status(
14776         (self->private_impl.magic == WUFFS_BASE__DISABLED)
14777             ? wuffs_base__error__disabled_by_previous_error
14778             : wuffs_base__error__initialize_not_called);
14779   }
14780 
14781   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
14782   int i;
14783   for (i = 0; i < 63; i++) {
14784     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
14785       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
14786           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
14787       return (*func_ptrs->decode_frame_config)(self, a_dst, a_src);
14788     } else if (v->vtable_name == NULL) {
14789       break;
14790     }
14791     v++;
14792   }
14793 
14794   return wuffs_base__make_status(wuffs_base__error__bad_vtable);
14795 }
14796 
14797 WUFFS_BASE__GENERATED_C_CODE
14798 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_base__image_decoder__decode_image_config(wuffs_base__image_decoder * self,wuffs_base__image_config * a_dst,wuffs_base__io_buffer * a_src)14799 wuffs_base__image_decoder__decode_image_config(
14800     wuffs_base__image_decoder* self,
14801     wuffs_base__image_config* a_dst,
14802     wuffs_base__io_buffer* a_src) {
14803   if (!self) {
14804     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
14805   }
14806   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
14807     return wuffs_base__make_status(
14808         (self->private_impl.magic == WUFFS_BASE__DISABLED)
14809             ? wuffs_base__error__disabled_by_previous_error
14810             : wuffs_base__error__initialize_not_called);
14811   }
14812 
14813   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
14814   int i;
14815   for (i = 0; i < 63; i++) {
14816     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
14817       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
14818           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
14819       return (*func_ptrs->decode_image_config)(self, a_dst, a_src);
14820     } else if (v->vtable_name == NULL) {
14821       break;
14822     }
14823     v++;
14824   }
14825 
14826   return wuffs_base__make_status(wuffs_base__error__bad_vtable);
14827 }
14828 
14829 WUFFS_BASE__GENERATED_C_CODE
14830 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
wuffs_base__image_decoder__frame_dirty_rect(const wuffs_base__image_decoder * self)14831 wuffs_base__image_decoder__frame_dirty_rect(
14832     const wuffs_base__image_decoder* self) {
14833   if (!self) {
14834     return wuffs_base__utility__empty_rect_ie_u32();
14835   }
14836   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
14837       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
14838     return wuffs_base__utility__empty_rect_ie_u32();
14839   }
14840 
14841   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
14842   int i;
14843   for (i = 0; i < 63; i++) {
14844     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
14845       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
14846           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
14847       return (*func_ptrs->frame_dirty_rect)(self);
14848     } else if (v->vtable_name == NULL) {
14849       break;
14850     }
14851     v++;
14852   }
14853 
14854   return wuffs_base__utility__empty_rect_ie_u32();
14855 }
14856 
14857 WUFFS_BASE__GENERATED_C_CODE
14858 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_base__image_decoder__get_quirk(const wuffs_base__image_decoder * self,uint32_t a_key)14859 wuffs_base__image_decoder__get_quirk(
14860     const wuffs_base__image_decoder* self,
14861     uint32_t a_key) {
14862   if (!self) {
14863     return 0;
14864   }
14865   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
14866       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
14867     return 0;
14868   }
14869 
14870   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
14871   int i;
14872   for (i = 0; i < 63; i++) {
14873     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
14874       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
14875           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
14876       return (*func_ptrs->get_quirk)(self, a_key);
14877     } else if (v->vtable_name == NULL) {
14878       break;
14879     }
14880     v++;
14881   }
14882 
14883   return 0;
14884 }
14885 
14886 WUFFS_BASE__GENERATED_C_CODE
14887 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_base__image_decoder__history_retain_length(const wuffs_base__image_decoder * self)14888 wuffs_base__image_decoder__history_retain_length(
14889     const wuffs_base__image_decoder* self) {
14890   if (!self) {
14891     return 0;
14892   }
14893   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
14894       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
14895     return 0;
14896   }
14897 
14898   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
14899   int i;
14900   for (i = 0; i < 63; i++) {
14901     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
14902       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
14903           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
14904       return (*func_ptrs->history_retain_length)(self);
14905     } else if (v->vtable_name == NULL) {
14906       break;
14907     }
14908     v++;
14909   }
14910 
14911   return 0;
14912 }
14913 
14914 WUFFS_BASE__GENERATED_C_CODE
14915 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_base__image_decoder__num_animation_loops(const wuffs_base__image_decoder * self)14916 wuffs_base__image_decoder__num_animation_loops(
14917     const wuffs_base__image_decoder* self) {
14918   if (!self) {
14919     return 0;
14920   }
14921   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
14922       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
14923     return 0;
14924   }
14925 
14926   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
14927   int i;
14928   for (i = 0; i < 63; i++) {
14929     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
14930       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
14931           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
14932       return (*func_ptrs->num_animation_loops)(self);
14933     } else if (v->vtable_name == NULL) {
14934       break;
14935     }
14936     v++;
14937   }
14938 
14939   return 0;
14940 }
14941 
14942 WUFFS_BASE__GENERATED_C_CODE
14943 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_base__image_decoder__num_decoded_frame_configs(const wuffs_base__image_decoder * self)14944 wuffs_base__image_decoder__num_decoded_frame_configs(
14945     const wuffs_base__image_decoder* self) {
14946   if (!self) {
14947     return 0;
14948   }
14949   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
14950       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
14951     return 0;
14952   }
14953 
14954   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
14955   int i;
14956   for (i = 0; i < 63; i++) {
14957     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
14958       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
14959           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
14960       return (*func_ptrs->num_decoded_frame_configs)(self);
14961     } else if (v->vtable_name == NULL) {
14962       break;
14963     }
14964     v++;
14965   }
14966 
14967   return 0;
14968 }
14969 
14970 WUFFS_BASE__GENERATED_C_CODE
14971 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_base__image_decoder__num_decoded_frames(const wuffs_base__image_decoder * self)14972 wuffs_base__image_decoder__num_decoded_frames(
14973     const wuffs_base__image_decoder* self) {
14974   if (!self) {
14975     return 0;
14976   }
14977   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
14978       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
14979     return 0;
14980   }
14981 
14982   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
14983   int i;
14984   for (i = 0; i < 63; i++) {
14985     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
14986       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
14987           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
14988       return (*func_ptrs->num_decoded_frames)(self);
14989     } else if (v->vtable_name == NULL) {
14990       break;
14991     }
14992     v++;
14993   }
14994 
14995   return 0;
14996 }
14997 
14998 WUFFS_BASE__GENERATED_C_CODE
14999 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_base__image_decoder__restart_frame(wuffs_base__image_decoder * self,uint64_t a_index,uint64_t a_io_position)15000 wuffs_base__image_decoder__restart_frame(
15001     wuffs_base__image_decoder* self,
15002     uint64_t a_index,
15003     uint64_t a_io_position) {
15004   if (!self) {
15005     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
15006   }
15007   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
15008     return wuffs_base__make_status(
15009         (self->private_impl.magic == WUFFS_BASE__DISABLED)
15010             ? wuffs_base__error__disabled_by_previous_error
15011             : wuffs_base__error__initialize_not_called);
15012   }
15013 
15014   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
15015   int i;
15016   for (i = 0; i < 63; i++) {
15017     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
15018       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
15019           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
15020       return (*func_ptrs->restart_frame)(self, a_index, a_io_position);
15021     } else if (v->vtable_name == NULL) {
15022       break;
15023     }
15024     v++;
15025   }
15026 
15027   return wuffs_base__make_status(wuffs_base__error__bad_vtable);
15028 }
15029 
15030 WUFFS_BASE__GENERATED_C_CODE
15031 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_base__image_decoder__set_quirk(wuffs_base__image_decoder * self,uint32_t a_key,uint64_t a_value)15032 wuffs_base__image_decoder__set_quirk(
15033     wuffs_base__image_decoder* self,
15034     uint32_t a_key,
15035     uint64_t a_value) {
15036   if (!self) {
15037     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
15038   }
15039   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
15040     return wuffs_base__make_status(
15041         (self->private_impl.magic == WUFFS_BASE__DISABLED)
15042             ? wuffs_base__error__disabled_by_previous_error
15043             : wuffs_base__error__initialize_not_called);
15044   }
15045 
15046   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
15047   int i;
15048   for (i = 0; i < 63; i++) {
15049     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
15050       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
15051           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
15052       return (*func_ptrs->set_quirk)(self, a_key, a_value);
15053     } else if (v->vtable_name == NULL) {
15054       break;
15055     }
15056     v++;
15057   }
15058 
15059   return wuffs_base__make_status(wuffs_base__error__bad_vtable);
15060 }
15061 
15062 WUFFS_BASE__GENERATED_C_CODE
15063 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_base__image_decoder__set_report_metadata(wuffs_base__image_decoder * self,uint32_t a_fourcc,bool a_report)15064 wuffs_base__image_decoder__set_report_metadata(
15065     wuffs_base__image_decoder* self,
15066     uint32_t a_fourcc,
15067     bool a_report) {
15068   if (!self) {
15069     return wuffs_base__make_empty_struct();
15070   }
15071   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
15072     return wuffs_base__make_empty_struct();
15073   }
15074 
15075   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
15076   int i;
15077   for (i = 0; i < 63; i++) {
15078     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
15079       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
15080           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
15081       return (*func_ptrs->set_report_metadata)(self, a_fourcc, a_report);
15082     } else if (v->vtable_name == NULL) {
15083       break;
15084     }
15085     v++;
15086   }
15087 
15088   return wuffs_base__make_empty_struct();
15089 }
15090 
15091 WUFFS_BASE__GENERATED_C_CODE
15092 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_base__image_decoder__tell_me_more(wuffs_base__image_decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__more_information * a_minfo,wuffs_base__io_buffer * a_src)15093 wuffs_base__image_decoder__tell_me_more(
15094     wuffs_base__image_decoder* self,
15095     wuffs_base__io_buffer* a_dst,
15096     wuffs_base__more_information* a_minfo,
15097     wuffs_base__io_buffer* a_src) {
15098   if (!self) {
15099     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
15100   }
15101   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
15102     return wuffs_base__make_status(
15103         (self->private_impl.magic == WUFFS_BASE__DISABLED)
15104             ? wuffs_base__error__disabled_by_previous_error
15105             : wuffs_base__error__initialize_not_called);
15106   }
15107 
15108   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
15109   int i;
15110   for (i = 0; i < 63; i++) {
15111     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
15112       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
15113           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
15114       return (*func_ptrs->tell_me_more)(self, a_dst, a_minfo, a_src);
15115     } else if (v->vtable_name == NULL) {
15116       break;
15117     }
15118     v++;
15119   }
15120 
15121   return wuffs_base__make_status(wuffs_base__error__bad_vtable);
15122 }
15123 
15124 WUFFS_BASE__GENERATED_C_CODE
15125 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_base__image_decoder__workbuf_len(const wuffs_base__image_decoder * self)15126 wuffs_base__image_decoder__workbuf_len(
15127     const wuffs_base__image_decoder* self) {
15128   if (!self) {
15129     return wuffs_base__utility__empty_range_ii_u64();
15130   }
15131   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
15132       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
15133     return wuffs_base__utility__empty_range_ii_u64();
15134   }
15135 
15136   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
15137   int i;
15138   for (i = 0; i < 63; i++) {
15139     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
15140       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
15141           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
15142       return (*func_ptrs->workbuf_len)(self);
15143     } else if (v->vtable_name == NULL) {
15144       break;
15145     }
15146     v++;
15147   }
15148 
15149   return wuffs_base__utility__empty_range_ii_u64();
15150 }
15151 
15152 // --------
15153 
15154 WUFFS_BASE__GENERATED_C_CODE
15155 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_base__io_transformer__get_quirk(const wuffs_base__io_transformer * self,uint32_t a_key)15156 wuffs_base__io_transformer__get_quirk(
15157     const wuffs_base__io_transformer* self,
15158     uint32_t a_key) {
15159   if (!self) {
15160     return 0;
15161   }
15162   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
15163       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
15164     return 0;
15165   }
15166 
15167   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
15168   int i;
15169   for (i = 0; i < 63; i++) {
15170     if (v->vtable_name == wuffs_base__io_transformer__vtable_name) {
15171       const wuffs_base__io_transformer__func_ptrs* func_ptrs =
15172           (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers);
15173       return (*func_ptrs->get_quirk)(self, a_key);
15174     } else if (v->vtable_name == NULL) {
15175       break;
15176     }
15177     v++;
15178   }
15179 
15180   return 0;
15181 }
15182 
15183 WUFFS_BASE__GENERATED_C_CODE
15184 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_base__io_transformer__history_retain_length(const wuffs_base__io_transformer * self)15185 wuffs_base__io_transformer__history_retain_length(
15186     const wuffs_base__io_transformer* self) {
15187   if (!self) {
15188     return 0;
15189   }
15190   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
15191       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
15192     return 0;
15193   }
15194 
15195   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
15196   int i;
15197   for (i = 0; i < 63; i++) {
15198     if (v->vtable_name == wuffs_base__io_transformer__vtable_name) {
15199       const wuffs_base__io_transformer__func_ptrs* func_ptrs =
15200           (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers);
15201       return (*func_ptrs->history_retain_length)(self);
15202     } else if (v->vtable_name == NULL) {
15203       break;
15204     }
15205     v++;
15206   }
15207 
15208   return 0;
15209 }
15210 
15211 WUFFS_BASE__GENERATED_C_CODE
15212 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_base__io_transformer__set_quirk(wuffs_base__io_transformer * self,uint32_t a_key,uint64_t a_value)15213 wuffs_base__io_transformer__set_quirk(
15214     wuffs_base__io_transformer* self,
15215     uint32_t a_key,
15216     uint64_t a_value) {
15217   if (!self) {
15218     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
15219   }
15220   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
15221     return wuffs_base__make_status(
15222         (self->private_impl.magic == WUFFS_BASE__DISABLED)
15223             ? wuffs_base__error__disabled_by_previous_error
15224             : wuffs_base__error__initialize_not_called);
15225   }
15226 
15227   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
15228   int i;
15229   for (i = 0; i < 63; i++) {
15230     if (v->vtable_name == wuffs_base__io_transformer__vtable_name) {
15231       const wuffs_base__io_transformer__func_ptrs* func_ptrs =
15232           (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers);
15233       return (*func_ptrs->set_quirk)(self, a_key, a_value);
15234     } else if (v->vtable_name == NULL) {
15235       break;
15236     }
15237     v++;
15238   }
15239 
15240   return wuffs_base__make_status(wuffs_base__error__bad_vtable);
15241 }
15242 
15243 WUFFS_BASE__GENERATED_C_CODE
15244 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_base__io_transformer__transform_io(wuffs_base__io_transformer * self,wuffs_base__io_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__slice_u8 a_workbuf)15245 wuffs_base__io_transformer__transform_io(
15246     wuffs_base__io_transformer* self,
15247     wuffs_base__io_buffer* a_dst,
15248     wuffs_base__io_buffer* a_src,
15249     wuffs_base__slice_u8 a_workbuf) {
15250   if (!self) {
15251     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
15252   }
15253   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
15254     return wuffs_base__make_status(
15255         (self->private_impl.magic == WUFFS_BASE__DISABLED)
15256             ? wuffs_base__error__disabled_by_previous_error
15257             : wuffs_base__error__initialize_not_called);
15258   }
15259 
15260   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
15261   int i;
15262   for (i = 0; i < 63; i++) {
15263     if (v->vtable_name == wuffs_base__io_transformer__vtable_name) {
15264       const wuffs_base__io_transformer__func_ptrs* func_ptrs =
15265           (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers);
15266       return (*func_ptrs->transform_io)(self, a_dst, a_src, a_workbuf);
15267     } else if (v->vtable_name == NULL) {
15268       break;
15269     }
15270     v++;
15271   }
15272 
15273   return wuffs_base__make_status(wuffs_base__error__bad_vtable);
15274 }
15275 
15276 WUFFS_BASE__GENERATED_C_CODE
15277 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_base__io_transformer__workbuf_len(const wuffs_base__io_transformer * self)15278 wuffs_base__io_transformer__workbuf_len(
15279     const wuffs_base__io_transformer* self) {
15280   if (!self) {
15281     return wuffs_base__utility__empty_range_ii_u64();
15282   }
15283   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
15284       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
15285     return wuffs_base__utility__empty_range_ii_u64();
15286   }
15287 
15288   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
15289   int i;
15290   for (i = 0; i < 63; i++) {
15291     if (v->vtable_name == wuffs_base__io_transformer__vtable_name) {
15292       const wuffs_base__io_transformer__func_ptrs* func_ptrs =
15293           (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers);
15294       return (*func_ptrs->workbuf_len)(self);
15295     } else if (v->vtable_name == NULL) {
15296       break;
15297     }
15298     v++;
15299   }
15300 
15301   return wuffs_base__utility__empty_range_ii_u64();
15302 }
15303 
15304 // --------
15305 
15306 WUFFS_BASE__GENERATED_C_CODE
15307 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_base__token_decoder__decode_tokens(wuffs_base__token_decoder * self,wuffs_base__token_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__slice_u8 a_workbuf)15308 wuffs_base__token_decoder__decode_tokens(
15309     wuffs_base__token_decoder* self,
15310     wuffs_base__token_buffer* a_dst,
15311     wuffs_base__io_buffer* a_src,
15312     wuffs_base__slice_u8 a_workbuf) {
15313   if (!self) {
15314     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
15315   }
15316   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
15317     return wuffs_base__make_status(
15318         (self->private_impl.magic == WUFFS_BASE__DISABLED)
15319             ? wuffs_base__error__disabled_by_previous_error
15320             : wuffs_base__error__initialize_not_called);
15321   }
15322 
15323   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
15324   int i;
15325   for (i = 0; i < 63; i++) {
15326     if (v->vtable_name == wuffs_base__token_decoder__vtable_name) {
15327       const wuffs_base__token_decoder__func_ptrs* func_ptrs =
15328           (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers);
15329       return (*func_ptrs->decode_tokens)(self, a_dst, a_src, a_workbuf);
15330     } else if (v->vtable_name == NULL) {
15331       break;
15332     }
15333     v++;
15334   }
15335 
15336   return wuffs_base__make_status(wuffs_base__error__bad_vtable);
15337 }
15338 
15339 WUFFS_BASE__GENERATED_C_CODE
15340 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_base__token_decoder__get_quirk(const wuffs_base__token_decoder * self,uint32_t a_key)15341 wuffs_base__token_decoder__get_quirk(
15342     const wuffs_base__token_decoder* self,
15343     uint32_t a_key) {
15344   if (!self) {
15345     return 0;
15346   }
15347   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
15348       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
15349     return 0;
15350   }
15351 
15352   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
15353   int i;
15354   for (i = 0; i < 63; i++) {
15355     if (v->vtable_name == wuffs_base__token_decoder__vtable_name) {
15356       const wuffs_base__token_decoder__func_ptrs* func_ptrs =
15357           (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers);
15358       return (*func_ptrs->get_quirk)(self, a_key);
15359     } else if (v->vtable_name == NULL) {
15360       break;
15361     }
15362     v++;
15363   }
15364 
15365   return 0;
15366 }
15367 
15368 WUFFS_BASE__GENERATED_C_CODE
15369 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_base__token_decoder__history_retain_length(const wuffs_base__token_decoder * self)15370 wuffs_base__token_decoder__history_retain_length(
15371     const wuffs_base__token_decoder* self) {
15372   if (!self) {
15373     return 0;
15374   }
15375   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
15376       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
15377     return 0;
15378   }
15379 
15380   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
15381   int i;
15382   for (i = 0; i < 63; i++) {
15383     if (v->vtable_name == wuffs_base__token_decoder__vtable_name) {
15384       const wuffs_base__token_decoder__func_ptrs* func_ptrs =
15385           (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers);
15386       return (*func_ptrs->history_retain_length)(self);
15387     } else if (v->vtable_name == NULL) {
15388       break;
15389     }
15390     v++;
15391   }
15392 
15393   return 0;
15394 }
15395 
15396 WUFFS_BASE__GENERATED_C_CODE
15397 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_base__token_decoder__set_quirk(wuffs_base__token_decoder * self,uint32_t a_key,uint64_t a_value)15398 wuffs_base__token_decoder__set_quirk(
15399     wuffs_base__token_decoder* self,
15400     uint32_t a_key,
15401     uint64_t a_value) {
15402   if (!self) {
15403     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
15404   }
15405   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
15406     return wuffs_base__make_status(
15407         (self->private_impl.magic == WUFFS_BASE__DISABLED)
15408             ? wuffs_base__error__disabled_by_previous_error
15409             : wuffs_base__error__initialize_not_called);
15410   }
15411 
15412   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
15413   int i;
15414   for (i = 0; i < 63; i++) {
15415     if (v->vtable_name == wuffs_base__token_decoder__vtable_name) {
15416       const wuffs_base__token_decoder__func_ptrs* func_ptrs =
15417           (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers);
15418       return (*func_ptrs->set_quirk)(self, a_key, a_value);
15419     } else if (v->vtable_name == NULL) {
15420       break;
15421     }
15422     v++;
15423   }
15424 
15425   return wuffs_base__make_status(wuffs_base__error__bad_vtable);
15426 }
15427 
15428 WUFFS_BASE__GENERATED_C_CODE
15429 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_base__token_decoder__workbuf_len(const wuffs_base__token_decoder * self)15430 wuffs_base__token_decoder__workbuf_len(
15431     const wuffs_base__token_decoder* self) {
15432   if (!self) {
15433     return wuffs_base__utility__empty_range_ii_u64();
15434   }
15435   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
15436       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
15437     return wuffs_base__utility__empty_range_ii_u64();
15438   }
15439 
15440   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
15441   int i;
15442   for (i = 0; i < 63; i++) {
15443     if (v->vtable_name == wuffs_base__token_decoder__vtable_name) {
15444       const wuffs_base__token_decoder__func_ptrs* func_ptrs =
15445           (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers);
15446       return (*func_ptrs->workbuf_len)(self);
15447     } else if (v->vtable_name == NULL) {
15448       break;
15449     }
15450     v++;
15451   }
15452 
15453   return wuffs_base__utility__empty_range_ii_u64();
15454 }
15455 
15456 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
15457         // defined(WUFFS_CONFIG__MODULE__BASE) ||
15458         // defined(WUFFS_CONFIG__MODULE__BASE__INTERFACES)
15459 
15460 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
15461     defined(WUFFS_CONFIG__MODULE__BASE__FLOATCONV)
15462 
15463 // ---------------- IEEE 754 Floating Point
15464 
15465 // The etc__hpd_left_shift and etc__powers_of_5 tables were printed by
15466 // script/print-hpd-left-shift.go. That script has an optional -comments flag,
15467 // whose output is not copied here, which prints further detail.
15468 //
15469 // These tables are used in
15470 // wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits.
15471 
15472 // wuffs_base__private_implementation__hpd_left_shift[i] encodes the number of
15473 // new digits created after multiplying a positive integer by (1 << i): the
15474 // additional length in the decimal representation. For example, shifting "234"
15475 // by 3 (equivalent to multiplying by 8) will produce "1872". Going from a
15476 // 3-length string to a 4-length string means that 1 new digit was added (and
15477 // existing digits may have changed).
15478 //
15479 // Shifting by i can add either N or N-1 new digits, depending on whether the
15480 // original positive integer compares >= or < to the i'th power of 5 (as 10
15481 // equals 2 * 5). Comparison is lexicographic, not numerical.
15482 //
15483 // For example, shifting by 4 (i.e. multiplying by 16) can add 1 or 2 new
15484 // digits, depending on a lexicographic comparison to (5 ** 4), i.e. "625":
15485 //  - ("1"      << 4) is "16",       which adds 1 new digit.
15486 //  - ("5678"   << 4) is "90848",    which adds 1 new digit.
15487 //  - ("624"    << 4) is "9984",     which adds 1 new digit.
15488 //  - ("62498"  << 4) is "999968",   which adds 1 new digit.
15489 //  - ("625"    << 4) is "10000",    which adds 2 new digits.
15490 //  - ("625001" << 4) is "10000016", which adds 2 new digits.
15491 //  - ("7008"   << 4) is "112128",   which adds 2 new digits.
15492 //  - ("99"     << 4) is "1584",     which adds 2 new digits.
15493 //
15494 // Thus, when i is 4, N is 2 and (5 ** i) is "625". This etc__hpd_left_shift
15495 // array encodes this as:
15496 //  - etc__hpd_left_shift[4] is 0x1006 = (2 << 11) | 0x0006.
15497 //  - etc__hpd_left_shift[5] is 0x1009 = (? << 11) | 0x0009.
15498 // where the ? isn't relevant for i == 4.
15499 //
15500 // The high 5 bits of etc__hpd_left_shift[i] is N, the higher of the two
15501 // possible number of new digits. The low 11 bits are an offset into the
15502 // etc__powers_of_5 array (of length 0x051C, so offsets fit in 11 bits). When i
15503 // is 4, its offset and the next one is 6 and 9, and etc__powers_of_5[6 .. 9]
15504 // is the string "\x06\x02\x05", so the relevant power of 5 is "625".
15505 //
15506 // Thanks to Ken Thompson for the original idea.
15507 static const uint16_t wuffs_base__private_implementation__hpd_left_shift[65] = {
15508     0x0000, 0x0800, 0x0801, 0x0803, 0x1006, 0x1009, 0x100D, 0x1812, 0x1817,
15509     0x181D, 0x2024, 0x202B, 0x2033, 0x203C, 0x2846, 0x2850, 0x285B, 0x3067,
15510     0x3073, 0x3080, 0x388E, 0x389C, 0x38AB, 0x38BB, 0x40CC, 0x40DD, 0x40EF,
15511     0x4902, 0x4915, 0x4929, 0x513E, 0x5153, 0x5169, 0x5180, 0x5998, 0x59B0,
15512     0x59C9, 0x61E3, 0x61FD, 0x6218, 0x6A34, 0x6A50, 0x6A6D, 0x6A8B, 0x72AA,
15513     0x72C9, 0x72E9, 0x7B0A, 0x7B2B, 0x7B4D, 0x8370, 0x8393, 0x83B7, 0x83DC,
15514     0x8C02, 0x8C28, 0x8C4F, 0x9477, 0x949F, 0x94C8, 0x9CF2, 0x051C, 0x051C,
15515     0x051C, 0x051C,
15516 };
15517 
15518 // wuffs_base__private_implementation__powers_of_5 contains the powers of 5,
15519 // concatenated together: "5", "25", "125", "625", "3125", etc.
15520 static const uint8_t wuffs_base__private_implementation__powers_of_5[0x051C] = {
15521     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,
15522     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,
15523     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,
15524     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,
15525     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,
15526     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,
15527     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,
15528     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,
15529     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,
15530     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,
15531     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,
15532     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,
15533     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,
15534     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,
15535     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,
15536     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,
15537     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,
15538     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,
15539     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,
15540     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,
15541     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,
15542     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,
15543     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,
15544     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,
15545     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,
15546     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,
15547     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,
15548     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,
15549     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,
15550     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,
15551     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,
15552     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,
15553     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,
15554     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,
15555     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,
15556     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,
15557     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,
15558     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,
15559     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,
15560     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,
15561     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,
15562     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,
15563     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,
15564     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,
15565     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,
15566     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,
15567     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,
15568     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,
15569     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,
15570     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,
15571     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,
15572     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,
15573     6, 9, 1, 4, 0, 6, 2, 5,
15574 };
15575 
15576 // --------
15577 
15578 // wuffs_base__private_implementation__powers_of_10 contains truncated
15579 // approximations to the powers of 10, ranging from 1e-307 to 1e+288 inclusive,
15580 // as 596 pairs of uint64_t values (a 128-bit mantissa).
15581 //
15582 // There's also an implicit third column (implied by a linear formula involving
15583 // the base-10 exponent) that is the base-2 exponent, biased by a magic
15584 // constant. That constant (1214 or 0x04BE) equals 1023 + 191. 1023 is the bias
15585 // for IEEE 754 double-precision floating point. 191 is ((3 * 64) - 1) and
15586 // wuffs_base__private_implementation__parse_number_f64_eisel_lemire works with
15587 // multiples-of-64-bit mantissas.
15588 //
15589 // For example, the third row holds the approximation to 1e-305:
15590 //   0xE0B62E29_29ABA83C_331ACDAB_FE94DE87 * (2 ** (0x0049 - 0x04BE))
15591 //
15592 // Similarly, 1e+4 is approximated by:
15593 //   0x9C400000_00000000_00000000_00000000 * (2 ** (0x044C - 0x04BE))
15594 //
15595 // Similarly, 1e+68 is approximated by:
15596 //   0xED63A231_D4C4FB27_4CA7AAA8_63EE4BDD * (2 ** (0x0520 - 0x04BE))
15597 //
15598 // This table was generated by by script/print-mpb-powers-of-10.go
15599 static const uint64_t wuffs_base__private_implementation__powers_of_10[596][2] =
15600     {
15601         {0xA5D3B6D479F8E056, 0x8FD0C16206306BAB},  // 1e-307
15602         {0x8F48A4899877186C, 0xB3C4F1BA87BC8696},  // 1e-306
15603         {0x331ACDABFE94DE87, 0xE0B62E2929ABA83C},  // 1e-305
15604         {0x9FF0C08B7F1D0B14, 0x8C71DCD9BA0B4925},  // 1e-304
15605         {0x07ECF0AE5EE44DD9, 0xAF8E5410288E1B6F},  // 1e-303
15606         {0xC9E82CD9F69D6150, 0xDB71E91432B1A24A},  // 1e-302
15607         {0xBE311C083A225CD2, 0x892731AC9FAF056E},  // 1e-301
15608         {0x6DBD630A48AAF406, 0xAB70FE17C79AC6CA},  // 1e-300
15609         {0x092CBBCCDAD5B108, 0xD64D3D9DB981787D},  // 1e-299
15610         {0x25BBF56008C58EA5, 0x85F0468293F0EB4E},  // 1e-298
15611         {0xAF2AF2B80AF6F24E, 0xA76C582338ED2621},  // 1e-297
15612         {0x1AF5AF660DB4AEE1, 0xD1476E2C07286FAA},  // 1e-296
15613         {0x50D98D9FC890ED4D, 0x82CCA4DB847945CA},  // 1e-295
15614         {0xE50FF107BAB528A0, 0xA37FCE126597973C},  // 1e-294
15615         {0x1E53ED49A96272C8, 0xCC5FC196FEFD7D0C},  // 1e-293
15616         {0x25E8E89C13BB0F7A, 0xFF77B1FCBEBCDC4F},  // 1e-292
15617         {0x77B191618C54E9AC, 0x9FAACF3DF73609B1},  // 1e-291
15618         {0xD59DF5B9EF6A2417, 0xC795830D75038C1D},  // 1e-290
15619         {0x4B0573286B44AD1D, 0xF97AE3D0D2446F25},  // 1e-289
15620         {0x4EE367F9430AEC32, 0x9BECCE62836AC577},  // 1e-288
15621         {0x229C41F793CDA73F, 0xC2E801FB244576D5},  // 1e-287
15622         {0x6B43527578C1110F, 0xF3A20279ED56D48A},  // 1e-286
15623         {0x830A13896B78AAA9, 0x9845418C345644D6},  // 1e-285
15624         {0x23CC986BC656D553, 0xBE5691EF416BD60C},  // 1e-284
15625         {0x2CBFBE86B7EC8AA8, 0xEDEC366B11C6CB8F},  // 1e-283
15626         {0x7BF7D71432F3D6A9, 0x94B3A202EB1C3F39},  // 1e-282
15627         {0xDAF5CCD93FB0CC53, 0xB9E08A83A5E34F07},  // 1e-281
15628         {0xD1B3400F8F9CFF68, 0xE858AD248F5C22C9},  // 1e-280
15629         {0x23100809B9C21FA1, 0x91376C36D99995BE},  // 1e-279
15630         {0xABD40A0C2832A78A, 0xB58547448FFFFB2D},  // 1e-278
15631         {0x16C90C8F323F516C, 0xE2E69915B3FFF9F9},  // 1e-277
15632         {0xAE3DA7D97F6792E3, 0x8DD01FAD907FFC3B},  // 1e-276
15633         {0x99CD11CFDF41779C, 0xB1442798F49FFB4A},  // 1e-275
15634         {0x40405643D711D583, 0xDD95317F31C7FA1D},  // 1e-274
15635         {0x482835EA666B2572, 0x8A7D3EEF7F1CFC52},  // 1e-273
15636         {0xDA3243650005EECF, 0xAD1C8EAB5EE43B66},  // 1e-272
15637         {0x90BED43E40076A82, 0xD863B256369D4A40},  // 1e-271
15638         {0x5A7744A6E804A291, 0x873E4F75E2224E68},  // 1e-270
15639         {0x711515D0A205CB36, 0xA90DE3535AAAE202},  // 1e-269
15640         {0x0D5A5B44CA873E03, 0xD3515C2831559A83},  // 1e-268
15641         {0xE858790AFE9486C2, 0x8412D9991ED58091},  // 1e-267
15642         {0x626E974DBE39A872, 0xA5178FFF668AE0B6},  // 1e-266
15643         {0xFB0A3D212DC8128F, 0xCE5D73FF402D98E3},  // 1e-265
15644         {0x7CE66634BC9D0B99, 0x80FA687F881C7F8E},  // 1e-264
15645         {0x1C1FFFC1EBC44E80, 0xA139029F6A239F72},  // 1e-263
15646         {0xA327FFB266B56220, 0xC987434744AC874E},  // 1e-262
15647         {0x4BF1FF9F0062BAA8, 0xFBE9141915D7A922},  // 1e-261
15648         {0x6F773FC3603DB4A9, 0x9D71AC8FADA6C9B5},  // 1e-260
15649         {0xCB550FB4384D21D3, 0xC4CE17B399107C22},  // 1e-259
15650         {0x7E2A53A146606A48, 0xF6019DA07F549B2B},  // 1e-258
15651         {0x2EDA7444CBFC426D, 0x99C102844F94E0FB},  // 1e-257
15652         {0xFA911155FEFB5308, 0xC0314325637A1939},  // 1e-256
15653         {0x793555AB7EBA27CA, 0xF03D93EEBC589F88},  // 1e-255
15654         {0x4BC1558B2F3458DE, 0x96267C7535B763B5},  // 1e-254
15655         {0x9EB1AAEDFB016F16, 0xBBB01B9283253CA2},  // 1e-253
15656         {0x465E15A979C1CADC, 0xEA9C227723EE8BCB},  // 1e-252
15657         {0x0BFACD89EC191EC9, 0x92A1958A7675175F},  // 1e-251
15658         {0xCEF980EC671F667B, 0xB749FAED14125D36},  // 1e-250
15659         {0x82B7E12780E7401A, 0xE51C79A85916F484},  // 1e-249
15660         {0xD1B2ECB8B0908810, 0x8F31CC0937AE58D2},  // 1e-248
15661         {0x861FA7E6DCB4AA15, 0xB2FE3F0B8599EF07},  // 1e-247
15662         {0x67A791E093E1D49A, 0xDFBDCECE67006AC9},  // 1e-246
15663         {0xE0C8BB2C5C6D24E0, 0x8BD6A141006042BD},  // 1e-245
15664         {0x58FAE9F773886E18, 0xAECC49914078536D},  // 1e-244
15665         {0xAF39A475506A899E, 0xDA7F5BF590966848},  // 1e-243
15666         {0x6D8406C952429603, 0x888F99797A5E012D},  // 1e-242
15667         {0xC8E5087BA6D33B83, 0xAAB37FD7D8F58178},  // 1e-241
15668         {0xFB1E4A9A90880A64, 0xD5605FCDCF32E1D6},  // 1e-240
15669         {0x5CF2EEA09A55067F, 0x855C3BE0A17FCD26},  // 1e-239
15670         {0xF42FAA48C0EA481E, 0xA6B34AD8C9DFC06F},  // 1e-238
15671         {0xF13B94DAF124DA26, 0xD0601D8EFC57B08B},  // 1e-237
15672         {0x76C53D08D6B70858, 0x823C12795DB6CE57},  // 1e-236
15673         {0x54768C4B0C64CA6E, 0xA2CB1717B52481ED},  // 1e-235
15674         {0xA9942F5DCF7DFD09, 0xCB7DDCDDA26DA268},  // 1e-234
15675         {0xD3F93B35435D7C4C, 0xFE5D54150B090B02},  // 1e-233
15676         {0xC47BC5014A1A6DAF, 0x9EFA548D26E5A6E1},  // 1e-232
15677         {0x359AB6419CA1091B, 0xC6B8E9B0709F109A},  // 1e-231
15678         {0xC30163D203C94B62, 0xF867241C8CC6D4C0},  // 1e-230
15679         {0x79E0DE63425DCF1D, 0x9B407691D7FC44F8},  // 1e-229
15680         {0x985915FC12F542E4, 0xC21094364DFB5636},  // 1e-228
15681         {0x3E6F5B7B17B2939D, 0xF294B943E17A2BC4},  // 1e-227
15682         {0xA705992CEECF9C42, 0x979CF3CA6CEC5B5A},  // 1e-226
15683         {0x50C6FF782A838353, 0xBD8430BD08277231},  // 1e-225
15684         {0xA4F8BF5635246428, 0xECE53CEC4A314EBD},  // 1e-224
15685         {0x871B7795E136BE99, 0x940F4613AE5ED136},  // 1e-223
15686         {0x28E2557B59846E3F, 0xB913179899F68584},  // 1e-222
15687         {0x331AEADA2FE589CF, 0xE757DD7EC07426E5},  // 1e-221
15688         {0x3FF0D2C85DEF7621, 0x9096EA6F3848984F},  // 1e-220
15689         {0x0FED077A756B53A9, 0xB4BCA50B065ABE63},  // 1e-219
15690         {0xD3E8495912C62894, 0xE1EBCE4DC7F16DFB},  // 1e-218
15691         {0x64712DD7ABBBD95C, 0x8D3360F09CF6E4BD},  // 1e-217
15692         {0xBD8D794D96AACFB3, 0xB080392CC4349DEC},  // 1e-216
15693         {0xECF0D7A0FC5583A0, 0xDCA04777F541C567},  // 1e-215
15694         {0xF41686C49DB57244, 0x89E42CAAF9491B60},  // 1e-214
15695         {0x311C2875C522CED5, 0xAC5D37D5B79B6239},  // 1e-213
15696         {0x7D633293366B828B, 0xD77485CB25823AC7},  // 1e-212
15697         {0xAE5DFF9C02033197, 0x86A8D39EF77164BC},  // 1e-211
15698         {0xD9F57F830283FDFC, 0xA8530886B54DBDEB},  // 1e-210
15699         {0xD072DF63C324FD7B, 0xD267CAA862A12D66},  // 1e-209
15700         {0x4247CB9E59F71E6D, 0x8380DEA93DA4BC60},  // 1e-208
15701         {0x52D9BE85F074E608, 0xA46116538D0DEB78},  // 1e-207
15702         {0x67902E276C921F8B, 0xCD795BE870516656},  // 1e-206
15703         {0x00BA1CD8A3DB53B6, 0x806BD9714632DFF6},  // 1e-205
15704         {0x80E8A40ECCD228A4, 0xA086CFCD97BF97F3},  // 1e-204
15705         {0x6122CD128006B2CD, 0xC8A883C0FDAF7DF0},  // 1e-203
15706         {0x796B805720085F81, 0xFAD2A4B13D1B5D6C},  // 1e-202
15707         {0xCBE3303674053BB0, 0x9CC3A6EEC6311A63},  // 1e-201
15708         {0xBEDBFC4411068A9C, 0xC3F490AA77BD60FC},  // 1e-200
15709         {0xEE92FB5515482D44, 0xF4F1B4D515ACB93B},  // 1e-199
15710         {0x751BDD152D4D1C4A, 0x991711052D8BF3C5},  // 1e-198
15711         {0xD262D45A78A0635D, 0xBF5CD54678EEF0B6},  // 1e-197
15712         {0x86FB897116C87C34, 0xEF340A98172AACE4},  // 1e-196
15713         {0xD45D35E6AE3D4DA0, 0x9580869F0E7AAC0E},  // 1e-195
15714         {0x8974836059CCA109, 0xBAE0A846D2195712},  // 1e-194
15715         {0x2BD1A438703FC94B, 0xE998D258869FACD7},  // 1e-193
15716         {0x7B6306A34627DDCF, 0x91FF83775423CC06},  // 1e-192
15717         {0x1A3BC84C17B1D542, 0xB67F6455292CBF08},  // 1e-191
15718         {0x20CABA5F1D9E4A93, 0xE41F3D6A7377EECA},  // 1e-190
15719         {0x547EB47B7282EE9C, 0x8E938662882AF53E},  // 1e-189
15720         {0xE99E619A4F23AA43, 0xB23867FB2A35B28D},  // 1e-188
15721         {0x6405FA00E2EC94D4, 0xDEC681F9F4C31F31},  // 1e-187
15722         {0xDE83BC408DD3DD04, 0x8B3C113C38F9F37E},  // 1e-186
15723         {0x9624AB50B148D445, 0xAE0B158B4738705E},  // 1e-185
15724         {0x3BADD624DD9B0957, 0xD98DDAEE19068C76},  // 1e-184
15725         {0xE54CA5D70A80E5D6, 0x87F8A8D4CFA417C9},  // 1e-183
15726         {0x5E9FCF4CCD211F4C, 0xA9F6D30A038D1DBC},  // 1e-182
15727         {0x7647C3200069671F, 0xD47487CC8470652B},  // 1e-181
15728         {0x29ECD9F40041E073, 0x84C8D4DFD2C63F3B},  // 1e-180
15729         {0xF468107100525890, 0xA5FB0A17C777CF09},  // 1e-179
15730         {0x7182148D4066EEB4, 0xCF79CC9DB955C2CC},  // 1e-178
15731         {0xC6F14CD848405530, 0x81AC1FE293D599BF},  // 1e-177
15732         {0xB8ADA00E5A506A7C, 0xA21727DB38CB002F},  // 1e-176
15733         {0xA6D90811F0E4851C, 0xCA9CF1D206FDC03B},  // 1e-175
15734         {0x908F4A166D1DA663, 0xFD442E4688BD304A},  // 1e-174
15735         {0x9A598E4E043287FE, 0x9E4A9CEC15763E2E},  // 1e-173
15736         {0x40EFF1E1853F29FD, 0xC5DD44271AD3CDBA},  // 1e-172
15737         {0xD12BEE59E68EF47C, 0xF7549530E188C128},  // 1e-171
15738         {0x82BB74F8301958CE, 0x9A94DD3E8CF578B9},  // 1e-170
15739         {0xE36A52363C1FAF01, 0xC13A148E3032D6E7},  // 1e-169
15740         {0xDC44E6C3CB279AC1, 0xF18899B1BC3F8CA1},  // 1e-168
15741         {0x29AB103A5EF8C0B9, 0x96F5600F15A7B7E5},  // 1e-167
15742         {0x7415D448F6B6F0E7, 0xBCB2B812DB11A5DE},  // 1e-166
15743         {0x111B495B3464AD21, 0xEBDF661791D60F56},  // 1e-165
15744         {0xCAB10DD900BEEC34, 0x936B9FCEBB25C995},  // 1e-164
15745         {0x3D5D514F40EEA742, 0xB84687C269EF3BFB},  // 1e-163
15746         {0x0CB4A5A3112A5112, 0xE65829B3046B0AFA},  // 1e-162
15747         {0x47F0E785EABA72AB, 0x8FF71A0FE2C2E6DC},  // 1e-161
15748         {0x59ED216765690F56, 0xB3F4E093DB73A093},  // 1e-160
15749         {0x306869C13EC3532C, 0xE0F218B8D25088B8},  // 1e-159
15750         {0x1E414218C73A13FB, 0x8C974F7383725573},  // 1e-158
15751         {0xE5D1929EF90898FA, 0xAFBD2350644EEACF},  // 1e-157
15752         {0xDF45F746B74ABF39, 0xDBAC6C247D62A583},  // 1e-156
15753         {0x6B8BBA8C328EB783, 0x894BC396CE5DA772},  // 1e-155
15754         {0x066EA92F3F326564, 0xAB9EB47C81F5114F},  // 1e-154
15755         {0xC80A537B0EFEFEBD, 0xD686619BA27255A2},  // 1e-153
15756         {0xBD06742CE95F5F36, 0x8613FD0145877585},  // 1e-152
15757         {0x2C48113823B73704, 0xA798FC4196E952E7},  // 1e-151
15758         {0xF75A15862CA504C5, 0xD17F3B51FCA3A7A0},  // 1e-150
15759         {0x9A984D73DBE722FB, 0x82EF85133DE648C4},  // 1e-149
15760         {0xC13E60D0D2E0EBBA, 0xA3AB66580D5FDAF5},  // 1e-148
15761         {0x318DF905079926A8, 0xCC963FEE10B7D1B3},  // 1e-147
15762         {0xFDF17746497F7052, 0xFFBBCFE994E5C61F},  // 1e-146
15763         {0xFEB6EA8BEDEFA633, 0x9FD561F1FD0F9BD3},  // 1e-145
15764         {0xFE64A52EE96B8FC0, 0xC7CABA6E7C5382C8},  // 1e-144
15765         {0x3DFDCE7AA3C673B0, 0xF9BD690A1B68637B},  // 1e-143
15766         {0x06BEA10CA65C084E, 0x9C1661A651213E2D},  // 1e-142
15767         {0x486E494FCFF30A62, 0xC31BFA0FE5698DB8},  // 1e-141
15768         {0x5A89DBA3C3EFCCFA, 0xF3E2F893DEC3F126},  // 1e-140
15769         {0xF89629465A75E01C, 0x986DDB5C6B3A76B7},  // 1e-139
15770         {0xF6BBB397F1135823, 0xBE89523386091465},  // 1e-138
15771         {0x746AA07DED582E2C, 0xEE2BA6C0678B597F},  // 1e-137
15772         {0xA8C2A44EB4571CDC, 0x94DB483840B717EF},  // 1e-136
15773         {0x92F34D62616CE413, 0xBA121A4650E4DDEB},  // 1e-135
15774         {0x77B020BAF9C81D17, 0xE896A0D7E51E1566},  // 1e-134
15775         {0x0ACE1474DC1D122E, 0x915E2486EF32CD60},  // 1e-133
15776         {0x0D819992132456BA, 0xB5B5ADA8AAFF80B8},  // 1e-132
15777         {0x10E1FFF697ED6C69, 0xE3231912D5BF60E6},  // 1e-131
15778         {0xCA8D3FFA1EF463C1, 0x8DF5EFABC5979C8F},  // 1e-130
15779         {0xBD308FF8A6B17CB2, 0xB1736B96B6FD83B3},  // 1e-129
15780         {0xAC7CB3F6D05DDBDE, 0xDDD0467C64BCE4A0},  // 1e-128
15781         {0x6BCDF07A423AA96B, 0x8AA22C0DBEF60EE4},  // 1e-127
15782         {0x86C16C98D2C953C6, 0xAD4AB7112EB3929D},  // 1e-126
15783         {0xE871C7BF077BA8B7, 0xD89D64D57A607744},  // 1e-125
15784         {0x11471CD764AD4972, 0x87625F056C7C4A8B},  // 1e-124
15785         {0xD598E40D3DD89BCF, 0xA93AF6C6C79B5D2D},  // 1e-123
15786         {0x4AFF1D108D4EC2C3, 0xD389B47879823479},  // 1e-122
15787         {0xCEDF722A585139BA, 0x843610CB4BF160CB},  // 1e-121
15788         {0xC2974EB4EE658828, 0xA54394FE1EEDB8FE},  // 1e-120
15789         {0x733D226229FEEA32, 0xCE947A3DA6A9273E},  // 1e-119
15790         {0x0806357D5A3F525F, 0x811CCC668829B887},  // 1e-118
15791         {0xCA07C2DCB0CF26F7, 0xA163FF802A3426A8},  // 1e-117
15792         {0xFC89B393DD02F0B5, 0xC9BCFF6034C13052},  // 1e-116
15793         {0xBBAC2078D443ACE2, 0xFC2C3F3841F17C67},  // 1e-115
15794         {0xD54B944B84AA4C0D, 0x9D9BA7832936EDC0},  // 1e-114
15795         {0x0A9E795E65D4DF11, 0xC5029163F384A931},  // 1e-113
15796         {0x4D4617B5FF4A16D5, 0xF64335BCF065D37D},  // 1e-112
15797         {0x504BCED1BF8E4E45, 0x99EA0196163FA42E},  // 1e-111
15798         {0xE45EC2862F71E1D6, 0xC06481FB9BCF8D39},  // 1e-110
15799         {0x5D767327BB4E5A4C, 0xF07DA27A82C37088},  // 1e-109
15800         {0x3A6A07F8D510F86F, 0x964E858C91BA2655},  // 1e-108
15801         {0x890489F70A55368B, 0xBBE226EFB628AFEA},  // 1e-107
15802         {0x2B45AC74CCEA842E, 0xEADAB0ABA3B2DBE5},  // 1e-106
15803         {0x3B0B8BC90012929D, 0x92C8AE6B464FC96F},  // 1e-105
15804         {0x09CE6EBB40173744, 0xB77ADA0617E3BBCB},  // 1e-104
15805         {0xCC420A6A101D0515, 0xE55990879DDCAABD},  // 1e-103
15806         {0x9FA946824A12232D, 0x8F57FA54C2A9EAB6},  // 1e-102
15807         {0x47939822DC96ABF9, 0xB32DF8E9F3546564},  // 1e-101
15808         {0x59787E2B93BC56F7, 0xDFF9772470297EBD},  // 1e-100
15809         {0x57EB4EDB3C55B65A, 0x8BFBEA76C619EF36},  // 1e-99
15810         {0xEDE622920B6B23F1, 0xAEFAE51477A06B03},  // 1e-98
15811         {0xE95FAB368E45ECED, 0xDAB99E59958885C4},  // 1e-97
15812         {0x11DBCB0218EBB414, 0x88B402F7FD75539B},  // 1e-96
15813         {0xD652BDC29F26A119, 0xAAE103B5FCD2A881},  // 1e-95
15814         {0x4BE76D3346F0495F, 0xD59944A37C0752A2},  // 1e-94
15815         {0x6F70A4400C562DDB, 0x857FCAE62D8493A5},  // 1e-93
15816         {0xCB4CCD500F6BB952, 0xA6DFBD9FB8E5B88E},  // 1e-92
15817         {0x7E2000A41346A7A7, 0xD097AD07A71F26B2},  // 1e-91
15818         {0x8ED400668C0C28C8, 0x825ECC24C873782F},  // 1e-90
15819         {0x728900802F0F32FA, 0xA2F67F2DFA90563B},  // 1e-89
15820         {0x4F2B40A03AD2FFB9, 0xCBB41EF979346BCA},  // 1e-88
15821         {0xE2F610C84987BFA8, 0xFEA126B7D78186BC},  // 1e-87
15822         {0x0DD9CA7D2DF4D7C9, 0x9F24B832E6B0F436},  // 1e-86
15823         {0x91503D1C79720DBB, 0xC6EDE63FA05D3143},  // 1e-85
15824         {0x75A44C6397CE912A, 0xF8A95FCF88747D94},  // 1e-84
15825         {0xC986AFBE3EE11ABA, 0x9B69DBE1B548CE7C},  // 1e-83
15826         {0xFBE85BADCE996168, 0xC24452DA229B021B},  // 1e-82
15827         {0xFAE27299423FB9C3, 0xF2D56790AB41C2A2},  // 1e-81
15828         {0xDCCD879FC967D41A, 0x97C560BA6B0919A5},  // 1e-80
15829         {0x5400E987BBC1C920, 0xBDB6B8E905CB600F},  // 1e-79
15830         {0x290123E9AAB23B68, 0xED246723473E3813},  // 1e-78
15831         {0xF9A0B6720AAF6521, 0x9436C0760C86E30B},  // 1e-77
15832         {0xF808E40E8D5B3E69, 0xB94470938FA89BCE},  // 1e-76
15833         {0xB60B1D1230B20E04, 0xE7958CB87392C2C2},  // 1e-75
15834         {0xB1C6F22B5E6F48C2, 0x90BD77F3483BB9B9},  // 1e-74
15835         {0x1E38AEB6360B1AF3, 0xB4ECD5F01A4AA828},  // 1e-73
15836         {0x25C6DA63C38DE1B0, 0xE2280B6C20DD5232},  // 1e-72
15837         {0x579C487E5A38AD0E, 0x8D590723948A535F},  // 1e-71
15838         {0x2D835A9DF0C6D851, 0xB0AF48EC79ACE837},  // 1e-70
15839         {0xF8E431456CF88E65, 0xDCDB1B2798182244},  // 1e-69
15840         {0x1B8E9ECB641B58FF, 0x8A08F0F8BF0F156B},  // 1e-68
15841         {0xE272467E3D222F3F, 0xAC8B2D36EED2DAC5},  // 1e-67
15842         {0x5B0ED81DCC6ABB0F, 0xD7ADF884AA879177},  // 1e-66
15843         {0x98E947129FC2B4E9, 0x86CCBB52EA94BAEA},  // 1e-65
15844         {0x3F2398D747B36224, 0xA87FEA27A539E9A5},  // 1e-64
15845         {0x8EEC7F0D19A03AAD, 0xD29FE4B18E88640E},  // 1e-63
15846         {0x1953CF68300424AC, 0x83A3EEEEF9153E89},  // 1e-62
15847         {0x5FA8C3423C052DD7, 0xA48CEAAAB75A8E2B},  // 1e-61
15848         {0x3792F412CB06794D, 0xCDB02555653131B6},  // 1e-60
15849         {0xE2BBD88BBEE40BD0, 0x808E17555F3EBF11},  // 1e-59
15850         {0x5B6ACEAEAE9D0EC4, 0xA0B19D2AB70E6ED6},  // 1e-58
15851         {0xF245825A5A445275, 0xC8DE047564D20A8B},  // 1e-57
15852         {0xEED6E2F0F0D56712, 0xFB158592BE068D2E},  // 1e-56
15853         {0x55464DD69685606B, 0x9CED737BB6C4183D},  // 1e-55
15854         {0xAA97E14C3C26B886, 0xC428D05AA4751E4C},  // 1e-54
15855         {0xD53DD99F4B3066A8, 0xF53304714D9265DF},  // 1e-53
15856         {0xE546A8038EFE4029, 0x993FE2C6D07B7FAB},  // 1e-52
15857         {0xDE98520472BDD033, 0xBF8FDB78849A5F96},  // 1e-51
15858         {0x963E66858F6D4440, 0xEF73D256A5C0F77C},  // 1e-50
15859         {0xDDE7001379A44AA8, 0x95A8637627989AAD},  // 1e-49
15860         {0x5560C018580D5D52, 0xBB127C53B17EC159},  // 1e-48
15861         {0xAAB8F01E6E10B4A6, 0xE9D71B689DDE71AF},  // 1e-47
15862         {0xCAB3961304CA70E8, 0x9226712162AB070D},  // 1e-46
15863         {0x3D607B97C5FD0D22, 0xB6B00D69BB55C8D1},  // 1e-45
15864         {0x8CB89A7DB77C506A, 0xE45C10C42A2B3B05},  // 1e-44
15865         {0x77F3608E92ADB242, 0x8EB98A7A9A5B04E3},  // 1e-43
15866         {0x55F038B237591ED3, 0xB267ED1940F1C61C},  // 1e-42
15867         {0x6B6C46DEC52F6688, 0xDF01E85F912E37A3},  // 1e-41
15868         {0x2323AC4B3B3DA015, 0x8B61313BBABCE2C6},  // 1e-40
15869         {0xABEC975E0A0D081A, 0xAE397D8AA96C1B77},  // 1e-39
15870         {0x96E7BD358C904A21, 0xD9C7DCED53C72255},  // 1e-38
15871         {0x7E50D64177DA2E54, 0x881CEA14545C7575},  // 1e-37
15872         {0xDDE50BD1D5D0B9E9, 0xAA242499697392D2},  // 1e-36
15873         {0x955E4EC64B44E864, 0xD4AD2DBFC3D07787},  // 1e-35
15874         {0xBD5AF13BEF0B113E, 0x84EC3C97DA624AB4},  // 1e-34
15875         {0xECB1AD8AEACDD58E, 0xA6274BBDD0FADD61},  // 1e-33
15876         {0x67DE18EDA5814AF2, 0xCFB11EAD453994BA},  // 1e-32
15877         {0x80EACF948770CED7, 0x81CEB32C4B43FCF4},  // 1e-31
15878         {0xA1258379A94D028D, 0xA2425FF75E14FC31},  // 1e-30
15879         {0x096EE45813A04330, 0xCAD2F7F5359A3B3E},  // 1e-29
15880         {0x8BCA9D6E188853FC, 0xFD87B5F28300CA0D},  // 1e-28
15881         {0x775EA264CF55347D, 0x9E74D1B791E07E48},  // 1e-27
15882         {0x95364AFE032A819D, 0xC612062576589DDA},  // 1e-26
15883         {0x3A83DDBD83F52204, 0xF79687AED3EEC551},  // 1e-25
15884         {0xC4926A9672793542, 0x9ABE14CD44753B52},  // 1e-24
15885         {0x75B7053C0F178293, 0xC16D9A0095928A27},  // 1e-23
15886         {0x5324C68B12DD6338, 0xF1C90080BAF72CB1},  // 1e-22
15887         {0xD3F6FC16EBCA5E03, 0x971DA05074DA7BEE},  // 1e-21
15888         {0x88F4BB1CA6BCF584, 0xBCE5086492111AEA},  // 1e-20
15889         {0x2B31E9E3D06C32E5, 0xEC1E4A7DB69561A5},  // 1e-19
15890         {0x3AFF322E62439FCF, 0x9392EE8E921D5D07},  // 1e-18
15891         {0x09BEFEB9FAD487C2, 0xB877AA3236A4B449},  // 1e-17
15892         {0x4C2EBE687989A9B3, 0xE69594BEC44DE15B},  // 1e-16
15893         {0x0F9D37014BF60A10, 0x901D7CF73AB0ACD9},  // 1e-15
15894         {0x538484C19EF38C94, 0xB424DC35095CD80F},  // 1e-14
15895         {0x2865A5F206B06FB9, 0xE12E13424BB40E13},  // 1e-13
15896         {0xF93F87B7442E45D3, 0x8CBCCC096F5088CB},  // 1e-12
15897         {0xF78F69A51539D748, 0xAFEBFF0BCB24AAFE},  // 1e-11
15898         {0xB573440E5A884D1B, 0xDBE6FECEBDEDD5BE},  // 1e-10
15899         {0x31680A88F8953030, 0x89705F4136B4A597},  // 1e-9
15900         {0xFDC20D2B36BA7C3D, 0xABCC77118461CEFC},  // 1e-8
15901         {0x3D32907604691B4C, 0xD6BF94D5E57A42BC},  // 1e-7
15902         {0xA63F9A49C2C1B10F, 0x8637BD05AF6C69B5},  // 1e-6
15903         {0x0FCF80DC33721D53, 0xA7C5AC471B478423},  // 1e-5
15904         {0xD3C36113404EA4A8, 0xD1B71758E219652B},  // 1e-4
15905         {0x645A1CAC083126E9, 0x83126E978D4FDF3B},  // 1e-3
15906         {0x3D70A3D70A3D70A3, 0xA3D70A3D70A3D70A},  // 1e-2
15907         {0xCCCCCCCCCCCCCCCC, 0xCCCCCCCCCCCCCCCC},  // 1e-1
15908         {0x0000000000000000, 0x8000000000000000},  // 1e0
15909         {0x0000000000000000, 0xA000000000000000},  // 1e1
15910         {0x0000000000000000, 0xC800000000000000},  // 1e2
15911         {0x0000000000000000, 0xFA00000000000000},  // 1e3
15912         {0x0000000000000000, 0x9C40000000000000},  // 1e4
15913         {0x0000000000000000, 0xC350000000000000},  // 1e5
15914         {0x0000000000000000, 0xF424000000000000},  // 1e6
15915         {0x0000000000000000, 0x9896800000000000},  // 1e7
15916         {0x0000000000000000, 0xBEBC200000000000},  // 1e8
15917         {0x0000000000000000, 0xEE6B280000000000},  // 1e9
15918         {0x0000000000000000, 0x9502F90000000000},  // 1e10
15919         {0x0000000000000000, 0xBA43B74000000000},  // 1e11
15920         {0x0000000000000000, 0xE8D4A51000000000},  // 1e12
15921         {0x0000000000000000, 0x9184E72A00000000},  // 1e13
15922         {0x0000000000000000, 0xB5E620F480000000},  // 1e14
15923         {0x0000000000000000, 0xE35FA931A0000000},  // 1e15
15924         {0x0000000000000000, 0x8E1BC9BF04000000},  // 1e16
15925         {0x0000000000000000, 0xB1A2BC2EC5000000},  // 1e17
15926         {0x0000000000000000, 0xDE0B6B3A76400000},  // 1e18
15927         {0x0000000000000000, 0x8AC7230489E80000},  // 1e19
15928         {0x0000000000000000, 0xAD78EBC5AC620000},  // 1e20
15929         {0x0000000000000000, 0xD8D726B7177A8000},  // 1e21
15930         {0x0000000000000000, 0x878678326EAC9000},  // 1e22
15931         {0x0000000000000000, 0xA968163F0A57B400},  // 1e23
15932         {0x0000000000000000, 0xD3C21BCECCEDA100},  // 1e24
15933         {0x0000000000000000, 0x84595161401484A0},  // 1e25
15934         {0x0000000000000000, 0xA56FA5B99019A5C8},  // 1e26
15935         {0x0000000000000000, 0xCECB8F27F4200F3A},  // 1e27
15936         {0x4000000000000000, 0x813F3978F8940984},  // 1e28
15937         {0x5000000000000000, 0xA18F07D736B90BE5},  // 1e29
15938         {0xA400000000000000, 0xC9F2C9CD04674EDE},  // 1e30
15939         {0x4D00000000000000, 0xFC6F7C4045812296},  // 1e31
15940         {0xF020000000000000, 0x9DC5ADA82B70B59D},  // 1e32
15941         {0x6C28000000000000, 0xC5371912364CE305},  // 1e33
15942         {0xC732000000000000, 0xF684DF56C3E01BC6},  // 1e34
15943         {0x3C7F400000000000, 0x9A130B963A6C115C},  // 1e35
15944         {0x4B9F100000000000, 0xC097CE7BC90715B3},  // 1e36
15945         {0x1E86D40000000000, 0xF0BDC21ABB48DB20},  // 1e37
15946         {0x1314448000000000, 0x96769950B50D88F4},  // 1e38
15947         {0x17D955A000000000, 0xBC143FA4E250EB31},  // 1e39
15948         {0x5DCFAB0800000000, 0xEB194F8E1AE525FD},  // 1e40
15949         {0x5AA1CAE500000000, 0x92EFD1B8D0CF37BE},  // 1e41
15950         {0xF14A3D9E40000000, 0xB7ABC627050305AD},  // 1e42
15951         {0x6D9CCD05D0000000, 0xE596B7B0C643C719},  // 1e43
15952         {0xE4820023A2000000, 0x8F7E32CE7BEA5C6F},  // 1e44
15953         {0xDDA2802C8A800000, 0xB35DBF821AE4F38B},  // 1e45
15954         {0xD50B2037AD200000, 0xE0352F62A19E306E},  // 1e46
15955         {0x4526F422CC340000, 0x8C213D9DA502DE45},  // 1e47
15956         {0x9670B12B7F410000, 0xAF298D050E4395D6},  // 1e48
15957         {0x3C0CDD765F114000, 0xDAF3F04651D47B4C},  // 1e49
15958         {0xA5880A69FB6AC800, 0x88D8762BF324CD0F},  // 1e50
15959         {0x8EEA0D047A457A00, 0xAB0E93B6EFEE0053},  // 1e51
15960         {0x72A4904598D6D880, 0xD5D238A4ABE98068},  // 1e52
15961         {0x47A6DA2B7F864750, 0x85A36366EB71F041},  // 1e53
15962         {0x999090B65F67D924, 0xA70C3C40A64E6C51},  // 1e54
15963         {0xFFF4B4E3F741CF6D, 0xD0CF4B50CFE20765},  // 1e55
15964         {0xBFF8F10E7A8921A4, 0x82818F1281ED449F},  // 1e56
15965         {0xAFF72D52192B6A0D, 0xA321F2D7226895C7},  // 1e57
15966         {0x9BF4F8A69F764490, 0xCBEA6F8CEB02BB39},  // 1e58
15967         {0x02F236D04753D5B4, 0xFEE50B7025C36A08},  // 1e59
15968         {0x01D762422C946590, 0x9F4F2726179A2245},  // 1e60
15969         {0x424D3AD2B7B97EF5, 0xC722F0EF9D80AAD6},  // 1e61
15970         {0xD2E0898765A7DEB2, 0xF8EBAD2B84E0D58B},  // 1e62
15971         {0x63CC55F49F88EB2F, 0x9B934C3B330C8577},  // 1e63
15972         {0x3CBF6B71C76B25FB, 0xC2781F49FFCFA6D5},  // 1e64
15973         {0x8BEF464E3945EF7A, 0xF316271C7FC3908A},  // 1e65
15974         {0x97758BF0E3CBB5AC, 0x97EDD871CFDA3A56},  // 1e66
15975         {0x3D52EEED1CBEA317, 0xBDE94E8E43D0C8EC},  // 1e67
15976         {0x4CA7AAA863EE4BDD, 0xED63A231D4C4FB27},  // 1e68
15977         {0x8FE8CAA93E74EF6A, 0x945E455F24FB1CF8},  // 1e69
15978         {0xB3E2FD538E122B44, 0xB975D6B6EE39E436},  // 1e70
15979         {0x60DBBCA87196B616, 0xE7D34C64A9C85D44},  // 1e71
15980         {0xBC8955E946FE31CD, 0x90E40FBEEA1D3A4A},  // 1e72
15981         {0x6BABAB6398BDBE41, 0xB51D13AEA4A488DD},  // 1e73
15982         {0xC696963C7EED2DD1, 0xE264589A4DCDAB14},  // 1e74
15983         {0xFC1E1DE5CF543CA2, 0x8D7EB76070A08AEC},  // 1e75
15984         {0x3B25A55F43294BCB, 0xB0DE65388CC8ADA8},  // 1e76
15985         {0x49EF0EB713F39EBE, 0xDD15FE86AFFAD912},  // 1e77
15986         {0x6E3569326C784337, 0x8A2DBF142DFCC7AB},  // 1e78
15987         {0x49C2C37F07965404, 0xACB92ED9397BF996},  // 1e79
15988         {0xDC33745EC97BE906, 0xD7E77A8F87DAF7FB},  // 1e80
15989         {0x69A028BB3DED71A3, 0x86F0AC99B4E8DAFD},  // 1e81
15990         {0xC40832EA0D68CE0C, 0xA8ACD7C0222311BC},  // 1e82
15991         {0xF50A3FA490C30190, 0xD2D80DB02AABD62B},  // 1e83
15992         {0x792667C6DA79E0FA, 0x83C7088E1AAB65DB},  // 1e84
15993         {0x577001B891185938, 0xA4B8CAB1A1563F52},  // 1e85
15994         {0xED4C0226B55E6F86, 0xCDE6FD5E09ABCF26},  // 1e86
15995         {0x544F8158315B05B4, 0x80B05E5AC60B6178},  // 1e87
15996         {0x696361AE3DB1C721, 0xA0DC75F1778E39D6},  // 1e88
15997         {0x03BC3A19CD1E38E9, 0xC913936DD571C84C},  // 1e89
15998         {0x04AB48A04065C723, 0xFB5878494ACE3A5F},  // 1e90
15999         {0x62EB0D64283F9C76, 0x9D174B2DCEC0E47B},  // 1e91
16000         {0x3BA5D0BD324F8394, 0xC45D1DF942711D9A},  // 1e92
16001         {0xCA8F44EC7EE36479, 0xF5746577930D6500},  // 1e93
16002         {0x7E998B13CF4E1ECB, 0x9968BF6ABBE85F20},  // 1e94
16003         {0x9E3FEDD8C321A67E, 0xBFC2EF456AE276E8},  // 1e95
16004         {0xC5CFE94EF3EA101E, 0xEFB3AB16C59B14A2},  // 1e96
16005         {0xBBA1F1D158724A12, 0x95D04AEE3B80ECE5},  // 1e97
16006         {0x2A8A6E45AE8EDC97, 0xBB445DA9CA61281F},  // 1e98
16007         {0xF52D09D71A3293BD, 0xEA1575143CF97226},  // 1e99
16008         {0x593C2626705F9C56, 0x924D692CA61BE758},  // 1e100
16009         {0x6F8B2FB00C77836C, 0xB6E0C377CFA2E12E},  // 1e101
16010         {0x0B6DFB9C0F956447, 0xE498F455C38B997A},  // 1e102
16011         {0x4724BD4189BD5EAC, 0x8EDF98B59A373FEC},  // 1e103
16012         {0x58EDEC91EC2CB657, 0xB2977EE300C50FE7},  // 1e104
16013         {0x2F2967B66737E3ED, 0xDF3D5E9BC0F653E1},  // 1e105
16014         {0xBD79E0D20082EE74, 0x8B865B215899F46C},  // 1e106
16015         {0xECD8590680A3AA11, 0xAE67F1E9AEC07187},  // 1e107
16016         {0xE80E6F4820CC9495, 0xDA01EE641A708DE9},  // 1e108
16017         {0x3109058D147FDCDD, 0x884134FE908658B2},  // 1e109
16018         {0xBD4B46F0599FD415, 0xAA51823E34A7EEDE},  // 1e110
16019         {0x6C9E18AC7007C91A, 0xD4E5E2CDC1D1EA96},  // 1e111
16020         {0x03E2CF6BC604DDB0, 0x850FADC09923329E},  // 1e112
16021         {0x84DB8346B786151C, 0xA6539930BF6BFF45},  // 1e113
16022         {0xE612641865679A63, 0xCFE87F7CEF46FF16},  // 1e114
16023         {0x4FCB7E8F3F60C07E, 0x81F14FAE158C5F6E},  // 1e115
16024         {0xE3BE5E330F38F09D, 0xA26DA3999AEF7749},  // 1e116
16025         {0x5CADF5BFD3072CC5, 0xCB090C8001AB551C},  // 1e117
16026         {0x73D9732FC7C8F7F6, 0xFDCB4FA002162A63},  // 1e118
16027         {0x2867E7FDDCDD9AFA, 0x9E9F11C4014DDA7E},  // 1e119
16028         {0xB281E1FD541501B8, 0xC646D63501A1511D},  // 1e120
16029         {0x1F225A7CA91A4226, 0xF7D88BC24209A565},  // 1e121
16030         {0x3375788DE9B06958, 0x9AE757596946075F},  // 1e122
16031         {0x0052D6B1641C83AE, 0xC1A12D2FC3978937},  // 1e123
16032         {0xC0678C5DBD23A49A, 0xF209787BB47D6B84},  // 1e124
16033         {0xF840B7BA963646E0, 0x9745EB4D50CE6332},  // 1e125
16034         {0xB650E5A93BC3D898, 0xBD176620A501FBFF},  // 1e126
16035         {0xA3E51F138AB4CEBE, 0xEC5D3FA8CE427AFF},  // 1e127
16036         {0xC66F336C36B10137, 0x93BA47C980E98CDF},  // 1e128
16037         {0xB80B0047445D4184, 0xB8A8D9BBE123F017},  // 1e129
16038         {0xA60DC059157491E5, 0xE6D3102AD96CEC1D},  // 1e130
16039         {0x87C89837AD68DB2F, 0x9043EA1AC7E41392},  // 1e131
16040         {0x29BABE4598C311FB, 0xB454E4A179DD1877},  // 1e132
16041         {0xF4296DD6FEF3D67A, 0xE16A1DC9D8545E94},  // 1e133
16042         {0x1899E4A65F58660C, 0x8CE2529E2734BB1D},  // 1e134
16043         {0x5EC05DCFF72E7F8F, 0xB01AE745B101E9E4},  // 1e135
16044         {0x76707543F4FA1F73, 0xDC21A1171D42645D},  // 1e136
16045         {0x6A06494A791C53A8, 0x899504AE72497EBA},  // 1e137
16046         {0x0487DB9D17636892, 0xABFA45DA0EDBDE69},  // 1e138
16047         {0x45A9D2845D3C42B6, 0xD6F8D7509292D603},  // 1e139
16048         {0x0B8A2392BA45A9B2, 0x865B86925B9BC5C2},  // 1e140
16049         {0x8E6CAC7768D7141E, 0xA7F26836F282B732},  // 1e141
16050         {0x3207D795430CD926, 0xD1EF0244AF2364FF},  // 1e142
16051         {0x7F44E6BD49E807B8, 0x8335616AED761F1F},  // 1e143
16052         {0x5F16206C9C6209A6, 0xA402B9C5A8D3A6E7},  // 1e144
16053         {0x36DBA887C37A8C0F, 0xCD036837130890A1},  // 1e145
16054         {0xC2494954DA2C9789, 0x802221226BE55A64},  // 1e146
16055         {0xF2DB9BAA10B7BD6C, 0xA02AA96B06DEB0FD},  // 1e147
16056         {0x6F92829494E5ACC7, 0xC83553C5C8965D3D},  // 1e148
16057         {0xCB772339BA1F17F9, 0xFA42A8B73ABBF48C},  // 1e149
16058         {0xFF2A760414536EFB, 0x9C69A97284B578D7},  // 1e150
16059         {0xFEF5138519684ABA, 0xC38413CF25E2D70D},  // 1e151
16060         {0x7EB258665FC25D69, 0xF46518C2EF5B8CD1},  // 1e152
16061         {0xEF2F773FFBD97A61, 0x98BF2F79D5993802},  // 1e153
16062         {0xAAFB550FFACFD8FA, 0xBEEEFB584AFF8603},  // 1e154
16063         {0x95BA2A53F983CF38, 0xEEAABA2E5DBF6784},  // 1e155
16064         {0xDD945A747BF26183, 0x952AB45CFA97A0B2},  // 1e156
16065         {0x94F971119AEEF9E4, 0xBA756174393D88DF},  // 1e157
16066         {0x7A37CD5601AAB85D, 0xE912B9D1478CEB17},  // 1e158
16067         {0xAC62E055C10AB33A, 0x91ABB422CCB812EE},  // 1e159
16068         {0x577B986B314D6009, 0xB616A12B7FE617AA},  // 1e160
16069         {0xED5A7E85FDA0B80B, 0xE39C49765FDF9D94},  // 1e161
16070         {0x14588F13BE847307, 0x8E41ADE9FBEBC27D},  // 1e162
16071         {0x596EB2D8AE258FC8, 0xB1D219647AE6B31C},  // 1e163
16072         {0x6FCA5F8ED9AEF3BB, 0xDE469FBD99A05FE3},  // 1e164
16073         {0x25DE7BB9480D5854, 0x8AEC23D680043BEE},  // 1e165
16074         {0xAF561AA79A10AE6A, 0xADA72CCC20054AE9},  // 1e166
16075         {0x1B2BA1518094DA04, 0xD910F7FF28069DA4},  // 1e167
16076         {0x90FB44D2F05D0842, 0x87AA9AFF79042286},  // 1e168
16077         {0x353A1607AC744A53, 0xA99541BF57452B28},  // 1e169
16078         {0x42889B8997915CE8, 0xD3FA922F2D1675F2},  // 1e170
16079         {0x69956135FEBADA11, 0x847C9B5D7C2E09B7},  // 1e171
16080         {0x43FAB9837E699095, 0xA59BC234DB398C25},  // 1e172
16081         {0x94F967E45E03F4BB, 0xCF02B2C21207EF2E},  // 1e173
16082         {0x1D1BE0EEBAC278F5, 0x8161AFB94B44F57D},  // 1e174
16083         {0x6462D92A69731732, 0xA1BA1BA79E1632DC},  // 1e175
16084         {0x7D7B8F7503CFDCFE, 0xCA28A291859BBF93},  // 1e176
16085         {0x5CDA735244C3D43E, 0xFCB2CB35E702AF78},  // 1e177
16086         {0x3A0888136AFA64A7, 0x9DEFBF01B061ADAB},  // 1e178
16087         {0x088AAA1845B8FDD0, 0xC56BAEC21C7A1916},  // 1e179
16088         {0x8AAD549E57273D45, 0xF6C69A72A3989F5B},  // 1e180
16089         {0x36AC54E2F678864B, 0x9A3C2087A63F6399},  // 1e181
16090         {0x84576A1BB416A7DD, 0xC0CB28A98FCF3C7F},  // 1e182
16091         {0x656D44A2A11C51D5, 0xF0FDF2D3F3C30B9F},  // 1e183
16092         {0x9F644AE5A4B1B325, 0x969EB7C47859E743},  // 1e184
16093         {0x873D5D9F0DDE1FEE, 0xBC4665B596706114},  // 1e185
16094         {0xA90CB506D155A7EA, 0xEB57FF22FC0C7959},  // 1e186
16095         {0x09A7F12442D588F2, 0x9316FF75DD87CBD8},  // 1e187
16096         {0x0C11ED6D538AEB2F, 0xB7DCBF5354E9BECE},  // 1e188
16097         {0x8F1668C8A86DA5FA, 0xE5D3EF282A242E81},  // 1e189
16098         {0xF96E017D694487BC, 0x8FA475791A569D10},  // 1e190
16099         {0x37C981DCC395A9AC, 0xB38D92D760EC4455},  // 1e191
16100         {0x85BBE253F47B1417, 0xE070F78D3927556A},  // 1e192
16101         {0x93956D7478CCEC8E, 0x8C469AB843B89562},  // 1e193
16102         {0x387AC8D1970027B2, 0xAF58416654A6BABB},  // 1e194
16103         {0x06997B05FCC0319E, 0xDB2E51BFE9D0696A},  // 1e195
16104         {0x441FECE3BDF81F03, 0x88FCF317F22241E2},  // 1e196
16105         {0xD527E81CAD7626C3, 0xAB3C2FDDEEAAD25A},  // 1e197
16106         {0x8A71E223D8D3B074, 0xD60B3BD56A5586F1},  // 1e198
16107         {0xF6872D5667844E49, 0x85C7056562757456},  // 1e199
16108         {0xB428F8AC016561DB, 0xA738C6BEBB12D16C},  // 1e200
16109         {0xE13336D701BEBA52, 0xD106F86E69D785C7},  // 1e201
16110         {0xECC0024661173473, 0x82A45B450226B39C},  // 1e202
16111         {0x27F002D7F95D0190, 0xA34D721642B06084},  // 1e203
16112         {0x31EC038DF7B441F4, 0xCC20CE9BD35C78A5},  // 1e204
16113         {0x7E67047175A15271, 0xFF290242C83396CE},  // 1e205
16114         {0x0F0062C6E984D386, 0x9F79A169BD203E41},  // 1e206
16115         {0x52C07B78A3E60868, 0xC75809C42C684DD1},  // 1e207
16116         {0xA7709A56CCDF8A82, 0xF92E0C3537826145},  // 1e208
16117         {0x88A66076400BB691, 0x9BBCC7A142B17CCB},  // 1e209
16118         {0x6ACFF893D00EA435, 0xC2ABF989935DDBFE},  // 1e210
16119         {0x0583F6B8C4124D43, 0xF356F7EBF83552FE},  // 1e211
16120         {0xC3727A337A8B704A, 0x98165AF37B2153DE},  // 1e212
16121         {0x744F18C0592E4C5C, 0xBE1BF1B059E9A8D6},  // 1e213
16122         {0x1162DEF06F79DF73, 0xEDA2EE1C7064130C},  // 1e214
16123         {0x8ADDCB5645AC2BA8, 0x9485D4D1C63E8BE7},  // 1e215
16124         {0x6D953E2BD7173692, 0xB9A74A0637CE2EE1},  // 1e216
16125         {0xC8FA8DB6CCDD0437, 0xE8111C87C5C1BA99},  // 1e217
16126         {0x1D9C9892400A22A2, 0x910AB1D4DB9914A0},  // 1e218
16127         {0x2503BEB6D00CAB4B, 0xB54D5E4A127F59C8},  // 1e219
16128         {0x2E44AE64840FD61D, 0xE2A0B5DC971F303A},  // 1e220
16129         {0x5CEAECFED289E5D2, 0x8DA471A9DE737E24},  // 1e221
16130         {0x7425A83E872C5F47, 0xB10D8E1456105DAD},  // 1e222
16131         {0xD12F124E28F77719, 0xDD50F1996B947518},  // 1e223
16132         {0x82BD6B70D99AAA6F, 0x8A5296FFE33CC92F},  // 1e224
16133         {0x636CC64D1001550B, 0xACE73CBFDC0BFB7B},  // 1e225
16134         {0x3C47F7E05401AA4E, 0xD8210BEFD30EFA5A},  // 1e226
16135         {0x65ACFAEC34810A71, 0x8714A775E3E95C78},  // 1e227
16136         {0x7F1839A741A14D0D, 0xA8D9D1535CE3B396},  // 1e228
16137         {0x1EDE48111209A050, 0xD31045A8341CA07C},  // 1e229
16138         {0x934AED0AAB460432, 0x83EA2B892091E44D},  // 1e230
16139         {0xF81DA84D5617853F, 0xA4E4B66B68B65D60},  // 1e231
16140         {0x36251260AB9D668E, 0xCE1DE40642E3F4B9},  // 1e232
16141         {0xC1D72B7C6B426019, 0x80D2AE83E9CE78F3},  // 1e233
16142         {0xB24CF65B8612F81F, 0xA1075A24E4421730},  // 1e234
16143         {0xDEE033F26797B627, 0xC94930AE1D529CFC},  // 1e235
16144         {0x169840EF017DA3B1, 0xFB9B7CD9A4A7443C},  // 1e236
16145         {0x8E1F289560EE864E, 0x9D412E0806E88AA5},  // 1e237
16146         {0xF1A6F2BAB92A27E2, 0xC491798A08A2AD4E},  // 1e238
16147         {0xAE10AF696774B1DB, 0xF5B5D7EC8ACB58A2},  // 1e239
16148         {0xACCA6DA1E0A8EF29, 0x9991A6F3D6BF1765},  // 1e240
16149         {0x17FD090A58D32AF3, 0xBFF610B0CC6EDD3F},  // 1e241
16150         {0xDDFC4B4CEF07F5B0, 0xEFF394DCFF8A948E},  // 1e242
16151         {0x4ABDAF101564F98E, 0x95F83D0A1FB69CD9},  // 1e243
16152         {0x9D6D1AD41ABE37F1, 0xBB764C4CA7A4440F},  // 1e244
16153         {0x84C86189216DC5ED, 0xEA53DF5FD18D5513},  // 1e245
16154         {0x32FD3CF5B4E49BB4, 0x92746B9BE2F8552C},  // 1e246
16155         {0x3FBC8C33221DC2A1, 0xB7118682DBB66A77},  // 1e247
16156         {0x0FABAF3FEAA5334A, 0xE4D5E82392A40515},  // 1e248
16157         {0x29CB4D87F2A7400E, 0x8F05B1163BA6832D},  // 1e249
16158         {0x743E20E9EF511012, 0xB2C71D5BCA9023F8},  // 1e250
16159         {0x914DA9246B255416, 0xDF78E4B2BD342CF6},  // 1e251
16160         {0x1AD089B6C2F7548E, 0x8BAB8EEFB6409C1A},  // 1e252
16161         {0xA184AC2473B529B1, 0xAE9672ABA3D0C320},  // 1e253
16162         {0xC9E5D72D90A2741E, 0xDA3C0F568CC4F3E8},  // 1e254
16163         {0x7E2FA67C7A658892, 0x8865899617FB1871},  // 1e255
16164         {0xDDBB901B98FEEAB7, 0xAA7EEBFB9DF9DE8D},  // 1e256
16165         {0x552A74227F3EA565, 0xD51EA6FA85785631},  // 1e257
16166         {0xD53A88958F87275F, 0x8533285C936B35DE},  // 1e258
16167         {0x8A892ABAF368F137, 0xA67FF273B8460356},  // 1e259
16168         {0x2D2B7569B0432D85, 0xD01FEF10A657842C},  // 1e260
16169         {0x9C3B29620E29FC73, 0x8213F56A67F6B29B},  // 1e261
16170         {0x8349F3BA91B47B8F, 0xA298F2C501F45F42},  // 1e262
16171         {0x241C70A936219A73, 0xCB3F2F7642717713},  // 1e263
16172         {0xED238CD383AA0110, 0xFE0EFB53D30DD4D7},  // 1e264
16173         {0xF4363804324A40AA, 0x9EC95D1463E8A506},  // 1e265
16174         {0xB143C6053EDCD0D5, 0xC67BB4597CE2CE48},  // 1e266
16175         {0xDD94B7868E94050A, 0xF81AA16FDC1B81DA},  // 1e267
16176         {0xCA7CF2B4191C8326, 0x9B10A4E5E9913128},  // 1e268
16177         {0xFD1C2F611F63A3F0, 0xC1D4CE1F63F57D72},  // 1e269
16178         {0xBC633B39673C8CEC, 0xF24A01A73CF2DCCF},  // 1e270
16179         {0xD5BE0503E085D813, 0x976E41088617CA01},  // 1e271
16180         {0x4B2D8644D8A74E18, 0xBD49D14AA79DBC82},  // 1e272
16181         {0xDDF8E7D60ED1219E, 0xEC9C459D51852BA2},  // 1e273
16182         {0xCABB90E5C942B503, 0x93E1AB8252F33B45},  // 1e274
16183         {0x3D6A751F3B936243, 0xB8DA1662E7B00A17},  // 1e275
16184         {0x0CC512670A783AD4, 0xE7109BFBA19C0C9D},  // 1e276
16185         {0x27FB2B80668B24C5, 0x906A617D450187E2},  // 1e277
16186         {0xB1F9F660802DEDF6, 0xB484F9DC9641E9DA},  // 1e278
16187         {0x5E7873F8A0396973, 0xE1A63853BBD26451},  // 1e279
16188         {0xDB0B487B6423E1E8, 0x8D07E33455637EB2},  // 1e280
16189         {0x91CE1A9A3D2CDA62, 0xB049DC016ABC5E5F},  // 1e281
16190         {0x7641A140CC7810FB, 0xDC5C5301C56B75F7},  // 1e282
16191         {0xA9E904C87FCB0A9D, 0x89B9B3E11B6329BA},  // 1e283
16192         {0x546345FA9FBDCD44, 0xAC2820D9623BF429},  // 1e284
16193         {0xA97C177947AD4095, 0xD732290FBACAF133},  // 1e285
16194         {0x49ED8EABCCCC485D, 0x867F59A9D4BED6C0},  // 1e286
16195         {0x5C68F256BFFF5A74, 0xA81F301449EE8C70},  // 1e287
16196         {0x73832EEC6FFF3111, 0xD226FC195C6A2F8C},  // 1e288
16197 };
16198 
16199 // wuffs_base__private_implementation__f64_powers_of_10 holds powers of 10 that
16200 // can be exactly represented by a float64 (what C calls a double).
16201 static const double wuffs_base__private_implementation__f64_powers_of_10[23] = {
16202     1e0,  1e1,  1e2,  1e3,  1e4,  1e5,  1e6,  1e7,  1e8,  1e9,  1e10, 1e11,
16203     1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22,
16204 };
16205 
16206 // ---------------- IEEE 754 Floating Point
16207 
16208 WUFFS_BASE__MAYBE_STATIC wuffs_base__lossy_value_u16  //
wuffs_base__ieee_754_bit_representation__from_f64_to_u16_truncate(double f)16209 wuffs_base__ieee_754_bit_representation__from_f64_to_u16_truncate(double f) {
16210   uint64_t u = 0;
16211   if (sizeof(uint64_t) == sizeof(double)) {
16212     memcpy(&u, &f, sizeof(uint64_t));
16213   }
16214   uint16_t neg = ((uint16_t)((u >> 63) << 15));
16215   u &= 0x7FFFFFFFFFFFFFFF;
16216   uint64_t exp = u >> 52;
16217   uint64_t man = u & 0x000FFFFFFFFFFFFF;
16218 
16219   if (exp == 0x7FF) {
16220     if (man == 0) {  // Infinity.
16221       wuffs_base__lossy_value_u16 ret;
16222       ret.value = neg | 0x7C00;
16223       ret.lossy = false;
16224       return ret;
16225     }
16226     // NaN. Shift the 52 mantissa bits to 10 mantissa bits, keeping the most
16227     // significant mantissa bit (quiet vs signaling NaNs). Also set the low 9
16228     // bits of ret.value so that the 10-bit mantissa is non-zero.
16229     wuffs_base__lossy_value_u16 ret;
16230     ret.value = neg | 0x7DFF | ((uint16_t)(man >> 42));
16231     ret.lossy = false;
16232     return ret;
16233 
16234   } else if (exp > 0x40E) {  // Truncate to the largest finite f16.
16235     wuffs_base__lossy_value_u16 ret;
16236     ret.value = neg | 0x7BFF;
16237     ret.lossy = true;
16238     return ret;
16239 
16240   } else if (exp <= 0x3E6) {  // Truncate to zero.
16241     wuffs_base__lossy_value_u16 ret;
16242     ret.value = neg;
16243     ret.lossy = (u != 0);
16244     return ret;
16245 
16246   } else if (exp <= 0x3F0) {  // Normal f64, subnormal f16.
16247     // Convert from a 53-bit mantissa (after realizing the implicit bit) to a
16248     // 10-bit mantissa and then adjust for the exponent.
16249     man |= 0x0010000000000000;
16250     uint32_t shift = ((uint32_t)(1051 - exp));  // 1051 = 0x3F0 + 53 - 10.
16251     uint64_t shifted_man = man >> shift;
16252     wuffs_base__lossy_value_u16 ret;
16253     ret.value = neg | ((uint16_t)shifted_man);
16254     ret.lossy = (shifted_man << shift) != man;
16255     return ret;
16256   }
16257 
16258   // Normal f64, normal f16.
16259 
16260   // Re-bias from 1023 to 15 and shift above f16's 10 mantissa bits.
16261   exp = (exp - 1008) << 10;  // 1008 = 1023 - 15 = 0x3FF - 0xF.
16262 
16263   // Convert from a 52-bit mantissa (excluding the implicit bit) to a 10-bit
16264   // mantissa (again excluding the implicit bit). We lose some information if
16265   // any of the bottom 42 bits are non-zero.
16266   wuffs_base__lossy_value_u16 ret;
16267   ret.value = neg | ((uint16_t)exp) | ((uint16_t)(man >> 42));
16268   ret.lossy = (man << 22) != 0;
16269   return ret;
16270 }
16271 
16272 WUFFS_BASE__MAYBE_STATIC wuffs_base__lossy_value_u32  //
wuffs_base__ieee_754_bit_representation__from_f64_to_u32_truncate(double f)16273 wuffs_base__ieee_754_bit_representation__from_f64_to_u32_truncate(double f) {
16274   uint64_t u = 0;
16275   if (sizeof(uint64_t) == sizeof(double)) {
16276     memcpy(&u, &f, sizeof(uint64_t));
16277   }
16278   uint32_t neg = ((uint32_t)(u >> 63)) << 31;
16279   u &= 0x7FFFFFFFFFFFFFFF;
16280   uint64_t exp = u >> 52;
16281   uint64_t man = u & 0x000FFFFFFFFFFFFF;
16282 
16283   if (exp == 0x7FF) {
16284     if (man == 0) {  // Infinity.
16285       wuffs_base__lossy_value_u32 ret;
16286       ret.value = neg | 0x7F800000;
16287       ret.lossy = false;
16288       return ret;
16289     }
16290     // NaN. Shift the 52 mantissa bits to 23 mantissa bits, keeping the most
16291     // significant mantissa bit (quiet vs signaling NaNs). Also set the low 22
16292     // bits of ret.value so that the 23-bit mantissa is non-zero.
16293     wuffs_base__lossy_value_u32 ret;
16294     ret.value = neg | 0x7FBFFFFF | ((uint32_t)(man >> 29));
16295     ret.lossy = false;
16296     return ret;
16297 
16298   } else if (exp > 0x47E) {  // Truncate to the largest finite f32.
16299     wuffs_base__lossy_value_u32 ret;
16300     ret.value = neg | 0x7F7FFFFF;
16301     ret.lossy = true;
16302     return ret;
16303 
16304   } else if (exp <= 0x369) {  // Truncate to zero.
16305     wuffs_base__lossy_value_u32 ret;
16306     ret.value = neg;
16307     ret.lossy = (u != 0);
16308     return ret;
16309 
16310   } else if (exp <= 0x380) {  // Normal f64, subnormal f32.
16311     // Convert from a 53-bit mantissa (after realizing the implicit bit) to a
16312     // 23-bit mantissa and then adjust for the exponent.
16313     man |= 0x0010000000000000;
16314     uint32_t shift = ((uint32_t)(926 - exp));  // 926 = 0x380 + 53 - 23.
16315     uint64_t shifted_man = man >> shift;
16316     wuffs_base__lossy_value_u32 ret;
16317     ret.value = neg | ((uint32_t)shifted_man);
16318     ret.lossy = (shifted_man << shift) != man;
16319     return ret;
16320   }
16321 
16322   // Normal f64, normal f32.
16323 
16324   // Re-bias from 1023 to 127 and shift above f32's 23 mantissa bits.
16325   exp = (exp - 896) << 23;  // 896 = 1023 - 127 = 0x3FF - 0x7F.
16326 
16327   // Convert from a 52-bit mantissa (excluding the implicit bit) to a 23-bit
16328   // mantissa (again excluding the implicit bit). We lose some information if
16329   // any of the bottom 29 bits are non-zero.
16330   wuffs_base__lossy_value_u32 ret;
16331   ret.value = neg | ((uint32_t)exp) | ((uint32_t)(man >> 29));
16332   ret.lossy = (man << 35) != 0;
16333   return ret;
16334 }
16335 
16336 // --------
16337 
16338 #define WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE 2047
16339 #define WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION 800
16340 
16341 // WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL is the largest N
16342 // such that ((10 << N) < (1 << 64)).
16343 #define WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL 60
16344 
16345 // wuffs_base__private_implementation__high_prec_dec (abbreviated as HPD) is a
16346 // fixed precision floating point decimal number, augmented with ±infinity
16347 // values, but it cannot represent NaN (Not a Number).
16348 //
16349 // "High precision" means that the mantissa holds 800 decimal digits. 800 is
16350 // WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION.
16351 //
16352 // An HPD isn't for general purpose arithmetic, only for conversions to and
16353 // from IEEE 754 double-precision floating point, where the largest and
16354 // smallest positive, finite values are approximately 1.8e+308 and 4.9e-324.
16355 // HPD exponents above +2047 mean infinity, below -2047 mean zero. The ±2047
16356 // bounds are further away from zero than ±(324 + 800), where 800 and 2047 is
16357 // WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION and
16358 // WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE.
16359 //
16360 // digits[.. num_digits] are the number's digits in big-endian order. The
16361 // uint8_t values are in the range [0 ..= 9], not ['0' ..= '9'], where e.g. '7'
16362 // is the ASCII value 0x37.
16363 //
16364 // decimal_point is the index (within digits) of the decimal point. It may be
16365 // negative or be larger than num_digits, in which case the explicit digits are
16366 // padded with implicit zeroes.
16367 //
16368 // For example, if num_digits is 3 and digits is "\x07\x08\x09":
16369 //  - A decimal_point of -2 means ".00789"
16370 //  - A decimal_point of -1 means ".0789"
16371 //  - A decimal_point of +0 means ".789"
16372 //  - A decimal_point of +1 means "7.89"
16373 //  - A decimal_point of +2 means "78.9"
16374 //  - A decimal_point of +3 means "789."
16375 //  - A decimal_point of +4 means "7890."
16376 //  - A decimal_point of +5 means "78900."
16377 //
16378 // As above, a decimal_point higher than +2047 means that the overall value is
16379 // infinity, lower than -2047 means zero.
16380 //
16381 // negative is a sign bit. An HPD can distinguish positive and negative zero.
16382 //
16383 // truncated is whether there are more than
16384 // WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION digits, and at
16385 // least one of those extra digits are non-zero. The existence of long-tail
16386 // digits can affect rounding.
16387 //
16388 // The "all fields are zero" value is valid, and represents the number +0.
16389 typedef struct wuffs_base__private_implementation__high_prec_dec__struct {
16390   uint32_t num_digits;
16391   int32_t decimal_point;
16392   bool negative;
16393   bool truncated;
16394   uint8_t digits[WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION];
16395 } wuffs_base__private_implementation__high_prec_dec;
16396 
16397 // wuffs_base__private_implementation__high_prec_dec__trim trims trailing
16398 // zeroes from the h->digits[.. h->num_digits] slice. They have no benefit,
16399 // since we explicitly track h->decimal_point.
16400 //
16401 // Preconditions:
16402 //  - h is non-NULL.
16403 static inline void  //
wuffs_base__private_implementation__high_prec_dec__trim(wuffs_base__private_implementation__high_prec_dec * h)16404 wuffs_base__private_implementation__high_prec_dec__trim(
16405     wuffs_base__private_implementation__high_prec_dec* h) {
16406   while ((h->num_digits > 0) && (h->digits[h->num_digits - 1] == 0)) {
16407     h->num_digits--;
16408   }
16409 }
16410 
16411 // wuffs_base__private_implementation__high_prec_dec__assign sets h to
16412 // represent the number x.
16413 //
16414 // Preconditions:
16415 //  - h is non-NULL.
16416 static void  //
wuffs_base__private_implementation__high_prec_dec__assign(wuffs_base__private_implementation__high_prec_dec * h,uint64_t x,bool negative)16417 wuffs_base__private_implementation__high_prec_dec__assign(
16418     wuffs_base__private_implementation__high_prec_dec* h,
16419     uint64_t x,
16420     bool negative) {
16421   uint32_t n = 0;
16422 
16423   // Set h->digits.
16424   if (x > 0) {
16425     // Calculate the digits, working right-to-left. After we determine n (how
16426     // many digits there are), copy from buf to h->digits.
16427     //
16428     // UINT64_MAX, 18446744073709551615, is 20 digits long. It can be faster to
16429     // copy a constant number of bytes than a variable number (20 instead of
16430     // n). Make buf large enough (and start writing to it from the middle) so
16431     // that can we always copy 20 bytes: the slice buf[(20-n) .. (40-n)].
16432     uint8_t buf[40] = {0};
16433     uint8_t* ptr = &buf[20];
16434     do {
16435       uint64_t remaining = x / 10;
16436       x -= remaining * 10;
16437       ptr--;
16438       *ptr = (uint8_t)x;
16439       n++;
16440       x = remaining;
16441     } while (x > 0);
16442     memcpy(h->digits, ptr, 20);
16443   }
16444 
16445   // Set h's other fields.
16446   h->num_digits = n;
16447   h->decimal_point = (int32_t)n;
16448   h->negative = negative;
16449   h->truncated = false;
16450   wuffs_base__private_implementation__high_prec_dec__trim(h);
16451 }
16452 
16453 static wuffs_base__status  //
wuffs_base__private_implementation__high_prec_dec__parse(wuffs_base__private_implementation__high_prec_dec * h,wuffs_base__slice_u8 s,uint32_t options)16454 wuffs_base__private_implementation__high_prec_dec__parse(
16455     wuffs_base__private_implementation__high_prec_dec* h,
16456     wuffs_base__slice_u8 s,
16457     uint32_t options) {
16458   if (!h) {
16459     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
16460   }
16461   h->num_digits = 0;
16462   h->decimal_point = 0;
16463   h->negative = false;
16464   h->truncated = false;
16465 
16466   uint8_t* p = s.ptr;
16467   uint8_t* q = s.ptr + s.len;
16468 
16469   if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
16470     for (;; p++) {
16471       if (p >= q) {
16472         return wuffs_base__make_status(wuffs_base__error__bad_argument);
16473       } else if (*p != '_') {
16474         break;
16475       }
16476     }
16477   }
16478 
16479   // Parse sign.
16480   do {
16481     if (*p == '+') {
16482       p++;
16483     } else if (*p == '-') {
16484       h->negative = true;
16485       p++;
16486     } else {
16487       break;
16488     }
16489     if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
16490       for (;; p++) {
16491         if (p >= q) {
16492           return wuffs_base__make_status(wuffs_base__error__bad_argument);
16493         } else if (*p != '_') {
16494           break;
16495         }
16496       }
16497     }
16498   } while (0);
16499 
16500   // Parse digits, up to (and including) a '.', 'E' or 'e'. Examples for each
16501   // limb in this if-else chain:
16502   //  - "0.789"
16503   //  - "1002.789"
16504   //  - ".789"
16505   //  - Other (invalid input).
16506   uint32_t nd = 0;
16507   int32_t dp = 0;
16508   bool no_digits_before_separator = false;
16509   if (('0' == *p) &&
16510       !(options &
16511         WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_MULTIPLE_LEADING_ZEROES)) {
16512     p++;
16513     for (;; p++) {
16514       if (p >= q) {
16515         goto after_all;
16516       } else if (*p ==
16517                  ((options &
16518                    WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)
16519                       ? ','
16520                       : '.')) {
16521         p++;
16522         goto after_sep;
16523       } else if ((*p == 'E') || (*p == 'e')) {
16524         p++;
16525         goto after_exp;
16526       } else if ((*p != '_') ||
16527                  !(options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) {
16528         return wuffs_base__make_status(wuffs_base__error__bad_argument);
16529       }
16530     }
16531 
16532   } else if (('0' <= *p) && (*p <= '9')) {
16533     if (*p == '0') {
16534       for (; (p < q) && (*p == '0'); p++) {
16535       }
16536     } else {
16537       h->digits[nd++] = (uint8_t)(*p - '0');
16538       dp = (int32_t)nd;
16539       p++;
16540     }
16541 
16542     for (;; p++) {
16543       if (p >= q) {
16544         goto after_all;
16545       } else if (('0' <= *p) && (*p <= '9')) {
16546         if (nd < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
16547           h->digits[nd++] = (uint8_t)(*p - '0');
16548           dp = (int32_t)nd;
16549         } else if ('0' != *p) {
16550           // Long-tail non-zeroes set the truncated bit.
16551           h->truncated = true;
16552         }
16553       } else if (*p ==
16554                  ((options &
16555                    WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)
16556                       ? ','
16557                       : '.')) {
16558         p++;
16559         goto after_sep;
16560       } else if ((*p == 'E') || (*p == 'e')) {
16561         p++;
16562         goto after_exp;
16563       } else if ((*p != '_') ||
16564                  !(options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) {
16565         return wuffs_base__make_status(wuffs_base__error__bad_argument);
16566       }
16567     }
16568 
16569   } else if (*p == ((options &
16570                      WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)
16571                         ? ','
16572                         : '.')) {
16573     p++;
16574     no_digits_before_separator = true;
16575 
16576   } else {
16577     return wuffs_base__make_status(wuffs_base__error__bad_argument);
16578   }
16579 
16580 after_sep:
16581   for (;; p++) {
16582     if (p >= q) {
16583       goto after_all;
16584     } else if ('0' == *p) {
16585       if (nd == 0) {
16586         // Track leading zeroes implicitly.
16587         dp--;
16588       } else if (nd <
16589                  WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
16590         h->digits[nd++] = (uint8_t)(*p - '0');
16591       }
16592     } else if (('0' < *p) && (*p <= '9')) {
16593       if (nd < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
16594         h->digits[nd++] = (uint8_t)(*p - '0');
16595       } else {
16596         // Long-tail non-zeroes set the truncated bit.
16597         h->truncated = true;
16598       }
16599     } else if ((*p == 'E') || (*p == 'e')) {
16600       p++;
16601       goto after_exp;
16602     } else if ((*p != '_') ||
16603                !(options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) {
16604       return wuffs_base__make_status(wuffs_base__error__bad_argument);
16605     }
16606   }
16607 
16608 after_exp:
16609   do {
16610     if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
16611       for (;; p++) {
16612         if (p >= q) {
16613           return wuffs_base__make_status(wuffs_base__error__bad_argument);
16614         } else if (*p != '_') {
16615           break;
16616         }
16617       }
16618     }
16619 
16620     int32_t exp_sign = +1;
16621     if (*p == '+') {
16622       p++;
16623     } else if (*p == '-') {
16624       exp_sign = -1;
16625       p++;
16626     }
16627 
16628     int32_t exp = 0;
16629     const int32_t exp_large =
16630         WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE +
16631         WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION;
16632     bool saw_exp_digits = false;
16633     for (; p < q; p++) {
16634       if ((*p == '_') &&
16635           (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) {
16636         // No-op.
16637       } else if (('0' <= *p) && (*p <= '9')) {
16638         saw_exp_digits = true;
16639         if (exp < exp_large) {
16640           exp = (10 * exp) + ((int32_t)(*p - '0'));
16641         }
16642       } else {
16643         break;
16644       }
16645     }
16646     if (!saw_exp_digits) {
16647       return wuffs_base__make_status(wuffs_base__error__bad_argument);
16648     }
16649     dp += exp_sign * exp;
16650   } while (0);
16651 
16652 after_all:
16653   if (p != q) {
16654     return wuffs_base__make_status(wuffs_base__error__bad_argument);
16655   }
16656   h->num_digits = nd;
16657   if (nd == 0) {
16658     if (no_digits_before_separator) {
16659       return wuffs_base__make_status(wuffs_base__error__bad_argument);
16660     }
16661     h->decimal_point = 0;
16662   } else if (dp <
16663              -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
16664     h->decimal_point =
16665         -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE - 1;
16666   } else if (dp >
16667              +WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
16668     h->decimal_point =
16669         +WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE + 1;
16670   } else {
16671     h->decimal_point = dp;
16672   }
16673   wuffs_base__private_implementation__high_prec_dec__trim(h);
16674   return wuffs_base__make_status(NULL);
16675 }
16676 
16677 // --------
16678 
16679 // wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits
16680 // returns the number of additional decimal digits when left-shifting by shift.
16681 //
16682 // See below for preconditions.
16683 static uint32_t  //
wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits(wuffs_base__private_implementation__high_prec_dec * h,uint32_t shift)16684 wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits(
16685     wuffs_base__private_implementation__high_prec_dec* h,
16686     uint32_t shift) {
16687   // Masking with 0x3F should be unnecessary (assuming the preconditions) but
16688   // it's cheap and ensures that we don't overflow the
16689   // wuffs_base__private_implementation__hpd_left_shift array.
16690   shift &= 63;
16691 
16692   uint32_t x_a = wuffs_base__private_implementation__hpd_left_shift[shift];
16693   uint32_t x_b = wuffs_base__private_implementation__hpd_left_shift[shift + 1];
16694   uint32_t num_new_digits = x_a >> 11;
16695   uint32_t pow5_a = 0x7FF & x_a;
16696   uint32_t pow5_b = 0x7FF & x_b;
16697 
16698   const uint8_t* pow5 =
16699       &wuffs_base__private_implementation__powers_of_5[pow5_a];
16700   uint32_t i = 0;
16701   uint32_t n = pow5_b - pow5_a;
16702   for (; i < n; i++) {
16703     if (i >= h->num_digits) {
16704       return num_new_digits - 1;
16705     } else if (h->digits[i] == pow5[i]) {
16706       continue;
16707     } else if (h->digits[i] < pow5[i]) {
16708       return num_new_digits - 1;
16709     } else {
16710       return num_new_digits;
16711     }
16712   }
16713   return num_new_digits;
16714 }
16715 
16716 // --------
16717 
16718 // wuffs_base__private_implementation__high_prec_dec__rounded_integer returns
16719 // the integral (non-fractional) part of h, provided that it is 18 or fewer
16720 // decimal digits. For 19 or more digits, it returns UINT64_MAX. Note that:
16721 //  - (1 << 53) is    9007199254740992, which has 16 decimal digits.
16722 //  - (1 << 56) is   72057594037927936, which has 17 decimal digits.
16723 //  - (1 << 59) is  576460752303423488, which has 18 decimal digits.
16724 //  - (1 << 63) is 9223372036854775808, which has 19 decimal digits.
16725 // and that IEEE 754 double precision has 52 mantissa bits.
16726 //
16727 // That integral part is rounded-to-even: rounding 7.5 or 8.5 both give 8.
16728 //
16729 // h's negative bit is ignored: rounding -8.6 returns 9.
16730 //
16731 // See below for preconditions.
16732 static uint64_t  //
wuffs_base__private_implementation__high_prec_dec__rounded_integer(wuffs_base__private_implementation__high_prec_dec * h)16733 wuffs_base__private_implementation__high_prec_dec__rounded_integer(
16734     wuffs_base__private_implementation__high_prec_dec* h) {
16735   if ((h->num_digits == 0) || (h->decimal_point < 0)) {
16736     return 0;
16737   } else if (h->decimal_point > 18) {
16738     return UINT64_MAX;
16739   }
16740 
16741   uint32_t dp = (uint32_t)(h->decimal_point);
16742   uint64_t n = 0;
16743   uint32_t i = 0;
16744   for (; i < dp; i++) {
16745     n = (10 * n) + ((i < h->num_digits) ? h->digits[i] : 0);
16746   }
16747 
16748   bool round_up = false;
16749   if (dp < h->num_digits) {
16750     round_up = h->digits[dp] >= 5;
16751     if ((h->digits[dp] == 5) && (dp + 1 == h->num_digits)) {
16752       // We are exactly halfway. If we're truncated, round up, otherwise round
16753       // to even.
16754       round_up = h->truncated ||  //
16755                  ((dp > 0) && (1 & h->digits[dp - 1]));
16756     }
16757   }
16758   if (round_up) {
16759     n++;
16760   }
16761 
16762   return n;
16763 }
16764 
16765 // wuffs_base__private_implementation__high_prec_dec__small_xshift shifts h's
16766 // number (where 'x' is 'l' or 'r' for left or right) by a small shift value.
16767 //
16768 // Preconditions:
16769 //  - h is non-NULL.
16770 //  - h->decimal_point is "not extreme".
16771 //  - shift is non-zero.
16772 //  - shift is "a small shift".
16773 //
16774 // "Not extreme" means within
16775 // ±WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE.
16776 //
16777 // "A small shift" means not more than
16778 // WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL.
16779 //
16780 // wuffs_base__private_implementation__high_prec_dec__rounded_integer and
16781 // wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits
16782 // have the same preconditions.
16783 //
16784 // wuffs_base__private_implementation__high_prec_dec__lshift keeps the first
16785 // two preconditions but not the last two. Its shift argument is signed and
16786 // does not need to be "small": zero is a no-op, positive means left shift and
16787 // negative means right shift.
16788 
16789 static void  //
wuffs_base__private_implementation__high_prec_dec__small_lshift(wuffs_base__private_implementation__high_prec_dec * h,uint32_t shift)16790 wuffs_base__private_implementation__high_prec_dec__small_lshift(
16791     wuffs_base__private_implementation__high_prec_dec* h,
16792     uint32_t shift) {
16793   if (h->num_digits == 0) {
16794     return;
16795   }
16796   uint32_t num_new_digits =
16797       wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits(
16798           h, shift);
16799   uint32_t rx = h->num_digits - 1;                   // Read  index.
16800   uint32_t wx = h->num_digits - 1 + num_new_digits;  // Write index.
16801   uint64_t n = 0;
16802 
16803   // Repeat: pick up a digit, put down a digit, right to left.
16804   while (((int32_t)rx) >= 0) {
16805     n += ((uint64_t)(h->digits[rx])) << shift;
16806     uint64_t quo = n / 10;
16807     uint64_t rem = n - (10 * quo);
16808     if (wx < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
16809       h->digits[wx] = (uint8_t)rem;
16810     } else if (rem > 0) {
16811       h->truncated = true;
16812     }
16813     n = quo;
16814     wx--;
16815     rx--;
16816   }
16817 
16818   // Put down leading digits, right to left.
16819   while (n > 0) {
16820     uint64_t quo = n / 10;
16821     uint64_t rem = n - (10 * quo);
16822     if (wx < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
16823       h->digits[wx] = (uint8_t)rem;
16824     } else if (rem > 0) {
16825       h->truncated = true;
16826     }
16827     n = quo;
16828     wx--;
16829   }
16830 
16831   // Finish.
16832   h->num_digits += num_new_digits;
16833   if (h->num_digits >
16834       WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
16835     h->num_digits = WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION;
16836   }
16837   h->decimal_point += (int32_t)num_new_digits;
16838   wuffs_base__private_implementation__high_prec_dec__trim(h);
16839 }
16840 
16841 static void  //
wuffs_base__private_implementation__high_prec_dec__small_rshift(wuffs_base__private_implementation__high_prec_dec * h,uint32_t shift)16842 wuffs_base__private_implementation__high_prec_dec__small_rshift(
16843     wuffs_base__private_implementation__high_prec_dec* h,
16844     uint32_t shift) {
16845   uint32_t rx = 0;  // Read  index.
16846   uint32_t wx = 0;  // Write index.
16847   uint64_t n = 0;
16848 
16849   // Pick up enough leading digits to cover the first shift.
16850   while ((n >> shift) == 0) {
16851     if (rx < h->num_digits) {
16852       // Read a digit.
16853       n = (10 * n) + h->digits[rx++];
16854     } else if (n == 0) {
16855       // h's number used to be zero and remains zero.
16856       return;
16857     } else {
16858       // Read sufficient implicit trailing zeroes.
16859       while ((n >> shift) == 0) {
16860         n = 10 * n;
16861         rx++;
16862       }
16863       break;
16864     }
16865   }
16866   h->decimal_point -= ((int32_t)(rx - 1));
16867   if (h->decimal_point <
16868       -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
16869     // After the shift, h's number is effectively zero.
16870     h->num_digits = 0;
16871     h->decimal_point = 0;
16872     h->truncated = false;
16873     return;
16874   }
16875 
16876   // Repeat: pick up a digit, put down a digit, left to right.
16877   uint64_t mask = (((uint64_t)(1)) << shift) - 1;
16878   while (rx < h->num_digits) {
16879     uint8_t new_digit = ((uint8_t)(n >> shift));
16880     n = (10 * (n & mask)) + h->digits[rx++];
16881     h->digits[wx++] = new_digit;
16882   }
16883 
16884   // Put down trailing digits, left to right.
16885   while (n > 0) {
16886     uint8_t new_digit = ((uint8_t)(n >> shift));
16887     n = 10 * (n & mask);
16888     if (wx < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
16889       h->digits[wx++] = new_digit;
16890     } else if (new_digit > 0) {
16891       h->truncated = true;
16892     }
16893   }
16894 
16895   // Finish.
16896   h->num_digits = wx;
16897   wuffs_base__private_implementation__high_prec_dec__trim(h);
16898 }
16899 
16900 static void  //
wuffs_base__private_implementation__high_prec_dec__lshift(wuffs_base__private_implementation__high_prec_dec * h,int32_t shift)16901 wuffs_base__private_implementation__high_prec_dec__lshift(
16902     wuffs_base__private_implementation__high_prec_dec* h,
16903     int32_t shift) {
16904   if (shift > 0) {
16905     while (shift > +WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL) {
16906       wuffs_base__private_implementation__high_prec_dec__small_lshift(
16907           h, WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL);
16908       shift -= WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
16909     }
16910     wuffs_base__private_implementation__high_prec_dec__small_lshift(
16911         h, ((uint32_t)(+shift)));
16912   } else if (shift < 0) {
16913     while (shift < -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL) {
16914       wuffs_base__private_implementation__high_prec_dec__small_rshift(
16915           h, WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL);
16916       shift += WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
16917     }
16918     wuffs_base__private_implementation__high_prec_dec__small_rshift(
16919         h, ((uint32_t)(-shift)));
16920   }
16921 }
16922 
16923 // --------
16924 
16925 // wuffs_base__private_implementation__high_prec_dec__round_etc rounds h's
16926 // number. For those functions that take an n argument, rounding produces at
16927 // most n digits (which is not necessarily at most n decimal places). Negative
16928 // n values are ignored, as well as any n greater than or equal to h's number
16929 // of digits. The etc__round_just_enough function implicitly chooses an n to
16930 // implement WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION.
16931 //
16932 // Preconditions:
16933 //  - h is non-NULL.
16934 //  - h->decimal_point is "not extreme".
16935 //
16936 // "Not extreme" means within
16937 // ±WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE.
16938 
16939 static void  //
wuffs_base__private_implementation__high_prec_dec__round_down(wuffs_base__private_implementation__high_prec_dec * h,int32_t n)16940 wuffs_base__private_implementation__high_prec_dec__round_down(
16941     wuffs_base__private_implementation__high_prec_dec* h,
16942     int32_t n) {
16943   if ((n < 0) || (h->num_digits <= (uint32_t)n)) {
16944     return;
16945   }
16946   h->num_digits = (uint32_t)(n);
16947   wuffs_base__private_implementation__high_prec_dec__trim(h);
16948 }
16949 
16950 static void  //
wuffs_base__private_implementation__high_prec_dec__round_up(wuffs_base__private_implementation__high_prec_dec * h,int32_t n)16951 wuffs_base__private_implementation__high_prec_dec__round_up(
16952     wuffs_base__private_implementation__high_prec_dec* h,
16953     int32_t n) {
16954   if ((n < 0) || (h->num_digits <= (uint32_t)n)) {
16955     return;
16956   }
16957 
16958   for (n--; n >= 0; n--) {
16959     if (h->digits[n] < 9) {
16960       h->digits[n]++;
16961       h->num_digits = (uint32_t)(n + 1);
16962       return;
16963     }
16964   }
16965 
16966   // The number is all 9s. Change to a single 1 and adjust the decimal point.
16967   h->digits[0] = 1;
16968   h->num_digits = 1;
16969   h->decimal_point++;
16970 }
16971 
16972 static void  //
wuffs_base__private_implementation__high_prec_dec__round_nearest(wuffs_base__private_implementation__high_prec_dec * h,int32_t n)16973 wuffs_base__private_implementation__high_prec_dec__round_nearest(
16974     wuffs_base__private_implementation__high_prec_dec* h,
16975     int32_t n) {
16976   if ((n < 0) || (h->num_digits <= (uint32_t)n)) {
16977     return;
16978   }
16979   bool up = h->digits[n] >= 5;
16980   if ((h->digits[n] == 5) && ((n + 1) == ((int32_t)(h->num_digits)))) {
16981     up = h->truncated ||  //
16982          ((n > 0) && ((h->digits[n - 1] & 1) != 0));
16983   }
16984 
16985   if (up) {
16986     wuffs_base__private_implementation__high_prec_dec__round_up(h, n);
16987   } else {
16988     wuffs_base__private_implementation__high_prec_dec__round_down(h, n);
16989   }
16990 }
16991 
16992 static void  //
wuffs_base__private_implementation__high_prec_dec__round_just_enough(wuffs_base__private_implementation__high_prec_dec * h,int32_t exp2,uint64_t mantissa)16993 wuffs_base__private_implementation__high_prec_dec__round_just_enough(
16994     wuffs_base__private_implementation__high_prec_dec* h,
16995     int32_t exp2,
16996     uint64_t mantissa) {
16997   // The magic numbers 52 and 53 in this function are because IEEE 754 double
16998   // precision has 52 mantissa bits.
16999   //
17000   // Let f be the floating point number represented by exp2 and mantissa (and
17001   // also the number in h): the number (mantissa * (2 ** (exp2 - 52))).
17002   //
17003   // If f is zero or a small integer, we can return early.
17004   if ((mantissa == 0) ||
17005       ((exp2 < 53) && (h->decimal_point >= ((int32_t)(h->num_digits))))) {
17006     return;
17007   }
17008 
17009   // The smallest normal f has an exp2 of -1022 and a mantissa of (1 << 52).
17010   // Subnormal numbers have the same exp2 but a smaller mantissa.
17011   static const int32_t min_incl_normal_exp2 = -1022;
17012   static const uint64_t min_incl_normal_mantissa = 0x0010000000000000ul;
17013 
17014   // Compute lower and upper bounds such that any number between them (possibly
17015   // inclusive) will round to f. First, the lower bound. Our number f is:
17016   //   ((mantissa + 0)         * (2 ** (  exp2 - 52)))
17017   //
17018   // The next lowest floating point number is:
17019   //   ((mantissa - 1)         * (2 ** (  exp2 - 52)))
17020   // unless (mantissa - 1) drops the (1 << 52) bit and exp2 is not the
17021   // min_incl_normal_exp2. Either way, call it:
17022   //   ((l_mantissa)           * (2 ** (l_exp2 - 52)))
17023   //
17024   // The lower bound is halfway between them (noting that 52 became 53):
17025   //   (((2 * l_mantissa) + 1) * (2 ** (l_exp2 - 53)))
17026   int32_t l_exp2 = exp2;
17027   uint64_t l_mantissa = mantissa - 1;
17028   if ((exp2 > min_incl_normal_exp2) && (mantissa <= min_incl_normal_mantissa)) {
17029     l_exp2 = exp2 - 1;
17030     l_mantissa = (2 * mantissa) - 1;
17031   }
17032   wuffs_base__private_implementation__high_prec_dec lower;
17033   wuffs_base__private_implementation__high_prec_dec__assign(
17034       &lower, (2 * l_mantissa) + 1, false);
17035   wuffs_base__private_implementation__high_prec_dec__lshift(&lower,
17036                                                             l_exp2 - 53);
17037 
17038   // Next, the upper bound. Our number f is:
17039   //   ((mantissa + 0)       * (2 ** (exp2 - 52)))
17040   //
17041   // The next highest floating point number is:
17042   //   ((mantissa + 1)       * (2 ** (exp2 - 52)))
17043   //
17044   // The upper bound is halfway between them (noting that 52 became 53):
17045   //   (((2 * mantissa) + 1) * (2 ** (exp2 - 53)))
17046   wuffs_base__private_implementation__high_prec_dec upper;
17047   wuffs_base__private_implementation__high_prec_dec__assign(
17048       &upper, (2 * mantissa) + 1, false);
17049   wuffs_base__private_implementation__high_prec_dec__lshift(&upper, exp2 - 53);
17050 
17051   // The lower and upper bounds are possible outputs only if the original
17052   // mantissa is even, so that IEEE round-to-even would round to the original
17053   // mantissa and not its neighbors.
17054   bool inclusive = (mantissa & 1) == 0;
17055 
17056   // As we walk the digits, we want to know whether rounding up would fall
17057   // within the upper bound. This is tracked by upper_delta:
17058   //  - When -1, the digits of h and upper are the same so far.
17059   //  - When +0, we saw a difference of 1 between h and upper on a previous
17060   //    digit and subsequently only 9s for h and 0s for upper. Thus, rounding
17061   //    up may fall outside of the bound if !inclusive.
17062   //  - When +1, the difference is greater than 1 and we know that rounding up
17063   //    falls within the bound.
17064   //
17065   // This is a state machine with three states. The numerical value for each
17066   // state (-1, +0 or +1) isn't important, other than their order.
17067   int upper_delta = -1;
17068 
17069   // We can now figure out the shortest number of digits required. Walk the
17070   // digits until h has distinguished itself from lower or upper.
17071   //
17072   // The zi and zd variables are indexes and digits, for z in l (lower), h (the
17073   // number) and u (upper).
17074   //
17075   // The lower, h and upper numbers may have their decimal points at different
17076   // places. In this case, upper is the longest, so we iterate ui starting from
17077   // 0 and iterate li and hi starting from either 0 or -1.
17078   int32_t ui = 0;
17079   for (;; ui++) {
17080     // Calculate hd, the middle number's digit.
17081     int32_t hi = ui - upper.decimal_point + h->decimal_point;
17082     if (hi >= ((int32_t)(h->num_digits))) {
17083       break;
17084     }
17085     uint8_t hd = (((uint32_t)hi) < h->num_digits) ? h->digits[hi] : 0;
17086 
17087     // Calculate ld, the lower bound's digit.
17088     int32_t li = ui - upper.decimal_point + lower.decimal_point;
17089     uint8_t ld = (((uint32_t)li) < lower.num_digits) ? lower.digits[li] : 0;
17090 
17091     // We can round down (truncate) if lower has a different digit than h or if
17092     // lower is inclusive and is exactly the result of rounding down (i.e. we
17093     // have reached the final digit of lower).
17094     bool can_round_down =
17095         (ld != hd) ||  //
17096         (inclusive && ((li + 1) == ((int32_t)(lower.num_digits))));
17097 
17098     // Calculate ud, the upper bound's digit, and update upper_delta.
17099     uint8_t ud = (((uint32_t)ui) < upper.num_digits) ? upper.digits[ui] : 0;
17100     if (upper_delta < 0) {
17101       if ((hd + 1) < ud) {
17102         // For example:
17103         // h     = 12345???
17104         // upper = 12347???
17105         upper_delta = +1;
17106       } else if (hd != ud) {
17107         // For example:
17108         // h     = 12345???
17109         // upper = 12346???
17110         upper_delta = +0;
17111       }
17112     } else if (upper_delta == 0) {
17113       if ((hd != 9) || (ud != 0)) {
17114         // For example:
17115         // h     = 1234598?
17116         // upper = 1234600?
17117         upper_delta = +1;
17118       }
17119     }
17120 
17121     // We can round up if upper has a different digit than h and either upper
17122     // is inclusive or upper is bigger than the result of rounding up.
17123     bool can_round_up =
17124         (upper_delta > 0) ||    //
17125         ((upper_delta == 0) &&  //
17126          (inclusive || ((ui + 1) < ((int32_t)(upper.num_digits)))));
17127 
17128     // If we can round either way, round to nearest. If we can round only one
17129     // way, do it. If we can't round, continue the loop.
17130     if (can_round_down) {
17131       if (can_round_up) {
17132         wuffs_base__private_implementation__high_prec_dec__round_nearest(
17133             h, hi + 1);
17134         return;
17135       } else {
17136         wuffs_base__private_implementation__high_prec_dec__round_down(h,
17137                                                                       hi + 1);
17138         return;
17139       }
17140     } else {
17141       if (can_round_up) {
17142         wuffs_base__private_implementation__high_prec_dec__round_up(h, hi + 1);
17143         return;
17144       }
17145     }
17146   }
17147 }
17148 
17149 // --------
17150 
17151 // wuffs_base__private_implementation__parse_number_f64_eisel_lemire produces
17152 // the IEEE 754 double-precision value for an exact mantissa and base-10
17153 // exponent. For example:
17154 //  - when parsing "12345.678e+02", man is 12345678 and exp10 is -1.
17155 //  - when parsing "-12", man is 12 and exp10 is 0. Processing the leading
17156 //    minus sign is the responsibility of the caller, not this function.
17157 //
17158 // On success, it returns a non-negative int64_t such that the low 63 bits hold
17159 // the 11-bit exponent and 52-bit mantissa.
17160 //
17161 // On failure, it returns a negative value.
17162 //
17163 // The algorithm is based on an original idea by Michael Eisel that was refined
17164 // by Daniel Lemire. See
17165 // https://lemire.me/blog/2020/03/10/fast-float-parsing-in-practice/
17166 // and
17167 // https://nigeltao.github.io/blog/2020/eisel-lemire.html
17168 //
17169 // Preconditions:
17170 //  - man is non-zero.
17171 //  - exp10 is in the range [-307 ..= 288], the same range of the
17172 //    wuffs_base__private_implementation__powers_of_10 array.
17173 //
17174 // The exp10 range (and the fact that man is in the range [1 ..= UINT64_MAX],
17175 // approximately [1 ..= 1.85e+19]) means that (man * (10 ** exp10)) is in the
17176 // range [1e-307 ..= 1.85e+307]. This is entirely within the range of normal
17177 // (neither subnormal nor non-finite) f64 values: DBL_MIN and DBL_MAX are
17178 // approximately 2.23e–308 and 1.80e+308.
17179 static int64_t  //
wuffs_base__private_implementation__parse_number_f64_eisel_lemire(uint64_t man,int32_t exp10)17180 wuffs_base__private_implementation__parse_number_f64_eisel_lemire(
17181     uint64_t man,
17182     int32_t exp10) {
17183   // Look up the (possibly truncated) base-2 representation of (10 ** exp10).
17184   // The look-up table was constructed so that it is already normalized: the
17185   // table entry's mantissa's MSB (most significant bit) is on.
17186   const uint64_t* po10 =
17187       &wuffs_base__private_implementation__powers_of_10[exp10 + 307][0];
17188 
17189   // Normalize the man argument. The (man != 0) precondition means that a
17190   // non-zero bit exists.
17191   uint32_t clz = wuffs_base__count_leading_zeroes_u64(man);
17192   man <<= clz;
17193 
17194   // Calculate the return value's base-2 exponent. We might tweak it by ±1
17195   // later, but its initial value comes from a linear scaling of exp10,
17196   // converting from power-of-10 to power-of-2, and adjusting by clz.
17197   //
17198   // The magic constants are:
17199   //  - 1087 = 1023 + 64. The 1023 is the f64 exponent bias. The 64 is because
17200   //    the look-up table uses 64-bit mantissas.
17201   //  - 217706 is such that the ratio 217706 / 65536 ≈ 3.321930 is close enough
17202   //    (over the practical range of exp10) to log(10) / log(2) ≈ 3.321928.
17203   //  - 65536 = 1<<16 is arbitrary but a power of 2, so division is a shift.
17204   //
17205   // Equality of the linearly-scaled value and the actual power-of-2, over the
17206   // range of exp10 arguments that this function accepts, is confirmed by
17207   // script/print-mpb-powers-of-10.go
17208   uint64_t ret_exp2 =
17209       ((uint64_t)(((217706 * exp10) >> 16) + 1087)) - ((uint64_t)clz);
17210 
17211   // Multiply the two mantissas. Normalization means that both mantissas are at
17212   // least (1<<63), so the 128-bit product must be at least (1<<126). The high
17213   // 64 bits of the product, x_hi, must therefore be at least (1<<62).
17214   //
17215   // As a consequence, x_hi has either 0 or 1 leading zeroes. Shifting x_hi
17216   // right by either 9 or 10 bits (depending on x_hi's MSB) will therefore
17217   // leave the top 10 MSBs (bits 54 ..= 63) off and the 11th MSB (bit 53) on.
17218   wuffs_base__multiply_u64__output x = wuffs_base__multiply_u64(man, po10[1]);
17219   uint64_t x_hi = x.hi;
17220   uint64_t x_lo = x.lo;
17221 
17222   // Before we shift right by at least 9 bits, recall that the look-up table
17223   // entry was possibly truncated. We have so far only calculated a lower bound
17224   // for the product (man * e), where e is (10 ** exp10). The upper bound would
17225   // add a further (man * 1) to the 128-bit product, which overflows the lower
17226   // 64-bit limb if ((x_lo + man) < man).
17227   //
17228   // If overflow occurs, that adds 1 to x_hi. Since we're about to shift right
17229   // by at least 9 bits, that carried 1 can be ignored unless the higher 64-bit
17230   // limb's low 9 bits are all on.
17231   //
17232   // For example, parsing "9999999999999999999" will take the if-true branch
17233   // here, since:
17234   //  - x_hi = 0x4563918244F3FFFF
17235   //  - x_lo = 0x8000000000000000
17236   //  - man  = 0x8AC7230489E7FFFF
17237   if (((x_hi & 0x1FF) == 0x1FF) && ((x_lo + man) < man)) {
17238     // Refine our calculation of (man * e). Before, our approximation of e used
17239     // a "low resolution" 64-bit mantissa. Now use a "high resolution" 128-bit
17240     // mantissa. We've already calculated x = (man * bits_0_to_63_incl_of_e).
17241     // Now calculate y = (man * bits_64_to_127_incl_of_e).
17242     wuffs_base__multiply_u64__output y = wuffs_base__multiply_u64(man, po10[0]);
17243     uint64_t y_hi = y.hi;
17244     uint64_t y_lo = y.lo;
17245 
17246     // Merge the 128-bit x and 128-bit y, which overlap by 64 bits, to
17247     // calculate the 192-bit product of the 64-bit man by the 128-bit e.
17248     // As we exit this if-block, we only care about the high 128 bits
17249     // (merged_hi and merged_lo) of that 192-bit product.
17250     //
17251     // For example, parsing "1.234e-45" will take the if-true branch here,
17252     // since:
17253     //  - x_hi = 0x70B7E3696DB29FFF
17254     //  - x_lo = 0xE040000000000000
17255     //  - y_hi = 0x33718BBEAB0E0D7A
17256     //  - y_lo = 0xA880000000000000
17257     uint64_t merged_hi = x_hi;
17258     uint64_t merged_lo = x_lo + y_hi;
17259     if (merged_lo < x_lo) {
17260       merged_hi++;  // Carry the overflow bit.
17261     }
17262 
17263     // The "high resolution" approximation of e is still a lower bound. Once
17264     // again, see if the upper bound is large enough to produce a different
17265     // result. This time, if it does, give up instead of reaching for an even
17266     // more precise approximation to e.
17267     //
17268     // This three-part check is similar to the two-part check that guarded the
17269     // if block that we're now in, but it has an extra term for the middle 64
17270     // bits (checking that adding 1 to merged_lo would overflow).
17271     //
17272     // For example, parsing "5.9604644775390625e-8" will take the if-true
17273     // branch here, since:
17274     //  - merged_hi = 0x7FFFFFFFFFFFFFFF
17275     //  - merged_lo = 0xFFFFFFFFFFFFFFFF
17276     //  - y_lo      = 0x4DB3FFC120988200
17277     //  - man       = 0xD3C21BCECCEDA100
17278     if (((merged_hi & 0x1FF) == 0x1FF) && ((merged_lo + 1) == 0) &&
17279         (y_lo + man < man)) {
17280       return -1;
17281     }
17282 
17283     // Replace the 128-bit x with merged.
17284     x_hi = merged_hi;
17285     x_lo = merged_lo;
17286   }
17287 
17288   // As mentioned above, shifting x_hi right by either 9 or 10 bits will leave
17289   // the top 10 MSBs (bits 54 ..= 63) off and the 11th MSB (bit 53) on. If the
17290   // MSB (before shifting) was on, adjust ret_exp2 for the larger shift.
17291   //
17292   // Having bit 53 on (and higher bits off) means that ret_mantissa is a 54-bit
17293   // number.
17294   uint64_t msb = x_hi >> 63;
17295   uint64_t ret_mantissa = x_hi >> (msb + 9);
17296   ret_exp2 -= 1 ^ msb;
17297 
17298   // IEEE 754 rounds to-nearest with ties rounded to-even. Rounding to-even can
17299   // be tricky. If we're half-way between two exactly representable numbers
17300   // (x's low 73 bits are zero and the next 2 bits that matter are "01"), give
17301   // up instead of trying to pick the winner.
17302   //
17303   // Technically, we could tighten the condition by changing "73" to "73 or 74,
17304   // depending on msb", but a flat "73" is simpler.
17305   //
17306   // For example, parsing "1e+23" will take the if-true branch here, since:
17307   //  - x_hi          = 0x54B40B1F852BDA00
17308   //  - ret_mantissa  = 0x002A5A058FC295ED
17309   if ((x_lo == 0) && ((x_hi & 0x1FF) == 0) && ((ret_mantissa & 3) == 1)) {
17310     return -1;
17311   }
17312 
17313   // If we're not halfway then it's rounding to-nearest. Starting with a 54-bit
17314   // number, carry the lowest bit (bit 0) up if it's on. Regardless of whether
17315   // it was on or off, shifting right by one then produces a 53-bit number. If
17316   // carrying up overflowed, shift again.
17317   ret_mantissa += ret_mantissa & 1;
17318   ret_mantissa >>= 1;
17319   // This if block is equivalent to (but benchmarks slightly faster than) the
17320   // following branchless form:
17321   //    uint64_t overflow_adjustment = ret_mantissa >> 53;
17322   //    ret_mantissa >>= overflow_adjustment;
17323   //    ret_exp2 += overflow_adjustment;
17324   //
17325   // For example, parsing "7.2057594037927933e+16" will take the if-true
17326   // branch here, since:
17327   //  - x_hi          = 0x7FFFFFFFFFFFFE80
17328   //  - ret_mantissa  = 0x0020000000000000
17329   if ((ret_mantissa >> 53) > 0) {
17330     ret_mantissa >>= 1;
17331     ret_exp2++;
17332   }
17333 
17334   // Starting with a 53-bit number, IEEE 754 double-precision normal numbers
17335   // have an implicit mantissa bit. Mask that away and keep the low 52 bits.
17336   ret_mantissa &= 0x000FFFFFFFFFFFFF;
17337 
17338   // Pack the bits and return.
17339   return ((int64_t)(ret_mantissa | (ret_exp2 << 52)));
17340 }
17341 
17342 // --------
17343 
17344 static wuffs_base__result_f64  //
wuffs_base__private_implementation__parse_number_f64_special(wuffs_base__slice_u8 s,uint32_t options)17345 wuffs_base__private_implementation__parse_number_f64_special(
17346     wuffs_base__slice_u8 s,
17347     uint32_t options) {
17348   do {
17349     if (options & WUFFS_BASE__PARSE_NUMBER_FXX__REJECT_INF_AND_NAN) {
17350       goto fail;
17351     }
17352 
17353     uint8_t* p = s.ptr;
17354     uint8_t* q = s.ptr + s.len;
17355 
17356     for (; (p < q) && (*p == '_'); p++) {
17357     }
17358     if (p >= q) {
17359       goto fail;
17360     }
17361 
17362     // Parse sign.
17363     bool negative = false;
17364     do {
17365       if (*p == '+') {
17366         p++;
17367       } else if (*p == '-') {
17368         negative = true;
17369         p++;
17370       } else {
17371         break;
17372       }
17373       for (; (p < q) && (*p == '_'); p++) {
17374       }
17375     } while (0);
17376     if (p >= q) {
17377       goto fail;
17378     }
17379 
17380     bool nan = false;
17381     switch (p[0]) {
17382       case 'I':
17383       case 'i':
17384         if (((q - p) < 3) ||                     //
17385             ((p[1] != 'N') && (p[1] != 'n')) ||  //
17386             ((p[2] != 'F') && (p[2] != 'f'))) {
17387           goto fail;
17388         }
17389         p += 3;
17390 
17391         if ((p >= q) || (*p == '_')) {
17392           break;
17393         } else if (((q - p) < 5) ||                     //
17394                    ((p[0] != 'I') && (p[0] != 'i')) ||  //
17395                    ((p[1] != 'N') && (p[1] != 'n')) ||  //
17396                    ((p[2] != 'I') && (p[2] != 'i')) ||  //
17397                    ((p[3] != 'T') && (p[3] != 't')) ||  //
17398                    ((p[4] != 'Y') && (p[4] != 'y'))) {
17399           goto fail;
17400         }
17401         p += 5;
17402 
17403         if ((p >= q) || (*p == '_')) {
17404           break;
17405         }
17406         goto fail;
17407 
17408       case 'N':
17409       case 'n':
17410         if (((q - p) < 3) ||                     //
17411             ((p[1] != 'A') && (p[1] != 'a')) ||  //
17412             ((p[2] != 'N') && (p[2] != 'n'))) {
17413           goto fail;
17414         }
17415         p += 3;
17416 
17417         if ((p >= q) || (*p == '_')) {
17418           nan = true;
17419           break;
17420         }
17421         goto fail;
17422 
17423       default:
17424         goto fail;
17425     }
17426 
17427     // Finish.
17428     for (; (p < q) && (*p == '_'); p++) {
17429     }
17430     if (p != q) {
17431       goto fail;
17432     }
17433     wuffs_base__result_f64 ret;
17434     ret.status.repr = NULL;
17435     ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
17436         (nan ? 0x7FFFFFFFFFFFFFFF : 0x7FF0000000000000) |
17437         (negative ? 0x8000000000000000 : 0));
17438     return ret;
17439   } while (0);
17440 
17441 fail:
17442   do {
17443     wuffs_base__result_f64 ret;
17444     ret.status.repr = wuffs_base__error__bad_argument;
17445     ret.value = 0;
17446     return ret;
17447   } while (0);
17448 }
17449 
17450 WUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64  //
wuffs_base__private_implementation__high_prec_dec__to_f64(wuffs_base__private_implementation__high_prec_dec * h,uint32_t options)17451 wuffs_base__private_implementation__high_prec_dec__to_f64(
17452     wuffs_base__private_implementation__high_prec_dec* h,
17453     uint32_t options) {
17454   do {
17455     // powers converts decimal powers of 10 to binary powers of 2. For example,
17456     // (10000 >> 13) is 1. It stops before the elements exceed 60, also known
17457     // as WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL.
17458     //
17459     // This rounds down (1<<13 is a lower bound for 1e4). Adding 1 to the array
17460     // element value rounds up (1<<14 is an upper bound for 1e4) while staying
17461     // at or below WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL.
17462     //
17463     // When starting in the range [1e+1 .. 1e+2] (i.e. h->decimal_point == +2),
17464     // powers[2] == 6 and so:
17465     //  - Right shifting by 6+0 produces the range [10/64 .. 100/64] =
17466     //    [0.156250 .. 1.56250]. The resultant h->decimal_point is +0 or +1.
17467     //  - Right shifting by 6+1 produces the range [10/128 .. 100/128] =
17468     //    [0.078125 .. 0.78125]. The resultant h->decimal_point is -1 or -0.
17469     //
17470     // When starting in the range [1e-3 .. 1e-2] (i.e. h->decimal_point == -2),
17471     // powers[2] == 6 and so:
17472     //  - Left shifting by 6+0 produces the range [0.001*64 .. 0.01*64] =
17473     //    [0.064 .. 0.64]. The resultant h->decimal_point is -1 or -0.
17474     //  - Left shifting by 6+1 produces the range [0.001*128 .. 0.01*128] =
17475     //    [0.128 .. 1.28]. The resultant h->decimal_point is +0 or +1.
17476     //
17477     // Thus, when targeting h->decimal_point being +0 or +1, use (powers[n]+0)
17478     // when right shifting but (powers[n]+1) when left shifting.
17479     static const uint32_t num_powers = 19;
17480     static const uint8_t powers[19] = {
17481         0,  3,  6,  9,  13, 16, 19, 23, 26, 29,  //
17482         33, 36, 39, 43, 46, 49, 53, 56, 59,      //
17483     };
17484 
17485     // Handle zero and obvious extremes. The largest and smallest positive
17486     // finite f64 values are approximately 1.8e+308 and 4.9e-324.
17487     if ((h->num_digits == 0) || (h->decimal_point < -326)) {
17488       goto zero;
17489     } else if (h->decimal_point > 310) {
17490       goto infinity;
17491     }
17492 
17493     // Try the fast Eisel-Lemire algorithm again. Calculating the (man, exp10)
17494     // pair from the high_prec_dec h is more correct but slower than the
17495     // approach taken in wuffs_base__parse_number_f64. The latter is optimized
17496     // for the common cases (e.g. assuming no underscores or a leading '+'
17497     // sign) rather than the full set of cases allowed by the Wuffs API.
17498     //
17499     // When we have 19 or fewer mantissa digits, run Eisel-Lemire once (trying
17500     // for an exact result). When we have more than 19 mantissa digits, run it
17501     // twice to get a lower and upper bound. We still have an exact result
17502     // (within f64's rounding margin) if both bounds are equal (and valid).
17503     uint32_t i_max = h->num_digits;
17504     if (i_max > 19) {
17505       i_max = 19;
17506     }
17507     int32_t exp10 = h->decimal_point - ((int32_t)i_max);
17508     if ((-307 <= exp10) && (exp10 <= 288)) {
17509       uint64_t man = 0;
17510       uint32_t i;
17511       for (i = 0; i < i_max; i++) {
17512         man = (10 * man) + h->digits[i];
17513       }
17514       while (man != 0) {  // The 'while' is just an 'if' that we can 'break'.
17515         int64_t r0 =
17516             wuffs_base__private_implementation__parse_number_f64_eisel_lemire(
17517                 man + 0, exp10);
17518         if (r0 < 0) {
17519           break;
17520         } else if (h->num_digits > 19) {
17521           int64_t r1 =
17522               wuffs_base__private_implementation__parse_number_f64_eisel_lemire(
17523                   man + 1, exp10);
17524           if (r1 != r0) {
17525             break;
17526           }
17527         }
17528         wuffs_base__result_f64 ret;
17529         ret.status.repr = NULL;
17530         ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
17531             ((uint64_t)r0) | (((uint64_t)(h->negative)) << 63));
17532         return ret;
17533       }
17534     }
17535 
17536     // When Eisel-Lemire fails, fall back to Simple Decimal Conversion. See
17537     // https://nigeltao.github.io/blog/2020/parse-number-f64-simple.html
17538     //
17539     // Scale by powers of 2 until we're in the range [0.1 .. 10]. Equivalently,
17540     // that h->decimal_point is +0 or +1.
17541     //
17542     // First we shift right while at or above 10...
17543     const int32_t f64_bias = -1023;
17544     int32_t exp2 = 0;
17545     while (h->decimal_point > 1) {
17546       uint32_t n = (uint32_t)(+h->decimal_point);
17547       uint32_t shift =
17548           (n < num_powers)
17549               ? powers[n]
17550               : WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
17551 
17552       wuffs_base__private_implementation__high_prec_dec__small_rshift(h, shift);
17553       if (h->decimal_point <
17554           -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
17555         goto zero;
17556       }
17557       exp2 += (int32_t)shift;
17558     }
17559     // ...then we shift left while below 0.1.
17560     while (h->decimal_point < 0) {
17561       uint32_t shift;
17562       uint32_t n = (uint32_t)(-h->decimal_point);
17563       shift = (n < num_powers)
17564                   // The +1 is per "when targeting h->decimal_point being +0 or
17565                   // +1... when left shifting" in the powers comment above.
17566                   ? (powers[n] + 1)
17567                   : WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
17568 
17569       wuffs_base__private_implementation__high_prec_dec__small_lshift(h, shift);
17570       if (h->decimal_point >
17571           +WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
17572         goto infinity;
17573       }
17574       exp2 -= (int32_t)shift;
17575     }
17576 
17577     // To get from "in the range [0.1 .. 10]" to "in the range [1 .. 2]" (which
17578     // will give us our exponent in base-2), the mantissa's first 3 digits will
17579     // determine the final left shift, equal to 52 (the number of explicit f64
17580     // bits) plus an additional adjustment.
17581     int man3 = (100 * h->digits[0]) +
17582                ((h->num_digits > 1) ? (10 * h->digits[1]) : 0) +
17583                ((h->num_digits > 2) ? h->digits[2] : 0);
17584     int32_t additional_lshift = 0;
17585     if (h->decimal_point == 0) {  // The value is in [0.1 .. 1].
17586       if (man3 < 125) {
17587         additional_lshift = +4;
17588       } else if (man3 < 250) {
17589         additional_lshift = +3;
17590       } else if (man3 < 500) {
17591         additional_lshift = +2;
17592       } else {
17593         additional_lshift = +1;
17594       }
17595     } else {  // The value is in [1 .. 10].
17596       if (man3 < 200) {
17597         additional_lshift = -0;
17598       } else if (man3 < 400) {
17599         additional_lshift = -1;
17600       } else if (man3 < 800) {
17601         additional_lshift = -2;
17602       } else {
17603         additional_lshift = -3;
17604       }
17605     }
17606     exp2 -= additional_lshift;
17607     uint32_t final_lshift = (uint32_t)(52 + additional_lshift);
17608 
17609     // The minimum normal exponent is (f64_bias + 1).
17610     while ((f64_bias + 1) > exp2) {
17611       uint32_t n = (uint32_t)((f64_bias + 1) - exp2);
17612       if (n > WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL) {
17613         n = WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
17614       }
17615       wuffs_base__private_implementation__high_prec_dec__small_rshift(h, n);
17616       exp2 += (int32_t)n;
17617     }
17618 
17619     // Check for overflow.
17620     if ((exp2 - f64_bias) >= 0x07FF) {  // (1 << 11) - 1.
17621       goto infinity;
17622     }
17623 
17624     // Extract 53 bits for the mantissa (in base-2).
17625     wuffs_base__private_implementation__high_prec_dec__small_lshift(
17626         h, final_lshift);
17627     uint64_t man2 =
17628         wuffs_base__private_implementation__high_prec_dec__rounded_integer(h);
17629 
17630     // Rounding might have added one bit. If so, shift and re-check overflow.
17631     if ((man2 >> 53) != 0) {
17632       man2 >>= 1;
17633       exp2++;
17634       if ((exp2 - f64_bias) >= 0x07FF) {  // (1 << 11) - 1.
17635         goto infinity;
17636       }
17637     }
17638 
17639     // Handle subnormal numbers.
17640     if ((man2 >> 52) == 0) {
17641       exp2 = f64_bias;
17642     }
17643 
17644     // Pack the bits and return.
17645     uint64_t exp2_bits =
17646         (uint64_t)((exp2 - f64_bias) & 0x07FF);              // (1 << 11) - 1.
17647     uint64_t bits = (man2 & 0x000FFFFFFFFFFFFF) |            // (1 << 52) - 1.
17648                     (exp2_bits << 52) |                      //
17649                     (h->negative ? 0x8000000000000000 : 0);  // (1 << 63).
17650 
17651     wuffs_base__result_f64 ret;
17652     ret.status.repr = NULL;
17653     ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(bits);
17654     return ret;
17655   } while (0);
17656 
17657 zero:
17658   do {
17659     uint64_t bits = h->negative ? 0x8000000000000000 : 0;
17660 
17661     wuffs_base__result_f64 ret;
17662     ret.status.repr = NULL;
17663     ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(bits);
17664     return ret;
17665   } while (0);
17666 
17667 infinity:
17668   do {
17669     if (options & WUFFS_BASE__PARSE_NUMBER_FXX__REJECT_INF_AND_NAN) {
17670       wuffs_base__result_f64 ret;
17671       ret.status.repr = wuffs_base__error__bad_argument;
17672       ret.value = 0;
17673       return ret;
17674     }
17675 
17676     uint64_t bits = h->negative ? 0xFFF0000000000000 : 0x7FF0000000000000;
17677 
17678     wuffs_base__result_f64 ret;
17679     ret.status.repr = NULL;
17680     ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(bits);
17681     return ret;
17682   } while (0);
17683 }
17684 
17685 static inline bool  //
wuffs_base__private_implementation__is_decimal_digit(uint8_t c)17686 wuffs_base__private_implementation__is_decimal_digit(uint8_t c) {
17687   return ('0' <= c) && (c <= '9');
17688 }
17689 
17690 WUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64  //
wuffs_base__parse_number_f64(wuffs_base__slice_u8 s,uint32_t options)17691 wuffs_base__parse_number_f64(wuffs_base__slice_u8 s, uint32_t options) {
17692   // In practice, almost all "dd.ddddE±xxx" numbers can be represented
17693   // losslessly by a uint64_t mantissa "dddddd" and an int32_t base-10
17694   // exponent, adjusting "xxx" for the position (if present) of the decimal
17695   // separator '.' or ','.
17696   //
17697   // This (u64 man, i32 exp10) data structure is superficially similar to the
17698   // "Do It Yourself Floating Point" type from Loitsch (†), but the exponent
17699   // here is base-10, not base-2.
17700   //
17701   // If s's number fits in a (man, exp10), parse that pair with the
17702   // Eisel-Lemire algorithm. If not, or if Eisel-Lemire fails, parsing s with
17703   // the fallback algorithm is slower but comprehensive.
17704   //
17705   // † "Printing Floating-Point Numbers Quickly and Accurately with Integers"
17706   // (https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf).
17707   // Florian Loitsch is also the primary contributor to
17708   // https://github.com/google/double-conversion
17709   do {
17710     // Calculating that (man, exp10) pair needs to stay within s's bounds.
17711     // Provided that s isn't extremely long, work on a NUL-terminated copy of
17712     // s's contents. The NUL byte isn't a valid part of "±dd.ddddE±xxx".
17713     //
17714     // As the pointer p walks the contents, it's faster to repeatedly check "is
17715     // *p a valid digit" than "is p within bounds and *p a valid digit".
17716     if (s.len >= 256) {
17717       goto fallback;
17718     }
17719     uint8_t z[256];
17720     memcpy(&z[0], s.ptr, s.len);
17721     z[s.len] = 0;
17722     const uint8_t* p = &z[0];
17723 
17724     // Look for a leading minus sign. Technically, we could also look for an
17725     // optional plus sign, but the "script/process-json-numbers.c with -p"
17726     // benchmark is noticably slower if we do. It's optional and, in practice,
17727     // usually absent. Let the fallback catch it.
17728     bool negative = (*p == '-');
17729     if (negative) {
17730       p++;
17731     }
17732 
17733     // After walking "dd.dddd", comparing p later with p now will produce the
17734     // number of "d"s and "."s.
17735     const uint8_t* const start_of_digits_ptr = p;
17736 
17737     // Walk the "d"s before a '.', 'E', NUL byte, etc. If it starts with '0',
17738     // it must be a single '0'. If it starts with a non-zero decimal digit, it
17739     // can be a sequence of decimal digits.
17740     //
17741     // Update the man variable during the walk. It's OK if man overflows now.
17742     // We'll detect that later.
17743     uint64_t man;
17744     if (*p == '0') {
17745       man = 0;
17746       p++;
17747       if (wuffs_base__private_implementation__is_decimal_digit(*p)) {
17748         goto fallback;
17749       }
17750     } else if (wuffs_base__private_implementation__is_decimal_digit(*p)) {
17751       man = ((uint8_t)(*p - '0'));
17752       p++;
17753       for (; wuffs_base__private_implementation__is_decimal_digit(*p); p++) {
17754         man = (10 * man) + ((uint8_t)(*p - '0'));
17755       }
17756     } else {
17757       goto fallback;
17758     }
17759 
17760     // Walk the "d"s after the optional decimal separator ('.' or ','),
17761     // updating the man and exp10 variables.
17762     int32_t exp10 = 0;
17763     if (*p ==
17764         ((options & WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)
17765              ? ','
17766              : '.')) {
17767       p++;
17768       const uint8_t* first_after_separator_ptr = p;
17769       if (!wuffs_base__private_implementation__is_decimal_digit(*p)) {
17770         goto fallback;
17771       }
17772       man = (10 * man) + ((uint8_t)(*p - '0'));
17773       p++;
17774       for (; wuffs_base__private_implementation__is_decimal_digit(*p); p++) {
17775         man = (10 * man) + ((uint8_t)(*p - '0'));
17776       }
17777       exp10 = ((int32_t)(first_after_separator_ptr - p));
17778     }
17779 
17780     // Count the number of digits:
17781     //  - for an input of "314159",  digit_count is 6.
17782     //  - for an input of "3.14159", digit_count is 7.
17783     //
17784     // This is off-by-one if there is a decimal separator. That's OK for now.
17785     // We'll correct for that later. The "script/process-json-numbers.c with
17786     // -p" benchmark is noticably slower if we try to correct for that now.
17787     uint32_t digit_count = (uint32_t)(p - start_of_digits_ptr);
17788 
17789     // Update exp10 for the optional exponent, starting with 'E' or 'e'.
17790     if ((*p | 0x20) == 'e') {
17791       p++;
17792       int32_t exp_sign = +1;
17793       if (*p == '-') {
17794         p++;
17795         exp_sign = -1;
17796       } else if (*p == '+') {
17797         p++;
17798       }
17799       if (!wuffs_base__private_implementation__is_decimal_digit(*p)) {
17800         goto fallback;
17801       }
17802       int32_t exp_num = ((uint8_t)(*p - '0'));
17803       p++;
17804       // The rest of the exp_num walking has a peculiar control flow but, once
17805       // again, the "script/process-json-numbers.c with -p" benchmark is
17806       // sensitive to alternative formulations.
17807       if (wuffs_base__private_implementation__is_decimal_digit(*p)) {
17808         exp_num = (10 * exp_num) + ((uint8_t)(*p - '0'));
17809         p++;
17810       }
17811       if (wuffs_base__private_implementation__is_decimal_digit(*p)) {
17812         exp_num = (10 * exp_num) + ((uint8_t)(*p - '0'));
17813         p++;
17814       }
17815       while (wuffs_base__private_implementation__is_decimal_digit(*p)) {
17816         if (exp_num > 0x1000000) {
17817           goto fallback;
17818         }
17819         exp_num = (10 * exp_num) + ((uint8_t)(*p - '0'));
17820         p++;
17821       }
17822       exp10 += exp_sign * exp_num;
17823     }
17824 
17825     // The Wuffs API is that the original slice has no trailing data. It also
17826     // allows underscores, which we don't catch here but the fallback should.
17827     if (p != &z[s.len]) {
17828       goto fallback;
17829     }
17830 
17831     // Check that the uint64_t typed man variable has not overflowed, based on
17832     // digit_count.
17833     //
17834     // For reference:
17835     //   - (1 << 63) is  9223372036854775808, which has 19 decimal digits.
17836     //   - (1 << 64) is 18446744073709551616, which has 20 decimal digits.
17837     //   - 19 nines,  9999999999999999999, is  0x8AC7230489E7FFFF, which has 64
17838     //     bits and 16 hexadecimal digits.
17839     //   - 20 nines, 99999999999999999999, is 0x56BC75E2D630FFFFF, which has 67
17840     //     bits and 17 hexadecimal digits.
17841     if (digit_count > 19) {
17842       // Even if we have more than 19 pseudo-digits, it's not yet definitely an
17843       // overflow. Recall that digit_count might be off-by-one (too large) if
17844       // there's a decimal separator. It will also over-report the number of
17845       // meaningful digits if the input looks something like "0.000dddExxx".
17846       //
17847       // We adjust by the number of leading '0's and '.'s and re-compare to 19.
17848       // Once again, technically, we could skip ','s too, but that perturbs the
17849       // "script/process-json-numbers.c with -p" benchmark.
17850       const uint8_t* q = start_of_digits_ptr;
17851       for (; (*q == '0') || (*q == '.'); q++) {
17852       }
17853       digit_count -= (uint32_t)(q - start_of_digits_ptr);
17854       if (digit_count > 19) {
17855         goto fallback;
17856       }
17857     }
17858 
17859     // The wuffs_base__private_implementation__parse_number_f64_eisel_lemire
17860     // preconditions include that exp10 is in the range [-307 ..= 288].
17861     if ((exp10 < -307) || (288 < exp10)) {
17862       goto fallback;
17863     }
17864 
17865     // If both man and (10 ** exp10) are exactly representable by a double, we
17866     // don't need to run the Eisel-Lemire algorithm.
17867     if ((-22 <= exp10) && (exp10 <= 22) && ((man >> 53) == 0)) {
17868       double d = (double)man;
17869       if (exp10 >= 0) {
17870         d *= wuffs_base__private_implementation__f64_powers_of_10[+exp10];
17871       } else {
17872         d /= wuffs_base__private_implementation__f64_powers_of_10[-exp10];
17873       }
17874       wuffs_base__result_f64 ret;
17875       ret.status.repr = NULL;
17876       ret.value = negative ? -d : +d;
17877       return ret;
17878     }
17879 
17880     // The wuffs_base__private_implementation__parse_number_f64_eisel_lemire
17881     // preconditions include that man is non-zero. Parsing "0" should be caught
17882     // by the "If both man and (10 ** exp10)" above, but "0e99" might not.
17883     if (man == 0) {
17884       goto fallback;
17885     }
17886 
17887     // Our man and exp10 are in range. Run the Eisel-Lemire algorithm.
17888     int64_t r =
17889         wuffs_base__private_implementation__parse_number_f64_eisel_lemire(
17890             man, exp10);
17891     if (r < 0) {
17892       goto fallback;
17893     }
17894     wuffs_base__result_f64 ret;
17895     ret.status.repr = NULL;
17896     ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
17897         ((uint64_t)r) | (((uint64_t)negative) << 63));
17898     return ret;
17899   } while (0);
17900 
17901 fallback:
17902   do {
17903     wuffs_base__private_implementation__high_prec_dec h;
17904     wuffs_base__status status =
17905         wuffs_base__private_implementation__high_prec_dec__parse(&h, s,
17906                                                                  options);
17907     if (status.repr) {
17908       return wuffs_base__private_implementation__parse_number_f64_special(
17909           s, options);
17910     }
17911     return wuffs_base__private_implementation__high_prec_dec__to_f64(&h,
17912                                                                      options);
17913   } while (0);
17914 }
17915 
17916 // --------
17917 
17918 static inline size_t  //
wuffs_base__private_implementation__render_inf(wuffs_base__slice_u8 dst,bool neg,uint32_t options)17919 wuffs_base__private_implementation__render_inf(wuffs_base__slice_u8 dst,
17920                                                bool neg,
17921                                                uint32_t options) {
17922   if (neg) {
17923     if (dst.len < 4) {
17924       return 0;
17925     }
17926     wuffs_base__poke_u32le__no_bounds_check(dst.ptr, 0x666E492D);  // '-Inf'le.
17927     return 4;
17928   }
17929 
17930   if (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN) {
17931     if (dst.len < 4) {
17932       return 0;
17933     }
17934     wuffs_base__poke_u32le__no_bounds_check(dst.ptr, 0x666E492B);  // '+Inf'le.
17935     return 4;
17936   }
17937 
17938   if (dst.len < 3) {
17939     return 0;
17940   }
17941   wuffs_base__poke_u24le__no_bounds_check(dst.ptr, 0x666E49);  // 'Inf'le.
17942   return 3;
17943 }
17944 
17945 static inline size_t  //
wuffs_base__private_implementation__render_nan(wuffs_base__slice_u8 dst)17946 wuffs_base__private_implementation__render_nan(wuffs_base__slice_u8 dst) {
17947   if (dst.len < 3) {
17948     return 0;
17949   }
17950   wuffs_base__poke_u24le__no_bounds_check(dst.ptr, 0x4E614E);  // 'NaN'le.
17951   return 3;
17952 }
17953 
17954 static size_t  //
wuffs_base__private_implementation__high_prec_dec__render_exponent_absent(wuffs_base__slice_u8 dst,wuffs_base__private_implementation__high_prec_dec * h,uint32_t precision,uint32_t options)17955 wuffs_base__private_implementation__high_prec_dec__render_exponent_absent(
17956     wuffs_base__slice_u8 dst,
17957     wuffs_base__private_implementation__high_prec_dec* h,
17958     uint32_t precision,
17959     uint32_t options) {
17960   size_t n = (h->negative ||
17961               (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN))
17962                  ? 1
17963                  : 0;
17964   if (h->decimal_point <= 0) {
17965     n += 1;
17966   } else {
17967     n += (size_t)(h->decimal_point);
17968   }
17969   if (precision > 0) {
17970     n += precision + 1;  // +1 for the '.'.
17971   }
17972 
17973   // Don't modify dst if the formatted number won't fit.
17974   if (n > dst.len) {
17975     return 0;
17976   }
17977 
17978   // Align-left or align-right.
17979   uint8_t* ptr = (options & WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT)
17980                      ? &dst.ptr[dst.len - n]
17981                      : &dst.ptr[0];
17982 
17983   // Leading "±".
17984   if (h->negative) {
17985     *ptr++ = '-';
17986   } else if (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN) {
17987     *ptr++ = '+';
17988   }
17989 
17990   // Integral digits.
17991   if (h->decimal_point <= 0) {
17992     *ptr++ = '0';
17993   } else {
17994     uint32_t m =
17995         wuffs_base__u32__min(h->num_digits, (uint32_t)(h->decimal_point));
17996     uint32_t i = 0;
17997     for (; i < m; i++) {
17998       *ptr++ = (uint8_t)('0' | h->digits[i]);
17999     }
18000     for (; i < (uint32_t)(h->decimal_point); i++) {
18001       *ptr++ = '0';
18002     }
18003   }
18004 
18005   // Separator and then fractional digits.
18006   if (precision > 0) {
18007     *ptr++ =
18008         (options & WUFFS_BASE__RENDER_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)
18009             ? ','
18010             : '.';
18011     uint32_t i = 0;
18012     for (; i < precision; i++) {
18013       uint32_t j = ((uint32_t)(h->decimal_point)) + i;
18014       *ptr++ = (uint8_t)('0' | ((j < h->num_digits) ? h->digits[j] : 0));
18015     }
18016   }
18017 
18018   return n;
18019 }
18020 
18021 static size_t  //
wuffs_base__private_implementation__high_prec_dec__render_exponent_present(wuffs_base__slice_u8 dst,wuffs_base__private_implementation__high_prec_dec * h,uint32_t precision,uint32_t options)18022 wuffs_base__private_implementation__high_prec_dec__render_exponent_present(
18023     wuffs_base__slice_u8 dst,
18024     wuffs_base__private_implementation__high_prec_dec* h,
18025     uint32_t precision,
18026     uint32_t options) {
18027   int32_t exp = 0;
18028   if (h->num_digits > 0) {
18029     exp = h->decimal_point - 1;
18030   }
18031   bool negative_exp = exp < 0;
18032   if (negative_exp) {
18033     exp = -exp;
18034   }
18035 
18036   size_t n = (h->negative ||
18037               (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN))
18038                  ? 4
18039                  : 3;  // Mininum 3 bytes: first digit and then "e±".
18040   if (precision > 0) {
18041     n += precision + 1;  // +1 for the '.'.
18042   }
18043   n += (exp < 100) ? 2 : 3;
18044 
18045   // Don't modify dst if the formatted number won't fit.
18046   if (n > dst.len) {
18047     return 0;
18048   }
18049 
18050   // Align-left or align-right.
18051   uint8_t* ptr = (options & WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT)
18052                      ? &dst.ptr[dst.len - n]
18053                      : &dst.ptr[0];
18054 
18055   // Leading "±".
18056   if (h->negative) {
18057     *ptr++ = '-';
18058   } else if (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN) {
18059     *ptr++ = '+';
18060   }
18061 
18062   // Integral digit.
18063   if (h->num_digits > 0) {
18064     *ptr++ = (uint8_t)('0' | h->digits[0]);
18065   } else {
18066     *ptr++ = '0';
18067   }
18068 
18069   // Separator and then fractional digits.
18070   if (precision > 0) {
18071     *ptr++ =
18072         (options & WUFFS_BASE__RENDER_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)
18073             ? ','
18074             : '.';
18075     uint32_t i = 1;
18076     uint32_t j = wuffs_base__u32__min(h->num_digits, precision + 1);
18077     for (; i < j; i++) {
18078       *ptr++ = (uint8_t)('0' | h->digits[i]);
18079     }
18080     for (; i <= precision; i++) {
18081       *ptr++ = '0';
18082     }
18083   }
18084 
18085   // Exponent: "e±" and then 2 or 3 digits.
18086   *ptr++ = 'e';
18087   *ptr++ = negative_exp ? '-' : '+';
18088   if (exp < 10) {
18089     *ptr++ = '0';
18090     *ptr++ = (uint8_t)('0' | exp);
18091   } else if (exp < 100) {
18092     *ptr++ = (uint8_t)('0' | (exp / 10));
18093     *ptr++ = (uint8_t)('0' | (exp % 10));
18094   } else {
18095     int32_t e = exp / 100;
18096     exp -= e * 100;
18097     *ptr++ = (uint8_t)('0' | e);
18098     *ptr++ = (uint8_t)('0' | (exp / 10));
18099     *ptr++ = (uint8_t)('0' | (exp % 10));
18100   }
18101 
18102   return n;
18103 }
18104 
18105 WUFFS_BASE__MAYBE_STATIC size_t  //
wuffs_base__render_number_f64(wuffs_base__slice_u8 dst,double x,uint32_t precision,uint32_t options)18106 wuffs_base__render_number_f64(wuffs_base__slice_u8 dst,
18107                               double x,
18108                               uint32_t precision,
18109                               uint32_t options) {
18110   // Decompose x (64 bits) into negativity (1 bit), base-2 exponent (11 bits
18111   // with a -1023 bias) and mantissa (52 bits).
18112   uint64_t bits = wuffs_base__ieee_754_bit_representation__from_f64_to_u64(x);
18113   bool neg = (bits >> 63) != 0;
18114   int32_t exp2 = ((int32_t)(bits >> 52)) & 0x7FF;
18115   uint64_t man = bits & 0x000FFFFFFFFFFFFFul;
18116 
18117   // Apply the exponent bias and set the implicit top bit of the mantissa,
18118   // unless x is subnormal. Also take care of Inf and NaN.
18119   if (exp2 == 0x7FF) {
18120     if (man != 0) {
18121       return wuffs_base__private_implementation__render_nan(dst);
18122     }
18123     return wuffs_base__private_implementation__render_inf(dst, neg, options);
18124   } else if (exp2 == 0) {
18125     exp2 = -1022;
18126   } else {
18127     exp2 -= 1023;
18128     man |= 0x0010000000000000ul;
18129   }
18130 
18131   // Ensure that precision isn't too large.
18132   if (precision > 4095) {
18133     precision = 4095;
18134   }
18135 
18136   // Convert from the (neg, exp2, man) tuple to an HPD.
18137   wuffs_base__private_implementation__high_prec_dec h;
18138   wuffs_base__private_implementation__high_prec_dec__assign(&h, man, neg);
18139   if (h.num_digits > 0) {
18140     wuffs_base__private_implementation__high_prec_dec__lshift(
18141         &h, exp2 - 52);  // 52 mantissa bits.
18142   }
18143 
18144   // Handle the "%e" and "%f" formats.
18145   switch (options & (WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_ABSENT |
18146                      WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_PRESENT)) {
18147     case WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_ABSENT:  // The "%"f" format.
18148       if (options & WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION) {
18149         wuffs_base__private_implementation__high_prec_dec__round_just_enough(
18150             &h, exp2, man);
18151         int32_t p = ((int32_t)(h.num_digits)) - h.decimal_point;
18152         precision = ((uint32_t)(wuffs_base__i32__max(0, p)));
18153       } else {
18154         wuffs_base__private_implementation__high_prec_dec__round_nearest(
18155             &h, ((int32_t)precision) + h.decimal_point);
18156       }
18157       return wuffs_base__private_implementation__high_prec_dec__render_exponent_absent(
18158           dst, &h, precision, options);
18159 
18160     case WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_PRESENT:  // The "%e" format.
18161       if (options & WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION) {
18162         wuffs_base__private_implementation__high_prec_dec__round_just_enough(
18163             &h, exp2, man);
18164         precision = (h.num_digits > 0) ? (h.num_digits - 1) : 0;
18165       } else {
18166         wuffs_base__private_implementation__high_prec_dec__round_nearest(
18167             &h, ((int32_t)precision) + 1);
18168       }
18169       return wuffs_base__private_implementation__high_prec_dec__render_exponent_present(
18170           dst, &h, precision, options);
18171   }
18172 
18173   // We have the "%g" format and so precision means the number of significant
18174   // digits, not the number of digits after the decimal separator. Perform
18175   // rounding and determine whether to use "%e" or "%f".
18176   int32_t e_threshold = 0;
18177   if (options & WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION) {
18178     wuffs_base__private_implementation__high_prec_dec__round_just_enough(
18179         &h, exp2, man);
18180     precision = h.num_digits;
18181     e_threshold = 6;
18182   } else {
18183     if (precision == 0) {
18184       precision = 1;
18185     }
18186     wuffs_base__private_implementation__high_prec_dec__round_nearest(
18187         &h, ((int32_t)precision));
18188     e_threshold = ((int32_t)precision);
18189     int32_t nd = ((int32_t)(h.num_digits));
18190     if ((e_threshold > nd) && (nd >= h.decimal_point)) {
18191       e_threshold = nd;
18192     }
18193   }
18194 
18195   // Use the "%e" format if the exponent is large.
18196   int32_t e = h.decimal_point - 1;
18197   if ((e < -4) || (e_threshold <= e)) {
18198     uint32_t p = wuffs_base__u32__min(precision, h.num_digits);
18199     return wuffs_base__private_implementation__high_prec_dec__render_exponent_present(
18200         dst, &h, (p > 0) ? (p - 1) : 0, options);
18201   }
18202 
18203   // Use the "%f" format otherwise.
18204   int32_t p = ((int32_t)precision);
18205   if (p > h.decimal_point) {
18206     p = ((int32_t)(h.num_digits));
18207   }
18208   precision = ((uint32_t)(wuffs_base__i32__max(0, p - h.decimal_point)));
18209   return wuffs_base__private_implementation__high_prec_dec__render_exponent_absent(
18210       dst, &h, precision, options);
18211 }
18212 
18213 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
18214         // defined(WUFFS_CONFIG__MODULE__BASE) ||
18215         // defined(WUFFS_CONFIG__MODULE__BASE__FLOATCONV)
18216 
18217 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
18218     defined(WUFFS_CONFIG__MODULE__BASE__INTCONV)
18219 
18220 // ---------------- Integer
18221 
18222 // wuffs_base__parse_number__foo_digits entries are 0x00 for invalid digits,
18223 // and (0x80 | v) for valid digits, where v is the 4 bit value.
18224 
18225 static const uint8_t wuffs_base__parse_number__decimal_digits[256] = {
18226     // 0     1     2     3     4     5     6     7
18227     // 8     9     A     B     C     D     E     F
18228     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x00 ..= 0x07.
18229     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x08 ..= 0x0F.
18230     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x10 ..= 0x17.
18231     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x18 ..= 0x1F.
18232     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x20 ..= 0x27.
18233     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x28 ..= 0x2F.
18234     0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,  // 0x30 ..= 0x37. '0'-'7'.
18235     0x88, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x38 ..= 0x3F. '8'-'9'.
18236 
18237     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x40 ..= 0x47.
18238     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x48 ..= 0x4F.
18239     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x50 ..= 0x57.
18240     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x58 ..= 0x5F.
18241     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x60 ..= 0x67.
18242     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x68 ..= 0x6F.
18243     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x70 ..= 0x77.
18244     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x78 ..= 0x7F.
18245 
18246     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x80 ..= 0x87.
18247     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x88 ..= 0x8F.
18248     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x90 ..= 0x97.
18249     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x98 ..= 0x9F.
18250     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xA0 ..= 0xA7.
18251     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xA8 ..= 0xAF.
18252     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xB0 ..= 0xB7.
18253     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xB8 ..= 0xBF.
18254 
18255     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xC0 ..= 0xC7.
18256     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xC8 ..= 0xCF.
18257     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xD0 ..= 0xD7.
18258     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xD8 ..= 0xDF.
18259     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xE0 ..= 0xE7.
18260     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xE8 ..= 0xEF.
18261     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xF0 ..= 0xF7.
18262     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xF8 ..= 0xFF.
18263     // 0     1     2     3     4     5     6     7
18264     // 8     9     A     B     C     D     E     F
18265 };
18266 
18267 static const uint8_t wuffs_base__parse_number__hexadecimal_digits[256] = {
18268     // 0     1     2     3     4     5     6     7
18269     // 8     9     A     B     C     D     E     F
18270     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x00 ..= 0x07.
18271     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x08 ..= 0x0F.
18272     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x10 ..= 0x17.
18273     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x18 ..= 0x1F.
18274     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x20 ..= 0x27.
18275     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x28 ..= 0x2F.
18276     0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,  // 0x30 ..= 0x37. '0'-'7'.
18277     0x88, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x38 ..= 0x3F. '8'-'9'.
18278 
18279     0x00, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x00,  // 0x40 ..= 0x47. 'A'-'F'.
18280     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x48 ..= 0x4F.
18281     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x50 ..= 0x57.
18282     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x58 ..= 0x5F.
18283     0x00, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x00,  // 0x60 ..= 0x67. 'a'-'f'.
18284     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x68 ..= 0x6F.
18285     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x70 ..= 0x77.
18286     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x78 ..= 0x7F.
18287 
18288     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x80 ..= 0x87.
18289     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x88 ..= 0x8F.
18290     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x90 ..= 0x97.
18291     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x98 ..= 0x9F.
18292     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xA0 ..= 0xA7.
18293     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xA8 ..= 0xAF.
18294     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xB0 ..= 0xB7.
18295     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xB8 ..= 0xBF.
18296 
18297     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xC0 ..= 0xC7.
18298     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xC8 ..= 0xCF.
18299     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xD0 ..= 0xD7.
18300     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xD8 ..= 0xDF.
18301     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xE0 ..= 0xE7.
18302     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xE8 ..= 0xEF.
18303     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xF0 ..= 0xF7.
18304     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xF8 ..= 0xFF.
18305     // 0     1     2     3     4     5     6     7
18306     // 8     9     A     B     C     D     E     F
18307 };
18308 
18309 static const uint8_t wuffs_base__private_implementation__encode_base16[16] = {
18310     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,  // 0x00 ..= 0x07.
18311     0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,  // 0x08 ..= 0x0F.
18312 };
18313 
18314 // --------
18315 
18316 WUFFS_BASE__MAYBE_STATIC wuffs_base__result_i64  //
wuffs_base__parse_number_i64(wuffs_base__slice_u8 s,uint32_t options)18317 wuffs_base__parse_number_i64(wuffs_base__slice_u8 s, uint32_t options) {
18318   uint8_t* p = s.ptr;
18319   uint8_t* q = s.ptr + s.len;
18320 
18321   if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
18322     for (; (p < q) && (*p == '_'); p++) {
18323     }
18324   }
18325 
18326   bool negative = false;
18327   if (p >= q) {
18328     goto fail_bad_argument;
18329   } else if (*p == '-') {
18330     p++;
18331     negative = true;
18332   } else if (*p == '+') {
18333     p++;
18334   }
18335 
18336   do {
18337     wuffs_base__result_u64 r = wuffs_base__parse_number_u64(
18338         wuffs_base__make_slice_u8(p, (size_t)(q - p)), options);
18339     if (r.status.repr != NULL) {
18340       wuffs_base__result_i64 ret;
18341       ret.status.repr = r.status.repr;
18342       ret.value = 0;
18343       return ret;
18344     } else if (negative) {
18345       if (r.value < 0x8000000000000000) {
18346         wuffs_base__result_i64 ret;
18347         ret.status.repr = NULL;
18348         ret.value = -(int64_t)(r.value);
18349         return ret;
18350       } else if (r.value == 0x8000000000000000) {
18351         wuffs_base__result_i64 ret;
18352         ret.status.repr = NULL;
18353         ret.value = INT64_MIN;
18354         return ret;
18355       }
18356       goto fail_out_of_bounds;
18357     } else if (r.value > 0x7FFFFFFFFFFFFFFF) {
18358       goto fail_out_of_bounds;
18359     } else {
18360       wuffs_base__result_i64 ret;
18361       ret.status.repr = NULL;
18362       ret.value = +(int64_t)(r.value);
18363       return ret;
18364     }
18365   } while (0);
18366 
18367 fail_bad_argument:
18368   do {
18369     wuffs_base__result_i64 ret;
18370     ret.status.repr = wuffs_base__error__bad_argument;
18371     ret.value = 0;
18372     return ret;
18373   } while (0);
18374 
18375 fail_out_of_bounds:
18376   do {
18377     wuffs_base__result_i64 ret;
18378     ret.status.repr = wuffs_base__error__out_of_bounds;
18379     ret.value = 0;
18380     return ret;
18381   } while (0);
18382 }
18383 
18384 WUFFS_BASE__MAYBE_STATIC wuffs_base__result_u64  //
wuffs_base__parse_number_u64(wuffs_base__slice_u8 s,uint32_t options)18385 wuffs_base__parse_number_u64(wuffs_base__slice_u8 s, uint32_t options) {
18386   uint8_t* p = s.ptr;
18387   uint8_t* q = s.ptr + s.len;
18388 
18389   if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
18390     for (; (p < q) && (*p == '_'); p++) {
18391     }
18392   }
18393 
18394   if (p >= q) {
18395     goto fail_bad_argument;
18396 
18397   } else if (*p == '0') {
18398     p++;
18399     if (p >= q) {
18400       goto ok_zero;
18401     }
18402     if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
18403       if (*p == '_') {
18404         p++;
18405         for (; p < q; p++) {
18406           if (*p != '_') {
18407             if (options &
18408                 WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_MULTIPLE_LEADING_ZEROES) {
18409               goto decimal;
18410             }
18411             goto fail_bad_argument;
18412           }
18413         }
18414         goto ok_zero;
18415       }
18416     }
18417 
18418     if ((*p == 'x') || (*p == 'X')) {
18419       p++;
18420       if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
18421         for (; (p < q) && (*p == '_'); p++) {
18422         }
18423       }
18424       if (p < q) {
18425         goto hexadecimal;
18426       }
18427 
18428     } else if ((*p == 'd') || (*p == 'D')) {
18429       p++;
18430       if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
18431         for (; (p < q) && (*p == '_'); p++) {
18432         }
18433       }
18434       if (p < q) {
18435         goto decimal;
18436       }
18437     }
18438 
18439     if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_MULTIPLE_LEADING_ZEROES) {
18440       goto decimal;
18441     }
18442     goto fail_bad_argument;
18443   }
18444 
18445 decimal:
18446   do {
18447     uint64_t v = wuffs_base__parse_number__decimal_digits[*p++];
18448     if (v == 0) {
18449       goto fail_bad_argument;
18450     }
18451     v &= 0x0F;
18452 
18453     // UINT64_MAX is 18446744073709551615, which is ((10 * max10) + max1).
18454     const uint64_t max10 = 1844674407370955161u;
18455     const uint8_t max1 = 5;
18456 
18457     for (; p < q; p++) {
18458       if ((*p == '_') &&
18459           (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) {
18460         continue;
18461       }
18462       uint8_t digit = wuffs_base__parse_number__decimal_digits[*p];
18463       if (digit == 0) {
18464         goto fail_bad_argument;
18465       }
18466       digit &= 0x0F;
18467       if ((v > max10) || ((v == max10) && (digit > max1))) {
18468         goto fail_out_of_bounds;
18469       }
18470       v = (10 * v) + ((uint64_t)(digit));
18471     }
18472 
18473     wuffs_base__result_u64 ret;
18474     ret.status.repr = NULL;
18475     ret.value = v;
18476     return ret;
18477   } while (0);
18478 
18479 hexadecimal:
18480   do {
18481     uint64_t v = wuffs_base__parse_number__hexadecimal_digits[*p++];
18482     if (v == 0) {
18483       goto fail_bad_argument;
18484     }
18485     v &= 0x0F;
18486 
18487     for (; p < q; p++) {
18488       if ((*p == '_') &&
18489           (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) {
18490         continue;
18491       }
18492       uint8_t digit = wuffs_base__parse_number__hexadecimal_digits[*p];
18493       if (digit == 0) {
18494         goto fail_bad_argument;
18495       }
18496       digit &= 0x0F;
18497       if ((v >> 60) != 0) {
18498         goto fail_out_of_bounds;
18499       }
18500       v = (v << 4) | ((uint64_t)(digit));
18501     }
18502 
18503     wuffs_base__result_u64 ret;
18504     ret.status.repr = NULL;
18505     ret.value = v;
18506     return ret;
18507   } while (0);
18508 
18509 ok_zero:
18510   do {
18511     wuffs_base__result_u64 ret;
18512     ret.status.repr = NULL;
18513     ret.value = 0;
18514     return ret;
18515   } while (0);
18516 
18517 fail_bad_argument:
18518   do {
18519     wuffs_base__result_u64 ret;
18520     ret.status.repr = wuffs_base__error__bad_argument;
18521     ret.value = 0;
18522     return ret;
18523   } while (0);
18524 
18525 fail_out_of_bounds:
18526   do {
18527     wuffs_base__result_u64 ret;
18528     ret.status.repr = wuffs_base__error__out_of_bounds;
18529     ret.value = 0;
18530     return ret;
18531   } while (0);
18532 }
18533 
18534 // --------
18535 
18536 // wuffs_base__render_number__first_hundred contains the decimal encodings of
18537 // the first one hundred numbers [0 ..= 99].
18538 static const uint8_t wuffs_base__render_number__first_hundred[200] = {
18539     '0', '0', '0', '1', '0', '2', '0', '3', '0', '4',  //
18540     '0', '5', '0', '6', '0', '7', '0', '8', '0', '9',  //
18541     '1', '0', '1', '1', '1', '2', '1', '3', '1', '4',  //
18542     '1', '5', '1', '6', '1', '7', '1', '8', '1', '9',  //
18543     '2', '0', '2', '1', '2', '2', '2', '3', '2', '4',  //
18544     '2', '5', '2', '6', '2', '7', '2', '8', '2', '9',  //
18545     '3', '0', '3', '1', '3', '2', '3', '3', '3', '4',  //
18546     '3', '5', '3', '6', '3', '7', '3', '8', '3', '9',  //
18547     '4', '0', '4', '1', '4', '2', '4', '3', '4', '4',  //
18548     '4', '5', '4', '6', '4', '7', '4', '8', '4', '9',  //
18549     '5', '0', '5', '1', '5', '2', '5', '3', '5', '4',  //
18550     '5', '5', '5', '6', '5', '7', '5', '8', '5', '9',  //
18551     '6', '0', '6', '1', '6', '2', '6', '3', '6', '4',  //
18552     '6', '5', '6', '6', '6', '7', '6', '8', '6', '9',  //
18553     '7', '0', '7', '1', '7', '2', '7', '3', '7', '4',  //
18554     '7', '5', '7', '6', '7', '7', '7', '8', '7', '9',  //
18555     '8', '0', '8', '1', '8', '2', '8', '3', '8', '4',  //
18556     '8', '5', '8', '6', '8', '7', '8', '8', '8', '9',  //
18557     '9', '0', '9', '1', '9', '2', '9', '3', '9', '4',  //
18558     '9', '5', '9', '6', '9', '7', '9', '8', '9', '9',  //
18559 };
18560 
18561 static size_t  //
wuffs_base__private_implementation__render_number_u64(wuffs_base__slice_u8 dst,uint64_t x,uint32_t options,bool neg)18562 wuffs_base__private_implementation__render_number_u64(wuffs_base__slice_u8 dst,
18563                                                       uint64_t x,
18564                                                       uint32_t options,
18565                                                       bool neg) {
18566   uint8_t buf[WUFFS_BASE__U64__BYTE_LENGTH__MAX_INCL];
18567   uint8_t* ptr = &buf[0] + sizeof(buf);
18568 
18569   while (x >= 100) {
18570     size_t index = ((size_t)((x % 100) * 2));
18571     x /= 100;
18572     uint8_t s0 = wuffs_base__render_number__first_hundred[index + 0];
18573     uint8_t s1 = wuffs_base__render_number__first_hundred[index + 1];
18574     ptr -= 2;
18575     ptr[0] = s0;
18576     ptr[1] = s1;
18577   }
18578 
18579   if (x < 10) {
18580     ptr -= 1;
18581     ptr[0] = (uint8_t)('0' + x);
18582   } else {
18583     size_t index = ((size_t)(x * 2));
18584     uint8_t s0 = wuffs_base__render_number__first_hundred[index + 0];
18585     uint8_t s1 = wuffs_base__render_number__first_hundred[index + 1];
18586     ptr -= 2;
18587     ptr[0] = s0;
18588     ptr[1] = s1;
18589   }
18590 
18591   if (neg) {
18592     ptr -= 1;
18593     ptr[0] = '-';
18594   } else if (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN) {
18595     ptr -= 1;
18596     ptr[0] = '+';
18597   }
18598 
18599   size_t n = sizeof(buf) - ((size_t)(ptr - &buf[0]));
18600   if (n > dst.len) {
18601     return 0;
18602   }
18603   memcpy(dst.ptr + ((options & WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT)
18604                         ? (dst.len - n)
18605                         : 0),
18606          ptr, n);
18607   return n;
18608 }
18609 
18610 WUFFS_BASE__MAYBE_STATIC size_t  //
wuffs_base__render_number_i64(wuffs_base__slice_u8 dst,int64_t x,uint32_t options)18611 wuffs_base__render_number_i64(wuffs_base__slice_u8 dst,
18612                               int64_t x,
18613                               uint32_t options) {
18614   uint64_t u = (uint64_t)x;
18615   bool neg = x < 0;
18616   if (neg) {
18617     u = 1 + ~u;
18618   }
18619   return wuffs_base__private_implementation__render_number_u64(dst, u, options,
18620                                                                neg);
18621 }
18622 
18623 WUFFS_BASE__MAYBE_STATIC size_t  //
wuffs_base__render_number_u64(wuffs_base__slice_u8 dst,uint64_t x,uint32_t options)18624 wuffs_base__render_number_u64(wuffs_base__slice_u8 dst,
18625                               uint64_t x,
18626                               uint32_t options) {
18627   return wuffs_base__private_implementation__render_number_u64(dst, x, options,
18628                                                                false);
18629 }
18630 
18631 // ---------------- Base-16
18632 
18633 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output  //
wuffs_base__base_16__decode2(wuffs_base__slice_u8 dst,wuffs_base__slice_u8 src,bool src_closed,uint32_t options)18634 wuffs_base__base_16__decode2(wuffs_base__slice_u8 dst,
18635                              wuffs_base__slice_u8 src,
18636                              bool src_closed,
18637                              uint32_t options) {
18638   wuffs_base__transform__output o;
18639   size_t src_len2 = src.len / 2;
18640   size_t len;
18641   if (dst.len < src_len2) {
18642     len = dst.len;
18643     o.status.repr = wuffs_base__suspension__short_write;
18644   } else {
18645     len = src_len2;
18646     if (!src_closed) {
18647       o.status.repr = wuffs_base__suspension__short_read;
18648     } else if (src.len & 1) {
18649       o.status.repr = wuffs_base__error__bad_data;
18650     } else {
18651       o.status.repr = NULL;
18652     }
18653   }
18654 
18655   uint8_t* d = dst.ptr;
18656   uint8_t* s = src.ptr;
18657   size_t n = len;
18658 
18659   while (n--) {
18660     *d = (uint8_t)((wuffs_base__parse_number__hexadecimal_digits[s[0]] << 4) |
18661                    (wuffs_base__parse_number__hexadecimal_digits[s[1]] & 0x0F));
18662     d += 1;
18663     s += 2;
18664   }
18665 
18666   o.num_dst = len;
18667   o.num_src = len * 2;
18668   return o;
18669 }
18670 
18671 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output  //
wuffs_base__base_16__decode4(wuffs_base__slice_u8 dst,wuffs_base__slice_u8 src,bool src_closed,uint32_t options)18672 wuffs_base__base_16__decode4(wuffs_base__slice_u8 dst,
18673                              wuffs_base__slice_u8 src,
18674                              bool src_closed,
18675                              uint32_t options) {
18676   wuffs_base__transform__output o;
18677   size_t src_len4 = src.len / 4;
18678   size_t len = dst.len < src_len4 ? dst.len : src_len4;
18679   if (dst.len < src_len4) {
18680     len = dst.len;
18681     o.status.repr = wuffs_base__suspension__short_write;
18682   } else {
18683     len = src_len4;
18684     if (!src_closed) {
18685       o.status.repr = wuffs_base__suspension__short_read;
18686     } else if (src.len & 1) {
18687       o.status.repr = wuffs_base__error__bad_data;
18688     } else {
18689       o.status.repr = NULL;
18690     }
18691   }
18692 
18693   uint8_t* d = dst.ptr;
18694   uint8_t* s = src.ptr;
18695   size_t n = len;
18696 
18697   while (n--) {
18698     *d = (uint8_t)((wuffs_base__parse_number__hexadecimal_digits[s[2]] << 4) |
18699                    (wuffs_base__parse_number__hexadecimal_digits[s[3]] & 0x0F));
18700     d += 1;
18701     s += 4;
18702   }
18703 
18704   o.num_dst = len;
18705   o.num_src = len * 4;
18706   return o;
18707 }
18708 
18709 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output  //
wuffs_base__base_16__encode2(wuffs_base__slice_u8 dst,wuffs_base__slice_u8 src,bool src_closed,uint32_t options)18710 wuffs_base__base_16__encode2(wuffs_base__slice_u8 dst,
18711                              wuffs_base__slice_u8 src,
18712                              bool src_closed,
18713                              uint32_t options) {
18714   wuffs_base__transform__output o;
18715   size_t dst_len2 = dst.len / 2;
18716   size_t len;
18717   if (dst_len2 < src.len) {
18718     len = dst_len2;
18719     o.status.repr = wuffs_base__suspension__short_write;
18720   } else {
18721     len = src.len;
18722     if (!src_closed) {
18723       o.status.repr = wuffs_base__suspension__short_read;
18724     } else {
18725       o.status.repr = NULL;
18726     }
18727   }
18728 
18729   uint8_t* d = dst.ptr;
18730   uint8_t* s = src.ptr;
18731   size_t n = len;
18732 
18733   while (n--) {
18734     uint8_t c = *s;
18735     d[0] = wuffs_base__private_implementation__encode_base16[c >> 4];
18736     d[1] = wuffs_base__private_implementation__encode_base16[c & 0x0F];
18737     d += 2;
18738     s += 1;
18739   }
18740 
18741   o.num_dst = len * 2;
18742   o.num_src = len;
18743   return o;
18744 }
18745 
18746 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output  //
wuffs_base__base_16__encode4(wuffs_base__slice_u8 dst,wuffs_base__slice_u8 src,bool src_closed,uint32_t options)18747 wuffs_base__base_16__encode4(wuffs_base__slice_u8 dst,
18748                              wuffs_base__slice_u8 src,
18749                              bool src_closed,
18750                              uint32_t options) {
18751   wuffs_base__transform__output o;
18752   size_t dst_len4 = dst.len / 4;
18753   size_t len;
18754   if (dst_len4 < src.len) {
18755     len = dst_len4;
18756     o.status.repr = wuffs_base__suspension__short_write;
18757   } else {
18758     len = src.len;
18759     if (!src_closed) {
18760       o.status.repr = wuffs_base__suspension__short_read;
18761     } else {
18762       o.status.repr = NULL;
18763     }
18764   }
18765 
18766   uint8_t* d = dst.ptr;
18767   uint8_t* s = src.ptr;
18768   size_t n = len;
18769 
18770   while (n--) {
18771     uint8_t c = *s;
18772     d[0] = '\\';
18773     d[1] = 'x';
18774     d[2] = wuffs_base__private_implementation__encode_base16[c >> 4];
18775     d[3] = wuffs_base__private_implementation__encode_base16[c & 0x0F];
18776     d += 4;
18777     s += 1;
18778   }
18779 
18780   o.num_dst = len * 4;
18781   o.num_src = len;
18782   return o;
18783 }
18784 
18785 // ---------------- Base-64
18786 
18787 // The two base-64 alphabets, std and url, differ only in the last two codes.
18788 //  - std: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
18789 //  - url: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
18790 
18791 static const uint8_t wuffs_base__base_64__decode_std[256] = {
18792     // 0     1     2     3     4     5     6     7
18793     // 8     9     A     B     C     D     E     F
18794     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x00 ..= 0x07.
18795     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x08 ..= 0x0F.
18796     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x10 ..= 0x17.
18797     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x18 ..= 0x1F.
18798     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x20 ..= 0x27.
18799     0x80, 0x80, 0x80, 0x3E, 0x80, 0x80, 0x80, 0x3F,  // 0x28 ..= 0x2F.
18800     0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,  // 0x30 ..= 0x37.
18801     0x3C, 0x3D, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x38 ..= 0x3F.
18802 
18803     0x80, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,  // 0x40 ..= 0x47.
18804     0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,  // 0x48 ..= 0x4F.
18805     0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,  // 0x50 ..= 0x57.
18806     0x17, 0x18, 0x19, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x58 ..= 0x5F.
18807     0x80, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,  // 0x60 ..= 0x67.
18808     0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,  // 0x68 ..= 0x6F.
18809     0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,  // 0x70 ..= 0x77.
18810     0x31, 0x32, 0x33, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x78 ..= 0x7F.
18811 
18812     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x80 ..= 0x87.
18813     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x88 ..= 0x8F.
18814     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x90 ..= 0x97.
18815     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x98 ..= 0x9F.
18816     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xA0 ..= 0xA7.
18817     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xA8 ..= 0xAF.
18818     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xB0 ..= 0xB7.
18819     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xB8 ..= 0xBF.
18820 
18821     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xC0 ..= 0xC7.
18822     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xC8 ..= 0xCF.
18823     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xD0 ..= 0xD7.
18824     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xD8 ..= 0xDF.
18825     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xE0 ..= 0xE7.
18826     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xE8 ..= 0xEF.
18827     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xF0 ..= 0xF7.
18828     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xF8 ..= 0xFF.
18829     // 0     1     2     3     4     5     6     7
18830     // 8     9     A     B     C     D     E     F
18831 };
18832 
18833 static const uint8_t wuffs_base__base_64__decode_url[256] = {
18834     // 0     1     2     3     4     5     6     7
18835     // 8     9     A     B     C     D     E     F
18836     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x00 ..= 0x07.
18837     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x08 ..= 0x0F.
18838     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x10 ..= 0x17.
18839     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x18 ..= 0x1F.
18840     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x20 ..= 0x27.
18841     0x80, 0x80, 0x80, 0x80, 0x80, 0x3E, 0x80, 0x80,  // 0x28 ..= 0x2F.
18842     0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,  // 0x30 ..= 0x37.
18843     0x3C, 0x3D, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x38 ..= 0x3F.
18844 
18845     0x80, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,  // 0x40 ..= 0x47.
18846     0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,  // 0x48 ..= 0x4F.
18847     0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,  // 0x50 ..= 0x57.
18848     0x17, 0x18, 0x19, 0x80, 0x80, 0x80, 0x80, 0x3F,  // 0x58 ..= 0x5F.
18849     0x80, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,  // 0x60 ..= 0x67.
18850     0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,  // 0x68 ..= 0x6F.
18851     0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,  // 0x70 ..= 0x77.
18852     0x31, 0x32, 0x33, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x78 ..= 0x7F.
18853 
18854     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x80 ..= 0x87.
18855     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x88 ..= 0x8F.
18856     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x90 ..= 0x97.
18857     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x98 ..= 0x9F.
18858     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xA0 ..= 0xA7.
18859     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xA8 ..= 0xAF.
18860     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xB0 ..= 0xB7.
18861     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xB8 ..= 0xBF.
18862 
18863     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xC0 ..= 0xC7.
18864     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xC8 ..= 0xCF.
18865     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xD0 ..= 0xD7.
18866     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xD8 ..= 0xDF.
18867     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xE0 ..= 0xE7.
18868     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xE8 ..= 0xEF.
18869     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xF0 ..= 0xF7.
18870     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xF8 ..= 0xFF.
18871     // 0     1     2     3     4     5     6     7
18872     // 8     9     A     B     C     D     E     F
18873 };
18874 
18875 static const uint8_t wuffs_base__base_64__encode_std[64] = {
18876     // 0     1     2     3     4     5     6     7
18877     // 8     9     A     B     C     D     E     F
18878     0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,  // 0x00 ..= 0x07.
18879     0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,  // 0x08 ..= 0x0F.
18880     0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,  // 0x10 ..= 0x17.
18881     0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,  // 0x18 ..= 0x1F.
18882     0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E,  // 0x20 ..= 0x27.
18883     0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,  // 0x28 ..= 0x2F.
18884     0x77, 0x78, 0x79, 0x7A, 0x30, 0x31, 0x32, 0x33,  // 0x30 ..= 0x37.
18885     0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2B, 0x2F,  // 0x38 ..= 0x3F.
18886 };
18887 
18888 static const uint8_t wuffs_base__base_64__encode_url[64] = {
18889     // 0     1     2     3     4     5     6     7
18890     // 8     9     A     B     C     D     E     F
18891     0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,  // 0x00 ..= 0x07.
18892     0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,  // 0x08 ..= 0x0F.
18893     0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,  // 0x10 ..= 0x17.
18894     0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,  // 0x18 ..= 0x1F.
18895     0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E,  // 0x20 ..= 0x27.
18896     0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,  // 0x28 ..= 0x2F.
18897     0x77, 0x78, 0x79, 0x7A, 0x30, 0x31, 0x32, 0x33,  // 0x30 ..= 0x37.
18898     0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2D, 0x5F,  // 0x38 ..= 0x3F.
18899 };
18900 
18901 // --------
18902 
18903 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output  //
wuffs_base__base_64__decode(wuffs_base__slice_u8 dst,wuffs_base__slice_u8 src,bool src_closed,uint32_t options)18904 wuffs_base__base_64__decode(wuffs_base__slice_u8 dst,
18905                             wuffs_base__slice_u8 src,
18906                             bool src_closed,
18907                             uint32_t options) {
18908   const uint8_t* alphabet = (options & WUFFS_BASE__BASE_64__URL_ALPHABET)
18909                                 ? wuffs_base__base_64__decode_url
18910                                 : wuffs_base__base_64__decode_std;
18911   wuffs_base__transform__output o;
18912   uint8_t* d_ptr = dst.ptr;
18913   size_t d_len = dst.len;
18914   const uint8_t* s_ptr = src.ptr;
18915   size_t s_len = src.len;
18916   bool pad = false;
18917 
18918   while (s_len >= 4) {
18919     uint32_t s = wuffs_base__peek_u32le__no_bounds_check(s_ptr);
18920     uint32_t s0 = alphabet[0xFF & (s >> 0)];
18921     uint32_t s1 = alphabet[0xFF & (s >> 8)];
18922     uint32_t s2 = alphabet[0xFF & (s >> 16)];
18923     uint32_t s3 = alphabet[0xFF & (s >> 24)];
18924 
18925     if (((s0 | s1 | s2 | s3) & 0xC0) != 0) {
18926       if (s_len > 4) {
18927         o.status.repr = wuffs_base__error__bad_data;
18928         goto done;
18929       } else if (!src_closed) {
18930         o.status.repr = wuffs_base__suspension__short_read;
18931         goto done;
18932       } else if ((options & WUFFS_BASE__BASE_64__DECODE_ALLOW_PADDING) &&
18933                  (s_ptr[3] == '=')) {
18934         pad = true;
18935         if (s_ptr[2] == '=') {
18936           goto src2;
18937         }
18938         goto src3;
18939       }
18940       o.status.repr = wuffs_base__error__bad_data;
18941       goto done;
18942     }
18943 
18944     if (d_len < 3) {
18945       o.status.repr = wuffs_base__suspension__short_write;
18946       goto done;
18947     }
18948 
18949     s_ptr += 4;
18950     s_len -= 4;
18951     s = (s0 << 18) | (s1 << 12) | (s2 << 6) | (s3 << 0);
18952     *d_ptr++ = (uint8_t)(s >> 16);
18953     *d_ptr++ = (uint8_t)(s >> 8);
18954     *d_ptr++ = (uint8_t)(s >> 0);
18955     d_len -= 3;
18956   }
18957 
18958   if (!src_closed) {
18959     o.status.repr = wuffs_base__suspension__short_read;
18960     goto done;
18961   }
18962 
18963   if (s_len == 0) {
18964     o.status.repr = NULL;
18965     goto done;
18966   } else if (s_len == 1) {
18967     o.status.repr = wuffs_base__error__bad_data;
18968     goto done;
18969   } else if (s_len == 2) {
18970     goto src2;
18971   }
18972 
18973 src3:
18974   do {
18975     uint32_t s = wuffs_base__peek_u24le__no_bounds_check(s_ptr);
18976     uint32_t s0 = alphabet[0xFF & (s >> 0)];
18977     uint32_t s1 = alphabet[0xFF & (s >> 8)];
18978     uint32_t s2 = alphabet[0xFF & (s >> 16)];
18979     if ((s0 & 0xC0) || (s1 & 0xC0) || (s2 & 0xC3)) {
18980       o.status.repr = wuffs_base__error__bad_data;
18981       goto done;
18982     }
18983     if (d_len < 2) {
18984       o.status.repr = wuffs_base__suspension__short_write;
18985       goto done;
18986     }
18987     s_ptr += pad ? 4 : 3;
18988     s = (s0 << 18) | (s1 << 12) | (s2 << 6);
18989     *d_ptr++ = (uint8_t)(s >> 16);
18990     *d_ptr++ = (uint8_t)(s >> 8);
18991     o.status.repr = NULL;
18992     goto done;
18993   } while (0);
18994 
18995 src2:
18996   do {
18997     uint32_t s = wuffs_base__peek_u16le__no_bounds_check(s_ptr);
18998     uint32_t s0 = alphabet[0xFF & (s >> 0)];
18999     uint32_t s1 = alphabet[0xFF & (s >> 8)];
19000     if ((s0 & 0xC0) || (s1 & 0xCF)) {
19001       o.status.repr = wuffs_base__error__bad_data;
19002       goto done;
19003     }
19004     if (d_len < 1) {
19005       o.status.repr = wuffs_base__suspension__short_write;
19006       goto done;
19007     }
19008     s_ptr += pad ? 4 : 2;
19009     s = (s0 << 18) | (s1 << 12);
19010     *d_ptr++ = (uint8_t)(s >> 16);
19011     o.status.repr = NULL;
19012     goto done;
19013   } while (0);
19014 
19015 done:
19016   o.num_dst = (size_t)(d_ptr - dst.ptr);
19017   o.num_src = (size_t)(s_ptr - src.ptr);
19018   return o;
19019 }
19020 
19021 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output  //
wuffs_base__base_64__encode(wuffs_base__slice_u8 dst,wuffs_base__slice_u8 src,bool src_closed,uint32_t options)19022 wuffs_base__base_64__encode(wuffs_base__slice_u8 dst,
19023                             wuffs_base__slice_u8 src,
19024                             bool src_closed,
19025                             uint32_t options) {
19026   const uint8_t* alphabet = (options & WUFFS_BASE__BASE_64__URL_ALPHABET)
19027                                 ? wuffs_base__base_64__encode_url
19028                                 : wuffs_base__base_64__encode_std;
19029   wuffs_base__transform__output o;
19030   uint8_t* d_ptr = dst.ptr;
19031   size_t d_len = dst.len;
19032   const uint8_t* s_ptr = src.ptr;
19033   size_t s_len = src.len;
19034 
19035   do {
19036     while (s_len >= 3) {
19037       if (d_len < 4) {
19038         o.status.repr = wuffs_base__suspension__short_write;
19039         goto done;
19040       }
19041       uint32_t s = wuffs_base__peek_u24be__no_bounds_check(s_ptr);
19042       s_ptr += 3;
19043       s_len -= 3;
19044       *d_ptr++ = alphabet[0x3F & (s >> 18)];
19045       *d_ptr++ = alphabet[0x3F & (s >> 12)];
19046       *d_ptr++ = alphabet[0x3F & (s >> 6)];
19047       *d_ptr++ = alphabet[0x3F & (s >> 0)];
19048       d_len -= 4;
19049     }
19050 
19051     if (!src_closed) {
19052       o.status.repr = wuffs_base__suspension__short_read;
19053       goto done;
19054     }
19055 
19056     if (s_len == 2) {
19057       if (d_len <
19058           ((options & WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING) ? 4 : 3)) {
19059         o.status.repr = wuffs_base__suspension__short_write;
19060         goto done;
19061       }
19062       uint32_t s = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(s_ptr)))
19063                    << 8;
19064       s_ptr += 2;
19065       *d_ptr++ = alphabet[0x3F & (s >> 18)];
19066       *d_ptr++ = alphabet[0x3F & (s >> 12)];
19067       *d_ptr++ = alphabet[0x3F & (s >> 6)];
19068       if (options & WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING) {
19069         *d_ptr++ = '=';
19070       }
19071       o.status.repr = NULL;
19072       goto done;
19073 
19074     } else if (s_len == 1) {
19075       if (d_len <
19076           ((options & WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING) ? 4 : 2)) {
19077         o.status.repr = wuffs_base__suspension__short_write;
19078         goto done;
19079       }
19080       uint32_t s = ((uint32_t)(wuffs_base__peek_u8__no_bounds_check(s_ptr)))
19081                    << 16;
19082       s_ptr += 1;
19083       *d_ptr++ = alphabet[0x3F & (s >> 18)];
19084       *d_ptr++ = alphabet[0x3F & (s >> 12)];
19085       if (options & WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING) {
19086         *d_ptr++ = '=';
19087         *d_ptr++ = '=';
19088       }
19089       o.status.repr = NULL;
19090       goto done;
19091 
19092     } else {
19093       o.status.repr = NULL;
19094       goto done;
19095     }
19096   } while (0);
19097 
19098 done:
19099   o.num_dst = (size_t)(d_ptr - dst.ptr);
19100   o.num_src = (size_t)(s_ptr - src.ptr);
19101   return o;
19102 }
19103 
19104 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
19105         // defined(WUFFS_CONFIG__MODULE__BASE) ||
19106         // defined(WUFFS_CONFIG__MODULE__BASE__INTCONV)
19107 
19108 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
19109     defined(WUFFS_CONFIG__MODULE__BASE__MAGIC)
19110 
19111 // ---------------- Magic Numbers
19112 
19113 // ICO doesn't start with a magic identifier. Instead, see if the opening bytes
19114 // are plausibly ICO.
19115 //
19116 // Callers should have already verified that (prefix_data.len >= 2) and the
19117 // first two bytes are 0x00.
19118 //
19119 // See:
19120 //  - https://docs.fileformat.com/image/ico/
19121 static int32_t  //
wuffs_base__magic_number_guess_fourcc__maybe_ico(wuffs_base__slice_u8 prefix_data,bool prefix_closed)19122 wuffs_base__magic_number_guess_fourcc__maybe_ico(
19123     wuffs_base__slice_u8 prefix_data,
19124     bool prefix_closed) {
19125   // Allow-list for the Image Type field.
19126   if (prefix_data.len < 4) {
19127     return prefix_closed ? 0 : -1;
19128   } else if (prefix_data.ptr[3] != 0) {
19129     return 0;
19130   }
19131   switch (prefix_data.ptr[2]) {
19132     case 0x01:  // ICO
19133     case 0x02:  // CUR
19134       break;
19135     default:
19136       return 0;
19137   }
19138 
19139   // The Number Of Images should be positive.
19140   if (prefix_data.len < 6) {
19141     return prefix_closed ? 0 : -1;
19142   } else if ((prefix_data.ptr[4] == 0) && (prefix_data.ptr[5] == 0)) {
19143     return 0;
19144   }
19145 
19146   // The first ICONDIRENTRY's fourth byte should be zero.
19147   if (prefix_data.len < 10) {
19148     return prefix_closed ? 0 : -1;
19149   } else if (prefix_data.ptr[9] != 0) {
19150     return 0;
19151   }
19152 
19153   // TODO: have a separate FourCC for CUR?
19154   return 0x49434F20;  // 'ICO 'be
19155 }
19156 
19157 // TGA doesn't start with a magic identifier. Instead, see if the opening bytes
19158 // are plausibly TGA.
19159 //
19160 // Callers should have already verified that (prefix_data.len >= 2) and the
19161 // second byte (prefix_data.ptr[1], the Color Map Type byte), is either 0x00 or
19162 // 0x01.
19163 //
19164 // See:
19165 //  - https://docs.fileformat.com/image/tga/
19166 //  - https://www.dca.fee.unicamp.br/~martino/disciplinas/ea978/tgaffs.pdf
19167 static int32_t  //
wuffs_base__magic_number_guess_fourcc__maybe_tga(wuffs_base__slice_u8 prefix_data,bool prefix_closed)19168 wuffs_base__magic_number_guess_fourcc__maybe_tga(
19169     wuffs_base__slice_u8 prefix_data,
19170     bool prefix_closed) {
19171   // Allow-list for the Image Type field.
19172   if (prefix_data.len < 3) {
19173     return prefix_closed ? 0 : -1;
19174   }
19175   switch (prefix_data.ptr[2]) {
19176     case 0x01:
19177     case 0x02:
19178     case 0x03:
19179     case 0x09:
19180     case 0x0A:
19181     case 0x0B:
19182       break;
19183     default:
19184       // TODO: 0x20 and 0x21 are invalid, according to the spec, but are
19185       // apparently unofficial extensions.
19186       return 0;
19187   }
19188 
19189   // Allow-list for the Color Map Entry Size field (if the Color Map Type field
19190   // is non-zero) or else all the Color Map fields should be zero.
19191   if (prefix_data.len < 8) {
19192     return prefix_closed ? 0 : -1;
19193   } else if (prefix_data.ptr[1] != 0x00) {
19194     switch (prefix_data.ptr[7]) {
19195       case 0x0F:
19196       case 0x10:
19197       case 0x18:
19198       case 0x20:
19199         break;
19200       default:
19201         return 0;
19202     }
19203   } else if ((prefix_data.ptr[3] | prefix_data.ptr[4] | prefix_data.ptr[5] |
19204               prefix_data.ptr[6] | prefix_data.ptr[7]) != 0x00) {
19205     return 0;
19206   }
19207 
19208   // Allow-list for the Pixel Depth field.
19209   if (prefix_data.len < 17) {
19210     return prefix_closed ? 0 : -1;
19211   }
19212   switch (prefix_data.ptr[16]) {
19213     case 0x01:
19214     case 0x08:
19215     case 0x0F:
19216     case 0x10:
19217     case 0x18:
19218     case 0x20:
19219       break;
19220     default:
19221       return 0;
19222   }
19223 
19224   return 0x54474120;  // 'TGA 'be
19225 }
19226 
19227 WUFFS_BASE__MAYBE_STATIC int32_t  //
wuffs_base__magic_number_guess_fourcc(wuffs_base__slice_u8 prefix_data,bool prefix_closed)19228 wuffs_base__magic_number_guess_fourcc(wuffs_base__slice_u8 prefix_data,
19229                                       bool prefix_closed) {
19230   // This is similar to (but different from):
19231   //  - the magic/Magdir tables under https://github.com/file/file
19232   //  - the MIME Sniffing algorithm at https://mimesniff.spec.whatwg.org/
19233 
19234   // table holds the 'magic numbers' (which are actually variable length
19235   // strings). The strings may contain NUL bytes, so the "const char* magic"
19236   // value starts with the length-minus-1 of the 'magic number'.
19237   //
19238   // Keep it sorted by magic[1], then magic[0] descending (prioritizing longer
19239   // matches) and finally by magic[2:]. When multiple entries match, the
19240   // longest one wins.
19241   //
19242   // The fourcc field might be negated, in which case there's further
19243   // specialization (see § below).
19244   static struct {
19245     int32_t fourcc;
19246     const char* magic;
19247   } table[] = {
19248       {-0x30302020, "\x01\x00\x00"},              // '00  'be
19249       {+0x475A2020, "\x02\x1F\x8B\x08"},          // GZ
19250       {+0x5A535444, "\x03\x28\xB5\x2F\xFD"},      // ZSTD
19251       {+0x425A3220, "\x02\x42\x5A\x68"},          // BZ2
19252       {+0x424D5020, "\x01\x42\x4D"},              // BMP
19253       {+0x47494620, "\x03\x47\x49\x46\x38"},      // GIF
19254       {+0x54494646, "\x03\x49\x49\x2A\x00"},      // TIFF (little-endian)
19255       {+0x54494646, "\x03\x4D\x4D\x00\x2A"},      // TIFF (big-endian)
19256       {+0x4E50424D, "\x02\x50\x35\x0A"},          // NPBM (P5; *.pgm)
19257       {+0x4E50424D, "\x02\x50\x36\x0A"},          // NPBM (P6; *.ppm)
19258       {-0x52494646, "\x03\x52\x49\x46\x46"},      // RIFF
19259       {+0x4C5A4D41, "\x04\x5D\x00\x10\x00\x00"},  // LZMA
19260       {+0x4C5A4D41, "\x02\x5D\x00\x00"},          // LZMA
19261       {+0x4E494520, "\x02\x6E\xC3\xAF"},          // NIE
19262       {+0x514F4920, "\x03\x71\x6F\x69\x66"},      // QOI
19263       {+0x5A4C4942, "\x01\x78\x9C"},              // ZLIB
19264       {+0x504E4720, "\x03\x89\x50\x4E\x47"},      // PNG
19265       {+0x585A2020, "\x04\xFD\x37\x7A\x58\x5A"},  // XZ
19266       {+0x4A504547, "\x01\xFF\xD8"},              // JPEG
19267   };
19268   static const size_t table_len = sizeof(table) / sizeof(table[0]);
19269 
19270   if (prefix_data.len == 0) {
19271     return prefix_closed ? 0 : -1;
19272   }
19273   uint8_t pre_first_byte = prefix_data.ptr[0];
19274 
19275   int32_t fourcc = 0;
19276   size_t i;
19277   for (i = 0; i < table_len; i++) {
19278     uint8_t mag_first_byte = ((uint8_t)(table[i].magic[1]));
19279     if (pre_first_byte < mag_first_byte) {
19280       break;
19281     } else if (pre_first_byte > mag_first_byte) {
19282       continue;
19283     }
19284     fourcc = table[i].fourcc;
19285 
19286     uint8_t mag_remaining_len = ((uint8_t)(table[i].magic[0]));
19287     if (mag_remaining_len == 0) {
19288       goto match;
19289     }
19290 
19291     const char* mag_remaining_ptr = table[i].magic + 2;
19292     uint8_t* pre_remaining_ptr = prefix_data.ptr + 1;
19293     size_t pre_remaining_len = prefix_data.len - 1;
19294     if (pre_remaining_len < mag_remaining_len) {
19295       if (!memcmp(pre_remaining_ptr, mag_remaining_ptr, pre_remaining_len)) {
19296         return prefix_closed ? 0 : -1;
19297       }
19298     } else {
19299       if (!memcmp(pre_remaining_ptr, mag_remaining_ptr, mag_remaining_len)) {
19300         goto match;
19301       }
19302     }
19303   }
19304 
19305   if (prefix_data.len < 2) {
19306     return prefix_closed ? 0 : -1;
19307   } else if ((prefix_data.ptr[1] == 0x00) || (prefix_data.ptr[1] == 0x01)) {
19308     return wuffs_base__magic_number_guess_fourcc__maybe_tga(prefix_data,
19309                                                             prefix_closed);
19310   }
19311 
19312   return 0;
19313 
19314 match:
19315   // Negative FourCC values (see § above) are further specialized.
19316   if (fourcc < 0) {
19317     fourcc = -fourcc;
19318 
19319     if (fourcc == 0x52494646) {  // 'RIFF'be
19320       if (prefix_data.len < 12) {
19321         return prefix_closed ? 0 : -1;
19322       }
19323       uint32_t x = wuffs_base__peek_u32be__no_bounds_check(prefix_data.ptr + 8);
19324       if (x == 0x57454250) {  // 'WEBP'be
19325         return 0x57454250;    // 'WEBP'be
19326       }
19327 
19328     } else if (fourcc == 0x30302020) {  // '00  'be
19329       // Binary data starting with multiple 0x00 NUL bytes is quite common.
19330       // Unfortunately, some file formats also don't start with a magic
19331       // identifier, so we have to use heuristics (where the order matters, the
19332       // same as /usr/bin/file's magic/Magdir tables) as best we can. Maybe
19333       // it's TGA, ICO/CUR, etc. Maybe it's something else.
19334       int32_t tga = wuffs_base__magic_number_guess_fourcc__maybe_tga(
19335           prefix_data, prefix_closed);
19336       if (tga != 0) {
19337         return tga;
19338       }
19339       int32_t ico = wuffs_base__magic_number_guess_fourcc__maybe_ico(
19340           prefix_data, prefix_closed);
19341       if (ico != 0) {
19342         return ico;
19343       }
19344       if (prefix_data.len < 4) {
19345         return prefix_closed ? 0 : -1;
19346       } else if ((prefix_data.ptr[2] != 0x00) &&
19347                  ((prefix_data.ptr[2] >= 0x80) ||
19348                   (prefix_data.ptr[3] != 0x00))) {
19349         // Roughly speaking, this could be a non-degenerate (non-0-width and
19350         // non-0-height) WBMP image.
19351         return 0x57424D50;  // 'WBMP'be
19352       }
19353       return 0;
19354     }
19355   }
19356   return fourcc;
19357 }
19358 
19359 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
19360         // defined(WUFFS_CONFIG__MODULE__BASE) ||
19361         // defined(WUFFS_CONFIG__MODULE__BASE__MAGIC)
19362 
19363 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
19364     defined(WUFFS_CONFIG__MODULE__BASE__PIXCONV)
19365 
19366 // ---------------- Pixel Swizzler
19367 
19368 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
19369 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
19370 static uint64_t  //
19371 wuffs_base__pixel_swizzler__bgrw__rgb__x86_sse42(uint8_t* dst_ptr,
19372                                                  size_t dst_len,
19373                                                  uint8_t* dst_palette_ptr,
19374                                                  size_t dst_palette_len,
19375                                                  const uint8_t* src_ptr,
19376                                                  size_t src_len);
19377 
19378 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
19379 static uint64_t  //
19380 wuffs_base__pixel_swizzler__swap_rgbx_bgrx__x86_sse42(uint8_t* dst_ptr,
19381                                                       size_t dst_len,
19382                                                       uint8_t* dst_palette_ptr,
19383                                                       size_t dst_palette_len,
19384                                                       const uint8_t* src_ptr,
19385                                                       size_t src_len);
19386 
19387 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
19388 static uint64_t  //
19389 wuffs_base__pixel_swizzler__xxxx__y__x86_sse42(uint8_t* dst_ptr,
19390                                                size_t dst_len,
19391                                                uint8_t* dst_palette_ptr,
19392                                                size_t dst_palette_len,
19393                                                const uint8_t* src_ptr,
19394                                                size_t src_len);
19395 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
19396 
19397 // --------
19398 
19399 static inline uint32_t  //
wuffs_base__swap_u32_argb_abgr(uint32_t u)19400 wuffs_base__swap_u32_argb_abgr(uint32_t u) {
19401   uint32_t o = u & 0xFF00FF00ul;
19402   uint32_t r = u & 0x00FF0000ul;
19403   uint32_t b = u & 0x000000FFul;
19404   return o | (r >> 16) | (b << 16);
19405 }
19406 
19407 static inline uint64_t  //
wuffs_base__swap_u64_argb_abgr(uint64_t u)19408 wuffs_base__swap_u64_argb_abgr(uint64_t u) {
19409   uint64_t o = u & 0xFFFF0000FFFF0000ull;
19410   uint64_t r = u & 0x0000FFFF00000000ull;
19411   uint64_t b = u & 0x000000000000FFFFull;
19412   return o | (r >> 32) | (b << 32);
19413 }
19414 
19415 static inline uint32_t  //
wuffs_base__color_u64__as__color_u32__swap_u32_argb_abgr(uint64_t c)19416 wuffs_base__color_u64__as__color_u32__swap_u32_argb_abgr(uint64_t c) {
19417   uint32_t a = ((uint32_t)(0xFF & (c >> 56)));
19418   uint32_t r = ((uint32_t)(0xFF & (c >> 40)));
19419   uint32_t g = ((uint32_t)(0xFF & (c >> 24)));
19420   uint32_t b = ((uint32_t)(0xFF & (c >> 8)));
19421   return (a << 24) | (b << 16) | (g << 8) | (r << 0);
19422 }
19423 
19424 // --------
19425 
19426 WUFFS_BASE__MAYBE_STATIC wuffs_base__color_u32_argb_premul  //
wuffs_base__pixel_buffer__color_u32_at(const wuffs_base__pixel_buffer * pb,uint32_t x,uint32_t y)19427 wuffs_base__pixel_buffer__color_u32_at(const wuffs_base__pixel_buffer* pb,
19428                                        uint32_t x,
19429                                        uint32_t y) {
19430   if (!pb || (x >= pb->pixcfg.private_impl.width) ||
19431       (y >= pb->pixcfg.private_impl.height)) {
19432     return 0;
19433   }
19434 
19435   if (wuffs_base__pixel_format__is_planar(&pb->pixcfg.private_impl.pixfmt)) {
19436     // TODO: support planar formats.
19437     return 0;
19438   }
19439 
19440   size_t stride = pb->private_impl.planes[0].stride;
19441   const uint8_t* row = pb->private_impl.planes[0].ptr + (stride * ((size_t)y));
19442 
19443   switch (pb->pixcfg.private_impl.pixfmt.repr) {
19444     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
19445     case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
19446       return wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x)));
19447 
19448     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL:
19449     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY: {
19450       uint8_t* palette = pb->private_impl.planes[3].ptr;
19451       return wuffs_base__peek_u32le__no_bounds_check(palette +
19452                                                      (4 * ((size_t)row[x])));
19453     }
19454 
19455       // Common formats above. Rarer formats below.
19456 
19457     case WUFFS_BASE__PIXEL_FORMAT__Y:
19458       return 0xFF000000 | (0x00010101 * ((uint32_t)(row[x])));
19459     case WUFFS_BASE__PIXEL_FORMAT__Y_16LE:
19460       return 0xFF000000 | (0x00010101 * ((uint32_t)(row[(2 * x) + 1])));
19461     case WUFFS_BASE__PIXEL_FORMAT__Y_16BE:
19462       return 0xFF000000 | (0x00010101 * ((uint32_t)(row[(2 * x) + 0])));
19463 
19464     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL: {
19465       uint8_t* palette = pb->private_impl.planes[3].ptr;
19466       return wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
19467           wuffs_base__peek_u32le__no_bounds_check(palette +
19468                                                   (4 * ((size_t)row[x]))));
19469     }
19470 
19471     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
19472       return wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
19473           wuffs_base__peek_u16le__no_bounds_check(row + (2 * ((size_t)x))));
19474     case WUFFS_BASE__PIXEL_FORMAT__BGR:
19475       return 0xFF000000 |
19476              wuffs_base__peek_u24le__no_bounds_check(row + (3 * ((size_t)x)));
19477     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
19478       return wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
19479           wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x))));
19480     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
19481       return wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(
19482           wuffs_base__peek_u64le__no_bounds_check(row + (8 * ((size_t)x))));
19483     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
19484       return 0xFF000000 |
19485              wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x)));
19486 
19487     case WUFFS_BASE__PIXEL_FORMAT__RGB:
19488       return wuffs_base__swap_u32_argb_abgr(
19489           0xFF000000 |
19490           wuffs_base__peek_u24le__no_bounds_check(row + (3 * ((size_t)x))));
19491     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
19492       return wuffs_base__swap_u32_argb_abgr(
19493           wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
19494               wuffs_base__peek_u32le__no_bounds_check(row +
19495                                                       (4 * ((size_t)x)))));
19496     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
19497     case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
19498       return wuffs_base__swap_u32_argb_abgr(
19499           wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x))));
19500     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
19501       return wuffs_base__swap_u32_argb_abgr(
19502           0xFF000000 |
19503           wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x))));
19504 
19505     default:
19506       // TODO: support more formats.
19507       break;
19508   }
19509 
19510   return 0;
19511 }
19512 
19513 // --------
19514 
19515 WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
wuffs_base__pixel_buffer__set_color_u32_at(wuffs_base__pixel_buffer * pb,uint32_t x,uint32_t y,wuffs_base__color_u32_argb_premul color)19516 wuffs_base__pixel_buffer__set_color_u32_at(
19517     wuffs_base__pixel_buffer* pb,
19518     uint32_t x,
19519     uint32_t y,
19520     wuffs_base__color_u32_argb_premul color) {
19521   if (!pb) {
19522     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
19523   }
19524   if ((x >= pb->pixcfg.private_impl.width) ||
19525       (y >= pb->pixcfg.private_impl.height)) {
19526     return wuffs_base__make_status(wuffs_base__error__bad_argument);
19527   }
19528 
19529   if (wuffs_base__pixel_format__is_planar(&pb->pixcfg.private_impl.pixfmt)) {
19530     // TODO: support planar formats.
19531     return wuffs_base__make_status(wuffs_base__error__unsupported_option);
19532   }
19533 
19534   size_t stride = pb->private_impl.planes[0].stride;
19535   uint8_t* row = pb->private_impl.planes[0].ptr + (stride * ((size_t)y));
19536 
19537   switch (pb->pixcfg.private_impl.pixfmt.repr) {
19538     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
19539     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
19540       wuffs_base__poke_u32le__no_bounds_check(row + (4 * ((size_t)x)), color);
19541       break;
19542 
19543       // Common formats above. Rarer formats below.
19544 
19545     case WUFFS_BASE__PIXEL_FORMAT__Y:
19546       wuffs_base__poke_u8__no_bounds_check(
19547           row + ((size_t)x),
19548           wuffs_base__color_u32_argb_premul__as__color_u8_gray(color));
19549       break;
19550     case WUFFS_BASE__PIXEL_FORMAT__Y_16LE:
19551       wuffs_base__poke_u16le__no_bounds_check(
19552           row + (2 * ((size_t)x)),
19553           wuffs_base__color_u32_argb_premul__as__color_u16_gray(color));
19554       break;
19555     case WUFFS_BASE__PIXEL_FORMAT__Y_16BE:
19556       wuffs_base__poke_u16be__no_bounds_check(
19557           row + (2 * ((size_t)x)),
19558           wuffs_base__color_u32_argb_premul__as__color_u16_gray(color));
19559       break;
19560 
19561     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:
19562     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL:
19563     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY:
19564       wuffs_base__poke_u8__no_bounds_check(
19565           row + ((size_t)x), wuffs_base__pixel_palette__closest_element(
19566                                  wuffs_base__pixel_buffer__palette(pb),
19567                                  pb->pixcfg.private_impl.pixfmt, color));
19568       break;
19569 
19570     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
19571       wuffs_base__poke_u16le__no_bounds_check(
19572           row + (2 * ((size_t)x)),
19573           wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(color));
19574       break;
19575     case WUFFS_BASE__PIXEL_FORMAT__BGR:
19576       wuffs_base__poke_u24le__no_bounds_check(row + (3 * ((size_t)x)), color);
19577       break;
19578     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
19579       wuffs_base__poke_u32le__no_bounds_check(
19580           row + (4 * ((size_t)x)),
19581           wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
19582               color));
19583       break;
19584     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
19585       wuffs_base__poke_u64le__no_bounds_check(
19586           row + (8 * ((size_t)x)),
19587           wuffs_base__color_u32_argb_premul__as__color_u64_argb_nonpremul(
19588               color));
19589       break;
19590 
19591     case WUFFS_BASE__PIXEL_FORMAT__RGB:
19592       wuffs_base__poke_u24le__no_bounds_check(
19593           row + (3 * ((size_t)x)), wuffs_base__swap_u32_argb_abgr(color));
19594       break;
19595     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
19596       wuffs_base__poke_u32le__no_bounds_check(
19597           row + (4 * ((size_t)x)),
19598           wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
19599               wuffs_base__swap_u32_argb_abgr(color)));
19600       break;
19601     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
19602     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
19603       wuffs_base__poke_u32le__no_bounds_check(
19604           row + (4 * ((size_t)x)), wuffs_base__swap_u32_argb_abgr(color));
19605       break;
19606 
19607     default:
19608       // TODO: support more formats.
19609       return wuffs_base__make_status(wuffs_base__error__unsupported_option);
19610   }
19611 
19612   return wuffs_base__make_status(NULL);
19613 }
19614 
19615 // --------
19616 
19617 static inline void  //
wuffs_base__pixel_buffer__set_color_u32_fill_rect__xx(wuffs_base__pixel_buffer * pb,wuffs_base__rect_ie_u32 rect,uint16_t color)19618 wuffs_base__pixel_buffer__set_color_u32_fill_rect__xx(
19619     wuffs_base__pixel_buffer* pb,
19620     wuffs_base__rect_ie_u32 rect,
19621     uint16_t color) {
19622   size_t stride = pb->private_impl.planes[0].stride;
19623   uint32_t width = wuffs_base__rect_ie_u32__width(&rect);
19624   if ((stride == (2 * ((uint64_t)width))) && (rect.min_incl_x == 0)) {
19625     uint8_t* ptr =
19626         pb->private_impl.planes[0].ptr + (stride * ((size_t)rect.min_incl_y));
19627     uint32_t height = wuffs_base__rect_ie_u32__height(&rect);
19628     size_t n;
19629     for (n = ((size_t)width) * ((size_t)height); n > 0; n--) {
19630       wuffs_base__poke_u16le__no_bounds_check(ptr, color);
19631       ptr += 2;
19632     }
19633     return;
19634   }
19635 
19636   uint32_t y;
19637   for (y = rect.min_incl_y; y < rect.max_excl_y; y++) {
19638     uint8_t* ptr = pb->private_impl.planes[0].ptr + (stride * ((size_t)y)) +
19639                    (2 * ((size_t)rect.min_incl_x));
19640     uint32_t n;
19641     for (n = width; n > 0; n--) {
19642       wuffs_base__poke_u16le__no_bounds_check(ptr, color);
19643       ptr += 2;
19644     }
19645   }
19646 }
19647 
19648 static inline void  //
wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxx(wuffs_base__pixel_buffer * pb,wuffs_base__rect_ie_u32 rect,uint32_t color)19649 wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxx(
19650     wuffs_base__pixel_buffer* pb,
19651     wuffs_base__rect_ie_u32 rect,
19652     uint32_t color) {
19653   size_t stride = pb->private_impl.planes[0].stride;
19654   uint32_t width = wuffs_base__rect_ie_u32__width(&rect);
19655   if ((stride == (3 * ((uint64_t)width))) && (rect.min_incl_x == 0)) {
19656     uint8_t* ptr =
19657         pb->private_impl.planes[0].ptr + (stride * ((size_t)rect.min_incl_y));
19658     uint32_t height = wuffs_base__rect_ie_u32__height(&rect);
19659     size_t n;
19660     for (n = ((size_t)width) * ((size_t)height); n > 0; n--) {
19661       wuffs_base__poke_u24le__no_bounds_check(ptr, color);
19662       ptr += 3;
19663     }
19664     return;
19665   }
19666 
19667   uint32_t y;
19668   for (y = rect.min_incl_y; y < rect.max_excl_y; y++) {
19669     uint8_t* ptr = pb->private_impl.planes[0].ptr + (stride * ((size_t)y)) +
19670                    (3 * ((size_t)rect.min_incl_x));
19671     uint32_t n;
19672     for (n = width; n > 0; n--) {
19673       wuffs_base__poke_u24le__no_bounds_check(ptr, color);
19674       ptr += 3;
19675     }
19676   }
19677 }
19678 
19679 static inline void  //
wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxx(wuffs_base__pixel_buffer * pb,wuffs_base__rect_ie_u32 rect,uint32_t color)19680 wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxx(
19681     wuffs_base__pixel_buffer* pb,
19682     wuffs_base__rect_ie_u32 rect,
19683     uint32_t color) {
19684   size_t stride = pb->private_impl.planes[0].stride;
19685   uint32_t width = wuffs_base__rect_ie_u32__width(&rect);
19686   if ((stride == (4 * ((uint64_t)width))) && (rect.min_incl_x == 0)) {
19687     uint8_t* ptr =
19688         pb->private_impl.planes[0].ptr + (stride * ((size_t)rect.min_incl_y));
19689     uint32_t height = wuffs_base__rect_ie_u32__height(&rect);
19690     size_t n;
19691     for (n = ((size_t)width) * ((size_t)height); n > 0; n--) {
19692       wuffs_base__poke_u32le__no_bounds_check(ptr, color);
19693       ptr += 4;
19694     }
19695     return;
19696   }
19697 
19698   uint32_t y;
19699   for (y = rect.min_incl_y; y < rect.max_excl_y; y++) {
19700     uint8_t* ptr = pb->private_impl.planes[0].ptr + (stride * ((size_t)y)) +
19701                    (4 * ((size_t)rect.min_incl_x));
19702     uint32_t n;
19703     for (n = width; n > 0; n--) {
19704       wuffs_base__poke_u32le__no_bounds_check(ptr, color);
19705       ptr += 4;
19706     }
19707   }
19708 }
19709 
19710 static inline void  //
wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxxxxxx(wuffs_base__pixel_buffer * pb,wuffs_base__rect_ie_u32 rect,uint64_t color)19711 wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxxxxxx(
19712     wuffs_base__pixel_buffer* pb,
19713     wuffs_base__rect_ie_u32 rect,
19714     uint64_t color) {
19715   size_t stride = pb->private_impl.planes[0].stride;
19716   uint32_t width = wuffs_base__rect_ie_u32__width(&rect);
19717   if ((stride == (8 * ((uint64_t)width))) && (rect.min_incl_x == 0)) {
19718     uint8_t* ptr =
19719         pb->private_impl.planes[0].ptr + (stride * ((size_t)rect.min_incl_y));
19720     uint32_t height = wuffs_base__rect_ie_u32__height(&rect);
19721     size_t n;
19722     for (n = ((size_t)width) * ((size_t)height); n > 0; n--) {
19723       wuffs_base__poke_u64le__no_bounds_check(ptr, color);
19724       ptr += 8;
19725     }
19726     return;
19727   }
19728 
19729   uint32_t y;
19730   for (y = rect.min_incl_y; y < rect.max_excl_y; y++) {
19731     uint8_t* ptr = pb->private_impl.planes[0].ptr + (stride * ((size_t)y)) +
19732                    (8 * ((size_t)rect.min_incl_x));
19733     uint32_t n;
19734     for (n = width; n > 0; n--) {
19735       wuffs_base__poke_u64le__no_bounds_check(ptr, color);
19736       ptr += 8;
19737     }
19738   }
19739 }
19740 
19741 WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
wuffs_base__pixel_buffer__set_color_u32_fill_rect(wuffs_base__pixel_buffer * pb,wuffs_base__rect_ie_u32 rect,wuffs_base__color_u32_argb_premul color)19742 wuffs_base__pixel_buffer__set_color_u32_fill_rect(
19743     wuffs_base__pixel_buffer* pb,
19744     wuffs_base__rect_ie_u32 rect,
19745     wuffs_base__color_u32_argb_premul color) {
19746   if (!pb) {
19747     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
19748   } else if (wuffs_base__rect_ie_u32__is_empty(&rect)) {
19749     return wuffs_base__make_status(NULL);
19750   }
19751   wuffs_base__rect_ie_u32 bounds =
19752       wuffs_base__pixel_config__bounds(&pb->pixcfg);
19753   if (!wuffs_base__rect_ie_u32__contains_rect(&bounds, rect)) {
19754     return wuffs_base__make_status(wuffs_base__error__bad_argument);
19755   }
19756 
19757   if (wuffs_base__pixel_format__is_planar(&pb->pixcfg.private_impl.pixfmt)) {
19758     // TODO: support planar formats.
19759     return wuffs_base__make_status(wuffs_base__error__unsupported_option);
19760   }
19761 
19762   switch (pb->pixcfg.private_impl.pixfmt.repr) {
19763     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
19764     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
19765       wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxx(pb, rect, color);
19766       return wuffs_base__make_status(NULL);
19767 
19768       // Common formats above. Rarer formats below.
19769 
19770     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
19771       wuffs_base__pixel_buffer__set_color_u32_fill_rect__xx(
19772           pb, rect,
19773           wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(color));
19774       return wuffs_base__make_status(NULL);
19775 
19776     case WUFFS_BASE__PIXEL_FORMAT__BGR:
19777       wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxx(pb, rect, color);
19778       return wuffs_base__make_status(NULL);
19779 
19780     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
19781       wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxx(
19782           pb, rect,
19783           wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
19784               color));
19785       return wuffs_base__make_status(NULL);
19786 
19787     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
19788       wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxxxxxx(
19789           pb, rect,
19790           wuffs_base__color_u32_argb_premul__as__color_u64_argb_nonpremul(
19791               color));
19792       return wuffs_base__make_status(NULL);
19793 
19794     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
19795       wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxx(
19796           pb, rect,
19797           wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
19798               wuffs_base__swap_u32_argb_abgr(color)));
19799       return wuffs_base__make_status(NULL);
19800 
19801     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
19802     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
19803       wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxx(
19804           pb, rect, wuffs_base__swap_u32_argb_abgr(color));
19805       return wuffs_base__make_status(NULL);
19806   }
19807 
19808   uint32_t y;
19809   for (y = rect.min_incl_y; y < rect.max_excl_y; y++) {
19810     uint32_t x;
19811     for (x = rect.min_incl_x; x < rect.max_excl_x; x++) {
19812       wuffs_base__pixel_buffer__set_color_u32_at(pb, x, y, color);
19813     }
19814   }
19815   return wuffs_base__make_status(NULL);
19816 }
19817 
19818 // --------
19819 
19820 WUFFS_BASE__MAYBE_STATIC uint8_t  //
wuffs_base__pixel_palette__closest_element(wuffs_base__slice_u8 palette_slice,wuffs_base__pixel_format palette_format,wuffs_base__color_u32_argb_premul c)19821 wuffs_base__pixel_palette__closest_element(
19822     wuffs_base__slice_u8 palette_slice,
19823     wuffs_base__pixel_format palette_format,
19824     wuffs_base__color_u32_argb_premul c) {
19825   size_t n = palette_slice.len / 4;
19826   if (n > (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
19827     n = (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4);
19828   }
19829   size_t best_index = 0;
19830   uint64_t best_score = 0xFFFFFFFFFFFFFFFF;
19831 
19832   // Work in 16-bit color.
19833   uint32_t ca = 0x101 * (0xFF & (c >> 24));
19834   uint32_t cr = 0x101 * (0xFF & (c >> 16));
19835   uint32_t cg = 0x101 * (0xFF & (c >> 8));
19836   uint32_t cb = 0x101 * (0xFF & (c >> 0));
19837 
19838   switch (palette_format.repr) {
19839     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:
19840     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL:
19841     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY: {
19842       bool nonpremul = palette_format.repr ==
19843                        WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL;
19844 
19845       size_t i;
19846       for (i = 0; i < n; i++) {
19847         // Work in 16-bit color.
19848         uint32_t pb = 0x101 * ((uint32_t)(palette_slice.ptr[(4 * i) + 0]));
19849         uint32_t pg = 0x101 * ((uint32_t)(palette_slice.ptr[(4 * i) + 1]));
19850         uint32_t pr = 0x101 * ((uint32_t)(palette_slice.ptr[(4 * i) + 2]));
19851         uint32_t pa = 0x101 * ((uint32_t)(palette_slice.ptr[(4 * i) + 3]));
19852 
19853         // Convert to premultiplied alpha.
19854         if (nonpremul && (pa != 0xFFFF)) {
19855           pb = (pb * pa) / 0xFFFF;
19856           pg = (pg * pa) / 0xFFFF;
19857           pr = (pr * pa) / 0xFFFF;
19858         }
19859 
19860         // These deltas are conceptually int32_t (signed) but after squaring,
19861         // it's equivalent to work in uint32_t (unsigned).
19862         pb -= cb;
19863         pg -= cg;
19864         pr -= cr;
19865         pa -= ca;
19866         uint64_t score = ((uint64_t)(pb * pb)) + ((uint64_t)(pg * pg)) +
19867                          ((uint64_t)(pr * pr)) + ((uint64_t)(pa * pa));
19868         if (best_score > score) {
19869           best_score = score;
19870           best_index = i;
19871         }
19872       }
19873       break;
19874     }
19875   }
19876 
19877   return (uint8_t)best_index;
19878 }
19879 
19880 // --------
19881 
19882 static inline uint32_t  //
wuffs_base__composite_nonpremul_nonpremul_u32_axxx(uint32_t dst_nonpremul,uint32_t src_nonpremul)19883 wuffs_base__composite_nonpremul_nonpremul_u32_axxx(uint32_t dst_nonpremul,
19884                                                    uint32_t src_nonpremul) {
19885   // Extract 16-bit color components.
19886   //
19887   // If the destination is transparent then SRC_OVER is equivalent to SRC: just
19888   // return src_nonpremul. This isn't just an optimization (skipping the rest
19889   // of the function's computation). It also preserves the nonpremul
19890   // distinction between e.g. transparent red and transparent blue that would
19891   // otherwise be lost by converting from nonpremul to premul and back.
19892   uint32_t da = 0x101 * (0xFF & (dst_nonpremul >> 24));
19893   if (da == 0) {
19894     return src_nonpremul;
19895   }
19896   uint32_t dr = 0x101 * (0xFF & (dst_nonpremul >> 16));
19897   uint32_t dg = 0x101 * (0xFF & (dst_nonpremul >> 8));
19898   uint32_t db = 0x101 * (0xFF & (dst_nonpremul >> 0));
19899   uint32_t sa = 0x101 * (0xFF & (src_nonpremul >> 24));
19900   uint32_t sr = 0x101 * (0xFF & (src_nonpremul >> 16));
19901   uint32_t sg = 0x101 * (0xFF & (src_nonpremul >> 8));
19902   uint32_t sb = 0x101 * (0xFF & (src_nonpremul >> 0));
19903 
19904   // Convert dst from nonpremul to premul.
19905   dr = (dr * da) / 0xFFFF;
19906   dg = (dg * da) / 0xFFFF;
19907   db = (db * da) / 0xFFFF;
19908 
19909   // Calculate the inverse of the src-alpha: how much of the dst to keep.
19910   uint32_t ia = 0xFFFF - sa;
19911 
19912   // Composite src (nonpremul) over dst (premul).
19913   da = sa + ((da * ia) / 0xFFFF);
19914   dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
19915   dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
19916   db = ((sb * sa) + (db * ia)) / 0xFFFF;
19917 
19918   // Convert dst from premul to nonpremul.
19919   if (da != 0) {
19920     dr = (dr * 0xFFFF) / da;
19921     dg = (dg * 0xFFFF) / da;
19922     db = (db * 0xFFFF) / da;
19923   }
19924 
19925   // Convert from 16-bit color to 8-bit color.
19926   da >>= 8;
19927   dr >>= 8;
19928   dg >>= 8;
19929   db >>= 8;
19930 
19931   // Combine components.
19932   return (db << 0) | (dg << 8) | (dr << 16) | (da << 24);
19933 }
19934 
19935 static inline uint64_t  //
wuffs_base__composite_nonpremul_nonpremul_u64_axxx(uint64_t dst_nonpremul,uint64_t src_nonpremul)19936 wuffs_base__composite_nonpremul_nonpremul_u64_axxx(uint64_t dst_nonpremul,
19937                                                    uint64_t src_nonpremul) {
19938   // Extract components.
19939   //
19940   // If the destination is transparent then SRC_OVER is equivalent to SRC: just
19941   // return src_nonpremul. This isn't just an optimization (skipping the rest
19942   // of the function's computation). It also preserves the nonpremul
19943   // distinction between e.g. transparent red and transparent blue that would
19944   // otherwise be lost by converting from nonpremul to premul and back.
19945   uint64_t da = 0xFFFF & (dst_nonpremul >> 48);
19946   if (da == 0) {
19947     return src_nonpremul;
19948   }
19949   uint64_t dr = 0xFFFF & (dst_nonpremul >> 32);
19950   uint64_t dg = 0xFFFF & (dst_nonpremul >> 16);
19951   uint64_t db = 0xFFFF & (dst_nonpremul >> 0);
19952   uint64_t sa = 0xFFFF & (src_nonpremul >> 48);
19953   uint64_t sr = 0xFFFF & (src_nonpremul >> 32);
19954   uint64_t sg = 0xFFFF & (src_nonpremul >> 16);
19955   uint64_t sb = 0xFFFF & (src_nonpremul >> 0);
19956 
19957   // Convert dst from nonpremul to premul.
19958   dr = (dr * da) / 0xFFFF;
19959   dg = (dg * da) / 0xFFFF;
19960   db = (db * da) / 0xFFFF;
19961 
19962   // Calculate the inverse of the src-alpha: how much of the dst to keep.
19963   uint64_t ia = 0xFFFF - sa;
19964 
19965   // Composite src (nonpremul) over dst (premul).
19966   da = sa + ((da * ia) / 0xFFFF);
19967   dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
19968   dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
19969   db = ((sb * sa) + (db * ia)) / 0xFFFF;
19970 
19971   // Convert dst from premul to nonpremul.
19972   if (da != 0) {
19973     dr = (dr * 0xFFFF) / da;
19974     dg = (dg * 0xFFFF) / da;
19975     db = (db * 0xFFFF) / da;
19976   }
19977 
19978   // Combine components.
19979   return (db << 0) | (dg << 16) | (dr << 32) | (da << 48);
19980 }
19981 
19982 static inline uint32_t  //
wuffs_base__composite_nonpremul_premul_u32_axxx(uint32_t dst_nonpremul,uint32_t src_premul)19983 wuffs_base__composite_nonpremul_premul_u32_axxx(uint32_t dst_nonpremul,
19984                                                 uint32_t src_premul) {
19985   // Extract 16-bit color components.
19986   uint32_t da = 0x101 * (0xFF & (dst_nonpremul >> 24));
19987   uint32_t dr = 0x101 * (0xFF & (dst_nonpremul >> 16));
19988   uint32_t dg = 0x101 * (0xFF & (dst_nonpremul >> 8));
19989   uint32_t db = 0x101 * (0xFF & (dst_nonpremul >> 0));
19990   uint32_t sa = 0x101 * (0xFF & (src_premul >> 24));
19991   uint32_t sr = 0x101 * (0xFF & (src_premul >> 16));
19992   uint32_t sg = 0x101 * (0xFF & (src_premul >> 8));
19993   uint32_t sb = 0x101 * (0xFF & (src_premul >> 0));
19994 
19995   // Convert dst from nonpremul to premul.
19996   dr = (dr * da) / 0xFFFF;
19997   dg = (dg * da) / 0xFFFF;
19998   db = (db * da) / 0xFFFF;
19999 
20000   // Calculate the inverse of the src-alpha: how much of the dst to keep.
20001   uint32_t ia = 0xFFFF - sa;
20002 
20003   // Composite src (premul) over dst (premul).
20004   da = sa + ((da * ia) / 0xFFFF);
20005   dr = sr + ((dr * ia) / 0xFFFF);
20006   dg = sg + ((dg * ia) / 0xFFFF);
20007   db = sb + ((db * ia) / 0xFFFF);
20008 
20009   // Convert dst from premul to nonpremul.
20010   if (da != 0) {
20011     dr = (dr * 0xFFFF) / da;
20012     dg = (dg * 0xFFFF) / da;
20013     db = (db * 0xFFFF) / da;
20014   }
20015 
20016   // Convert from 16-bit color to 8-bit color.
20017   da >>= 8;
20018   dr >>= 8;
20019   dg >>= 8;
20020   db >>= 8;
20021 
20022   // Combine components.
20023   return (db << 0) | (dg << 8) | (dr << 16) | (da << 24);
20024 }
20025 
20026 static inline uint64_t  //
wuffs_base__composite_nonpremul_premul_u64_axxx(uint64_t dst_nonpremul,uint64_t src_premul)20027 wuffs_base__composite_nonpremul_premul_u64_axxx(uint64_t dst_nonpremul,
20028                                                 uint64_t src_premul) {
20029   // Extract components.
20030   uint64_t da = 0xFFFF & (dst_nonpremul >> 48);
20031   uint64_t dr = 0xFFFF & (dst_nonpremul >> 32);
20032   uint64_t dg = 0xFFFF & (dst_nonpremul >> 16);
20033   uint64_t db = 0xFFFF & (dst_nonpremul >> 0);
20034   uint64_t sa = 0xFFFF & (src_premul >> 48);
20035   uint64_t sr = 0xFFFF & (src_premul >> 32);
20036   uint64_t sg = 0xFFFF & (src_premul >> 16);
20037   uint64_t sb = 0xFFFF & (src_premul >> 0);
20038 
20039   // Convert dst from nonpremul to premul.
20040   dr = (dr * da) / 0xFFFF;
20041   dg = (dg * da) / 0xFFFF;
20042   db = (db * da) / 0xFFFF;
20043 
20044   // Calculate the inverse of the src-alpha: how much of the dst to keep.
20045   uint64_t ia = 0xFFFF - sa;
20046 
20047   // Composite src (premul) over dst (premul).
20048   da = sa + ((da * ia) / 0xFFFF);
20049   dr = sr + ((dr * ia) / 0xFFFF);
20050   dg = sg + ((dg * ia) / 0xFFFF);
20051   db = sb + ((db * ia) / 0xFFFF);
20052 
20053   // Convert dst from premul to nonpremul.
20054   if (da != 0) {
20055     dr = (dr * 0xFFFF) / da;
20056     dg = (dg * 0xFFFF) / da;
20057     db = (db * 0xFFFF) / da;
20058   }
20059 
20060   // Combine components.
20061   return (db << 0) | (dg << 16) | (dr << 32) | (da << 48);
20062 }
20063 
20064 static inline uint32_t  //
wuffs_base__composite_premul_nonpremul_u32_axxx(uint32_t dst_premul,uint32_t src_nonpremul)20065 wuffs_base__composite_premul_nonpremul_u32_axxx(uint32_t dst_premul,
20066                                                 uint32_t src_nonpremul) {
20067   // Extract 16-bit color components.
20068   uint32_t da = 0x101 * (0xFF & (dst_premul >> 24));
20069   uint32_t dr = 0x101 * (0xFF & (dst_premul >> 16));
20070   uint32_t dg = 0x101 * (0xFF & (dst_premul >> 8));
20071   uint32_t db = 0x101 * (0xFF & (dst_premul >> 0));
20072   uint32_t sa = 0x101 * (0xFF & (src_nonpremul >> 24));
20073   uint32_t sr = 0x101 * (0xFF & (src_nonpremul >> 16));
20074   uint32_t sg = 0x101 * (0xFF & (src_nonpremul >> 8));
20075   uint32_t sb = 0x101 * (0xFF & (src_nonpremul >> 0));
20076 
20077   // Calculate the inverse of the src-alpha: how much of the dst to keep.
20078   uint32_t ia = 0xFFFF - sa;
20079 
20080   // Composite src (nonpremul) over dst (premul).
20081   da = sa + ((da * ia) / 0xFFFF);
20082   dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
20083   dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
20084   db = ((sb * sa) + (db * ia)) / 0xFFFF;
20085 
20086   // Convert from 16-bit color to 8-bit color.
20087   da >>= 8;
20088   dr >>= 8;
20089   dg >>= 8;
20090   db >>= 8;
20091 
20092   // Combine components.
20093   return (db << 0) | (dg << 8) | (dr << 16) | (da << 24);
20094 }
20095 
20096 static inline uint64_t  //
wuffs_base__composite_premul_nonpremul_u64_axxx(uint64_t dst_premul,uint64_t src_nonpremul)20097 wuffs_base__composite_premul_nonpremul_u64_axxx(uint64_t dst_premul,
20098                                                 uint64_t src_nonpremul) {
20099   // Extract components.
20100   uint64_t da = 0xFFFF & (dst_premul >> 48);
20101   uint64_t dr = 0xFFFF & (dst_premul >> 32);
20102   uint64_t dg = 0xFFFF & (dst_premul >> 16);
20103   uint64_t db = 0xFFFF & (dst_premul >> 0);
20104   uint64_t sa = 0xFFFF & (src_nonpremul >> 48);
20105   uint64_t sr = 0xFFFF & (src_nonpremul >> 32);
20106   uint64_t sg = 0xFFFF & (src_nonpremul >> 16);
20107   uint64_t sb = 0xFFFF & (src_nonpremul >> 0);
20108 
20109   // Calculate the inverse of the src-alpha: how much of the dst to keep.
20110   uint64_t ia = 0xFFFF - sa;
20111 
20112   // Composite src (nonpremul) over dst (premul).
20113   da = sa + ((da * ia) / 0xFFFF);
20114   dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
20115   dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
20116   db = ((sb * sa) + (db * ia)) / 0xFFFF;
20117 
20118   // Combine components.
20119   return (db << 0) | (dg << 16) | (dr << 32) | (da << 48);
20120 }
20121 
20122 static inline uint32_t  //
wuffs_base__composite_premul_premul_u32_axxx(uint32_t dst_premul,uint32_t src_premul)20123 wuffs_base__composite_premul_premul_u32_axxx(uint32_t dst_premul,
20124                                              uint32_t src_premul) {
20125   // Extract 16-bit color components.
20126   uint32_t da = 0x101 * (0xFF & (dst_premul >> 24));
20127   uint32_t dr = 0x101 * (0xFF & (dst_premul >> 16));
20128   uint32_t dg = 0x101 * (0xFF & (dst_premul >> 8));
20129   uint32_t db = 0x101 * (0xFF & (dst_premul >> 0));
20130   uint32_t sa = 0x101 * (0xFF & (src_premul >> 24));
20131   uint32_t sr = 0x101 * (0xFF & (src_premul >> 16));
20132   uint32_t sg = 0x101 * (0xFF & (src_premul >> 8));
20133   uint32_t sb = 0x101 * (0xFF & (src_premul >> 0));
20134 
20135   // Calculate the inverse of the src-alpha: how much of the dst to keep.
20136   uint32_t ia = 0xFFFF - sa;
20137 
20138   // Composite src (premul) over dst (premul).
20139   da = sa + ((da * ia) / 0xFFFF);
20140   dr = sr + ((dr * ia) / 0xFFFF);
20141   dg = sg + ((dg * ia) / 0xFFFF);
20142   db = sb + ((db * ia) / 0xFFFF);
20143 
20144   // Convert from 16-bit color to 8-bit color.
20145   da >>= 8;
20146   dr >>= 8;
20147   dg >>= 8;
20148   db >>= 8;
20149 
20150   // Combine components.
20151   return (db << 0) | (dg << 8) | (dr << 16) | (da << 24);
20152 }
20153 
20154 // --------
20155 
20156 static uint64_t  //
wuffs_base__pixel_swizzler__squash_align4_bgr_565_8888(uint8_t * dst_ptr,size_t dst_len,const uint8_t * src_ptr,size_t src_len,bool nonpremul)20157 wuffs_base__pixel_swizzler__squash_align4_bgr_565_8888(uint8_t* dst_ptr,
20158                                                        size_t dst_len,
20159                                                        const uint8_t* src_ptr,
20160                                                        size_t src_len,
20161                                                        bool nonpremul) {
20162   size_t len = (dst_len < src_len ? dst_len : src_len) / 4;
20163   uint8_t* d = dst_ptr;
20164   const uint8_t* s = src_ptr;
20165 
20166   size_t n = len;
20167   while (n--) {
20168     uint32_t argb = wuffs_base__peek_u32le__no_bounds_check(s);
20169     if (nonpremul) {
20170       argb =
20171           wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(argb);
20172     }
20173     uint32_t b5 = 0x1F & (argb >> (8 - 5));
20174     uint32_t g6 = 0x3F & (argb >> (16 - 6));
20175     uint32_t r5 = 0x1F & (argb >> (24 - 5));
20176     uint32_t alpha = argb & 0xFF000000;
20177     wuffs_base__poke_u32le__no_bounds_check(
20178         d, alpha | (r5 << 11) | (g6 << 5) | (b5 << 0));
20179     s += 4;
20180     d += 4;
20181   }
20182   return len;
20183 }
20184 
20185 // --------
20186 
20187 static uint64_t  //
wuffs_base__pixel_swizzler__swap_rgb_bgr(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)20188 wuffs_base__pixel_swizzler__swap_rgb_bgr(uint8_t* dst_ptr,
20189                                          size_t dst_len,
20190                                          uint8_t* dst_palette_ptr,
20191                                          size_t dst_palette_len,
20192                                          const uint8_t* src_ptr,
20193                                          size_t src_len) {
20194   size_t len = (dst_len < src_len ? dst_len : src_len) / 3;
20195   uint8_t* d = dst_ptr;
20196   const uint8_t* s = src_ptr;
20197 
20198   size_t n = len;
20199   while (n--) {
20200     uint8_t s0 = s[0];
20201     uint8_t s1 = s[1];
20202     uint8_t s2 = s[2];
20203     d[0] = s2;
20204     d[1] = s1;
20205     d[2] = s0;
20206     s += 3;
20207     d += 3;
20208   }
20209   return len;
20210 }
20211 
20212 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
20213 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
20214 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
20215 static uint64_t  //
wuffs_base__pixel_swizzler__swap_rgbx_bgrx__x86_sse42(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)20216 wuffs_base__pixel_swizzler__swap_rgbx_bgrx__x86_sse42(uint8_t* dst_ptr,
20217                                                       size_t dst_len,
20218                                                       uint8_t* dst_palette_ptr,
20219                                                       size_t dst_palette_len,
20220                                                       const uint8_t* src_ptr,
20221                                                       size_t src_len) {
20222   size_t len = (dst_len < src_len ? dst_len : src_len) / 4;
20223   uint8_t* d = dst_ptr;
20224   const uint8_t* s = src_ptr;
20225   size_t n = len;
20226 
20227   __m128i shuffle = _mm_set_epi8(+0x0F, +0x0C, +0x0D, +0x0E,  //
20228                                  +0x0B, +0x08, +0x09, +0x0A,  //
20229                                  +0x07, +0x04, +0x05, +0x06,  //
20230                                  +0x03, +0x00, +0x01, +0x02);
20231 
20232   while (n >= 4) {
20233     __m128i x;
20234     x = _mm_lddqu_si128((const __m128i*)(const void*)s);
20235     x = _mm_shuffle_epi8(x, shuffle);
20236     _mm_storeu_si128((__m128i*)(void*)d, x);
20237 
20238     s += 4 * 4;
20239     d += 4 * 4;
20240     n -= 4;
20241   }
20242 
20243   while (n--) {
20244     uint8_t s0 = s[0];
20245     uint8_t s1 = s[1];
20246     uint8_t s2 = s[2];
20247     uint8_t s3 = s[3];
20248     d[0] = s2;
20249     d[1] = s1;
20250     d[2] = s0;
20251     d[3] = s3;
20252     s += 4;
20253     d += 4;
20254   }
20255   return len;
20256 }
20257 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
20258 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
20259 
20260 static uint64_t  //
wuffs_base__pixel_swizzler__swap_rgbx_bgrx(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)20261 wuffs_base__pixel_swizzler__swap_rgbx_bgrx(uint8_t* dst_ptr,
20262                                            size_t dst_len,
20263                                            uint8_t* dst_palette_ptr,
20264                                            size_t dst_palette_len,
20265                                            const uint8_t* src_ptr,
20266                                            size_t src_len) {
20267   size_t len = (dst_len < src_len ? dst_len : src_len) / 4;
20268   uint8_t* d = dst_ptr;
20269   const uint8_t* s = src_ptr;
20270 
20271   size_t n = len;
20272   while (n--) {
20273     uint8_t s0 = s[0];
20274     uint8_t s1 = s[1];
20275     uint8_t s2 = s[2];
20276     uint8_t s3 = s[3];
20277     d[0] = s2;
20278     d[1] = s1;
20279     d[2] = s0;
20280     d[3] = s3;
20281     s += 4;
20282     d += 4;
20283   }
20284   return len;
20285 }
20286 
20287 // --------
20288 
20289 static uint64_t  //
wuffs_base__pixel_swizzler__copy_1_1(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)20290 wuffs_base__pixel_swizzler__copy_1_1(uint8_t* dst_ptr,
20291                                      size_t dst_len,
20292                                      uint8_t* dst_palette_ptr,
20293                                      size_t dst_palette_len,
20294                                      const uint8_t* src_ptr,
20295                                      size_t src_len) {
20296   size_t len = (dst_len < src_len) ? dst_len : src_len;
20297   if (len > 0) {
20298     memmove(dst_ptr, src_ptr, len);
20299   }
20300   return len;
20301 }
20302 
20303 static uint64_t  //
wuffs_base__pixel_swizzler__copy_2_2(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)20304 wuffs_base__pixel_swizzler__copy_2_2(uint8_t* dst_ptr,
20305                                      size_t dst_len,
20306                                      uint8_t* dst_palette_ptr,
20307                                      size_t dst_palette_len,
20308                                      const uint8_t* src_ptr,
20309                                      size_t src_len) {
20310   size_t dst_len2 = dst_len / 2;
20311   size_t src_len2 = src_len / 2;
20312   size_t len = (dst_len2 < src_len2) ? dst_len2 : src_len2;
20313   if (len > 0) {
20314     memmove(dst_ptr, src_ptr, len * 2);
20315   }
20316   return len;
20317 }
20318 
20319 static uint64_t  //
wuffs_base__pixel_swizzler__copy_3_3(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)20320 wuffs_base__pixel_swizzler__copy_3_3(uint8_t* dst_ptr,
20321                                      size_t dst_len,
20322                                      uint8_t* dst_palette_ptr,
20323                                      size_t dst_palette_len,
20324                                      const uint8_t* src_ptr,
20325                                      size_t src_len) {
20326   size_t dst_len3 = dst_len / 3;
20327   size_t src_len3 = src_len / 3;
20328   size_t len = (dst_len3 < src_len3) ? dst_len3 : src_len3;
20329   if (len > 0) {
20330     memmove(dst_ptr, src_ptr, len * 3);
20331   }
20332   return len;
20333 }
20334 
20335 static uint64_t  //
wuffs_base__pixel_swizzler__copy_4_4(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)20336 wuffs_base__pixel_swizzler__copy_4_4(uint8_t* dst_ptr,
20337                                      size_t dst_len,
20338                                      uint8_t* dst_palette_ptr,
20339                                      size_t dst_palette_len,
20340                                      const uint8_t* src_ptr,
20341                                      size_t src_len) {
20342   size_t dst_len4 = dst_len / 4;
20343   size_t src_len4 = src_len / 4;
20344   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
20345   if (len > 0) {
20346     memmove(dst_ptr, src_ptr, len * 4);
20347   }
20348   return len;
20349 }
20350 
20351 static uint64_t  //
wuffs_base__pixel_swizzler__copy_8_8(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)20352 wuffs_base__pixel_swizzler__copy_8_8(uint8_t* dst_ptr,
20353                                      size_t dst_len,
20354                                      uint8_t* dst_palette_ptr,
20355                                      size_t dst_palette_len,
20356                                      const uint8_t* src_ptr,
20357                                      size_t src_len) {
20358   size_t dst_len8 = dst_len / 8;
20359   size_t src_len8 = src_len / 8;
20360   size_t len = (dst_len8 < src_len8) ? dst_len8 : src_len8;
20361   if (len > 0) {
20362     memmove(dst_ptr, src_ptr, len * 8);
20363   }
20364   return len;
20365 }
20366 
20367 // --------
20368 
20369 static uint64_t  //
wuffs_base__pixel_swizzler__bgr_565__bgr(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)20370 wuffs_base__pixel_swizzler__bgr_565__bgr(uint8_t* dst_ptr,
20371                                          size_t dst_len,
20372                                          uint8_t* dst_palette_ptr,
20373                                          size_t dst_palette_len,
20374                                          const uint8_t* src_ptr,
20375                                          size_t src_len) {
20376   size_t dst_len2 = dst_len / 2;
20377   size_t src_len3 = src_len / 3;
20378   size_t len = (dst_len2 < src_len3) ? dst_len2 : src_len3;
20379   uint8_t* d = dst_ptr;
20380   const uint8_t* s = src_ptr;
20381   size_t n = len;
20382 
20383   // TODO: unroll.
20384 
20385   while (n >= 1) {
20386     uint32_t b5 = s[0] >> 3;
20387     uint32_t g6 = s[1] >> 2;
20388     uint32_t r5 = s[2] >> 3;
20389     uint32_t rgb_565 = (r5 << 11) | (g6 << 5) | (b5 << 0);
20390     wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565);
20391 
20392     s += 1 * 3;
20393     d += 1 * 2;
20394     n -= 1;
20395   }
20396 
20397   return len;
20398 }
20399 
20400 static uint64_t  //
wuffs_base__pixel_swizzler__bgr_565__bgrx(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)20401 wuffs_base__pixel_swizzler__bgr_565__bgrx(uint8_t* dst_ptr,
20402                                           size_t dst_len,
20403                                           uint8_t* dst_palette_ptr,
20404                                           size_t dst_palette_len,
20405                                           const uint8_t* src_ptr,
20406                                           size_t src_len) {
20407   size_t dst_len2 = dst_len / 2;
20408   size_t src_len4 = src_len / 4;
20409   size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
20410   uint8_t* d = dst_ptr;
20411   const uint8_t* s = src_ptr;
20412   size_t n = len;
20413 
20414   // TODO: unroll.
20415 
20416   while (n >= 1) {
20417     uint32_t b5 = s[0] >> 3;
20418     uint32_t g6 = s[1] >> 2;
20419     uint32_t r5 = s[2] >> 3;
20420     uint32_t rgb_565 = (r5 << 11) | (g6 << 5) | (b5 << 0);
20421     wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565);
20422 
20423     s += 1 * 4;
20424     d += 1 * 2;
20425     n -= 1;
20426   }
20427 
20428   return len;
20429 }
20430 
20431 static uint64_t  //
wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)20432 wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul__src(
20433     uint8_t* dst_ptr,
20434     size_t dst_len,
20435     uint8_t* dst_palette_ptr,
20436     size_t dst_palette_len,
20437     const uint8_t* src_ptr,
20438     size_t src_len) {
20439   size_t dst_len2 = dst_len / 2;
20440   size_t src_len4 = src_len / 4;
20441   size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
20442   uint8_t* d = dst_ptr;
20443   const uint8_t* s = src_ptr;
20444   size_t n = len;
20445 
20446   // TODO: unroll.
20447 
20448   while (n >= 1) {
20449     wuffs_base__poke_u16le__no_bounds_check(
20450         d + (0 * 2),
20451         wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
20452             wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
20453                 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)))));
20454 
20455     s += 1 * 4;
20456     d += 1 * 2;
20457     n -= 1;
20458   }
20459 
20460   return len;
20461 }
20462 
20463 static uint64_t  //
wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul_4x16le__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)20464 wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul_4x16le__src(
20465     uint8_t* dst_ptr,
20466     size_t dst_len,
20467     uint8_t* dst_palette_ptr,
20468     size_t dst_palette_len,
20469     const uint8_t* src_ptr,
20470     size_t src_len) {
20471   size_t dst_len2 = dst_len / 2;
20472   size_t src_len8 = src_len / 8;
20473   size_t len = (dst_len2 < src_len8) ? dst_len2 : src_len8;
20474   uint8_t* d = dst_ptr;
20475   const uint8_t* s = src_ptr;
20476   size_t n = len;
20477 
20478   // TODO: unroll.
20479 
20480   while (n >= 1) {
20481     wuffs_base__poke_u16le__no_bounds_check(
20482         d + (0 * 2),
20483         wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
20484             wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(
20485                 wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)))));
20486 
20487     s += 1 * 8;
20488     d += 1 * 2;
20489     n -= 1;
20490   }
20491 
20492   return len;
20493 }
20494 
20495 static uint64_t  //
wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)20496 wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul__src_over(
20497     uint8_t* dst_ptr,
20498     size_t dst_len,
20499     uint8_t* dst_palette_ptr,
20500     size_t dst_palette_len,
20501     const uint8_t* src_ptr,
20502     size_t src_len) {
20503   size_t dst_len2 = dst_len / 2;
20504   size_t src_len4 = src_len / 4;
20505   size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
20506   uint8_t* d = dst_ptr;
20507   const uint8_t* s = src_ptr;
20508   size_t n = len;
20509 
20510   // TODO: unroll.
20511 
20512   while (n >= 1) {
20513     // Extract 16-bit color components.
20514     uint32_t sa = 0x101 * ((uint32_t)s[3]);
20515     uint32_t sr = 0x101 * ((uint32_t)s[2]);
20516     uint32_t sg = 0x101 * ((uint32_t)s[1]);
20517     uint32_t sb = 0x101 * ((uint32_t)s[0]);
20518 
20519     // Convert from 565 color to 16-bit color.
20520     uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2));
20521     uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11);
20522     uint32_t dr = (0x8421 * old_r5) >> 4;
20523     uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5);
20524     uint32_t dg = (0x1041 * old_g6) >> 2;
20525     uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0);
20526     uint32_t db = (0x8421 * old_b5) >> 4;
20527 
20528     // Calculate the inverse of the src-alpha: how much of the dst to keep.
20529     uint32_t ia = 0xFFFF - sa;
20530 
20531     // Composite src (nonpremul) over dst (premul).
20532     dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
20533     dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
20534     db = ((sb * sa) + (db * ia)) / 0xFFFF;
20535 
20536     // Convert from 16-bit color to 565 color and combine the components.
20537     uint32_t new_r5 = 0x1F & (dr >> 11);
20538     uint32_t new_g6 = 0x3F & (dg >> 10);
20539     uint32_t new_b5 = 0x1F & (db >> 11);
20540     uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0);
20541     wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565);
20542 
20543     s += 1 * 4;
20544     d += 1 * 2;
20545     n -= 1;
20546   }
20547 
20548   return len;
20549 }
20550 
20551 static uint64_t  //
wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul_4x16le__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)20552 wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul_4x16le__src_over(
20553     uint8_t* dst_ptr,
20554     size_t dst_len,
20555     uint8_t* dst_palette_ptr,
20556     size_t dst_palette_len,
20557     const uint8_t* src_ptr,
20558     size_t src_len) {
20559   size_t dst_len2 = dst_len / 2;
20560   size_t src_len8 = src_len / 8;
20561   size_t len = (dst_len2 < src_len8) ? dst_len2 : src_len8;
20562   uint8_t* d = dst_ptr;
20563   const uint8_t* s = src_ptr;
20564   size_t n = len;
20565 
20566   // TODO: unroll.
20567 
20568   while (n >= 1) {
20569     // Extract 16-bit color components.
20570     uint32_t sa = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 6));
20571     uint32_t sr = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 4));
20572     uint32_t sg = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 2));
20573     uint32_t sb = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 0));
20574 
20575     // Convert from 565 color to 16-bit color.
20576     uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2));
20577     uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11);
20578     uint32_t dr = (0x8421 * old_r5) >> 4;
20579     uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5);
20580     uint32_t dg = (0x1041 * old_g6) >> 2;
20581     uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0);
20582     uint32_t db = (0x8421 * old_b5) >> 4;
20583 
20584     // Calculate the inverse of the src-alpha: how much of the dst to keep.
20585     uint32_t ia = 0xFFFF - sa;
20586 
20587     // Composite src (nonpremul) over dst (premul).
20588     dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
20589     dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
20590     db = ((sb * sa) + (db * ia)) / 0xFFFF;
20591 
20592     // Convert from 16-bit color to 565 color and combine the components.
20593     uint32_t new_r5 = 0x1F & (dr >> 11);
20594     uint32_t new_g6 = 0x3F & (dg >> 10);
20595     uint32_t new_b5 = 0x1F & (db >> 11);
20596     uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0);
20597     wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565);
20598 
20599     s += 1 * 8;
20600     d += 1 * 2;
20601     n -= 1;
20602   }
20603 
20604   return len;
20605 }
20606 
20607 static uint64_t  //
wuffs_base__pixel_swizzler__bgr_565__bgra_premul__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)20608 wuffs_base__pixel_swizzler__bgr_565__bgra_premul__src(uint8_t* dst_ptr,
20609                                                       size_t dst_len,
20610                                                       uint8_t* dst_palette_ptr,
20611                                                       size_t dst_palette_len,
20612                                                       const uint8_t* src_ptr,
20613                                                       size_t src_len) {
20614   size_t dst_len2 = dst_len / 2;
20615   size_t src_len4 = src_len / 4;
20616   size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
20617   uint8_t* d = dst_ptr;
20618   const uint8_t* s = src_ptr;
20619   size_t n = len;
20620 
20621   // TODO: unroll.
20622 
20623   while (n >= 1) {
20624     wuffs_base__poke_u16le__no_bounds_check(
20625         d + (0 * 2), wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
20626                          wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))));
20627 
20628     s += 1 * 4;
20629     d += 1 * 2;
20630     n -= 1;
20631   }
20632 
20633   return len;
20634 }
20635 
20636 static uint64_t  //
wuffs_base__pixel_swizzler__bgr_565__bgra_premul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)20637 wuffs_base__pixel_swizzler__bgr_565__bgra_premul__src_over(
20638     uint8_t* dst_ptr,
20639     size_t dst_len,
20640     uint8_t* dst_palette_ptr,
20641     size_t dst_palette_len,
20642     const uint8_t* src_ptr,
20643     size_t src_len) {
20644   size_t dst_len2 = dst_len / 2;
20645   size_t src_len4 = src_len / 4;
20646   size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
20647   uint8_t* d = dst_ptr;
20648   const uint8_t* s = src_ptr;
20649   size_t n = len;
20650 
20651   // TODO: unroll.
20652 
20653   while (n >= 1) {
20654     // Extract 16-bit color components.
20655     uint32_t sa = 0x101 * ((uint32_t)s[3]);
20656     uint32_t sr = 0x101 * ((uint32_t)s[2]);
20657     uint32_t sg = 0x101 * ((uint32_t)s[1]);
20658     uint32_t sb = 0x101 * ((uint32_t)s[0]);
20659 
20660     // Convert from 565 color to 16-bit color.
20661     uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2));
20662     uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11);
20663     uint32_t dr = (0x8421 * old_r5) >> 4;
20664     uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5);
20665     uint32_t dg = (0x1041 * old_g6) >> 2;
20666     uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0);
20667     uint32_t db = (0x8421 * old_b5) >> 4;
20668 
20669     // Calculate the inverse of the src-alpha: how much of the dst to keep.
20670     uint32_t ia = 0xFFFF - sa;
20671 
20672     // Composite src (premul) over dst (premul).
20673     dr = sr + ((dr * ia) / 0xFFFF);
20674     dg = sg + ((dg * ia) / 0xFFFF);
20675     db = sb + ((db * ia) / 0xFFFF);
20676 
20677     // Convert from 16-bit color to 565 color and combine the components.
20678     uint32_t new_r5 = 0x1F & (dr >> 11);
20679     uint32_t new_g6 = 0x3F & (dg >> 10);
20680     uint32_t new_b5 = 0x1F & (db >> 11);
20681     uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0);
20682     wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565);
20683 
20684     s += 1 * 4;
20685     d += 1 * 2;
20686     n -= 1;
20687   }
20688 
20689   return len;
20690 }
20691 
20692 static uint64_t  //
wuffs_base__pixel_swizzler__bgr_565__rgb(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)20693 wuffs_base__pixel_swizzler__bgr_565__rgb(uint8_t* dst_ptr,
20694                                          size_t dst_len,
20695                                          uint8_t* dst_palette_ptr,
20696                                          size_t dst_palette_len,
20697                                          const uint8_t* src_ptr,
20698                                          size_t src_len) {
20699   size_t dst_len2 = dst_len / 2;
20700   size_t src_len3 = src_len / 3;
20701   size_t len = (dst_len2 < src_len3) ? dst_len2 : src_len3;
20702   uint8_t* d = dst_ptr;
20703   const uint8_t* s = src_ptr;
20704   size_t n = len;
20705 
20706   // TODO: unroll.
20707 
20708   while (n >= 1) {
20709     uint32_t r5 = s[0] >> 3;
20710     uint32_t g6 = s[1] >> 2;
20711     uint32_t b5 = s[2] >> 3;
20712     uint32_t rgb_565 = (r5 << 11) | (g6 << 5) | (b5 << 0);
20713     wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565);
20714 
20715     s += 1 * 3;
20716     d += 1 * 2;
20717     n -= 1;
20718   }
20719 
20720   return len;
20721 }
20722 
20723 static uint64_t  //
wuffs_base__pixel_swizzler__bgr_565__rgba_nonpremul__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)20724 wuffs_base__pixel_swizzler__bgr_565__rgba_nonpremul__src(
20725     uint8_t* dst_ptr,
20726     size_t dst_len,
20727     uint8_t* dst_palette_ptr,
20728     size_t dst_palette_len,
20729     const uint8_t* src_ptr,
20730     size_t src_len) {
20731   size_t dst_len2 = dst_len / 2;
20732   size_t src_len4 = src_len / 4;
20733   size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
20734   uint8_t* d = dst_ptr;
20735   const uint8_t* s = src_ptr;
20736   size_t n = len;
20737 
20738   // TODO: unroll.
20739 
20740   while (n >= 1) {
20741     wuffs_base__poke_u16le__no_bounds_check(
20742         d + (0 * 2),
20743         wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
20744             wuffs_base__swap_u32_argb_abgr(
20745                 wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
20746                     wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))))));
20747 
20748     s += 1 * 4;
20749     d += 1 * 2;
20750     n -= 1;
20751   }
20752 
20753   return len;
20754 }
20755 
20756 static uint64_t  //
wuffs_base__pixel_swizzler__bgr_565__rgba_nonpremul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)20757 wuffs_base__pixel_swizzler__bgr_565__rgba_nonpremul__src_over(
20758     uint8_t* dst_ptr,
20759     size_t dst_len,
20760     uint8_t* dst_palette_ptr,
20761     size_t dst_palette_len,
20762     const uint8_t* src_ptr,
20763     size_t src_len) {
20764   size_t dst_len2 = dst_len / 2;
20765   size_t src_len4 = src_len / 4;
20766   size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
20767   uint8_t* d = dst_ptr;
20768   const uint8_t* s = src_ptr;
20769   size_t n = len;
20770 
20771   // TODO: unroll.
20772 
20773   while (n >= 1) {
20774     // Extract 16-bit color components.
20775     uint32_t sa = 0x101 * ((uint32_t)s[3]);
20776     uint32_t sb = 0x101 * ((uint32_t)s[2]);
20777     uint32_t sg = 0x101 * ((uint32_t)s[1]);
20778     uint32_t sr = 0x101 * ((uint32_t)s[0]);
20779 
20780     // Convert from 565 color to 16-bit color.
20781     uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2));
20782     uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11);
20783     uint32_t dr = (0x8421 * old_r5) >> 4;
20784     uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5);
20785     uint32_t dg = (0x1041 * old_g6) >> 2;
20786     uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0);
20787     uint32_t db = (0x8421 * old_b5) >> 4;
20788 
20789     // Calculate the inverse of the src-alpha: how much of the dst to keep.
20790     uint32_t ia = 0xFFFF - sa;
20791 
20792     // Composite src (nonpremul) over dst (premul).
20793     dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
20794     dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
20795     db = ((sb * sa) + (db * ia)) / 0xFFFF;
20796 
20797     // Convert from 16-bit color to 565 color and combine the components.
20798     uint32_t new_r5 = 0x1F & (dr >> 11);
20799     uint32_t new_g6 = 0x3F & (dg >> 10);
20800     uint32_t new_b5 = 0x1F & (db >> 11);
20801     uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0);
20802     wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565);
20803 
20804     s += 1 * 4;
20805     d += 1 * 2;
20806     n -= 1;
20807   }
20808 
20809   return len;
20810 }
20811 
20812 static uint64_t  //
wuffs_base__pixel_swizzler__bgr_565__rgba_premul__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)20813 wuffs_base__pixel_swizzler__bgr_565__rgba_premul__src(uint8_t* dst_ptr,
20814                                                       size_t dst_len,
20815                                                       uint8_t* dst_palette_ptr,
20816                                                       size_t dst_palette_len,
20817                                                       const uint8_t* src_ptr,
20818                                                       size_t src_len) {
20819   size_t dst_len2 = dst_len / 2;
20820   size_t src_len4 = src_len / 4;
20821   size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
20822   uint8_t* d = dst_ptr;
20823   const uint8_t* s = src_ptr;
20824   size_t n = len;
20825 
20826   // TODO: unroll.
20827 
20828   while (n >= 1) {
20829     wuffs_base__poke_u16le__no_bounds_check(
20830         d + (0 * 2),
20831         wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
20832             wuffs_base__swap_u32_argb_abgr(
20833                 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)))));
20834 
20835     s += 1 * 4;
20836     d += 1 * 2;
20837     n -= 1;
20838   }
20839 
20840   return len;
20841 }
20842 
20843 static uint64_t  //
wuffs_base__pixel_swizzler__bgr_565__rgba_premul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)20844 wuffs_base__pixel_swizzler__bgr_565__rgba_premul__src_over(
20845     uint8_t* dst_ptr,
20846     size_t dst_len,
20847     uint8_t* dst_palette_ptr,
20848     size_t dst_palette_len,
20849     const uint8_t* src_ptr,
20850     size_t src_len) {
20851   size_t dst_len2 = dst_len / 2;
20852   size_t src_len4 = src_len / 4;
20853   size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
20854   uint8_t* d = dst_ptr;
20855   const uint8_t* s = src_ptr;
20856   size_t n = len;
20857 
20858   // TODO: unroll.
20859 
20860   while (n >= 1) {
20861     // Extract 16-bit color components.
20862     uint32_t sa = 0x101 * ((uint32_t)s[3]);
20863     uint32_t sb = 0x101 * ((uint32_t)s[2]);
20864     uint32_t sg = 0x101 * ((uint32_t)s[1]);
20865     uint32_t sr = 0x101 * ((uint32_t)s[0]);
20866 
20867     // Convert from 565 color to 16-bit color.
20868     uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2));
20869     uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11);
20870     uint32_t dr = (0x8421 * old_r5) >> 4;
20871     uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5);
20872     uint32_t dg = (0x1041 * old_g6) >> 2;
20873     uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0);
20874     uint32_t db = (0x8421 * old_b5) >> 4;
20875 
20876     // Calculate the inverse of the src-alpha: how much of the dst to keep.
20877     uint32_t ia = 0xFFFF - sa;
20878 
20879     // Composite src (premul) over dst (premul).
20880     dr = sr + ((dr * ia) / 0xFFFF);
20881     dg = sg + ((dg * ia) / 0xFFFF);
20882     db = sb + ((db * ia) / 0xFFFF);
20883 
20884     // Convert from 16-bit color to 565 color and combine the components.
20885     uint32_t new_r5 = 0x1F & (dr >> 11);
20886     uint32_t new_g6 = 0x3F & (dg >> 10);
20887     uint32_t new_b5 = 0x1F & (db >> 11);
20888     uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0);
20889     wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565);
20890 
20891     s += 1 * 4;
20892     d += 1 * 2;
20893     n -= 1;
20894   }
20895 
20896   return len;
20897 }
20898 
20899 static uint64_t  //
wuffs_base__pixel_swizzler__bgr_565__y(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)20900 wuffs_base__pixel_swizzler__bgr_565__y(uint8_t* dst_ptr,
20901                                        size_t dst_len,
20902                                        uint8_t* dst_palette_ptr,
20903                                        size_t dst_palette_len,
20904                                        const uint8_t* src_ptr,
20905                                        size_t src_len) {
20906   size_t dst_len2 = dst_len / 2;
20907   size_t len = (dst_len2 < src_len) ? dst_len2 : src_len;
20908   uint8_t* d = dst_ptr;
20909   const uint8_t* s = src_ptr;
20910   size_t n = len;
20911 
20912   // TODO: unroll.
20913 
20914   while (n >= 1) {
20915     uint32_t y5 = s[0] >> 3;
20916     uint32_t y6 = s[0] >> 2;
20917     uint32_t rgb_565 = (y5 << 11) | (y6 << 5) | (y5 << 0);
20918     wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565);
20919 
20920     s += 1 * 1;
20921     d += 1 * 2;
20922     n -= 1;
20923   }
20924 
20925   return len;
20926 }
20927 
20928 static uint64_t  //
wuffs_base__pixel_swizzler__bgr_565__y_16be(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)20929 wuffs_base__pixel_swizzler__bgr_565__y_16be(uint8_t* dst_ptr,
20930                                             size_t dst_len,
20931                                             uint8_t* dst_palette_ptr,
20932                                             size_t dst_palette_len,
20933                                             const uint8_t* src_ptr,
20934                                             size_t src_len) {
20935   size_t dst_len2 = dst_len / 2;
20936   size_t src_len2 = src_len / 2;
20937   size_t len = (dst_len2 < src_len2) ? dst_len2 : src_len2;
20938   uint8_t* d = dst_ptr;
20939   const uint8_t* s = src_ptr;
20940   size_t n = len;
20941 
20942   // TODO: unroll.
20943 
20944   while (n >= 1) {
20945     uint32_t y5 = s[0] >> 3;
20946     uint32_t y6 = s[0] >> 2;
20947     uint32_t rgb_565 = (y5 << 11) | (y6 << 5) | (y5 << 0);
20948     wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565);
20949 
20950     s += 1 * 2;
20951     d += 1 * 2;
20952     n -= 1;
20953   }
20954 
20955   return len;
20956 }
20957 
20958 static uint64_t  //
wuffs_base__pixel_swizzler__bgr_565__index__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)20959 wuffs_base__pixel_swizzler__bgr_565__index__src(uint8_t* dst_ptr,
20960                                                 size_t dst_len,
20961                                                 uint8_t* dst_palette_ptr,
20962                                                 size_t dst_palette_len,
20963                                                 const uint8_t* src_ptr,
20964                                                 size_t src_len) {
20965   if (dst_palette_len !=
20966       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
20967     return 0;
20968   }
20969   size_t dst_len2 = dst_len / 2;
20970   size_t len = (dst_len2 < src_len) ? dst_len2 : src_len;
20971   uint8_t* d = dst_ptr;
20972   const uint8_t* s = src_ptr;
20973   size_t n = len;
20974 
20975   const size_t loop_unroll_count = 4;
20976 
20977   while (n >= loop_unroll_count) {
20978     wuffs_base__poke_u16le__no_bounds_check(
20979         d + (0 * 2), wuffs_base__peek_u16le__no_bounds_check(
20980                          dst_palette_ptr + ((size_t)s[0] * 4)));
20981     wuffs_base__poke_u16le__no_bounds_check(
20982         d + (1 * 2), wuffs_base__peek_u16le__no_bounds_check(
20983                          dst_palette_ptr + ((size_t)s[1] * 4)));
20984     wuffs_base__poke_u16le__no_bounds_check(
20985         d + (2 * 2), wuffs_base__peek_u16le__no_bounds_check(
20986                          dst_palette_ptr + ((size_t)s[2] * 4)));
20987     wuffs_base__poke_u16le__no_bounds_check(
20988         d + (3 * 2), wuffs_base__peek_u16le__no_bounds_check(
20989                          dst_palette_ptr + ((size_t)s[3] * 4)));
20990 
20991     s += loop_unroll_count * 1;
20992     d += loop_unroll_count * 2;
20993     n -= loop_unroll_count;
20994   }
20995 
20996   while (n >= 1) {
20997     wuffs_base__poke_u16le__no_bounds_check(
20998         d + (0 * 2), wuffs_base__peek_u16le__no_bounds_check(
20999                          dst_palette_ptr + ((size_t)s[0] * 4)));
21000 
21001     s += 1 * 1;
21002     d += 1 * 2;
21003     n -= 1;
21004   }
21005 
21006   return len;
21007 }
21008 
21009 static uint64_t  //
wuffs_base__pixel_swizzler__bgr_565__index_bgra_nonpremul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)21010 wuffs_base__pixel_swizzler__bgr_565__index_bgra_nonpremul__src_over(
21011     uint8_t* dst_ptr,
21012     size_t dst_len,
21013     uint8_t* dst_palette_ptr,
21014     size_t dst_palette_len,
21015     const uint8_t* src_ptr,
21016     size_t src_len) {
21017   if (dst_palette_len !=
21018       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
21019     return 0;
21020   }
21021   size_t dst_len2 = dst_len / 2;
21022   size_t len = (dst_len2 < src_len) ? dst_len2 : src_len;
21023   uint8_t* d = dst_ptr;
21024   const uint8_t* s = src_ptr;
21025   size_t n = len;
21026 
21027   // TODO: unroll.
21028 
21029   while (n >= 1) {
21030     uint32_t d0 = wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
21031         wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2)));
21032     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
21033                                                           ((size_t)s[0] * 4));
21034     wuffs_base__poke_u16le__no_bounds_check(
21035         d + (0 * 2),
21036         wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
21037             wuffs_base__composite_premul_nonpremul_u32_axxx(d0, s0)));
21038 
21039     s += 1 * 1;
21040     d += 1 * 2;
21041     n -= 1;
21042   }
21043 
21044   return len;
21045 }
21046 
21047 static uint64_t  //
wuffs_base__pixel_swizzler__bgr_565__index_binary_alpha__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)21048 wuffs_base__pixel_swizzler__bgr_565__index_binary_alpha__src_over(
21049     uint8_t* dst_ptr,
21050     size_t dst_len,
21051     uint8_t* dst_palette_ptr,
21052     size_t dst_palette_len,
21053     const uint8_t* src_ptr,
21054     size_t src_len) {
21055   if (dst_palette_len !=
21056       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
21057     return 0;
21058   }
21059   size_t dst_len2 = dst_len / 2;
21060   size_t len = (dst_len2 < src_len) ? dst_len2 : src_len;
21061   uint8_t* d = dst_ptr;
21062   const uint8_t* s = src_ptr;
21063   size_t n = len;
21064 
21065   // TODO: unroll.
21066 
21067   while (n >= 1) {
21068     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
21069                                                           ((size_t)s[0] * 4));
21070     if (s0) {
21071       wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)s0);
21072     }
21073 
21074     s += 1 * 1;
21075     d += 1 * 2;
21076     n -= 1;
21077   }
21078 
21079   return len;
21080 }
21081 
21082 // --------
21083 
21084 static uint64_t  //
wuffs_base__pixel_swizzler__bgr__bgr_565(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)21085 wuffs_base__pixel_swizzler__bgr__bgr_565(uint8_t* dst_ptr,
21086                                          size_t dst_len,
21087                                          uint8_t* dst_palette_ptr,
21088                                          size_t dst_palette_len,
21089                                          const uint8_t* src_ptr,
21090                                          size_t src_len) {
21091   size_t dst_len3 = dst_len / 3;
21092   size_t src_len2 = src_len / 2;
21093   size_t len = (dst_len3 < src_len2) ? dst_len3 : src_len2;
21094   uint8_t* d = dst_ptr;
21095   const uint8_t* s = src_ptr;
21096   size_t n = len;
21097 
21098   // TODO: unroll.
21099 
21100   while (n >= 1) {
21101     uint32_t s0 = wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
21102         wuffs_base__peek_u16le__no_bounds_check(s + (0 * 2)));
21103     wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
21104 
21105     s += 1 * 2;
21106     d += 1 * 3;
21107     n -= 1;
21108   }
21109 
21110   return len;
21111 }
21112 
21113 static uint64_t  //
wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)21114 wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src(uint8_t* dst_ptr,
21115                                                      size_t dst_len,
21116                                                      uint8_t* dst_palette_ptr,
21117                                                      size_t dst_palette_len,
21118                                                      const uint8_t* src_ptr,
21119                                                      size_t src_len) {
21120   size_t dst_len3 = dst_len / 3;
21121   size_t src_len4 = src_len / 4;
21122   size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
21123   uint8_t* d = dst_ptr;
21124   const uint8_t* s = src_ptr;
21125   size_t n = len;
21126 
21127   // TODO: unroll.
21128 
21129   while (n >= 1) {
21130     uint32_t s0 =
21131         wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
21132             wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
21133     wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
21134 
21135     s += 1 * 4;
21136     d += 1 * 3;
21137     n -= 1;
21138   }
21139 
21140   return len;
21141 }
21142 
21143 static uint64_t  //
wuffs_base__pixel_swizzler__bgr__bgra_nonpremul_4x16le__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)21144 wuffs_base__pixel_swizzler__bgr__bgra_nonpremul_4x16le__src(
21145     uint8_t* dst_ptr,
21146     size_t dst_len,
21147     uint8_t* dst_palette_ptr,
21148     size_t dst_palette_len,
21149     const uint8_t* src_ptr,
21150     size_t src_len) {
21151   size_t dst_len3 = dst_len / 3;
21152   size_t src_len8 = src_len / 8;
21153   size_t len = (dst_len3 < src_len8) ? dst_len3 : src_len8;
21154   uint8_t* d = dst_ptr;
21155   const uint8_t* s = src_ptr;
21156   size_t n = len;
21157 
21158   // TODO: unroll.
21159 
21160   while (n >= 1) {
21161     uint32_t s0 =
21162         wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(
21163             wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)));
21164     wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
21165 
21166     s += 1 * 8;
21167     d += 1 * 3;
21168     n -= 1;
21169   }
21170 
21171   return len;
21172 }
21173 
21174 static uint64_t  //
wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)21175 wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src_over(
21176     uint8_t* dst_ptr,
21177     size_t dst_len,
21178     uint8_t* dst_palette_ptr,
21179     size_t dst_palette_len,
21180     const uint8_t* src_ptr,
21181     size_t src_len) {
21182   size_t dst_len3 = dst_len / 3;
21183   size_t src_len4 = src_len / 4;
21184   size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
21185   uint8_t* d = dst_ptr;
21186   const uint8_t* s = src_ptr;
21187   size_t n = len;
21188 
21189   // TODO: unroll.
21190 
21191   while (n >= 1) {
21192     // Extract 16-bit color components.
21193     uint32_t dr = 0x101 * ((uint32_t)d[2]);
21194     uint32_t dg = 0x101 * ((uint32_t)d[1]);
21195     uint32_t db = 0x101 * ((uint32_t)d[0]);
21196     uint32_t sa = 0x101 * ((uint32_t)s[3]);
21197     uint32_t sr = 0x101 * ((uint32_t)s[2]);
21198     uint32_t sg = 0x101 * ((uint32_t)s[1]);
21199     uint32_t sb = 0x101 * ((uint32_t)s[0]);
21200 
21201     // Calculate the inverse of the src-alpha: how much of the dst to keep.
21202     uint32_t ia = 0xFFFF - sa;
21203 
21204     // Composite src (nonpremul) over dst (premul).
21205     dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
21206     dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
21207     db = ((sb * sa) + (db * ia)) / 0xFFFF;
21208 
21209     // Convert from 16-bit color to 8-bit color.
21210     d[0] = (uint8_t)(db >> 8);
21211     d[1] = (uint8_t)(dg >> 8);
21212     d[2] = (uint8_t)(dr >> 8);
21213 
21214     s += 1 * 4;
21215     d += 1 * 3;
21216     n -= 1;
21217   }
21218 
21219   return len;
21220 }
21221 
21222 static uint64_t  //
wuffs_base__pixel_swizzler__bgr__bgra_nonpremul_4x16le__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)21223 wuffs_base__pixel_swizzler__bgr__bgra_nonpremul_4x16le__src_over(
21224     uint8_t* dst_ptr,
21225     size_t dst_len,
21226     uint8_t* dst_palette_ptr,
21227     size_t dst_palette_len,
21228     const uint8_t* src_ptr,
21229     size_t src_len) {
21230   size_t dst_len3 = dst_len / 3;
21231   size_t src_len8 = src_len / 8;
21232   size_t len = (dst_len3 < src_len8) ? dst_len3 : src_len8;
21233   uint8_t* d = dst_ptr;
21234   const uint8_t* s = src_ptr;
21235   size_t n = len;
21236 
21237   // TODO: unroll.
21238 
21239   while (n >= 1) {
21240     // Extract 16-bit color components.
21241     uint32_t dr = 0x101 * ((uint32_t)d[2]);
21242     uint32_t dg = 0x101 * ((uint32_t)d[1]);
21243     uint32_t db = 0x101 * ((uint32_t)d[0]);
21244     uint32_t sa = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 6));
21245     uint32_t sr = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 4));
21246     uint32_t sg = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 2));
21247     uint32_t sb = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 0));
21248 
21249     // Calculate the inverse of the src-alpha: how much of the dst to keep.
21250     uint32_t ia = 0xFFFF - sa;
21251 
21252     // Composite src (nonpremul) over dst (premul).
21253     dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
21254     dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
21255     db = ((sb * sa) + (db * ia)) / 0xFFFF;
21256 
21257     // Convert from 16-bit color to 8-bit color.
21258     d[0] = (uint8_t)(db >> 8);
21259     d[1] = (uint8_t)(dg >> 8);
21260     d[2] = (uint8_t)(dr >> 8);
21261 
21262     s += 1 * 8;
21263     d += 1 * 3;
21264     n -= 1;
21265   }
21266 
21267   return len;
21268 }
21269 
21270 static uint64_t  //
wuffs_base__pixel_swizzler__bgr__bgra_premul__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)21271 wuffs_base__pixel_swizzler__bgr__bgra_premul__src(uint8_t* dst_ptr,
21272                                                   size_t dst_len,
21273                                                   uint8_t* dst_palette_ptr,
21274                                                   size_t dst_palette_len,
21275                                                   const uint8_t* src_ptr,
21276                                                   size_t src_len) {
21277   size_t dst_len3 = dst_len / 3;
21278   size_t src_len4 = src_len / 4;
21279   size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
21280   uint8_t* d = dst_ptr;
21281   const uint8_t* s = src_ptr;
21282   size_t n = len;
21283 
21284   while (n >= 1) {
21285     uint8_t s0 = s[0];
21286     uint8_t s1 = s[1];
21287     uint8_t s2 = s[2];
21288     d[0] = s0;
21289     d[1] = s1;
21290     d[2] = s2;
21291 
21292     s += 1 * 4;
21293     d += 1 * 3;
21294     n -= 1;
21295   }
21296 
21297   return len;
21298 }
21299 
21300 static uint64_t  //
wuffs_base__pixel_swizzler__bgr__bgra_premul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)21301 wuffs_base__pixel_swizzler__bgr__bgra_premul__src_over(uint8_t* dst_ptr,
21302                                                        size_t dst_len,
21303                                                        uint8_t* dst_palette_ptr,
21304                                                        size_t dst_palette_len,
21305                                                        const uint8_t* src_ptr,
21306                                                        size_t src_len) {
21307   size_t dst_len3 = dst_len / 3;
21308   size_t src_len4 = src_len / 4;
21309   size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
21310   uint8_t* d = dst_ptr;
21311   const uint8_t* s = src_ptr;
21312   size_t n = len;
21313 
21314   while (n >= 1) {
21315     // Extract 16-bit color components.
21316     uint32_t dr = 0x101 * ((uint32_t)d[2]);
21317     uint32_t dg = 0x101 * ((uint32_t)d[1]);
21318     uint32_t db = 0x101 * ((uint32_t)d[0]);
21319     uint32_t sa = 0x101 * ((uint32_t)s[3]);
21320     uint32_t sr = 0x101 * ((uint32_t)s[2]);
21321     uint32_t sg = 0x101 * ((uint32_t)s[1]);
21322     uint32_t sb = 0x101 * ((uint32_t)s[0]);
21323 
21324     // Calculate the inverse of the src-alpha: how much of the dst to keep.
21325     uint32_t ia = 0xFFFF - sa;
21326 
21327     // Composite src (premul) over dst (premul).
21328     dr = sr + ((dr * ia) / 0xFFFF);
21329     dg = sg + ((dg * ia) / 0xFFFF);
21330     db = sb + ((db * ia) / 0xFFFF);
21331 
21332     // Convert from 16-bit color to 8-bit color.
21333     d[0] = (uint8_t)(db >> 8);
21334     d[1] = (uint8_t)(dg >> 8);
21335     d[2] = (uint8_t)(dr >> 8);
21336 
21337     s += 1 * 4;
21338     d += 1 * 3;
21339     n -= 1;
21340   }
21341 
21342   return len;
21343 }
21344 
21345 static uint64_t  //
wuffs_base__pixel_swizzler__bgr__rgba_nonpremul__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)21346 wuffs_base__pixel_swizzler__bgr__rgba_nonpremul__src(uint8_t* dst_ptr,
21347                                                      size_t dst_len,
21348                                                      uint8_t* dst_palette_ptr,
21349                                                      size_t dst_palette_len,
21350                                                      const uint8_t* src_ptr,
21351                                                      size_t src_len) {
21352   size_t dst_len3 = dst_len / 3;
21353   size_t src_len4 = src_len / 4;
21354   size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
21355   uint8_t* d = dst_ptr;
21356   const uint8_t* s = src_ptr;
21357   size_t n = len;
21358 
21359   // TODO: unroll.
21360 
21361   while (n >= 1) {
21362     uint32_t s0 = wuffs_base__swap_u32_argb_abgr(
21363         wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
21364             wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))));
21365     wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
21366 
21367     s += 1 * 4;
21368     d += 1 * 3;
21369     n -= 1;
21370   }
21371 
21372   return len;
21373 }
21374 
21375 static uint64_t  //
wuffs_base__pixel_swizzler__bgr__rgba_nonpremul_4x16le__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)21376 wuffs_base__pixel_swizzler__bgr__rgba_nonpremul_4x16le__src(
21377     uint8_t* dst_ptr,
21378     size_t dst_len,
21379     uint8_t* dst_palette_ptr,
21380     size_t dst_palette_len,
21381     const uint8_t* src_ptr,
21382     size_t src_len) {
21383   size_t dst_len3 = dst_len / 3;
21384   size_t src_len8 = src_len / 8;
21385   size_t len = (dst_len3 < src_len8) ? dst_len3 : src_len8;
21386   uint8_t* d = dst_ptr;
21387   const uint8_t* s = src_ptr;
21388   size_t n = len;
21389 
21390   // TODO: unroll.
21391 
21392   while (n >= 1) {
21393     uint32_t s0 = wuffs_base__swap_u32_argb_abgr(
21394         wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(
21395             wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8))));
21396     wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
21397 
21398     s += 1 * 8;
21399     d += 1 * 3;
21400     n -= 1;
21401   }
21402 
21403   return len;
21404 }
21405 
21406 static uint64_t  //
wuffs_base__pixel_swizzler__bgr__rgba_nonpremul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)21407 wuffs_base__pixel_swizzler__bgr__rgba_nonpremul__src_over(
21408     uint8_t* dst_ptr,
21409     size_t dst_len,
21410     uint8_t* dst_palette_ptr,
21411     size_t dst_palette_len,
21412     const uint8_t* src_ptr,
21413     size_t src_len) {
21414   size_t dst_len3 = dst_len / 3;
21415   size_t src_len4 = src_len / 4;
21416   size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
21417   uint8_t* d = dst_ptr;
21418   const uint8_t* s = src_ptr;
21419   size_t n = len;
21420 
21421   // TODO: unroll.
21422 
21423   while (n >= 1) {
21424     // Extract 16-bit color components.
21425     uint32_t dr = 0x101 * ((uint32_t)d[2]);
21426     uint32_t dg = 0x101 * ((uint32_t)d[1]);
21427     uint32_t db = 0x101 * ((uint32_t)d[0]);
21428     uint32_t sa = 0x101 * ((uint32_t)s[3]);
21429     uint32_t sb = 0x101 * ((uint32_t)s[2]);
21430     uint32_t sg = 0x101 * ((uint32_t)s[1]);
21431     uint32_t sr = 0x101 * ((uint32_t)s[0]);
21432 
21433     // Calculate the inverse of the src-alpha: how much of the dst to keep.
21434     uint32_t ia = 0xFFFF - sa;
21435 
21436     // Composite src (nonpremul) over dst (premul).
21437     dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
21438     dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
21439     db = ((sb * sa) + (db * ia)) / 0xFFFF;
21440 
21441     // Convert from 16-bit color to 8-bit color.
21442     d[0] = (uint8_t)(db >> 8);
21443     d[1] = (uint8_t)(dg >> 8);
21444     d[2] = (uint8_t)(dr >> 8);
21445 
21446     s += 1 * 4;
21447     d += 1 * 3;
21448     n -= 1;
21449   }
21450 
21451   return len;
21452 }
21453 
21454 static uint64_t  //
wuffs_base__pixel_swizzler__bgr__rgba_nonpremul_4x16le__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)21455 wuffs_base__pixel_swizzler__bgr__rgba_nonpremul_4x16le__src_over(
21456     uint8_t* dst_ptr,
21457     size_t dst_len,
21458     uint8_t* dst_palette_ptr,
21459     size_t dst_palette_len,
21460     const uint8_t* src_ptr,
21461     size_t src_len) {
21462   size_t dst_len3 = dst_len / 3;
21463   size_t src_len8 = src_len / 8;
21464   size_t len = (dst_len3 < src_len8) ? dst_len3 : src_len8;
21465   uint8_t* d = dst_ptr;
21466   const uint8_t* s = src_ptr;
21467   size_t n = len;
21468 
21469   // TODO: unroll.
21470 
21471   while (n >= 1) {
21472     // Extract 16-bit color components.
21473     uint32_t dr = 0x101 * ((uint32_t)d[2]);
21474     uint32_t dg = 0x101 * ((uint32_t)d[1]);
21475     uint32_t db = 0x101 * ((uint32_t)d[0]);
21476     uint32_t sa = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 6));
21477     uint32_t sb = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 4));
21478     uint32_t sg = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 2));
21479     uint32_t sr = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 0));
21480 
21481     // Calculate the inverse of the src-alpha: how much of the dst to keep.
21482     uint32_t ia = 0xFFFF - sa;
21483 
21484     // Composite src (nonpremul) over dst (premul).
21485     dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
21486     dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
21487     db = ((sb * sa) + (db * ia)) / 0xFFFF;
21488 
21489     // Convert from 16-bit color to 8-bit color.
21490     d[0] = (uint8_t)(db >> 8);
21491     d[1] = (uint8_t)(dg >> 8);
21492     d[2] = (uint8_t)(dr >> 8);
21493 
21494     s += 1 * 8;
21495     d += 1 * 3;
21496     n -= 1;
21497   }
21498 
21499   return len;
21500 }
21501 
21502 static uint64_t  //
wuffs_base__pixel_swizzler__bgr__rgba_premul__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)21503 wuffs_base__pixel_swizzler__bgr__rgba_premul__src(uint8_t* dst_ptr,
21504                                                   size_t dst_len,
21505                                                   uint8_t* dst_palette_ptr,
21506                                                   size_t dst_palette_len,
21507                                                   const uint8_t* src_ptr,
21508                                                   size_t src_len) {
21509   size_t dst_len3 = dst_len / 3;
21510   size_t src_len4 = src_len / 4;
21511   size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
21512   uint8_t* d = dst_ptr;
21513   const uint8_t* s = src_ptr;
21514   size_t n = len;
21515 
21516   while (n >= 1) {
21517     uint8_t s0 = s[0];
21518     uint8_t s1 = s[1];
21519     uint8_t s2 = s[2];
21520     d[0] = s2;
21521     d[1] = s1;
21522     d[2] = s0;
21523 
21524     s += 1 * 4;
21525     d += 1 * 3;
21526     n -= 1;
21527   }
21528 
21529   return len;
21530 }
21531 
21532 static uint64_t  //
wuffs_base__pixel_swizzler__bgr__rgba_premul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)21533 wuffs_base__pixel_swizzler__bgr__rgba_premul__src_over(uint8_t* dst_ptr,
21534                                                        size_t dst_len,
21535                                                        uint8_t* dst_palette_ptr,
21536                                                        size_t dst_palette_len,
21537                                                        const uint8_t* src_ptr,
21538                                                        size_t src_len) {
21539   size_t dst_len3 = dst_len / 3;
21540   size_t src_len4 = src_len / 4;
21541   size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
21542   uint8_t* d = dst_ptr;
21543   const uint8_t* s = src_ptr;
21544   size_t n = len;
21545 
21546   while (n >= 1) {
21547     // Extract 16-bit color components.
21548     uint32_t dr = 0x101 * ((uint32_t)d[2]);
21549     uint32_t dg = 0x101 * ((uint32_t)d[1]);
21550     uint32_t db = 0x101 * ((uint32_t)d[0]);
21551     uint32_t sa = 0x101 * ((uint32_t)s[3]);
21552     uint32_t sb = 0x101 * ((uint32_t)s[2]);
21553     uint32_t sg = 0x101 * ((uint32_t)s[1]);
21554     uint32_t sr = 0x101 * ((uint32_t)s[0]);
21555 
21556     // Calculate the inverse of the src-alpha: how much of the dst to keep.
21557     uint32_t ia = 0xFFFF - sa;
21558 
21559     // Composite src (premul) over dst (premul).
21560     dr = sr + ((dr * ia) / 0xFFFF);
21561     dg = sg + ((dg * ia) / 0xFFFF);
21562     db = sb + ((db * ia) / 0xFFFF);
21563 
21564     // Convert from 16-bit color to 8-bit color.
21565     d[0] = (uint8_t)(db >> 8);
21566     d[1] = (uint8_t)(dg >> 8);
21567     d[2] = (uint8_t)(dr >> 8);
21568 
21569     s += 1 * 4;
21570     d += 1 * 3;
21571     n -= 1;
21572   }
21573 
21574   return len;
21575 }
21576 
21577 static uint64_t  //
wuffs_base__pixel_swizzler__bgr__rgbx(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)21578 wuffs_base__pixel_swizzler__bgr__rgbx(uint8_t* dst_ptr,
21579                                       size_t dst_len,
21580                                       uint8_t* dst_palette_ptr,
21581                                       size_t dst_palette_len,
21582                                       const uint8_t* src_ptr,
21583                                       size_t src_len) {
21584   size_t dst_len3 = dst_len / 3;
21585   size_t src_len4 = src_len / 4;
21586   size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
21587   uint8_t* d = dst_ptr;
21588   const uint8_t* s = src_ptr;
21589   size_t n = len;
21590 
21591   // TODO: unroll.
21592 
21593   while (n >= 1) {
21594     uint8_t b0 = s[0];
21595     uint8_t b1 = s[1];
21596     uint8_t b2 = s[2];
21597     d[0] = b2;
21598     d[1] = b1;
21599     d[2] = b0;
21600 
21601     s += 1 * 4;
21602     d += 1 * 3;
21603     n -= 1;
21604   }
21605 
21606   return len;
21607 }
21608 
21609 // --------
21610 
21611 static uint64_t  //
wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)21612 wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul__src_over(
21613     uint8_t* dst_ptr,
21614     size_t dst_len,
21615     uint8_t* dst_palette_ptr,
21616     size_t dst_palette_len,
21617     const uint8_t* src_ptr,
21618     size_t src_len) {
21619   size_t dst_len4 = dst_len / 4;
21620   size_t src_len4 = src_len / 4;
21621   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
21622   uint8_t* d = dst_ptr;
21623   const uint8_t* s = src_ptr;
21624   size_t n = len;
21625 
21626   while (n >= 1) {
21627     uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
21628     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
21629     wuffs_base__poke_u32le__no_bounds_check(
21630         d + (0 * 4),
21631         wuffs_base__composite_nonpremul_nonpremul_u32_axxx(d0, s0));
21632 
21633     s += 1 * 4;
21634     d += 1 * 4;
21635     n -= 1;
21636   }
21637 
21638   return len;
21639 }
21640 
21641 static uint64_t  //
wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul_4x16le__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)21642 wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul_4x16le__src(
21643     uint8_t* dst_ptr,
21644     size_t dst_len,
21645     uint8_t* dst_palette_ptr,
21646     size_t dst_palette_len,
21647     const uint8_t* src_ptr,
21648     size_t src_len) {
21649   size_t dst_len4 = dst_len / 4;
21650   size_t src_len8 = src_len / 8;
21651   size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
21652   uint8_t* d = dst_ptr;
21653   const uint8_t* s = src_ptr;
21654 
21655   size_t n = len;
21656   while (n >= 1) {
21657     wuffs_base__poke_u32le__no_bounds_check(
21658         d + (0 * 4), wuffs_base__color_u64__as__color_u32(
21659                          wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8))));
21660 
21661     s += 1 * 8;
21662     d += 1 * 4;
21663     n -= 1;
21664   }
21665   return len;
21666 }
21667 
21668 static uint64_t  //
wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul_4x16le__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)21669 wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul_4x16le__src_over(
21670     uint8_t* dst_ptr,
21671     size_t dst_len,
21672     uint8_t* dst_palette_ptr,
21673     size_t dst_palette_len,
21674     const uint8_t* src_ptr,
21675     size_t src_len) {
21676   size_t dst_len4 = dst_len / 4;
21677   size_t src_len8 = src_len / 8;
21678   size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
21679   uint8_t* d = dst_ptr;
21680   const uint8_t* s = src_ptr;
21681   size_t n = len;
21682 
21683   while (n >= 1) {
21684     uint64_t d0 = wuffs_base__color_u32__as__color_u64(
21685         wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)));
21686     uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8));
21687     wuffs_base__poke_u32le__no_bounds_check(
21688         d + (0 * 4),
21689         wuffs_base__color_u64__as__color_u32(
21690             wuffs_base__composite_nonpremul_nonpremul_u64_axxx(d0, s0)));
21691 
21692     s += 1 * 8;
21693     d += 1 * 4;
21694     n -= 1;
21695   }
21696 
21697   return len;
21698 }
21699 
21700 static uint64_t  //
wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)21701 wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src(
21702     uint8_t* dst_ptr,
21703     size_t dst_len,
21704     uint8_t* dst_palette_ptr,
21705     size_t dst_palette_len,
21706     const uint8_t* src_ptr,
21707     size_t src_len) {
21708   size_t dst_len4 = dst_len / 4;
21709   size_t src_len4 = src_len / 4;
21710   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
21711   uint8_t* d = dst_ptr;
21712   const uint8_t* s = src_ptr;
21713   size_t n = len;
21714 
21715   while (n >= 1) {
21716     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
21717     wuffs_base__poke_u32le__no_bounds_check(
21718         d + (0 * 4),
21719         wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(s0));
21720 
21721     s += 1 * 4;
21722     d += 1 * 4;
21723     n -= 1;
21724   }
21725 
21726   return len;
21727 }
21728 
21729 static uint64_t  //
wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)21730 wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src_over(
21731     uint8_t* dst_ptr,
21732     size_t dst_len,
21733     uint8_t* dst_palette_ptr,
21734     size_t dst_palette_len,
21735     const uint8_t* src_ptr,
21736     size_t src_len) {
21737   size_t dst_len4 = dst_len / 4;
21738   size_t src_len4 = src_len / 4;
21739   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
21740   uint8_t* d = dst_ptr;
21741   const uint8_t* s = src_ptr;
21742   size_t n = len;
21743 
21744   while (n >= 1) {
21745     uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
21746     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
21747     wuffs_base__poke_u32le__no_bounds_check(
21748         d + (0 * 4), wuffs_base__composite_nonpremul_premul_u32_axxx(d0, s0));
21749 
21750     s += 1 * 4;
21751     d += 1 * 4;
21752     n -= 1;
21753   }
21754 
21755   return len;
21756 }
21757 
21758 static uint64_t  //
wuffs_base__pixel_swizzler__bgra_nonpremul__index_bgra_nonpremul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)21759 wuffs_base__pixel_swizzler__bgra_nonpremul__index_bgra_nonpremul__src_over(
21760     uint8_t* dst_ptr,
21761     size_t dst_len,
21762     uint8_t* dst_palette_ptr,
21763     size_t dst_palette_len,
21764     const uint8_t* src_ptr,
21765     size_t src_len) {
21766   if (dst_palette_len !=
21767       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
21768     return 0;
21769   }
21770   size_t dst_len4 = dst_len / 4;
21771   size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
21772   uint8_t* d = dst_ptr;
21773   const uint8_t* s = src_ptr;
21774   size_t n = len;
21775 
21776   // TODO: unroll.
21777 
21778   while (n >= 1) {
21779     uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
21780     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
21781                                                           ((size_t)s[0] * 4));
21782     wuffs_base__poke_u32le__no_bounds_check(
21783         d + (0 * 4),
21784         wuffs_base__composite_nonpremul_nonpremul_u32_axxx(d0, s0));
21785 
21786     s += 1 * 1;
21787     d += 1 * 4;
21788     n -= 1;
21789   }
21790 
21791   return len;
21792 }
21793 
21794 static uint64_t  //
wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_nonpremul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)21795 wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_nonpremul__src_over(
21796     uint8_t* dst_ptr,
21797     size_t dst_len,
21798     uint8_t* dst_palette_ptr,
21799     size_t dst_palette_len,
21800     const uint8_t* src_ptr,
21801     size_t src_len) {
21802   size_t dst_len4 = dst_len / 4;
21803   size_t src_len4 = src_len / 4;
21804   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
21805   uint8_t* d = dst_ptr;
21806   const uint8_t* s = src_ptr;
21807   size_t n = len;
21808 
21809   while (n >= 1) {
21810     uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
21811     uint32_t s0 = wuffs_base__swap_u32_argb_abgr(
21812         wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
21813     wuffs_base__poke_u32le__no_bounds_check(
21814         d + (0 * 4),
21815         wuffs_base__composite_nonpremul_nonpremul_u32_axxx(d0, s0));
21816 
21817     s += 1 * 4;
21818     d += 1 * 4;
21819     n -= 1;
21820   }
21821 
21822   return len;
21823 }
21824 
21825 static uint64_t  //
wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)21826 wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src(
21827     uint8_t* dst_ptr,
21828     size_t dst_len,
21829     uint8_t* dst_palette_ptr,
21830     size_t dst_palette_len,
21831     const uint8_t* src_ptr,
21832     size_t src_len) {
21833   size_t dst_len4 = dst_len / 4;
21834   size_t src_len4 = src_len / 4;
21835   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
21836   uint8_t* d = dst_ptr;
21837   const uint8_t* s = src_ptr;
21838   size_t n = len;
21839 
21840   while (n >= 1) {
21841     uint32_t s0 = wuffs_base__swap_u32_argb_abgr(
21842         wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
21843     wuffs_base__poke_u32le__no_bounds_check(
21844         d + (0 * 4),
21845         wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(s0));
21846 
21847     s += 1 * 4;
21848     d += 1 * 4;
21849     n -= 1;
21850   }
21851 
21852   return len;
21853 }
21854 
21855 static uint64_t  //
wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)21856 wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src_over(
21857     uint8_t* dst_ptr,
21858     size_t dst_len,
21859     uint8_t* dst_palette_ptr,
21860     size_t dst_palette_len,
21861     const uint8_t* src_ptr,
21862     size_t src_len) {
21863   size_t dst_len4 = dst_len / 4;
21864   size_t src_len4 = src_len / 4;
21865   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
21866   uint8_t* d = dst_ptr;
21867   const uint8_t* s = src_ptr;
21868   size_t n = len;
21869 
21870   while (n >= 1) {
21871     uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
21872     uint32_t s0 = wuffs_base__swap_u32_argb_abgr(
21873         wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
21874     wuffs_base__poke_u32le__no_bounds_check(
21875         d + (0 * 4), wuffs_base__composite_nonpremul_premul_u32_axxx(d0, s0));
21876 
21877     s += 1 * 4;
21878     d += 1 * 4;
21879     n -= 1;
21880   }
21881 
21882   return len;
21883 }
21884 
21885 // --------
21886 
21887 static uint64_t  //
wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)21888 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul__src(
21889     uint8_t* dst_ptr,
21890     size_t dst_len,
21891     uint8_t* dst_palette_ptr,
21892     size_t dst_palette_len,
21893     const uint8_t* src_ptr,
21894     size_t src_len) {
21895   size_t dst_len8 = dst_len / 8;
21896   size_t src_len4 = src_len / 4;
21897   size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
21898   uint8_t* d = dst_ptr;
21899   const uint8_t* s = src_ptr;
21900 
21901   size_t n = len;
21902   while (n >= 1) {
21903     uint8_t s0 = s[0];
21904     uint8_t s1 = s[1];
21905     uint8_t s2 = s[2];
21906     uint8_t s3 = s[3];
21907     d[0] = s0;
21908     d[1] = s0;
21909     d[2] = s1;
21910     d[3] = s1;
21911     d[4] = s2;
21912     d[5] = s2;
21913     d[6] = s3;
21914     d[7] = s3;
21915 
21916     s += 1 * 4;
21917     d += 1 * 8;
21918     n -= 1;
21919   }
21920   return len;
21921 }
21922 
21923 static uint64_t  //
wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)21924 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul__src_over(
21925     uint8_t* dst_ptr,
21926     size_t dst_len,
21927     uint8_t* dst_palette_ptr,
21928     size_t dst_palette_len,
21929     const uint8_t* src_ptr,
21930     size_t src_len) {
21931   size_t dst_len8 = dst_len / 8;
21932   size_t src_len4 = src_len / 4;
21933   size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
21934   uint8_t* d = dst_ptr;
21935   const uint8_t* s = src_ptr;
21936 
21937   size_t n = len;
21938   while (n >= 1) {
21939     uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8));
21940     uint64_t s0 = wuffs_base__color_u32__as__color_u64(
21941         wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
21942     wuffs_base__poke_u64le__no_bounds_check(
21943         d + (0 * 8),
21944         wuffs_base__composite_nonpremul_nonpremul_u64_axxx(d0, s0));
21945 
21946     s += 1 * 4;
21947     d += 1 * 8;
21948     n -= 1;
21949   }
21950   return len;
21951 }
21952 
21953 static uint64_t  //
wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul_4x16le__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)21954 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul_4x16le__src_over(
21955     uint8_t* dst_ptr,
21956     size_t dst_len,
21957     uint8_t* dst_palette_ptr,
21958     size_t dst_palette_len,
21959     const uint8_t* src_ptr,
21960     size_t src_len) {
21961   size_t dst_len8 = dst_len / 8;
21962   size_t src_len8 = src_len / 8;
21963   size_t len = (dst_len8 < src_len8) ? dst_len8 : src_len8;
21964   uint8_t* d = dst_ptr;
21965   const uint8_t* s = src_ptr;
21966 
21967   size_t n = len;
21968   while (n >= 1) {
21969     uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8));
21970     uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8));
21971     wuffs_base__poke_u64le__no_bounds_check(
21972         d + (0 * 8),
21973         wuffs_base__composite_nonpremul_nonpremul_u64_axxx(d0, s0));
21974 
21975     s += 1 * 8;
21976     d += 1 * 8;
21977     n -= 1;
21978   }
21979   return len;
21980 }
21981 
21982 static uint64_t  //
wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_premul__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)21983 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_premul__src(
21984     uint8_t* dst_ptr,
21985     size_t dst_len,
21986     uint8_t* dst_palette_ptr,
21987     size_t dst_palette_len,
21988     const uint8_t* src_ptr,
21989     size_t src_len) {
21990   size_t dst_len8 = dst_len / 8;
21991   size_t src_len4 = src_len / 4;
21992   size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
21993   uint8_t* d = dst_ptr;
21994   const uint8_t* s = src_ptr;
21995 
21996   size_t n = len;
21997   while (n >= 1) {
21998     uint64_t s0 = wuffs_base__color_u32__as__color_u64(
21999         wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
22000             wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))));
22001     wuffs_base__poke_u64le__no_bounds_check(d + (0 * 8), s0);
22002 
22003     s += 1 * 4;
22004     d += 1 * 8;
22005     n -= 1;
22006   }
22007   return len;
22008 }
22009 
22010 static uint64_t  //
wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_premul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)22011 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_premul__src_over(
22012     uint8_t* dst_ptr,
22013     size_t dst_len,
22014     uint8_t* dst_palette_ptr,
22015     size_t dst_palette_len,
22016     const uint8_t* src_ptr,
22017     size_t src_len) {
22018   size_t dst_len8 = dst_len / 8;
22019   size_t src_len4 = src_len / 4;
22020   size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
22021   uint8_t* d = dst_ptr;
22022   const uint8_t* s = src_ptr;
22023 
22024   size_t n = len;
22025   while (n >= 1) {
22026     uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8));
22027     uint64_t s0 = wuffs_base__color_u32__as__color_u64(
22028         wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
22029     wuffs_base__poke_u64le__no_bounds_check(
22030         d + (0 * 8), wuffs_base__composite_nonpremul_premul_u64_axxx(d0, s0));
22031 
22032     s += 1 * 4;
22033     d += 1 * 8;
22034     n -= 1;
22035   }
22036   return len;
22037 }
22038 
22039 static uint64_t  //
wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__index_bgra_nonpremul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)22040 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__index_bgra_nonpremul__src_over(
22041     uint8_t* dst_ptr,
22042     size_t dst_len,
22043     uint8_t* dst_palette_ptr,
22044     size_t dst_palette_len,
22045     const uint8_t* src_ptr,
22046     size_t src_len) {
22047   if (dst_palette_len !=
22048       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
22049     return 0;
22050   }
22051   size_t dst_len8 = dst_len / 8;
22052   size_t len = (dst_len8 < src_len) ? dst_len8 : src_len;
22053   uint8_t* d = dst_ptr;
22054   const uint8_t* s = src_ptr;
22055   size_t n = len;
22056 
22057   while (n >= 1) {
22058     uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8));
22059     uint64_t s0 = wuffs_base__color_u32__as__color_u64(
22060         wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
22061                                                 ((size_t)s[0] * 4)));
22062     wuffs_base__poke_u64le__no_bounds_check(
22063         d + (0 * 8),
22064         wuffs_base__composite_nonpremul_nonpremul_u64_axxx(d0, s0));
22065 
22066     s += 1 * 1;
22067     d += 1 * 8;
22068     n -= 1;
22069   }
22070 
22071   return len;
22072 }
22073 
22074 static uint64_t  //
wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_nonpremul__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)22075 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_nonpremul__src(
22076     uint8_t* dst_ptr,
22077     size_t dst_len,
22078     uint8_t* dst_palette_ptr,
22079     size_t dst_palette_len,
22080     const uint8_t* src_ptr,
22081     size_t src_len) {
22082   size_t dst_len8 = dst_len / 8;
22083   size_t src_len4 = src_len / 4;
22084   size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
22085   uint8_t* d = dst_ptr;
22086   const uint8_t* s = src_ptr;
22087 
22088   size_t n = len;
22089   while (n >= 1) {
22090     uint8_t s0 = s[0];
22091     uint8_t s1 = s[1];
22092     uint8_t s2 = s[2];
22093     uint8_t s3 = s[3];
22094     d[0] = s2;
22095     d[1] = s2;
22096     d[2] = s1;
22097     d[3] = s1;
22098     d[4] = s0;
22099     d[5] = s0;
22100     d[6] = s3;
22101     d[7] = s3;
22102 
22103     s += 1 * 4;
22104     d += 1 * 8;
22105     n -= 1;
22106   }
22107   return len;
22108 }
22109 
22110 static uint64_t  //
wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_nonpremul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)22111 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_nonpremul__src_over(
22112     uint8_t* dst_ptr,
22113     size_t dst_len,
22114     uint8_t* dst_palette_ptr,
22115     size_t dst_palette_len,
22116     const uint8_t* src_ptr,
22117     size_t src_len) {
22118   size_t dst_len8 = dst_len / 8;
22119   size_t src_len4 = src_len / 4;
22120   size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
22121   uint8_t* d = dst_ptr;
22122   const uint8_t* s = src_ptr;
22123 
22124   size_t n = len;
22125   while (n >= 1) {
22126     uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8));
22127     uint64_t s0 =
22128         wuffs_base__color_u32__as__color_u64(wuffs_base__swap_u32_argb_abgr(
22129             wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))));
22130     wuffs_base__poke_u64le__no_bounds_check(
22131         d + (0 * 8),
22132         wuffs_base__composite_nonpremul_nonpremul_u64_axxx(d0, s0));
22133 
22134     s += 1 * 4;
22135     d += 1 * 8;
22136     n -= 1;
22137   }
22138   return len;
22139 }
22140 
22141 static uint64_t  //
wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_premul__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)22142 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_premul__src(
22143     uint8_t* dst_ptr,
22144     size_t dst_len,
22145     uint8_t* dst_palette_ptr,
22146     size_t dst_palette_len,
22147     const uint8_t* src_ptr,
22148     size_t src_len) {
22149   size_t dst_len8 = dst_len / 8;
22150   size_t src_len4 = src_len / 4;
22151   size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
22152   uint8_t* d = dst_ptr;
22153   const uint8_t* s = src_ptr;
22154 
22155   size_t n = len;
22156   while (n >= 1) {
22157     uint64_t s0 = wuffs_base__color_u32__as__color_u64(
22158         wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
22159             wuffs_base__swap_u32_argb_abgr(
22160                 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)))));
22161     wuffs_base__poke_u64le__no_bounds_check(d + (0 * 8), s0);
22162 
22163     s += 1 * 4;
22164     d += 1 * 8;
22165     n -= 1;
22166   }
22167   return len;
22168 }
22169 
22170 static uint64_t  //
wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_premul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)22171 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_premul__src_over(
22172     uint8_t* dst_ptr,
22173     size_t dst_len,
22174     uint8_t* dst_palette_ptr,
22175     size_t dst_palette_len,
22176     const uint8_t* src_ptr,
22177     size_t src_len) {
22178   size_t dst_len8 = dst_len / 8;
22179   size_t src_len4 = src_len / 4;
22180   size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
22181   uint8_t* d = dst_ptr;
22182   const uint8_t* s = src_ptr;
22183 
22184   size_t n = len;
22185   while (n >= 1) {
22186     uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8));
22187     uint64_t s0 =
22188         wuffs_base__color_u32__as__color_u64(wuffs_base__swap_u32_argb_abgr(
22189             wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))));
22190     wuffs_base__poke_u64le__no_bounds_check(
22191         d + (0 * 8), wuffs_base__composite_nonpremul_premul_u64_axxx(d0, s0));
22192 
22193     s += 1 * 4;
22194     d += 1 * 8;
22195     n -= 1;
22196   }
22197   return len;
22198 }
22199 
22200 // --------
22201 
22202 static uint64_t  //
wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)22203 wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src(
22204     uint8_t* dst_ptr,
22205     size_t dst_len,
22206     uint8_t* dst_palette_ptr,
22207     size_t dst_palette_len,
22208     const uint8_t* src_ptr,
22209     size_t src_len) {
22210   size_t dst_len4 = dst_len / 4;
22211   size_t src_len4 = src_len / 4;
22212   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
22213   uint8_t* d = dst_ptr;
22214   const uint8_t* s = src_ptr;
22215   size_t n = len;
22216 
22217   // TODO: unroll.
22218 
22219   while (n >= 1) {
22220     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
22221     wuffs_base__poke_u32le__no_bounds_check(
22222         d + (0 * 4),
22223         wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(s0));
22224 
22225     s += 1 * 4;
22226     d += 1 * 4;
22227     n -= 1;
22228   }
22229 
22230   return len;
22231 }
22232 
22233 static uint64_t  //
wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul_4x16le__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)22234 wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul_4x16le__src(
22235     uint8_t* dst_ptr,
22236     size_t dst_len,
22237     uint8_t* dst_palette_ptr,
22238     size_t dst_palette_len,
22239     const uint8_t* src_ptr,
22240     size_t src_len) {
22241   size_t dst_len4 = dst_len / 4;
22242   size_t src_len8 = src_len / 8;
22243   size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
22244   uint8_t* d = dst_ptr;
22245   const uint8_t* s = src_ptr;
22246   size_t n = len;
22247 
22248   // TODO: unroll.
22249 
22250   while (n >= 1) {
22251     uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8));
22252     wuffs_base__poke_u32le__no_bounds_check(
22253         d + (0 * 4),
22254         wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(s0));
22255 
22256     s += 1 * 8;
22257     d += 1 * 4;
22258     n -= 1;
22259   }
22260 
22261   return len;
22262 }
22263 
22264 static uint64_t  //
wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)22265 wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src_over(
22266     uint8_t* dst_ptr,
22267     size_t dst_len,
22268     uint8_t* dst_palette_ptr,
22269     size_t dst_palette_len,
22270     const uint8_t* src_ptr,
22271     size_t src_len) {
22272   size_t dst_len4 = dst_len / 4;
22273   size_t src_len4 = src_len / 4;
22274   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
22275   uint8_t* d = dst_ptr;
22276   const uint8_t* s = src_ptr;
22277   size_t n = len;
22278 
22279   // TODO: unroll.
22280 
22281   while (n >= 1) {
22282     uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
22283     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
22284     wuffs_base__poke_u32le__no_bounds_check(
22285         d + (0 * 4), wuffs_base__composite_premul_nonpremul_u32_axxx(d0, s0));
22286 
22287     s += 1 * 4;
22288     d += 1 * 4;
22289     n -= 1;
22290   }
22291 
22292   return len;
22293 }
22294 
22295 static uint64_t  //
wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul_4x16le__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)22296 wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul_4x16le__src_over(
22297     uint8_t* dst_ptr,
22298     size_t dst_len,
22299     uint8_t* dst_palette_ptr,
22300     size_t dst_palette_len,
22301     const uint8_t* src_ptr,
22302     size_t src_len) {
22303   size_t dst_len4 = dst_len / 4;
22304   size_t src_len8 = src_len / 8;
22305   size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
22306   uint8_t* d = dst_ptr;
22307   const uint8_t* s = src_ptr;
22308   size_t n = len;
22309 
22310   // TODO: unroll.
22311 
22312   while (n >= 1) {
22313     uint64_t d0 = wuffs_base__color_u32__as__color_u64(
22314         wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)));
22315     uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8));
22316     wuffs_base__poke_u32le__no_bounds_check(
22317         d + (0 * 4),
22318         wuffs_base__color_u64__as__color_u32(
22319             wuffs_base__composite_premul_nonpremul_u64_axxx(d0, s0)));
22320 
22321     s += 1 * 8;
22322     d += 1 * 4;
22323     n -= 1;
22324   }
22325 
22326   return len;
22327 }
22328 
22329 static uint64_t  //
wuffs_base__pixel_swizzler__bgra_premul__bgra_premul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)22330 wuffs_base__pixel_swizzler__bgra_premul__bgra_premul__src_over(
22331     uint8_t* dst_ptr,
22332     size_t dst_len,
22333     uint8_t* dst_palette_ptr,
22334     size_t dst_palette_len,
22335     const uint8_t* src_ptr,
22336     size_t src_len) {
22337   size_t dst_len4 = dst_len / 4;
22338   size_t src_len4 = src_len / 4;
22339   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
22340   uint8_t* d = dst_ptr;
22341   const uint8_t* s = src_ptr;
22342   size_t n = len;
22343 
22344   // TODO: unroll.
22345 
22346   while (n >= 1) {
22347     uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
22348     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
22349     wuffs_base__poke_u32le__no_bounds_check(
22350         d + (0 * 4), wuffs_base__composite_premul_premul_u32_axxx(d0, s0));
22351 
22352     s += 1 * 4;
22353     d += 1 * 4;
22354     n -= 1;
22355   }
22356 
22357   return len;
22358 }
22359 
22360 static uint64_t  //
wuffs_base__pixel_swizzler__bgra_premul__index_bgra_nonpremul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)22361 wuffs_base__pixel_swizzler__bgra_premul__index_bgra_nonpremul__src_over(
22362     uint8_t* dst_ptr,
22363     size_t dst_len,
22364     uint8_t* dst_palette_ptr,
22365     size_t dst_palette_len,
22366     const uint8_t* src_ptr,
22367     size_t src_len) {
22368   if (dst_palette_len !=
22369       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
22370     return 0;
22371   }
22372   size_t dst_len4 = dst_len / 4;
22373   size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
22374   uint8_t* d = dst_ptr;
22375   const uint8_t* s = src_ptr;
22376   size_t n = len;
22377 
22378   // TODO: unroll.
22379 
22380   while (n >= 1) {
22381     uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
22382     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
22383                                                           ((size_t)s[0] * 4));
22384     wuffs_base__poke_u32le__no_bounds_check(
22385         d + (0 * 4), wuffs_base__composite_premul_nonpremul_u32_axxx(d0, s0));
22386 
22387     s += 1 * 1;
22388     d += 1 * 4;
22389     n -= 1;
22390   }
22391 
22392   return len;
22393 }
22394 
22395 static uint64_t  //
wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)22396 wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src(
22397     uint8_t* dst_ptr,
22398     size_t dst_len,
22399     uint8_t* dst_palette_ptr,
22400     size_t dst_palette_len,
22401     const uint8_t* src_ptr,
22402     size_t src_len) {
22403   size_t dst_len4 = dst_len / 4;
22404   size_t src_len4 = src_len / 4;
22405   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
22406   uint8_t* d = dst_ptr;
22407   const uint8_t* s = src_ptr;
22408   size_t n = len;
22409 
22410   // TODO: unroll.
22411 
22412   while (n >= 1) {
22413     uint32_t s0 = wuffs_base__swap_u32_argb_abgr(
22414         wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
22415     wuffs_base__poke_u32le__no_bounds_check(
22416         d + (0 * 4),
22417         wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(s0));
22418 
22419     s += 1 * 4;
22420     d += 1 * 4;
22421     n -= 1;
22422   }
22423 
22424   return len;
22425 }
22426 
22427 static uint64_t  //
wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)22428 wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src_over(
22429     uint8_t* dst_ptr,
22430     size_t dst_len,
22431     uint8_t* dst_palette_ptr,
22432     size_t dst_palette_len,
22433     const uint8_t* src_ptr,
22434     size_t src_len) {
22435   size_t dst_len4 = dst_len / 4;
22436   size_t src_len4 = src_len / 4;
22437   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
22438   uint8_t* d = dst_ptr;
22439   const uint8_t* s = src_ptr;
22440   size_t n = len;
22441 
22442   // TODO: unroll.
22443 
22444   while (n >= 1) {
22445     uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
22446     uint32_t s0 = wuffs_base__swap_u32_argb_abgr(
22447         wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
22448     wuffs_base__poke_u32le__no_bounds_check(
22449         d + (0 * 4), wuffs_base__composite_premul_nonpremul_u32_axxx(d0, s0));
22450 
22451     s += 1 * 4;
22452     d += 1 * 4;
22453     n -= 1;
22454   }
22455 
22456   return len;
22457 }
22458 
22459 static uint64_t  //
wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul_4x16le__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)22460 wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul_4x16le__src(
22461     uint8_t* dst_ptr,
22462     size_t dst_len,
22463     uint8_t* dst_palette_ptr,
22464     size_t dst_palette_len,
22465     const uint8_t* src_ptr,
22466     size_t src_len) {
22467   size_t dst_len4 = dst_len / 4;
22468   size_t src_len8 = src_len / 8;
22469   size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
22470   uint8_t* d = dst_ptr;
22471   const uint8_t* s = src_ptr;
22472   size_t n = len;
22473 
22474   // TODO: unroll.
22475 
22476   while (n >= 1) {
22477     uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8));
22478     wuffs_base__poke_u32le__no_bounds_check(
22479         d + (0 * 4),
22480         wuffs_base__swap_u32_argb_abgr(
22481             wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(
22482                 s0)));
22483 
22484     s += 1 * 8;
22485     d += 1 * 4;
22486     n -= 1;
22487   }
22488 
22489   return len;
22490 }
22491 
22492 static uint64_t  //
wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul_4x16le__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)22493 wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul_4x16le__src_over(
22494     uint8_t* dst_ptr,
22495     size_t dst_len,
22496     uint8_t* dst_palette_ptr,
22497     size_t dst_palette_len,
22498     const uint8_t* src_ptr,
22499     size_t src_len) {
22500   size_t dst_len4 = dst_len / 4;
22501   size_t src_len8 = src_len / 8;
22502   size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
22503   uint8_t* d = dst_ptr;
22504   const uint8_t* s = src_ptr;
22505   size_t n = len;
22506 
22507   // TODO: unroll.
22508 
22509   while (n >= 1) {
22510     uint64_t d0 = wuffs_base__color_u32__as__color_u64(
22511         wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)));
22512     uint64_t s0 = wuffs_base__swap_u64_argb_abgr(
22513         wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)));
22514     wuffs_base__poke_u32le__no_bounds_check(
22515         d + (0 * 4),
22516         wuffs_base__color_u64__as__color_u32(
22517             wuffs_base__composite_premul_nonpremul_u64_axxx(d0, s0)));
22518 
22519     s += 1 * 8;
22520     d += 1 * 4;
22521     n -= 1;
22522   }
22523 
22524   return len;
22525 }
22526 
22527 static uint64_t  //
wuffs_base__pixel_swizzler__bgra_premul__rgba_premul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)22528 wuffs_base__pixel_swizzler__bgra_premul__rgba_premul__src_over(
22529     uint8_t* dst_ptr,
22530     size_t dst_len,
22531     uint8_t* dst_palette_ptr,
22532     size_t dst_palette_len,
22533     const uint8_t* src_ptr,
22534     size_t src_len) {
22535   size_t dst_len4 = dst_len / 4;
22536   size_t src_len4 = src_len / 4;
22537   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
22538   uint8_t* d = dst_ptr;
22539   const uint8_t* s = src_ptr;
22540   size_t n = len;
22541 
22542   while (n >= 1) {
22543     uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
22544     uint32_t s0 = wuffs_base__swap_u32_argb_abgr(
22545         wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
22546     wuffs_base__poke_u32le__no_bounds_check(
22547         d + (0 * 4), wuffs_base__composite_premul_premul_u32_axxx(d0, s0));
22548 
22549     s += 1 * 4;
22550     d += 1 * 4;
22551     n -= 1;
22552   }
22553 
22554   return len;
22555 }
22556 
22557 // --------
22558 
22559 static uint64_t  //
wuffs_base__pixel_swizzler__bgrw__bgr(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)22560 wuffs_base__pixel_swizzler__bgrw__bgr(uint8_t* dst_ptr,
22561                                       size_t dst_len,
22562                                       uint8_t* dst_palette_ptr,
22563                                       size_t dst_palette_len,
22564                                       const uint8_t* src_ptr,
22565                                       size_t src_len) {
22566   size_t dst_len4 = dst_len / 4;
22567   size_t src_len3 = src_len / 3;
22568   size_t len = (dst_len4 < src_len3) ? dst_len4 : src_len3;
22569   uint8_t* d = dst_ptr;
22570   const uint8_t* s = src_ptr;
22571   size_t n = len;
22572 
22573   // TODO: unroll.
22574 
22575   while (n >= 1) {
22576     wuffs_base__poke_u32le__no_bounds_check(
22577         d + (0 * 4),
22578         0xFF000000 | wuffs_base__peek_u24le__no_bounds_check(s + (0 * 3)));
22579 
22580     s += 1 * 3;
22581     d += 1 * 4;
22582     n -= 1;
22583   }
22584 
22585   return len;
22586 }
22587 
22588 static uint64_t  //
wuffs_base__pixel_swizzler__bgrw__bgr_565(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)22589 wuffs_base__pixel_swizzler__bgrw__bgr_565(uint8_t* dst_ptr,
22590                                           size_t dst_len,
22591                                           uint8_t* dst_palette_ptr,
22592                                           size_t dst_palette_len,
22593                                           const uint8_t* src_ptr,
22594                                           size_t src_len) {
22595   size_t dst_len4 = dst_len / 4;
22596   size_t src_len2 = src_len / 2;
22597   size_t len = (dst_len4 < src_len2) ? dst_len4 : src_len2;
22598   uint8_t* d = dst_ptr;
22599   const uint8_t* s = src_ptr;
22600   size_t n = len;
22601 
22602   // TODO: unroll.
22603 
22604   while (n >= 1) {
22605     wuffs_base__poke_u32le__no_bounds_check(
22606         d + (0 * 4), wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
22607                          wuffs_base__peek_u16le__no_bounds_check(s + (0 * 2))));
22608 
22609     s += 1 * 2;
22610     d += 1 * 4;
22611     n -= 1;
22612   }
22613 
22614   return len;
22615 }
22616 
22617 static uint64_t  //
wuffs_base__pixel_swizzler__bgrw__bgrx(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)22618 wuffs_base__pixel_swizzler__bgrw__bgrx(uint8_t* dst_ptr,
22619                                        size_t dst_len,
22620                                        uint8_t* dst_palette_ptr,
22621                                        size_t dst_palette_len,
22622                                        const uint8_t* src_ptr,
22623                                        size_t src_len) {
22624   size_t dst_len4 = dst_len / 4;
22625   size_t src_len4 = src_len / 4;
22626   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
22627   uint8_t* d = dst_ptr;
22628   const uint8_t* s = src_ptr;
22629   size_t n = len;
22630 
22631   // TODO: unroll.
22632 
22633   while (n >= 1) {
22634     wuffs_base__poke_u32le__no_bounds_check(
22635         d + (0 * 4),
22636         0xFF000000 | wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
22637 
22638     s += 1 * 4;
22639     d += 1 * 4;
22640     n -= 1;
22641   }
22642 
22643   return len;
22644 }
22645 
22646 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
22647 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
22648 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
22649 static uint64_t  //
wuffs_base__pixel_swizzler__bgrw__rgb__x86_sse42(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)22650 wuffs_base__pixel_swizzler__bgrw__rgb__x86_sse42(uint8_t* dst_ptr,
22651                                                  size_t dst_len,
22652                                                  uint8_t* dst_palette_ptr,
22653                                                  size_t dst_palette_len,
22654                                                  const uint8_t* src_ptr,
22655                                                  size_t src_len) {
22656   size_t dst_len4 = dst_len / 4;
22657   size_t src_len3 = src_len / 3;
22658   size_t len = (dst_len4 < src_len3) ? dst_len4 : src_len3;
22659   uint8_t* d = dst_ptr;
22660   const uint8_t* s = src_ptr;
22661   size_t n = len;
22662 
22663   __m128i shuffle = _mm_set_epi8(+0x00, +0x09, +0x0A, +0x0B,  //
22664                                  +0x00, +0x06, +0x07, +0x08,  //
22665                                  +0x00, +0x03, +0x04, +0x05,  //
22666                                  +0x00, +0x00, +0x01, +0x02);
22667   __m128i or_ff = _mm_set_epi8(-0x01, +0x00, +0x00, +0x00,  //
22668                                -0x01, +0x00, +0x00, +0x00,  //
22669                                -0x01, +0x00, +0x00, +0x00,  //
22670                                -0x01, +0x00, +0x00, +0x00);
22671 
22672   while (n >= 6) {
22673     __m128i x;
22674     x = _mm_lddqu_si128((const __m128i*)(const void*)s);
22675     x = _mm_shuffle_epi8(x, shuffle);
22676     x = _mm_or_si128(x, or_ff);
22677     _mm_storeu_si128((__m128i*)(void*)d, x);
22678 
22679     s += 4 * 3;
22680     d += 4 * 4;
22681     n -= 4;
22682   }
22683 
22684   while (n >= 1) {
22685     uint8_t b0 = s[0];
22686     uint8_t b1 = s[1];
22687     uint8_t b2 = s[2];
22688     d[0] = b2;
22689     d[1] = b1;
22690     d[2] = b0;
22691     d[3] = 0xFF;
22692 
22693     s += 1 * 3;
22694     d += 1 * 4;
22695     n -= 1;
22696   }
22697 
22698   return len;
22699 }
22700 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
22701 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
22702 
22703 static uint64_t  //
wuffs_base__pixel_swizzler__bgrw__rgb(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)22704 wuffs_base__pixel_swizzler__bgrw__rgb(uint8_t* dst_ptr,
22705                                       size_t dst_len,
22706                                       uint8_t* dst_palette_ptr,
22707                                       size_t dst_palette_len,
22708                                       const uint8_t* src_ptr,
22709                                       size_t src_len) {
22710   size_t dst_len4 = dst_len / 4;
22711   size_t src_len3 = src_len / 3;
22712   size_t len = (dst_len4 < src_len3) ? dst_len4 : src_len3;
22713   uint8_t* d = dst_ptr;
22714   const uint8_t* s = src_ptr;
22715   size_t n = len;
22716 
22717   while (n >= 1) {
22718     uint8_t b0 = s[0];
22719     uint8_t b1 = s[1];
22720     uint8_t b2 = s[2];
22721     d[0] = b2;
22722     d[1] = b1;
22723     d[2] = b0;
22724     d[3] = 0xFF;
22725 
22726     s += 1 * 3;
22727     d += 1 * 4;
22728     n -= 1;
22729   }
22730 
22731   return len;
22732 }
22733 
22734 static uint64_t  //
wuffs_base__pixel_swizzler__bgrw__rgbx(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)22735 wuffs_base__pixel_swizzler__bgrw__rgbx(uint8_t* dst_ptr,
22736                                        size_t dst_len,
22737                                        uint8_t* dst_palette_ptr,
22738                                        size_t dst_palette_len,
22739                                        const uint8_t* src_ptr,
22740                                        size_t src_len) {
22741   size_t dst_len4 = dst_len / 4;
22742   size_t src_len4 = src_len / 4;
22743   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
22744   uint8_t* d = dst_ptr;
22745   const uint8_t* s = src_ptr;
22746   size_t n = len;
22747 
22748   // TODO: unroll.
22749 
22750   while (n >= 1) {
22751     uint8_t b0 = s[0];
22752     uint8_t b1 = s[1];
22753     uint8_t b2 = s[2];
22754     d[0] = b2;
22755     d[1] = b1;
22756     d[2] = b0;
22757     d[3] = 0xFF;
22758 
22759     s += 1 * 4;
22760     d += 1 * 4;
22761     n -= 1;
22762   }
22763 
22764   return len;
22765 }
22766 
22767 // --------
22768 
22769 static uint64_t  //
wuffs_base__pixel_swizzler__bgrw_4x16le__bgr(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)22770 wuffs_base__pixel_swizzler__bgrw_4x16le__bgr(uint8_t* dst_ptr,
22771                                              size_t dst_len,
22772                                              uint8_t* dst_palette_ptr,
22773                                              size_t dst_palette_len,
22774                                              const uint8_t* src_ptr,
22775                                              size_t src_len) {
22776   size_t dst_len8 = dst_len / 8;
22777   size_t src_len3 = src_len / 3;
22778   size_t len = (dst_len8 < src_len3) ? dst_len8 : src_len3;
22779   uint8_t* d = dst_ptr;
22780   const uint8_t* s = src_ptr;
22781   size_t n = len;
22782 
22783   while (n >= 1) {
22784     uint8_t s0 = s[0];
22785     uint8_t s1 = s[1];
22786     uint8_t s2 = s[2];
22787     d[0] = s0;
22788     d[1] = s0;
22789     d[2] = s1;
22790     d[3] = s1;
22791     d[4] = s2;
22792     d[5] = s2;
22793     d[6] = 0xFF;
22794     d[7] = 0xFF;
22795 
22796     s += 1 * 3;
22797     d += 1 * 8;
22798     n -= 1;
22799   }
22800 
22801   return len;
22802 }
22803 
22804 static uint64_t  //
wuffs_base__pixel_swizzler__bgrw_4x16le__bgr_565(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)22805 wuffs_base__pixel_swizzler__bgrw_4x16le__bgr_565(uint8_t* dst_ptr,
22806                                                  size_t dst_len,
22807                                                  uint8_t* dst_palette_ptr,
22808                                                  size_t dst_palette_len,
22809                                                  const uint8_t* src_ptr,
22810                                                  size_t src_len) {
22811   size_t dst_len8 = dst_len / 8;
22812   size_t src_len2 = src_len / 2;
22813   size_t len = (dst_len8 < src_len2) ? dst_len8 : src_len2;
22814   uint8_t* d = dst_ptr;
22815   const uint8_t* s = src_ptr;
22816   size_t n = len;
22817 
22818   while (n >= 1) {
22819     wuffs_base__poke_u64le__no_bounds_check(
22820         d + (0 * 8),
22821         wuffs_base__color_u32__as__color_u64(
22822             wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
22823                 wuffs_base__peek_u16le__no_bounds_check(s + (0 * 2)))));
22824 
22825     s += 1 * 2;
22826     d += 1 * 8;
22827     n -= 1;
22828   }
22829 
22830   return len;
22831 }
22832 
22833 static uint64_t  //
wuffs_base__pixel_swizzler__bgrw_4x16le__bgrx(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)22834 wuffs_base__pixel_swizzler__bgrw_4x16le__bgrx(uint8_t* dst_ptr,
22835                                               size_t dst_len,
22836                                               uint8_t* dst_palette_ptr,
22837                                               size_t dst_palette_len,
22838                                               const uint8_t* src_ptr,
22839                                               size_t src_len) {
22840   size_t dst_len8 = dst_len / 8;
22841   size_t src_len4 = src_len / 4;
22842   size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
22843   uint8_t* d = dst_ptr;
22844   const uint8_t* s = src_ptr;
22845   size_t n = len;
22846 
22847   while (n >= 1) {
22848     uint8_t s0 = s[0];
22849     uint8_t s1 = s[1];
22850     uint8_t s2 = s[2];
22851     d[0] = s0;
22852     d[1] = s0;
22853     d[2] = s1;
22854     d[3] = s1;
22855     d[4] = s2;
22856     d[5] = s2;
22857     d[6] = 0xFF;
22858     d[7] = 0xFF;
22859 
22860     s += 1 * 4;
22861     d += 1 * 8;
22862     n -= 1;
22863   }
22864 
22865   return len;
22866 }
22867 
22868 static uint64_t  //
wuffs_base__pixel_swizzler__bgrw_4x16le__rgb(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)22869 wuffs_base__pixel_swizzler__bgrw_4x16le__rgb(uint8_t* dst_ptr,
22870                                              size_t dst_len,
22871                                              uint8_t* dst_palette_ptr,
22872                                              size_t dst_palette_len,
22873                                              const uint8_t* src_ptr,
22874                                              size_t src_len) {
22875   size_t dst_len8 = dst_len / 8;
22876   size_t src_len3 = src_len / 3;
22877   size_t len = (dst_len8 < src_len3) ? dst_len8 : src_len3;
22878   uint8_t* d = dst_ptr;
22879   const uint8_t* s = src_ptr;
22880   size_t n = len;
22881 
22882   while (n >= 1) {
22883     uint8_t s0 = s[0];
22884     uint8_t s1 = s[1];
22885     uint8_t s2 = s[2];
22886     d[0] = s2;
22887     d[1] = s2;
22888     d[2] = s1;
22889     d[3] = s1;
22890     d[4] = s0;
22891     d[5] = s0;
22892     d[6] = 0xFF;
22893     d[7] = 0xFF;
22894 
22895     s += 1 * 3;
22896     d += 1 * 8;
22897     n -= 1;
22898   }
22899 
22900   return len;
22901 }
22902 
22903 // --------
22904 
22905 static uint64_t  //
wuffs_base__pixel_swizzler__rgb__bgr_565(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)22906 wuffs_base__pixel_swizzler__rgb__bgr_565(uint8_t* dst_ptr,
22907                                          size_t dst_len,
22908                                          uint8_t* dst_palette_ptr,
22909                                          size_t dst_palette_len,
22910                                          const uint8_t* src_ptr,
22911                                          size_t src_len) {
22912   size_t dst_len3 = dst_len / 3;
22913   size_t src_len2 = src_len / 2;
22914   size_t len = (dst_len3 < src_len2) ? dst_len3 : src_len2;
22915   uint8_t* d = dst_ptr;
22916   const uint8_t* s = src_ptr;
22917   size_t n = len;
22918 
22919   // TODO: unroll.
22920 
22921   while (n >= 1) {
22922     wuffs_base__poke_u24le__no_bounds_check(
22923         d + (0 * 3),
22924         wuffs_base__swap_u32_argb_abgr(
22925             wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
22926                 wuffs_base__peek_u16le__no_bounds_check(s + (0 * 2)))));
22927 
22928     s += 1 * 2;
22929     d += 1 * 3;
22930     n -= 1;
22931   }
22932 
22933   return len;
22934 }
22935 
22936 // --------
22937 
22938 static uint64_t  //
wuffs_base__pixel_swizzler__rgba_nonpremul__bgra_nonpremul_4x16le__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)22939 wuffs_base__pixel_swizzler__rgba_nonpremul__bgra_nonpremul_4x16le__src(
22940     uint8_t* dst_ptr,
22941     size_t dst_len,
22942     uint8_t* dst_palette_ptr,
22943     size_t dst_palette_len,
22944     const uint8_t* src_ptr,
22945     size_t src_len) {
22946   size_t dst_len4 = dst_len / 4;
22947   size_t src_len8 = src_len / 8;
22948   size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
22949   uint8_t* d = dst_ptr;
22950   const uint8_t* s = src_ptr;
22951 
22952   size_t n = len;
22953   while (n >= 1) {
22954     wuffs_base__poke_u32le__no_bounds_check(
22955         d + (0 * 4), wuffs_base__color_u64__as__color_u32__swap_u32_argb_abgr(
22956                          wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8))));
22957 
22958     s += 1 * 8;
22959     d += 1 * 4;
22960     n -= 1;
22961   }
22962   return len;
22963 }
22964 
22965 static uint64_t  //
wuffs_base__pixel_swizzler__rgba_nonpremul__bgra_nonpremul_4x16le__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)22966 wuffs_base__pixel_swizzler__rgba_nonpremul__bgra_nonpremul_4x16le__src_over(
22967     uint8_t* dst_ptr,
22968     size_t dst_len,
22969     uint8_t* dst_palette_ptr,
22970     size_t dst_palette_len,
22971     const uint8_t* src_ptr,
22972     size_t src_len) {
22973   size_t dst_len4 = dst_len / 4;
22974   size_t src_len8 = src_len / 8;
22975   size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
22976   uint8_t* d = dst_ptr;
22977   const uint8_t* s = src_ptr;
22978   size_t n = len;
22979 
22980   while (n >= 1) {
22981     uint64_t d0 = wuffs_base__color_u32__as__color_u64(
22982         wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)));
22983     uint64_t s0 = wuffs_base__swap_u64_argb_abgr(
22984         wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)));
22985     wuffs_base__poke_u32le__no_bounds_check(
22986         d + (0 * 4),
22987         wuffs_base__color_u64__as__color_u32(
22988             wuffs_base__composite_nonpremul_nonpremul_u64_axxx(d0, s0)));
22989 
22990     s += 1 * 8;
22991     d += 1 * 4;
22992     n -= 1;
22993   }
22994 
22995   return len;
22996 }
22997 
22998 // --------
22999 
23000 static uint64_t  //
wuffs_base__pixel_swizzler__rgbw__bgr_565(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)23001 wuffs_base__pixel_swizzler__rgbw__bgr_565(uint8_t* dst_ptr,
23002                                           size_t dst_len,
23003                                           uint8_t* dst_palette_ptr,
23004                                           size_t dst_palette_len,
23005                                           const uint8_t* src_ptr,
23006                                           size_t src_len) {
23007   size_t dst_len4 = dst_len / 4;
23008   size_t src_len2 = src_len / 2;
23009   size_t len = (dst_len4 < src_len2) ? dst_len4 : src_len2;
23010   uint8_t* d = dst_ptr;
23011   const uint8_t* s = src_ptr;
23012   size_t n = len;
23013 
23014   // TODO: unroll.
23015 
23016   while (n >= 1) {
23017     wuffs_base__poke_u32le__no_bounds_check(
23018         d + (0 * 4),
23019         wuffs_base__swap_u32_argb_abgr(
23020             wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
23021                 wuffs_base__peek_u16le__no_bounds_check(s + (0 * 2)))));
23022 
23023     s += 1 * 2;
23024     d += 1 * 4;
23025     n -= 1;
23026   }
23027 
23028   return len;
23029 }
23030 
23031 // --------
23032 
23033 static uint64_t  //
wuffs_base__pixel_swizzler__xxx__index__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)23034 wuffs_base__pixel_swizzler__xxx__index__src(uint8_t* dst_ptr,
23035                                             size_t dst_len,
23036                                             uint8_t* dst_palette_ptr,
23037                                             size_t dst_palette_len,
23038                                             const uint8_t* src_ptr,
23039                                             size_t src_len) {
23040   if (dst_palette_len !=
23041       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
23042     return 0;
23043   }
23044   size_t dst_len3 = dst_len / 3;
23045   size_t len = (dst_len3 < src_len) ? dst_len3 : src_len;
23046   uint8_t* d = dst_ptr;
23047   const uint8_t* s = src_ptr;
23048   size_t n = len;
23049 
23050   const size_t loop_unroll_count = 4;
23051 
23052   // The comparison in the while condition is ">", not ">=", because with
23053   // ">=", the last 4-byte store could write past the end of the dst slice.
23054   //
23055   // Each 4-byte store writes one too many bytes, but a subsequent store
23056   // will overwrite that with the correct byte. There is always another
23057   // store, whether a 4-byte store in this loop or a 1-byte store in the
23058   // next loop.
23059   while (n > loop_unroll_count) {
23060     wuffs_base__poke_u32le__no_bounds_check(
23061         d + (0 * 3), wuffs_base__peek_u32le__no_bounds_check(
23062                          dst_palette_ptr + ((size_t)s[0] * 4)));
23063     wuffs_base__poke_u32le__no_bounds_check(
23064         d + (1 * 3), wuffs_base__peek_u32le__no_bounds_check(
23065                          dst_palette_ptr + ((size_t)s[1] * 4)));
23066     wuffs_base__poke_u32le__no_bounds_check(
23067         d + (2 * 3), wuffs_base__peek_u32le__no_bounds_check(
23068                          dst_palette_ptr + ((size_t)s[2] * 4)));
23069     wuffs_base__poke_u32le__no_bounds_check(
23070         d + (3 * 3), wuffs_base__peek_u32le__no_bounds_check(
23071                          dst_palette_ptr + ((size_t)s[3] * 4)));
23072 
23073     s += loop_unroll_count * 1;
23074     d += loop_unroll_count * 3;
23075     n -= loop_unroll_count;
23076   }
23077 
23078   while (n >= 1) {
23079     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
23080                                                           ((size_t)s[0] * 4));
23081     wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
23082 
23083     s += 1 * 1;
23084     d += 1 * 3;
23085     n -= 1;
23086   }
23087 
23088   return len;
23089 }
23090 
23091 static uint64_t  //
wuffs_base__pixel_swizzler__xxx__index_bgra_nonpremul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)23092 wuffs_base__pixel_swizzler__xxx__index_bgra_nonpremul__src_over(
23093     uint8_t* dst_ptr,
23094     size_t dst_len,
23095     uint8_t* dst_palette_ptr,
23096     size_t dst_palette_len,
23097     const uint8_t* src_ptr,
23098     size_t src_len) {
23099   if (dst_palette_len !=
23100       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
23101     return 0;
23102   }
23103   size_t dst_len3 = dst_len / 3;
23104   size_t len = (dst_len3 < src_len) ? dst_len3 : src_len;
23105   uint8_t* d = dst_ptr;
23106   const uint8_t* s = src_ptr;
23107   size_t n = len;
23108 
23109   // TODO: unroll.
23110 
23111   while (n >= 1) {
23112     uint32_t d0 =
23113         wuffs_base__peek_u24le__no_bounds_check(d + (0 * 3)) | 0xFF000000;
23114     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
23115                                                           ((size_t)s[0] * 4));
23116     wuffs_base__poke_u24le__no_bounds_check(
23117         d + (0 * 3), wuffs_base__composite_premul_nonpremul_u32_axxx(d0, s0));
23118 
23119     s += 1 * 1;
23120     d += 1 * 3;
23121     n -= 1;
23122   }
23123 
23124   return len;
23125 }
23126 
23127 static uint64_t  //
wuffs_base__pixel_swizzler__xxx__index_binary_alpha__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)23128 wuffs_base__pixel_swizzler__xxx__index_binary_alpha__src_over(
23129     uint8_t* dst_ptr,
23130     size_t dst_len,
23131     uint8_t* dst_palette_ptr,
23132     size_t dst_palette_len,
23133     const uint8_t* src_ptr,
23134     size_t src_len) {
23135   if (dst_palette_len !=
23136       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
23137     return 0;
23138   }
23139   size_t dst_len3 = dst_len / 3;
23140   size_t len = (dst_len3 < src_len) ? dst_len3 : src_len;
23141   uint8_t* d = dst_ptr;
23142   const uint8_t* s = src_ptr;
23143   size_t n = len;
23144 
23145   const size_t loop_unroll_count = 4;
23146 
23147   while (n >= loop_unroll_count) {
23148     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
23149                                                           ((size_t)s[0] * 4));
23150     if (s0) {
23151       wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
23152     }
23153     uint32_t s1 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
23154                                                           ((size_t)s[1] * 4));
23155     if (s1) {
23156       wuffs_base__poke_u24le__no_bounds_check(d + (1 * 3), s1);
23157     }
23158     uint32_t s2 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
23159                                                           ((size_t)s[2] * 4));
23160     if (s2) {
23161       wuffs_base__poke_u24le__no_bounds_check(d + (2 * 3), s2);
23162     }
23163     uint32_t s3 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
23164                                                           ((size_t)s[3] * 4));
23165     if (s3) {
23166       wuffs_base__poke_u24le__no_bounds_check(d + (3 * 3), s3);
23167     }
23168 
23169     s += loop_unroll_count * 1;
23170     d += loop_unroll_count * 3;
23171     n -= loop_unroll_count;
23172   }
23173 
23174   while (n >= 1) {
23175     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
23176                                                           ((size_t)s[0] * 4));
23177     if (s0) {
23178       wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
23179     }
23180 
23181     s += 1 * 1;
23182     d += 1 * 3;
23183     n -= 1;
23184   }
23185 
23186   return len;
23187 }
23188 
23189 static uint64_t  //
wuffs_base__pixel_swizzler__xxx__xxxx(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)23190 wuffs_base__pixel_swizzler__xxx__xxxx(uint8_t* dst_ptr,
23191                                       size_t dst_len,
23192                                       uint8_t* dst_palette_ptr,
23193                                       size_t dst_palette_len,
23194                                       const uint8_t* src_ptr,
23195                                       size_t src_len) {
23196   size_t dst_len3 = dst_len / 3;
23197   size_t src_len4 = src_len / 4;
23198   size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
23199   uint8_t* d = dst_ptr;
23200   const uint8_t* s = src_ptr;
23201   size_t n = len;
23202 
23203   // TODO: unroll.
23204 
23205   while (n >= 1) {
23206     wuffs_base__poke_u24le__no_bounds_check(
23207         d + (0 * 3), wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
23208 
23209     s += 1 * 4;
23210     d += 1 * 3;
23211     n -= 1;
23212   }
23213 
23214   return len;
23215 }
23216 
23217 static uint64_t  //
wuffs_base__pixel_swizzler__xxx__y(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)23218 wuffs_base__pixel_swizzler__xxx__y(uint8_t* dst_ptr,
23219                                    size_t dst_len,
23220                                    uint8_t* dst_palette_ptr,
23221                                    size_t dst_palette_len,
23222                                    const uint8_t* src_ptr,
23223                                    size_t src_len) {
23224   size_t dst_len3 = dst_len / 3;
23225   size_t len = (dst_len3 < src_len) ? dst_len3 : src_len;
23226   uint8_t* d = dst_ptr;
23227   const uint8_t* s = src_ptr;
23228   size_t n = len;
23229 
23230   // TODO: unroll.
23231 
23232   while (n >= 1) {
23233     uint8_t s0 = s[0];
23234     d[0] = s0;
23235     d[1] = s0;
23236     d[2] = s0;
23237 
23238     s += 1 * 1;
23239     d += 1 * 3;
23240     n -= 1;
23241   }
23242 
23243   return len;
23244 }
23245 
23246 static uint64_t  //
wuffs_base__pixel_swizzler__xxx__y_16be(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)23247 wuffs_base__pixel_swizzler__xxx__y_16be(uint8_t* dst_ptr,
23248                                         size_t dst_len,
23249                                         uint8_t* dst_palette_ptr,
23250                                         size_t dst_palette_len,
23251                                         const uint8_t* src_ptr,
23252                                         size_t src_len) {
23253   size_t dst_len3 = dst_len / 3;
23254   size_t src_len2 = src_len / 2;
23255   size_t len = (dst_len3 < src_len2) ? dst_len3 : src_len2;
23256   uint8_t* d = dst_ptr;
23257   const uint8_t* s = src_ptr;
23258   size_t n = len;
23259 
23260   // TODO: unroll.
23261 
23262   while (n >= 1) {
23263     uint8_t s0 = s[0];
23264     d[0] = s0;
23265     d[1] = s0;
23266     d[2] = s0;
23267 
23268     s += 1 * 2;
23269     d += 1 * 3;
23270     n -= 1;
23271   }
23272 
23273   return len;
23274 }
23275 
23276 // --------
23277 
23278 static uint64_t  //
wuffs_base__pixel_swizzler__xxxx__index__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)23279 wuffs_base__pixel_swizzler__xxxx__index__src(uint8_t* dst_ptr,
23280                                              size_t dst_len,
23281                                              uint8_t* dst_palette_ptr,
23282                                              size_t dst_palette_len,
23283                                              const uint8_t* src_ptr,
23284                                              size_t src_len) {
23285   if (dst_palette_len !=
23286       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
23287     return 0;
23288   }
23289   size_t dst_len4 = dst_len / 4;
23290   size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
23291   uint8_t* d = dst_ptr;
23292   const uint8_t* s = src_ptr;
23293   size_t n = len;
23294 
23295   const size_t loop_unroll_count = 4;
23296 
23297   while (n >= loop_unroll_count) {
23298     wuffs_base__poke_u32le__no_bounds_check(
23299         d + (0 * 4), wuffs_base__peek_u32le__no_bounds_check(
23300                          dst_palette_ptr + ((size_t)s[0] * 4)));
23301     wuffs_base__poke_u32le__no_bounds_check(
23302         d + (1 * 4), wuffs_base__peek_u32le__no_bounds_check(
23303                          dst_palette_ptr + ((size_t)s[1] * 4)));
23304     wuffs_base__poke_u32le__no_bounds_check(
23305         d + (2 * 4), wuffs_base__peek_u32le__no_bounds_check(
23306                          dst_palette_ptr + ((size_t)s[2] * 4)));
23307     wuffs_base__poke_u32le__no_bounds_check(
23308         d + (3 * 4), wuffs_base__peek_u32le__no_bounds_check(
23309                          dst_palette_ptr + ((size_t)s[3] * 4)));
23310 
23311     s += loop_unroll_count * 1;
23312     d += loop_unroll_count * 4;
23313     n -= loop_unroll_count;
23314   }
23315 
23316   while (n >= 1) {
23317     wuffs_base__poke_u32le__no_bounds_check(
23318         d + (0 * 4), wuffs_base__peek_u32le__no_bounds_check(
23319                          dst_palette_ptr + ((size_t)s[0] * 4)));
23320 
23321     s += 1 * 1;
23322     d += 1 * 4;
23323     n -= 1;
23324   }
23325 
23326   return len;
23327 }
23328 
23329 static uint64_t  //
wuffs_base__pixel_swizzler__xxxx__index_binary_alpha__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)23330 wuffs_base__pixel_swizzler__xxxx__index_binary_alpha__src_over(
23331     uint8_t* dst_ptr,
23332     size_t dst_len,
23333     uint8_t* dst_palette_ptr,
23334     size_t dst_palette_len,
23335     const uint8_t* src_ptr,
23336     size_t src_len) {
23337   if (dst_palette_len !=
23338       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
23339     return 0;
23340   }
23341   size_t dst_len4 = dst_len / 4;
23342   size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
23343   uint8_t* d = dst_ptr;
23344   const uint8_t* s = src_ptr;
23345   size_t n = len;
23346 
23347   const size_t loop_unroll_count = 4;
23348 
23349   while (n >= loop_unroll_count) {
23350     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
23351                                                           ((size_t)s[0] * 4));
23352     if (s0) {
23353       wuffs_base__poke_u32le__no_bounds_check(d + (0 * 4), s0);
23354     }
23355     uint32_t s1 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
23356                                                           ((size_t)s[1] * 4));
23357     if (s1) {
23358       wuffs_base__poke_u32le__no_bounds_check(d + (1 * 4), s1);
23359     }
23360     uint32_t s2 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
23361                                                           ((size_t)s[2] * 4));
23362     if (s2) {
23363       wuffs_base__poke_u32le__no_bounds_check(d + (2 * 4), s2);
23364     }
23365     uint32_t s3 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
23366                                                           ((size_t)s[3] * 4));
23367     if (s3) {
23368       wuffs_base__poke_u32le__no_bounds_check(d + (3 * 4), s3);
23369     }
23370 
23371     s += loop_unroll_count * 1;
23372     d += loop_unroll_count * 4;
23373     n -= loop_unroll_count;
23374   }
23375 
23376   while (n >= 1) {
23377     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
23378                                                           ((size_t)s[0] * 4));
23379     if (s0) {
23380       wuffs_base__poke_u32le__no_bounds_check(d + (0 * 4), s0);
23381     }
23382 
23383     s += 1 * 1;
23384     d += 1 * 4;
23385     n -= 1;
23386   }
23387 
23388   return len;
23389 }
23390 
23391 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
23392 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
23393 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
23394 static uint64_t  //
wuffs_base__pixel_swizzler__xxxx__y__x86_sse42(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)23395 wuffs_base__pixel_swizzler__xxxx__y__x86_sse42(uint8_t* dst_ptr,
23396                                                size_t dst_len,
23397                                                uint8_t* dst_palette_ptr,
23398                                                size_t dst_palette_len,
23399                                                const uint8_t* src_ptr,
23400                                                size_t src_len) {
23401   size_t dst_len4 = dst_len / 4;
23402   size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
23403   uint8_t* d = dst_ptr;
23404   const uint8_t* s = src_ptr;
23405   size_t n = len;
23406 
23407   __m128i shuffle = _mm_set_epi8(+0x03, +0x03, +0x03, +0x03,  //
23408                                  +0x02, +0x02, +0x02, +0x02,  //
23409                                  +0x01, +0x01, +0x01, +0x01,  //
23410                                  +0x00, +0x00, +0x00, +0x00);
23411   __m128i or_ff = _mm_set_epi8(-0x01, +0x00, +0x00, +0x00,  //
23412                                -0x01, +0x00, +0x00, +0x00,  //
23413                                -0x01, +0x00, +0x00, +0x00,  //
23414                                -0x01, +0x00, +0x00, +0x00);
23415 
23416   while (n >= 4) {
23417     __m128i x;
23418     x = _mm_cvtsi32_si128((int)(wuffs_base__peek_u32le__no_bounds_check(s)));
23419     x = _mm_shuffle_epi8(x, shuffle);
23420     x = _mm_or_si128(x, or_ff);
23421     _mm_storeu_si128((__m128i*)(void*)d, x);
23422 
23423     s += 4 * 1;
23424     d += 4 * 4;
23425     n -= 4;
23426   }
23427 
23428   while (n >= 1) {
23429     wuffs_base__poke_u32le__no_bounds_check(
23430         d + (0 * 4), 0xFF000000 | (0x010101 * (uint32_t)s[0]));
23431 
23432     s += 1 * 1;
23433     d += 1 * 4;
23434     n -= 1;
23435   }
23436 
23437   return len;
23438 }
23439 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
23440 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
23441 
23442 static uint64_t  //
wuffs_base__pixel_swizzler__xxxx__y(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)23443 wuffs_base__pixel_swizzler__xxxx__y(uint8_t* dst_ptr,
23444                                     size_t dst_len,
23445                                     uint8_t* dst_palette_ptr,
23446                                     size_t dst_palette_len,
23447                                     const uint8_t* src_ptr,
23448                                     size_t src_len) {
23449   size_t dst_len4 = dst_len / 4;
23450   size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
23451   uint8_t* d = dst_ptr;
23452   const uint8_t* s = src_ptr;
23453   size_t n = len;
23454 
23455   while (n >= 1) {
23456     wuffs_base__poke_u32le__no_bounds_check(
23457         d + (0 * 4), 0xFF000000 | (0x010101 * (uint32_t)s[0]));
23458 
23459     s += 1 * 1;
23460     d += 1 * 4;
23461     n -= 1;
23462   }
23463 
23464   return len;
23465 }
23466 
23467 static uint64_t  //
wuffs_base__pixel_swizzler__xxxx__y_16be(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)23468 wuffs_base__pixel_swizzler__xxxx__y_16be(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_len4 = dst_len / 4;
23475   size_t src_len2 = src_len / 2;
23476   size_t len = (dst_len4 < src_len2) ? dst_len4 : src_len2;
23477   uint8_t* d = dst_ptr;
23478   const uint8_t* s = src_ptr;
23479   size_t n = len;
23480 
23481   while (n >= 1) {
23482     wuffs_base__poke_u32le__no_bounds_check(
23483         d + (0 * 4), 0xFF000000 | (0x010101 * (uint32_t)s[0]));
23484 
23485     s += 1 * 2;
23486     d += 1 * 4;
23487     n -= 1;
23488   }
23489 
23490   return len;
23491 }
23492 
23493 // --------
23494 
23495 static uint64_t  //
wuffs_base__pixel_swizzler__xxxxxxxx__index__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)23496 wuffs_base__pixel_swizzler__xxxxxxxx__index__src(uint8_t* dst_ptr,
23497                                                  size_t dst_len,
23498                                                  uint8_t* dst_palette_ptr,
23499                                                  size_t dst_palette_len,
23500                                                  const uint8_t* src_ptr,
23501                                                  size_t src_len) {
23502   if (dst_palette_len !=
23503       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
23504     return 0;
23505   }
23506   size_t dst_len8 = dst_len / 8;
23507   size_t len = (dst_len8 < src_len) ? dst_len8 : src_len;
23508   uint8_t* d = dst_ptr;
23509   const uint8_t* s = src_ptr;
23510   size_t n = len;
23511 
23512   while (n >= 1) {
23513     wuffs_base__poke_u64le__no_bounds_check(
23514         d + (0 * 8), wuffs_base__color_u32__as__color_u64(
23515                          wuffs_base__peek_u32le__no_bounds_check(
23516                              dst_palette_ptr + ((size_t)s[0] * 4))));
23517 
23518     s += 1 * 1;
23519     d += 1 * 8;
23520     n -= 1;
23521   }
23522 
23523   return len;
23524 }
23525 
23526 static uint64_t  //
wuffs_base__pixel_swizzler__xxxxxxxx__index_binary_alpha__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)23527 wuffs_base__pixel_swizzler__xxxxxxxx__index_binary_alpha__src_over(
23528     uint8_t* dst_ptr,
23529     size_t dst_len,
23530     uint8_t* dst_palette_ptr,
23531     size_t dst_palette_len,
23532     const uint8_t* src_ptr,
23533     size_t src_len) {
23534   if (dst_palette_len !=
23535       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
23536     return 0;
23537   }
23538   size_t dst_len8 = dst_len / 8;
23539   size_t len = (dst_len8 < src_len) ? dst_len8 : src_len;
23540   uint8_t* d = dst_ptr;
23541   const uint8_t* s = src_ptr;
23542   size_t n = len;
23543 
23544   while (n >= 1) {
23545     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
23546                                                           ((size_t)s[0] * 4));
23547     if (s0) {
23548       wuffs_base__poke_u64le__no_bounds_check(
23549           d + (0 * 8), wuffs_base__color_u32__as__color_u64(s0));
23550     }
23551 
23552     s += 1 * 1;
23553     d += 1 * 8;
23554     n -= 1;
23555   }
23556 
23557   return len;
23558 }
23559 
23560 static uint64_t  //
wuffs_base__pixel_swizzler__xxxxxxxx__y(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)23561 wuffs_base__pixel_swizzler__xxxxxxxx__y(uint8_t* dst_ptr,
23562                                         size_t dst_len,
23563                                         uint8_t* dst_palette_ptr,
23564                                         size_t dst_palette_len,
23565                                         const uint8_t* src_ptr,
23566                                         size_t src_len) {
23567   size_t dst_len8 = dst_len / 8;
23568   size_t len = (dst_len8 < src_len) ? dst_len8 : src_len;
23569   uint8_t* d = dst_ptr;
23570   const uint8_t* s = src_ptr;
23571   size_t n = len;
23572 
23573   while (n >= 1) {
23574     wuffs_base__poke_u64le__no_bounds_check(
23575         d + (0 * 8), 0xFFFF000000000000 | (0x010101010101 * (uint64_t)s[0]));
23576 
23577     s += 1 * 1;
23578     d += 1 * 8;
23579     n -= 1;
23580   }
23581 
23582   return len;
23583 }
23584 
23585 static uint64_t  //
wuffs_base__pixel_swizzler__xxxxxxxx__y_16be(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)23586 wuffs_base__pixel_swizzler__xxxxxxxx__y_16be(uint8_t* dst_ptr,
23587                                              size_t dst_len,
23588                                              uint8_t* dst_palette_ptr,
23589                                              size_t dst_palette_len,
23590                                              const uint8_t* src_ptr,
23591                                              size_t src_len) {
23592   size_t dst_len8 = dst_len / 8;
23593   size_t src_len2 = src_len / 2;
23594   size_t len = (dst_len8 < src_len2) ? dst_len8 : src_len2;
23595   uint8_t* d = dst_ptr;
23596   const uint8_t* s = src_ptr;
23597   size_t n = len;
23598 
23599   while (n >= 1) {
23600     uint64_t s0 =
23601         ((uint64_t)(wuffs_base__peek_u16be__no_bounds_check(s + (0 * 2))));
23602     wuffs_base__poke_u64le__no_bounds_check(
23603         d + (0 * 8), 0xFFFF000000000000 | (0x000100010001 * s0));
23604 
23605     s += 1 * 2;
23606     d += 1 * 8;
23607     n -= 1;
23608   }
23609 
23610   return len;
23611 }
23612 
23613 // --------
23614 
23615 static uint64_t  //
wuffs_base__pixel_swizzler__y__y_16be(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)23616 wuffs_base__pixel_swizzler__y__y_16be(uint8_t* dst_ptr,
23617                                       size_t dst_len,
23618                                       uint8_t* dst_palette_ptr,
23619                                       size_t dst_palette_len,
23620                                       const uint8_t* src_ptr,
23621                                       size_t src_len) {
23622   size_t src_len2 = src_len / 2;
23623   size_t len = (dst_len < src_len2) ? dst_len : src_len2;
23624   uint8_t* d = dst_ptr;
23625   const uint8_t* s = src_ptr;
23626   size_t n = len;
23627 
23628   while (n >= 1) {
23629     d[0] = s[0];
23630 
23631     s += 1 * 2;
23632     d += 1 * 1;
23633     n -= 1;
23634   }
23635 
23636   return len;
23637 }
23638 
23639 static uint64_t  //
wuffs_base__pixel_swizzler__y_16le__y_16be(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)23640 wuffs_base__pixel_swizzler__y_16le__y_16be(uint8_t* dst_ptr,
23641                                            size_t dst_len,
23642                                            uint8_t* dst_palette_ptr,
23643                                            size_t dst_palette_len,
23644                                            const uint8_t* src_ptr,
23645                                            size_t src_len) {
23646   size_t dst_len2 = dst_len / 2;
23647   size_t src_len2 = src_len / 2;
23648   size_t len = (dst_len2 < src_len2) ? dst_len2 : src_len2;
23649   uint8_t* d = dst_ptr;
23650   const uint8_t* s = src_ptr;
23651   size_t n = len;
23652 
23653   while (n >= 1) {
23654     uint8_t s0 = s[0];
23655     uint8_t s1 = s[1];
23656     d[0] = s1;
23657     d[1] = s0;
23658 
23659     s += 1 * 2;
23660     d += 1 * 2;
23661     n -= 1;
23662   }
23663 
23664   return len;
23665 }
23666 
23667 // --------
23668 
23669 static uint64_t  //
wuffs_base__pixel_swizzler__transparent_black_src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,uint64_t num_pixels,uint32_t dst_pixfmt_bytes_per_pixel)23670 wuffs_base__pixel_swizzler__transparent_black_src(
23671     uint8_t* dst_ptr,
23672     size_t dst_len,
23673     uint8_t* dst_palette_ptr,
23674     size_t dst_palette_len,
23675     uint64_t num_pixels,
23676     uint32_t dst_pixfmt_bytes_per_pixel) {
23677   uint64_t n = ((uint64_t)dst_len) / dst_pixfmt_bytes_per_pixel;
23678   if (n > num_pixels) {
23679     n = num_pixels;
23680   }
23681   memset(dst_ptr, 0, ((size_t)(n * dst_pixfmt_bytes_per_pixel)));
23682   return n;
23683 }
23684 
23685 static uint64_t  //
wuffs_base__pixel_swizzler__transparent_black_src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,uint64_t num_pixels,uint32_t dst_pixfmt_bytes_per_pixel)23686 wuffs_base__pixel_swizzler__transparent_black_src_over(
23687     uint8_t* dst_ptr,
23688     size_t dst_len,
23689     uint8_t* dst_palette_ptr,
23690     size_t dst_palette_len,
23691     uint64_t num_pixels,
23692     uint32_t dst_pixfmt_bytes_per_pixel) {
23693   uint64_t n = ((uint64_t)dst_len) / dst_pixfmt_bytes_per_pixel;
23694   if (n > num_pixels) {
23695     n = num_pixels;
23696   }
23697   return n;
23698 }
23699 
23700 // --------
23701 
23702 static wuffs_base__pixel_swizzler__func  //
wuffs_base__pixel_swizzler__prepare__y(wuffs_base__pixel_swizzler * p,wuffs_base__pixel_format dst_pixfmt,wuffs_base__slice_u8 dst_palette,wuffs_base__slice_u8 src_palette,wuffs_base__pixel_blend blend)23703 wuffs_base__pixel_swizzler__prepare__y(wuffs_base__pixel_swizzler* p,
23704                                        wuffs_base__pixel_format dst_pixfmt,
23705                                        wuffs_base__slice_u8 dst_palette,
23706                                        wuffs_base__slice_u8 src_palette,
23707                                        wuffs_base__pixel_blend blend) {
23708   switch (dst_pixfmt.repr) {
23709     case WUFFS_BASE__PIXEL_FORMAT__Y:
23710       return wuffs_base__pixel_swizzler__copy_1_1;
23711 
23712     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
23713       return wuffs_base__pixel_swizzler__bgr_565__y;
23714 
23715     case WUFFS_BASE__PIXEL_FORMAT__BGR:
23716     case WUFFS_BASE__PIXEL_FORMAT__RGB:
23717       return wuffs_base__pixel_swizzler__xxx__y;
23718 
23719     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
23720     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
23721     case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
23722     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
23723     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
23724     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
23725     case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
23726     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
23727 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
23728       if (wuffs_base__cpu_arch__have_x86_sse42()) {
23729         return wuffs_base__pixel_swizzler__xxxx__y__x86_sse42;
23730       }
23731 #endif
23732       return wuffs_base__pixel_swizzler__xxxx__y;
23733 
23734     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
23735     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE:
23736     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL_4X16LE:
23737     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL_4X16LE:
23738       return wuffs_base__pixel_swizzler__xxxxxxxx__y;
23739   }
23740   return NULL;
23741 }
23742 
23743 static wuffs_base__pixel_swizzler__func  //
wuffs_base__pixel_swizzler__prepare__y_16be(wuffs_base__pixel_swizzler * p,wuffs_base__pixel_format dst_pixfmt,wuffs_base__slice_u8 dst_palette,wuffs_base__slice_u8 src_palette,wuffs_base__pixel_blend blend)23744 wuffs_base__pixel_swizzler__prepare__y_16be(wuffs_base__pixel_swizzler* p,
23745                                             wuffs_base__pixel_format dst_pixfmt,
23746                                             wuffs_base__slice_u8 dst_palette,
23747                                             wuffs_base__slice_u8 src_palette,
23748                                             wuffs_base__pixel_blend blend) {
23749   switch (dst_pixfmt.repr) {
23750     case WUFFS_BASE__PIXEL_FORMAT__Y:
23751       return wuffs_base__pixel_swizzler__y__y_16be;
23752 
23753     case WUFFS_BASE__PIXEL_FORMAT__Y_16LE:
23754       return wuffs_base__pixel_swizzler__y_16le__y_16be;
23755 
23756     case WUFFS_BASE__PIXEL_FORMAT__Y_16BE:
23757       return wuffs_base__pixel_swizzler__copy_2_2;
23758 
23759     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
23760       return wuffs_base__pixel_swizzler__bgr_565__y_16be;
23761 
23762     case WUFFS_BASE__PIXEL_FORMAT__BGR:
23763     case WUFFS_BASE__PIXEL_FORMAT__RGB:
23764       return wuffs_base__pixel_swizzler__xxx__y_16be;
23765 
23766     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
23767     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
23768     case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
23769     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
23770     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
23771     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
23772     case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
23773     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
23774       return wuffs_base__pixel_swizzler__xxxx__y_16be;
23775 
23776     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
23777     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE:
23778     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL_4X16LE:
23779     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL_4X16LE:
23780       return wuffs_base__pixel_swizzler__xxxxxxxx__y_16be;
23781   }
23782   return NULL;
23783 }
23784 
23785 static wuffs_base__pixel_swizzler__func  //
wuffs_base__pixel_swizzler__prepare__indexed__bgra_nonpremul(wuffs_base__pixel_swizzler * p,wuffs_base__pixel_format dst_pixfmt,wuffs_base__slice_u8 dst_palette,wuffs_base__slice_u8 src_palette,wuffs_base__pixel_blend blend)23786 wuffs_base__pixel_swizzler__prepare__indexed__bgra_nonpremul(
23787     wuffs_base__pixel_swizzler* p,
23788     wuffs_base__pixel_format dst_pixfmt,
23789     wuffs_base__slice_u8 dst_palette,
23790     wuffs_base__slice_u8 src_palette,
23791     wuffs_base__pixel_blend blend) {
23792   switch (dst_pixfmt.repr) {
23793     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:
23794       if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
23795           WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
23796         return NULL;
23797       }
23798       switch (blend) {
23799         case WUFFS_BASE__PIXEL_BLEND__SRC:
23800           return wuffs_base__pixel_swizzler__copy_1_1;
23801       }
23802       return NULL;
23803 
23804     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
23805       switch (blend) {
23806         case WUFFS_BASE__PIXEL_BLEND__SRC:
23807           if (wuffs_base__pixel_swizzler__squash_align4_bgr_565_8888(
23808                   dst_palette.ptr, dst_palette.len, src_palette.ptr,
23809                   src_palette.len, true) !=
23810               (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
23811             return NULL;
23812           }
23813           return wuffs_base__pixel_swizzler__bgr_565__index__src;
23814         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
23815           if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
23816               WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
23817             return NULL;
23818           }
23819           return wuffs_base__pixel_swizzler__bgr_565__index_bgra_nonpremul__src_over;
23820       }
23821       return NULL;
23822 
23823     case WUFFS_BASE__PIXEL_FORMAT__BGR:
23824       switch (blend) {
23825         case WUFFS_BASE__PIXEL_BLEND__SRC:
23826           if (wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src(
23827                   dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
23828                   src_palette.len) !=
23829               (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
23830             return NULL;
23831           }
23832           return wuffs_base__pixel_swizzler__xxx__index__src;
23833         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
23834           if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
23835               WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
23836             return NULL;
23837           }
23838           return wuffs_base__pixel_swizzler__xxx__index_bgra_nonpremul__src_over;
23839       }
23840       return NULL;
23841 
23842     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
23843       if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
23844           WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
23845         return NULL;
23846       }
23847       switch (blend) {
23848         case WUFFS_BASE__PIXEL_BLEND__SRC:
23849           return wuffs_base__pixel_swizzler__xxxx__index__src;
23850         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
23851           return wuffs_base__pixel_swizzler__bgra_nonpremul__index_bgra_nonpremul__src_over;
23852       }
23853       return NULL;
23854 
23855     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
23856       if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
23857           WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
23858         return NULL;
23859       }
23860       switch (blend) {
23861         case WUFFS_BASE__PIXEL_BLEND__SRC:
23862           return wuffs_base__pixel_swizzler__xxxxxxxx__index__src;
23863         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
23864           return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__index_bgra_nonpremul__src_over;
23865       }
23866       return NULL;
23867 
23868     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
23869       switch (blend) {
23870         case WUFFS_BASE__PIXEL_BLEND__SRC:
23871           if (wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src(
23872                   dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
23873                   src_palette.len) !=
23874               (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
23875             return NULL;
23876           }
23877           return wuffs_base__pixel_swizzler__xxxx__index__src;
23878         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
23879           if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
23880               WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
23881             return NULL;
23882           }
23883           return wuffs_base__pixel_swizzler__bgra_premul__index_bgra_nonpremul__src_over;
23884       }
23885       return NULL;
23886 
23887     case WUFFS_BASE__PIXEL_FORMAT__RGB:
23888       switch (blend) {
23889         case WUFFS_BASE__PIXEL_BLEND__SRC:
23890           if (wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src(
23891                   dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
23892                   src_palette.len) !=
23893               (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
23894             return NULL;
23895           }
23896           return wuffs_base__pixel_swizzler__xxx__index__src;
23897         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
23898           if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx(
23899                   dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
23900                   src_palette.len) !=
23901               (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
23902             return NULL;
23903           }
23904           return wuffs_base__pixel_swizzler__xxx__index_bgra_nonpremul__src_over;
23905       }
23906       return NULL;
23907 
23908     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
23909       if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx(
23910               dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
23911               src_palette.len) !=
23912           (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
23913         return NULL;
23914       }
23915       switch (blend) {
23916         case WUFFS_BASE__PIXEL_BLEND__SRC:
23917           return wuffs_base__pixel_swizzler__xxxx__index__src;
23918         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
23919           return wuffs_base__pixel_swizzler__bgra_nonpremul__index_bgra_nonpremul__src_over;
23920       }
23921       return NULL;
23922 
23923     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
23924       switch (blend) {
23925         case WUFFS_BASE__PIXEL_BLEND__SRC:
23926           if (wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src(
23927                   dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
23928                   src_palette.len) !=
23929               (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
23930             return NULL;
23931           }
23932           return wuffs_base__pixel_swizzler__xxxx__index__src;
23933         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
23934           if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx(
23935                   dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
23936                   src_palette.len) !=
23937               (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
23938             return NULL;
23939           }
23940           return wuffs_base__pixel_swizzler__bgra_premul__index_bgra_nonpremul__src_over;
23941       }
23942       return NULL;
23943 
23944     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
23945       // TODO.
23946       break;
23947   }
23948   return NULL;
23949 }
23950 
23951 static wuffs_base__pixel_swizzler__func  //
wuffs_base__pixel_swizzler__prepare__indexed__bgra_binary(wuffs_base__pixel_swizzler * p,wuffs_base__pixel_format dst_pixfmt,wuffs_base__slice_u8 dst_palette,wuffs_base__slice_u8 src_palette,wuffs_base__pixel_blend blend)23952 wuffs_base__pixel_swizzler__prepare__indexed__bgra_binary(
23953     wuffs_base__pixel_swizzler* p,
23954     wuffs_base__pixel_format dst_pixfmt,
23955     wuffs_base__slice_u8 dst_palette,
23956     wuffs_base__slice_u8 src_palette,
23957     wuffs_base__pixel_blend blend) {
23958   switch (dst_pixfmt.repr) {
23959     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:
23960     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL:
23961     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY:
23962       if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
23963           WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
23964         return NULL;
23965       }
23966       switch (blend) {
23967         case WUFFS_BASE__PIXEL_BLEND__SRC:
23968           return wuffs_base__pixel_swizzler__copy_1_1;
23969       }
23970       return NULL;
23971 
23972     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
23973       if (wuffs_base__pixel_swizzler__squash_align4_bgr_565_8888(
23974               dst_palette.ptr, dst_palette.len, src_palette.ptr,
23975               src_palette.len, false) !=
23976           (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
23977         return NULL;
23978       }
23979       switch (blend) {
23980         case WUFFS_BASE__PIXEL_BLEND__SRC:
23981           return wuffs_base__pixel_swizzler__bgr_565__index__src;
23982         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
23983           return wuffs_base__pixel_swizzler__bgr_565__index_binary_alpha__src_over;
23984       }
23985       return NULL;
23986 
23987     case WUFFS_BASE__PIXEL_FORMAT__BGR:
23988       if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
23989           WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
23990         return NULL;
23991       }
23992       switch (blend) {
23993         case WUFFS_BASE__PIXEL_BLEND__SRC:
23994           return wuffs_base__pixel_swizzler__xxx__index__src;
23995         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
23996           return wuffs_base__pixel_swizzler__xxx__index_binary_alpha__src_over;
23997       }
23998       return NULL;
23999 
24000     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
24001     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
24002     case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
24003       if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
24004           WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
24005         return NULL;
24006       }
24007       switch (blend) {
24008         case WUFFS_BASE__PIXEL_BLEND__SRC:
24009           return wuffs_base__pixel_swizzler__xxxx__index__src;
24010         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24011           return wuffs_base__pixel_swizzler__xxxx__index_binary_alpha__src_over;
24012       }
24013       return NULL;
24014 
24015     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
24016     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE:
24017       if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
24018           WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
24019         return NULL;
24020       }
24021       switch (blend) {
24022         case WUFFS_BASE__PIXEL_BLEND__SRC:
24023           return wuffs_base__pixel_swizzler__xxxxxxxx__index__src;
24024         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24025           return wuffs_base__pixel_swizzler__xxxxxxxx__index_binary_alpha__src_over;
24026       }
24027       return NULL;
24028 
24029     case WUFFS_BASE__PIXEL_FORMAT__RGB:
24030       if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx(
24031               dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
24032               src_palette.len) !=
24033           (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
24034         return NULL;
24035       }
24036       switch (blend) {
24037         case WUFFS_BASE__PIXEL_BLEND__SRC:
24038           return wuffs_base__pixel_swizzler__xxx__index__src;
24039         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24040           return wuffs_base__pixel_swizzler__xxx__index_binary_alpha__src_over;
24041       }
24042       return NULL;
24043 
24044     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
24045     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
24046     case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
24047       if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx(
24048               dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
24049               src_palette.len) !=
24050           (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
24051         return NULL;
24052       }
24053       switch (blend) {
24054         case WUFFS_BASE__PIXEL_BLEND__SRC:
24055           return wuffs_base__pixel_swizzler__xxxx__index__src;
24056         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24057           return wuffs_base__pixel_swizzler__xxxx__index_binary_alpha__src_over;
24058       }
24059       return NULL;
24060   }
24061   return NULL;
24062 }
24063 
24064 static wuffs_base__pixel_swizzler__func  //
wuffs_base__pixel_swizzler__prepare__bgr_565(wuffs_base__pixel_swizzler * p,wuffs_base__pixel_format dst_pixfmt,wuffs_base__slice_u8 dst_palette,wuffs_base__slice_u8 src_palette,wuffs_base__pixel_blend blend)24065 wuffs_base__pixel_swizzler__prepare__bgr_565(
24066     wuffs_base__pixel_swizzler* p,
24067     wuffs_base__pixel_format dst_pixfmt,
24068     wuffs_base__slice_u8 dst_palette,
24069     wuffs_base__slice_u8 src_palette,
24070     wuffs_base__pixel_blend blend) {
24071   switch (dst_pixfmt.repr) {
24072     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
24073       return wuffs_base__pixel_swizzler__copy_2_2;
24074 
24075     case WUFFS_BASE__PIXEL_FORMAT__BGR:
24076       return wuffs_base__pixel_swizzler__bgr__bgr_565;
24077 
24078     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
24079     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
24080     case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
24081     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
24082       return wuffs_base__pixel_swizzler__bgrw__bgr_565;
24083 
24084     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
24085     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE:
24086       return wuffs_base__pixel_swizzler__bgrw_4x16le__bgr_565;
24087 
24088     case WUFFS_BASE__PIXEL_FORMAT__RGB:
24089       return wuffs_base__pixel_swizzler__rgb__bgr_565;
24090 
24091     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
24092     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
24093     case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
24094     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
24095       return wuffs_base__pixel_swizzler__rgbw__bgr_565;
24096   }
24097   return NULL;
24098 }
24099 
24100 static wuffs_base__pixel_swizzler__func  //
wuffs_base__pixel_swizzler__prepare__bgr(wuffs_base__pixel_swizzler * p,wuffs_base__pixel_format dst_pixfmt,wuffs_base__slice_u8 dst_palette,wuffs_base__slice_u8 src_palette,wuffs_base__pixel_blend blend)24101 wuffs_base__pixel_swizzler__prepare__bgr(wuffs_base__pixel_swizzler* p,
24102                                          wuffs_base__pixel_format dst_pixfmt,
24103                                          wuffs_base__slice_u8 dst_palette,
24104                                          wuffs_base__slice_u8 src_palette,
24105                                          wuffs_base__pixel_blend blend) {
24106   switch (dst_pixfmt.repr) {
24107     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
24108       return wuffs_base__pixel_swizzler__bgr_565__bgr;
24109 
24110     case WUFFS_BASE__PIXEL_FORMAT__BGR:
24111       return wuffs_base__pixel_swizzler__copy_3_3;
24112 
24113     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
24114     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
24115     case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
24116     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
24117       return wuffs_base__pixel_swizzler__bgrw__bgr;
24118 
24119     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
24120     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE:
24121       return wuffs_base__pixel_swizzler__bgrw_4x16le__bgr;
24122 
24123     case WUFFS_BASE__PIXEL_FORMAT__RGB:
24124       return wuffs_base__pixel_swizzler__swap_rgb_bgr;
24125 
24126     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
24127     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
24128     case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
24129     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
24130 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
24131       if (wuffs_base__cpu_arch__have_x86_sse42()) {
24132         return wuffs_base__pixel_swizzler__bgrw__rgb__x86_sse42;
24133       }
24134 #endif
24135       return wuffs_base__pixel_swizzler__bgrw__rgb;
24136   }
24137   return NULL;
24138 }
24139 
24140 static wuffs_base__pixel_swizzler__func  //
wuffs_base__pixel_swizzler__prepare__bgra_nonpremul(wuffs_base__pixel_swizzler * p,wuffs_base__pixel_format dst_pixfmt,wuffs_base__slice_u8 dst_palette,wuffs_base__slice_u8 src_palette,wuffs_base__pixel_blend blend)24141 wuffs_base__pixel_swizzler__prepare__bgra_nonpremul(
24142     wuffs_base__pixel_swizzler* p,
24143     wuffs_base__pixel_format dst_pixfmt,
24144     wuffs_base__slice_u8 dst_palette,
24145     wuffs_base__slice_u8 src_palette,
24146     wuffs_base__pixel_blend blend) {
24147   switch (dst_pixfmt.repr) {
24148     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
24149       switch (blend) {
24150         case WUFFS_BASE__PIXEL_BLEND__SRC:
24151           return wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul__src;
24152         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24153           return wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul__src_over;
24154       }
24155       return NULL;
24156 
24157     case WUFFS_BASE__PIXEL_FORMAT__BGR:
24158       switch (blend) {
24159         case WUFFS_BASE__PIXEL_BLEND__SRC:
24160           return wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src;
24161         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24162           return wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src_over;
24163       }
24164       return NULL;
24165 
24166     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
24167       switch (blend) {
24168         case WUFFS_BASE__PIXEL_BLEND__SRC:
24169           return wuffs_base__pixel_swizzler__copy_4_4;
24170         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24171           return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul__src_over;
24172       }
24173       return NULL;
24174 
24175     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
24176       switch (blend) {
24177         case WUFFS_BASE__PIXEL_BLEND__SRC:
24178           return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul__src;
24179         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24180           return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul__src_over;
24181       }
24182       return NULL;
24183 
24184     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
24185       switch (blend) {
24186         case WUFFS_BASE__PIXEL_BLEND__SRC:
24187           return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src;
24188         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24189           return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src_over;
24190       }
24191       return NULL;
24192 
24193     case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
24194     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
24195       // TODO.
24196       break;
24197 
24198     case WUFFS_BASE__PIXEL_FORMAT__RGB:
24199       switch (blend) {
24200         case WUFFS_BASE__PIXEL_BLEND__SRC:
24201           return wuffs_base__pixel_swizzler__bgr__rgba_nonpremul__src;
24202         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24203           return wuffs_base__pixel_swizzler__bgr__rgba_nonpremul__src_over;
24204       }
24205       return NULL;
24206 
24207     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
24208       switch (blend) {
24209         case WUFFS_BASE__PIXEL_BLEND__SRC:
24210 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
24211           if (wuffs_base__cpu_arch__have_x86_sse42()) {
24212             return wuffs_base__pixel_swizzler__swap_rgbx_bgrx__x86_sse42;
24213           }
24214 #endif
24215           return wuffs_base__pixel_swizzler__swap_rgbx_bgrx;
24216         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24217           return wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_nonpremul__src_over;
24218       }
24219       return NULL;
24220 
24221     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
24222       switch (blend) {
24223         case WUFFS_BASE__PIXEL_BLEND__SRC:
24224           return wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src;
24225         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24226           return wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src_over;
24227       }
24228       return NULL;
24229 
24230     case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
24231     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
24232       // TODO.
24233       break;
24234   }
24235   return NULL;
24236 }
24237 
24238 static wuffs_base__pixel_swizzler__func  //
wuffs_base__pixel_swizzler__prepare__bgra_nonpremul_4x16le(wuffs_base__pixel_swizzler * p,wuffs_base__pixel_format dst_pixfmt,wuffs_base__slice_u8 dst_palette,wuffs_base__slice_u8 src_palette,wuffs_base__pixel_blend blend)24239 wuffs_base__pixel_swizzler__prepare__bgra_nonpremul_4x16le(
24240     wuffs_base__pixel_swizzler* p,
24241     wuffs_base__pixel_format dst_pixfmt,
24242     wuffs_base__slice_u8 dst_palette,
24243     wuffs_base__slice_u8 src_palette,
24244     wuffs_base__pixel_blend blend) {
24245   switch (dst_pixfmt.repr) {
24246     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
24247       switch (blend) {
24248         case WUFFS_BASE__PIXEL_BLEND__SRC:
24249           return wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul_4x16le__src;
24250         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24251           return wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul_4x16le__src_over;
24252       }
24253       return NULL;
24254 
24255     case WUFFS_BASE__PIXEL_FORMAT__BGR:
24256       switch (blend) {
24257         case WUFFS_BASE__PIXEL_BLEND__SRC:
24258           return wuffs_base__pixel_swizzler__bgr__bgra_nonpremul_4x16le__src;
24259         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24260           return wuffs_base__pixel_swizzler__bgr__bgra_nonpremul_4x16le__src_over;
24261       }
24262       return NULL;
24263 
24264     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
24265       switch (blend) {
24266         case WUFFS_BASE__PIXEL_BLEND__SRC:
24267           return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul_4x16le__src;
24268         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24269           return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul_4x16le__src_over;
24270       }
24271       return NULL;
24272 
24273     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
24274       switch (blend) {
24275         case WUFFS_BASE__PIXEL_BLEND__SRC:
24276           return wuffs_base__pixel_swizzler__copy_8_8;
24277         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24278           return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul_4x16le__src_over;
24279       }
24280       return NULL;
24281 
24282     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
24283       switch (blend) {
24284         case WUFFS_BASE__PIXEL_BLEND__SRC:
24285           return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul_4x16le__src;
24286         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24287           return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul_4x16le__src_over;
24288       }
24289       return NULL;
24290 
24291     case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
24292     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
24293       // TODO.
24294       break;
24295 
24296     case WUFFS_BASE__PIXEL_FORMAT__RGB:
24297       switch (blend) {
24298         case WUFFS_BASE__PIXEL_BLEND__SRC:
24299           return wuffs_base__pixel_swizzler__bgr__rgba_nonpremul_4x16le__src;
24300         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24301           return wuffs_base__pixel_swizzler__bgr__rgba_nonpremul_4x16le__src_over;
24302       }
24303       return NULL;
24304 
24305     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
24306       switch (blend) {
24307         case WUFFS_BASE__PIXEL_BLEND__SRC:
24308           return wuffs_base__pixel_swizzler__rgba_nonpremul__bgra_nonpremul_4x16le__src;
24309         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24310           return wuffs_base__pixel_swizzler__rgba_nonpremul__bgra_nonpremul_4x16le__src_over;
24311       }
24312       break;
24313 
24314     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
24315       switch (blend) {
24316         case WUFFS_BASE__PIXEL_BLEND__SRC:
24317           return wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul_4x16le__src;
24318         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24319           return wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul_4x16le__src_over;
24320       }
24321       return NULL;
24322 
24323     case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
24324     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
24325       // TODO.
24326       break;
24327   }
24328   return NULL;
24329 }
24330 
24331 static wuffs_base__pixel_swizzler__func  //
wuffs_base__pixel_swizzler__prepare__bgra_premul(wuffs_base__pixel_swizzler * p,wuffs_base__pixel_format dst_pixfmt,wuffs_base__slice_u8 dst_palette,wuffs_base__slice_u8 src_palette,wuffs_base__pixel_blend blend)24332 wuffs_base__pixel_swizzler__prepare__bgra_premul(
24333     wuffs_base__pixel_swizzler* p,
24334     wuffs_base__pixel_format dst_pixfmt,
24335     wuffs_base__slice_u8 dst_palette,
24336     wuffs_base__slice_u8 src_palette,
24337     wuffs_base__pixel_blend blend) {
24338   switch (dst_pixfmt.repr) {
24339     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
24340       switch (blend) {
24341         case WUFFS_BASE__PIXEL_BLEND__SRC:
24342           return wuffs_base__pixel_swizzler__bgr_565__bgra_premul__src;
24343         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24344           return wuffs_base__pixel_swizzler__bgr_565__bgra_premul__src_over;
24345       }
24346       return NULL;
24347 
24348     case WUFFS_BASE__PIXEL_FORMAT__BGR:
24349       switch (blend) {
24350         case WUFFS_BASE__PIXEL_BLEND__SRC:
24351           return wuffs_base__pixel_swizzler__bgr__bgra_premul__src;
24352         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24353           return wuffs_base__pixel_swizzler__bgr__bgra_premul__src_over;
24354       }
24355       return NULL;
24356 
24357     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
24358       switch (blend) {
24359         case WUFFS_BASE__PIXEL_BLEND__SRC:
24360           return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src;
24361         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24362           return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src_over;
24363       }
24364       return NULL;
24365 
24366     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
24367       switch (blend) {
24368         case WUFFS_BASE__PIXEL_BLEND__SRC:
24369           return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_premul__src;
24370         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24371           return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_premul__src_over;
24372       }
24373       return NULL;
24374 
24375     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
24376       switch (blend) {
24377         case WUFFS_BASE__PIXEL_BLEND__SRC:
24378           return wuffs_base__pixel_swizzler__copy_4_4;
24379         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24380           return wuffs_base__pixel_swizzler__bgra_premul__bgra_premul__src_over;
24381       }
24382       return NULL;
24383 
24384     case WUFFS_BASE__PIXEL_FORMAT__RGB:
24385       switch (blend) {
24386         case WUFFS_BASE__PIXEL_BLEND__SRC:
24387           return wuffs_base__pixel_swizzler__bgr__rgba_premul__src;
24388         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24389           return wuffs_base__pixel_swizzler__bgr__rgba_premul__src_over;
24390       }
24391       return NULL;
24392 
24393     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
24394       switch (blend) {
24395         case WUFFS_BASE__PIXEL_BLEND__SRC:
24396           return wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src;
24397         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24398           return wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src_over;
24399       }
24400       return NULL;
24401 
24402     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
24403       switch (blend) {
24404         case WUFFS_BASE__PIXEL_BLEND__SRC:
24405 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
24406           if (wuffs_base__cpu_arch__have_x86_sse42()) {
24407             return wuffs_base__pixel_swizzler__swap_rgbx_bgrx__x86_sse42;
24408           }
24409 #endif
24410           return wuffs_base__pixel_swizzler__swap_rgbx_bgrx;
24411         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24412           return wuffs_base__pixel_swizzler__bgra_premul__rgba_premul__src_over;
24413       }
24414       return NULL;
24415   }
24416   return NULL;
24417 }
24418 
24419 static wuffs_base__pixel_swizzler__func  //
wuffs_base__pixel_swizzler__prepare__bgrx(wuffs_base__pixel_swizzler * p,wuffs_base__pixel_format dst_pixfmt,wuffs_base__slice_u8 dst_palette,wuffs_base__slice_u8 src_palette,wuffs_base__pixel_blend blend)24420 wuffs_base__pixel_swizzler__prepare__bgrx(wuffs_base__pixel_swizzler* p,
24421                                           wuffs_base__pixel_format dst_pixfmt,
24422                                           wuffs_base__slice_u8 dst_palette,
24423                                           wuffs_base__slice_u8 src_palette,
24424                                           wuffs_base__pixel_blend blend) {
24425   switch (dst_pixfmt.repr) {
24426     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
24427       return wuffs_base__pixel_swizzler__bgr_565__bgrx;
24428 
24429     case WUFFS_BASE__PIXEL_FORMAT__BGR:
24430       return wuffs_base__pixel_swizzler__xxx__xxxx;
24431 
24432     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
24433     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
24434     case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
24435       return wuffs_base__pixel_swizzler__bgrw__bgrx;
24436 
24437     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
24438       return wuffs_base__pixel_swizzler__bgrw_4x16le__bgrx;
24439 
24440     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
24441       return wuffs_base__pixel_swizzler__copy_4_4;
24442 
24443     case WUFFS_BASE__PIXEL_FORMAT__RGB:
24444       return wuffs_base__pixel_swizzler__bgr__rgbx;
24445 
24446     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
24447     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
24448     case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
24449     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
24450       return wuffs_base__pixel_swizzler__bgrw__rgbx;
24451   }
24452   return NULL;
24453 }
24454 
24455 static wuffs_base__pixel_swizzler__func  //
wuffs_base__pixel_swizzler__prepare__rgb(wuffs_base__pixel_swizzler * p,wuffs_base__pixel_format dst_pixfmt,wuffs_base__slice_u8 dst_palette,wuffs_base__slice_u8 src_palette,wuffs_base__pixel_blend blend)24456 wuffs_base__pixel_swizzler__prepare__rgb(wuffs_base__pixel_swizzler* p,
24457                                          wuffs_base__pixel_format dst_pixfmt,
24458                                          wuffs_base__slice_u8 dst_palette,
24459                                          wuffs_base__slice_u8 src_palette,
24460                                          wuffs_base__pixel_blend blend) {
24461   switch (dst_pixfmt.repr) {
24462     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
24463       return wuffs_base__pixel_swizzler__bgr_565__rgb;
24464 
24465     case WUFFS_BASE__PIXEL_FORMAT__BGR:
24466       return wuffs_base__pixel_swizzler__swap_rgb_bgr;
24467 
24468     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
24469     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
24470     case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
24471     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
24472 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
24473       if (wuffs_base__cpu_arch__have_x86_sse42()) {
24474         return wuffs_base__pixel_swizzler__bgrw__rgb__x86_sse42;
24475       }
24476 #endif
24477       return wuffs_base__pixel_swizzler__bgrw__rgb;
24478 
24479     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
24480       return wuffs_base__pixel_swizzler__bgrw_4x16le__rgb;
24481 
24482     case WUFFS_BASE__PIXEL_FORMAT__RGB:
24483       return wuffs_base__pixel_swizzler__copy_3_3;
24484 
24485     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
24486     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
24487     case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
24488     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
24489       return wuffs_base__pixel_swizzler__bgrw__bgr;
24490   }
24491   return NULL;
24492 }
24493 
24494 static wuffs_base__pixel_swizzler__func  //
wuffs_base__pixel_swizzler__prepare__rgba_nonpremul(wuffs_base__pixel_swizzler * p,wuffs_base__pixel_format dst_pixfmt,wuffs_base__slice_u8 dst_palette,wuffs_base__slice_u8 src_palette,wuffs_base__pixel_blend blend)24495 wuffs_base__pixel_swizzler__prepare__rgba_nonpremul(
24496     wuffs_base__pixel_swizzler* p,
24497     wuffs_base__pixel_format dst_pixfmt,
24498     wuffs_base__slice_u8 dst_palette,
24499     wuffs_base__slice_u8 src_palette,
24500     wuffs_base__pixel_blend blend) {
24501   switch (dst_pixfmt.repr) {
24502     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
24503       switch (blend) {
24504         case WUFFS_BASE__PIXEL_BLEND__SRC:
24505           return wuffs_base__pixel_swizzler__bgr_565__rgba_nonpremul__src;
24506         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24507           return wuffs_base__pixel_swizzler__bgr_565__rgba_nonpremul__src_over;
24508       }
24509       return NULL;
24510 
24511     case WUFFS_BASE__PIXEL_FORMAT__BGR:
24512       switch (blend) {
24513         case WUFFS_BASE__PIXEL_BLEND__SRC:
24514           return wuffs_base__pixel_swizzler__bgr__rgba_nonpremul__src;
24515         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24516           return wuffs_base__pixel_swizzler__bgr__rgba_nonpremul__src_over;
24517       }
24518       return NULL;
24519 
24520     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
24521       switch (blend) {
24522         case WUFFS_BASE__PIXEL_BLEND__SRC:
24523 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
24524           if (wuffs_base__cpu_arch__have_x86_sse42()) {
24525             return wuffs_base__pixel_swizzler__swap_rgbx_bgrx__x86_sse42;
24526           }
24527 #endif
24528           return wuffs_base__pixel_swizzler__swap_rgbx_bgrx;
24529         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24530           return wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_nonpremul__src_over;
24531       }
24532       return NULL;
24533 
24534     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
24535       switch (blend) {
24536         case WUFFS_BASE__PIXEL_BLEND__SRC:
24537           return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_nonpremul__src;
24538         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24539           return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_nonpremul__src_over;
24540       }
24541       return NULL;
24542 
24543     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
24544       switch (blend) {
24545         case WUFFS_BASE__PIXEL_BLEND__SRC:
24546           return wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src;
24547         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24548           return wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src_over;
24549       }
24550       return NULL;
24551 
24552     case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
24553     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
24554       // TODO.
24555       break;
24556 
24557     case WUFFS_BASE__PIXEL_FORMAT__RGB:
24558       switch (blend) {
24559         case WUFFS_BASE__PIXEL_BLEND__SRC:
24560           return wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src;
24561         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24562           return wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src_over;
24563       }
24564       return NULL;
24565 
24566     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
24567       switch (blend) {
24568         case WUFFS_BASE__PIXEL_BLEND__SRC:
24569           return wuffs_base__pixel_swizzler__copy_4_4;
24570         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24571           return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul__src_over;
24572       }
24573       return NULL;
24574 
24575     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
24576       switch (blend) {
24577         case WUFFS_BASE__PIXEL_BLEND__SRC:
24578           return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src;
24579         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24580           return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src_over;
24581       }
24582       return NULL;
24583 
24584     case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
24585     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
24586       // TODO.
24587       break;
24588   }
24589   return NULL;
24590 }
24591 
24592 static wuffs_base__pixel_swizzler__func  //
wuffs_base__pixel_swizzler__prepare__rgba_premul(wuffs_base__pixel_swizzler * p,wuffs_base__pixel_format dst_pixfmt,wuffs_base__slice_u8 dst_palette,wuffs_base__slice_u8 src_palette,wuffs_base__pixel_blend blend)24593 wuffs_base__pixel_swizzler__prepare__rgba_premul(
24594     wuffs_base__pixel_swizzler* p,
24595     wuffs_base__pixel_format dst_pixfmt,
24596     wuffs_base__slice_u8 dst_palette,
24597     wuffs_base__slice_u8 src_palette,
24598     wuffs_base__pixel_blend blend) {
24599   switch (dst_pixfmt.repr) {
24600     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
24601       switch (blend) {
24602         case WUFFS_BASE__PIXEL_BLEND__SRC:
24603           return wuffs_base__pixel_swizzler__bgr_565__rgba_premul__src;
24604         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24605           return wuffs_base__pixel_swizzler__bgr_565__rgba_premul__src_over;
24606       }
24607       return NULL;
24608 
24609     case WUFFS_BASE__PIXEL_FORMAT__BGR:
24610       switch (blend) {
24611         case WUFFS_BASE__PIXEL_BLEND__SRC:
24612           return wuffs_base__pixel_swizzler__bgr__rgba_premul__src;
24613         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24614           return wuffs_base__pixel_swizzler__bgr__rgba_premul__src_over;
24615       }
24616       return NULL;
24617 
24618     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
24619       switch (blend) {
24620         case WUFFS_BASE__PIXEL_BLEND__SRC:
24621           return wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src;
24622         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24623           return wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src_over;
24624       }
24625       return NULL;
24626 
24627     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
24628       switch (blend) {
24629         case WUFFS_BASE__PIXEL_BLEND__SRC:
24630           return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_premul__src;
24631         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24632           return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_premul__src_over;
24633       }
24634       return NULL;
24635 
24636     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
24637       switch (blend) {
24638         case WUFFS_BASE__PIXEL_BLEND__SRC:
24639 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
24640           if (wuffs_base__cpu_arch__have_x86_sse42()) {
24641             return wuffs_base__pixel_swizzler__swap_rgbx_bgrx__x86_sse42;
24642           }
24643 #endif
24644           return wuffs_base__pixel_swizzler__swap_rgbx_bgrx;
24645         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24646           return wuffs_base__pixel_swizzler__bgra_premul__rgba_premul__src_over;
24647       }
24648       return NULL;
24649 
24650     case WUFFS_BASE__PIXEL_FORMAT__RGB:
24651       switch (blend) {
24652         case WUFFS_BASE__PIXEL_BLEND__SRC:
24653           return wuffs_base__pixel_swizzler__bgr__bgra_premul__src;
24654         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24655           return wuffs_base__pixel_swizzler__bgr__bgra_premul__src_over;
24656       }
24657       return NULL;
24658 
24659     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
24660       switch (blend) {
24661         case WUFFS_BASE__PIXEL_BLEND__SRC:
24662           return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src;
24663         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24664           return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src_over;
24665       }
24666       return NULL;
24667 
24668     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
24669       switch (blend) {
24670         case WUFFS_BASE__PIXEL_BLEND__SRC:
24671           return wuffs_base__pixel_swizzler__copy_4_4;
24672         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24673           return wuffs_base__pixel_swizzler__bgra_premul__bgra_premul__src_over;
24674       }
24675       return NULL;
24676   }
24677   return NULL;
24678 }
24679 
24680 // --------
24681 
24682 WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
wuffs_base__pixel_swizzler__prepare(wuffs_base__pixel_swizzler * p,wuffs_base__pixel_format dst_pixfmt,wuffs_base__slice_u8 dst_palette,wuffs_base__pixel_format src_pixfmt,wuffs_base__slice_u8 src_palette,wuffs_base__pixel_blend blend)24683 wuffs_base__pixel_swizzler__prepare(wuffs_base__pixel_swizzler* p,
24684                                     wuffs_base__pixel_format dst_pixfmt,
24685                                     wuffs_base__slice_u8 dst_palette,
24686                                     wuffs_base__pixel_format src_pixfmt,
24687                                     wuffs_base__slice_u8 src_palette,
24688                                     wuffs_base__pixel_blend blend) {
24689   if (!p) {
24690     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
24691   }
24692   p->private_impl.func = NULL;
24693   p->private_impl.transparent_black_func = NULL;
24694   p->private_impl.dst_pixfmt_bytes_per_pixel = 0;
24695   p->private_impl.src_pixfmt_bytes_per_pixel = 0;
24696 
24697   wuffs_base__pixel_swizzler__func func = NULL;
24698   wuffs_base__pixel_swizzler__transparent_black_func transparent_black_func =
24699       NULL;
24700 
24701   uint32_t dst_pixfmt_bits_per_pixel =
24702       wuffs_base__pixel_format__bits_per_pixel(&dst_pixfmt);
24703   if ((dst_pixfmt_bits_per_pixel == 0) ||
24704       ((dst_pixfmt_bits_per_pixel & 7) != 0)) {
24705     return wuffs_base__make_status(
24706         wuffs_base__error__unsupported_pixel_swizzler_option);
24707   }
24708 
24709   uint32_t src_pixfmt_bits_per_pixel =
24710       wuffs_base__pixel_format__bits_per_pixel(&src_pixfmt);
24711   if ((src_pixfmt_bits_per_pixel == 0) ||
24712       ((src_pixfmt_bits_per_pixel & 7) != 0)) {
24713     return wuffs_base__make_status(
24714         wuffs_base__error__unsupported_pixel_swizzler_option);
24715   }
24716 
24717   // TODO: support many more formats.
24718 
24719   switch (blend) {
24720     case WUFFS_BASE__PIXEL_BLEND__SRC:
24721       transparent_black_func =
24722           wuffs_base__pixel_swizzler__transparent_black_src;
24723       break;
24724 
24725     case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
24726       transparent_black_func =
24727           wuffs_base__pixel_swizzler__transparent_black_src_over;
24728       break;
24729   }
24730 
24731   switch (src_pixfmt.repr) {
24732     case WUFFS_BASE__PIXEL_FORMAT__Y:
24733       func = wuffs_base__pixel_swizzler__prepare__y(p, dst_pixfmt, dst_palette,
24734                                                     src_palette, blend);
24735       break;
24736 
24737     case WUFFS_BASE__PIXEL_FORMAT__Y_16BE:
24738       func = wuffs_base__pixel_swizzler__prepare__y_16be(
24739           p, dst_pixfmt, dst_palette, src_palette, blend);
24740       break;
24741 
24742     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:
24743       func = wuffs_base__pixel_swizzler__prepare__indexed__bgra_nonpremul(
24744           p, dst_pixfmt, dst_palette, src_palette, blend);
24745       break;
24746 
24747     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY:
24748       func = wuffs_base__pixel_swizzler__prepare__indexed__bgra_binary(
24749           p, dst_pixfmt, dst_palette, src_palette, blend);
24750       break;
24751 
24752     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
24753       func = wuffs_base__pixel_swizzler__prepare__bgr_565(
24754           p, dst_pixfmt, dst_palette, src_palette, blend);
24755       break;
24756 
24757     case WUFFS_BASE__PIXEL_FORMAT__BGR:
24758       func = wuffs_base__pixel_swizzler__prepare__bgr(
24759           p, dst_pixfmt, dst_palette, src_palette, blend);
24760       break;
24761 
24762     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
24763       func = wuffs_base__pixel_swizzler__prepare__bgra_nonpremul(
24764           p, dst_pixfmt, dst_palette, src_palette, blend);
24765       break;
24766 
24767     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
24768       func = wuffs_base__pixel_swizzler__prepare__bgra_nonpremul_4x16le(
24769           p, dst_pixfmt, dst_palette, src_palette, blend);
24770       break;
24771 
24772     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
24773       func = wuffs_base__pixel_swizzler__prepare__bgra_premul(
24774           p, dst_pixfmt, dst_palette, src_palette, blend);
24775       break;
24776 
24777     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
24778       func = wuffs_base__pixel_swizzler__prepare__bgrx(
24779           p, dst_pixfmt, dst_palette, src_palette, blend);
24780       break;
24781 
24782     case WUFFS_BASE__PIXEL_FORMAT__RGB:
24783       func = wuffs_base__pixel_swizzler__prepare__rgb(
24784           p, dst_pixfmt, dst_palette, src_palette, blend);
24785       break;
24786 
24787     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
24788       func = wuffs_base__pixel_swizzler__prepare__rgba_nonpremul(
24789           p, dst_pixfmt, dst_palette, src_palette, blend);
24790       break;
24791 
24792     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
24793       func = wuffs_base__pixel_swizzler__prepare__rgba_premul(
24794           p, dst_pixfmt, dst_palette, src_palette, blend);
24795       break;
24796   }
24797 
24798   p->private_impl.func = func;
24799   p->private_impl.transparent_black_func = transparent_black_func;
24800   p->private_impl.dst_pixfmt_bytes_per_pixel = dst_pixfmt_bits_per_pixel / 8;
24801   p->private_impl.src_pixfmt_bytes_per_pixel = src_pixfmt_bits_per_pixel / 8;
24802   return wuffs_base__make_status(
24803       func ? NULL : wuffs_base__error__unsupported_pixel_swizzler_option);
24804 }
24805 
24806 WUFFS_BASE__MAYBE_STATIC uint64_t  //
wuffs_base__pixel_swizzler__limited_swizzle_u32_interleaved_from_reader(const wuffs_base__pixel_swizzler * p,uint32_t up_to_num_pixels,wuffs_base__slice_u8 dst,wuffs_base__slice_u8 dst_palette,const uint8_t ** ptr_iop_r,const uint8_t * io2_r)24807 wuffs_base__pixel_swizzler__limited_swizzle_u32_interleaved_from_reader(
24808     const wuffs_base__pixel_swizzler* p,
24809     uint32_t up_to_num_pixels,
24810     wuffs_base__slice_u8 dst,
24811     wuffs_base__slice_u8 dst_palette,
24812     const uint8_t** ptr_iop_r,
24813     const uint8_t* io2_r) {
24814   if (p && p->private_impl.func) {
24815     const uint8_t* iop_r = *ptr_iop_r;
24816     uint64_t src_len = wuffs_base__u64__min(
24817         ((uint64_t)up_to_num_pixels) *
24818             ((uint64_t)p->private_impl.src_pixfmt_bytes_per_pixel),
24819         ((uint64_t)(io2_r - iop_r)));
24820     uint64_t n =
24821         (*p->private_impl.func)(dst.ptr, dst.len, dst_palette.ptr,
24822                                 dst_palette.len, iop_r, (size_t)src_len);
24823     *ptr_iop_r += n * p->private_impl.src_pixfmt_bytes_per_pixel;
24824     return n;
24825   }
24826   return 0;
24827 }
24828 
24829 WUFFS_BASE__MAYBE_STATIC uint64_t  //
wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(const wuffs_base__pixel_swizzler * p,wuffs_base__slice_u8 dst,wuffs_base__slice_u8 dst_palette,const uint8_t ** ptr_iop_r,const uint8_t * io2_r)24830 wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(
24831     const wuffs_base__pixel_swizzler* p,
24832     wuffs_base__slice_u8 dst,
24833     wuffs_base__slice_u8 dst_palette,
24834     const uint8_t** ptr_iop_r,
24835     const uint8_t* io2_r) {
24836   if (p && p->private_impl.func) {
24837     const uint8_t* iop_r = *ptr_iop_r;
24838     uint64_t src_len = ((uint64_t)(io2_r - iop_r));
24839     uint64_t n =
24840         (*p->private_impl.func)(dst.ptr, dst.len, dst_palette.ptr,
24841                                 dst_palette.len, iop_r, (size_t)src_len);
24842     *ptr_iop_r += n * p->private_impl.src_pixfmt_bytes_per_pixel;
24843     return n;
24844   }
24845   return 0;
24846 }
24847 
24848 WUFFS_BASE__MAYBE_STATIC uint64_t  //
wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(const wuffs_base__pixel_swizzler * p,wuffs_base__slice_u8 dst,wuffs_base__slice_u8 dst_palette,wuffs_base__slice_u8 src)24849 wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(
24850     const wuffs_base__pixel_swizzler* p,
24851     wuffs_base__slice_u8 dst,
24852     wuffs_base__slice_u8 dst_palette,
24853     wuffs_base__slice_u8 src) {
24854   if (p && p->private_impl.func) {
24855     return (*p->private_impl.func)(dst.ptr, dst.len, dst_palette.ptr,
24856                                    dst_palette.len, src.ptr, src.len);
24857   }
24858   return 0;
24859 }
24860 
24861 WUFFS_BASE__MAYBE_STATIC uint64_t  //
wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(const wuffs_base__pixel_swizzler * p,wuffs_base__slice_u8 dst,wuffs_base__slice_u8 dst_palette,uint64_t num_pixels)24862 wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(
24863     const wuffs_base__pixel_swizzler* p,
24864     wuffs_base__slice_u8 dst,
24865     wuffs_base__slice_u8 dst_palette,
24866     uint64_t num_pixels) {
24867   if (p && p->private_impl.transparent_black_func) {
24868     return (*p->private_impl.transparent_black_func)(
24869         dst.ptr, dst.len, dst_palette.ptr, dst_palette.len, num_pixels,
24870         p->private_impl.dst_pixfmt_bytes_per_pixel);
24871   }
24872   return 0;
24873 }
24874 
24875 // --------
24876 
24877 #if defined(WUFFS_BASE__CPU_ARCH__X86_64)
24878 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2")
24879 static void  //
24880 wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_bgrx_x86_avx2(
24881     wuffs_base__pixel_buffer* dst,
24882     uint32_t x,
24883     uint32_t x_end,
24884     uint32_t y,
24885     const uint8_t* up0,
24886     const uint8_t* up1,
24887     const uint8_t* up2);
24888 
24889 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2")
24890 static void  //
24891 wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_rgbx_x86_avx2(
24892     wuffs_base__pixel_buffer* dst,
24893     uint32_t x,
24894     uint32_t x_end,
24895     uint32_t y,
24896     const uint8_t* up0,
24897     const uint8_t* up1,
24898     const uint8_t* up2);
24899 
24900 #if defined(__GNUC__) && !defined(__clang__)
24901 // No-op.
24902 #else
24903 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2")
24904 static const uint8_t*  //
24905 wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2v2_triangle_x86_avx2(
24906     uint8_t* dst_ptr,
24907     const uint8_t* src_ptr_major,
24908     const uint8_t* src_ptr_minor,
24909     size_t src_len,
24910     uint32_t h1v2_bias_ignored,
24911     bool first_column,
24912     bool last_column);
24913 #endif
24914 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_64)
24915 
24916 // --------
24917 
24918 static inline uint32_t  //
wuffs_base__u32__max_of_4(uint32_t a,uint32_t b,uint32_t c,uint32_t d)24919 wuffs_base__u32__max_of_4(uint32_t a, uint32_t b, uint32_t c, uint32_t d) {
24920   return wuffs_base__u32__max(     //
24921       wuffs_base__u32__max(a, b),  //
24922       wuffs_base__u32__max(c, d));
24923 }
24924 
24925 static inline uint32_t  //
wuffs_base__u32__min_of_5(uint32_t a,uint32_t b,uint32_t c,uint32_t d,uint32_t e)24926 wuffs_base__u32__min_of_5(uint32_t a,
24927                           uint32_t b,
24928                           uint32_t c,
24929                           uint32_t d,
24930                           uint32_t e) {
24931   return wuffs_base__u32__min(          //
24932       wuffs_base__u32__min(             //
24933           wuffs_base__u32__min(a, b),   //
24934           wuffs_base__u32__min(c, d)),  //
24935       e);
24936 }
24937 
24938 // --------
24939 
24940 typedef void (*wuffs_base__pixel_swizzler__swizzle_ycc__convert_4_func)(
24941     wuffs_base__pixel_buffer* dst,
24942     uint32_t x,
24943     uint32_t x_end,
24944     uint32_t y,
24945     const uint8_t* up0,
24946     const uint8_t* up1,
24947     const uint8_t* up2,
24948     const uint8_t* up3);
24949 
24950 static void  //
wuffs_base__pixel_swizzler__swizzle_cmyk__convert_4_general(wuffs_base__pixel_buffer * dst,uint32_t x,uint32_t x_end,uint32_t y,const uint8_t * up0,const uint8_t * up1,const uint8_t * up2,const uint8_t * up3)24951 wuffs_base__pixel_swizzler__swizzle_cmyk__convert_4_general(
24952     wuffs_base__pixel_buffer* dst,
24953     uint32_t x,
24954     uint32_t x_end,
24955     uint32_t y,
24956     const uint8_t* up0,
24957     const uint8_t* up1,
24958     const uint8_t* up2,
24959     const uint8_t* up3) {
24960   for (; x < x_end; x++) {
24961     // It's called CMYK but, but for Adobe CMYK JPEG images in practice, it's
24962     // RGBW: 0xFFu means no ink instead of full ink. Note that a double
24963     // inversion is a no-op, so inversions might be implicit in the code below.
24964     uint32_t r = ((uint32_t)(*up0++));
24965     uint32_t g = ((uint32_t)(*up1++));
24966     uint32_t b = ((uint32_t)(*up2++));
24967     uint32_t w = ((uint32_t)(*up3++));
24968     r = ((r * w) + 0x7Fu) / 0xFFu;
24969     g = ((g * w) + 0x7Fu) / 0xFFu;
24970     b = ((b * w) + 0x7Fu) / 0xFFu;
24971     wuffs_base__pixel_buffer__set_color_u32_at(
24972         dst, x, y, 0xFF000000u | (r << 16u) | (g << 8u) | (b << 0u));
24973   }
24974 }
24975 
24976 static void  //
wuffs_base__pixel_swizzler__swizzle_ycck__convert_4_general(wuffs_base__pixel_buffer * dst,uint32_t x,uint32_t x_end,uint32_t y,const uint8_t * up0,const uint8_t * up1,const uint8_t * up2,const uint8_t * up3)24977 wuffs_base__pixel_swizzler__swizzle_ycck__convert_4_general(
24978     wuffs_base__pixel_buffer* dst,
24979     uint32_t x,
24980     uint32_t x_end,
24981     uint32_t y,
24982     const uint8_t* up0,
24983     const uint8_t* up1,
24984     const uint8_t* up2,
24985     const uint8_t* up3) {
24986   for (; x < x_end; x++) {
24987     // We invert once again: 0xFFu means no ink instead of full ink.
24988     uint32_t color =                           //
24989         wuffs_base__color_ycc__as__color_u32(  //
24990             *up0++, *up1++, *up2++);
24991     uint32_t r = 0xFFu - (0xFFu & (color >> 16u));
24992     uint32_t g = 0xFFu - (0xFFu & (color >> 8u));
24993     uint32_t b = 0xFFu - (0xFFu & (color >> 0u));
24994     uint32_t w = ((uint32_t)(*up3++));
24995     r = ((r * w) + 0x7Fu) / 0xFFu;
24996     g = ((g * w) + 0x7Fu) / 0xFFu;
24997     b = ((b * w) + 0x7Fu) / 0xFFu;
24998     wuffs_base__pixel_buffer__set_color_u32_at(
24999         dst, x, y, 0xFF000000u | (r << 16u) | (g << 8u) | (b << 0u));
25000   }
25001 }
25002 
25003 // --------
25004 
25005 typedef void (*wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_func)(
25006     wuffs_base__pixel_buffer* dst,
25007     uint32_t x,
25008     uint32_t x_end,
25009     uint32_t y,
25010     const uint8_t* up0,
25011     const uint8_t* up1,
25012     const uint8_t* up2);
25013 
25014 static void  //
wuffs_base__pixel_swizzler__swizzle_rgb__convert_3_general(wuffs_base__pixel_buffer * dst,uint32_t x,uint32_t x_end,uint32_t y,const uint8_t * up0,const uint8_t * up1,const uint8_t * up2)25015 wuffs_base__pixel_swizzler__swizzle_rgb__convert_3_general(
25016     wuffs_base__pixel_buffer* dst,
25017     uint32_t x,
25018     uint32_t x_end,
25019     uint32_t y,
25020     const uint8_t* up0,
25021     const uint8_t* up1,
25022     const uint8_t* up2) {
25023   for (; x < x_end; x++) {
25024     uint32_t color = 0xFF000000u |                    //
25025                      (((uint32_t)(*up0++)) << 16u) |  //
25026                      (((uint32_t)(*up1++)) << 8u) |   //
25027                      (((uint32_t)(*up2++)) << 0u);
25028     wuffs_base__pixel_buffer__set_color_u32_at(dst, x, y, color);
25029   }
25030 }
25031 
25032 static void  //
wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_general(wuffs_base__pixel_buffer * dst,uint32_t x,uint32_t x_end,uint32_t y,const uint8_t * up0,const uint8_t * up1,const uint8_t * up2)25033 wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_general(
25034     wuffs_base__pixel_buffer* dst,
25035     uint32_t x,
25036     uint32_t x_end,
25037     uint32_t y,
25038     const uint8_t* up0,
25039     const uint8_t* up1,
25040     const uint8_t* up2) {
25041   for (; x < x_end; x++) {
25042     uint32_t color =                           //
25043         wuffs_base__color_ycc__as__color_u32(  //
25044             *up0++, *up1++, *up2++);
25045     wuffs_base__pixel_buffer__set_color_u32_at(dst, x, y, color);
25046   }
25047 }
25048 
25049 static void  //
wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_bgrx(wuffs_base__pixel_buffer * dst,uint32_t x,uint32_t x_end,uint32_t y,const uint8_t * up0,const uint8_t * up1,const uint8_t * up2)25050 wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_bgrx(
25051     wuffs_base__pixel_buffer* dst,
25052     uint32_t x,
25053     uint32_t x_end,
25054     uint32_t y,
25055     const uint8_t* up0,
25056     const uint8_t* up1,
25057     const uint8_t* up2) {
25058   size_t dst_stride = dst->private_impl.planes[0].stride;
25059   uint8_t* dst_iter = dst->private_impl.planes[0].ptr +
25060                       (dst_stride * ((size_t)y)) + (4u * ((size_t)x));
25061 
25062   for (; x < x_end; x++) {
25063     uint32_t color =                           //
25064         wuffs_base__color_ycc__as__color_u32(  //
25065             *up0++, *up1++, *up2++);
25066     wuffs_base__poke_u32le__no_bounds_check(dst_iter, color);
25067     dst_iter += 4u;
25068   }
25069 }
25070 
25071 static void  //
wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_rgbx(wuffs_base__pixel_buffer * dst,uint32_t x,uint32_t x_end,uint32_t y,const uint8_t * up0,const uint8_t * up1,const uint8_t * up2)25072 wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_rgbx(
25073     wuffs_base__pixel_buffer* dst,
25074     uint32_t x,
25075     uint32_t x_end,
25076     uint32_t y,
25077     const uint8_t* up0,
25078     const uint8_t* up1,
25079     const uint8_t* up2) {
25080   size_t dst_stride = dst->private_impl.planes[0].stride;
25081   uint8_t* dst_iter = dst->private_impl.planes[0].ptr +
25082                       (dst_stride * ((size_t)y)) + (4u * ((size_t)x));
25083 
25084   for (; x < x_end; x++) {
25085     uint32_t color =                                //
25086         wuffs_base__color_ycc__as__color_u32_abgr(  //
25087             *up0++, *up1++, *up2++);
25088     wuffs_base__poke_u32le__no_bounds_check(dst_iter, color);
25089     dst_iter += 4u;
25090   }
25091 }
25092 
25093 // --------
25094 
25095 // wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upsamples to a
25096 // destination slice at least 480 (YCCK) or 672 (YCC) bytes long and whose
25097 // src_len (multiplied by 1, 2, 3 or 4) is positive but no more than that. This
25098 // 480 or 672 length is just under 1/4 or 1/3 of the scratch_buffer_2k slice
25099 // length. Both (480 * 4) = 1920 and (672 * 3) = 2016 are less than 2048.
25100 //
25101 // 480 and 672 are nice round numbers because a JPEG MCU is 1, 2, 3 or 4 blocks
25102 // wide and each block is 8 pixels wide. We have:
25103 //   480 = 1 * 8 * 60,   672 = 1 * 8 * 84
25104 //   480 = 2 * 8 * 30,   672 = 2 * 8 * 42
25105 //   480 = 3 * 8 * 20,   672 = 3 * 8 * 28
25106 //   480 = 4 * 8 * 15,   672 = 4 * 8 * 21
25107 //
25108 // Box filters are equivalent to nearest neighbor upsampling. These ignore the
25109 // src_ptr_minor, h1v2_bias, first_column and last_column arguments.
25110 //
25111 // Triangle filters use a 3:1 ratio (in 1 dimension), or 9:3:3:1 (in 2
25112 // dimensions), which is higher quality (less blocky) but also higher
25113 // computational effort.
25114 //
25115 // In theory, we could use triangle filters for any (inv_h, inv_v) combination.
25116 // In practice, matching libjpeg-turbo, we only implement it for the common
25117 // chroma subsampling ratios (YCC420, YCC422 or YCC440), corresponding to an
25118 // (inv_h, inv_v) pair of (2, 2), (2, 1) or (1, 2).
25119 typedef const uint8_t* (
25120     *wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func)(
25121     uint8_t* dst_ptr,
25122     const uint8_t* src_ptr_major,  // Nearest row.
25123     const uint8_t* src_ptr_minor,  // Adjacent row, alternating above or below.
25124     size_t src_len,
25125     uint32_t h1v2_bias,
25126     bool first_column,
25127     bool last_column);
25128 
25129 static const uint8_t*  //
wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h1vn_box(uint8_t * dst_ptr,const uint8_t * src_ptr_major,const uint8_t * src_ptr_minor_ignored,size_t src_len,uint32_t h1v2_bias_ignored,bool first_column_ignored,bool last_column_ignored)25130 wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h1vn_box(
25131     uint8_t* dst_ptr,
25132     const uint8_t* src_ptr_major,
25133     const uint8_t* src_ptr_minor_ignored,
25134     size_t src_len,
25135     uint32_t h1v2_bias_ignored,
25136     bool first_column_ignored,
25137     bool last_column_ignored) {
25138   return src_ptr_major;
25139 }
25140 
25141 static const uint8_t*  //
wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2vn_box(uint8_t * dst_ptr,const uint8_t * src_ptr_major,const uint8_t * src_ptr_minor_ignored,size_t src_len,uint32_t h1v2_bias_ignored,bool first_column_ignored,bool last_column_ignored)25142 wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2vn_box(
25143     uint8_t* dst_ptr,
25144     const uint8_t* src_ptr_major,
25145     const uint8_t* src_ptr_minor_ignored,
25146     size_t src_len,
25147     uint32_t h1v2_bias_ignored,
25148     bool first_column_ignored,
25149     bool last_column_ignored) {
25150   uint8_t* dp = dst_ptr;
25151   const uint8_t* sp = src_ptr_major;
25152   while (src_len--) {
25153     uint8_t sv = *sp++;
25154     *dp++ = sv;
25155     *dp++ = sv;
25156   }
25157   return dst_ptr;
25158 }
25159 
25160 static const uint8_t*  //
wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h3vn_box(uint8_t * dst_ptr,const uint8_t * src_ptr_major,const uint8_t * src_ptr_minor_ignored,size_t src_len,uint32_t h1v2_bias_ignored,bool first_column_ignored,bool last_column_ignored)25161 wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h3vn_box(
25162     uint8_t* dst_ptr,
25163     const uint8_t* src_ptr_major,
25164     const uint8_t* src_ptr_minor_ignored,
25165     size_t src_len,
25166     uint32_t h1v2_bias_ignored,
25167     bool first_column_ignored,
25168     bool last_column_ignored) {
25169   uint8_t* dp = dst_ptr;
25170   const uint8_t* sp = src_ptr_major;
25171   while (src_len--) {
25172     uint8_t sv = *sp++;
25173     *dp++ = sv;
25174     *dp++ = sv;
25175     *dp++ = sv;
25176   }
25177   return dst_ptr;
25178 }
25179 
25180 static const uint8_t*  //
wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h4vn_box(uint8_t * dst_ptr,const uint8_t * src_ptr_major,const uint8_t * src_ptr_minor_ignored,size_t src_len,uint32_t h1v2_bias_ignored,bool first_column_ignored,bool last_column_ignored)25181 wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h4vn_box(
25182     uint8_t* dst_ptr,
25183     const uint8_t* src_ptr_major,
25184     const uint8_t* src_ptr_minor_ignored,
25185     size_t src_len,
25186     uint32_t h1v2_bias_ignored,
25187     bool first_column_ignored,
25188     bool last_column_ignored) {
25189   uint8_t* dp = dst_ptr;
25190   const uint8_t* sp = src_ptr_major;
25191   while (src_len--) {
25192     uint8_t sv = *sp++;
25193     *dp++ = sv;
25194     *dp++ = sv;
25195     *dp++ = sv;
25196     *dp++ = sv;
25197   }
25198   return dst_ptr;
25199 }
25200 
25201 static const uint8_t*  //
wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h1v2_triangle(uint8_t * dst_ptr,const uint8_t * src_ptr_major,const uint8_t * src_ptr_minor,size_t src_len,uint32_t h1v2_bias,bool first_column,bool last_column)25202 wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h1v2_triangle(
25203     uint8_t* dst_ptr,
25204     const uint8_t* src_ptr_major,
25205     const uint8_t* src_ptr_minor,
25206     size_t src_len,
25207     uint32_t h1v2_bias,
25208     bool first_column,
25209     bool last_column) {
25210   uint8_t* dp = dst_ptr;
25211   const uint8_t* sp_major = src_ptr_major;
25212   const uint8_t* sp_minor = src_ptr_minor;
25213   while (src_len--) {
25214     *dp++ = (uint8_t)(((3u * ((uint32_t)(*sp_major++))) +  //
25215                        (1u * ((uint32_t)(*sp_minor++))) +  //
25216                        h1v2_bias) >>
25217                       2u);
25218   }
25219   return dst_ptr;
25220 }
25221 
25222 static const uint8_t*  //
wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2v1_triangle(uint8_t * dst_ptr,const uint8_t * src_ptr_major,const uint8_t * src_ptr_minor,size_t src_len,uint32_t h1v2_bias_ignored,bool first_column,bool last_column)25223 wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2v1_triangle(
25224     uint8_t* dst_ptr,
25225     const uint8_t* src_ptr_major,
25226     const uint8_t* src_ptr_minor,
25227     size_t src_len,
25228     uint32_t h1v2_bias_ignored,
25229     bool first_column,
25230     bool last_column) {
25231   uint8_t* dp = dst_ptr;
25232   const uint8_t* sp = src_ptr_major;
25233 
25234   if (first_column) {
25235     src_len--;
25236     if ((src_len <= 0u) && last_column) {
25237       uint8_t sv = *sp++;
25238       *dp++ = sv;
25239       *dp++ = sv;
25240       return dst_ptr;
25241     }
25242     uint32_t svp1 = sp[+1];
25243     uint8_t sv = *sp++;
25244     *dp++ = sv;
25245     *dp++ = (uint8_t)(((3u * (uint32_t)sv) + svp1 + 2u) >> 2u);
25246     if (src_len <= 0u) {
25247       return dst_ptr;
25248     }
25249   }
25250 
25251   if (last_column) {
25252     src_len--;
25253   }
25254 
25255   for (; src_len > 0u; src_len--) {
25256     uint32_t svm1 = sp[-1];
25257     uint32_t svp1 = sp[+1];
25258     uint32_t sv3 = 3u * (uint32_t)(*sp++);
25259     *dp++ = (uint8_t)((sv3 + svm1 + 1u) >> 2u);
25260     *dp++ = (uint8_t)((sv3 + svp1 + 2u) >> 2u);
25261   }
25262 
25263   if (last_column) {
25264     uint32_t svm1 = sp[-1];
25265     uint8_t sv = *sp++;
25266     *dp++ = (uint8_t)(((3u * (uint32_t)sv) + svm1 + 1u) >> 2u);
25267     *dp++ = sv;
25268   }
25269 
25270   return dst_ptr;
25271 }
25272 
25273 static const uint8_t*  //
wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2v2_triangle(uint8_t * dst_ptr,const uint8_t * src_ptr_major,const uint8_t * src_ptr_minor,size_t src_len,uint32_t h1v2_bias_ignored,bool first_column,bool last_column)25274 wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2v2_triangle(
25275     uint8_t* dst_ptr,
25276     const uint8_t* src_ptr_major,
25277     const uint8_t* src_ptr_minor,
25278     size_t src_len,
25279     uint32_t h1v2_bias_ignored,
25280     bool first_column,
25281     bool last_column) {
25282   uint8_t* dp = dst_ptr;
25283   const uint8_t* sp_major = src_ptr_major;
25284   const uint8_t* sp_minor = src_ptr_minor;
25285 
25286   if (first_column) {
25287     src_len--;
25288     if ((src_len <= 0u) && last_column) {
25289       uint32_t sv = (12u * ((uint32_t)(*sp_major++))) +  //
25290                     (4u * ((uint32_t)(*sp_minor++)));
25291       *dp++ = (uint8_t)((sv + 8u) >> 4u);
25292       *dp++ = (uint8_t)((sv + 7u) >> 4u);
25293       return dst_ptr;
25294     }
25295 
25296     uint32_t sv_major_m1 = sp_major[-0];  // Clamp offset to zero.
25297     uint32_t sv_minor_m1 = sp_minor[-0];  // Clamp offset to zero.
25298     uint32_t sv_major_p1 = sp_major[+1];
25299     uint32_t sv_minor_p1 = sp_minor[+1];
25300 
25301     uint32_t sv = (9u * ((uint32_t)(*sp_major++))) +  //
25302                   (3u * ((uint32_t)(*sp_minor++)));
25303     *dp++ = (uint8_t)((sv + (3u * sv_major_m1) + (sv_minor_m1) + 8u) >> 4u);
25304     *dp++ = (uint8_t)((sv + (3u * sv_major_p1) + (sv_minor_p1) + 7u) >> 4u);
25305     if (src_len <= 0u) {
25306       return dst_ptr;
25307     }
25308   }
25309 
25310   if (last_column) {
25311     src_len--;
25312   }
25313 
25314   for (; src_len > 0u; src_len--) {
25315     uint32_t sv_major_m1 = sp_major[-1];
25316     uint32_t sv_minor_m1 = sp_minor[-1];
25317     uint32_t sv_major_p1 = sp_major[+1];
25318     uint32_t sv_minor_p1 = sp_minor[+1];
25319 
25320     uint32_t sv = (9u * ((uint32_t)(*sp_major++))) +  //
25321                   (3u * ((uint32_t)(*sp_minor++)));
25322     *dp++ = (uint8_t)((sv + (3u * sv_major_m1) + (sv_minor_m1) + 8u) >> 4u);
25323     *dp++ = (uint8_t)((sv + (3u * sv_major_p1) + (sv_minor_p1) + 7u) >> 4u);
25324   }
25325 
25326   if (last_column) {
25327     uint32_t sv_major_m1 = sp_major[-1];
25328     uint32_t sv_minor_m1 = sp_minor[-1];
25329     uint32_t sv_major_p1 = sp_major[+0];  // Clamp offset to zero.
25330     uint32_t sv_minor_p1 = sp_minor[+0];  // Clamp offset to zero.
25331 
25332     uint32_t sv = (9u * ((uint32_t)(*sp_major++))) +  //
25333                   (3u * ((uint32_t)(*sp_minor++)));
25334     *dp++ = (uint8_t)((sv + (3u * sv_major_m1) + (sv_minor_m1) + 8u) >> 4u);
25335     *dp++ = (uint8_t)((sv + (3u * sv_major_p1) + (sv_minor_p1) + 7u) >> 4u);
25336   }
25337 
25338   return dst_ptr;
25339 }
25340 
25341 // wuffs_base__pixel_swizzler__swizzle_ycc__upsample_funcs is indexed by inv_h
25342 // and then inv_v.
25343 static const wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func
25344     wuffs_base__pixel_swizzler__swizzle_ycc__upsample_funcs[4][4] = {
25345         {
25346             wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h1vn_box,
25347             wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h1vn_box,
25348             wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h1vn_box,
25349             wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h1vn_box,
25350         },
25351         {
25352             wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2vn_box,
25353             wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2vn_box,
25354             wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2vn_box,
25355             wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2vn_box,
25356         },
25357         {
25358             wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h3vn_box,
25359             wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h3vn_box,
25360             wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h3vn_box,
25361             wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h3vn_box,
25362         },
25363         {
25364             wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h4vn_box,
25365             wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h4vn_box,
25366             wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h4vn_box,
25367             wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h4vn_box,
25368         },
25369 };
25370 
25371 static inline uint32_t  //
wuffs_base__pixel_swizzler__has_triangle_upsampler(uint32_t inv_h,uint32_t inv_v)25372 wuffs_base__pixel_swizzler__has_triangle_upsampler(uint32_t inv_h,
25373                                                    uint32_t inv_v) {
25374   if (inv_h == 1u) {
25375     return inv_v == 2u;
25376   } else if (inv_h == 2u) {
25377     return (inv_v == 1u) || (inv_v == 2u);
25378   }
25379   return false;
25380 }
25381 
25382 // --------
25383 
25384 // All of the wuffs_base__pixel_swizzler__swizzle_ycc__etc functions have
25385 // preconditions. See all of the checks made in
25386 // wuffs_base__pixel_swizzler__swizzle_ycck before calling these functions. For
25387 // example, (width > 0) is a precondition, but there are many more.
25388 
25389 static void  //
wuffs_base__pixel_swizzler__swizzle_ycck__general__triangle_filter_edge_row(wuffs_base__pixel_buffer * dst,uint32_t width,uint32_t y,const uint8_t * src_ptr0,const uint8_t * src_ptr1,const uint8_t * src_ptr2,const uint8_t * src_ptr3,uint32_t stride0,uint32_t stride1,uint32_t stride2,uint32_t stride3,uint32_t inv_h0,uint32_t inv_h1,uint32_t inv_h2,uint32_t inv_h3,uint32_t inv_v0,uint32_t inv_v1,uint32_t inv_v2,uint32_t inv_v3,uint32_t half_width_for_2to1,uint32_t h1v2_bias,uint8_t * scratch_buffer_2k_ptr,wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc0,wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc1,wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc2,wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc3,wuffs_base__pixel_swizzler__swizzle_ycc__convert_4_func conv4func)25390 wuffs_base__pixel_swizzler__swizzle_ycck__general__triangle_filter_edge_row(
25391     wuffs_base__pixel_buffer* dst,
25392     uint32_t width,
25393     uint32_t y,
25394     const uint8_t* src_ptr0,
25395     const uint8_t* src_ptr1,
25396     const uint8_t* src_ptr2,
25397     const uint8_t* src_ptr3,
25398     uint32_t stride0,
25399     uint32_t stride1,
25400     uint32_t stride2,
25401     uint32_t stride3,
25402     uint32_t inv_h0,
25403     uint32_t inv_h1,
25404     uint32_t inv_h2,
25405     uint32_t inv_h3,
25406     uint32_t inv_v0,
25407     uint32_t inv_v1,
25408     uint32_t inv_v2,
25409     uint32_t inv_v3,
25410     uint32_t half_width_for_2to1,
25411     uint32_t h1v2_bias,
25412     uint8_t* scratch_buffer_2k_ptr,
25413     wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc0,
25414     wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc1,
25415     wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc2,
25416     wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc3,
25417     wuffs_base__pixel_swizzler__swizzle_ycc__convert_4_func conv4func) {
25418   const uint8_t* src0 = src_ptr0 + ((y / inv_v0) * (size_t)stride0);
25419   const uint8_t* src1 = src_ptr1 + ((y / inv_v1) * (size_t)stride1);
25420   const uint8_t* src2 = src_ptr2 + ((y / inv_v2) * (size_t)stride2);
25421   const uint8_t* src3 = src_ptr3 + ((y / inv_v3) * (size_t)stride3);
25422   uint32_t total_src_len0 = 0u;
25423   uint32_t total_src_len1 = 0u;
25424   uint32_t total_src_len2 = 0u;
25425   uint32_t total_src_len3 = 0u;
25426 
25427   uint32_t x = 0u;
25428   while (x < width) {
25429     bool first_column = x == 0u;
25430     uint32_t end = x + 480u;
25431     if (end > width) {
25432       end = width;
25433     }
25434 
25435     uint32_t src_len0 = ((end - x) + inv_h0 - 1u) / inv_h0;
25436     uint32_t src_len1 = ((end - x) + inv_h1 - 1u) / inv_h1;
25437     uint32_t src_len2 = ((end - x) + inv_h2 - 1u) / inv_h2;
25438     uint32_t src_len3 = ((end - x) + inv_h3 - 1u) / inv_h3;
25439     total_src_len0 += src_len0;
25440     total_src_len1 += src_len1;
25441     total_src_len2 += src_len2;
25442     total_src_len3 += src_len3;
25443 
25444     const uint8_t* src_ptr_x0 = src0 + (x / inv_h0);
25445     const uint8_t* up0 = (*upfunc0)(          //
25446         scratch_buffer_2k_ptr + (0u * 480u),  //
25447         src_ptr_x0,                           //
25448         src_ptr_x0,                           //
25449         src_len0,                             //
25450         h1v2_bias,                            //
25451         first_column,                         //
25452         (total_src_len0 >= half_width_for_2to1));
25453 
25454     const uint8_t* src_ptr_x1 = src1 + (x / inv_h1);
25455     const uint8_t* up1 = (*upfunc1)(          //
25456         scratch_buffer_2k_ptr + (1u * 480u),  //
25457         src_ptr_x1,                           //
25458         src_ptr_x1,                           //
25459         src_len1,                             //
25460         h1v2_bias,                            //
25461         first_column,                         //
25462         (total_src_len1 >= half_width_for_2to1));
25463 
25464     const uint8_t* src_ptr_x2 = src2 + (x / inv_h2);
25465     const uint8_t* up2 = (*upfunc2)(          //
25466         scratch_buffer_2k_ptr + (2u * 480u),  //
25467         src_ptr_x2,                           //
25468         src_ptr_x2,                           //
25469         src_len2,                             //
25470         h1v2_bias,                            //
25471         first_column,                         //
25472         (total_src_len2 >= half_width_for_2to1));
25473 
25474     const uint8_t* src_ptr_x3 = src3 + (x / inv_h3);
25475     const uint8_t* up3 = (*upfunc3)(          //
25476         scratch_buffer_2k_ptr + (3u * 480u),  //
25477         src_ptr_x3,                           //
25478         src_ptr_x3,                           //
25479         src_len3,                             //
25480         h1v2_bias,                            //
25481         first_column,                         //
25482         (total_src_len3 >= half_width_for_2to1));
25483 
25484     (*conv4func)(dst, x, end, y, up0, up1, up2, up3);
25485     x = end;
25486   }
25487 }
25488 
25489 static void  //
wuffs_base__pixel_swizzler__swizzle_ycck__general__triangle_filter(wuffs_base__pixel_buffer * dst,uint32_t width,uint32_t height,const uint8_t * src_ptr0,const uint8_t * src_ptr1,const uint8_t * src_ptr2,const uint8_t * src_ptr3,uint32_t stride0,uint32_t stride1,uint32_t stride2,uint32_t stride3,uint32_t inv_h0,uint32_t inv_h1,uint32_t inv_h2,uint32_t inv_h3,uint32_t inv_v0,uint32_t inv_v1,uint32_t inv_v2,uint32_t inv_v3,uint32_t half_width_for_2to1,uint32_t half_height_for_2to1,uint8_t * scratch_buffer_2k_ptr,wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func (* upfuncs)[4][4],wuffs_base__pixel_swizzler__swizzle_ycc__convert_4_func conv4func)25490 wuffs_base__pixel_swizzler__swizzle_ycck__general__triangle_filter(
25491     wuffs_base__pixel_buffer* dst,
25492     uint32_t width,
25493     uint32_t height,
25494     const uint8_t* src_ptr0,
25495     const uint8_t* src_ptr1,
25496     const uint8_t* src_ptr2,
25497     const uint8_t* src_ptr3,
25498     uint32_t stride0,
25499     uint32_t stride1,
25500     uint32_t stride2,
25501     uint32_t stride3,
25502     uint32_t inv_h0,
25503     uint32_t inv_h1,
25504     uint32_t inv_h2,
25505     uint32_t inv_h3,
25506     uint32_t inv_v0,
25507     uint32_t inv_v1,
25508     uint32_t inv_v2,
25509     uint32_t inv_v3,
25510     uint32_t half_width_for_2to1,
25511     uint32_t half_height_for_2to1,
25512     uint8_t* scratch_buffer_2k_ptr,
25513     wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func (*upfuncs)[4][4],
25514     wuffs_base__pixel_swizzler__swizzle_ycc__convert_4_func conv4func) {
25515   wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc0 =
25516       (*upfuncs)[(inv_h0 - 1u) & 3u][(inv_v0 - 1u) & 3u];
25517   wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc1 =
25518       (*upfuncs)[(inv_h1 - 1u) & 3u][(inv_v1 - 1u) & 3u];
25519   wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc2 =
25520       (*upfuncs)[(inv_h2 - 1u) & 3u][(inv_v2 - 1u) & 3u];
25521   wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc3 =
25522       (*upfuncs)[(inv_h3 - 1u) & 3u][(inv_v3 - 1u) & 3u];
25523 
25524   // First row.
25525   uint32_t h1v2_bias = 1u;
25526   wuffs_base__pixel_swizzler__swizzle_ycck__general__triangle_filter_edge_row(
25527       dst, width, 0u,                          //
25528       src_ptr0, src_ptr1, src_ptr2, src_ptr3,  //
25529       stride0, stride1, stride2, stride3,      //
25530       inv_h0, inv_h1, inv_h2, inv_h3,          //
25531       inv_v0, inv_v1, inv_v2, inv_v3,          //
25532       half_width_for_2to1,                     //
25533       h1v2_bias,                               //
25534       scratch_buffer_2k_ptr,                   //
25535       upfunc0, upfunc1, upfunc2, upfunc3, conv4func);
25536   h1v2_bias = 2u;
25537 
25538   // Middle rows.
25539   bool last_row = height == 2u * half_height_for_2to1;
25540   uint32_t y_max_excl = last_row ? (height - 1u) : height;
25541   uint32_t y;
25542   for (y = 1u; y < y_max_excl; y++) {
25543     const uint8_t* src0_major = src_ptr0 + ((y / inv_v0) * (size_t)stride0);
25544     const uint8_t* src0_minor =
25545         (inv_v0 != 2u)
25546             ? src0_major
25547             : ((y & 1u) ? (src0_major + stride0) : (src0_major - stride0));
25548     const uint8_t* src1_major = src_ptr1 + ((y / inv_v1) * (size_t)stride1);
25549     const uint8_t* src1_minor =
25550         (inv_v1 != 2u)
25551             ? src1_major
25552             : ((y & 1u) ? (src1_major + stride1) : (src1_major - stride1));
25553     const uint8_t* src2_major = src_ptr2 + ((y / inv_v2) * (size_t)stride2);
25554     const uint8_t* src2_minor =
25555         (inv_v2 != 2u)
25556             ? src2_major
25557             : ((y & 1u) ? (src2_major + stride2) : (src2_major - stride2));
25558     const uint8_t* src3_major = src_ptr3 + ((y / inv_v3) * (size_t)stride3);
25559     const uint8_t* src3_minor =
25560         (inv_v3 != 2u)
25561             ? src3_major
25562             : ((y & 1u) ? (src3_major + stride3) : (src3_major - stride3));
25563     uint32_t total_src_len0 = 0u;
25564     uint32_t total_src_len1 = 0u;
25565     uint32_t total_src_len2 = 0u;
25566     uint32_t total_src_len3 = 0u;
25567 
25568     uint32_t x = 0u;
25569     while (x < width) {
25570       bool first_column = x == 0u;
25571       uint32_t end = x + 480u;
25572       if (end > width) {
25573         end = width;
25574       }
25575 
25576       uint32_t src_len0 = ((end - x) + inv_h0 - 1u) / inv_h0;
25577       uint32_t src_len1 = ((end - x) + inv_h1 - 1u) / inv_h1;
25578       uint32_t src_len2 = ((end - x) + inv_h2 - 1u) / inv_h2;
25579       uint32_t src_len3 = ((end - x) + inv_h3 - 1u) / inv_h3;
25580       total_src_len0 += src_len0;
25581       total_src_len1 += src_len1;
25582       total_src_len2 += src_len2;
25583       total_src_len3 += src_len3;
25584 
25585       const uint8_t* up0 = (*upfunc0)(          //
25586           scratch_buffer_2k_ptr + (0u * 480u),  //
25587           src0_major + (x / inv_h0),            //
25588           src0_minor + (x / inv_h0),            //
25589           src_len0,                             //
25590           h1v2_bias,                            //
25591           first_column,                         //
25592           (total_src_len0 >= half_width_for_2to1));
25593 
25594       const uint8_t* up1 = (*upfunc1)(          //
25595           scratch_buffer_2k_ptr + (1u * 480u),  //
25596           src1_major + (x / inv_h1),            //
25597           src1_minor + (x / inv_h1),            //
25598           src_len1,                             //
25599           h1v2_bias,                            //
25600           first_column,                         //
25601           (total_src_len1 >= half_width_for_2to1));
25602 
25603       const uint8_t* up2 = (*upfunc2)(          //
25604           scratch_buffer_2k_ptr + (2u * 480u),  //
25605           src2_major + (x / inv_h2),            //
25606           src2_minor + (x / inv_h2),            //
25607           src_len2,                             //
25608           h1v2_bias,                            //
25609           first_column,                         //
25610           (total_src_len2 >= half_width_for_2to1));
25611 
25612       const uint8_t* up3 = (*upfunc3)(          //
25613           scratch_buffer_2k_ptr + (3u * 480u),  //
25614           src3_major + (x / inv_h3),            //
25615           src3_minor + (x / inv_h3),            //
25616           src_len3,                             //
25617           h1v2_bias,                            //
25618           first_column,                         //
25619           (total_src_len3 >= half_width_for_2to1));
25620 
25621       (*conv4func)(dst, x, end, y, up0, up1, up2, up3);
25622       x = end;
25623     }
25624 
25625     h1v2_bias ^= 3u;
25626   }
25627 
25628   // Last row.
25629   if (y_max_excl != height) {
25630     wuffs_base__pixel_swizzler__swizzle_ycck__general__triangle_filter_edge_row(
25631         dst, width, height - 1u,                 //
25632         src_ptr0, src_ptr1, src_ptr2, src_ptr3,  //
25633         stride0, stride1, stride2, stride3,      //
25634         inv_h0, inv_h1, inv_h2, inv_h3,          //
25635         inv_v0, inv_v1, inv_v2, inv_v3,          //
25636         half_width_for_2to1,                     //
25637         h1v2_bias,                               //
25638         scratch_buffer_2k_ptr,                   //
25639         upfunc0, upfunc1, upfunc2, upfunc3, conv4func);
25640   }
25641 }
25642 
25643 static void  //
wuffs_base__pixel_swizzler__swizzle_ycc__general__triangle_filter_edge_row(wuffs_base__pixel_buffer * dst,uint32_t width,uint32_t y,const uint8_t * src_ptr0,const uint8_t * src_ptr1,const uint8_t * src_ptr2,uint32_t stride0,uint32_t stride1,uint32_t stride2,uint32_t inv_h0,uint32_t inv_h1,uint32_t inv_h2,uint32_t inv_v0,uint32_t inv_v1,uint32_t inv_v2,uint32_t half_width_for_2to1,uint32_t h1v2_bias,uint8_t * scratch_buffer_2k_ptr,wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc0,wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc1,wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc2,wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_func conv3func)25644 wuffs_base__pixel_swizzler__swizzle_ycc__general__triangle_filter_edge_row(
25645     wuffs_base__pixel_buffer* dst,
25646     uint32_t width,
25647     uint32_t y,
25648     const uint8_t* src_ptr0,
25649     const uint8_t* src_ptr1,
25650     const uint8_t* src_ptr2,
25651     uint32_t stride0,
25652     uint32_t stride1,
25653     uint32_t stride2,
25654     uint32_t inv_h0,
25655     uint32_t inv_h1,
25656     uint32_t inv_h2,
25657     uint32_t inv_v0,
25658     uint32_t inv_v1,
25659     uint32_t inv_v2,
25660     uint32_t half_width_for_2to1,
25661     uint32_t h1v2_bias,
25662     uint8_t* scratch_buffer_2k_ptr,
25663     wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc0,
25664     wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc1,
25665     wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc2,
25666     wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_func conv3func) {
25667   const uint8_t* src0 = src_ptr0 + ((y / inv_v0) * (size_t)stride0);
25668   const uint8_t* src1 = src_ptr1 + ((y / inv_v1) * (size_t)stride1);
25669   const uint8_t* src2 = src_ptr2 + ((y / inv_v2) * (size_t)stride2);
25670   uint32_t total_src_len0 = 0u;
25671   uint32_t total_src_len1 = 0u;
25672   uint32_t total_src_len2 = 0u;
25673 
25674   uint32_t x = 0u;
25675   while (x < width) {
25676     bool first_column = x == 0u;
25677     uint32_t end = x + 672u;
25678     if (end > width) {
25679       end = width;
25680     }
25681 
25682     uint32_t src_len0 = ((end - x) + inv_h0 - 1u) / inv_h0;
25683     uint32_t src_len1 = ((end - x) + inv_h1 - 1u) / inv_h1;
25684     uint32_t src_len2 = ((end - x) + inv_h2 - 1u) / inv_h2;
25685     total_src_len0 += src_len0;
25686     total_src_len1 += src_len1;
25687     total_src_len2 += src_len2;
25688 
25689     const uint8_t* src_ptr_x0 = src0 + (x / inv_h0);
25690     const uint8_t* up0 = (*upfunc0)(          //
25691         scratch_buffer_2k_ptr + (0u * 672u),  //
25692         src_ptr_x0,                           //
25693         src_ptr_x0,                           //
25694         src_len0,                             //
25695         h1v2_bias,                            //
25696         first_column,                         //
25697         (total_src_len0 >= half_width_for_2to1));
25698 
25699     const uint8_t* src_ptr_x1 = src1 + (x / inv_h1);
25700     const uint8_t* up1 = (*upfunc1)(          //
25701         scratch_buffer_2k_ptr + (1u * 672u),  //
25702         src_ptr_x1,                           //
25703         src_ptr_x1,                           //
25704         src_len1,                             //
25705         h1v2_bias,                            //
25706         first_column,                         //
25707         (total_src_len1 >= half_width_for_2to1));
25708 
25709     const uint8_t* src_ptr_x2 = src2 + (x / inv_h2);
25710     const uint8_t* up2 = (*upfunc2)(          //
25711         scratch_buffer_2k_ptr + (2u * 672u),  //
25712         src_ptr_x2,                           //
25713         src_ptr_x2,                           //
25714         src_len2,                             //
25715         h1v2_bias,                            //
25716         first_column,                         //
25717         (total_src_len2 >= half_width_for_2to1));
25718 
25719     (*conv3func)(dst, x, end, y, up0, up1, up2);
25720     x = end;
25721   }
25722 }
25723 
25724 static void  //
wuffs_base__pixel_swizzler__swizzle_ycc__general__triangle_filter(wuffs_base__pixel_buffer * dst,uint32_t width,uint32_t height,const uint8_t * src_ptr0,const uint8_t * src_ptr1,const uint8_t * src_ptr2,uint32_t stride0,uint32_t stride1,uint32_t stride2,uint32_t inv_h0,uint32_t inv_h1,uint32_t inv_h2,uint32_t inv_v0,uint32_t inv_v1,uint32_t inv_v2,uint32_t half_width_for_2to1,uint32_t half_height_for_2to1,uint8_t * scratch_buffer_2k_ptr,wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func (* upfuncs)[4][4],wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_func conv3func)25725 wuffs_base__pixel_swizzler__swizzle_ycc__general__triangle_filter(
25726     wuffs_base__pixel_buffer* dst,
25727     uint32_t width,
25728     uint32_t height,
25729     const uint8_t* src_ptr0,
25730     const uint8_t* src_ptr1,
25731     const uint8_t* src_ptr2,
25732     uint32_t stride0,
25733     uint32_t stride1,
25734     uint32_t stride2,
25735     uint32_t inv_h0,
25736     uint32_t inv_h1,
25737     uint32_t inv_h2,
25738     uint32_t inv_v0,
25739     uint32_t inv_v1,
25740     uint32_t inv_v2,
25741     uint32_t half_width_for_2to1,
25742     uint32_t half_height_for_2to1,
25743     uint8_t* scratch_buffer_2k_ptr,
25744     wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func (*upfuncs)[4][4],
25745     wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_func conv3func) {
25746   wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc0 =
25747       (*upfuncs)[(inv_h0 - 1u) & 3u][(inv_v0 - 1u) & 3u];
25748   wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc1 =
25749       (*upfuncs)[(inv_h1 - 1u) & 3u][(inv_v1 - 1u) & 3u];
25750   wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc2 =
25751       (*upfuncs)[(inv_h2 - 1u) & 3u][(inv_v2 - 1u) & 3u];
25752 
25753   // First row.
25754   uint32_t h1v2_bias = 1u;
25755   wuffs_base__pixel_swizzler__swizzle_ycc__general__triangle_filter_edge_row(
25756       dst, width, 0u,                //
25757       src_ptr0, src_ptr1, src_ptr2,  //
25758       stride0, stride1, stride2,     //
25759       inv_h0, inv_h1, inv_h2,        //
25760       inv_v0, inv_v1, inv_v2,        //
25761       half_width_for_2to1,           //
25762       h1v2_bias,                     //
25763       scratch_buffer_2k_ptr,         //
25764       upfunc0, upfunc1, upfunc2, conv3func);
25765   h1v2_bias = 2u;
25766 
25767   // Middle rows.
25768   bool last_row = height == 2u * half_height_for_2to1;
25769   uint32_t y_max_excl = last_row ? (height - 1u) : height;
25770   uint32_t y;
25771   for (y = 1u; y < y_max_excl; y++) {
25772     const uint8_t* src0_major = src_ptr0 + ((y / inv_v0) * (size_t)stride0);
25773     const uint8_t* src0_minor =
25774         (inv_v0 != 2u)
25775             ? src0_major
25776             : ((y & 1u) ? (src0_major + stride0) : (src0_major - stride0));
25777     const uint8_t* src1_major = src_ptr1 + ((y / inv_v1) * (size_t)stride1);
25778     const uint8_t* src1_minor =
25779         (inv_v1 != 2u)
25780             ? src1_major
25781             : ((y & 1u) ? (src1_major + stride1) : (src1_major - stride1));
25782     const uint8_t* src2_major = src_ptr2 + ((y / inv_v2) * (size_t)stride2);
25783     const uint8_t* src2_minor =
25784         (inv_v2 != 2u)
25785             ? src2_major
25786             : ((y & 1u) ? (src2_major + stride2) : (src2_major - stride2));
25787     uint32_t total_src_len0 = 0u;
25788     uint32_t total_src_len1 = 0u;
25789     uint32_t total_src_len2 = 0u;
25790 
25791     uint32_t x = 0u;
25792     while (x < width) {
25793       bool first_column = x == 0u;
25794       uint32_t end = x + 672u;
25795       if (end > width) {
25796         end = width;
25797       }
25798 
25799       uint32_t src_len0 = ((end - x) + inv_h0 - 1u) / inv_h0;
25800       uint32_t src_len1 = ((end - x) + inv_h1 - 1u) / inv_h1;
25801       uint32_t src_len2 = ((end - x) + inv_h2 - 1u) / inv_h2;
25802       total_src_len0 += src_len0;
25803       total_src_len1 += src_len1;
25804       total_src_len2 += src_len2;
25805 
25806       const uint8_t* up0 = (*upfunc0)(          //
25807           scratch_buffer_2k_ptr + (0u * 672u),  //
25808           src0_major + (x / inv_h0),            //
25809           src0_minor + (x / inv_h0),            //
25810           src_len0,                             //
25811           h1v2_bias,                            //
25812           first_column,                         //
25813           (total_src_len0 >= half_width_for_2to1));
25814 
25815       const uint8_t* up1 = (*upfunc1)(          //
25816           scratch_buffer_2k_ptr + (1u * 672u),  //
25817           src1_major + (x / inv_h1),            //
25818           src1_minor + (x / inv_h1),            //
25819           src_len1,                             //
25820           h1v2_bias,                            //
25821           first_column,                         //
25822           (total_src_len1 >= half_width_for_2to1));
25823 
25824       const uint8_t* up2 = (*upfunc2)(          //
25825           scratch_buffer_2k_ptr + (2u * 672u),  //
25826           src2_major + (x / inv_h2),            //
25827           src2_minor + (x / inv_h2),            //
25828           src_len2,                             //
25829           h1v2_bias,                            //
25830           first_column,                         //
25831           (total_src_len2 >= half_width_for_2to1));
25832 
25833       (*conv3func)(dst, x, end, y, up0, up1, up2);
25834       x = end;
25835     }
25836 
25837     h1v2_bias ^= 3u;
25838   }
25839 
25840   // Last row.
25841   if (y_max_excl != height) {
25842     wuffs_base__pixel_swizzler__swizzle_ycc__general__triangle_filter_edge_row(
25843         dst, width, height - 1u,       //
25844         src_ptr0, src_ptr1, src_ptr2,  //
25845         stride0, stride1, stride2,     //
25846         inv_h0, inv_h1, inv_h2,        //
25847         inv_v0, inv_v1, inv_v2,        //
25848         half_width_for_2to1,           //
25849         h1v2_bias,                     //
25850         scratch_buffer_2k_ptr,         //
25851         upfunc0, upfunc1, upfunc2, conv3func);
25852   }
25853 }
25854 
25855 static void  //
wuffs_base__pixel_swizzler__swizzle_ycc__general__box_filter(wuffs_base__pixel_buffer * dst,uint32_t width,uint32_t height,const uint8_t * src_ptr0,const uint8_t * src_ptr1,const uint8_t * src_ptr2,uint32_t stride0,uint32_t stride1,uint32_t stride2,uint32_t inv_h0,uint32_t inv_h1,uint32_t inv_h2,uint32_t inv_v0,uint32_t inv_v1,uint32_t inv_v2,uint32_t half_width_for_2to1,uint32_t half_height_for_2to1,uint8_t * scratch_buffer_2k_ptr,wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func (* upfuncs)[4][4],wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_func conv3func)25856 wuffs_base__pixel_swizzler__swizzle_ycc__general__box_filter(
25857     wuffs_base__pixel_buffer* dst,
25858     uint32_t width,
25859     uint32_t height,
25860     const uint8_t* src_ptr0,
25861     const uint8_t* src_ptr1,
25862     const uint8_t* src_ptr2,
25863     uint32_t stride0,
25864     uint32_t stride1,
25865     uint32_t stride2,
25866     uint32_t inv_h0,
25867     uint32_t inv_h1,
25868     uint32_t inv_h2,
25869     uint32_t inv_v0,
25870     uint32_t inv_v1,
25871     uint32_t inv_v2,
25872     uint32_t half_width_for_2to1,
25873     uint32_t half_height_for_2to1,
25874     uint8_t* scratch_buffer_2k_ptr,
25875     wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func (*upfuncs)[4][4],
25876     wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_func conv3func) {
25877   wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc0 =
25878       (*upfuncs)[(inv_h0 - 1u) & 3u][(inv_v0 - 1u) & 3u];
25879   wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc1 =
25880       (*upfuncs)[(inv_h1 - 1u) & 3u][(inv_v1 - 1u) & 3u];
25881   wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc2 =
25882       (*upfuncs)[(inv_h2 - 1u) & 3u][(inv_v2 - 1u) & 3u];
25883 
25884   uint32_t y;
25885   for (y = 0u; y < height; y++) {
25886     const uint8_t* src0_major = src_ptr0 + ((y / inv_v0) * (size_t)stride0);
25887     const uint8_t* src1_major = src_ptr1 + ((y / inv_v1) * (size_t)stride1);
25888     const uint8_t* src2_major = src_ptr2 + ((y / inv_v2) * (size_t)stride2);
25889 
25890     uint32_t x = 0u;
25891     while (x < width) {
25892       uint32_t end = x + 672u;
25893       if (end > width) {
25894         end = width;
25895       }
25896 
25897       uint32_t src_len0 = ((end - x) + inv_h0 - 1u) / inv_h0;
25898       uint32_t src_len1 = ((end - x) + inv_h1 - 1u) / inv_h1;
25899       uint32_t src_len2 = ((end - x) + inv_h2 - 1u) / inv_h2;
25900 
25901       const uint8_t* up0 = (*upfunc0)(          //
25902           scratch_buffer_2k_ptr + (0u * 672u),  //
25903           src0_major + (x / inv_h0),            //
25904           src0_major + (x / inv_h0),            //
25905           src_len0,                             //
25906           0u, false, false);
25907 
25908       const uint8_t* up1 = (*upfunc1)(          //
25909           scratch_buffer_2k_ptr + (1u * 672u),  //
25910           src1_major + (x / inv_h1),            //
25911           src1_major + (x / inv_h1),            //
25912           src_len1,                             //
25913           0u, false, false);
25914 
25915       const uint8_t* up2 = (*upfunc2)(          //
25916           scratch_buffer_2k_ptr + (2u * 672u),  //
25917           src2_major + (x / inv_h2),            //
25918           src2_major + (x / inv_h2),            //
25919           src_len2,                             //
25920           0u, false, false);
25921 
25922       (*conv3func)(dst, x, end, y, up0, up1, up2);
25923       x = end;
25924     }
25925   }
25926 }
25927 
25928 // --------
25929 
25930 // wuffs_base__pixel_swizzler__flattened_length is like
25931 // wuffs_base__table__flattened_length but returns uint64_t (not size_t) and
25932 // also accounts for subsampling.
25933 static uint64_t  //
wuffs_base__pixel_swizzler__flattened_length(uint32_t width,uint32_t height,uint32_t stride,uint32_t inv_h,uint32_t inv_v)25934 wuffs_base__pixel_swizzler__flattened_length(uint32_t width,
25935                                              uint32_t height,
25936                                              uint32_t stride,
25937                                              uint32_t inv_h,
25938                                              uint32_t inv_v) {
25939   uint64_t scaled_width = (((uint64_t)width) + (inv_h - 1u)) / inv_h;
25940   uint64_t scaled_height = (((uint64_t)height) + (inv_v - 1u)) / inv_v;
25941   if (scaled_height <= 0u) {
25942     return 0u;
25943   }
25944   return ((scaled_height - 1u) * stride) + scaled_width;
25945 }
25946 
25947 WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
wuffs_base__pixel_swizzler__swizzle_ycck(const wuffs_base__pixel_swizzler * p,wuffs_base__pixel_buffer * dst,wuffs_base__slice_u8 dst_palette,uint32_t width,uint32_t height,wuffs_base__slice_u8 src0,wuffs_base__slice_u8 src1,wuffs_base__slice_u8 src2,wuffs_base__slice_u8 src3,uint32_t width0,uint32_t width1,uint32_t width2,uint32_t width3,uint32_t height0,uint32_t height1,uint32_t height2,uint32_t height3,uint32_t stride0,uint32_t stride1,uint32_t stride2,uint32_t stride3,uint8_t h0,uint8_t h1,uint8_t h2,uint8_t h3,uint8_t v0,uint8_t v1,uint8_t v2,uint8_t v3,bool is_rgb_or_cmyk,bool triangle_filter_for_2to1,wuffs_base__slice_u8 scratch_buffer_2k)25948 wuffs_base__pixel_swizzler__swizzle_ycck(
25949     const wuffs_base__pixel_swizzler* p,
25950     wuffs_base__pixel_buffer* dst,
25951     wuffs_base__slice_u8 dst_palette,
25952     uint32_t width,
25953     uint32_t height,
25954     wuffs_base__slice_u8 src0,
25955     wuffs_base__slice_u8 src1,
25956     wuffs_base__slice_u8 src2,
25957     wuffs_base__slice_u8 src3,
25958     uint32_t width0,
25959     uint32_t width1,
25960     uint32_t width2,
25961     uint32_t width3,
25962     uint32_t height0,
25963     uint32_t height1,
25964     uint32_t height2,
25965     uint32_t height3,
25966     uint32_t stride0,
25967     uint32_t stride1,
25968     uint32_t stride2,
25969     uint32_t stride3,
25970     uint8_t h0,
25971     uint8_t h1,
25972     uint8_t h2,
25973     uint8_t h3,
25974     uint8_t v0,
25975     uint8_t v1,
25976     uint8_t v2,
25977     uint8_t v3,
25978     bool is_rgb_or_cmyk,
25979     bool triangle_filter_for_2to1,
25980     wuffs_base__slice_u8 scratch_buffer_2k) {
25981   if (!p) {
25982     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
25983   } else if (!dst || (width > 0xFFFFu) || (height > 0xFFFFu) ||  //
25984              (4u <= ((unsigned int)h0 - 1u)) ||                  //
25985              (4u <= ((unsigned int)h1 - 1u)) ||                  //
25986              (4u <= ((unsigned int)h2 - 1u)) ||                  //
25987              (4u <= ((unsigned int)v0 - 1u)) ||                  //
25988              (4u <= ((unsigned int)v1 - 1u)) ||                  //
25989              (4u <= ((unsigned int)v2 - 1u)) ||                  //
25990              (scratch_buffer_2k.len < 2048u)) {
25991     return wuffs_base__make_status(wuffs_base__error__bad_argument);
25992   }
25993   if ((h3 != 0u) || (v3 != 0u)) {
25994     if ((4u <= ((unsigned int)h3 - 1u)) ||  //
25995         (4u <= ((unsigned int)v3 - 1u))) {
25996       return wuffs_base__make_status(wuffs_base__error__bad_argument);
25997     }
25998   }
25999 
26000   uint32_t max_incl_h = wuffs_base__u32__max_of_4(h0, h1, h2, h3);
26001   uint32_t max_incl_v = wuffs_base__u32__max_of_4(v0, v1, v2, v3);
26002 
26003   // Calculate the inverse h and v ratios.
26004   //
26005   // It also canonicalizes (h=2 and max_incl_h=4) as equivalent to (h=1 and
26006   // max_incl_h=2). In both cases, the inv_h value is 2.
26007   uint32_t inv_h0 = max_incl_h / h0;
26008   uint32_t inv_h1 = max_incl_h / h1;
26009   uint32_t inv_h2 = max_incl_h / h2;
26010   uint32_t inv_h3 = h3 ? (max_incl_h / h3) : 0u;
26011   uint32_t inv_v0 = max_incl_v / v0;
26012   uint32_t inv_v1 = max_incl_v / v1;
26013   uint32_t inv_v2 = max_incl_v / v2;
26014   uint32_t inv_v3 = v3 ? (max_incl_v / v3) : 0u;
26015 
26016   uint32_t half_width_for_2to1 = (width + 1u) / 2u;
26017   uint32_t half_height_for_2to1 = (height + 1u) / 2u;
26018 
26019   width = wuffs_base__u32__min_of_5(  //
26020       width,                          //
26021       width0 * inv_h0,                //
26022       width1 * inv_h1,                //
26023       width2 * inv_h2,                //
26024       wuffs_base__pixel_config__width(&dst->pixcfg));
26025   height = wuffs_base__u32__min_of_5(  //
26026       height,                          //
26027       height0 * inv_v0,                //
26028       height1 * inv_v1,                //
26029       height2 * inv_v2,                //
26030       wuffs_base__pixel_config__height(&dst->pixcfg));
26031 
26032   if (((h0 * inv_h0) != max_incl_h) ||  //
26033       ((h1 * inv_h1) != max_incl_h) ||  //
26034       ((h2 * inv_h2) != max_incl_h) ||  //
26035       ((v0 * inv_v0) != max_incl_v) ||  //
26036       ((v1 * inv_v1) != max_incl_v) ||  //
26037       ((v2 * inv_v2) != max_incl_v) ||  //
26038       (src0.len < wuffs_base__pixel_swizzler__flattened_length(
26039                       width, height, stride0, inv_h0, inv_v0)) ||
26040       (src1.len < wuffs_base__pixel_swizzler__flattened_length(
26041                       width, height, stride1, inv_h1, inv_v1)) ||
26042       (src2.len < wuffs_base__pixel_swizzler__flattened_length(
26043                       width, height, stride2, inv_h2, inv_v2))) {
26044     return wuffs_base__make_status(wuffs_base__error__bad_argument);
26045   }
26046   if ((h3 != 0u) || (v3 != 0u)) {
26047     if (((h3 * inv_h3) != max_incl_h) ||  //
26048         ((v3 * inv_v3) != max_incl_v) ||  //
26049         (src3.len < wuffs_base__pixel_swizzler__flattened_length(
26050                         width, height, stride3, inv_h3, inv_v3))) {
26051       return wuffs_base__make_status(wuffs_base__error__bad_argument);
26052     }
26053   }
26054 
26055   if (wuffs_base__pixel_format__is_planar(&dst->pixcfg.private_impl.pixfmt)) {
26056     // TODO: see wuffs_base__pixel_buffer__set_color_u32_at's TODO.
26057     return wuffs_base__make_status(
26058         wuffs_base__error__unsupported_pixel_swizzler_option);
26059   }
26060 
26061   switch (dst->pixcfg.private_impl.pixfmt.repr) {
26062     case WUFFS_BASE__PIXEL_FORMAT__Y:
26063     case WUFFS_BASE__PIXEL_FORMAT__Y_16LE:
26064     case WUFFS_BASE__PIXEL_FORMAT__Y_16BE:
26065     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:
26066     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL:
26067     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY:
26068     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
26069     case WUFFS_BASE__PIXEL_FORMAT__BGR:
26070     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
26071     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
26072     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
26073     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
26074     case WUFFS_BASE__PIXEL_FORMAT__RGB:
26075     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
26076     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
26077     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
26078       break;
26079 
26080     default:
26081       // TODO: see wuffs_base__pixel_buffer__set_color_u32_at's TODO.
26082       return wuffs_base__make_status(
26083           wuffs_base__error__unsupported_pixel_swizzler_option);
26084   }
26085 
26086   if ((width <= 0u) || (height <= 0u)) {
26087     return wuffs_base__make_status(NULL);
26088   }
26089 
26090   wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_func conv3func = NULL;
26091 
26092   if (is_rgb_or_cmyk) {
26093     conv3func = &wuffs_base__pixel_swizzler__swizzle_rgb__convert_3_general;
26094   } else {
26095     switch (dst->pixcfg.private_impl.pixfmt.repr) {
26096       case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
26097       case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
26098       case WUFFS_BASE__PIXEL_FORMAT__BGRX:
26099 #if defined(WUFFS_BASE__CPU_ARCH__X86_64)
26100         if (wuffs_base__cpu_arch__have_x86_avx2()) {
26101           conv3func =
26102               &wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_bgrx_x86_avx2;
26103           break;
26104         }
26105 #endif
26106         conv3func = &wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_bgrx;
26107         break;
26108       case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
26109       case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
26110       case WUFFS_BASE__PIXEL_FORMAT__RGBX:
26111 #if defined(WUFFS_BASE__CPU_ARCH__X86_64)
26112         if (wuffs_base__cpu_arch__have_x86_avx2()) {
26113           conv3func =
26114               &wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_rgbx_x86_avx2;
26115           break;
26116         }
26117 #endif
26118         conv3func = &wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_rgbx;
26119         break;
26120       default:
26121         conv3func = &wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_general;
26122         break;
26123     }
26124   }
26125 
26126   void (*func)(
26127       wuffs_base__pixel_buffer * dst,  //
26128       uint32_t width,                  //
26129       uint32_t height,                 //
26130       const uint8_t* src_ptr0,         //
26131       const uint8_t* src_ptr1,         //
26132       const uint8_t* src_ptr2,         //
26133       uint32_t stride0,                //
26134       uint32_t stride1,                //
26135       uint32_t stride2,                //
26136       uint32_t inv_h0,                 //
26137       uint32_t inv_h1,                 //
26138       uint32_t inv_h2,                 //
26139       uint32_t inv_v0,                 //
26140       uint32_t inv_v1,                 //
26141       uint32_t inv_v2,                 //
26142       uint32_t half_width_for_2to1,    //
26143       uint32_t half_height_for_2to1,   //
26144       uint8_t* scratch_buffer_2k_ptr,  //
26145       wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func(*upfuncs)[4][4],
26146       wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_func conv3func) =
26147       &wuffs_base__pixel_swizzler__swizzle_ycc__general__box_filter;
26148 
26149   wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfuncs[4][4];
26150   memcpy(&upfuncs, &wuffs_base__pixel_swizzler__swizzle_ycc__upsample_funcs,
26151          sizeof upfuncs);
26152 
26153   if (triangle_filter_for_2to1 &&
26154       (wuffs_base__pixel_swizzler__has_triangle_upsampler(inv_h0, inv_v0) ||
26155        wuffs_base__pixel_swizzler__has_triangle_upsampler(inv_h1, inv_v1) ||
26156        wuffs_base__pixel_swizzler__has_triangle_upsampler(inv_h2, inv_v2))) {
26157     func = &wuffs_base__pixel_swizzler__swizzle_ycc__general__triangle_filter;
26158 
26159     upfuncs[0][1] =
26160         wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h1v2_triangle;
26161     upfuncs[1][0] =
26162         wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2v1_triangle;
26163     upfuncs[1][1] =
26164         wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2v2_triangle;
26165 
26166 #if defined(WUFFS_BASE__CPU_ARCH__X86_64)
26167 #if defined(__GNUC__) && !defined(__clang__)
26168     // Don't use our AVX2 implementation for GCC (but do use it for clang). For
26169     // some unknown reason, GCC performs noticably better on the non-SIMD
26170     // version. Possibly because GCC's auto-vectorizer is smarter (just with
26171     // SSE2, not AVX2) than our hand-written code, but that's just a guess.
26172     //
26173     // See commits 51bc60ef9298cb2efc1b29a9681191f66d49820d and
26174     // cd769a0cdf1b5affee13f6089b995f3d39569cb4 for benchmark numbers.
26175     //
26176     // See also https://godbolt.org/z/MbhbPGEz4 for Debian Bullseye's clang 11
26177     // versus gcc 10, where only gcc auto-vectorizes, although later clang
26178     // versions will also auto-vectorize.
26179 #else
26180     if (wuffs_base__cpu_arch__have_x86_avx2()) {
26181       upfuncs[1][1] =
26182           wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2v2_triangle_x86_avx2;
26183     }
26184 #endif
26185 #endif
26186   }
26187 
26188   if ((h3 != 0u) || (v3 != 0u)) {
26189     wuffs_base__pixel_swizzler__swizzle_ycc__convert_4_func conv4func =
26190         is_rgb_or_cmyk
26191             ? &wuffs_base__pixel_swizzler__swizzle_cmyk__convert_4_general
26192             : &wuffs_base__pixel_swizzler__swizzle_ycck__convert_4_general;
26193     wuffs_base__pixel_swizzler__swizzle_ycck__general__triangle_filter(  //
26194         dst, width, height,                                              //
26195         src0.ptr, src1.ptr, src2.ptr, src3.ptr,                          //
26196         stride0, stride1, stride2, stride3,                              //
26197         inv_h0, inv_h1, inv_h2, inv_h3,                                  //
26198         inv_v0, inv_v1, inv_v2, inv_v3,                                  //
26199         half_width_for_2to1, half_height_for_2to1,                       //
26200         scratch_buffer_2k.ptr, &upfuncs, conv4func);
26201 
26202   } else {
26203     (*func)(                                        //
26204         dst, width, height,                         //
26205         src0.ptr, src1.ptr, src2.ptr,               //
26206         stride0, stride1, stride2,                  //
26207         inv_h0, inv_h1, inv_h2,                     //
26208         inv_v0, inv_v1, inv_v2,                     //
26209         half_width_for_2to1, half_height_for_2to1,  //
26210         scratch_buffer_2k.ptr, &upfuncs, conv3func);
26211   }
26212 
26213   return wuffs_base__make_status(NULL);
26214 }
26215 
26216 // --------
26217 
26218 // ‼ WUFFS MULTI-FILE SECTION +x86_avx2
26219 #if defined(WUFFS_BASE__CPU_ARCH__X86_64)
26220 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2")
26221 static void  //
wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_bgrx_x86_avx2(wuffs_base__pixel_buffer * dst,uint32_t x,uint32_t x_end,uint32_t y,const uint8_t * up0,const uint8_t * up1,const uint8_t * up2)26222 wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_bgrx_x86_avx2(
26223     wuffs_base__pixel_buffer* dst,
26224     uint32_t x,
26225     uint32_t x_end,
26226     uint32_t y,
26227     const uint8_t* up0,
26228     const uint8_t* up1,
26229     const uint8_t* up2) {
26230   if ((x + 32u) > x_end) {
26231     wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_bgrx(  //
26232         dst, x, x_end, y, up0, up1, up2);
26233     return;
26234   }
26235 
26236   size_t dst_stride = dst->private_impl.planes[0].stride;
26237   uint8_t* dst_iter = dst->private_impl.planes[0].ptr +
26238                       (dst_stride * ((size_t)y)) + (4u * ((size_t)x));
26239 
26240   // u0001 = u16x16 [0x0001 .. 0x0001]
26241   // u00FF = u16x16 [0x00FF .. 0x00FF]
26242   // uFF80 = u16x16 [0xFF80 .. 0xFF80]
26243   // uFFFF = u16x16 [0xFFFF .. 0xFFFF]
26244   const __m256i u0001 = _mm256_set1_epi16(+0x0001);
26245   const __m256i u00FF = _mm256_set1_epi16(+0x00FF);
26246   const __m256i uFF80 = _mm256_set1_epi16(-0x0080);
26247   const __m256i uFFFF = _mm256_set1_epi16(-0x0001);
26248 
26249   // p8000_p0000 = u16x16 [0x8000 0x0000 .. 0x8000 0x0000]
26250   const __m256i p8000_p0000 = _mm256_set_epi16(  //
26251       +0x0000, -0x8000, +0x0000, -0x8000,        //
26252       +0x0000, -0x8000, +0x0000, -0x8000,        //
26253       +0x0000, -0x8000, +0x0000, -0x8000,        //
26254       +0x0000, -0x8000, +0x0000, -0x8000);
26255 
26256   // Per wuffs_base__color_ycc__as__color_u32, the formulae:
26257   //
26258   //  R = Y                + 1.40200 * Cr
26259   //  G = Y - 0.34414 * Cb - 0.71414 * Cr
26260   //  B = Y + 1.77200 * Cb
26261   //
26262   // When scaled by 1<<16:
26263   //
26264   //  0.34414 becomes 0x0581A =  22554.
26265   //  0.71414 becomes 0x0B6D2 =  46802.
26266   //  1.40200 becomes 0x166E9 =  91881.
26267   //  1.77200 becomes 0x1C5A2 = 116130.
26268   //
26269   // Separate the integer and fractional parts, since we work with signed
26270   // 16-bit SIMD lanes. The fractional parts range from -0.5 .. +0.5 (as
26271   // floating-point) which is from -0x8000 .. +0x8000 (as fixed-point).
26272   //
26273   //  -0x3A5E = -0x20000 + 0x1C5A2     The B:Cb factor.
26274   //  +0x66E9 = -0x10000 + 0x166E9     The R:Cr factor.
26275   //  -0x581A = +0x00000 - 0x0581A     The G:Cb factor.
26276   //  +0x492E = +0x10000 - 0x0B6D2     The G:Cr factor.
26277   const __m256i m3A5E = _mm256_set1_epi16(-0x3A5E);
26278   const __m256i p66E9 = _mm256_set1_epi16(+0x66E9);
26279   const __m256i m581A_p492E = _mm256_set_epi16(  //
26280       +0x492E, -0x581A, +0x492E, -0x581A,        //
26281       +0x492E, -0x581A, +0x492E, -0x581A,        //
26282       +0x492E, -0x581A, +0x492E, -0x581A,        //
26283       +0x492E, -0x581A, +0x492E, -0x581A);
26284 
26285   while (x < x_end) {
26286     // Load chroma values in even and odd columns (the high 8 bits of each
26287     // u16x16 element are zero) and then subtract 0x0080.
26288     //
26289     // cb_all = u8x32  [cb.00 cb.01 cb.02 cb.03 .. cb.1C cb.1D cb.1E cb.1F]
26290     // cb_eve = i16x16 [cb.00-0x80  cb.02-0x80  .. cb.1C-0x80  cb.1E-0x80 ]
26291     // cb_odd = i16x16 [cb.01-0x80  cb.03-0x80  .. cb.1D-0x80  cb.1F-0x80 ]
26292     //
26293     // Ditto for the cr_xxx Chroma-Red values.
26294     __m256i cb_all = _mm256_lddqu_si256((const __m256i*)(const void*)up1);
26295     __m256i cr_all = _mm256_lddqu_si256((const __m256i*)(const void*)up2);
26296     __m256i cb_eve = _mm256_add_epi16(uFF80, _mm256_and_si256(cb_all, u00FF));
26297     __m256i cr_eve = _mm256_add_epi16(uFF80, _mm256_and_si256(cr_all, u00FF));
26298     __m256i cb_odd = _mm256_add_epi16(uFF80, _mm256_srli_epi16(cb_all, 8));
26299     __m256i cr_odd = _mm256_add_epi16(uFF80, _mm256_srli_epi16(cr_all, 8));
26300 
26301     // ----
26302 
26303     // Calculate:
26304     //
26305     //  B-Y = (+1.77200 * Cb)                 as floating-point
26306     //  R-Y = (+1.40200 * Cr)                 as floating-point
26307     //
26308     //  B-Y = ((0x2_0000 - 0x3A5E) * Cb)      as fixed-point
26309     //  R-Y = ((0x1_0000 + 0x66E9) * Cr)      as fixed-point
26310     //
26311     //  B-Y = ((-0x3A5E * Cb) + ("2.0" * Cb))
26312     //  R-Y = ((+0x66E9 * Cr) + ("1.0" * Cr))
26313 
26314     // Multiply by m3A5E or p66E9, taking the high 16 bits. There's also a
26315     // doubling (add x to itself), adding-of-1 and halving (shift right by 1).
26316     // That makes multiply-and-take-high round to nearest (instead of down).
26317     __m256i tmp_by_eve = _mm256_srai_epi16(
26318         _mm256_add_epi16(
26319             _mm256_mulhi_epi16(_mm256_add_epi16(cb_eve, cb_eve), m3A5E), u0001),
26320         1);
26321     __m256i tmp_by_odd = _mm256_srai_epi16(
26322         _mm256_add_epi16(
26323             _mm256_mulhi_epi16(_mm256_add_epi16(cb_odd, cb_odd), m3A5E), u0001),
26324         1);
26325     __m256i tmp_ry_eve = _mm256_srai_epi16(
26326         _mm256_add_epi16(
26327             _mm256_mulhi_epi16(_mm256_add_epi16(cr_eve, cr_eve), p66E9), u0001),
26328         1);
26329     __m256i tmp_ry_odd = _mm256_srai_epi16(
26330         _mm256_add_epi16(
26331             _mm256_mulhi_epi16(_mm256_add_epi16(cr_odd, cr_odd), p66E9), u0001),
26332         1);
26333 
26334     // Add (2 * Cb) and (1 * Cr).
26335     __m256i by_eve =
26336         _mm256_add_epi16(tmp_by_eve, _mm256_add_epi16(cb_eve, cb_eve));
26337     __m256i by_odd =
26338         _mm256_add_epi16(tmp_by_odd, _mm256_add_epi16(cb_odd, cb_odd));
26339     __m256i ry_eve = _mm256_add_epi16(tmp_ry_eve, cr_eve);
26340     __m256i ry_odd = _mm256_add_epi16(tmp_ry_odd, cr_odd);
26341 
26342     // ----
26343 
26344     // Calculate:
26345     //
26346     //  G-Y = (-0.34414 * Cb) +
26347     //        (-0.71414 * Cr)                 as floating-point
26348     //
26349     //  G-Y = ((+0x0_0000 - 0x581A) * Cb) +
26350     //        ((-0x1_0000 + 0x492E) * Cr)     as fixed-point
26351     //
26352     //  G-Y =  (-0x581A * Cb) +
26353     //         (+0x492E * Cr) - ("1.0" * Cr)
26354 
26355     // Multiply-add to get ((-0x581A * Cb) + (+0x492E * Cr)).
26356     __m256i tmp0_gy_eve_lo = _mm256_madd_epi16(  //
26357         _mm256_unpacklo_epi16(cb_eve, cr_eve), m581A_p492E);
26358     __m256i tmp0_gy_eve_hi = _mm256_madd_epi16(  //
26359         _mm256_unpackhi_epi16(cb_eve, cr_eve), m581A_p492E);
26360     __m256i tmp0_gy_odd_lo = _mm256_madd_epi16(  //
26361         _mm256_unpacklo_epi16(cb_odd, cr_odd), m581A_p492E);
26362     __m256i tmp0_gy_odd_hi = _mm256_madd_epi16(  //
26363         _mm256_unpackhi_epi16(cb_odd, cr_odd), m581A_p492E);
26364 
26365     // Divide the i32x8 vectors by (1 << 16), rounding to nearest.
26366     __m256i tmp1_gy_eve_lo =
26367         _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_eve_lo, p8000_p0000), 16);
26368     __m256i tmp1_gy_eve_hi =
26369         _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_eve_hi, p8000_p0000), 16);
26370     __m256i tmp1_gy_odd_lo =
26371         _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_odd_lo, p8000_p0000), 16);
26372     __m256i tmp1_gy_odd_hi =
26373         _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_odd_hi, p8000_p0000), 16);
26374 
26375     // Pack the ((-0x581A * Cb) + (+0x492E * Cr)) as i16x16 and subtract Cr.
26376     __m256i gy_eve = _mm256_sub_epi16(
26377         _mm256_packs_epi32(tmp1_gy_eve_lo, tmp1_gy_eve_hi), cr_eve);
26378     __m256i gy_odd = _mm256_sub_epi16(
26379         _mm256_packs_epi32(tmp1_gy_odd_lo, tmp1_gy_odd_hi), cr_odd);
26380 
26381     // ----
26382 
26383     // Add Y to (B-Y), (G-Y) and (R-Y) to produce B, G and R.
26384     //
26385     // For the resultant packed_x_xxx vectors, only elements 0 ..= 7 and 16 ..=
26386     // 23 of the 32-element vectors matter (since we'll unpacklo but not
26387     // unpackhi them). Let … denote 8 ignored consecutive u8 values and let %
26388     // denote 0xFF. We'll end this section with:
26389     //
26390     // packed_b_eve = u8x32 [b00 b02 .. b0C b0E  …  b10 b12 .. b1C b1E  …]
26391     // packed_b_odd = u8x32 [b01 b03 .. b0D b0F  …  b11 b13 .. b1D b1F  …]
26392     // packed_g_eve = u8x32 [g00 g02 .. g0C g0E  …  g10 g12 .. g1C g1E  …]
26393     // packed_g_odd = u8x32 [g01 g03 .. g0D g0F  …  g11 g13 .. g1D g1F  …]
26394     // packed_r_eve = u8x32 [r00 r02 .. r0C r0E  …  r10 r12 .. r1C r1E  …]
26395     // packed_r_odd = u8x32 [r01 r03 .. r0D r0F  …  r11 r13 .. r1D r1F  …]
26396     // uFFFF        = u8x32 [  %   % ..   %   %  …    %   % ..   %   %  …]
26397 
26398     __m256i yy_all = _mm256_lddqu_si256((const __m256i*)(const void*)up0);
26399     __m256i yy_eve = _mm256_and_si256(yy_all, u00FF);
26400     __m256i yy_odd = _mm256_srli_epi16(yy_all, 8);
26401 
26402     __m256i loose_b_eve = _mm256_add_epi16(by_eve, yy_eve);
26403     __m256i loose_b_odd = _mm256_add_epi16(by_odd, yy_odd);
26404     __m256i packed_b_eve = _mm256_packus_epi16(loose_b_eve, loose_b_eve);
26405     __m256i packed_b_odd = _mm256_packus_epi16(loose_b_odd, loose_b_odd);
26406 
26407     __m256i loose_g_eve = _mm256_add_epi16(gy_eve, yy_eve);
26408     __m256i loose_g_odd = _mm256_add_epi16(gy_odd, yy_odd);
26409     __m256i packed_g_eve = _mm256_packus_epi16(loose_g_eve, loose_g_eve);
26410     __m256i packed_g_odd = _mm256_packus_epi16(loose_g_odd, loose_g_odd);
26411 
26412     __m256i loose_r_eve = _mm256_add_epi16(ry_eve, yy_eve);
26413     __m256i loose_r_odd = _mm256_add_epi16(ry_odd, yy_odd);
26414     __m256i packed_r_eve = _mm256_packus_epi16(loose_r_eve, loose_r_eve);
26415     __m256i packed_r_odd = _mm256_packus_epi16(loose_r_odd, loose_r_odd);
26416 
26417     // ----
26418 
26419     // Mix those values (unpacking in 8, 16 and then 32 bit units) to get the
26420     // desired BGRX/RGBX order.
26421     //
26422     // From here onwards, all of our __m256i registers are u8x32.
26423 
26424     // mix00 = [b00 g00 b02 g02 .. b0E g0E b10 g10 .. b1C g1C b1E g1E]
26425     // mix01 = [b01 g01 b03 g03 .. b0F g0F b11 g11 .. b1D g1D b1F g1F]
26426     // mix02 = [r00   % r02   % .. r0E   % r10   % .. r1C   % r1E   %]
26427     // mix03 = [r01   % r03   % .. r0F   % r11   % .. r1D   % r1F   %]
26428     //
26429     // See also § below.
26430     __m256i mix00 = _mm256_unpacklo_epi8(packed_b_eve, packed_g_eve);
26431     __m256i mix01 = _mm256_unpacklo_epi8(packed_b_odd, packed_g_odd);
26432     __m256i mix02 = _mm256_unpacklo_epi8(packed_r_eve, uFFFF);
26433     __m256i mix03 = _mm256_unpacklo_epi8(packed_r_odd, uFFFF);
26434 
26435     // mix10 = [b00 g00 r00 %  b02 g02 r02 %  b04 g04 r04 %  b06 g06 r06 %
26436     //          b10 g10 r10 %  b12 g12 r12 %  b14 g14 r14 %  b16 g16 r16 %]
26437     // mix11 = [b01 g01 r01 %  b03 g03 r03 %  b05 g05 r05 %  b07 g07 r07 %
26438     //          b11 g11 r11 %  b13 g13 r13 %  b15 g15 r15 %  b17 g17 r17 %]
26439     // mix12 = [b08 g08 r08 %  b0A g0A r0A %  b0C g0C r0C %  b0E g0E r0E %
26440     //          b18 g18 r18 %  b1A g1A r1A %  b1C g1C r1C %  b1E g1E r1E %]
26441     // mix13 = [b09 g09 r09 %  b0B g0B r0B %  b0D g0D r0D %  b0F g0F r0F %
26442     //          b19 g19 r19 %  b1B g1B r1B %  b1D g1D r1D %  b1F g1F r1F %]
26443     __m256i mix10 = _mm256_unpacklo_epi16(mix00, mix02);
26444     __m256i mix11 = _mm256_unpacklo_epi16(mix01, mix03);
26445     __m256i mix12 = _mm256_unpackhi_epi16(mix00, mix02);
26446     __m256i mix13 = _mm256_unpackhi_epi16(mix01, mix03);
26447 
26448     // mix20 = [b00 g00 r00 %  b01 g01 r01 %  b02 g02 r02 %  b03 g03 r03 %
26449     //          b10 g10 r10 %  b11 g11 r11 %  b12 g12 r12 %  b13 g13 r13 %]
26450     // mix21 = [b04 g04 r04 %  b05 g05 r05 %  b06 g06 r06 %  b07 g07 r07 %
26451     //          b14 g14 r14 %  b15 g15 r15 %  b16 g16 r16 %  b17 g17 r17 %]
26452     // mix22 = [b08 g08 r08 %  b09 g09 r09 %  b0A g0A r0A %  b0B g0B r0B %
26453     //          b18 g18 r18 %  b19 g19 r19 %  b1A g1A r1A %  b1B g1B r1B %]
26454     // mix23 = [b0C g0C r0C %  b0D g0D r0D %  b0E g0E r0E %  b0F g0F r0F %
26455     //          b1C g1C r1C %  b1D g1D r1D %  b1E g1E r1E %  b1F g1F r1F %]
26456     __m256i mix20 = _mm256_unpacklo_epi32(mix10, mix11);
26457     __m256i mix21 = _mm256_unpackhi_epi32(mix10, mix11);
26458     __m256i mix22 = _mm256_unpacklo_epi32(mix12, mix13);
26459     __m256i mix23 = _mm256_unpackhi_epi32(mix12, mix13);
26460 
26461     // mix30 = [b00 g00 r00 %  b01 g01 r01 %  b02 g02 r02 %  b03 g03 r03 %
26462     //          b04 g04 r04 %  b05 g05 r05 %  b06 g06 r06 %  b07 g07 r07 %]
26463     // mix31 = [b08 g08 r08 %  b09 g09 r09 %  b0A g0A r0A %  b0B g0B r0B %
26464     //          b0C g0C r0C %  b0D g0D r0D %  b0E g0E r0E %  b0F g0F r0F %]
26465     // mix32 = [b10 g10 r10 %  b11 g11 r11 %  b12 g12 r12 %  b13 g13 r13 %
26466     //          b14 g14 r14 %  b15 g15 r15 %  b16 g16 r16 %  b17 g17 r17 %]
26467     // mix33 = [b18 g18 r18 %  b19 g19 r19 %  b1A g1A r1A %  b1B g1B r1B %
26468     //          b1C g1C r1C %  b1D g1D r1D %  b1E g1E r1E %  b1F g1F r1F %]
26469     __m256i mix30 = _mm256_permute2x128_si256(mix20, mix21, 0x20);
26470     __m256i mix31 = _mm256_permute2x128_si256(mix22, mix23, 0x20);
26471     __m256i mix32 = _mm256_permute2x128_si256(mix20, mix21, 0x31);
26472     __m256i mix33 = _mm256_permute2x128_si256(mix22, mix23, 0x31);
26473 
26474     // Write out four u8x32 SIMD registers (128 bytes, 32 BGRX/RGBX pixels).
26475     _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x00), mix30);
26476     _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x20), mix31);
26477     _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x40), mix32);
26478     _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x60), mix33);
26479 
26480     // Advance by up to 32 pixels. The first iteration might be smaller than 32
26481     // so that all of the remaining steps are exactly 32.
26482     uint32_t n = 32u - (31u & (x - x_end));
26483     dst_iter += 4u * n;
26484     up0 += n;
26485     up1 += n;
26486     up2 += n;
26487     x += n;
26488   }
26489 }
26490 
26491 // The rgbx flavor (below) is exactly the same as the bgrx flavor (above)
26492 // except for the lines marked with a § and that comments were stripped.
26493 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2")
26494 static void  //
wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_rgbx_x86_avx2(wuffs_base__pixel_buffer * dst,uint32_t x,uint32_t x_end,uint32_t y,const uint8_t * up0,const uint8_t * up1,const uint8_t * up2)26495 wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_rgbx_x86_avx2(
26496     wuffs_base__pixel_buffer* dst,
26497     uint32_t x,
26498     uint32_t x_end,
26499     uint32_t y,
26500     const uint8_t* up0,
26501     const uint8_t* up1,
26502     const uint8_t* up2) {
26503   if ((x + 32u) > x_end) {
26504     wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_bgrx(  //
26505         dst, x, x_end, y, up0, up1, up2);
26506     return;
26507   }
26508 
26509   size_t dst_stride = dst->private_impl.planes[0].stride;
26510   uint8_t* dst_iter = dst->private_impl.planes[0].ptr +
26511                       (dst_stride * ((size_t)y)) + (4u * ((size_t)x));
26512 
26513   const __m256i u0001 = _mm256_set1_epi16(+0x0001);
26514   const __m256i u00FF = _mm256_set1_epi16(+0x00FF);
26515   const __m256i uFF80 = _mm256_set1_epi16(-0x0080);
26516   const __m256i uFFFF = _mm256_set1_epi16(-0x0001);
26517 
26518   const __m256i p8000_p0000 = _mm256_set_epi16(  //
26519       +0x0000, -0x8000, +0x0000, -0x8000,        //
26520       +0x0000, -0x8000, +0x0000, -0x8000,        //
26521       +0x0000, -0x8000, +0x0000, -0x8000,        //
26522       +0x0000, -0x8000, +0x0000, -0x8000);
26523 
26524   const __m256i m3A5E = _mm256_set1_epi16(-0x3A5E);
26525   const __m256i p66E9 = _mm256_set1_epi16(+0x66E9);
26526   const __m256i m581A_p492E = _mm256_set_epi16(  //
26527       +0x492E, -0x581A, +0x492E, -0x581A,        //
26528       +0x492E, -0x581A, +0x492E, -0x581A,        //
26529       +0x492E, -0x581A, +0x492E, -0x581A,        //
26530       +0x492E, -0x581A, +0x492E, -0x581A);
26531 
26532   while (x < x_end) {
26533     __m256i cb_all = _mm256_lddqu_si256((const __m256i*)(const void*)up1);
26534     __m256i cr_all = _mm256_lddqu_si256((const __m256i*)(const void*)up2);
26535     __m256i cb_eve = _mm256_add_epi16(uFF80, _mm256_and_si256(cb_all, u00FF));
26536     __m256i cr_eve = _mm256_add_epi16(uFF80, _mm256_and_si256(cr_all, u00FF));
26537     __m256i cb_odd = _mm256_add_epi16(uFF80, _mm256_srli_epi16(cb_all, 8));
26538     __m256i cr_odd = _mm256_add_epi16(uFF80, _mm256_srli_epi16(cr_all, 8));
26539 
26540     __m256i tmp_by_eve = _mm256_srai_epi16(
26541         _mm256_add_epi16(
26542             _mm256_mulhi_epi16(_mm256_add_epi16(cb_eve, cb_eve), m3A5E), u0001),
26543         1);
26544     __m256i tmp_by_odd = _mm256_srai_epi16(
26545         _mm256_add_epi16(
26546             _mm256_mulhi_epi16(_mm256_add_epi16(cb_odd, cb_odd), m3A5E), u0001),
26547         1);
26548     __m256i tmp_ry_eve = _mm256_srai_epi16(
26549         _mm256_add_epi16(
26550             _mm256_mulhi_epi16(_mm256_add_epi16(cr_eve, cr_eve), p66E9), u0001),
26551         1);
26552     __m256i tmp_ry_odd = _mm256_srai_epi16(
26553         _mm256_add_epi16(
26554             _mm256_mulhi_epi16(_mm256_add_epi16(cr_odd, cr_odd), p66E9), u0001),
26555         1);
26556 
26557     __m256i by_eve =
26558         _mm256_add_epi16(tmp_by_eve, _mm256_add_epi16(cb_eve, cb_eve));
26559     __m256i by_odd =
26560         _mm256_add_epi16(tmp_by_odd, _mm256_add_epi16(cb_odd, cb_odd));
26561     __m256i ry_eve = _mm256_add_epi16(tmp_ry_eve, cr_eve);
26562     __m256i ry_odd = _mm256_add_epi16(tmp_ry_odd, cr_odd);
26563 
26564     __m256i tmp0_gy_eve_lo = _mm256_madd_epi16(  //
26565         _mm256_unpacklo_epi16(cb_eve, cr_eve), m581A_p492E);
26566     __m256i tmp0_gy_eve_hi = _mm256_madd_epi16(  //
26567         _mm256_unpackhi_epi16(cb_eve, cr_eve), m581A_p492E);
26568     __m256i tmp0_gy_odd_lo = _mm256_madd_epi16(  //
26569         _mm256_unpacklo_epi16(cb_odd, cr_odd), m581A_p492E);
26570     __m256i tmp0_gy_odd_hi = _mm256_madd_epi16(  //
26571         _mm256_unpackhi_epi16(cb_odd, cr_odd), m581A_p492E);
26572 
26573     __m256i tmp1_gy_eve_lo =
26574         _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_eve_lo, p8000_p0000), 16);
26575     __m256i tmp1_gy_eve_hi =
26576         _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_eve_hi, p8000_p0000), 16);
26577     __m256i tmp1_gy_odd_lo =
26578         _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_odd_lo, p8000_p0000), 16);
26579     __m256i tmp1_gy_odd_hi =
26580         _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_odd_hi, p8000_p0000), 16);
26581 
26582     __m256i gy_eve = _mm256_sub_epi16(
26583         _mm256_packs_epi32(tmp1_gy_eve_lo, tmp1_gy_eve_hi), cr_eve);
26584     __m256i gy_odd = _mm256_sub_epi16(
26585         _mm256_packs_epi32(tmp1_gy_odd_lo, tmp1_gy_odd_hi), cr_odd);
26586 
26587     __m256i yy_all = _mm256_lddqu_si256((const __m256i*)(const void*)up0);
26588     __m256i yy_eve = _mm256_and_si256(yy_all, u00FF);
26589     __m256i yy_odd = _mm256_srli_epi16(yy_all, 8);
26590 
26591     __m256i loose_b_eve = _mm256_add_epi16(by_eve, yy_eve);
26592     __m256i loose_b_odd = _mm256_add_epi16(by_odd, yy_odd);
26593     __m256i packed_b_eve = _mm256_packus_epi16(loose_b_eve, loose_b_eve);
26594     __m256i packed_b_odd = _mm256_packus_epi16(loose_b_odd, loose_b_odd);
26595 
26596     __m256i loose_g_eve = _mm256_add_epi16(gy_eve, yy_eve);
26597     __m256i loose_g_odd = _mm256_add_epi16(gy_odd, yy_odd);
26598     __m256i packed_g_eve = _mm256_packus_epi16(loose_g_eve, loose_g_eve);
26599     __m256i packed_g_odd = _mm256_packus_epi16(loose_g_odd, loose_g_odd);
26600 
26601     __m256i loose_r_eve = _mm256_add_epi16(ry_eve, yy_eve);
26602     __m256i loose_r_odd = _mm256_add_epi16(ry_odd, yy_odd);
26603     __m256i packed_r_eve = _mm256_packus_epi16(loose_r_eve, loose_r_eve);
26604     __m256i packed_r_odd = _mm256_packus_epi16(loose_r_odd, loose_r_odd);
26605 
26606     // § Note the swapped B and R channels.
26607     __m256i mix00 = _mm256_unpacklo_epi8(packed_r_eve, packed_g_eve);
26608     __m256i mix01 = _mm256_unpacklo_epi8(packed_r_odd, packed_g_odd);
26609     __m256i mix02 = _mm256_unpacklo_epi8(packed_b_eve, uFFFF);
26610     __m256i mix03 = _mm256_unpacklo_epi8(packed_b_odd, uFFFF);
26611 
26612     __m256i mix10 = _mm256_unpacklo_epi16(mix00, mix02);
26613     __m256i mix11 = _mm256_unpacklo_epi16(mix01, mix03);
26614     __m256i mix12 = _mm256_unpackhi_epi16(mix00, mix02);
26615     __m256i mix13 = _mm256_unpackhi_epi16(mix01, mix03);
26616 
26617     __m256i mix20 = _mm256_unpacklo_epi32(mix10, mix11);
26618     __m256i mix21 = _mm256_unpackhi_epi32(mix10, mix11);
26619     __m256i mix22 = _mm256_unpacklo_epi32(mix12, mix13);
26620     __m256i mix23 = _mm256_unpackhi_epi32(mix12, mix13);
26621 
26622     __m256i mix30 = _mm256_permute2x128_si256(mix20, mix21, 0x20);
26623     __m256i mix31 = _mm256_permute2x128_si256(mix22, mix23, 0x20);
26624     __m256i mix32 = _mm256_permute2x128_si256(mix20, mix21, 0x31);
26625     __m256i mix33 = _mm256_permute2x128_si256(mix22, mix23, 0x31);
26626 
26627     _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x00), mix30);
26628     _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x20), mix31);
26629     _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x40), mix32);
26630     _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x60), mix33);
26631 
26632     uint32_t n = 32u - (31u & (x - x_end));
26633     dst_iter += 4u * n;
26634     up0 += n;
26635     up1 += n;
26636     up2 += n;
26637     x += n;
26638   }
26639 }
26640 
26641 #if defined(__GNUC__) && !defined(__clang__)
26642 // No-op.
26643 #else
26644 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2")
26645 static const uint8_t*  //
wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2v2_triangle_x86_avx2(uint8_t * dst_ptr,const uint8_t * src_ptr_major,const uint8_t * src_ptr_minor,size_t src_len,uint32_t h1v2_bias_ignored,bool first_column,bool last_column)26646 wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2v2_triangle_x86_avx2(
26647     uint8_t* dst_ptr,
26648     const uint8_t* src_ptr_major,
26649     const uint8_t* src_ptr_minor,
26650     size_t src_len,
26651     uint32_t h1v2_bias_ignored,
26652     bool first_column,
26653     bool last_column) {
26654   uint8_t* dp = dst_ptr;
26655   const uint8_t* sp_major = src_ptr_major;
26656   const uint8_t* sp_minor = src_ptr_minor;
26657 
26658   if (first_column) {
26659     src_len--;
26660     if ((src_len <= 0u) && last_column) {
26661       uint32_t sv = (12u * ((uint32_t)(*sp_major++))) +  //
26662                     (4u * ((uint32_t)(*sp_minor++)));
26663       *dp++ = (uint8_t)((sv + 8u) >> 4u);
26664       *dp++ = (uint8_t)((sv + 7u) >> 4u);
26665       return dst_ptr;
26666     }
26667 
26668     uint32_t sv_major_m1 = sp_major[-0];  // Clamp offset to zero.
26669     uint32_t sv_minor_m1 = sp_minor[-0];  // Clamp offset to zero.
26670     uint32_t sv_major_p1 = sp_major[+1];
26671     uint32_t sv_minor_p1 = sp_minor[+1];
26672 
26673     uint32_t sv = (9u * ((uint32_t)(*sp_major++))) +  //
26674                   (3u * ((uint32_t)(*sp_minor++)));
26675     *dp++ = (uint8_t)((sv + (3u * sv_major_m1) + (sv_minor_m1) + 8u) >> 4u);
26676     *dp++ = (uint8_t)((sv + (3u * sv_major_p1) + (sv_minor_p1) + 7u) >> 4u);
26677     if (src_len <= 0u) {
26678       return dst_ptr;
26679     }
26680   }
26681 
26682   if (last_column) {
26683     src_len--;
26684   }
26685 
26686   if (src_len < 32) {
26687     // This fallback is the same as the non-SIMD-capable code path.
26688     for (; src_len > 0u; src_len--) {
26689       uint32_t sv_major_m1 = sp_major[-1];
26690       uint32_t sv_minor_m1 = sp_minor[-1];
26691       uint32_t sv_major_p1 = sp_major[+1];
26692       uint32_t sv_minor_p1 = sp_minor[+1];
26693 
26694       uint32_t sv = (9u * ((uint32_t)(*sp_major++))) +  //
26695                     (3u * ((uint32_t)(*sp_minor++)));
26696       *dp++ = (uint8_t)((sv + (3u * sv_major_m1) + (sv_minor_m1) + 8u) >> 4u);
26697       *dp++ = (uint8_t)((sv + (3u * sv_major_p1) + (sv_minor_p1) + 7u) >> 4u);
26698     }
26699 
26700   } else {
26701     while (src_len > 0u) {
26702       // Load 1+32+1 samples (six u8x32 vectors) from the major (jxx) and minor
26703       // (nxx) rows.
26704       //
26705       // major_p0 = [j00 j01 j02 j03 .. j28 j29 j30 j31]   // p0 = "plus  0"
26706       // minor_p0 = [n00 n01 n02 n03 .. n28 n29 n30 n31]   // p0 = "plus  0"
26707       // major_m1 = [jm1 j00 j01 j02 .. j27 j28 j29 j30]   // m1 = "minus 1"
26708       // minor_m1 = [nm1 n00 n01 n02 .. n27 n28 n29 n30]   // m1 = "minus 1"
26709       // major_p1 = [j01 j02 j03 j04 .. j29 j30 j31 j32]   // p1 = "plus  1"
26710       // minor_p1 = [n01 n02 n03 n04 .. n29 n30 n31 n32]   // p1 = "plus  1"
26711       __m256i major_p0 =
26712           _mm256_lddqu_si256((const __m256i*)(const void*)(sp_major + 0));
26713       __m256i minor_p0 =
26714           _mm256_lddqu_si256((const __m256i*)(const void*)(sp_minor + 0));
26715       __m256i major_m1 =
26716           _mm256_lddqu_si256((const __m256i*)(const void*)(sp_major - 1));
26717       __m256i minor_m1 =
26718           _mm256_lddqu_si256((const __m256i*)(const void*)(sp_minor - 1));
26719       __m256i major_p1 =
26720           _mm256_lddqu_si256((const __m256i*)(const void*)(sp_major + 1));
26721       __m256i minor_p1 =
26722           _mm256_lddqu_si256((const __m256i*)(const void*)(sp_minor + 1));
26723 
26724       // Unpack, staying with u8x32 vectors.
26725       //
26726       // step1_p0_lo = [j00 n00 j01 n01 .. j07 n07  j16 n16 j17 n17 .. j23 n23]
26727       // step1_p0_hi = [j08 n08 j09 n09 .. j15 n15  j24 n24 j25 n25 .. j31 n31]
26728       // step1_m1_lo = [jm1 nm1 j00 n00 .. j06 n06  j15 n15 j16 n16 .. j22 n22]
26729       // step1_m1_hi = [j07 n07 j08 n08 .. j14 n14  j23 n23 j24 n24 .. j30 n30]
26730       // step1_p1_lo = [j01 n01 j02 n02 .. j08 n08  j17 n17 j18 n18 .. j24 n24]
26731       // step1_p1_hi = [j09 n09 j10 n10 .. j16 n16  j25 n25 j26 n26 .. j32 n32]
26732       __m256i step1_p0_lo = _mm256_unpacklo_epi8(major_p0, minor_p0);
26733       __m256i step1_p0_hi = _mm256_unpackhi_epi8(major_p0, minor_p0);
26734       __m256i step1_m1_lo = _mm256_unpacklo_epi8(major_m1, minor_m1);
26735       __m256i step1_m1_hi = _mm256_unpackhi_epi8(major_m1, minor_m1);
26736       __m256i step1_p1_lo = _mm256_unpacklo_epi8(major_p1, minor_p1);
26737       __m256i step1_p1_hi = _mm256_unpackhi_epi8(major_p1, minor_p1);
26738 
26739       // Multiply-add to get u16x16 vectors.
26740       //
26741       // step2_p0_lo = [9*j00+3*n00 9*j01+3*n01 .. 9*j23+3*n23]
26742       // step2_p0_hi = [9*j08+3*n08 9*j09+3*n09 .. 9*j31+3*n31]
26743       // step2_m1_lo = [3*jm1+1*nm1 3*j00+1*n00 .. 3*j22+1*n22]
26744       // step2_m1_hi = [3*j07+1*n07 3*j08+1*n08 .. 3*j30+1*n30]
26745       // step2_p1_lo = [3*j01+1*n01 3*j02+1*n02 .. 3*j24+1*n24]
26746       // step2_p1_hi = [3*j09+1*n09 3*j10+1*n10 .. 3*j32+1*n32]
26747       const __m256i k0309 = _mm256_set1_epi16(0x0309);
26748       const __m256i k0103 = _mm256_set1_epi16(0x0103);
26749       __m256i step2_p0_lo = _mm256_maddubs_epi16(step1_p0_lo, k0309);
26750       __m256i step2_p0_hi = _mm256_maddubs_epi16(step1_p0_hi, k0309);
26751       __m256i step2_m1_lo = _mm256_maddubs_epi16(step1_m1_lo, k0103);
26752       __m256i step2_m1_hi = _mm256_maddubs_epi16(step1_m1_hi, k0103);
26753       __m256i step2_p1_lo = _mm256_maddubs_epi16(step1_p1_lo, k0103);
26754       __m256i step2_p1_hi = _mm256_maddubs_epi16(step1_p1_hi, k0103);
26755 
26756       // Compute the weighted sums of (p0, m1) and (p0, p1). For example:
26757       //
26758       // step3_m1_lo[00] = ((9*j00) + (3*n00) + (3*jm1) + (1*nm1)) as u16
26759       // step3_p1_hi[15] = ((9*j31) + (3*n31) + (3*j32) + (1*n32)) as u16
26760       __m256i step3_m1_lo = _mm256_add_epi16(step2_p0_lo, step2_m1_lo);
26761       __m256i step3_m1_hi = _mm256_add_epi16(step2_p0_hi, step2_m1_hi);
26762       __m256i step3_p1_lo = _mm256_add_epi16(step2_p0_lo, step2_p1_lo);
26763       __m256i step3_p1_hi = _mm256_add_epi16(step2_p0_hi, step2_p1_hi);
26764 
26765       // Bias by 8 (on the left) or 7 (on the right) and then divide by 16
26766       // (which is 9+3+3+1) to get a weighted average. On the left (m1), shift
26767       // the u16 right value by 4. On the right (p1), shift right by 4 and then
26768       // shift left by 8 so that, when still in the u16x16 little-endian
26769       // interpretation, we have:
26770       //  - m1_element =  (etcetera + 8) >> 4
26771       //  - p1_element = ((etcetera + 7) >> 4) << 8
26772       //
26773       // step4_m1_lo = [0x00?? 0x00?? ... 0x00?? 0x00??]
26774       // step4_p1_lo = [0x??00 0x??00 ... 0x??00 0x??00]
26775       // step4_m1_hi = [0x00?? 0x00?? ... 0x00?? 0x00??]
26776       // step4_p1_hi = [0x??00 0x??00 ... 0x??00 0x??00]
26777       __m256i step4_m1_lo = _mm256_srli_epi16(
26778           _mm256_add_epi16(step3_m1_lo, _mm256_set1_epi16(8)), 4);
26779       __m256i step4_p1_lo = _mm256_slli_epi16(
26780           _mm256_srli_epi16(_mm256_add_epi16(step3_p1_lo, _mm256_set1_epi16(7)),
26781                             4),
26782           8);
26783       __m256i step4_m1_hi = _mm256_srli_epi16(
26784           _mm256_add_epi16(step3_m1_hi, _mm256_set1_epi16(8)), 4);
26785       __m256i step4_p1_hi = _mm256_slli_epi16(
26786           _mm256_srli_epi16(_mm256_add_epi16(step3_p1_hi, _mm256_set1_epi16(7)),
26787                             4),
26788           8);
26789 
26790       // Bitwise-or two "0x00"-rich u16x16 vectors to get a u8x32 vector. Do
26791       // that twice. Once for the low columns and once for the high columns.
26792       //
26793       // In terms of jxx (major row) or nxx (minor row) source samples:
26794       //  - low  columns means ( 0 ..  8; 16 .. 24).
26795       //  - high columns means ( 8 .. 16; 24 .. 32).
26796       //
26797       // In terms of dxx destination samples (there are twice as many):
26798       //  - low  columns means ( 0 .. 16; 32 .. 48).
26799       //  - high columns means (16 .. 32; 48 .. 64).
26800       //
26801       // step5_lo = [d00 d01 .. d14 d15  d32 d33 .. d46 d47]
26802       // step5_hi = [d16 d17 .. d30 d31  d48 d49 .. d62 d63]
26803       //
26804       // The d00, d02 ... d62 even elements come from (p0, m1) weighted sums.
26805       // The d01, d03 ... d63 odd  elements come from (p0, p1) weighted sums.
26806       __m256i step5_lo = _mm256_or_si256(step4_m1_lo, step4_p1_lo);
26807       __m256i step5_hi = _mm256_or_si256(step4_m1_hi, step4_p1_hi);
26808 
26809       // Permute and store.
26810       //
26811       // step6_00_31 = [d00 d01 .. d14 d15  d16 d17 .. d30 d31]
26812       // step6_32_63 = [d32 d33 .. d46 d47  d48 d49 .. d62 d63]
26813       __m256i step6_00_31 = _mm256_permute2x128_si256(step5_lo, step5_hi, 0x20);
26814       __m256i step6_32_63 = _mm256_permute2x128_si256(step5_lo, step5_hi, 0x31);
26815       _mm256_storeu_si256((__m256i*)(void*)(dp + 0x00), step6_00_31);
26816       _mm256_storeu_si256((__m256i*)(void*)(dp + 0x20), step6_32_63);
26817 
26818       // Advance by up to 32 source samples (64 destination samples). The first
26819       // iteration might be smaller than 32 so that all of the remaining steps
26820       // are exactly 32.
26821       size_t n = 32u - (31u & (0u - src_len));
26822       dp += 2u * n;
26823       sp_major += n;
26824       sp_minor += n;
26825       src_len -= n;
26826     }
26827   }
26828 
26829   if (last_column) {
26830     uint32_t sv_major_m1 = sp_major[-1];
26831     uint32_t sv_minor_m1 = sp_minor[-1];
26832     uint32_t sv_major_p1 = sp_major[+0];  // Clamp offset to zero.
26833     uint32_t sv_minor_p1 = sp_minor[+0];  // Clamp offset to zero.
26834 
26835     uint32_t sv = (9u * ((uint32_t)(*sp_major++))) +  //
26836                   (3u * ((uint32_t)(*sp_minor++)));
26837     *dp++ = (uint8_t)((sv + (3u * sv_major_m1) + (sv_minor_m1) + 8u) >> 4u);
26838     *dp++ = (uint8_t)((sv + (3u * sv_major_p1) + (sv_minor_p1) + 7u) >> 4u);
26839   }
26840 
26841   return dst_ptr;
26842 }
26843 #endif
26844 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_64)
26845 // ‼ WUFFS MULTI-FILE SECTION -x86_avx2
26846 
26847 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
26848         // defined(WUFFS_CONFIG__MODULE__BASE) ||
26849         // defined(WUFFS_CONFIG__MODULE__BASE__PIXCONV)
26850 
26851 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
26852     defined(WUFFS_CONFIG__MODULE__BASE__UTF8)
26853 
26854 // ---------------- Unicode and UTF-8
26855 
26856 WUFFS_BASE__MAYBE_STATIC size_t  //
wuffs_base__utf_8__encode(wuffs_base__slice_u8 dst,uint32_t code_point)26857 wuffs_base__utf_8__encode(wuffs_base__slice_u8 dst, uint32_t code_point) {
26858   if (code_point <= 0x7F) {
26859     if (dst.len >= 1) {
26860       dst.ptr[0] = (uint8_t)(code_point);
26861       return 1;
26862     }
26863 
26864   } else if (code_point <= 0x07FF) {
26865     if (dst.len >= 2) {
26866       dst.ptr[0] = (uint8_t)(0xC0 | ((code_point >> 6)));
26867       dst.ptr[1] = (uint8_t)(0x80 | ((code_point >> 0) & 0x3F));
26868       return 2;
26869     }
26870 
26871   } else if (code_point <= 0xFFFF) {
26872     if ((dst.len >= 3) && ((code_point < 0xD800) || (0xDFFF < code_point))) {
26873       dst.ptr[0] = (uint8_t)(0xE0 | ((code_point >> 12)));
26874       dst.ptr[1] = (uint8_t)(0x80 | ((code_point >> 6) & 0x3F));
26875       dst.ptr[2] = (uint8_t)(0x80 | ((code_point >> 0) & 0x3F));
26876       return 3;
26877     }
26878 
26879   } else if (code_point <= 0x10FFFF) {
26880     if (dst.len >= 4) {
26881       dst.ptr[0] = (uint8_t)(0xF0 | ((code_point >> 18)));
26882       dst.ptr[1] = (uint8_t)(0x80 | ((code_point >> 12) & 0x3F));
26883       dst.ptr[2] = (uint8_t)(0x80 | ((code_point >> 6) & 0x3F));
26884       dst.ptr[3] = (uint8_t)(0x80 | ((code_point >> 0) & 0x3F));
26885       return 4;
26886     }
26887   }
26888 
26889   return 0;
26890 }
26891 
26892 // wuffs_base__utf_8__byte_length_minus_1 is the byte length (minus 1) of a
26893 // UTF-8 encoded code point, based on the encoding's initial byte.
26894 //  - 0x00 is 1-byte UTF-8 (ASCII).
26895 //  - 0x01 is the start of 2-byte UTF-8.
26896 //  - 0x02 is the start of 3-byte UTF-8.
26897 //  - 0x03 is the start of 4-byte UTF-8.
26898 //  - 0x40 is a UTF-8 tail byte.
26899 //  - 0x80 is invalid UTF-8.
26900 //
26901 // RFC 3629 (UTF-8) gives this grammar for valid UTF-8:
26902 //    UTF8-1      = %x00-7F
26903 //    UTF8-2      = %xC2-DF UTF8-tail
26904 //    UTF8-3      = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) /
26905 //                  %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )
26906 //    UTF8-4      = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) /
26907 //                  %xF4 %x80-8F 2( UTF8-tail )
26908 //    UTF8-tail   = %x80-BF
26909 static const uint8_t wuffs_base__utf_8__byte_length_minus_1[256] = {
26910     // 0     1     2     3     4     5     6     7
26911     // 8     9     A     B     C     D     E     F
26912     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x00 ..= 0x07.
26913     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x08 ..= 0x0F.
26914     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x10 ..= 0x17.
26915     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x18 ..= 0x1F.
26916     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x20 ..= 0x27.
26917     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x28 ..= 0x2F.
26918     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x30 ..= 0x37.
26919     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x38 ..= 0x3F.
26920 
26921     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x40 ..= 0x47.
26922     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x48 ..= 0x4F.
26923     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x50 ..= 0x57.
26924     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x58 ..= 0x5F.
26925     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x60 ..= 0x67.
26926     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x68 ..= 0x6F.
26927     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x70 ..= 0x77.
26928     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x78 ..= 0x7F.
26929 
26930     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  // 0x80 ..= 0x87.
26931     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  // 0x88 ..= 0x8F.
26932     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  // 0x90 ..= 0x97.
26933     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  // 0x98 ..= 0x9F.
26934     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  // 0xA0 ..= 0xA7.
26935     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  // 0xA8 ..= 0xAF.
26936     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  // 0xB0 ..= 0xB7.
26937     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  // 0xB8 ..= 0xBF.
26938 
26939     0x80, 0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  // 0xC0 ..= 0xC7.
26940     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  // 0xC8 ..= 0xCF.
26941     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  // 0xD0 ..= 0xD7.
26942     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  // 0xD8 ..= 0xDF.
26943     0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,  // 0xE0 ..= 0xE7.
26944     0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,  // 0xE8 ..= 0xEF.
26945     0x03, 0x03, 0x03, 0x03, 0x03, 0x80, 0x80, 0x80,  // 0xF0 ..= 0xF7.
26946     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xF8 ..= 0xFF.
26947     // 0     1     2     3     4     5     6     7
26948     // 8     9     A     B     C     D     E     F
26949 };
26950 
26951 WUFFS_BASE__MAYBE_STATIC wuffs_base__utf_8__next__output  //
wuffs_base__utf_8__next(const uint8_t * s_ptr,size_t s_len)26952 wuffs_base__utf_8__next(const uint8_t* s_ptr, size_t s_len) {
26953   if (s_len == 0) {
26954     return wuffs_base__make_utf_8__next__output(0, 0);
26955   }
26956   uint32_t c = s_ptr[0];
26957   switch (wuffs_base__utf_8__byte_length_minus_1[c & 0xFF]) {
26958     case 0:
26959       return wuffs_base__make_utf_8__next__output(c, 1);
26960 
26961     case 1:
26962       if (s_len < 2) {
26963         break;
26964       }
26965       c = wuffs_base__peek_u16le__no_bounds_check(s_ptr);
26966       if ((c & 0xC000) != 0x8000) {
26967         break;
26968       }
26969       c = (0x0007C0 & (c << 6)) | (0x00003F & (c >> 8));
26970       return wuffs_base__make_utf_8__next__output(c, 2);
26971 
26972     case 2:
26973       if (s_len < 3) {
26974         break;
26975       }
26976       c = wuffs_base__peek_u24le__no_bounds_check(s_ptr);
26977       if ((c & 0xC0C000) != 0x808000) {
26978         break;
26979       }
26980       c = (0x00F000 & (c << 12)) | (0x000FC0 & (c >> 2)) |
26981           (0x00003F & (c >> 16));
26982       if ((c <= 0x07FF) || ((0xD800 <= c) && (c <= 0xDFFF))) {
26983         break;
26984       }
26985       return wuffs_base__make_utf_8__next__output(c, 3);
26986 
26987     case 3:
26988       if (s_len < 4) {
26989         break;
26990       }
26991       c = wuffs_base__peek_u32le__no_bounds_check(s_ptr);
26992       if ((c & 0xC0C0C000) != 0x80808000) {
26993         break;
26994       }
26995       c = (0x1C0000 & (c << 18)) | (0x03F000 & (c << 4)) |
26996           (0x000FC0 & (c >> 10)) | (0x00003F & (c >> 24));
26997       if ((c <= 0xFFFF) || (0x110000 <= c)) {
26998         break;
26999       }
27000       return wuffs_base__make_utf_8__next__output(c, 4);
27001   }
27002 
27003   return wuffs_base__make_utf_8__next__output(
27004       WUFFS_BASE__UNICODE_REPLACEMENT_CHARACTER, 1);
27005 }
27006 
27007 WUFFS_BASE__MAYBE_STATIC wuffs_base__utf_8__next__output  //
wuffs_base__utf_8__next_from_end(const uint8_t * s_ptr,size_t s_len)27008 wuffs_base__utf_8__next_from_end(const uint8_t* s_ptr, size_t s_len) {
27009   if (s_len == 0) {
27010     return wuffs_base__make_utf_8__next__output(0, 0);
27011   }
27012   const uint8_t* ptr = &s_ptr[s_len - 1];
27013   if (*ptr < 0x80) {
27014     return wuffs_base__make_utf_8__next__output(*ptr, 1);
27015 
27016   } else if (*ptr < 0xC0) {
27017     const uint8_t* too_far = &s_ptr[(s_len > 4) ? (s_len - 4) : 0];
27018     uint32_t n = 1;
27019     while (ptr != too_far) {
27020       ptr--;
27021       n++;
27022       if (*ptr < 0x80) {
27023         break;
27024       } else if (*ptr < 0xC0) {
27025         continue;
27026       }
27027       wuffs_base__utf_8__next__output o = wuffs_base__utf_8__next(ptr, n);
27028       if (o.byte_length != n) {
27029         break;
27030       }
27031       return o;
27032     }
27033   }
27034 
27035   return wuffs_base__make_utf_8__next__output(
27036       WUFFS_BASE__UNICODE_REPLACEMENT_CHARACTER, 1);
27037 }
27038 
27039 WUFFS_BASE__MAYBE_STATIC size_t  //
wuffs_base__utf_8__longest_valid_prefix(const uint8_t * s_ptr,size_t s_len)27040 wuffs_base__utf_8__longest_valid_prefix(const uint8_t* s_ptr, size_t s_len) {
27041   // TODO: possibly optimize the all-ASCII case (4 or 8 bytes at a time).
27042   //
27043   // TODO: possibly optimize this by manually inlining the
27044   // wuffs_base__utf_8__next calls.
27045   size_t original_len = s_len;
27046   while (s_len > 0) {
27047     wuffs_base__utf_8__next__output o = wuffs_base__utf_8__next(s_ptr, s_len);
27048     if ((o.code_point > 0x7F) && (o.byte_length == 1)) {
27049       break;
27050     }
27051     s_ptr += o.byte_length;
27052     s_len -= o.byte_length;
27053   }
27054   return original_len - s_len;
27055 }
27056 
27057 WUFFS_BASE__MAYBE_STATIC size_t  //
wuffs_base__ascii__longest_valid_prefix(const uint8_t * s_ptr,size_t s_len)27058 wuffs_base__ascii__longest_valid_prefix(const uint8_t* s_ptr, size_t s_len) {
27059   // TODO: possibly optimize this by checking 4 or 8 bytes at a time.
27060   const uint8_t* original_ptr = s_ptr;
27061   const uint8_t* p = s_ptr;
27062   const uint8_t* q = s_ptr + s_len;
27063   for (; (p != q) && ((*p & 0x80) == 0); p++) {
27064   }
27065   return (size_t)(p - original_ptr);
27066 }
27067 
27068 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
27069         // defined(WUFFS_CONFIG__MODULE__BASE) ||
27070         // defined(WUFFS_CONFIG__MODULE__BASE__UTF8)
27071 
27072 #ifdef __cplusplus
27073 }  // extern "C"
27074 #endif
27075 
27076 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ADLER32)
27077 
27078 // ---------------- Status Codes Implementations
27079 
27080 // ---------------- Private Consts
27081 
27082 // ---------------- Private Initializer Prototypes
27083 
27084 // ---------------- Private Function Prototypes
27085 
27086 WUFFS_BASE__GENERATED_C_CODE
27087 static wuffs_base__empty_struct
27088 wuffs_adler32__hasher__up(
27089     wuffs_adler32__hasher* self,
27090     wuffs_base__slice_u8 a_x);
27091 
27092 WUFFS_BASE__GENERATED_C_CODE
27093 static wuffs_base__empty_struct
27094 wuffs_adler32__hasher__up__choosy_default(
27095     wuffs_adler32__hasher* self,
27096     wuffs_base__slice_u8 a_x);
27097 
27098 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
27099 WUFFS_BASE__GENERATED_C_CODE
27100 static wuffs_base__empty_struct
27101 wuffs_adler32__hasher__up_arm_neon(
27102     wuffs_adler32__hasher* self,
27103     wuffs_base__slice_u8 a_x);
27104 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
27105 
27106 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
27107 WUFFS_BASE__GENERATED_C_CODE
27108 static wuffs_base__empty_struct
27109 wuffs_adler32__hasher__up_x86_sse42(
27110     wuffs_adler32__hasher* self,
27111     wuffs_base__slice_u8 a_x);
27112 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
27113 
27114 // ---------------- VTables
27115 
27116 const wuffs_base__hasher_u32__func_ptrs
27117 wuffs_adler32__hasher__func_ptrs_for__wuffs_base__hasher_u32 = {
27118   (uint32_t(*)(const void*))(&wuffs_adler32__hasher__checksum_u32),
27119   (uint64_t(*)(const void*,
27120       uint32_t))(&wuffs_adler32__hasher__get_quirk),
27121   (wuffs_base__status(*)(void*,
27122       uint32_t,
27123       uint64_t))(&wuffs_adler32__hasher__set_quirk),
27124   (wuffs_base__empty_struct(*)(void*,
27125       wuffs_base__slice_u8))(&wuffs_adler32__hasher__update),
27126   (uint32_t(*)(void*,
27127       wuffs_base__slice_u8))(&wuffs_adler32__hasher__update_u32),
27128 };
27129 
27130 // ---------------- Initializer Implementations
27131 
27132 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
wuffs_adler32__hasher__initialize(wuffs_adler32__hasher * self,size_t sizeof_star_self,uint64_t wuffs_version,uint32_t options)27133 wuffs_adler32__hasher__initialize(
27134     wuffs_adler32__hasher* self,
27135     size_t sizeof_star_self,
27136     uint64_t wuffs_version,
27137     uint32_t options){
27138   if (!self) {
27139     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
27140   }
27141   if (sizeof(*self) != sizeof_star_self) {
27142     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
27143   }
27144   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
27145       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
27146     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
27147   }
27148 
27149   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
27150     // The whole point of this if-check is to detect an uninitialized *self.
27151     // We disable the warning on GCC. Clang-5.0 does not have this warning.
27152 #if !defined(__clang__) && defined(__GNUC__)
27153 #pragma GCC diagnostic push
27154 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
27155 #endif
27156     if (self->private_impl.magic != 0) {
27157       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
27158     }
27159 #if !defined(__clang__) && defined(__GNUC__)
27160 #pragma GCC diagnostic pop
27161 #endif
27162   } else {
27163     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
27164       memset(self, 0, sizeof(*self));
27165       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
27166     } else {
27167       memset(&(self->private_impl), 0, sizeof(self->private_impl));
27168     }
27169   }
27170 
27171   self->private_impl.choosy_up = &wuffs_adler32__hasher__up__choosy_default;
27172 
27173   self->private_impl.magic = WUFFS_BASE__MAGIC;
27174   self->private_impl.vtable_for__wuffs_base__hasher_u32.vtable_name =
27175       wuffs_base__hasher_u32__vtable_name;
27176   self->private_impl.vtable_for__wuffs_base__hasher_u32.function_pointers =
27177       (const void*)(&wuffs_adler32__hasher__func_ptrs_for__wuffs_base__hasher_u32);
27178   return wuffs_base__make_status(NULL);
27179 }
27180 
27181 wuffs_adler32__hasher*
wuffs_adler32__hasher__alloc(void)27182 wuffs_adler32__hasher__alloc(void) {
27183   wuffs_adler32__hasher* x =
27184       (wuffs_adler32__hasher*)(calloc(sizeof(wuffs_adler32__hasher), 1));
27185   if (!x) {
27186     return NULL;
27187   }
27188   if (wuffs_adler32__hasher__initialize(
27189       x, sizeof(wuffs_adler32__hasher), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
27190     free(x);
27191     return NULL;
27192   }
27193   return x;
27194 }
27195 
27196 size_t
sizeof__wuffs_adler32__hasher(void)27197 sizeof__wuffs_adler32__hasher(void) {
27198   return sizeof(wuffs_adler32__hasher);
27199 }
27200 
27201 // ---------------- Function Implementations
27202 
27203 // -------- func adler32.hasher.get_quirk
27204 
27205 WUFFS_BASE__GENERATED_C_CODE
27206 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_adler32__hasher__get_quirk(const wuffs_adler32__hasher * self,uint32_t a_key)27207 wuffs_adler32__hasher__get_quirk(
27208     const wuffs_adler32__hasher* self,
27209     uint32_t a_key) {
27210   if (!self) {
27211     return 0;
27212   }
27213   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
27214       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
27215     return 0;
27216   }
27217 
27218   return 0u;
27219 }
27220 
27221 // -------- func adler32.hasher.set_quirk
27222 
27223 WUFFS_BASE__GENERATED_C_CODE
27224 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_adler32__hasher__set_quirk(wuffs_adler32__hasher * self,uint32_t a_key,uint64_t a_value)27225 wuffs_adler32__hasher__set_quirk(
27226     wuffs_adler32__hasher* self,
27227     uint32_t a_key,
27228     uint64_t a_value) {
27229   if (!self) {
27230     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
27231   }
27232   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
27233     return wuffs_base__make_status(
27234         (self->private_impl.magic == WUFFS_BASE__DISABLED)
27235         ? wuffs_base__error__disabled_by_previous_error
27236         : wuffs_base__error__initialize_not_called);
27237   }
27238 
27239   return wuffs_base__make_status(wuffs_base__error__unsupported_option);
27240 }
27241 
27242 // -------- func adler32.hasher.update
27243 
27244 WUFFS_BASE__GENERATED_C_CODE
27245 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_adler32__hasher__update(wuffs_adler32__hasher * self,wuffs_base__slice_u8 a_x)27246 wuffs_adler32__hasher__update(
27247     wuffs_adler32__hasher* self,
27248     wuffs_base__slice_u8 a_x) {
27249   if (!self) {
27250     return wuffs_base__make_empty_struct();
27251   }
27252   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
27253     return wuffs_base__make_empty_struct();
27254   }
27255 
27256   if ( ! self->private_impl.f_started) {
27257     self->private_impl.f_started = true;
27258     self->private_impl.f_state = 1u;
27259     self->private_impl.choosy_up = (
27260 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
27261         wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_adler32__hasher__up_arm_neon :
27262 #endif
27263 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
27264         wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_adler32__hasher__up_x86_sse42 :
27265 #endif
27266         self->private_impl.choosy_up);
27267   }
27268   wuffs_adler32__hasher__up(self, a_x);
27269   return wuffs_base__make_empty_struct();
27270 }
27271 
27272 // -------- func adler32.hasher.update_u32
27273 
27274 WUFFS_BASE__GENERATED_C_CODE
27275 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_adler32__hasher__update_u32(wuffs_adler32__hasher * self,wuffs_base__slice_u8 a_x)27276 wuffs_adler32__hasher__update_u32(
27277     wuffs_adler32__hasher* self,
27278     wuffs_base__slice_u8 a_x) {
27279   if (!self) {
27280     return 0;
27281   }
27282   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
27283     return 0;
27284   }
27285 
27286   wuffs_adler32__hasher__update(self, a_x);
27287   return self->private_impl.f_state;
27288 }
27289 
27290 // -------- func adler32.hasher.up
27291 
27292 WUFFS_BASE__GENERATED_C_CODE
27293 static wuffs_base__empty_struct
wuffs_adler32__hasher__up(wuffs_adler32__hasher * self,wuffs_base__slice_u8 a_x)27294 wuffs_adler32__hasher__up(
27295     wuffs_adler32__hasher* self,
27296     wuffs_base__slice_u8 a_x) {
27297   return (*self->private_impl.choosy_up)(self, a_x);
27298 }
27299 
27300 WUFFS_BASE__GENERATED_C_CODE
27301 static wuffs_base__empty_struct
wuffs_adler32__hasher__up__choosy_default(wuffs_adler32__hasher * self,wuffs_base__slice_u8 a_x)27302 wuffs_adler32__hasher__up__choosy_default(
27303     wuffs_adler32__hasher* self,
27304     wuffs_base__slice_u8 a_x) {
27305   uint32_t v_s1 = 0;
27306   uint32_t v_s2 = 0;
27307   wuffs_base__slice_u8 v_remaining = {0};
27308   wuffs_base__slice_u8 v_p = {0};
27309 
27310   v_s1 = ((self->private_impl.f_state) & 0xFFFFu);
27311   v_s2 = ((self->private_impl.f_state) >> (32u - 16u));
27312   while (((uint64_t)(a_x.len)) > 0u) {
27313     v_remaining = wuffs_base__slice_u8__subslice_j(a_x, 0u);
27314     if (((uint64_t)(a_x.len)) > 5552u) {
27315       v_remaining = wuffs_base__slice_u8__subslice_i(a_x, 5552u);
27316       a_x = wuffs_base__slice_u8__subslice_j(a_x, 5552u);
27317     }
27318     {
27319       wuffs_base__slice_u8 i_slice_p = a_x;
27320       v_p.ptr = i_slice_p.ptr;
27321       v_p.len = 1;
27322       uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 8) * 8);
27323       while (v_p.ptr < i_end0_p) {
27324         v_s1 += ((uint32_t)(v_p.ptr[0u]));
27325         v_s2 += v_s1;
27326         v_p.ptr += 1;
27327         v_s1 += ((uint32_t)(v_p.ptr[0u]));
27328         v_s2 += v_s1;
27329         v_p.ptr += 1;
27330         v_s1 += ((uint32_t)(v_p.ptr[0u]));
27331         v_s2 += v_s1;
27332         v_p.ptr += 1;
27333         v_s1 += ((uint32_t)(v_p.ptr[0u]));
27334         v_s2 += v_s1;
27335         v_p.ptr += 1;
27336         v_s1 += ((uint32_t)(v_p.ptr[0u]));
27337         v_s2 += v_s1;
27338         v_p.ptr += 1;
27339         v_s1 += ((uint32_t)(v_p.ptr[0u]));
27340         v_s2 += v_s1;
27341         v_p.ptr += 1;
27342         v_s1 += ((uint32_t)(v_p.ptr[0u]));
27343         v_s2 += v_s1;
27344         v_p.ptr += 1;
27345         v_s1 += ((uint32_t)(v_p.ptr[0u]));
27346         v_s2 += v_s1;
27347         v_p.ptr += 1;
27348       }
27349       v_p.len = 1;
27350       uint8_t* i_end1_p = i_slice_p.ptr + i_slice_p.len;
27351       while (v_p.ptr < i_end1_p) {
27352         v_s1 += ((uint32_t)(v_p.ptr[0u]));
27353         v_s2 += v_s1;
27354         v_p.ptr += 1;
27355       }
27356       v_p.len = 0;
27357     }
27358     v_s1 %= 65521u;
27359     v_s2 %= 65521u;
27360     a_x = v_remaining;
27361   }
27362   self->private_impl.f_state = (((v_s2 & 65535u) << 16u) | (v_s1 & 65535u));
27363   return wuffs_base__make_empty_struct();
27364 }
27365 
27366 // -------- func adler32.hasher.checksum_u32
27367 
27368 WUFFS_BASE__GENERATED_C_CODE
27369 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_adler32__hasher__checksum_u32(const wuffs_adler32__hasher * self)27370 wuffs_adler32__hasher__checksum_u32(
27371     const wuffs_adler32__hasher* self) {
27372   if (!self) {
27373     return 0;
27374   }
27375   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
27376       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
27377     return 0;
27378   }
27379 
27380   return self->private_impl.f_state;
27381 }
27382 
27383 // ‼ WUFFS MULTI-FILE SECTION +arm_neon
27384 // -------- func adler32.hasher.up_arm_neon
27385 
27386 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
27387 WUFFS_BASE__GENERATED_C_CODE
27388 static wuffs_base__empty_struct
wuffs_adler32__hasher__up_arm_neon(wuffs_adler32__hasher * self,wuffs_base__slice_u8 a_x)27389 wuffs_adler32__hasher__up_arm_neon(
27390     wuffs_adler32__hasher* self,
27391     wuffs_base__slice_u8 a_x) {
27392   uint32_t v_s1 = 0;
27393   uint32_t v_s2 = 0;
27394   wuffs_base__slice_u8 v_remaining = {0};
27395   wuffs_base__slice_u8 v_p = {0};
27396   uint8x16_t v_p__left = {0};
27397   uint8x16_t v_p_right = {0};
27398   uint32x4_t v_v1 = {0};
27399   uint32x4_t v_v2 = {0};
27400   uint16x8_t v_col0 = {0};
27401   uint16x8_t v_col1 = {0};
27402   uint16x8_t v_col2 = {0};
27403   uint16x8_t v_col3 = {0};
27404   uint32x2_t v_sum1 = {0};
27405   uint32x2_t v_sum2 = {0};
27406   uint32x2_t v_sum12 = {0};
27407   uint32_t v_num_iterate_bytes = 0;
27408   uint64_t v_tail_index = 0;
27409 
27410   v_s1 = ((self->private_impl.f_state) & 0xFFFFu);
27411   v_s2 = ((self->private_impl.f_state) >> (32u - 16u));
27412   while ((((uint64_t)(a_x.len)) > 0u) && ((15u & ((uint32_t)(0xFFFu & (uintptr_t)(a_x.ptr)))) != 0u)) {
27413     v_s1 += ((uint32_t)(a_x.ptr[0u]));
27414     v_s2 += v_s1;
27415     a_x = wuffs_base__slice_u8__subslice_i(a_x, 1u);
27416   }
27417   v_s1 %= 65521u;
27418   v_s2 %= 65521u;
27419   while (((uint64_t)(a_x.len)) > 0u) {
27420     v_remaining = wuffs_base__slice_u8__subslice_j(a_x, 0u);
27421     if (((uint64_t)(a_x.len)) > 5536u) {
27422       v_remaining = wuffs_base__slice_u8__subslice_i(a_x, 5536u);
27423       a_x = wuffs_base__slice_u8__subslice_j(a_x, 5536u);
27424     }
27425     v_num_iterate_bytes = ((uint32_t)((((uint64_t)(a_x.len)) & 4294967264u)));
27426     v_s2 += ((uint32_t)(v_s1 * v_num_iterate_bytes));
27427     v_v1 = vdupq_n_u32(0u);
27428     v_v2 = vdupq_n_u32(0u);
27429     v_col0 = vdupq_n_u16(0u);
27430     v_col1 = vdupq_n_u16(0u);
27431     v_col2 = vdupq_n_u16(0u);
27432     v_col3 = vdupq_n_u16(0u);
27433     {
27434       wuffs_base__slice_u8 i_slice_p = a_x;
27435       v_p.ptr = i_slice_p.ptr;
27436       v_p.len = 32;
27437       uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 32) * 32);
27438       while (v_p.ptr < i_end0_p) {
27439         v_p__left = vld1q_u8(v_p.ptr);
27440         v_p_right = vld1q_u8(v_p.ptr + 16u);
27441         v_v2 = vaddq_u32(v_v2, v_v1);
27442         v_v1 = vpadalq_u16(v_v1, vpadalq_u8(vpaddlq_u8(v_p__left), v_p_right));
27443         v_col0 = vaddw_u8(v_col0, vget_low_u8(v_p__left));
27444         v_col1 = vaddw_u8(v_col1, vget_high_u8(v_p__left));
27445         v_col2 = vaddw_u8(v_col2, vget_low_u8(v_p_right));
27446         v_col3 = vaddw_u8(v_col3, vget_high_u8(v_p_right));
27447         v_p.ptr += 32;
27448       }
27449       v_p.len = 0;
27450     }
27451     v_v2 = vshlq_n_u32(v_v2, 5u);
27452     v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col0), ((uint16x4_t){32u, 31u, 30u, 29u}));
27453     v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col0), ((uint16x4_t){28u, 27u, 26u, 25u}));
27454     v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col1), ((uint16x4_t){24u, 23u, 22u, 21u}));
27455     v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col1), ((uint16x4_t){20u, 19u, 18u, 17u}));
27456     v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col2), ((uint16x4_t){16u, 15u, 14u, 13u}));
27457     v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col2), ((uint16x4_t){12u, 11u, 10u, 9u}));
27458     v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col3), ((uint16x4_t){8u, 7u, 6u, 5u}));
27459     v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col3), ((uint16x4_t){4u, 3u, 2u, 1u}));
27460     v_sum1 = vpadd_u32(vget_low_u32(v_v1), vget_high_u32(v_v1));
27461     v_sum2 = vpadd_u32(vget_low_u32(v_v2), vget_high_u32(v_v2));
27462     v_sum12 = vpadd_u32(v_sum1, v_sum2);
27463     v_s1 += vget_lane_u32(v_sum12, 0u);
27464     v_s2 += vget_lane_u32(v_sum12, 1u);
27465     v_tail_index = (((uint64_t)(a_x.len)) & 18446744073709551584u);
27466     if (v_tail_index < ((uint64_t)(a_x.len))) {
27467       {
27468         wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, v_tail_index);
27469         v_p.ptr = i_slice_p.ptr;
27470         v_p.len = 1;
27471         uint8_t* i_end0_p = i_slice_p.ptr + i_slice_p.len;
27472         while (v_p.ptr < i_end0_p) {
27473           v_s1 += ((uint32_t)(v_p.ptr[0u]));
27474           v_s2 += v_s1;
27475           v_p.ptr += 1;
27476         }
27477         v_p.len = 0;
27478       }
27479     }
27480     v_s1 %= 65521u;
27481     v_s2 %= 65521u;
27482     a_x = v_remaining;
27483   }
27484   self->private_impl.f_state = (((v_s2 & 65535u) << 16u) | (v_s1 & 65535u));
27485   return wuffs_base__make_empty_struct();
27486 }
27487 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
27488 // ‼ WUFFS MULTI-FILE SECTION -arm_neon
27489 
27490 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
27491 // -------- func adler32.hasher.up_x86_sse42
27492 
27493 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
27494 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
27495 WUFFS_BASE__GENERATED_C_CODE
27496 static wuffs_base__empty_struct
wuffs_adler32__hasher__up_x86_sse42(wuffs_adler32__hasher * self,wuffs_base__slice_u8 a_x)27497 wuffs_adler32__hasher__up_x86_sse42(
27498     wuffs_adler32__hasher* self,
27499     wuffs_base__slice_u8 a_x) {
27500   uint32_t v_s1 = 0;
27501   uint32_t v_s2 = 0;
27502   wuffs_base__slice_u8 v_remaining = {0};
27503   wuffs_base__slice_u8 v_p = {0};
27504   __m128i v_zeroes = {0};
27505   __m128i v_ones = {0};
27506   __m128i v_weights__left = {0};
27507   __m128i v_weights_right = {0};
27508   __m128i v_q__left = {0};
27509   __m128i v_q_right = {0};
27510   __m128i v_v1 = {0};
27511   __m128i v_v2 = {0};
27512   __m128i v_v2j = {0};
27513   __m128i v_v2k = {0};
27514   uint32_t v_num_iterate_bytes = 0;
27515   uint64_t v_tail_index = 0;
27516 
27517   v_zeroes = _mm_set1_epi16((int16_t)(0u));
27518   v_ones = _mm_set1_epi16((int16_t)(1u));
27519   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));
27520   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));
27521   v_s1 = ((self->private_impl.f_state) & 0xFFFFu);
27522   v_s2 = ((self->private_impl.f_state) >> (32u - 16u));
27523   while (((uint64_t)(a_x.len)) > 0u) {
27524     v_remaining = wuffs_base__slice_u8__subslice_j(a_x, 0u);
27525     if (((uint64_t)(a_x.len)) > 5536u) {
27526       v_remaining = wuffs_base__slice_u8__subslice_i(a_x, 5536u);
27527       a_x = wuffs_base__slice_u8__subslice_j(a_x, 5536u);
27528     }
27529     v_num_iterate_bytes = ((uint32_t)((((uint64_t)(a_x.len)) & 4294967264u)));
27530     v_s2 += ((uint32_t)(v_s1 * v_num_iterate_bytes));
27531     v_v1 = _mm_setzero_si128();
27532     v_v2j = _mm_setzero_si128();
27533     v_v2k = _mm_setzero_si128();
27534     {
27535       wuffs_base__slice_u8 i_slice_p = a_x;
27536       v_p.ptr = i_slice_p.ptr;
27537       v_p.len = 32;
27538       uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 32) * 32);
27539       while (v_p.ptr < i_end0_p) {
27540         v_q__left = _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr));
27541         v_q_right = _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 16u));
27542         v_v2j = _mm_add_epi32(v_v2j, v_v1);
27543         v_v1 = _mm_add_epi32(v_v1, _mm_sad_epu8(v_q__left, v_zeroes));
27544         v_v1 = _mm_add_epi32(v_v1, _mm_sad_epu8(v_q_right, v_zeroes));
27545         v_v2k = _mm_add_epi32(v_v2k, _mm_madd_epi16(v_ones, _mm_maddubs_epi16(v_q__left, v_weights__left)));
27546         v_v2k = _mm_add_epi32(v_v2k, _mm_madd_epi16(v_ones, _mm_maddubs_epi16(v_q_right, v_weights_right)));
27547         v_p.ptr += 32;
27548       }
27549       v_p.len = 0;
27550     }
27551     v_v1 = _mm_add_epi32(v_v1, _mm_shuffle_epi32(v_v1, (int32_t)(177u)));
27552     v_v1 = _mm_add_epi32(v_v1, _mm_shuffle_epi32(v_v1, (int32_t)(78u)));
27553     v_s1 += ((uint32_t)(_mm_cvtsi128_si32(v_v1)));
27554     v_v2 = _mm_add_epi32(v_v2k, _mm_slli_epi32(v_v2j, (int32_t)(5u)));
27555     v_v2 = _mm_add_epi32(v_v2, _mm_shuffle_epi32(v_v2, (int32_t)(177u)));
27556     v_v2 = _mm_add_epi32(v_v2, _mm_shuffle_epi32(v_v2, (int32_t)(78u)));
27557     v_s2 += ((uint32_t)(_mm_cvtsi128_si32(v_v2)));
27558     v_tail_index = (((uint64_t)(a_x.len)) & 18446744073709551584u);
27559     if (v_tail_index < ((uint64_t)(a_x.len))) {
27560       {
27561         wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, v_tail_index);
27562         v_p.ptr = i_slice_p.ptr;
27563         v_p.len = 1;
27564         uint8_t* i_end0_p = i_slice_p.ptr + i_slice_p.len;
27565         while (v_p.ptr < i_end0_p) {
27566           v_s1 += ((uint32_t)(v_p.ptr[0u]));
27567           v_s2 += v_s1;
27568           v_p.ptr += 1;
27569         }
27570         v_p.len = 0;
27571       }
27572     }
27573     v_s1 %= 65521u;
27574     v_s2 %= 65521u;
27575     a_x = v_remaining;
27576   }
27577   self->private_impl.f_state = (((v_s2 & 65535u) << 16u) | (v_s1 & 65535u));
27578   return wuffs_base__make_empty_struct();
27579 }
27580 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
27581 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
27582 
27583 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ADLER32)
27584 
27585 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BMP)
27586 
27587 // ---------------- Status Codes Implementations
27588 
27589 const char wuffs_bmp__error__bad_header[] = "#bmp: bad header";
27590 const char wuffs_bmp__error__bad_rle_compression[] = "#bmp: bad RLE compression";
27591 const char wuffs_bmp__error__truncated_input[] = "#bmp: truncated input";
27592 const char wuffs_bmp__error__unsupported_bmp_file[] = "#bmp: unsupported BMP file";
27593 const char wuffs_bmp__note__internal_note_short_read[] = "@bmp: internal note: short read";
27594 
27595 // ---------------- Private Consts
27596 
27597 #define WUFFS_BMP__COMPRESSION_NONE 0
27598 
27599 #define WUFFS_BMP__COMPRESSION_RLE8 1
27600 
27601 #define WUFFS_BMP__COMPRESSION_RLE4 2
27602 
27603 #define WUFFS_BMP__COMPRESSION_BITFIELDS 3
27604 
27605 #define WUFFS_BMP__COMPRESSION_JPEG 4
27606 
27607 #define WUFFS_BMP__COMPRESSION_PNG 5
27608 
27609 #define WUFFS_BMP__COMPRESSION_ALPHABITFIELDS 6
27610 
27611 #define WUFFS_BMP__COMPRESSION_LOW_BIT_DEPTH 256
27612 
27613 #define WUFFS_BMP__RLE_STATE_NEUTRAL 0
27614 
27615 #define WUFFS_BMP__RLE_STATE_RUN 1
27616 
27617 #define WUFFS_BMP__RLE_STATE_ESCAPE 2
27618 
27619 #define WUFFS_BMP__RLE_STATE_LITERAL 3
27620 
27621 #define WUFFS_BMP__RLE_STATE_DELTA_X 4
27622 
27623 #define WUFFS_BMP__RLE_STATE_DELTA_Y 5
27624 
27625 // ---------------- Private Initializer Prototypes
27626 
27627 // ---------------- Private Function Prototypes
27628 
27629 WUFFS_BASE__GENERATED_C_CODE
27630 static wuffs_base__status
27631 wuffs_bmp__decoder__do_decode_image_config(
27632     wuffs_bmp__decoder* self,
27633     wuffs_base__image_config* a_dst,
27634     wuffs_base__io_buffer* a_src);
27635 
27636 WUFFS_BASE__GENERATED_C_CODE
27637 static wuffs_base__status
27638 wuffs_bmp__decoder__do_decode_frame_config(
27639     wuffs_bmp__decoder* self,
27640     wuffs_base__frame_config* a_dst,
27641     wuffs_base__io_buffer* a_src);
27642 
27643 WUFFS_BASE__GENERATED_C_CODE
27644 static wuffs_base__status
27645 wuffs_bmp__decoder__do_decode_frame(
27646     wuffs_bmp__decoder* self,
27647     wuffs_base__pixel_buffer* a_dst,
27648     wuffs_base__io_buffer* a_src,
27649     wuffs_base__pixel_blend a_blend,
27650     wuffs_base__slice_u8 a_workbuf,
27651     wuffs_base__decode_frame_options* a_opts);
27652 
27653 WUFFS_BASE__GENERATED_C_CODE
27654 static wuffs_base__status
27655 wuffs_bmp__decoder__swizzle_none(
27656     wuffs_bmp__decoder* self,
27657     wuffs_base__pixel_buffer* a_dst,
27658     wuffs_base__io_buffer* a_src);
27659 
27660 WUFFS_BASE__GENERATED_C_CODE
27661 static wuffs_base__status
27662 wuffs_bmp__decoder__swizzle_rle(
27663     wuffs_bmp__decoder* self,
27664     wuffs_base__pixel_buffer* a_dst,
27665     wuffs_base__io_buffer* a_src);
27666 
27667 WUFFS_BASE__GENERATED_C_CODE
27668 static wuffs_base__status
27669 wuffs_bmp__decoder__swizzle_bitfields(
27670     wuffs_bmp__decoder* self,
27671     wuffs_base__pixel_buffer* a_dst,
27672     wuffs_base__io_buffer* a_src);
27673 
27674 WUFFS_BASE__GENERATED_C_CODE
27675 static wuffs_base__status
27676 wuffs_bmp__decoder__swizzle_low_bit_depth(
27677     wuffs_bmp__decoder* self,
27678     wuffs_base__pixel_buffer* a_dst,
27679     wuffs_base__io_buffer* a_src);
27680 
27681 WUFFS_BASE__GENERATED_C_CODE
27682 static wuffs_base__status
27683 wuffs_bmp__decoder__do_tell_me_more(
27684     wuffs_bmp__decoder* self,
27685     wuffs_base__io_buffer* a_dst,
27686     wuffs_base__more_information* a_minfo,
27687     wuffs_base__io_buffer* a_src);
27688 
27689 WUFFS_BASE__GENERATED_C_CODE
27690 static wuffs_base__status
27691 wuffs_bmp__decoder__read_palette(
27692     wuffs_bmp__decoder* self,
27693     wuffs_base__io_buffer* a_src);
27694 
27695 WUFFS_BASE__GENERATED_C_CODE
27696 static wuffs_base__status
27697 wuffs_bmp__decoder__process_masks(
27698     wuffs_bmp__decoder* self);
27699 
27700 // ---------------- VTables
27701 
27702 const wuffs_base__image_decoder__func_ptrs
27703 wuffs_bmp__decoder__func_ptrs_for__wuffs_base__image_decoder = {
27704   (wuffs_base__status(*)(void*,
27705       wuffs_base__pixel_buffer*,
27706       wuffs_base__io_buffer*,
27707       wuffs_base__pixel_blend,
27708       wuffs_base__slice_u8,
27709       wuffs_base__decode_frame_options*))(&wuffs_bmp__decoder__decode_frame),
27710   (wuffs_base__status(*)(void*,
27711       wuffs_base__frame_config*,
27712       wuffs_base__io_buffer*))(&wuffs_bmp__decoder__decode_frame_config),
27713   (wuffs_base__status(*)(void*,
27714       wuffs_base__image_config*,
27715       wuffs_base__io_buffer*))(&wuffs_bmp__decoder__decode_image_config),
27716   (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_bmp__decoder__frame_dirty_rect),
27717   (uint64_t(*)(const void*,
27718       uint32_t))(&wuffs_bmp__decoder__get_quirk),
27719   (uint64_t(*)(const void*))(&wuffs_bmp__decoder__history_retain_length),
27720   (uint32_t(*)(const void*))(&wuffs_bmp__decoder__num_animation_loops),
27721   (uint64_t(*)(const void*))(&wuffs_bmp__decoder__num_decoded_frame_configs),
27722   (uint64_t(*)(const void*))(&wuffs_bmp__decoder__num_decoded_frames),
27723   (wuffs_base__status(*)(void*,
27724       uint64_t,
27725       uint64_t))(&wuffs_bmp__decoder__restart_frame),
27726   (wuffs_base__status(*)(void*,
27727       uint32_t,
27728       uint64_t))(&wuffs_bmp__decoder__set_quirk),
27729   (wuffs_base__empty_struct(*)(void*,
27730       uint32_t,
27731       bool))(&wuffs_bmp__decoder__set_report_metadata),
27732   (wuffs_base__status(*)(void*,
27733       wuffs_base__io_buffer*,
27734       wuffs_base__more_information*,
27735       wuffs_base__io_buffer*))(&wuffs_bmp__decoder__tell_me_more),
27736   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_bmp__decoder__workbuf_len),
27737 };
27738 
27739 // ---------------- Initializer Implementations
27740 
27741 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
wuffs_bmp__decoder__initialize(wuffs_bmp__decoder * self,size_t sizeof_star_self,uint64_t wuffs_version,uint32_t options)27742 wuffs_bmp__decoder__initialize(
27743     wuffs_bmp__decoder* self,
27744     size_t sizeof_star_self,
27745     uint64_t wuffs_version,
27746     uint32_t options){
27747   if (!self) {
27748     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
27749   }
27750   if (sizeof(*self) != sizeof_star_self) {
27751     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
27752   }
27753   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
27754       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
27755     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
27756   }
27757 
27758   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
27759     // The whole point of this if-check is to detect an uninitialized *self.
27760     // We disable the warning on GCC. Clang-5.0 does not have this warning.
27761 #if !defined(__clang__) && defined(__GNUC__)
27762 #pragma GCC diagnostic push
27763 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
27764 #endif
27765     if (self->private_impl.magic != 0) {
27766       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
27767     }
27768 #if !defined(__clang__) && defined(__GNUC__)
27769 #pragma GCC diagnostic pop
27770 #endif
27771   } else {
27772     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
27773       memset(self, 0, sizeof(*self));
27774       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
27775     } else {
27776       memset(&(self->private_impl), 0, sizeof(self->private_impl));
27777     }
27778   }
27779 
27780   self->private_impl.magic = WUFFS_BASE__MAGIC;
27781   self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
27782       wuffs_base__image_decoder__vtable_name;
27783   self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
27784       (const void*)(&wuffs_bmp__decoder__func_ptrs_for__wuffs_base__image_decoder);
27785   return wuffs_base__make_status(NULL);
27786 }
27787 
27788 wuffs_bmp__decoder*
wuffs_bmp__decoder__alloc(void)27789 wuffs_bmp__decoder__alloc(void) {
27790   wuffs_bmp__decoder* x =
27791       (wuffs_bmp__decoder*)(calloc(sizeof(wuffs_bmp__decoder), 1));
27792   if (!x) {
27793     return NULL;
27794   }
27795   if (wuffs_bmp__decoder__initialize(
27796       x, sizeof(wuffs_bmp__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
27797     free(x);
27798     return NULL;
27799   }
27800   return x;
27801 }
27802 
27803 size_t
sizeof__wuffs_bmp__decoder(void)27804 sizeof__wuffs_bmp__decoder(void) {
27805   return sizeof(wuffs_bmp__decoder);
27806 }
27807 
27808 // ---------------- Function Implementations
27809 
27810 // -------- func bmp.decoder.get_quirk
27811 
27812 WUFFS_BASE__GENERATED_C_CODE
27813 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_bmp__decoder__get_quirk(const wuffs_bmp__decoder * self,uint32_t a_key)27814 wuffs_bmp__decoder__get_quirk(
27815     const wuffs_bmp__decoder* self,
27816     uint32_t a_key) {
27817   if (!self) {
27818     return 0;
27819   }
27820   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
27821       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
27822     return 0;
27823   }
27824 
27825   return 0u;
27826 }
27827 
27828 // -------- func bmp.decoder.set_quirk
27829 
27830 WUFFS_BASE__GENERATED_C_CODE
27831 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_bmp__decoder__set_quirk(wuffs_bmp__decoder * self,uint32_t a_key,uint64_t a_value)27832 wuffs_bmp__decoder__set_quirk(
27833     wuffs_bmp__decoder* self,
27834     uint32_t a_key,
27835     uint64_t a_value) {
27836   if (!self) {
27837     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
27838   }
27839   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
27840     return wuffs_base__make_status(
27841         (self->private_impl.magic == WUFFS_BASE__DISABLED)
27842         ? wuffs_base__error__disabled_by_previous_error
27843         : wuffs_base__error__initialize_not_called);
27844   }
27845 
27846   return wuffs_base__make_status(wuffs_base__error__unsupported_option);
27847 }
27848 
27849 // -------- func bmp.decoder.decode_image_config
27850 
27851 WUFFS_BASE__GENERATED_C_CODE
27852 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_bmp__decoder__decode_image_config(wuffs_bmp__decoder * self,wuffs_base__image_config * a_dst,wuffs_base__io_buffer * a_src)27853 wuffs_bmp__decoder__decode_image_config(
27854     wuffs_bmp__decoder* self,
27855     wuffs_base__image_config* a_dst,
27856     wuffs_base__io_buffer* a_src) {
27857   if (!self) {
27858     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
27859   }
27860   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
27861     return wuffs_base__make_status(
27862         (self->private_impl.magic == WUFFS_BASE__DISABLED)
27863         ? wuffs_base__error__disabled_by_previous_error
27864         : wuffs_base__error__initialize_not_called);
27865   }
27866   if (!a_src) {
27867     self->private_impl.magic = WUFFS_BASE__DISABLED;
27868     return wuffs_base__make_status(wuffs_base__error__bad_argument);
27869   }
27870   if ((self->private_impl.active_coroutine != 0) &&
27871       (self->private_impl.active_coroutine != 1)) {
27872     self->private_impl.magic = WUFFS_BASE__DISABLED;
27873     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
27874   }
27875   self->private_impl.active_coroutine = 0;
27876   wuffs_base__status status = wuffs_base__make_status(NULL);
27877 
27878   wuffs_base__status v_status = wuffs_base__make_status(NULL);
27879 
27880   uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
27881   switch (coro_susp_point) {
27882     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
27883 
27884     while (true) {
27885       {
27886         wuffs_base__status t_0 = wuffs_bmp__decoder__do_decode_image_config(self, a_dst, a_src);
27887         v_status = t_0;
27888       }
27889       if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
27890         status = wuffs_base__make_status(wuffs_bmp__error__truncated_input);
27891         goto exit;
27892       }
27893       status = v_status;
27894       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
27895     }
27896 
27897     ok:
27898     self->private_impl.p_decode_image_config[0] = 0;
27899     goto exit;
27900   }
27901 
27902   goto suspend;
27903   suspend:
27904   self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
27905   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
27906 
27907   goto exit;
27908   exit:
27909   if (wuffs_base__status__is_error(&status)) {
27910     self->private_impl.magic = WUFFS_BASE__DISABLED;
27911   }
27912   return status;
27913 }
27914 
27915 // -------- func bmp.decoder.do_decode_image_config
27916 
27917 WUFFS_BASE__GENERATED_C_CODE
27918 static wuffs_base__status
wuffs_bmp__decoder__do_decode_image_config(wuffs_bmp__decoder * self,wuffs_base__image_config * a_dst,wuffs_base__io_buffer * a_src)27919 wuffs_bmp__decoder__do_decode_image_config(
27920     wuffs_bmp__decoder* self,
27921     wuffs_base__image_config* a_dst,
27922     wuffs_base__io_buffer* a_src) {
27923   wuffs_base__status status = wuffs_base__make_status(NULL);
27924 
27925   uint32_t v_magic = 0;
27926   uint32_t v_width = 0;
27927   uint32_t v_height = 0;
27928   uint32_t v_planes = 0;
27929   uint32_t v_dst_pixfmt = 0;
27930   uint32_t v_byte_width = 0;
27931 
27932   const uint8_t* iop_a_src = NULL;
27933   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27934   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27935   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27936   if (a_src && a_src->data.ptr) {
27937     io0_a_src = a_src->data.ptr;
27938     io1_a_src = io0_a_src + a_src->meta.ri;
27939     iop_a_src = io1_a_src;
27940     io2_a_src = io0_a_src + a_src->meta.wi;
27941   }
27942 
27943   uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config[0];
27944   switch (coro_susp_point) {
27945     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
27946 
27947     if ((self->private_impl.f_call_sequence != 0u) || (self->private_impl.f_io_redirect_fourcc == 1u)) {
27948       status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
27949       goto exit;
27950     } else if (self->private_impl.f_io_redirect_fourcc != 0u) {
27951       status = wuffs_base__make_status(wuffs_base__note__i_o_redirect);
27952       goto ok;
27953     }
27954     {
27955       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
27956       uint32_t t_0;
27957       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
27958         t_0 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
27959         iop_a_src += 2;
27960       } else {
27961         self->private_data.s_do_decode_image_config[0].scratch = 0;
27962         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
27963         while (true) {
27964           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
27965             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
27966             goto suspend;
27967           }
27968           uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
27969           uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
27970           *scratch <<= 8;
27971           *scratch >>= 8;
27972           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
27973           if (num_bits_0 == 8) {
27974             t_0 = ((uint32_t)(*scratch));
27975             break;
27976           }
27977           num_bits_0 += 8u;
27978           *scratch |= ((uint64_t)(num_bits_0)) << 56;
27979         }
27980       }
27981       v_magic = t_0;
27982     }
27983     if (v_magic != 19778u) {
27984       status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
27985       goto exit;
27986     }
27987     self->private_data.s_do_decode_image_config[0].scratch = 8u;
27988     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
27989     if (self->private_data.s_do_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
27990       self->private_data.s_do_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
27991       iop_a_src = io2_a_src;
27992       status = wuffs_base__make_status(wuffs_base__suspension__short_read);
27993       goto suspend;
27994     }
27995     iop_a_src += self->private_data.s_do_decode_image_config[0].scratch;
27996     {
27997       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
27998       uint32_t t_1;
27999       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
28000         t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
28001         iop_a_src += 4;
28002       } else {
28003         self->private_data.s_do_decode_image_config[0].scratch = 0;
28004         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
28005         while (true) {
28006           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
28007             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28008             goto suspend;
28009           }
28010           uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
28011           uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
28012           *scratch <<= 8;
28013           *scratch >>= 8;
28014           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
28015           if (num_bits_1 == 24) {
28016             t_1 = ((uint32_t)(*scratch));
28017             break;
28018           }
28019           num_bits_1 += 8u;
28020           *scratch |= ((uint64_t)(num_bits_1)) << 56;
28021         }
28022       }
28023       self->private_impl.f_padding = t_1;
28024     }
28025     if (self->private_impl.f_padding < 14u) {
28026       status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
28027       goto exit;
28028     }
28029     self->private_impl.f_padding -= 14u;
28030     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))));
28031     {
28032       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
28033       uint32_t t_2;
28034       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
28035         t_2 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
28036         iop_a_src += 4;
28037       } else {
28038         self->private_data.s_do_decode_image_config[0].scratch = 0;
28039         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
28040         while (true) {
28041           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
28042             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28043             goto suspend;
28044           }
28045           uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
28046           uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
28047           *scratch <<= 8;
28048           *scratch >>= 8;
28049           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
28050           if (num_bits_2 == 24) {
28051             t_2 = ((uint32_t)(*scratch));
28052             break;
28053           }
28054           num_bits_2 += 8u;
28055           *scratch |= ((uint64_t)(num_bits_2)) << 56;
28056         }
28057       }
28058       self->private_impl.f_bitmap_info_len = t_2;
28059     }
28060     if (self->private_impl.f_padding < self->private_impl.f_bitmap_info_len) {
28061       status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
28062       goto exit;
28063     }
28064     self->private_impl.f_padding -= self->private_impl.f_bitmap_info_len;
28065     if (self->private_impl.f_bitmap_info_len == 12u) {
28066       {
28067         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
28068         uint32_t t_3;
28069         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
28070           t_3 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
28071           iop_a_src += 2;
28072         } else {
28073           self->private_data.s_do_decode_image_config[0].scratch = 0;
28074           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
28075           while (true) {
28076             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
28077               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28078               goto suspend;
28079             }
28080             uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
28081             uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56));
28082             *scratch <<= 8;
28083             *scratch >>= 8;
28084             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3;
28085             if (num_bits_3 == 8) {
28086               t_3 = ((uint32_t)(*scratch));
28087               break;
28088             }
28089             num_bits_3 += 8u;
28090             *scratch |= ((uint64_t)(num_bits_3)) << 56;
28091           }
28092         }
28093         self->private_impl.f_width = t_3;
28094       }
28095       {
28096         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
28097         uint32_t t_4;
28098         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
28099           t_4 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
28100           iop_a_src += 2;
28101         } else {
28102           self->private_data.s_do_decode_image_config[0].scratch = 0;
28103           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
28104           while (true) {
28105             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
28106               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28107               goto suspend;
28108             }
28109             uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
28110             uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
28111             *scratch <<= 8;
28112             *scratch >>= 8;
28113             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
28114             if (num_bits_4 == 8) {
28115               t_4 = ((uint32_t)(*scratch));
28116               break;
28117             }
28118             num_bits_4 += 8u;
28119             *scratch |= ((uint64_t)(num_bits_4)) << 56;
28120           }
28121         }
28122         self->private_impl.f_height = t_4;
28123       }
28124       {
28125         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
28126         uint32_t t_5;
28127         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
28128           t_5 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
28129           iop_a_src += 2;
28130         } else {
28131           self->private_data.s_do_decode_image_config[0].scratch = 0;
28132           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
28133           while (true) {
28134             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
28135               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28136               goto suspend;
28137             }
28138             uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
28139             uint32_t num_bits_5 = ((uint32_t)(*scratch >> 56));
28140             *scratch <<= 8;
28141             *scratch >>= 8;
28142             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_5;
28143             if (num_bits_5 == 8) {
28144               t_5 = ((uint32_t)(*scratch));
28145               break;
28146             }
28147             num_bits_5 += 8u;
28148             *scratch |= ((uint64_t)(num_bits_5)) << 56;
28149           }
28150         }
28151         v_planes = t_5;
28152       }
28153       if (v_planes != 1u) {
28154         status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
28155         goto exit;
28156       }
28157       {
28158         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
28159         uint32_t t_6;
28160         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
28161           t_6 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
28162           iop_a_src += 2;
28163         } else {
28164           self->private_data.s_do_decode_image_config[0].scratch = 0;
28165           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
28166           while (true) {
28167             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
28168               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28169               goto suspend;
28170             }
28171             uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
28172             uint32_t num_bits_6 = ((uint32_t)(*scratch >> 56));
28173             *scratch <<= 8;
28174             *scratch >>= 8;
28175             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_6;
28176             if (num_bits_6 == 8) {
28177               t_6 = ((uint32_t)(*scratch));
28178               break;
28179             }
28180             num_bits_6 += 8u;
28181             *scratch |= ((uint64_t)(num_bits_6)) << 56;
28182           }
28183         }
28184         self->private_impl.f_bits_per_pixel = t_6;
28185       }
28186     } else if (self->private_impl.f_bitmap_info_len == 16u) {
28187       {
28188         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
28189         uint32_t t_7;
28190         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
28191           t_7 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
28192           iop_a_src += 4;
28193         } else {
28194           self->private_data.s_do_decode_image_config[0].scratch = 0;
28195           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(17);
28196           while (true) {
28197             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
28198               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28199               goto suspend;
28200             }
28201             uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
28202             uint32_t num_bits_7 = ((uint32_t)(*scratch >> 56));
28203             *scratch <<= 8;
28204             *scratch >>= 8;
28205             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_7;
28206             if (num_bits_7 == 24) {
28207               t_7 = ((uint32_t)(*scratch));
28208               break;
28209             }
28210             num_bits_7 += 8u;
28211             *scratch |= ((uint64_t)(num_bits_7)) << 56;
28212           }
28213         }
28214         v_width = t_7;
28215       }
28216       if (v_width > 2147483647u) {
28217         status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
28218         goto exit;
28219       } else if (v_width > 16777215u) {
28220         status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension);
28221         goto exit;
28222       }
28223       self->private_impl.f_width = v_width;
28224       {
28225         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(18);
28226         uint32_t t_8;
28227         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
28228           t_8 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
28229           iop_a_src += 4;
28230         } else {
28231           self->private_data.s_do_decode_image_config[0].scratch = 0;
28232           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(19);
28233           while (true) {
28234             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
28235               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28236               goto suspend;
28237             }
28238             uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
28239             uint32_t num_bits_8 = ((uint32_t)(*scratch >> 56));
28240             *scratch <<= 8;
28241             *scratch >>= 8;
28242             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_8;
28243             if (num_bits_8 == 24) {
28244               t_8 = ((uint32_t)(*scratch));
28245               break;
28246             }
28247             num_bits_8 += 8u;
28248             *scratch |= ((uint64_t)(num_bits_8)) << 56;
28249           }
28250         }
28251         v_height = t_8;
28252       }
28253       if (v_height > 2147483647u) {
28254         status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
28255         goto exit;
28256       } else if (v_height > 16777215u) {
28257         status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension);
28258         goto exit;
28259       }
28260       self->private_impl.f_height = v_height;
28261       {
28262         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(20);
28263         uint32_t t_9;
28264         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
28265           t_9 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
28266           iop_a_src += 2;
28267         } else {
28268           self->private_data.s_do_decode_image_config[0].scratch = 0;
28269           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(21);
28270           while (true) {
28271             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
28272               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28273               goto suspend;
28274             }
28275             uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
28276             uint32_t num_bits_9 = ((uint32_t)(*scratch >> 56));
28277             *scratch <<= 8;
28278             *scratch >>= 8;
28279             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_9;
28280             if (num_bits_9 == 8) {
28281               t_9 = ((uint32_t)(*scratch));
28282               break;
28283             }
28284             num_bits_9 += 8u;
28285             *scratch |= ((uint64_t)(num_bits_9)) << 56;
28286           }
28287         }
28288         v_planes = t_9;
28289       }
28290       if (v_planes != 1u) {
28291         status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
28292         goto exit;
28293       }
28294       {
28295         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(22);
28296         uint32_t t_10;
28297         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
28298           t_10 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
28299           iop_a_src += 2;
28300         } else {
28301           self->private_data.s_do_decode_image_config[0].scratch = 0;
28302           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(23);
28303           while (true) {
28304             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
28305               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28306               goto suspend;
28307             }
28308             uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
28309             uint32_t num_bits_10 = ((uint32_t)(*scratch >> 56));
28310             *scratch <<= 8;
28311             *scratch >>= 8;
28312             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_10;
28313             if (num_bits_10 == 8) {
28314               t_10 = ((uint32_t)(*scratch));
28315               break;
28316             }
28317             num_bits_10 += 8u;
28318             *scratch |= ((uint64_t)(num_bits_10)) << 56;
28319           }
28320         }
28321         self->private_impl.f_bits_per_pixel = t_10;
28322       }
28323     } else {
28324       {
28325         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(24);
28326         uint32_t t_11;
28327         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
28328           t_11 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
28329           iop_a_src += 4;
28330         } else {
28331           self->private_data.s_do_decode_image_config[0].scratch = 0;
28332           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(25);
28333           while (true) {
28334             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
28335               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28336               goto suspend;
28337             }
28338             uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
28339             uint32_t num_bits_11 = ((uint32_t)(*scratch >> 56));
28340             *scratch <<= 8;
28341             *scratch >>= 8;
28342             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_11;
28343             if (num_bits_11 == 24) {
28344               t_11 = ((uint32_t)(*scratch));
28345               break;
28346             }
28347             num_bits_11 += 8u;
28348             *scratch |= ((uint64_t)(num_bits_11)) << 56;
28349           }
28350         }
28351         v_width = t_11;
28352       }
28353       if (v_width > 2147483647u) {
28354         status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
28355         goto exit;
28356       } else if (v_width > 16777215u) {
28357         status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension);
28358         goto exit;
28359       }
28360       self->private_impl.f_width = v_width;
28361       {
28362         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(26);
28363         uint32_t t_12;
28364         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
28365           t_12 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
28366           iop_a_src += 4;
28367         } else {
28368           self->private_data.s_do_decode_image_config[0].scratch = 0;
28369           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(27);
28370           while (true) {
28371             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
28372               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28373               goto suspend;
28374             }
28375             uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
28376             uint32_t num_bits_12 = ((uint32_t)(*scratch >> 56));
28377             *scratch <<= 8;
28378             *scratch >>= 8;
28379             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_12;
28380             if (num_bits_12 == 24) {
28381               t_12 = ((uint32_t)(*scratch));
28382               break;
28383             }
28384             num_bits_12 += 8u;
28385             *scratch |= ((uint64_t)(num_bits_12)) << 56;
28386           }
28387         }
28388         v_height = t_12;
28389       }
28390       if (v_height == 2147483648u) {
28391         status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
28392         goto exit;
28393       } else if (v_height > 2147483648u) {
28394         v_height = ((uint32_t)(0u - v_height));
28395         if (v_height > 16777215u) {
28396           status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension);
28397           goto exit;
28398         }
28399         self->private_impl.f_height = v_height;
28400         self->private_impl.f_top_down = true;
28401       } else if (v_height > 16777215u) {
28402         status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension);
28403         goto exit;
28404       } else {
28405         self->private_impl.f_height = v_height;
28406       }
28407       {
28408         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(28);
28409         uint32_t t_13;
28410         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
28411           t_13 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
28412           iop_a_src += 2;
28413         } else {
28414           self->private_data.s_do_decode_image_config[0].scratch = 0;
28415           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(29);
28416           while (true) {
28417             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
28418               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28419               goto suspend;
28420             }
28421             uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
28422             uint32_t num_bits_13 = ((uint32_t)(*scratch >> 56));
28423             *scratch <<= 8;
28424             *scratch >>= 8;
28425             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_13;
28426             if (num_bits_13 == 8) {
28427               t_13 = ((uint32_t)(*scratch));
28428               break;
28429             }
28430             num_bits_13 += 8u;
28431             *scratch |= ((uint64_t)(num_bits_13)) << 56;
28432           }
28433         }
28434         v_planes = t_13;
28435       }
28436       if (v_planes != 1u) {
28437         status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
28438         goto exit;
28439       }
28440       {
28441         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(30);
28442         uint32_t t_14;
28443         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
28444           t_14 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
28445           iop_a_src += 2;
28446         } else {
28447           self->private_data.s_do_decode_image_config[0].scratch = 0;
28448           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(31);
28449           while (true) {
28450             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
28451               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28452               goto suspend;
28453             }
28454             uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
28455             uint32_t num_bits_14 = ((uint32_t)(*scratch >> 56));
28456             *scratch <<= 8;
28457             *scratch >>= 8;
28458             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_14;
28459             if (num_bits_14 == 8) {
28460               t_14 = ((uint32_t)(*scratch));
28461               break;
28462             }
28463             num_bits_14 += 8u;
28464             *scratch |= ((uint64_t)(num_bits_14)) << 56;
28465           }
28466         }
28467         self->private_impl.f_bits_per_pixel = t_14;
28468       }
28469       {
28470         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(32);
28471         uint32_t t_15;
28472         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
28473           t_15 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
28474           iop_a_src += 4;
28475         } else {
28476           self->private_data.s_do_decode_image_config[0].scratch = 0;
28477           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(33);
28478           while (true) {
28479             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
28480               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28481               goto suspend;
28482             }
28483             uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
28484             uint32_t num_bits_15 = ((uint32_t)(*scratch >> 56));
28485             *scratch <<= 8;
28486             *scratch >>= 8;
28487             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_15;
28488             if (num_bits_15 == 24) {
28489               t_15 = ((uint32_t)(*scratch));
28490               break;
28491             }
28492             num_bits_15 += 8u;
28493             *scratch |= ((uint64_t)(num_bits_15)) << 56;
28494           }
28495         }
28496         self->private_impl.f_compression = t_15;
28497       }
28498       if (self->private_impl.f_bits_per_pixel == 0u) {
28499         if (self->private_impl.f_compression == 4u) {
28500           self->private_impl.f_io_redirect_fourcc = 1246774599u;
28501           status = wuffs_base__make_status(wuffs_base__note__i_o_redirect);
28502           goto ok;
28503         } else if (self->private_impl.f_compression == 5u) {
28504           self->private_impl.f_io_redirect_fourcc = 1347307296u;
28505           status = wuffs_base__make_status(wuffs_base__note__i_o_redirect);
28506           goto ok;
28507         }
28508         status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
28509         goto exit;
28510       }
28511       self->private_data.s_do_decode_image_config[0].scratch = 20u;
28512       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(34);
28513       if (self->private_data.s_do_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
28514         self->private_data.s_do_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
28515         iop_a_src = io2_a_src;
28516         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28517         goto suspend;
28518       }
28519       iop_a_src += self->private_data.s_do_decode_image_config[0].scratch;
28520       if (self->private_impl.f_bitmap_info_len == 40u) {
28521         if (self->private_impl.f_bits_per_pixel >= 16u) {
28522           if (self->private_impl.f_padding >= 16u) {
28523             self->private_impl.f_bitmap_info_len = 56u;
28524             self->private_impl.f_padding -= 16u;
28525           } else if (self->private_impl.f_padding >= 12u) {
28526             self->private_impl.f_bitmap_info_len = 52u;
28527             self->private_impl.f_padding -= 12u;
28528           }
28529         }
28530       } else if ((self->private_impl.f_bitmap_info_len != 52u) &&
28531           (self->private_impl.f_bitmap_info_len != 56u) &&
28532           (self->private_impl.f_bitmap_info_len != 64u) &&
28533           (self->private_impl.f_bitmap_info_len != 108u) &&
28534           (self->private_impl.f_bitmap_info_len != 124u)) {
28535         status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
28536         goto exit;
28537       }
28538       if (self->private_impl.f_compression == 6u) {
28539         self->private_impl.f_compression = 3u;
28540       }
28541       if (self->private_impl.f_compression == 3u) {
28542         if (self->private_impl.f_bitmap_info_len >= 52u) {
28543           {
28544             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(35);
28545             uint32_t t_16;
28546             if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
28547               t_16 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
28548               iop_a_src += 4;
28549             } else {
28550               self->private_data.s_do_decode_image_config[0].scratch = 0;
28551               WUFFS_BASE__COROUTINE_SUSPENSION_POINT(36);
28552               while (true) {
28553                 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
28554                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28555                   goto suspend;
28556                 }
28557                 uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
28558                 uint32_t num_bits_16 = ((uint32_t)(*scratch >> 56));
28559                 *scratch <<= 8;
28560                 *scratch >>= 8;
28561                 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_16;
28562                 if (num_bits_16 == 24) {
28563                   t_16 = ((uint32_t)(*scratch));
28564                   break;
28565                 }
28566                 num_bits_16 += 8u;
28567                 *scratch |= ((uint64_t)(num_bits_16)) << 56;
28568               }
28569             }
28570             self->private_impl.f_channel_masks[2u] = t_16;
28571           }
28572           {
28573             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(37);
28574             uint32_t t_17;
28575             if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
28576               t_17 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
28577               iop_a_src += 4;
28578             } else {
28579               self->private_data.s_do_decode_image_config[0].scratch = 0;
28580               WUFFS_BASE__COROUTINE_SUSPENSION_POINT(38);
28581               while (true) {
28582                 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
28583                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28584                   goto suspend;
28585                 }
28586                 uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
28587                 uint32_t num_bits_17 = ((uint32_t)(*scratch >> 56));
28588                 *scratch <<= 8;
28589                 *scratch >>= 8;
28590                 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_17;
28591                 if (num_bits_17 == 24) {
28592                   t_17 = ((uint32_t)(*scratch));
28593                   break;
28594                 }
28595                 num_bits_17 += 8u;
28596                 *scratch |= ((uint64_t)(num_bits_17)) << 56;
28597               }
28598             }
28599             self->private_impl.f_channel_masks[1u] = t_17;
28600           }
28601           {
28602             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(39);
28603             uint32_t t_18;
28604             if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
28605               t_18 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
28606               iop_a_src += 4;
28607             } else {
28608               self->private_data.s_do_decode_image_config[0].scratch = 0;
28609               WUFFS_BASE__COROUTINE_SUSPENSION_POINT(40);
28610               while (true) {
28611                 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
28612                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28613                   goto suspend;
28614                 }
28615                 uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
28616                 uint32_t num_bits_18 = ((uint32_t)(*scratch >> 56));
28617                 *scratch <<= 8;
28618                 *scratch >>= 8;
28619                 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_18;
28620                 if (num_bits_18 == 24) {
28621                   t_18 = ((uint32_t)(*scratch));
28622                   break;
28623                 }
28624                 num_bits_18 += 8u;
28625                 *scratch |= ((uint64_t)(num_bits_18)) << 56;
28626               }
28627             }
28628             self->private_impl.f_channel_masks[0u] = t_18;
28629           }
28630           if (self->private_impl.f_bitmap_info_len >= 56u) {
28631             {
28632               WUFFS_BASE__COROUTINE_SUSPENSION_POINT(41);
28633               uint32_t t_19;
28634               if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
28635                 t_19 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
28636                 iop_a_src += 4;
28637               } else {
28638                 self->private_data.s_do_decode_image_config[0].scratch = 0;
28639                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(42);
28640                 while (true) {
28641                   if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
28642                     status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28643                     goto suspend;
28644                   }
28645                   uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
28646                   uint32_t num_bits_19 = ((uint32_t)(*scratch >> 56));
28647                   *scratch <<= 8;
28648                   *scratch >>= 8;
28649                   *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_19;
28650                   if (num_bits_19 == 24) {
28651                     t_19 = ((uint32_t)(*scratch));
28652                     break;
28653                   }
28654                   num_bits_19 += 8u;
28655                   *scratch |= ((uint64_t)(num_bits_19)) << 56;
28656                 }
28657               }
28658               self->private_impl.f_channel_masks[3u] = t_19;
28659             }
28660             self->private_data.s_do_decode_image_config[0].scratch = ((uint32_t)(self->private_impl.f_bitmap_info_len - 56u));
28661             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(43);
28662             if (self->private_data.s_do_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
28663               self->private_data.s_do_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
28664               iop_a_src = io2_a_src;
28665               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28666               goto suspend;
28667             }
28668             iop_a_src += self->private_data.s_do_decode_image_config[0].scratch;
28669           }
28670           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)) {
28671             if (self->private_impl.f_bits_per_pixel == 24u) {
28672               self->private_impl.f_compression = 0u;
28673             } else if (self->private_impl.f_bits_per_pixel == 32u) {
28674               if ((self->private_impl.f_channel_masks[3u] == 0u) || (self->private_impl.f_channel_masks[3u] == 4278190080u)) {
28675                 self->private_impl.f_compression = 0u;
28676               }
28677             }
28678           }
28679           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(44);
28680           status = wuffs_bmp__decoder__process_masks(self);
28681           if (status.repr) {
28682             goto suspend;
28683           }
28684         }
28685       } else if (self->private_impl.f_bitmap_info_len >= 40u) {
28686         self->private_data.s_do_decode_image_config[0].scratch = (self->private_impl.f_bitmap_info_len - 40u);
28687         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(45);
28688         if (self->private_data.s_do_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
28689           self->private_data.s_do_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
28690           iop_a_src = io2_a_src;
28691           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28692           goto suspend;
28693         }
28694         iop_a_src += self->private_data.s_do_decode_image_config[0].scratch;
28695       } else {
28696         status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
28697         goto exit;
28698       }
28699     }
28700     if (self->private_impl.f_compression != 3u) {
28701       if (self->private_impl.f_bits_per_pixel < 16u) {
28702         if (a_src) {
28703           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
28704         }
28705         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(46);
28706         status = wuffs_bmp__decoder__read_palette(self, a_src);
28707         if (a_src) {
28708           iop_a_src = a_src->data.ptr + a_src->meta.ri;
28709         }
28710         if (status.repr) {
28711           goto suspend;
28712         }
28713       }
28714     }
28715     if (self->private_impl.f_compression == 0u) {
28716       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)) {
28717         self->private_impl.f_src_pixfmt = 2198077448u;
28718         self->private_impl.f_compression = 256u;
28719       } else if (self->private_impl.f_bits_per_pixel == 8u) {
28720         self->private_impl.f_src_pixfmt = 2198077448u;
28721       } else if (self->private_impl.f_bits_per_pixel == 16u) {
28722         self->private_impl.f_compression = 3u;
28723         self->private_impl.f_channel_masks[0u] = 31u;
28724         self->private_impl.f_channel_masks[1u] = 992u;
28725         self->private_impl.f_channel_masks[2u] = 31744u;
28726         self->private_impl.f_channel_masks[3u] = 0u;
28727         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(47);
28728         status = wuffs_bmp__decoder__process_masks(self);
28729         if (status.repr) {
28730           goto suspend;
28731         }
28732         self->private_impl.f_src_pixfmt = 2164308923u;
28733       } else if (self->private_impl.f_bits_per_pixel == 24u) {
28734         self->private_impl.f_src_pixfmt = 2147485832u;
28735       } else if (self->private_impl.f_bits_per_pixel == 32u) {
28736         if (self->private_impl.f_channel_masks[3u] == 0u) {
28737           self->private_impl.f_src_pixfmt = 2415954056u;
28738         } else {
28739           self->private_impl.f_src_pixfmt = 2164295816u;
28740         }
28741       } else {
28742         status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
28743         goto exit;
28744       }
28745     } else if (self->private_impl.f_compression == 1u) {
28746       if (self->private_impl.f_bits_per_pixel == 8u) {
28747         self->private_impl.f_src_pixfmt = 2198077448u;
28748       } else {
28749         status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
28750         goto exit;
28751       }
28752     } else if (self->private_impl.f_compression == 2u) {
28753       if (self->private_impl.f_bits_per_pixel == 4u) {
28754         self->private_impl.f_src_pixfmt = 2198077448u;
28755       } else {
28756         status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
28757         goto exit;
28758       }
28759     } else if (self->private_impl.f_compression == 3u) {
28760       if ((self->private_impl.f_bits_per_pixel == 16u) || (self->private_impl.f_bits_per_pixel == 32u)) {
28761         self->private_impl.f_src_pixfmt = 2164308923u;
28762       } else {
28763         status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
28764         goto exit;
28765       }
28766     } else {
28767       status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
28768       goto exit;
28769     }
28770     if (((self->private_impl.f_bitmap_info_len < 40u) || (self->private_impl.f_bitmap_info_len == 64u)) &&
28771         (self->private_impl.f_bits_per_pixel != 1u) &&
28772         (self->private_impl.f_bits_per_pixel != 4u) &&
28773         (self->private_impl.f_bits_per_pixel != 8u) &&
28774         (self->private_impl.f_bits_per_pixel != 24u)) {
28775       status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
28776       goto exit;
28777     }
28778     if (self->private_impl.f_bits_per_pixel == 1u) {
28779       v_byte_width = ((self->private_impl.f_width >> 3u) + (((self->private_impl.f_width & 7u) + 7u) >> 3u));
28780       self->private_impl.f_pad_per_row = ((4u - (v_byte_width & 3u)) & 3u);
28781     } else if (self->private_impl.f_bits_per_pixel == 2u) {
28782       v_byte_width = ((self->private_impl.f_width >> 2u) + (((self->private_impl.f_width & 3u) + 3u) >> 2u));
28783       self->private_impl.f_pad_per_row = ((4u - (v_byte_width & 3u)) & 3u);
28784     } else if (self->private_impl.f_bits_per_pixel == 4u) {
28785       v_byte_width = ((self->private_impl.f_width >> 1u) + (self->private_impl.f_width & 1u));
28786       self->private_impl.f_pad_per_row = ((4u - (v_byte_width & 3u)) & 3u);
28787     } else if (self->private_impl.f_bits_per_pixel == 8u) {
28788       self->private_impl.f_pad_per_row = ((4u - (self->private_impl.f_width & 3u)) & 3u);
28789     } else if (self->private_impl.f_bits_per_pixel == 16u) {
28790       self->private_impl.f_pad_per_row = ((self->private_impl.f_width & 1u) * 2u);
28791     } else if (self->private_impl.f_bits_per_pixel == 24u) {
28792       self->private_impl.f_pad_per_row = (self->private_impl.f_width & 3u);
28793     } else if (self->private_impl.f_bits_per_pixel == 32u) {
28794       self->private_impl.f_pad_per_row = 0u;
28795     }
28796     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)));
28797     if (a_dst != NULL) {
28798       v_dst_pixfmt = 2164295816u;
28799       if ((self->private_impl.f_channel_num_bits[0u] > 8u) ||
28800           (self->private_impl.f_channel_num_bits[1u] > 8u) ||
28801           (self->private_impl.f_channel_num_bits[2u] > 8u) ||
28802           (self->private_impl.f_channel_num_bits[3u] > 8u)) {
28803         v_dst_pixfmt = 2164308923u;
28804       }
28805       wuffs_base__image_config__set(
28806           a_dst,
28807           v_dst_pixfmt,
28808           0u,
28809           self->private_impl.f_width,
28810           self->private_impl.f_height,
28811           self->private_impl.f_frame_config_io_position,
28812           (self->private_impl.f_channel_masks[3u] == 0u));
28813     }
28814     self->private_impl.f_call_sequence = 32u;
28815 
28816     ok:
28817     self->private_impl.p_do_decode_image_config[0] = 0;
28818     goto exit;
28819   }
28820 
28821   goto suspend;
28822   suspend:
28823   self->private_impl.p_do_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
28824 
28825   goto exit;
28826   exit:
28827   if (a_src && a_src->data.ptr) {
28828     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
28829   }
28830 
28831   return status;
28832 }
28833 
28834 // -------- func bmp.decoder.decode_frame_config
28835 
28836 WUFFS_BASE__GENERATED_C_CODE
28837 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_bmp__decoder__decode_frame_config(wuffs_bmp__decoder * self,wuffs_base__frame_config * a_dst,wuffs_base__io_buffer * a_src)28838 wuffs_bmp__decoder__decode_frame_config(
28839     wuffs_bmp__decoder* self,
28840     wuffs_base__frame_config* a_dst,
28841     wuffs_base__io_buffer* a_src) {
28842   if (!self) {
28843     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
28844   }
28845   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
28846     return wuffs_base__make_status(
28847         (self->private_impl.magic == WUFFS_BASE__DISABLED)
28848         ? wuffs_base__error__disabled_by_previous_error
28849         : wuffs_base__error__initialize_not_called);
28850   }
28851   if (!a_src) {
28852     self->private_impl.magic = WUFFS_BASE__DISABLED;
28853     return wuffs_base__make_status(wuffs_base__error__bad_argument);
28854   }
28855   if ((self->private_impl.active_coroutine != 0) &&
28856       (self->private_impl.active_coroutine != 2)) {
28857     self->private_impl.magic = WUFFS_BASE__DISABLED;
28858     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
28859   }
28860   self->private_impl.active_coroutine = 0;
28861   wuffs_base__status status = wuffs_base__make_status(NULL);
28862 
28863   wuffs_base__status v_status = wuffs_base__make_status(NULL);
28864 
28865   uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
28866   switch (coro_susp_point) {
28867     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
28868 
28869     while (true) {
28870       {
28871         wuffs_base__status t_0 = wuffs_bmp__decoder__do_decode_frame_config(self, a_dst, a_src);
28872         v_status = t_0;
28873       }
28874       if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
28875         status = wuffs_base__make_status(wuffs_bmp__error__truncated_input);
28876         goto exit;
28877       }
28878       status = v_status;
28879       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
28880     }
28881 
28882     ok:
28883     self->private_impl.p_decode_frame_config[0] = 0;
28884     goto exit;
28885   }
28886 
28887   goto suspend;
28888   suspend:
28889   self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
28890   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
28891 
28892   goto exit;
28893   exit:
28894   if (wuffs_base__status__is_error(&status)) {
28895     self->private_impl.magic = WUFFS_BASE__DISABLED;
28896   }
28897   return status;
28898 }
28899 
28900 // -------- func bmp.decoder.do_decode_frame_config
28901 
28902 WUFFS_BASE__GENERATED_C_CODE
28903 static wuffs_base__status
wuffs_bmp__decoder__do_decode_frame_config(wuffs_bmp__decoder * self,wuffs_base__frame_config * a_dst,wuffs_base__io_buffer * a_src)28904 wuffs_bmp__decoder__do_decode_frame_config(
28905     wuffs_bmp__decoder* self,
28906     wuffs_base__frame_config* a_dst,
28907     wuffs_base__io_buffer* a_src) {
28908   wuffs_base__status status = wuffs_base__make_status(NULL);
28909 
28910   const uint8_t* iop_a_src = NULL;
28911   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
28912   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
28913   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
28914   if (a_src && a_src->data.ptr) {
28915     io0_a_src = a_src->data.ptr;
28916     io1_a_src = io0_a_src + a_src->meta.ri;
28917     iop_a_src = io1_a_src;
28918     io2_a_src = io0_a_src + a_src->meta.wi;
28919   }
28920 
28921   uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config[0];
28922   switch (coro_susp_point) {
28923     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
28924 
28925     if (self->private_impl.f_call_sequence == 32u) {
28926     } else if (self->private_impl.f_call_sequence < 32u) {
28927       if (a_src) {
28928         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
28929       }
28930       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
28931       status = wuffs_bmp__decoder__do_decode_image_config(self, NULL, a_src);
28932       if (a_src) {
28933         iop_a_src = a_src->data.ptr + a_src->meta.ri;
28934       }
28935       if (status.repr) {
28936         goto suspend;
28937       }
28938     } else if (self->private_impl.f_call_sequence == 40u) {
28939       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)))) {
28940         status = wuffs_base__make_status(wuffs_base__error__bad_restart);
28941         goto exit;
28942       }
28943     } else if (self->private_impl.f_call_sequence == 64u) {
28944       self->private_impl.f_call_sequence = 96u;
28945       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
28946       goto ok;
28947     } else {
28948       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
28949       goto ok;
28950     }
28951     if (a_dst != NULL) {
28952       wuffs_base__frame_config__set(
28953           a_dst,
28954           wuffs_base__utility__make_rect_ie_u32(
28955           0u,
28956           0u,
28957           self->private_impl.f_width,
28958           self->private_impl.f_height),
28959           ((wuffs_base__flicks)(0u)),
28960           0u,
28961           self->private_impl.f_frame_config_io_position,
28962           0u,
28963           true,
28964           false,
28965           4278190080u);
28966     }
28967     self->private_impl.f_call_sequence = 64u;
28968 
28969     ok:
28970     self->private_impl.p_do_decode_frame_config[0] = 0;
28971     goto exit;
28972   }
28973 
28974   goto suspend;
28975   suspend:
28976   self->private_impl.p_do_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
28977 
28978   goto exit;
28979   exit:
28980   if (a_src && a_src->data.ptr) {
28981     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
28982   }
28983 
28984   return status;
28985 }
28986 
28987 // -------- func bmp.decoder.decode_frame
28988 
28989 WUFFS_BASE__GENERATED_C_CODE
28990 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_bmp__decoder__decode_frame(wuffs_bmp__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__pixel_blend a_blend,wuffs_base__slice_u8 a_workbuf,wuffs_base__decode_frame_options * a_opts)28991 wuffs_bmp__decoder__decode_frame(
28992     wuffs_bmp__decoder* self,
28993     wuffs_base__pixel_buffer* a_dst,
28994     wuffs_base__io_buffer* a_src,
28995     wuffs_base__pixel_blend a_blend,
28996     wuffs_base__slice_u8 a_workbuf,
28997     wuffs_base__decode_frame_options* a_opts) {
28998   if (!self) {
28999     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
29000   }
29001   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
29002     return wuffs_base__make_status(
29003         (self->private_impl.magic == WUFFS_BASE__DISABLED)
29004         ? wuffs_base__error__disabled_by_previous_error
29005         : wuffs_base__error__initialize_not_called);
29006   }
29007   if (!a_dst || !a_src) {
29008     self->private_impl.magic = WUFFS_BASE__DISABLED;
29009     return wuffs_base__make_status(wuffs_base__error__bad_argument);
29010   }
29011   if ((self->private_impl.active_coroutine != 0) &&
29012       (self->private_impl.active_coroutine != 3)) {
29013     self->private_impl.magic = WUFFS_BASE__DISABLED;
29014     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
29015   }
29016   self->private_impl.active_coroutine = 0;
29017   wuffs_base__status status = wuffs_base__make_status(NULL);
29018 
29019   wuffs_base__status v_status = wuffs_base__make_status(NULL);
29020 
29021   uint32_t coro_susp_point = self->private_impl.p_decode_frame[0];
29022   switch (coro_susp_point) {
29023     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
29024 
29025     while (true) {
29026       {
29027         wuffs_base__status t_0 = wuffs_bmp__decoder__do_decode_frame(self,
29028             a_dst,
29029             a_src,
29030             a_blend,
29031             a_workbuf,
29032             a_opts);
29033         v_status = t_0;
29034       }
29035       if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
29036         status = wuffs_base__make_status(wuffs_bmp__error__truncated_input);
29037         goto exit;
29038       }
29039       status = v_status;
29040       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
29041     }
29042 
29043     ok:
29044     self->private_impl.p_decode_frame[0] = 0;
29045     goto exit;
29046   }
29047 
29048   goto suspend;
29049   suspend:
29050   self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
29051   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
29052 
29053   goto exit;
29054   exit:
29055   if (wuffs_base__status__is_error(&status)) {
29056     self->private_impl.magic = WUFFS_BASE__DISABLED;
29057   }
29058   return status;
29059 }
29060 
29061 // -------- func bmp.decoder.do_decode_frame
29062 
29063 WUFFS_BASE__GENERATED_C_CODE
29064 static wuffs_base__status
wuffs_bmp__decoder__do_decode_frame(wuffs_bmp__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__pixel_blend a_blend,wuffs_base__slice_u8 a_workbuf,wuffs_base__decode_frame_options * a_opts)29065 wuffs_bmp__decoder__do_decode_frame(
29066     wuffs_bmp__decoder* self,
29067     wuffs_base__pixel_buffer* a_dst,
29068     wuffs_base__io_buffer* a_src,
29069     wuffs_base__pixel_blend a_blend,
29070     wuffs_base__slice_u8 a_workbuf,
29071     wuffs_base__decode_frame_options* a_opts) {
29072   wuffs_base__status status = wuffs_base__make_status(NULL);
29073 
29074   wuffs_base__status v_status = wuffs_base__make_status(NULL);
29075 
29076   const uint8_t* iop_a_src = NULL;
29077   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29078   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29079   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29080   if (a_src && a_src->data.ptr) {
29081     io0_a_src = a_src->data.ptr;
29082     io1_a_src = io0_a_src + a_src->meta.ri;
29083     iop_a_src = io1_a_src;
29084     io2_a_src = io0_a_src + a_src->meta.wi;
29085   }
29086 
29087   uint32_t coro_susp_point = self->private_impl.p_do_decode_frame[0];
29088   switch (coro_susp_point) {
29089     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
29090 
29091     if (self->private_impl.f_call_sequence == 64u) {
29092     } else if (self->private_impl.f_call_sequence < 64u) {
29093       if (a_src) {
29094         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
29095       }
29096       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
29097       status = wuffs_bmp__decoder__do_decode_frame_config(self, NULL, a_src);
29098       if (a_src) {
29099         iop_a_src = a_src->data.ptr + a_src->meta.ri;
29100       }
29101       if (status.repr) {
29102         goto suspend;
29103       }
29104     } else {
29105       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
29106       goto ok;
29107     }
29108     self->private_data.s_do_decode_frame[0].scratch = self->private_impl.f_padding;
29109     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
29110     if (self->private_data.s_do_decode_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
29111       self->private_data.s_do_decode_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
29112       iop_a_src = io2_a_src;
29113       status = wuffs_base__make_status(wuffs_base__suspension__short_read);
29114       goto suspend;
29115     }
29116     iop_a_src += self->private_data.s_do_decode_frame[0].scratch;
29117     if ((self->private_impl.f_width > 0u) && (self->private_impl.f_height > 0u)) {
29118       self->private_impl.f_dst_x = 0u;
29119       if (self->private_impl.f_top_down) {
29120         self->private_impl.f_dst_y = 0u;
29121         self->private_impl.f_dst_y_inc = 1u;
29122       } else {
29123         self->private_impl.f_dst_y = ((uint32_t)(self->private_impl.f_height - 1u));
29124         self->private_impl.f_dst_y_inc = 4294967295u;
29125       }
29126       v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
29127           wuffs_base__pixel_buffer__pixel_format(a_dst),
29128           wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8_ij(self->private_data.f_scratch, 1024, 2048)),
29129           wuffs_base__utility__make_pixel_format(self->private_impl.f_src_pixfmt),
29130           wuffs_base__make_slice_u8(self->private_data.f_src_palette, 1024),
29131           a_blend);
29132       if ( ! wuffs_base__status__is_ok(&v_status)) {
29133         status = v_status;
29134         if (wuffs_base__status__is_error(&status)) {
29135           goto exit;
29136         } else if (wuffs_base__status__is_suspension(&status)) {
29137           status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
29138           goto exit;
29139         }
29140         goto ok;
29141       }
29142       while (true) {
29143         if (self->private_impl.f_compression == 0u) {
29144           if (a_src) {
29145             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
29146           }
29147           v_status = wuffs_bmp__decoder__swizzle_none(self, a_dst, a_src);
29148           if (a_src) {
29149             iop_a_src = a_src->data.ptr + a_src->meta.ri;
29150           }
29151         } else if (self->private_impl.f_compression < 3u) {
29152           if (a_src) {
29153             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
29154           }
29155           v_status = wuffs_bmp__decoder__swizzle_rle(self, a_dst, a_src);
29156           if (a_src) {
29157             iop_a_src = a_src->data.ptr + a_src->meta.ri;
29158           }
29159         } else if (self->private_impl.f_compression == 3u) {
29160           if (a_src) {
29161             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
29162           }
29163           v_status = wuffs_bmp__decoder__swizzle_bitfields(self, a_dst, a_src);
29164           if (a_src) {
29165             iop_a_src = a_src->data.ptr + a_src->meta.ri;
29166           }
29167         } else {
29168           if (a_src) {
29169             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
29170           }
29171           v_status = wuffs_bmp__decoder__swizzle_low_bit_depth(self, a_dst, a_src);
29172           if (a_src) {
29173             iop_a_src = a_src->data.ptr + a_src->meta.ri;
29174           }
29175         }
29176         if (wuffs_base__status__is_ok(&v_status)) {
29177           break;
29178         } else if (v_status.repr != wuffs_bmp__note__internal_note_short_read) {
29179           status = v_status;
29180           if (wuffs_base__status__is_error(&status)) {
29181             goto exit;
29182           } else if (wuffs_base__status__is_suspension(&status)) {
29183             status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
29184             goto exit;
29185           }
29186           goto ok;
29187         }
29188         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
29189         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
29190       }
29191       self->private_data.s_do_decode_frame[0].scratch = self->private_impl.f_pending_pad;
29192       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
29193       if (self->private_data.s_do_decode_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
29194         self->private_data.s_do_decode_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
29195         iop_a_src = io2_a_src;
29196         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
29197         goto suspend;
29198       }
29199       iop_a_src += self->private_data.s_do_decode_frame[0].scratch;
29200       self->private_impl.f_pending_pad = 0u;
29201     }
29202     self->private_impl.f_call_sequence = 96u;
29203 
29204     ok:
29205     self->private_impl.p_do_decode_frame[0] = 0;
29206     goto exit;
29207   }
29208 
29209   goto suspend;
29210   suspend:
29211   self->private_impl.p_do_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
29212 
29213   goto exit;
29214   exit:
29215   if (a_src && a_src->data.ptr) {
29216     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
29217   }
29218 
29219   return status;
29220 }
29221 
29222 // -------- func bmp.decoder.swizzle_none
29223 
29224 WUFFS_BASE__GENERATED_C_CODE
29225 static wuffs_base__status
wuffs_bmp__decoder__swizzle_none(wuffs_bmp__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src)29226 wuffs_bmp__decoder__swizzle_none(
29227     wuffs_bmp__decoder* self,
29228     wuffs_base__pixel_buffer* a_dst,
29229     wuffs_base__io_buffer* a_src) {
29230   wuffs_base__status status = wuffs_base__make_status(NULL);
29231 
29232   wuffs_base__pixel_format v_dst_pixfmt = {0};
29233   uint32_t v_dst_bits_per_pixel = 0;
29234   uint32_t v_dst_bytes_per_pixel = 0;
29235   uint64_t v_dst_bytes_per_row = 0;
29236   uint32_t v_src_bytes_per_pixel = 0;
29237   wuffs_base__slice_u8 v_dst_palette = {0};
29238   wuffs_base__table_u8 v_tab = {0};
29239   wuffs_base__slice_u8 v_dst = {0};
29240   uint64_t v_i = 0;
29241   uint64_t v_j = 0;
29242   uint64_t v_n = 0;
29243 
29244   const uint8_t* iop_a_src = NULL;
29245   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29246   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29247   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29248   if (a_src && a_src->data.ptr) {
29249     io0_a_src = a_src->data.ptr;
29250     io1_a_src = io0_a_src + a_src->meta.ri;
29251     iop_a_src = io1_a_src;
29252     io2_a_src = io0_a_src + a_src->meta.wi;
29253   }
29254 
29255   v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
29256   v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
29257   if ((v_dst_bits_per_pixel & 7u) != 0u) {
29258     status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
29259     goto exit;
29260   }
29261   v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u);
29262   v_dst_bytes_per_row = ((uint64_t)((self->private_impl.f_width * v_dst_bytes_per_pixel)));
29263   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));
29264   v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
29265   label__outer__continue:;
29266   while (true) {
29267     while (self->private_impl.f_pending_pad > 0u) {
29268       if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
29269         status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
29270         goto ok;
29271       }
29272       self->private_impl.f_pending_pad -= 1u;
29273       iop_a_src += 1u;
29274     }
29275     while (true) {
29276       if (self->private_impl.f_dst_x == self->private_impl.f_width) {
29277         self->private_impl.f_dst_x = 0u;
29278         self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc;
29279         if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
29280           if (self->private_impl.f_height > 0u) {
29281             self->private_impl.f_pending_pad = self->private_impl.f_pad_per_row;
29282           }
29283           goto label__outer__break;
29284         } else if (self->private_impl.f_pad_per_row != 0u) {
29285           self->private_impl.f_pending_pad = self->private_impl.f_pad_per_row;
29286           goto label__outer__continue;
29287         }
29288       }
29289       v_dst = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
29290       if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) {
29291         v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row);
29292       }
29293       v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_dst_bytes_per_pixel)));
29294       if (v_i >= ((uint64_t)(v_dst.len))) {
29295         if (self->private_impl.f_bits_per_pixel > 32u) {
29296           status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
29297           goto exit;
29298         }
29299         v_src_bytes_per_pixel = (self->private_impl.f_bits_per_pixel / 8u);
29300         if (v_src_bytes_per_pixel == 0u) {
29301           status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
29302           goto exit;
29303         }
29304         v_n = (((uint64_t)(io2_a_src - iop_a_src)) / ((uint64_t)(v_src_bytes_per_pixel)));
29305         v_n = wuffs_base__u64__min(v_n, ((uint64_t)(((uint32_t)(self->private_impl.f_width - self->private_impl.f_dst_x)))));
29306         v_j = v_n;
29307         while (v_j >= 8u) {
29308           if (((uint64_t)(io2_a_src - iop_a_src)) >= ((uint64_t)((v_src_bytes_per_pixel * 8u)))) {
29309             iop_a_src += (v_src_bytes_per_pixel * 8u);
29310           }
29311           v_j -= 8u;
29312         }
29313         while (v_j > 0u) {
29314           if (((uint64_t)(io2_a_src - iop_a_src)) >= ((uint64_t)((v_src_bytes_per_pixel * 1u)))) {
29315             iop_a_src += (v_src_bytes_per_pixel * 1u);
29316           }
29317           v_j -= 1u;
29318         }
29319       } else {
29320         v_n = wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(
29321             &self->private_impl.f_swizzler,
29322             wuffs_base__slice_u8__subslice_i(v_dst, v_i),
29323             v_dst_palette,
29324             &iop_a_src,
29325             io2_a_src);
29326       }
29327       if (v_n == 0u) {
29328         status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
29329         goto ok;
29330       }
29331       wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n)));
29332     }
29333   }
29334   label__outer__break:;
29335   status = wuffs_base__make_status(NULL);
29336   goto ok;
29337 
29338   ok:
29339   goto exit;
29340   exit:
29341   if (a_src && a_src->data.ptr) {
29342     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
29343   }
29344 
29345   return status;
29346 }
29347 
29348 // -------- func bmp.decoder.swizzle_rle
29349 
29350 WUFFS_BASE__GENERATED_C_CODE
29351 static wuffs_base__status
wuffs_bmp__decoder__swizzle_rle(wuffs_bmp__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src)29352 wuffs_bmp__decoder__swizzle_rle(
29353     wuffs_bmp__decoder* self,
29354     wuffs_base__pixel_buffer* a_dst,
29355     wuffs_base__io_buffer* a_src) {
29356   wuffs_base__status status = wuffs_base__make_status(NULL);
29357 
29358   wuffs_base__pixel_format v_dst_pixfmt = {0};
29359   uint32_t v_dst_bits_per_pixel = 0;
29360   uint32_t v_dst_bytes_per_pixel = 0;
29361   uint64_t v_dst_bytes_per_row = 0;
29362   wuffs_base__slice_u8 v_dst_palette = {0};
29363   wuffs_base__table_u8 v_tab = {0};
29364   wuffs_base__slice_u8 v_row = {0};
29365   wuffs_base__slice_u8 v_dst = {0};
29366   uint64_t v_i = 0;
29367   uint64_t v_n = 0;
29368   uint32_t v_p0 = 0;
29369   uint8_t v_code = 0;
29370   uint8_t v_indexes[2] = {0};
29371   uint32_t v_rle_state = 0;
29372   uint32_t v_chunk_bits = 0;
29373   uint32_t v_chunk_count = 0;
29374 
29375   const uint8_t* iop_a_src = NULL;
29376   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29377   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29378   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29379   if (a_src && a_src->data.ptr) {
29380     io0_a_src = a_src->data.ptr;
29381     io1_a_src = io0_a_src + a_src->meta.ri;
29382     iop_a_src = io1_a_src;
29383     io2_a_src = io0_a_src + a_src->meta.wi;
29384   }
29385 
29386   v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
29387   v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
29388   if ((v_dst_bits_per_pixel & 7u) != 0u) {
29389     status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
29390     goto exit;
29391   }
29392   v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u);
29393   v_dst_bytes_per_row = ((uint64_t)((self->private_impl.f_width * v_dst_bytes_per_pixel)));
29394   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));
29395   v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
29396   v_rle_state = self->private_impl.f_rle_state;
29397   label__outer__continue:;
29398   while (true) {
29399     v_row = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
29400     if (v_dst_bytes_per_row < ((uint64_t)(v_row.len))) {
29401       v_row = wuffs_base__slice_u8__subslice_j(v_row, v_dst_bytes_per_row);
29402     }
29403     label__middle__continue:;
29404     while (true) {
29405       v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_dst_bytes_per_pixel)));
29406       if (v_i <= ((uint64_t)(v_row.len))) {
29407         v_dst = wuffs_base__slice_u8__subslice_i(v_row, v_i);
29408       } else {
29409         v_dst = wuffs_base__utility__empty_slice_u8();
29410       }
29411       while (true) {
29412         while (true) {
29413           if (v_rle_state == 0u) {
29414             if (((uint64_t)(io2_a_src - iop_a_src)) < 1u) {
29415               goto label__goto_suspend__break;
29416             }
29417             v_code = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
29418             iop_a_src += 1u;
29419             if (v_code == 0u) {
29420               v_rle_state = 2u;
29421               continue;
29422             }
29423             self->private_impl.f_rle_length = ((uint32_t)(v_code));
29424             v_rle_state = 1u;
29425             continue;
29426           } else if (v_rle_state == 1u) {
29427             if (((uint64_t)(io2_a_src - iop_a_src)) < 1u) {
29428               goto label__goto_suspend__break;
29429             }
29430             v_code = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
29431             iop_a_src += 1u;
29432             if (self->private_impl.f_bits_per_pixel == 8u) {
29433               v_p0 = 0u;
29434               while (v_p0 < self->private_impl.f_rle_length) {
29435                 self->private_data.f_scratch[v_p0] = v_code;
29436                 v_p0 += 1u;
29437               }
29438             } else {
29439               v_indexes[0u] = ((uint8_t)((v_code >> 4u)));
29440               v_indexes[1u] = (v_code & 15u);
29441               v_p0 = 0u;
29442               while (v_p0 < self->private_impl.f_rle_length) {
29443                 self->private_data.f_scratch[(v_p0 + 0u)] = v_indexes[0u];
29444                 self->private_data.f_scratch[(v_p0 + 1u)] = v_indexes[1u];
29445                 v_p0 += 2u;
29446               }
29447             }
29448             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));
29449             wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, self->private_impl.f_rle_length);
29450             v_rle_state = 0u;
29451             goto label__middle__continue;
29452           } else if (v_rle_state == 2u) {
29453             if (((uint64_t)(io2_a_src - iop_a_src)) < 1u) {
29454               goto label__goto_suspend__break;
29455             }
29456             v_code = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
29457             iop_a_src += 1u;
29458             if (v_code < 2u) {
29459               if ((self->private_impl.f_dst_y >= self->private_impl.f_height) && (v_code == 0u)) {
29460                 status = wuffs_base__make_status(wuffs_bmp__error__bad_rle_compression);
29461                 goto exit;
29462               }
29463               wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(&self->private_impl.f_swizzler, v_dst, v_dst_palette, 18446744073709551615u);
29464               self->private_impl.f_dst_x = 0u;
29465               self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc;
29466               if (v_code > 0u) {
29467                 goto label__outer__break;
29468               }
29469               v_rle_state = 0u;
29470               goto label__outer__continue;
29471             } else if (v_code == 2u) {
29472               v_rle_state = 4u;
29473               continue;
29474             }
29475             self->private_impl.f_rle_length = ((uint32_t)(v_code));
29476             self->private_impl.f_rle_padded = ((self->private_impl.f_bits_per_pixel == 8u) && ((v_code & 1u) != 0u));
29477             v_rle_state = 3u;
29478             continue;
29479           } else if (v_rle_state == 3u) {
29480             if (self->private_impl.f_bits_per_pixel == 8u) {
29481               v_n = wuffs_base__pixel_swizzler__limited_swizzle_u32_interleaved_from_reader(
29482                   &self->private_impl.f_swizzler,
29483                   self->private_impl.f_rle_length,
29484                   v_dst,
29485                   v_dst_palette,
29486                   &iop_a_src,
29487                   io2_a_src);
29488               wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n)));
29489               wuffs_base__u32__sat_sub_indirect(&self->private_impl.f_rle_length, ((uint32_t)(v_n)));
29490             } else {
29491               v_chunk_count = ((self->private_impl.f_rle_length + 3u) / 4u);
29492               v_p0 = 0u;
29493               while ((v_chunk_count > 0u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 2u)) {
29494                 v_chunk_bits = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
29495                 iop_a_src += 2u;
29496                 self->private_data.f_scratch[(v_p0 + 0u)] = ((uint8_t)((15u & (v_chunk_bits >> 12u))));
29497                 self->private_data.f_scratch[(v_p0 + 1u)] = ((uint8_t)((15u & (v_chunk_bits >> 8u))));
29498                 self->private_data.f_scratch[(v_p0 + 2u)] = ((uint8_t)((15u & (v_chunk_bits >> 4u))));
29499                 self->private_data.f_scratch[(v_p0 + 3u)] = ((uint8_t)((15u & (v_chunk_bits >> 0u))));
29500                 v_p0 = ((v_p0 & 255u) + 4u);
29501                 v_chunk_count -= 1u;
29502               }
29503               v_p0 = wuffs_base__u32__min(v_p0, self->private_impl.f_rle_length);
29504               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));
29505               wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, v_p0);
29506               wuffs_base__u32__sat_sub_indirect(&self->private_impl.f_rle_length, v_p0);
29507             }
29508             if (self->private_impl.f_rle_length > 0u) {
29509               goto label__goto_suspend__break;
29510             }
29511             if (self->private_impl.f_rle_padded) {
29512               if (((uint64_t)(io2_a_src - iop_a_src)) < 1u) {
29513                 goto label__goto_suspend__break;
29514               }
29515               iop_a_src += 1u;
29516               self->private_impl.f_rle_padded = false;
29517             }
29518             v_rle_state = 0u;
29519             goto label__middle__continue;
29520           } else if (v_rle_state == 4u) {
29521             if (((uint64_t)(io2_a_src - iop_a_src)) < 1u) {
29522               goto label__goto_suspend__break;
29523             }
29524             self->private_impl.f_rle_delta_x = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
29525             iop_a_src += 1u;
29526             v_rle_state = 5u;
29527             continue;
29528           }
29529           if (((uint64_t)(io2_a_src - iop_a_src)) < 1u) {
29530             goto label__goto_suspend__break;
29531           }
29532           v_code = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
29533           iop_a_src += 1u;
29534           if (self->private_impl.f_rle_delta_x > 0u) {
29535             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)));
29536             wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(self->private_impl.f_rle_delta_x)));
29537             self->private_impl.f_rle_delta_x = 0u;
29538             if (self->private_impl.f_dst_x > self->private_impl.f_width) {
29539               status = wuffs_base__make_status(wuffs_bmp__error__bad_rle_compression);
29540               goto exit;
29541             }
29542           }
29543           if (v_code > 0u) {
29544 #if defined(__GNUC__)
29545 #pragma GCC diagnostic push
29546 #pragma GCC diagnostic ignored "-Wconversion"
29547 #endif
29548             v_code -= 1u;
29549 #if defined(__GNUC__)
29550 #pragma GCC diagnostic pop
29551 #endif
29552             while (true) {
29553               self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc;
29554               if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
29555                 status = wuffs_base__make_status(wuffs_bmp__error__bad_rle_compression);
29556                 goto exit;
29557               }
29558               v_row = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
29559               if (v_dst_bytes_per_row < ((uint64_t)(v_row.len))) {
29560                 v_row = wuffs_base__slice_u8__subslice_j(v_row, v_dst_bytes_per_row);
29561               }
29562               if (v_code <= 0u) {
29563                 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)));
29564                 break;
29565               }
29566               wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(&self->private_impl.f_swizzler, v_row, v_dst_palette, 18446744073709551615u);
29567 #if defined(__GNUC__)
29568 #pragma GCC diagnostic push
29569 #pragma GCC diagnostic ignored "-Wconversion"
29570 #endif
29571               v_code -= 1u;
29572 #if defined(__GNUC__)
29573 #pragma GCC diagnostic pop
29574 #endif
29575             }
29576           }
29577           v_rle_state = 0u;
29578           goto label__middle__continue;
29579         }
29580       }
29581       label__goto_suspend__break:;
29582       self->private_impl.f_rle_state = v_rle_state;
29583       status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
29584       goto ok;
29585     }
29586   }
29587   label__outer__break:;
29588   while (self->private_impl.f_dst_y < self->private_impl.f_height) {
29589     v_row = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
29590     if (v_dst_bytes_per_row < ((uint64_t)(v_row.len))) {
29591       v_row = wuffs_base__slice_u8__subslice_j(v_row, v_dst_bytes_per_row);
29592     }
29593     wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(&self->private_impl.f_swizzler, v_row, v_dst_palette, 18446744073709551615u);
29594     self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc;
29595   }
29596   status = wuffs_base__make_status(NULL);
29597   goto ok;
29598 
29599   ok:
29600   goto exit;
29601   exit:
29602   if (a_src && a_src->data.ptr) {
29603     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
29604   }
29605 
29606   return status;
29607 }
29608 
29609 // -------- func bmp.decoder.swizzle_bitfields
29610 
29611 WUFFS_BASE__GENERATED_C_CODE
29612 static wuffs_base__status
wuffs_bmp__decoder__swizzle_bitfields(wuffs_bmp__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src)29613 wuffs_bmp__decoder__swizzle_bitfields(
29614     wuffs_bmp__decoder* self,
29615     wuffs_base__pixel_buffer* a_dst,
29616     wuffs_base__io_buffer* a_src) {
29617   wuffs_base__status status = wuffs_base__make_status(NULL);
29618 
29619   wuffs_base__pixel_format v_dst_pixfmt = {0};
29620   uint32_t v_dst_bits_per_pixel = 0;
29621   uint32_t v_dst_bytes_per_pixel = 0;
29622   uint64_t v_dst_bytes_per_row = 0;
29623   wuffs_base__slice_u8 v_dst_palette = {0};
29624   wuffs_base__table_u8 v_tab = {0};
29625   wuffs_base__slice_u8 v_dst = {0};
29626   uint64_t v_i = 0;
29627   uint64_t v_n = 0;
29628   uint32_t v_p0 = 0;
29629   uint32_t v_p1 = 0;
29630   uint32_t v_p1_temp = 0;
29631   uint32_t v_num_bits = 0;
29632   uint32_t v_c = 0;
29633   uint32_t v_c32 = 0;
29634   uint32_t v_channel = 0;
29635 
29636   const uint8_t* iop_a_src = NULL;
29637   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29638   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29639   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29640   if (a_src && a_src->data.ptr) {
29641     io0_a_src = a_src->data.ptr;
29642     io1_a_src = io0_a_src + a_src->meta.ri;
29643     iop_a_src = io1_a_src;
29644     io2_a_src = io0_a_src + a_src->meta.wi;
29645   }
29646 
29647   v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
29648   v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
29649   if ((v_dst_bits_per_pixel & 7u) != 0u) {
29650     status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
29651     goto exit;
29652   }
29653   v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u);
29654   v_dst_bytes_per_row = ((uint64_t)((self->private_impl.f_width * v_dst_bytes_per_pixel)));
29655   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));
29656   v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
29657   label__outer__continue:;
29658   while (true) {
29659     while (self->private_impl.f_pending_pad > 0u) {
29660       if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
29661         status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
29662         goto ok;
29663       }
29664       self->private_impl.f_pending_pad -= 1u;
29665       iop_a_src += 1u;
29666     }
29667     while (true) {
29668       if (self->private_impl.f_dst_x == self->private_impl.f_width) {
29669         self->private_impl.f_dst_x = 0u;
29670         self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc;
29671         if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
29672           if (self->private_impl.f_height > 0u) {
29673             self->private_impl.f_pending_pad = self->private_impl.f_pad_per_row;
29674           }
29675           goto label__outer__break;
29676         } else if (self->private_impl.f_pad_per_row != 0u) {
29677           self->private_impl.f_pending_pad = self->private_impl.f_pad_per_row;
29678           goto label__outer__continue;
29679         }
29680       }
29681       v_p1_temp = ((uint32_t)(self->private_impl.f_width - self->private_impl.f_dst_x));
29682       v_p1 = wuffs_base__u32__min(v_p1_temp, 256u);
29683       v_p0 = 0u;
29684       while (v_p0 < v_p1) {
29685         if (self->private_impl.f_bits_per_pixel == 16u) {
29686           if (((uint64_t)(io2_a_src - iop_a_src)) < 2u) {
29687             break;
29688           }
29689           v_c32 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
29690           iop_a_src += 2u;
29691         } else {
29692           if (((uint64_t)(io2_a_src - iop_a_src)) < 4u) {
29693             break;
29694           }
29695           v_c32 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
29696           iop_a_src += 4u;
29697         }
29698         v_channel = 0u;
29699         while (v_channel < 4u) {
29700           if (self->private_impl.f_channel_num_bits[v_channel] == 0u) {
29701             self->private_data.f_scratch[((8u * v_p0) + (2u * v_channel) + 0u)] = 255u;
29702             self->private_data.f_scratch[((8u * v_p0) + (2u * v_channel) + 1u)] = 255u;
29703           } else {
29704             v_c = ((v_c32 & self->private_impl.f_channel_masks[v_channel]) >> self->private_impl.f_channel_shifts[v_channel]);
29705             v_num_bits = ((uint32_t)(self->private_impl.f_channel_num_bits[v_channel]));
29706             while (v_num_bits < 16u) {
29707               v_c |= ((uint32_t)(v_c << v_num_bits));
29708               v_num_bits *= 2u;
29709             }
29710             v_c >>= (v_num_bits - 16u);
29711             self->private_data.f_scratch[((8u * v_p0) + (2u * v_channel) + 0u)] = ((uint8_t)((v_c >> 0u)));
29712             self->private_data.f_scratch[((8u * v_p0) + (2u * v_channel) + 1u)] = ((uint8_t)((v_c >> 8u)));
29713           }
29714           v_channel += 1u;
29715         }
29716         v_p0 += 1u;
29717       }
29718       v_dst = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
29719       if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) {
29720         v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row);
29721       }
29722       v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_dst_bytes_per_pixel)));
29723       if (v_i >= ((uint64_t)(v_dst.len))) {
29724         v_n = ((uint64_t)(v_p0));
29725       } else {
29726         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)));
29727       }
29728       if (v_n == 0u) {
29729         status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
29730         goto ok;
29731       }
29732       wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n)));
29733     }
29734   }
29735   label__outer__break:;
29736   status = wuffs_base__make_status(NULL);
29737   goto ok;
29738 
29739   ok:
29740   goto exit;
29741   exit:
29742   if (a_src && a_src->data.ptr) {
29743     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
29744   }
29745 
29746   return status;
29747 }
29748 
29749 // -------- func bmp.decoder.swizzle_low_bit_depth
29750 
29751 WUFFS_BASE__GENERATED_C_CODE
29752 static wuffs_base__status
wuffs_bmp__decoder__swizzle_low_bit_depth(wuffs_bmp__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src)29753 wuffs_bmp__decoder__swizzle_low_bit_depth(
29754     wuffs_bmp__decoder* self,
29755     wuffs_base__pixel_buffer* a_dst,
29756     wuffs_base__io_buffer* a_src) {
29757   wuffs_base__status status = wuffs_base__make_status(NULL);
29758 
29759   wuffs_base__pixel_format v_dst_pixfmt = {0};
29760   uint32_t v_dst_bits_per_pixel = 0;
29761   uint32_t v_dst_bytes_per_pixel = 0;
29762   uint64_t v_dst_bytes_per_row = 0;
29763   wuffs_base__slice_u8 v_dst_palette = {0};
29764   wuffs_base__table_u8 v_tab = {0};
29765   wuffs_base__slice_u8 v_dst = {0};
29766   uint64_t v_i = 0;
29767   uint64_t v_n = 0;
29768   uint32_t v_p0 = 0;
29769   uint32_t v_chunk_bits = 0;
29770   uint32_t v_chunk_count = 0;
29771   uint32_t v_pixels_per_chunk = 0;
29772 
29773   const uint8_t* iop_a_src = NULL;
29774   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29775   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29776   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29777   if (a_src && a_src->data.ptr) {
29778     io0_a_src = a_src->data.ptr;
29779     io1_a_src = io0_a_src + a_src->meta.ri;
29780     iop_a_src = io1_a_src;
29781     io2_a_src = io0_a_src + a_src->meta.wi;
29782   }
29783 
29784   v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
29785   v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
29786   if ((v_dst_bits_per_pixel & 7u) != 0u) {
29787     status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
29788     goto exit;
29789   }
29790   v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u);
29791   v_dst_bytes_per_row = ((uint64_t)((self->private_impl.f_width * v_dst_bytes_per_pixel)));
29792   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));
29793   v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
29794   while (true) {
29795     if (self->private_impl.f_dst_x == self->private_impl.f_width) {
29796       self->private_impl.f_dst_x = 0u;
29797       self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc;
29798       if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
29799         break;
29800       }
29801     }
29802     v_dst = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
29803     if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) {
29804       v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row);
29805     }
29806     v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_dst_bytes_per_pixel)));
29807     if (v_i >= ((uint64_t)(v_dst.len))) {
29808       if (self->private_impl.f_bits_per_pixel == 1u) {
29809         v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 31u) / 32u);
29810         v_pixels_per_chunk = 32u;
29811       } else if (self->private_impl.f_bits_per_pixel == 2u) {
29812         v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 15u) / 16u);
29813         v_pixels_per_chunk = 16u;
29814       } else {
29815         v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 7u) / 8u);
29816         v_pixels_per_chunk = 8u;
29817       }
29818       while ((v_chunk_count >= 64u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 256u)) {
29819         iop_a_src += 256u;
29820         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))));
29821         v_chunk_count -= 64u;
29822       }
29823       while ((v_chunk_count >= 8u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 32u)) {
29824         iop_a_src += 32u;
29825         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))));
29826         v_chunk_count -= 8u;
29827       }
29828       while (v_chunk_count > 0u) {
29829         if (((uint64_t)(io2_a_src - iop_a_src)) < 4u) {
29830           status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
29831           goto ok;
29832         }
29833         iop_a_src += 4u;
29834         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))));
29835         v_chunk_count -= 1u;
29836       }
29837       continue;
29838     }
29839     v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_i);
29840     v_p0 = 0u;
29841     if (self->private_impl.f_bits_per_pixel == 1u) {
29842       v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 31u) / 32u);
29843       v_chunk_count = wuffs_base__u32__min(v_chunk_count, 16u);
29844       while ((v_chunk_count > 0u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 4u)) {
29845         v_chunk_bits = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
29846         iop_a_src += 4u;
29847         self->private_data.f_scratch[(v_p0 + 0u)] = ((uint8_t)((1u & (v_chunk_bits >> 31u))));
29848         self->private_data.f_scratch[(v_p0 + 1u)] = ((uint8_t)((1u & (v_chunk_bits >> 30u))));
29849         self->private_data.f_scratch[(v_p0 + 2u)] = ((uint8_t)((1u & (v_chunk_bits >> 29u))));
29850         self->private_data.f_scratch[(v_p0 + 3u)] = ((uint8_t)((1u & (v_chunk_bits >> 28u))));
29851         self->private_data.f_scratch[(v_p0 + 4u)] = ((uint8_t)((1u & (v_chunk_bits >> 27u))));
29852         self->private_data.f_scratch[(v_p0 + 5u)] = ((uint8_t)((1u & (v_chunk_bits >> 26u))));
29853         self->private_data.f_scratch[(v_p0 + 6u)] = ((uint8_t)((1u & (v_chunk_bits >> 25u))));
29854         self->private_data.f_scratch[(v_p0 + 7u)] = ((uint8_t)((1u & (v_chunk_bits >> 24u))));
29855         self->private_data.f_scratch[(v_p0 + 8u)] = ((uint8_t)((1u & (v_chunk_bits >> 23u))));
29856         self->private_data.f_scratch[(v_p0 + 9u)] = ((uint8_t)((1u & (v_chunk_bits >> 22u))));
29857         self->private_data.f_scratch[(v_p0 + 10u)] = ((uint8_t)((1u & (v_chunk_bits >> 21u))));
29858         self->private_data.f_scratch[(v_p0 + 11u)] = ((uint8_t)((1u & (v_chunk_bits >> 20u))));
29859         self->private_data.f_scratch[(v_p0 + 12u)] = ((uint8_t)((1u & (v_chunk_bits >> 19u))));
29860         self->private_data.f_scratch[(v_p0 + 13u)] = ((uint8_t)((1u & (v_chunk_bits >> 18u))));
29861         self->private_data.f_scratch[(v_p0 + 14u)] = ((uint8_t)((1u & (v_chunk_bits >> 17u))));
29862         self->private_data.f_scratch[(v_p0 + 15u)] = ((uint8_t)((1u & (v_chunk_bits >> 16u))));
29863         self->private_data.f_scratch[(v_p0 + 16u)] = ((uint8_t)((1u & (v_chunk_bits >> 15u))));
29864         self->private_data.f_scratch[(v_p0 + 17u)] = ((uint8_t)((1u & (v_chunk_bits >> 14u))));
29865         self->private_data.f_scratch[(v_p0 + 18u)] = ((uint8_t)((1u & (v_chunk_bits >> 13u))));
29866         self->private_data.f_scratch[(v_p0 + 19u)] = ((uint8_t)((1u & (v_chunk_bits >> 12u))));
29867         self->private_data.f_scratch[(v_p0 + 20u)] = ((uint8_t)((1u & (v_chunk_bits >> 11u))));
29868         self->private_data.f_scratch[(v_p0 + 21u)] = ((uint8_t)((1u & (v_chunk_bits >> 10u))));
29869         self->private_data.f_scratch[(v_p0 + 22u)] = ((uint8_t)((1u & (v_chunk_bits >> 9u))));
29870         self->private_data.f_scratch[(v_p0 + 23u)] = ((uint8_t)((1u & (v_chunk_bits >> 8u))));
29871         self->private_data.f_scratch[(v_p0 + 24u)] = ((uint8_t)((1u & (v_chunk_bits >> 7u))));
29872         self->private_data.f_scratch[(v_p0 + 25u)] = ((uint8_t)((1u & (v_chunk_bits >> 6u))));
29873         self->private_data.f_scratch[(v_p0 + 26u)] = ((uint8_t)((1u & (v_chunk_bits >> 5u))));
29874         self->private_data.f_scratch[(v_p0 + 27u)] = ((uint8_t)((1u & (v_chunk_bits >> 4u))));
29875         self->private_data.f_scratch[(v_p0 + 28u)] = ((uint8_t)((1u & (v_chunk_bits >> 3u))));
29876         self->private_data.f_scratch[(v_p0 + 29u)] = ((uint8_t)((1u & (v_chunk_bits >> 2u))));
29877         self->private_data.f_scratch[(v_p0 + 30u)] = ((uint8_t)((1u & (v_chunk_bits >> 1u))));
29878         self->private_data.f_scratch[(v_p0 + 31u)] = ((uint8_t)((1u & (v_chunk_bits >> 0u))));
29879         v_p0 = ((v_p0 & 511u) + 32u);
29880         v_chunk_count -= 1u;
29881       }
29882     } else if (self->private_impl.f_bits_per_pixel == 2u) {
29883       v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 15u) / 16u);
29884       v_chunk_count = wuffs_base__u32__min(v_chunk_count, 32u);
29885       while ((v_chunk_count > 0u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 4u)) {
29886         v_chunk_bits = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
29887         iop_a_src += 4u;
29888         self->private_data.f_scratch[(v_p0 + 0u)] = ((uint8_t)((3u & (v_chunk_bits >> 30u))));
29889         self->private_data.f_scratch[(v_p0 + 1u)] = ((uint8_t)((3u & (v_chunk_bits >> 28u))));
29890         self->private_data.f_scratch[(v_p0 + 2u)] = ((uint8_t)((3u & (v_chunk_bits >> 26u))));
29891         self->private_data.f_scratch[(v_p0 + 3u)] = ((uint8_t)((3u & (v_chunk_bits >> 24u))));
29892         self->private_data.f_scratch[(v_p0 + 4u)] = ((uint8_t)((3u & (v_chunk_bits >> 22u))));
29893         self->private_data.f_scratch[(v_p0 + 5u)] = ((uint8_t)((3u & (v_chunk_bits >> 20u))));
29894         self->private_data.f_scratch[(v_p0 + 6u)] = ((uint8_t)((3u & (v_chunk_bits >> 18u))));
29895         self->private_data.f_scratch[(v_p0 + 7u)] = ((uint8_t)((3u & (v_chunk_bits >> 16u))));
29896         self->private_data.f_scratch[(v_p0 + 8u)] = ((uint8_t)((3u & (v_chunk_bits >> 14u))));
29897         self->private_data.f_scratch[(v_p0 + 9u)] = ((uint8_t)((3u & (v_chunk_bits >> 12u))));
29898         self->private_data.f_scratch[(v_p0 + 10u)] = ((uint8_t)((3u & (v_chunk_bits >> 10u))));
29899         self->private_data.f_scratch[(v_p0 + 11u)] = ((uint8_t)((3u & (v_chunk_bits >> 8u))));
29900         self->private_data.f_scratch[(v_p0 + 12u)] = ((uint8_t)((3u & (v_chunk_bits >> 6u))));
29901         self->private_data.f_scratch[(v_p0 + 13u)] = ((uint8_t)((3u & (v_chunk_bits >> 4u))));
29902         self->private_data.f_scratch[(v_p0 + 14u)] = ((uint8_t)((3u & (v_chunk_bits >> 2u))));
29903         self->private_data.f_scratch[(v_p0 + 15u)] = ((uint8_t)((3u & (v_chunk_bits >> 0u))));
29904         v_p0 = ((v_p0 & 511u) + 16u);
29905         v_chunk_count -= 1u;
29906       }
29907     } else {
29908       v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 7u) / 8u);
29909       v_chunk_count = wuffs_base__u32__min(v_chunk_count, 64u);
29910       while ((v_chunk_count > 0u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 4u)) {
29911         v_chunk_bits = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
29912         iop_a_src += 4u;
29913         self->private_data.f_scratch[(v_p0 + 0u)] = ((uint8_t)((15u & (v_chunk_bits >> 28u))));
29914         self->private_data.f_scratch[(v_p0 + 1u)] = ((uint8_t)((15u & (v_chunk_bits >> 24u))));
29915         self->private_data.f_scratch[(v_p0 + 2u)] = ((uint8_t)((15u & (v_chunk_bits >> 20u))));
29916         self->private_data.f_scratch[(v_p0 + 3u)] = ((uint8_t)((15u & (v_chunk_bits >> 16u))));
29917         self->private_data.f_scratch[(v_p0 + 4u)] = ((uint8_t)((15u & (v_chunk_bits >> 12u))));
29918         self->private_data.f_scratch[(v_p0 + 5u)] = ((uint8_t)((15u & (v_chunk_bits >> 8u))));
29919         self->private_data.f_scratch[(v_p0 + 6u)] = ((uint8_t)((15u & (v_chunk_bits >> 4u))));
29920         self->private_data.f_scratch[(v_p0 + 7u)] = ((uint8_t)((15u & (v_chunk_bits >> 0u))));
29921         v_p0 = ((v_p0 & 511u) + 8u);
29922         v_chunk_count -= 1u;
29923       }
29924     }
29925     v_p0 = wuffs_base__u32__min(v_p0, wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x));
29926     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));
29927     if (v_n == 0u) {
29928       status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
29929       goto ok;
29930     }
29931     wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n)));
29932   }
29933   status = wuffs_base__make_status(NULL);
29934   goto ok;
29935 
29936   ok:
29937   goto exit;
29938   exit:
29939   if (a_src && a_src->data.ptr) {
29940     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
29941   }
29942 
29943   return status;
29944 }
29945 
29946 // -------- func bmp.decoder.frame_dirty_rect
29947 
29948 WUFFS_BASE__GENERATED_C_CODE
29949 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
wuffs_bmp__decoder__frame_dirty_rect(const wuffs_bmp__decoder * self)29950 wuffs_bmp__decoder__frame_dirty_rect(
29951     const wuffs_bmp__decoder* self) {
29952   if (!self) {
29953     return wuffs_base__utility__empty_rect_ie_u32();
29954   }
29955   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
29956       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
29957     return wuffs_base__utility__empty_rect_ie_u32();
29958   }
29959 
29960   return wuffs_base__utility__make_rect_ie_u32(
29961       0u,
29962       0u,
29963       self->private_impl.f_width,
29964       self->private_impl.f_height);
29965 }
29966 
29967 // -------- func bmp.decoder.num_animation_loops
29968 
29969 WUFFS_BASE__GENERATED_C_CODE
29970 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_bmp__decoder__num_animation_loops(const wuffs_bmp__decoder * self)29971 wuffs_bmp__decoder__num_animation_loops(
29972     const wuffs_bmp__decoder* self) {
29973   if (!self) {
29974     return 0;
29975   }
29976   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
29977       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
29978     return 0;
29979   }
29980 
29981   return 0u;
29982 }
29983 
29984 // -------- func bmp.decoder.num_decoded_frame_configs
29985 
29986 WUFFS_BASE__GENERATED_C_CODE
29987 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_bmp__decoder__num_decoded_frame_configs(const wuffs_bmp__decoder * self)29988 wuffs_bmp__decoder__num_decoded_frame_configs(
29989     const wuffs_bmp__decoder* self) {
29990   if (!self) {
29991     return 0;
29992   }
29993   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
29994       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
29995     return 0;
29996   }
29997 
29998   if (self->private_impl.f_call_sequence > 32u) {
29999     return 1u;
30000   }
30001   return 0u;
30002 }
30003 
30004 // -------- func bmp.decoder.num_decoded_frames
30005 
30006 WUFFS_BASE__GENERATED_C_CODE
30007 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_bmp__decoder__num_decoded_frames(const wuffs_bmp__decoder * self)30008 wuffs_bmp__decoder__num_decoded_frames(
30009     const wuffs_bmp__decoder* self) {
30010   if (!self) {
30011     return 0;
30012   }
30013   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
30014       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
30015     return 0;
30016   }
30017 
30018   if (self->private_impl.f_call_sequence > 64u) {
30019     return 1u;
30020   }
30021   return 0u;
30022 }
30023 
30024 // -------- func bmp.decoder.restart_frame
30025 
30026 WUFFS_BASE__GENERATED_C_CODE
30027 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_bmp__decoder__restart_frame(wuffs_bmp__decoder * self,uint64_t a_index,uint64_t a_io_position)30028 wuffs_bmp__decoder__restart_frame(
30029     wuffs_bmp__decoder* self,
30030     uint64_t a_index,
30031     uint64_t a_io_position) {
30032   if (!self) {
30033     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
30034   }
30035   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
30036     return wuffs_base__make_status(
30037         (self->private_impl.magic == WUFFS_BASE__DISABLED)
30038         ? wuffs_base__error__disabled_by_previous_error
30039         : wuffs_base__error__initialize_not_called);
30040   }
30041 
30042   if (self->private_impl.f_call_sequence < 32u) {
30043     return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
30044   }
30045   if (a_index != 0u) {
30046     return wuffs_base__make_status(wuffs_base__error__bad_argument);
30047   }
30048   self->private_impl.f_call_sequence = 40u;
30049   self->private_impl.f_frame_config_io_position = a_io_position;
30050   return wuffs_base__make_status(NULL);
30051 }
30052 
30053 // -------- func bmp.decoder.set_report_metadata
30054 
30055 WUFFS_BASE__GENERATED_C_CODE
30056 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_bmp__decoder__set_report_metadata(wuffs_bmp__decoder * self,uint32_t a_fourcc,bool a_report)30057 wuffs_bmp__decoder__set_report_metadata(
30058     wuffs_bmp__decoder* self,
30059     uint32_t a_fourcc,
30060     bool a_report) {
30061   return wuffs_base__make_empty_struct();
30062 }
30063 
30064 // -------- func bmp.decoder.tell_me_more
30065 
30066 WUFFS_BASE__GENERATED_C_CODE
30067 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_bmp__decoder__tell_me_more(wuffs_bmp__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__more_information * a_minfo,wuffs_base__io_buffer * a_src)30068 wuffs_bmp__decoder__tell_me_more(
30069     wuffs_bmp__decoder* self,
30070     wuffs_base__io_buffer* a_dst,
30071     wuffs_base__more_information* a_minfo,
30072     wuffs_base__io_buffer* a_src) {
30073   if (!self) {
30074     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
30075   }
30076   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
30077     return wuffs_base__make_status(
30078         (self->private_impl.magic == WUFFS_BASE__DISABLED)
30079         ? wuffs_base__error__disabled_by_previous_error
30080         : wuffs_base__error__initialize_not_called);
30081   }
30082   if (!a_dst || !a_src) {
30083     self->private_impl.magic = WUFFS_BASE__DISABLED;
30084     return wuffs_base__make_status(wuffs_base__error__bad_argument);
30085   }
30086   if ((self->private_impl.active_coroutine != 0) &&
30087       (self->private_impl.active_coroutine != 4)) {
30088     self->private_impl.magic = WUFFS_BASE__DISABLED;
30089     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
30090   }
30091   self->private_impl.active_coroutine = 0;
30092   wuffs_base__status status = wuffs_base__make_status(NULL);
30093 
30094   wuffs_base__status v_status = wuffs_base__make_status(NULL);
30095 
30096   uint32_t coro_susp_point = self->private_impl.p_tell_me_more[0];
30097   switch (coro_susp_point) {
30098     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
30099 
30100     while (true) {
30101       {
30102         wuffs_base__status t_0 = wuffs_bmp__decoder__do_tell_me_more(self, a_dst, a_minfo, a_src);
30103         v_status = t_0;
30104       }
30105       if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
30106         status = wuffs_base__make_status(wuffs_bmp__error__truncated_input);
30107         goto exit;
30108       }
30109       status = v_status;
30110       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
30111     }
30112 
30113     ok:
30114     self->private_impl.p_tell_me_more[0] = 0;
30115     goto exit;
30116   }
30117 
30118   goto suspend;
30119   suspend:
30120   self->private_impl.p_tell_me_more[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
30121   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 4 : 0;
30122 
30123   goto exit;
30124   exit:
30125   if (wuffs_base__status__is_error(&status)) {
30126     self->private_impl.magic = WUFFS_BASE__DISABLED;
30127   }
30128   return status;
30129 }
30130 
30131 // -------- func bmp.decoder.do_tell_me_more
30132 
30133 WUFFS_BASE__GENERATED_C_CODE
30134 static wuffs_base__status
wuffs_bmp__decoder__do_tell_me_more(wuffs_bmp__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__more_information * a_minfo,wuffs_base__io_buffer * a_src)30135 wuffs_bmp__decoder__do_tell_me_more(
30136     wuffs_bmp__decoder* self,
30137     wuffs_base__io_buffer* a_dst,
30138     wuffs_base__more_information* a_minfo,
30139     wuffs_base__io_buffer* a_src) {
30140   wuffs_base__status status = wuffs_base__make_status(NULL);
30141 
30142   if (self->private_impl.f_io_redirect_fourcc <= 1u) {
30143     status = wuffs_base__make_status(wuffs_base__error__no_more_information);
30144     goto exit;
30145   }
30146   if (a_minfo != NULL) {
30147     wuffs_base__more_information__set(a_minfo,
30148         1u,
30149         self->private_impl.f_io_redirect_fourcc,
30150         0u,
30151         self->private_impl.f_io_redirect_pos,
30152         18446744073709551615u);
30153   }
30154   self->private_impl.f_io_redirect_fourcc = 1u;
30155 
30156   goto ok;
30157   ok:
30158   goto exit;
30159   exit:
30160   return status;
30161 }
30162 
30163 // -------- func bmp.decoder.history_retain_length
30164 
30165 WUFFS_BASE__GENERATED_C_CODE
30166 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_bmp__decoder__history_retain_length(const wuffs_bmp__decoder * self)30167 wuffs_bmp__decoder__history_retain_length(
30168     const wuffs_bmp__decoder* self) {
30169   if (!self) {
30170     return 0;
30171   }
30172   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
30173       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
30174     return 0;
30175   }
30176 
30177   return 0u;
30178 }
30179 
30180 // -------- func bmp.decoder.workbuf_len
30181 
30182 WUFFS_BASE__GENERATED_C_CODE
30183 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_bmp__decoder__workbuf_len(const wuffs_bmp__decoder * self)30184 wuffs_bmp__decoder__workbuf_len(
30185     const wuffs_bmp__decoder* self) {
30186   if (!self) {
30187     return wuffs_base__utility__empty_range_ii_u64();
30188   }
30189   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
30190       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
30191     return wuffs_base__utility__empty_range_ii_u64();
30192   }
30193 
30194   return wuffs_base__utility__make_range_ii_u64(0u, 0u);
30195 }
30196 
30197 // -------- func bmp.decoder.read_palette
30198 
30199 WUFFS_BASE__GENERATED_C_CODE
30200 static wuffs_base__status
wuffs_bmp__decoder__read_palette(wuffs_bmp__decoder * self,wuffs_base__io_buffer * a_src)30201 wuffs_bmp__decoder__read_palette(
30202     wuffs_bmp__decoder* self,
30203     wuffs_base__io_buffer* a_src) {
30204   wuffs_base__status status = wuffs_base__make_status(NULL);
30205 
30206   uint32_t v_i = 0;
30207   uint32_t v_argb = 0;
30208 
30209   const uint8_t* iop_a_src = NULL;
30210   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30211   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30212   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30213   if (a_src && a_src->data.ptr) {
30214     io0_a_src = a_src->data.ptr;
30215     io1_a_src = io0_a_src + a_src->meta.ri;
30216     iop_a_src = io1_a_src;
30217     io2_a_src = io0_a_src + a_src->meta.wi;
30218   }
30219 
30220   uint32_t coro_susp_point = self->private_impl.p_read_palette[0];
30221   if (coro_susp_point) {
30222     v_i = self->private_data.s_read_palette[0].v_i;
30223   }
30224   switch (coro_susp_point) {
30225     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
30226 
30227     if (self->private_impl.f_bitmap_info_len == 12u) {
30228       while ((v_i < 256u) && (self->private_impl.f_padding >= 3u)) {
30229         self->private_impl.f_padding -= 3u;
30230         {
30231           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
30232           uint32_t t_0;
30233           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) {
30234             t_0 = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src)));
30235             iop_a_src += 3;
30236           } else {
30237             self->private_data.s_read_palette[0].scratch = 0;
30238             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
30239             while (true) {
30240               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30241                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30242                 goto suspend;
30243               }
30244               uint64_t* scratch = &self->private_data.s_read_palette[0].scratch;
30245               uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
30246               *scratch <<= 8;
30247               *scratch >>= 8;
30248               *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
30249               if (num_bits_0 == 16) {
30250                 t_0 = ((uint32_t)(*scratch));
30251                 break;
30252               }
30253               num_bits_0 += 8u;
30254               *scratch |= ((uint64_t)(num_bits_0)) << 56;
30255             }
30256           }
30257           v_argb = t_0;
30258         }
30259         v_argb |= 4278190080u;
30260         self->private_data.f_src_palette[((4u * v_i) + 0u)] = ((uint8_t)((v_argb >> 0u)));
30261         self->private_data.f_src_palette[((4u * v_i) + 1u)] = ((uint8_t)((v_argb >> 8u)));
30262         self->private_data.f_src_palette[((4u * v_i) + 2u)] = ((uint8_t)((v_argb >> 16u)));
30263         self->private_data.f_src_palette[((4u * v_i) + 3u)] = ((uint8_t)((v_argb >> 24u)));
30264         v_i += 1u;
30265       }
30266     } else {
30267       while ((v_i < 256u) && (self->private_impl.f_padding >= 4u)) {
30268         self->private_impl.f_padding -= 4u;
30269         {
30270           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
30271           uint32_t t_1;
30272           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
30273             t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
30274             iop_a_src += 4;
30275           } else {
30276             self->private_data.s_read_palette[0].scratch = 0;
30277             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
30278             while (true) {
30279               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30280                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30281                 goto suspend;
30282               }
30283               uint64_t* scratch = &self->private_data.s_read_palette[0].scratch;
30284               uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
30285               *scratch <<= 8;
30286               *scratch >>= 8;
30287               *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
30288               if (num_bits_1 == 24) {
30289                 t_1 = ((uint32_t)(*scratch));
30290                 break;
30291               }
30292               num_bits_1 += 8u;
30293               *scratch |= ((uint64_t)(num_bits_1)) << 56;
30294             }
30295           }
30296           v_argb = t_1;
30297         }
30298         v_argb |= 4278190080u;
30299         self->private_data.f_src_palette[((4u * v_i) + 0u)] = ((uint8_t)((v_argb >> 0u)));
30300         self->private_data.f_src_palette[((4u * v_i) + 1u)] = ((uint8_t)((v_argb >> 8u)));
30301         self->private_data.f_src_palette[((4u * v_i) + 2u)] = ((uint8_t)((v_argb >> 16u)));
30302         self->private_data.f_src_palette[((4u * v_i) + 3u)] = ((uint8_t)((v_argb >> 24u)));
30303         v_i += 1u;
30304       }
30305     }
30306     while (v_i < 256u) {
30307       self->private_data.f_src_palette[((4u * v_i) + 0u)] = 0u;
30308       self->private_data.f_src_palette[((4u * v_i) + 1u)] = 0u;
30309       self->private_data.f_src_palette[((4u * v_i) + 2u)] = 0u;
30310       self->private_data.f_src_palette[((4u * v_i) + 3u)] = 255u;
30311       v_i += 1u;
30312     }
30313 
30314     goto ok;
30315     ok:
30316     self->private_impl.p_read_palette[0] = 0;
30317     goto exit;
30318   }
30319 
30320   goto suspend;
30321   suspend:
30322   self->private_impl.p_read_palette[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
30323   self->private_data.s_read_palette[0].v_i = v_i;
30324 
30325   goto exit;
30326   exit:
30327   if (a_src && a_src->data.ptr) {
30328     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30329   }
30330 
30331   return status;
30332 }
30333 
30334 // -------- func bmp.decoder.process_masks
30335 
30336 WUFFS_BASE__GENERATED_C_CODE
30337 static wuffs_base__status
wuffs_bmp__decoder__process_masks(wuffs_bmp__decoder * self)30338 wuffs_bmp__decoder__process_masks(
30339     wuffs_bmp__decoder* self) {
30340   wuffs_base__status status = wuffs_base__make_status(NULL);
30341 
30342   uint32_t v_i = 0;
30343   uint32_t v_mask = 0;
30344   uint32_t v_n = 0;
30345 
30346   while (v_i < 4u) {
30347     v_mask = self->private_impl.f_channel_masks[v_i];
30348     if (v_mask != 0u) {
30349       v_n = 0u;
30350       while ((v_mask & 1u) == 0u) {
30351         v_n += 1u;
30352         v_mask >>= 1u;
30353       }
30354       self->private_impl.f_channel_shifts[v_i] = ((uint8_t)((v_n & 31u)));
30355       v_n = 0u;
30356       while ((v_mask & 1u) == 1u) {
30357         v_n += 1u;
30358         v_mask >>= 1u;
30359       }
30360       if ((v_mask != 0u) || (v_n > 32u)) {
30361         status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
30362         goto exit;
30363       }
30364       self->private_impl.f_channel_num_bits[v_i] = ((uint8_t)(v_n));
30365     } else if (v_i != 3u) {
30366       status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
30367       goto exit;
30368     }
30369     v_i += 1u;
30370   }
30371 
30372   goto ok;
30373   ok:
30374   goto exit;
30375   exit:
30376   return status;
30377 }
30378 
30379 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BMP)
30380 
30381 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BZIP2)
30382 
30383 // ---------------- Status Codes Implementations
30384 
30385 const char wuffs_bzip2__error__bad_huffman_code_over_subscribed[] = "#bzip2: bad Huffman code (over-subscribed)";
30386 const char wuffs_bzip2__error__bad_huffman_code_under_subscribed[] = "#bzip2: bad Huffman code (under-subscribed)";
30387 const char wuffs_bzip2__error__bad_block_header[] = "#bzip2: bad block header";
30388 const char wuffs_bzip2__error__bad_block_length[] = "#bzip2: bad block length";
30389 const char wuffs_bzip2__error__bad_checksum[] = "#bzip2: bad checksum";
30390 const char wuffs_bzip2__error__bad_header[] = "#bzip2: bad header";
30391 const char wuffs_bzip2__error__bad_number_of_sections[] = "#bzip2: bad number of sections";
30392 const char wuffs_bzip2__error__truncated_input[] = "#bzip2: truncated input";
30393 const char wuffs_bzip2__error__unsupported_block_randomization[] = "#bzip2: unsupported block randomization";
30394 const char wuffs_bzip2__error__internal_error_inconsistent_huffman_decoder_state[] = "#bzip2: internal error: inconsistent Huffman decoder state";
30395 
30396 // ---------------- Private Consts
30397 
30398 static const uint8_t
30399 WUFFS_BZIP2__CLAMP_TO_5[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
30400   0, 1, 2, 3, 4, 5, 5, 5,
30401 };
30402 
30403 static const uint32_t
30404 WUFFS_BZIP2__REV_CRC32_TABLE[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
30405   0, 79764919, 159529838, 222504665, 319059676, 398814059, 445009330, 507990021,
30406   638119352, 583659535, 797628118, 726387553, 890018660, 835552979, 1015980042, 944750013,
30407   1276238704, 1221641927, 1167319070, 1095957929, 1595256236, 1540665371, 1452775106, 1381403509,
30408   1780037320, 1859660671, 1671105958, 1733955601, 2031960084, 2111593891, 1889500026, 1952343757,
30409   2552477408, 2632100695, 2443283854, 2506133561, 2334638140, 2414271883, 2191915858, 2254759653,
30410   3190512472, 3135915759, 3081330742, 3009969537, 2905550212, 2850959411, 2762807018, 2691435357,
30411   3560074640, 3505614887, 3719321342, 3648080713, 3342211916, 3287746299, 3467911202, 3396681109,
30412   4063920168, 4143685023, 4223187782, 4286162673, 3779000052, 3858754371, 3904687514, 3967668269,
30413   881225847, 809987520, 1023691545, 969234094, 662832811, 591600412, 771767749, 717299826,
30414   311336399, 374308984, 453813921, 533576470, 25881363, 88864420, 134795389, 214552010,
30415   2023205639, 2086057648, 1897238633, 1976864222, 1804852699, 1867694188, 1645340341, 1724971778,
30416   1587496639, 1516133128, 1461550545, 1406951526, 1302016099, 1230646740, 1142491917, 1087903418,
30417   2896545431, 2825181984, 2770861561, 2716262478, 3215044683, 3143675388, 3055782693, 3001194130,
30418   2326604591, 2389456536, 2200899649, 2280525302, 2578013683, 2640855108, 2418763421, 2498394922,
30419   3769900519, 3832873040, 3912640137, 3992402750, 4088425275, 4151408268, 4197601365, 4277358050,
30420   3334271071, 3263032808, 3476998961, 3422541446, 3585640067, 3514407732, 3694837229, 3640369242,
30421   1762451694, 1842216281, 1619975040, 1682949687, 2047383090, 2127137669, 1938468188, 2001449195,
30422   1325665622, 1271206113, 1183200824, 1111960463, 1543535498, 1489069629, 1434599652, 1363369299,
30423   622672798, 568075817, 748617968, 677256519, 907627842, 853037301, 1067152940, 995781531,
30424   51762726, 131386257, 177728840, 240578815, 269590778, 349224269, 429104020, 491947555,
30425   4046411278, 4126034873, 4172115296, 4234965207, 3794477266, 3874110821, 3953728444, 4016571915,
30426   3609705398, 3555108353, 3735388376, 3664026991, 3290680682, 3236090077, 3449943556, 3378572211,
30427   3174993278, 3120533705, 3032266256, 2961025959, 2923101090, 2868635157, 2813903052, 2742672763,
30428   2604032198, 2683796849, 2461293480, 2524268063, 2284983834, 2364738477, 2175806836, 2238787779,
30429   1569362073, 1498123566, 1409854455, 1355396672, 1317987909, 1246755826, 1192025387, 1137557660,
30430   2072149281, 2135122070, 1912620623, 1992383480, 1753615357, 1816598090, 1627664531, 1707420964,
30431   295390185, 358241886, 404320391, 483945776, 43990325, 106832002, 186451547, 266083308,
30432   932423249, 861060070, 1041341759, 986742920, 613929101, 542559546, 756411363, 701822548,
30433   3316196985, 3244833742, 3425377559, 3370778784, 3601682597, 3530312978, 3744426955, 3689838204,
30434   3819031489, 3881883254, 3928223919, 4007849240, 4037393693, 4100235434, 4180117107, 4259748804,
30435   2310601993, 2373574846, 2151335527, 2231098320, 2596047829, 2659030626, 2470359227, 2550115596,
30436   2947551409, 2876312838, 2788305887, 2733848168, 3165939309, 3094707162, 3040238851, 2985771188,
30437 };
30438 
30439 // ---------------- Private Initializer Prototypes
30440 
30441 // ---------------- Private Function Prototypes
30442 
30443 WUFFS_BASE__GENERATED_C_CODE
30444 static wuffs_base__status
30445 wuffs_bzip2__decoder__do_transform_io(
30446     wuffs_bzip2__decoder* self,
30447     wuffs_base__io_buffer* a_dst,
30448     wuffs_base__io_buffer* a_src,
30449     wuffs_base__slice_u8 a_workbuf);
30450 
30451 WUFFS_BASE__GENERATED_C_CODE
30452 static wuffs_base__status
30453 wuffs_bzip2__decoder__prepare_block(
30454     wuffs_bzip2__decoder* self,
30455     wuffs_base__io_buffer* a_src);
30456 
30457 WUFFS_BASE__GENERATED_C_CODE
30458 static wuffs_base__status
30459 wuffs_bzip2__decoder__read_code_lengths(
30460     wuffs_bzip2__decoder* self,
30461     wuffs_base__io_buffer* a_src);
30462 
30463 WUFFS_BASE__GENERATED_C_CODE
30464 static wuffs_base__status
30465 wuffs_bzip2__decoder__build_huffman_tree(
30466     wuffs_bzip2__decoder* self,
30467     uint32_t a_which);
30468 
30469 WUFFS_BASE__GENERATED_C_CODE
30470 static wuffs_base__empty_struct
30471 wuffs_bzip2__decoder__build_huffman_table(
30472     wuffs_bzip2__decoder* self,
30473     uint32_t a_which);
30474 
30475 WUFFS_BASE__GENERATED_C_CODE
30476 static wuffs_base__empty_struct
30477 wuffs_bzip2__decoder__invert_bwt(
30478     wuffs_bzip2__decoder* self);
30479 
30480 WUFFS_BASE__GENERATED_C_CODE
30481 static wuffs_base__empty_struct
30482 wuffs_bzip2__decoder__flush_fast(
30483     wuffs_bzip2__decoder* self,
30484     wuffs_base__io_buffer* a_dst);
30485 
30486 WUFFS_BASE__GENERATED_C_CODE
30487 static wuffs_base__status
30488 wuffs_bzip2__decoder__flush_slow(
30489     wuffs_bzip2__decoder* self,
30490     wuffs_base__io_buffer* a_dst);
30491 
30492 WUFFS_BASE__GENERATED_C_CODE
30493 static wuffs_base__status
30494 wuffs_bzip2__decoder__decode_huffman_fast(
30495     wuffs_bzip2__decoder* self,
30496     wuffs_base__io_buffer* a_src);
30497 
30498 WUFFS_BASE__GENERATED_C_CODE
30499 static wuffs_base__status
30500 wuffs_bzip2__decoder__decode_huffman_slow(
30501     wuffs_bzip2__decoder* self,
30502     wuffs_base__io_buffer* a_src);
30503 
30504 // ---------------- VTables
30505 
30506 const wuffs_base__io_transformer__func_ptrs
30507 wuffs_bzip2__decoder__func_ptrs_for__wuffs_base__io_transformer = {
30508   (uint64_t(*)(const void*,
30509       uint32_t))(&wuffs_bzip2__decoder__get_quirk),
30510   (uint64_t(*)(const void*))(&wuffs_bzip2__decoder__history_retain_length),
30511   (wuffs_base__status(*)(void*,
30512       uint32_t,
30513       uint64_t))(&wuffs_bzip2__decoder__set_quirk),
30514   (wuffs_base__status(*)(void*,
30515       wuffs_base__io_buffer*,
30516       wuffs_base__io_buffer*,
30517       wuffs_base__slice_u8))(&wuffs_bzip2__decoder__transform_io),
30518   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_bzip2__decoder__workbuf_len),
30519 };
30520 
30521 // ---------------- Initializer Implementations
30522 
30523 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
wuffs_bzip2__decoder__initialize(wuffs_bzip2__decoder * self,size_t sizeof_star_self,uint64_t wuffs_version,uint32_t options)30524 wuffs_bzip2__decoder__initialize(
30525     wuffs_bzip2__decoder* self,
30526     size_t sizeof_star_self,
30527     uint64_t wuffs_version,
30528     uint32_t options){
30529   if (!self) {
30530     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
30531   }
30532   if (sizeof(*self) != sizeof_star_self) {
30533     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
30534   }
30535   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
30536       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
30537     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
30538   }
30539 
30540   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
30541     // The whole point of this if-check is to detect an uninitialized *self.
30542     // We disable the warning on GCC. Clang-5.0 does not have this warning.
30543 #if !defined(__clang__) && defined(__GNUC__)
30544 #pragma GCC diagnostic push
30545 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
30546 #endif
30547     if (self->private_impl.magic != 0) {
30548       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
30549     }
30550 #if !defined(__clang__) && defined(__GNUC__)
30551 #pragma GCC diagnostic pop
30552 #endif
30553   } else {
30554     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
30555       memset(self, 0, sizeof(*self));
30556       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
30557     } else {
30558       memset(&(self->private_impl), 0, sizeof(self->private_impl));
30559     }
30560   }
30561 
30562   self->private_impl.magic = WUFFS_BASE__MAGIC;
30563   self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name =
30564       wuffs_base__io_transformer__vtable_name;
30565   self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers =
30566       (const void*)(&wuffs_bzip2__decoder__func_ptrs_for__wuffs_base__io_transformer);
30567   return wuffs_base__make_status(NULL);
30568 }
30569 
30570 wuffs_bzip2__decoder*
wuffs_bzip2__decoder__alloc(void)30571 wuffs_bzip2__decoder__alloc(void) {
30572   wuffs_bzip2__decoder* x =
30573       (wuffs_bzip2__decoder*)(calloc(sizeof(wuffs_bzip2__decoder), 1));
30574   if (!x) {
30575     return NULL;
30576   }
30577   if (wuffs_bzip2__decoder__initialize(
30578       x, sizeof(wuffs_bzip2__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
30579     free(x);
30580     return NULL;
30581   }
30582   return x;
30583 }
30584 
30585 size_t
sizeof__wuffs_bzip2__decoder(void)30586 sizeof__wuffs_bzip2__decoder(void) {
30587   return sizeof(wuffs_bzip2__decoder);
30588 }
30589 
30590 // ---------------- Function Implementations
30591 
30592 // -------- func bzip2.decoder.get_quirk
30593 
30594 WUFFS_BASE__GENERATED_C_CODE
30595 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_bzip2__decoder__get_quirk(const wuffs_bzip2__decoder * self,uint32_t a_key)30596 wuffs_bzip2__decoder__get_quirk(
30597     const wuffs_bzip2__decoder* self,
30598     uint32_t a_key) {
30599   if (!self) {
30600     return 0;
30601   }
30602   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
30603       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
30604     return 0;
30605   }
30606 
30607   return 0u;
30608 }
30609 
30610 // -------- func bzip2.decoder.set_quirk
30611 
30612 WUFFS_BASE__GENERATED_C_CODE
30613 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_bzip2__decoder__set_quirk(wuffs_bzip2__decoder * self,uint32_t a_key,uint64_t a_value)30614 wuffs_bzip2__decoder__set_quirk(
30615     wuffs_bzip2__decoder* self,
30616     uint32_t a_key,
30617     uint64_t a_value) {
30618   if (!self) {
30619     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
30620   }
30621   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
30622     return wuffs_base__make_status(
30623         (self->private_impl.magic == WUFFS_BASE__DISABLED)
30624         ? wuffs_base__error__disabled_by_previous_error
30625         : wuffs_base__error__initialize_not_called);
30626   }
30627 
30628   if (a_key == 1u) {
30629     self->private_impl.f_ignore_checksum = (a_value > 0u);
30630     return wuffs_base__make_status(NULL);
30631   }
30632   return wuffs_base__make_status(wuffs_base__error__unsupported_option);
30633 }
30634 
30635 // -------- func bzip2.decoder.history_retain_length
30636 
30637 WUFFS_BASE__GENERATED_C_CODE
30638 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_bzip2__decoder__history_retain_length(const wuffs_bzip2__decoder * self)30639 wuffs_bzip2__decoder__history_retain_length(
30640     const wuffs_bzip2__decoder* self) {
30641   if (!self) {
30642     return 0;
30643   }
30644   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
30645       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
30646     return 0;
30647   }
30648 
30649   return 0u;
30650 }
30651 
30652 // -------- func bzip2.decoder.workbuf_len
30653 
30654 WUFFS_BASE__GENERATED_C_CODE
30655 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_bzip2__decoder__workbuf_len(const wuffs_bzip2__decoder * self)30656 wuffs_bzip2__decoder__workbuf_len(
30657     const wuffs_bzip2__decoder* self) {
30658   if (!self) {
30659     return wuffs_base__utility__empty_range_ii_u64();
30660   }
30661   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
30662       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
30663     return wuffs_base__utility__empty_range_ii_u64();
30664   }
30665 
30666   return wuffs_base__utility__make_range_ii_u64(0u, 0u);
30667 }
30668 
30669 // -------- func bzip2.decoder.transform_io
30670 
30671 WUFFS_BASE__GENERATED_C_CODE
30672 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_bzip2__decoder__transform_io(wuffs_bzip2__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__slice_u8 a_workbuf)30673 wuffs_bzip2__decoder__transform_io(
30674     wuffs_bzip2__decoder* self,
30675     wuffs_base__io_buffer* a_dst,
30676     wuffs_base__io_buffer* a_src,
30677     wuffs_base__slice_u8 a_workbuf) {
30678   if (!self) {
30679     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
30680   }
30681   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
30682     return wuffs_base__make_status(
30683         (self->private_impl.magic == WUFFS_BASE__DISABLED)
30684         ? wuffs_base__error__disabled_by_previous_error
30685         : wuffs_base__error__initialize_not_called);
30686   }
30687   if (!a_dst || !a_src) {
30688     self->private_impl.magic = WUFFS_BASE__DISABLED;
30689     return wuffs_base__make_status(wuffs_base__error__bad_argument);
30690   }
30691   if ((self->private_impl.active_coroutine != 0) &&
30692       (self->private_impl.active_coroutine != 1)) {
30693     self->private_impl.magic = WUFFS_BASE__DISABLED;
30694     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
30695   }
30696   self->private_impl.active_coroutine = 0;
30697   wuffs_base__status status = wuffs_base__make_status(NULL);
30698 
30699   wuffs_base__status v_status = wuffs_base__make_status(NULL);
30700 
30701   uint32_t coro_susp_point = self->private_impl.p_transform_io[0];
30702   switch (coro_susp_point) {
30703     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
30704 
30705     while (true) {
30706       {
30707         wuffs_base__status t_0 = wuffs_bzip2__decoder__do_transform_io(self, a_dst, a_src, a_workbuf);
30708         v_status = t_0;
30709       }
30710       if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
30711         status = wuffs_base__make_status(wuffs_bzip2__error__truncated_input);
30712         goto exit;
30713       }
30714       status = v_status;
30715       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
30716     }
30717 
30718     ok:
30719     self->private_impl.p_transform_io[0] = 0;
30720     goto exit;
30721   }
30722 
30723   goto suspend;
30724   suspend:
30725   self->private_impl.p_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
30726   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
30727 
30728   goto exit;
30729   exit:
30730   if (wuffs_base__status__is_error(&status)) {
30731     self->private_impl.magic = WUFFS_BASE__DISABLED;
30732   }
30733   return status;
30734 }
30735 
30736 // -------- func bzip2.decoder.do_transform_io
30737 
30738 WUFFS_BASE__GENERATED_C_CODE
30739 static wuffs_base__status
wuffs_bzip2__decoder__do_transform_io(wuffs_bzip2__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__slice_u8 a_workbuf)30740 wuffs_bzip2__decoder__do_transform_io(
30741     wuffs_bzip2__decoder* self,
30742     wuffs_base__io_buffer* a_dst,
30743     wuffs_base__io_buffer* a_src,
30744     wuffs_base__slice_u8 a_workbuf) {
30745   wuffs_base__status status = wuffs_base__make_status(NULL);
30746 
30747   uint8_t v_c = 0;
30748   uint32_t v_i = 0;
30749   uint64_t v_tag = 0;
30750   wuffs_base__status v_status = wuffs_base__make_status(NULL);
30751   uint32_t v_final_checksum_want = 0;
30752 
30753   const uint8_t* iop_a_src = NULL;
30754   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30755   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30756   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30757   if (a_src && a_src->data.ptr) {
30758     io0_a_src = a_src->data.ptr;
30759     io1_a_src = io0_a_src + a_src->meta.ri;
30760     iop_a_src = io1_a_src;
30761     io2_a_src = io0_a_src + a_src->meta.wi;
30762   }
30763 
30764   uint32_t coro_susp_point = self->private_impl.p_do_transform_io[0];
30765   if (coro_susp_point) {
30766     v_i = self->private_data.s_do_transform_io[0].v_i;
30767     v_tag = self->private_data.s_do_transform_io[0].v_tag;
30768     v_final_checksum_want = self->private_data.s_do_transform_io[0].v_final_checksum_want;
30769   }
30770   switch (coro_susp_point) {
30771     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
30772 
30773     {
30774       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
30775       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30776         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30777         goto suspend;
30778       }
30779       uint8_t t_0 = *iop_a_src++;
30780       v_c = t_0;
30781     }
30782     if (v_c != 66u) {
30783       status = wuffs_base__make_status(wuffs_bzip2__error__bad_header);
30784       goto exit;
30785     }
30786     {
30787       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
30788       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30789         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30790         goto suspend;
30791       }
30792       uint8_t t_1 = *iop_a_src++;
30793       v_c = t_1;
30794     }
30795     if (v_c != 90u) {
30796       status = wuffs_base__make_status(wuffs_bzip2__error__bad_header);
30797       goto exit;
30798     }
30799     {
30800       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
30801       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30802         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30803         goto suspend;
30804       }
30805       uint8_t t_2 = *iop_a_src++;
30806       v_c = t_2;
30807     }
30808     if (v_c != 104u) {
30809       status = wuffs_base__make_status(wuffs_bzip2__error__bad_header);
30810       goto exit;
30811     }
30812     {
30813       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
30814       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30815         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30816         goto suspend;
30817       }
30818       uint8_t t_3 = *iop_a_src++;
30819       v_c = t_3;
30820     }
30821     if ((v_c < 49u) || (57u < v_c)) {
30822       status = wuffs_base__make_status(wuffs_bzip2__error__bad_header);
30823       goto exit;
30824     }
30825     self->private_impl.f_max_incl_block_size = (((uint32_t)((v_c - 48u))) * 100000u);
30826     while (true) {
30827       v_tag = 0u;
30828       v_i = 0u;
30829       while (v_i < 48u) {
30830         if (self->private_impl.f_n_bits <= 0u) {
30831           {
30832             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
30833             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30834               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30835               goto suspend;
30836             }
30837             uint8_t t_4 = *iop_a_src++;
30838             v_c = t_4;
30839           }
30840           self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u);
30841           self->private_impl.f_n_bits = 8u;
30842         }
30843         v_tag <<= 1u;
30844         v_tag |= ((uint64_t)((self->private_impl.f_bits >> 31u)));
30845         self->private_impl.f_bits <<= 1u;
30846         self->private_impl.f_n_bits -= 1u;
30847         v_i += 1u;
30848       }
30849       if (v_tag == 25779555029136u) {
30850         break;
30851       } else if (v_tag != 54156738319193u) {
30852         status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_header);
30853         goto exit;
30854       }
30855       if (a_src) {
30856         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30857       }
30858       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
30859       status = wuffs_bzip2__decoder__prepare_block(self, a_src);
30860       if (a_src) {
30861         iop_a_src = a_src->data.ptr + a_src->meta.ri;
30862       }
30863       if (status.repr) {
30864         goto suspend;
30865       }
30866       self->private_impl.f_block_size = 0u;
30867       self->private_impl.f_decode_huffman_finished = false;
30868       self->private_impl.f_decode_huffman_which = WUFFS_BZIP2__CLAMP_TO_5[(self->private_data.f_huffman_selectors[0u] & 7u)];
30869       self->private_impl.f_decode_huffman_ticks = 50u;
30870       self->private_impl.f_decode_huffman_section = 0u;
30871       self->private_impl.f_decode_huffman_run_shift = 0u;
30872       while ( ! self->private_impl.f_decode_huffman_finished) {
30873         if (a_src) {
30874           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30875         }
30876         v_status = wuffs_bzip2__decoder__decode_huffman_fast(self, a_src);
30877         if (a_src) {
30878           iop_a_src = a_src->data.ptr + a_src->meta.ri;
30879         }
30880         if (wuffs_base__status__is_error(&v_status)) {
30881           status = v_status;
30882           goto exit;
30883         } else if (self->private_impl.f_decode_huffman_finished) {
30884           break;
30885         }
30886         if (a_src) {
30887           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30888         }
30889         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
30890         status = wuffs_bzip2__decoder__decode_huffman_slow(self, a_src);
30891         if (a_src) {
30892           iop_a_src = a_src->data.ptr + a_src->meta.ri;
30893         }
30894         if (status.repr) {
30895           goto suspend;
30896         }
30897       }
30898       wuffs_bzip2__decoder__invert_bwt(self);
30899       self->private_impl.f_block_checksum_have = 4294967295u;
30900       if (self->private_impl.f_original_pointer >= self->private_impl.f_block_size) {
30901         status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_length);
30902         goto exit;
30903       }
30904       self->private_impl.f_flush_pointer = (self->private_data.f_bwt[self->private_impl.f_original_pointer] >> 12u);
30905       self->private_impl.f_flush_repeat_count = 0u;
30906       self->private_impl.f_flush_prev = 0u;
30907       while (self->private_impl.f_block_size > 0u) {
30908         wuffs_bzip2__decoder__flush_fast(self, a_dst);
30909         if (self->private_impl.f_block_size <= 0u) {
30910           break;
30911         }
30912         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
30913         status = wuffs_bzip2__decoder__flush_slow(self, a_dst);
30914         if (status.repr) {
30915           goto suspend;
30916         }
30917       }
30918       self->private_impl.f_block_checksum_have ^= 4294967295u;
30919       if ( ! self->private_impl.f_ignore_checksum && (self->private_impl.f_block_checksum_have != self->private_impl.f_block_checksum_want)) {
30920         status = wuffs_base__make_status(wuffs_bzip2__error__bad_checksum);
30921         goto exit;
30922       }
30923       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))));
30924     }
30925     v_final_checksum_want = 0u;
30926     v_i = 0u;
30927     while (v_i < 32u) {
30928       if (self->private_impl.f_n_bits <= 0u) {
30929         {
30930           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
30931           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30932             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30933             goto suspend;
30934           }
30935           uint8_t t_5 = *iop_a_src++;
30936           v_c = t_5;
30937         }
30938         self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u);
30939         self->private_impl.f_n_bits = 8u;
30940       }
30941       v_final_checksum_want <<= 1u;
30942       v_final_checksum_want |= (self->private_impl.f_bits >> 31u);
30943       self->private_impl.f_bits <<= 1u;
30944       self->private_impl.f_n_bits -= 1u;
30945       v_i += 1u;
30946     }
30947     if ( ! self->private_impl.f_ignore_checksum && (self->private_impl.f_final_checksum_have != v_final_checksum_want)) {
30948       status = wuffs_base__make_status(wuffs_bzip2__error__bad_checksum);
30949       goto exit;
30950     }
30951 
30952     goto ok;
30953     ok:
30954     self->private_impl.p_do_transform_io[0] = 0;
30955     goto exit;
30956   }
30957 
30958   goto suspend;
30959   suspend:
30960   self->private_impl.p_do_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
30961   self->private_data.s_do_transform_io[0].v_i = v_i;
30962   self->private_data.s_do_transform_io[0].v_tag = v_tag;
30963   self->private_data.s_do_transform_io[0].v_final_checksum_want = v_final_checksum_want;
30964 
30965   goto exit;
30966   exit:
30967   if (a_src && a_src->data.ptr) {
30968     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30969   }
30970 
30971   return status;
30972 }
30973 
30974 // -------- func bzip2.decoder.prepare_block
30975 
30976 WUFFS_BASE__GENERATED_C_CODE
30977 static wuffs_base__status
wuffs_bzip2__decoder__prepare_block(wuffs_bzip2__decoder * self,wuffs_base__io_buffer * a_src)30978 wuffs_bzip2__decoder__prepare_block(
30979     wuffs_bzip2__decoder* self,
30980     wuffs_base__io_buffer* a_src) {
30981   wuffs_base__status status = wuffs_base__make_status(NULL);
30982 
30983   uint8_t v_c = 0;
30984   uint32_t v_i = 0;
30985   uint32_t v_j = 0;
30986   uint32_t v_selector = 0;
30987   uint32_t v_sel_ff = 0;
30988   uint8_t v_movee = 0;
30989   wuffs_base__status v_status = wuffs_base__make_status(NULL);
30990 
30991   const uint8_t* iop_a_src = NULL;
30992   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30993   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30994   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30995   if (a_src && a_src->data.ptr) {
30996     io0_a_src = a_src->data.ptr;
30997     io1_a_src = io0_a_src + a_src->meta.ri;
30998     iop_a_src = io1_a_src;
30999     io2_a_src = io0_a_src + a_src->meta.wi;
31000   }
31001 
31002   uint32_t coro_susp_point = self->private_impl.p_prepare_block[0];
31003   if (coro_susp_point) {
31004     v_i = self->private_data.s_prepare_block[0].v_i;
31005     v_selector = self->private_data.s_prepare_block[0].v_selector;
31006   }
31007   switch (coro_susp_point) {
31008     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
31009 
31010     self->private_impl.f_block_checksum_want = 0u;
31011     v_i = 0u;
31012     while (v_i < 32u) {
31013       if (self->private_impl.f_n_bits <= 0u) {
31014         {
31015           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
31016           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31017             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31018             goto suspend;
31019           }
31020           uint8_t t_0 = *iop_a_src++;
31021           v_c = t_0;
31022         }
31023         self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u);
31024         self->private_impl.f_n_bits = 8u;
31025       }
31026       self->private_impl.f_block_checksum_want <<= 1u;
31027       self->private_impl.f_block_checksum_want |= (self->private_impl.f_bits >> 31u);
31028       self->private_impl.f_bits <<= 1u;
31029       self->private_impl.f_n_bits -= 1u;
31030       v_i += 1u;
31031     }
31032     if (self->private_impl.f_n_bits <= 0u) {
31033       {
31034         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
31035         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31036           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31037           goto suspend;
31038         }
31039         uint8_t t_1 = *iop_a_src++;
31040         v_c = t_1;
31041       }
31042       self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u);
31043       self->private_impl.f_n_bits = 8u;
31044     }
31045     if ((self->private_impl.f_bits >> 31u) != 0u) {
31046       status = wuffs_base__make_status(wuffs_bzip2__error__unsupported_block_randomization);
31047       goto exit;
31048     }
31049     self->private_impl.f_bits <<= 1u;
31050     self->private_impl.f_n_bits -= 1u;
31051     self->private_impl.f_original_pointer = 0u;
31052     v_i = 0u;
31053     while (v_i < 24u) {
31054       if (self->private_impl.f_n_bits <= 0u) {
31055         {
31056           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
31057           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31058             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31059             goto suspend;
31060           }
31061           uint8_t t_2 = *iop_a_src++;
31062           v_c = t_2;
31063         }
31064         self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u);
31065         self->private_impl.f_n_bits = 8u;
31066       }
31067       self->private_impl.f_original_pointer <<= 1u;
31068       self->private_impl.f_original_pointer |= (self->private_impl.f_bits >> 31u);
31069       self->private_impl.f_bits <<= 1u;
31070       self->private_impl.f_n_bits -= 1u;
31071       v_i += 1u;
31072     }
31073     v_i = 0u;
31074     while (v_i < 256u) {
31075       self->private_data.f_presence[v_i] = 0u;
31076       v_i += 1u;
31077     }
31078     v_i = 0u;
31079     while (v_i < 256u) {
31080       if (self->private_impl.f_n_bits <= 0u) {
31081         {
31082           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
31083           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31084             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31085             goto suspend;
31086           }
31087           uint8_t t_3 = *iop_a_src++;
31088           v_c = t_3;
31089         }
31090         self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u);
31091         self->private_impl.f_n_bits = 8u;
31092       }
31093       if ((self->private_impl.f_bits >> 31u) != 0u) {
31094         self->private_data.f_presence[v_i] = 1u;
31095       }
31096       self->private_impl.f_bits <<= 1u;
31097       self->private_impl.f_n_bits -= 1u;
31098       v_i += 16u;
31099     }
31100     self->private_data.f_scratch = 0u;
31101     v_i = 0u;
31102     while (v_i < 256u) {
31103       if (self->private_data.f_presence[v_i] == 0u) {
31104         v_i += 16u;
31105         continue;
31106       }
31107       while (true) {
31108         if (self->private_impl.f_n_bits <= 0u) {
31109           {
31110             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
31111             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31112               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31113               goto suspend;
31114             }
31115             uint8_t t_4 = *iop_a_src++;
31116             v_c = t_4;
31117           }
31118           self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u);
31119           self->private_impl.f_n_bits = 8u;
31120         }
31121         self->private_data.f_scratch += (self->private_impl.f_bits >> 31u);
31122         self->private_data.f_presence[(v_i & 255u)] = ((uint8_t)((self->private_impl.f_bits >> 31u)));
31123         self->private_impl.f_bits <<= 1u;
31124         self->private_impl.f_n_bits -= 1u;
31125         v_i += 1u;
31126         if ((v_i & 15u) == 0u) {
31127           break;
31128         }
31129       }
31130     }
31131     if ((self->private_data.f_scratch < 1u) || (256u < self->private_data.f_scratch)) {
31132       status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_header);
31133       goto exit;
31134     }
31135     self->private_impl.f_num_symbols = (self->private_data.f_scratch + 2u);
31136     self->private_data.f_scratch = 0u;
31137     v_i = 0u;
31138     while (v_i < 3u) {
31139       if (self->private_impl.f_n_bits <= 0u) {
31140         {
31141           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
31142           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31143             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31144             goto suspend;
31145           }
31146           uint8_t t_5 = *iop_a_src++;
31147           v_c = t_5;
31148         }
31149         self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u);
31150         self->private_impl.f_n_bits = 8u;
31151       }
31152       self->private_data.f_scratch <<= 1u;
31153       self->private_data.f_scratch |= (self->private_impl.f_bits >> 31u);
31154       self->private_impl.f_bits <<= 1u;
31155       self->private_impl.f_n_bits -= 1u;
31156       v_i += 1u;
31157     }
31158     if ((self->private_data.f_scratch < 2u) || (6u < self->private_data.f_scratch)) {
31159       status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_header);
31160       goto exit;
31161     }
31162     self->private_impl.f_num_huffman_codes = self->private_data.f_scratch;
31163     self->private_data.f_scratch = 0u;
31164     v_i = 0u;
31165     while (v_i < 15u) {
31166       if (self->private_impl.f_n_bits <= 0u) {
31167         {
31168           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
31169           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31170             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31171             goto suspend;
31172           }
31173           uint8_t t_6 = *iop_a_src++;
31174           v_c = t_6;
31175         }
31176         self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u);
31177         self->private_impl.f_n_bits = 8u;
31178       }
31179       self->private_data.f_scratch <<= 1u;
31180       self->private_data.f_scratch |= (self->private_impl.f_bits >> 31u);
31181       self->private_impl.f_bits <<= 1u;
31182       self->private_impl.f_n_bits -= 1u;
31183       v_i += 1u;
31184     }
31185     if ((self->private_data.f_scratch < 1u) || (18001u < self->private_data.f_scratch)) {
31186       status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_header);
31187       goto exit;
31188     }
31189     self->private_impl.f_num_sections = self->private_data.f_scratch;
31190     v_i = 0u;
31191     while (v_i < self->private_impl.f_num_huffman_codes) {
31192       self->private_data.f_mtft[v_i] = ((uint8_t)(v_i));
31193       v_i += 1u;
31194     }
31195     v_i = 0u;
31196     while (v_i < self->private_impl.f_num_sections) {
31197       v_selector = 0u;
31198       while (true) {
31199         if (self->private_impl.f_n_bits <= 0u) {
31200           {
31201             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
31202             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31203               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31204               goto suspend;
31205             }
31206             uint8_t t_7 = *iop_a_src++;
31207             v_c = t_7;
31208           }
31209           self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u);
31210           self->private_impl.f_n_bits = 8u;
31211         }
31212         if ((self->private_impl.f_bits >> 31u) == 0u) {
31213           self->private_impl.f_bits <<= 1u;
31214           self->private_impl.f_n_bits -= 1u;
31215           break;
31216         }
31217         self->private_impl.f_bits <<= 1u;
31218         self->private_impl.f_n_bits -= 1u;
31219         v_selector += 1u;
31220         if (v_selector >= self->private_impl.f_num_huffman_codes) {
31221           status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_header);
31222           goto exit;
31223         }
31224       }
31225       if (v_selector == 0u) {
31226         self->private_data.f_huffman_selectors[v_i] = self->private_data.f_mtft[0u];
31227       } else {
31228         v_sel_ff = (v_selector & 255u);
31229         v_movee = self->private_data.f_mtft[v_sel_ff];
31230         wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8_ij(self->private_data.f_mtft, 1, (1u + v_sel_ff)), wuffs_base__make_slice_u8(self->private_data.f_mtft, v_sel_ff));
31231         self->private_data.f_mtft[0u] = v_movee;
31232         self->private_data.f_huffman_selectors[v_i] = v_movee;
31233       }
31234       v_i += 1u;
31235     }
31236     v_i = 0u;
31237     while (v_i < self->private_impl.f_num_huffman_codes) {
31238       if (a_src) {
31239         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
31240       }
31241       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
31242       status = wuffs_bzip2__decoder__read_code_lengths(self, a_src);
31243       if (a_src) {
31244         iop_a_src = a_src->data.ptr + a_src->meta.ri;
31245       }
31246       if (status.repr) {
31247         goto suspend;
31248       }
31249       v_status = wuffs_bzip2__decoder__build_huffman_tree(self, v_i);
31250       if (wuffs_base__status__is_error(&v_status)) {
31251         status = v_status;
31252         goto exit;
31253       }
31254       wuffs_bzip2__decoder__build_huffman_table(self, v_i);
31255       v_i += 1u;
31256     }
31257     v_i = 0u;
31258     v_j = 0u;
31259     while (v_i < 256u) {
31260       if (self->private_data.f_presence[v_i] != 0u) {
31261         self->private_data.f_mtft[(v_j & 255u)] = ((uint8_t)(v_i));
31262         v_j += 1u;
31263       }
31264       v_i += 1u;
31265     }
31266     v_i = 0u;
31267     while (v_i < 256u) {
31268       self->private_data.f_letter_counts[v_i] = 0u;
31269       v_i += 1u;
31270     }
31271 
31272     goto ok;
31273     ok:
31274     self->private_impl.p_prepare_block[0] = 0;
31275     goto exit;
31276   }
31277 
31278   goto suspend;
31279   suspend:
31280   self->private_impl.p_prepare_block[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
31281   self->private_data.s_prepare_block[0].v_i = v_i;
31282   self->private_data.s_prepare_block[0].v_selector = v_selector;
31283 
31284   goto exit;
31285   exit:
31286   if (a_src && a_src->data.ptr) {
31287     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
31288   }
31289 
31290   return status;
31291 }
31292 
31293 // -------- func bzip2.decoder.read_code_lengths
31294 
31295 WUFFS_BASE__GENERATED_C_CODE
31296 static wuffs_base__status
wuffs_bzip2__decoder__read_code_lengths(wuffs_bzip2__decoder * self,wuffs_base__io_buffer * a_src)31297 wuffs_bzip2__decoder__read_code_lengths(
31298     wuffs_bzip2__decoder* self,
31299     wuffs_base__io_buffer* a_src) {
31300   wuffs_base__status status = wuffs_base__make_status(NULL);
31301 
31302   uint8_t v_c = 0;
31303   uint32_t v_i = 0;
31304   uint32_t v_code_length = 0;
31305 
31306   const uint8_t* iop_a_src = NULL;
31307   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31308   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31309   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31310   if (a_src && a_src->data.ptr) {
31311     io0_a_src = a_src->data.ptr;
31312     io1_a_src = io0_a_src + a_src->meta.ri;
31313     iop_a_src = io1_a_src;
31314     io2_a_src = io0_a_src + a_src->meta.wi;
31315   }
31316 
31317   uint32_t coro_susp_point = self->private_impl.p_read_code_lengths[0];
31318   if (coro_susp_point) {
31319     v_i = self->private_data.s_read_code_lengths[0].v_i;
31320     v_code_length = self->private_data.s_read_code_lengths[0].v_code_length;
31321   }
31322   switch (coro_susp_point) {
31323     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
31324 
31325     self->private_impl.f_code_lengths_bitmask = 0u;
31326     v_i = 0u;
31327     while (v_i < 5u) {
31328       if (self->private_impl.f_n_bits <= 0u) {
31329         {
31330           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
31331           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31332             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31333             goto suspend;
31334           }
31335           uint8_t t_0 = *iop_a_src++;
31336           v_c = t_0;
31337         }
31338         self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u);
31339         self->private_impl.f_n_bits = 8u;
31340       }
31341       v_code_length <<= 1u;
31342       v_code_length |= (self->private_impl.f_bits >> 31u);
31343       self->private_impl.f_bits <<= 1u;
31344       self->private_impl.f_n_bits -= 1u;
31345       v_i += 1u;
31346     }
31347     v_i = 0u;
31348     while (v_i < self->private_impl.f_num_symbols) {
31349       while (true) {
31350         if ((v_code_length < 1u) || (20u < v_code_length)) {
31351           status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_header);
31352           goto exit;
31353         }
31354         if (self->private_impl.f_n_bits <= 0u) {
31355           {
31356             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
31357             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31358               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31359               goto suspend;
31360             }
31361             uint8_t t_1 = *iop_a_src++;
31362             v_c = t_1;
31363           }
31364           self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u);
31365           self->private_impl.f_n_bits = 8u;
31366         }
31367         if ((self->private_impl.f_bits >> 31u) == 0u) {
31368           self->private_impl.f_bits <<= 1u;
31369           self->private_impl.f_n_bits -= 1u;
31370           break;
31371         }
31372         self->private_impl.f_bits <<= 1u;
31373         self->private_impl.f_n_bits -= 1u;
31374         if (self->private_impl.f_n_bits <= 0u) {
31375           {
31376             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
31377             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31378               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31379               goto suspend;
31380             }
31381             uint8_t t_2 = *iop_a_src++;
31382             v_c = t_2;
31383           }
31384           self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u);
31385           self->private_impl.f_n_bits = 8u;
31386         }
31387         if ((self->private_impl.f_bits >> 31u) == 0u) {
31388           v_code_length += 1u;
31389         } else {
31390           v_code_length -= 1u;
31391         }
31392         self->private_impl.f_bits <<= 1u;
31393         self->private_impl.f_n_bits -= 1u;
31394       }
31395       self->private_impl.f_code_lengths_bitmask |= (((uint32_t)(1u)) << (v_code_length & 31u));
31396       self->private_data.f_bwt[v_i] = v_code_length;
31397       v_i += 1u;
31398     }
31399 
31400     goto ok;
31401     ok:
31402     self->private_impl.p_read_code_lengths[0] = 0;
31403     goto exit;
31404   }
31405 
31406   goto suspend;
31407   suspend:
31408   self->private_impl.p_read_code_lengths[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
31409   self->private_data.s_read_code_lengths[0].v_i = v_i;
31410   self->private_data.s_read_code_lengths[0].v_code_length = v_code_length;
31411 
31412   goto exit;
31413   exit:
31414   if (a_src && a_src->data.ptr) {
31415     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
31416   }
31417 
31418   return status;
31419 }
31420 
31421 // -------- func bzip2.decoder.build_huffman_tree
31422 
31423 WUFFS_BASE__GENERATED_C_CODE
31424 static wuffs_base__status
wuffs_bzip2__decoder__build_huffman_tree(wuffs_bzip2__decoder * self,uint32_t a_which)31425 wuffs_bzip2__decoder__build_huffman_tree(
31426     wuffs_bzip2__decoder* self,
31427     uint32_t a_which) {
31428   uint32_t v_code_length = 0;
31429   uint32_t v_symbol_index = 0;
31430   uint32_t v_num_branch_nodes = 0;
31431   uint32_t v_stack_height = 0;
31432   uint32_t v_stack_values[21] = {0};
31433   uint32_t v_node_index = 0;
31434   uint16_t v_leaf_value = 0;
31435 
31436   self->private_data.f_huffman_trees[a_which][0u][0u] = 0u;
31437   self->private_data.f_huffman_trees[a_which][0u][1u] = 0u;
31438   v_num_branch_nodes = 1u;
31439   v_stack_height = 1u;
31440   v_stack_values[0u] = 0u;
31441   v_code_length = 1u;
31442   while (v_code_length <= 20u) {
31443     if ((self->private_impl.f_code_lengths_bitmask & (((uint32_t)(1u)) << v_code_length)) == 0u) {
31444       v_code_length += 1u;
31445       continue;
31446     }
31447     v_symbol_index = 0u;
31448     while (v_symbol_index < self->private_impl.f_num_symbols) {
31449       if (self->private_data.f_bwt[v_symbol_index] != v_code_length) {
31450         v_symbol_index += 1u;
31451         continue;
31452       }
31453       while (true) {
31454         if (v_stack_height <= 0u) {
31455           return wuffs_base__make_status(wuffs_bzip2__error__bad_huffman_code_over_subscribed);
31456         } else if (v_stack_height >= v_code_length) {
31457           break;
31458         }
31459         v_node_index = v_stack_values[(v_stack_height - 1u)];
31460         if (self->private_data.f_huffman_trees[a_which][v_node_index][0u] == 0u) {
31461           self->private_data.f_huffman_trees[a_which][v_node_index][0u] = ((uint16_t)(v_num_branch_nodes));
31462         } else {
31463           self->private_data.f_huffman_trees[a_which][v_node_index][1u] = ((uint16_t)(v_num_branch_nodes));
31464         }
31465         if (v_num_branch_nodes >= 257u) {
31466           return wuffs_base__make_status(wuffs_bzip2__error__bad_huffman_code_under_subscribed);
31467         }
31468         v_stack_values[v_stack_height] = v_num_branch_nodes;
31469         self->private_data.f_huffman_trees[a_which][v_num_branch_nodes][0u] = 0u;
31470         self->private_data.f_huffman_trees[a_which][v_num_branch_nodes][1u] = 0u;
31471         v_num_branch_nodes += 1u;
31472         v_stack_height += 1u;
31473       }
31474       v_node_index = v_stack_values[(v_stack_height - 1u)];
31475       if (v_symbol_index < 2u) {
31476         v_leaf_value = ((uint16_t)((769u + v_symbol_index)));
31477       } else if ((v_symbol_index + 1u) < self->private_impl.f_num_symbols) {
31478         v_leaf_value = ((uint16_t)((511u + v_symbol_index)));
31479       } else {
31480         v_leaf_value = 768u;
31481       }
31482       if (self->private_data.f_huffman_trees[a_which][v_node_index][0u] == 0u) {
31483         self->private_data.f_huffman_trees[a_which][v_node_index][0u] = v_leaf_value;
31484       } else {
31485         self->private_data.f_huffman_trees[a_which][v_node_index][1u] = v_leaf_value;
31486         v_stack_height -= 1u;
31487         while (v_stack_height > 0u) {
31488           v_node_index = v_stack_values[(v_stack_height - 1u)];
31489           if (self->private_data.f_huffman_trees[a_which][v_node_index][1u] == 0u) {
31490             break;
31491           }
31492           v_stack_height -= 1u;
31493         }
31494       }
31495       v_symbol_index += 1u;
31496     }
31497     v_code_length += 1u;
31498   }
31499   if (v_stack_height != 0u) {
31500     return wuffs_base__make_status(wuffs_bzip2__error__bad_huffman_code_under_subscribed);
31501   }
31502   return wuffs_base__make_status(NULL);
31503 }
31504 
31505 // -------- func bzip2.decoder.build_huffman_table
31506 
31507 WUFFS_BASE__GENERATED_C_CODE
31508 static wuffs_base__empty_struct
wuffs_bzip2__decoder__build_huffman_table(wuffs_bzip2__decoder * self,uint32_t a_which)31509 wuffs_bzip2__decoder__build_huffman_table(
31510     wuffs_bzip2__decoder* self,
31511     uint32_t a_which) {
31512   uint32_t v_i = 0;
31513   uint32_t v_bits = 0;
31514   uint16_t v_n_bits = 0;
31515   uint16_t v_child = 0;
31516 
31517   while (v_i < 256u) {
31518     v_bits = (v_i << 24u);
31519     v_n_bits = 0u;
31520     v_child = 0u;
31521     while ((v_child < 257u) && (v_n_bits < 8u)) {
31522       v_child = self->private_data.f_huffman_trees[a_which][v_child][(v_bits >> 31u)];
31523       v_bits <<= 1u;
31524 #if defined(__GNUC__)
31525 #pragma GCC diagnostic push
31526 #pragma GCC diagnostic ignored "-Wconversion"
31527 #endif
31528       v_n_bits += 1u;
31529 #if defined(__GNUC__)
31530 #pragma GCC diagnostic pop
31531 #endif
31532     }
31533     self->private_data.f_huffman_tables[a_which][v_i] = ((uint16_t)((v_child | (v_n_bits << 12u))));
31534     v_i += 1u;
31535   }
31536   return wuffs_base__make_empty_struct();
31537 }
31538 
31539 // -------- func bzip2.decoder.invert_bwt
31540 
31541 WUFFS_BASE__GENERATED_C_CODE
31542 static wuffs_base__empty_struct
wuffs_bzip2__decoder__invert_bwt(wuffs_bzip2__decoder * self)31543 wuffs_bzip2__decoder__invert_bwt(
31544     wuffs_bzip2__decoder* self) {
31545   uint32_t v_i = 0;
31546   uint32_t v_letter = 0;
31547   uint32_t v_sum = 0;
31548   uint32_t v_old_sum = 0;
31549 
31550   v_sum = 0u;
31551   v_i = 0u;
31552   while (v_i < 256u) {
31553     v_old_sum = v_sum;
31554     v_sum += self->private_data.f_letter_counts[v_i];
31555     self->private_data.f_letter_counts[v_i] = v_old_sum;
31556     v_i += 1u;
31557   }
31558   v_i = 0u;
31559   while (v_i < self->private_impl.f_block_size) {
31560     v_letter = (self->private_data.f_bwt[v_i] & 255u);
31561     self->private_data.f_bwt[(self->private_data.f_letter_counts[v_letter] & 1048575u)] |= (v_i << 12u);
31562     self->private_data.f_letter_counts[v_letter] += 1u;
31563     v_i += 1u;
31564   }
31565   return wuffs_base__make_empty_struct();
31566 }
31567 
31568 // -------- func bzip2.decoder.flush_fast
31569 
31570 WUFFS_BASE__GENERATED_C_CODE
31571 static wuffs_base__empty_struct
wuffs_bzip2__decoder__flush_fast(wuffs_bzip2__decoder * self,wuffs_base__io_buffer * a_dst)31572 wuffs_bzip2__decoder__flush_fast(
31573     wuffs_bzip2__decoder* self,
31574     wuffs_base__io_buffer* a_dst) {
31575   uint32_t v_flush_pointer = 0;
31576   uint32_t v_flush_repeat_count = 0;
31577   uint8_t v_flush_prev = 0;
31578   uint32_t v_block_checksum_have = 0;
31579   uint32_t v_block_size = 0;
31580   uint32_t v_entry = 0;
31581   uint8_t v_curr = 0;
31582 
31583   uint8_t* iop_a_dst = NULL;
31584   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31585   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31586   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31587   if (a_dst && a_dst->data.ptr) {
31588     io0_a_dst = a_dst->data.ptr;
31589     io1_a_dst = io0_a_dst + a_dst->meta.wi;
31590     iop_a_dst = io1_a_dst;
31591     io2_a_dst = io0_a_dst + a_dst->data.len;
31592     if (a_dst->meta.closed) {
31593       io2_a_dst = iop_a_dst;
31594     }
31595   }
31596 
31597   v_flush_pointer = self->private_impl.f_flush_pointer;
31598   v_flush_repeat_count = self->private_impl.f_flush_repeat_count;
31599   v_flush_prev = self->private_impl.f_flush_prev;
31600   v_block_checksum_have = self->private_impl.f_block_checksum_have;
31601   v_block_size = self->private_impl.f_block_size;
31602   while ((v_block_size > 0u) && (((uint64_t)(io2_a_dst - iop_a_dst)) >= 255u)) {
31603     if (v_flush_repeat_count < 4u) {
31604       v_entry = self->private_data.f_bwt[v_flush_pointer];
31605       v_curr = ((uint8_t)(v_entry));
31606       v_flush_pointer = (v_entry >> 12u);
31607       if (v_curr == v_flush_prev) {
31608         v_flush_repeat_count += 1u;
31609       } else {
31610         v_flush_repeat_count = 1u;
31611       }
31612       v_block_checksum_have = (WUFFS_BZIP2__REV_CRC32_TABLE[(((uint8_t)((v_block_checksum_have >> 24u))) ^ v_curr)] ^ ((uint32_t)(v_block_checksum_have << 8u)));
31613       (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, v_curr), iop_a_dst += 1);
31614       v_flush_prev = v_curr;
31615       v_block_size -= 1u;
31616     } else {
31617       v_entry = self->private_data.f_bwt[v_flush_pointer];
31618       v_curr = ((uint8_t)(v_entry));
31619       v_flush_pointer = (v_entry >> 12u);
31620       v_flush_repeat_count = ((uint32_t)(v_curr));
31621       while (v_flush_repeat_count > 0u) {
31622         v_block_checksum_have = (WUFFS_BZIP2__REV_CRC32_TABLE[(((uint8_t)((v_block_checksum_have >> 24u))) ^ v_flush_prev)] ^ ((uint32_t)(v_block_checksum_have << 8u)));
31623         if (((uint64_t)(io2_a_dst - iop_a_dst)) > 0u) {
31624           (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, v_flush_prev), iop_a_dst += 1);
31625         }
31626         v_flush_repeat_count -= 1u;
31627       }
31628       v_flush_repeat_count = 0u;
31629       v_flush_prev = v_curr;
31630       v_block_size -= 1u;
31631     }
31632   }
31633   self->private_impl.f_flush_pointer = v_flush_pointer;
31634   self->private_impl.f_flush_repeat_count = v_flush_repeat_count;
31635   self->private_impl.f_flush_prev = v_flush_prev;
31636   self->private_impl.f_block_checksum_have = v_block_checksum_have;
31637   if (v_block_size <= 900000u) {
31638     self->private_impl.f_block_size = v_block_size;
31639   }
31640   if (a_dst && a_dst->data.ptr) {
31641     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
31642   }
31643 
31644   return wuffs_base__make_empty_struct();
31645 }
31646 
31647 // -------- func bzip2.decoder.flush_slow
31648 
31649 WUFFS_BASE__GENERATED_C_CODE
31650 static wuffs_base__status
wuffs_bzip2__decoder__flush_slow(wuffs_bzip2__decoder * self,wuffs_base__io_buffer * a_dst)31651 wuffs_bzip2__decoder__flush_slow(
31652     wuffs_bzip2__decoder* self,
31653     wuffs_base__io_buffer* a_dst) {
31654   wuffs_base__status status = wuffs_base__make_status(NULL);
31655 
31656   uint32_t v_flush_pointer = 0;
31657   uint32_t v_flush_repeat_count = 0;
31658   uint8_t v_flush_prev = 0;
31659   uint32_t v_block_checksum_have = 0;
31660   uint32_t v_block_size = 0;
31661   uint32_t v_entry = 0;
31662   uint8_t v_curr = 0;
31663 
31664   uint8_t* iop_a_dst = NULL;
31665   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31666   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31667   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31668   if (a_dst && a_dst->data.ptr) {
31669     io0_a_dst = a_dst->data.ptr;
31670     io1_a_dst = io0_a_dst + a_dst->meta.wi;
31671     iop_a_dst = io1_a_dst;
31672     io2_a_dst = io0_a_dst + a_dst->data.len;
31673     if (a_dst->meta.closed) {
31674       io2_a_dst = iop_a_dst;
31675     }
31676   }
31677 
31678   uint32_t coro_susp_point = self->private_impl.p_flush_slow[0];
31679   if (coro_susp_point) {
31680     v_flush_pointer = self->private_data.s_flush_slow[0].v_flush_pointer;
31681     v_flush_repeat_count = self->private_data.s_flush_slow[0].v_flush_repeat_count;
31682     v_flush_prev = self->private_data.s_flush_slow[0].v_flush_prev;
31683     v_block_checksum_have = self->private_data.s_flush_slow[0].v_block_checksum_have;
31684     v_block_size = self->private_data.s_flush_slow[0].v_block_size;
31685     v_curr = self->private_data.s_flush_slow[0].v_curr;
31686   }
31687   switch (coro_susp_point) {
31688     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
31689 
31690     v_flush_pointer = self->private_impl.f_flush_pointer;
31691     v_flush_repeat_count = self->private_impl.f_flush_repeat_count;
31692     v_flush_prev = self->private_impl.f_flush_prev;
31693     v_block_checksum_have = self->private_impl.f_block_checksum_have;
31694     v_block_size = self->private_impl.f_block_size;
31695     while ((v_block_size > 0u) &&  ! (self->private_impl.p_flush_slow[0] != 0)) {
31696       if (v_flush_repeat_count < 4u) {
31697         v_entry = self->private_data.f_bwt[v_flush_pointer];
31698         v_curr = ((uint8_t)(v_entry));
31699         v_flush_pointer = (v_entry >> 12u);
31700         if (v_curr == v_flush_prev) {
31701           v_flush_repeat_count += 1u;
31702         } else {
31703           v_flush_repeat_count = 1u;
31704         }
31705         v_block_checksum_have = (WUFFS_BZIP2__REV_CRC32_TABLE[(((uint8_t)((v_block_checksum_have >> 24u))) ^ v_curr)] ^ ((uint32_t)(v_block_checksum_have << 8u)));
31706         self->private_data.s_flush_slow[0].scratch = v_curr;
31707         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
31708         if (iop_a_dst == io2_a_dst) {
31709           status = wuffs_base__make_status(wuffs_base__suspension__short_write);
31710           goto suspend;
31711         }
31712         *iop_a_dst++ = ((uint8_t)(self->private_data.s_flush_slow[0].scratch));
31713         v_flush_prev = v_curr;
31714         v_block_size -= 1u;
31715       } else {
31716         v_entry = self->private_data.f_bwt[v_flush_pointer];
31717         v_curr = ((uint8_t)(v_entry));
31718         v_flush_pointer = (v_entry >> 12u);
31719         v_flush_repeat_count = ((uint32_t)(v_curr));
31720         while (v_flush_repeat_count > 0u) {
31721           v_block_checksum_have = (WUFFS_BZIP2__REV_CRC32_TABLE[(((uint8_t)((v_block_checksum_have >> 24u))) ^ v_flush_prev)] ^ ((uint32_t)(v_block_checksum_have << 8u)));
31722           self->private_data.s_flush_slow[0].scratch = v_flush_prev;
31723           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
31724           if (iop_a_dst == io2_a_dst) {
31725             status = wuffs_base__make_status(wuffs_base__suspension__short_write);
31726             goto suspend;
31727           }
31728           *iop_a_dst++ = ((uint8_t)(self->private_data.s_flush_slow[0].scratch));
31729           v_flush_repeat_count -= 1u;
31730         }
31731         v_flush_repeat_count = 0u;
31732         v_flush_prev = v_curr;
31733         v_block_size -= 1u;
31734       }
31735     }
31736     self->private_impl.f_flush_pointer = v_flush_pointer;
31737     self->private_impl.f_flush_repeat_count = v_flush_repeat_count;
31738     self->private_impl.f_flush_prev = v_flush_prev;
31739     self->private_impl.f_block_checksum_have = v_block_checksum_have;
31740     if (v_block_size <= 900000u) {
31741       self->private_impl.f_block_size = v_block_size;
31742     }
31743 
31744     goto ok;
31745     ok:
31746     self->private_impl.p_flush_slow[0] = 0;
31747     goto exit;
31748   }
31749 
31750   goto suspend;
31751   suspend:
31752   self->private_impl.p_flush_slow[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
31753   self->private_data.s_flush_slow[0].v_flush_pointer = v_flush_pointer;
31754   self->private_data.s_flush_slow[0].v_flush_repeat_count = v_flush_repeat_count;
31755   self->private_data.s_flush_slow[0].v_flush_prev = v_flush_prev;
31756   self->private_data.s_flush_slow[0].v_block_checksum_have = v_block_checksum_have;
31757   self->private_data.s_flush_slow[0].v_block_size = v_block_size;
31758   self->private_data.s_flush_slow[0].v_curr = v_curr;
31759 
31760   goto exit;
31761   exit:
31762   if (a_dst && a_dst->data.ptr) {
31763     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
31764   }
31765 
31766   return status;
31767 }
31768 
31769 // -------- func bzip2.decoder.decode_huffman_fast
31770 
31771 WUFFS_BASE__GENERATED_C_CODE
31772 static wuffs_base__status
wuffs_bzip2__decoder__decode_huffman_fast(wuffs_bzip2__decoder * self,wuffs_base__io_buffer * a_src)31773 wuffs_bzip2__decoder__decode_huffman_fast(
31774     wuffs_bzip2__decoder* self,
31775     wuffs_base__io_buffer* a_src) {
31776   wuffs_base__status status = wuffs_base__make_status(NULL);
31777 
31778   uint32_t v_bits = 0;
31779   uint32_t v_n_bits = 0;
31780   uint32_t v_block_size = 0;
31781   uint8_t v_which = 0;
31782   uint32_t v_ticks = 0;
31783   uint32_t v_section = 0;
31784   uint32_t v_run_shift = 0;
31785   uint16_t v_table_entry = 0;
31786   uint16_t v_child = 0;
31787   uint32_t v_child_ff = 0;
31788   uint32_t v_i = 0;
31789   uint32_t v_j = 0;
31790   uint32_t v_output = 0;
31791   uint32_t v_run = 0;
31792   uint32_t v_mtft0 = 0;
31793 
31794   const uint8_t* iop_a_src = NULL;
31795   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31796   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31797   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31798   if (a_src && a_src->data.ptr) {
31799     io0_a_src = a_src->data.ptr;
31800     io1_a_src = io0_a_src + a_src->meta.ri;
31801     iop_a_src = io1_a_src;
31802     io2_a_src = io0_a_src + a_src->meta.wi;
31803   }
31804 
31805   v_bits = self->private_impl.f_bits;
31806   v_n_bits = self->private_impl.f_n_bits;
31807   v_block_size = self->private_impl.f_block_size;
31808   v_which = self->private_impl.f_decode_huffman_which;
31809   v_ticks = self->private_impl.f_decode_huffman_ticks;
31810   v_section = self->private_impl.f_decode_huffman_section;
31811   v_run_shift = self->private_impl.f_decode_huffman_run_shift;
31812   while (((uint64_t)(io2_a_src - iop_a_src)) >= 4u) {
31813     if (v_ticks > 0u) {
31814       v_ticks -= 1u;
31815     } else {
31816       v_ticks = 49u;
31817       v_section += 1u;
31818       if (v_section >= self->private_impl.f_num_sections) {
31819         status = wuffs_base__make_status(wuffs_bzip2__error__bad_number_of_sections);
31820         goto exit;
31821       }
31822       v_which = WUFFS_BZIP2__CLAMP_TO_5[(self->private_data.f_huffman_selectors[(v_section & 32767u)] & 7u)];
31823     }
31824     v_bits |= (wuffs_base__peek_u32be__no_bounds_check(iop_a_src) >> v_n_bits);
31825     iop_a_src += ((31u - v_n_bits) >> 3u);
31826     v_n_bits |= 24u;
31827     v_table_entry = self->private_data.f_huffman_tables[v_which][(v_bits >> 24u)];
31828     v_bits <<= (v_table_entry >> 12u);
31829     v_n_bits -= ((uint32_t)((v_table_entry >> 12u)));
31830     v_child = (v_table_entry & 1023u);
31831     while (v_child < 257u) {
31832       v_child = self->private_data.f_huffman_trees[v_which][v_child][(v_bits >> 31u)];
31833       v_bits <<= 1u;
31834       if (v_n_bits <= 0u) {
31835         status = wuffs_base__make_status(wuffs_bzip2__error__internal_error_inconsistent_huffman_decoder_state);
31836         goto exit;
31837       }
31838       v_n_bits -= 1u;
31839     }
31840     if (v_child < 768u) {
31841       v_child_ff = ((uint32_t)((v_child & 255u)));
31842       v_output = ((uint32_t)(self->private_data.f_mtft[v_child_ff]));
31843       wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8_ij(self->private_data.f_mtft, 1, (1u + v_child_ff)), wuffs_base__make_slice_u8(self->private_data.f_mtft, v_child_ff));
31844       self->private_data.f_mtft[0u] = ((uint8_t)(v_output));
31845       self->private_data.f_letter_counts[v_output] += 1u;
31846       self->private_data.f_bwt[v_block_size] = v_output;
31847       if (v_block_size >= self->private_impl.f_max_incl_block_size) {
31848         status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_length);
31849         goto exit;
31850       }
31851       v_block_size += 1u;
31852       v_run_shift = 0u;
31853       continue;
31854     } else if (v_child == 768u) {
31855       self->private_impl.f_decode_huffman_finished = true;
31856       break;
31857     }
31858     if (v_run_shift >= 23u) {
31859       status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_length);
31860       goto exit;
31861     }
31862     v_run = ((((uint32_t)(v_child)) & 3u) << v_run_shift);
31863     v_run_shift += 1u;
31864     v_i = v_block_size;
31865     v_j = (v_run + v_block_size);
31866     if (v_j > self->private_impl.f_max_incl_block_size) {
31867       status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_length);
31868       goto exit;
31869     }
31870     v_block_size = v_j;
31871     v_mtft0 = ((uint32_t)(self->private_data.f_mtft[0u]));
31872     self->private_data.f_letter_counts[v_mtft0] += v_run;
31873     while (v_i < v_j) {
31874       self->private_data.f_bwt[v_i] = v_mtft0;
31875       v_i += 1u;
31876     }
31877   }
31878   self->private_impl.f_bits = v_bits;
31879   self->private_impl.f_n_bits = v_n_bits;
31880   self->private_impl.f_block_size = v_block_size;
31881   self->private_impl.f_decode_huffman_which = v_which;
31882   self->private_impl.f_decode_huffman_ticks = v_ticks;
31883   self->private_impl.f_decode_huffman_section = v_section;
31884   self->private_impl.f_decode_huffman_run_shift = v_run_shift;
31885   status = wuffs_base__make_status(NULL);
31886   goto ok;
31887 
31888   ok:
31889   goto exit;
31890   exit:
31891   if (a_src && a_src->data.ptr) {
31892     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
31893   }
31894 
31895   return status;
31896 }
31897 
31898 // -------- func bzip2.decoder.decode_huffman_slow
31899 
31900 WUFFS_BASE__GENERATED_C_CODE
31901 static wuffs_base__status
wuffs_bzip2__decoder__decode_huffman_slow(wuffs_bzip2__decoder * self,wuffs_base__io_buffer * a_src)31902 wuffs_bzip2__decoder__decode_huffman_slow(
31903     wuffs_bzip2__decoder* self,
31904     wuffs_base__io_buffer* a_src) {
31905   wuffs_base__status status = wuffs_base__make_status(NULL);
31906 
31907   uint8_t v_c = 0;
31908   uint32_t v_node_index = 0;
31909   uint16_t v_child = 0;
31910   uint32_t v_child_ff = 0;
31911   uint32_t v_i = 0;
31912   uint32_t v_j = 0;
31913   uint32_t v_output = 0;
31914   uint32_t v_run = 0;
31915   uint32_t v_mtft0 = 0;
31916 
31917   const uint8_t* iop_a_src = NULL;
31918   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31919   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31920   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31921   if (a_src && a_src->data.ptr) {
31922     io0_a_src = a_src->data.ptr;
31923     io1_a_src = io0_a_src + a_src->meta.ri;
31924     iop_a_src = io1_a_src;
31925     io2_a_src = io0_a_src + a_src->meta.wi;
31926   }
31927 
31928   uint32_t coro_susp_point = self->private_impl.p_decode_huffman_slow[0];
31929   if (coro_susp_point) {
31930     v_node_index = self->private_data.s_decode_huffman_slow[0].v_node_index;
31931   }
31932   switch (coro_susp_point) {
31933     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
31934 
31935     while ( ! (self->private_impl.p_decode_huffman_slow[0] != 0)) {
31936       if (self->private_impl.f_decode_huffman_ticks > 0u) {
31937         self->private_impl.f_decode_huffman_ticks -= 1u;
31938       } else {
31939         self->private_impl.f_decode_huffman_ticks = 49u;
31940         self->private_impl.f_decode_huffman_section += 1u;
31941         if (self->private_impl.f_decode_huffman_section >= self->private_impl.f_num_sections) {
31942           status = wuffs_base__make_status(wuffs_bzip2__error__bad_number_of_sections);
31943           goto exit;
31944         }
31945         self->private_impl.f_decode_huffman_which = WUFFS_BZIP2__CLAMP_TO_5[(self->private_data.f_huffman_selectors[(self->private_impl.f_decode_huffman_section & 32767u)] & 7u)];
31946       }
31947       v_node_index = 0u;
31948       while (true) {
31949         if (self->private_impl.f_n_bits <= 0u) {
31950           {
31951             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
31952             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31953               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31954               goto suspend;
31955             }
31956             uint8_t t_0 = *iop_a_src++;
31957             v_c = t_0;
31958           }
31959           self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u);
31960           self->private_impl.f_n_bits = 8u;
31961         }
31962         v_child = self->private_data.f_huffman_trees[self->private_impl.f_decode_huffman_which][v_node_index][(self->private_impl.f_bits >> 31u)];
31963         self->private_impl.f_bits <<= 1u;
31964         self->private_impl.f_n_bits -= 1u;
31965         if (v_child < 257u) {
31966           v_node_index = ((uint32_t)(v_child));
31967           continue;
31968         } else if (v_child < 768u) {
31969           v_child_ff = ((uint32_t)((v_child & 255u)));
31970           v_output = ((uint32_t)(self->private_data.f_mtft[v_child_ff]));
31971           wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8_ij(self->private_data.f_mtft, 1, (1u + v_child_ff)), wuffs_base__make_slice_u8(self->private_data.f_mtft, v_child_ff));
31972           self->private_data.f_mtft[0u] = ((uint8_t)(v_output));
31973           self->private_data.f_letter_counts[v_output] += 1u;
31974           self->private_data.f_bwt[self->private_impl.f_block_size] = v_output;
31975           if (self->private_impl.f_block_size >= self->private_impl.f_max_incl_block_size) {
31976             status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_length);
31977             goto exit;
31978           }
31979           self->private_impl.f_block_size += 1u;
31980           self->private_impl.f_decode_huffman_run_shift = 0u;
31981           break;
31982         } else if (v_child == 768u) {
31983           self->private_impl.f_decode_huffman_finished = true;
31984           goto label__outer__break;
31985         }
31986         if (self->private_impl.f_decode_huffman_run_shift >= 23u) {
31987           status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_length);
31988           goto exit;
31989         }
31990         v_run = ((((uint32_t)(v_child)) & 3u) << self->private_impl.f_decode_huffman_run_shift);
31991         self->private_impl.f_decode_huffman_run_shift += 1u;
31992         v_i = self->private_impl.f_block_size;
31993         v_j = (v_run + self->private_impl.f_block_size);
31994         if (v_j > self->private_impl.f_max_incl_block_size) {
31995           status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_length);
31996           goto exit;
31997         }
31998         self->private_impl.f_block_size = v_j;
31999         v_mtft0 = ((uint32_t)(self->private_data.f_mtft[0u]));
32000         self->private_data.f_letter_counts[v_mtft0] += v_run;
32001         while (v_i < v_j) {
32002           self->private_data.f_bwt[v_i] = v_mtft0;
32003           v_i += 1u;
32004         }
32005         break;
32006       }
32007     }
32008     label__outer__break:;
32009 
32010     goto ok;
32011     ok:
32012     self->private_impl.p_decode_huffman_slow[0] = 0;
32013     goto exit;
32014   }
32015 
32016   goto suspend;
32017   suspend:
32018   self->private_impl.p_decode_huffman_slow[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
32019   self->private_data.s_decode_huffman_slow[0].v_node_index = v_node_index;
32020 
32021   goto exit;
32022   exit:
32023   if (a_src && a_src->data.ptr) {
32024     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
32025   }
32026 
32027   return status;
32028 }
32029 
32030 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BZIP2)
32031 
32032 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CBOR)
32033 
32034 // ---------------- Status Codes Implementations
32035 
32036 const char wuffs_cbor__error__bad_input[] = "#cbor: bad input";
32037 const char wuffs_cbor__error__unsupported_recursion_depth[] = "#cbor: unsupported recursion depth";
32038 const char wuffs_cbor__error__internal_error_inconsistent_i_o[] = "#cbor: internal error: inconsistent I/O";
32039 const char wuffs_cbor__error__internal_error_inconsistent_token_length[] = "#cbor: internal error: inconsistent token length";
32040 
32041 // ---------------- Private Consts
32042 
32043 static const uint32_t
32044 WUFFS_CBOR__LITERALS[4] WUFFS_BASE__POTENTIALLY_UNUSED = {
32045   8388612, 8388616, 8388610, 8388609,
32046 };
32047 
32048 static const uint8_t
32049 WUFFS_CBOR__TOKEN_LENGTHS[32] WUFFS_BASE__POTENTIALLY_UNUSED = {
32050   1, 1, 1, 1, 1, 1, 1, 1,
32051   1, 1, 1, 1, 1, 1, 1, 1,
32052   1, 1, 1, 1, 1, 1, 1, 1,
32053   2, 3, 5, 9, 0, 0, 0, 1,
32054 };
32055 
32056 // ---------------- Private Initializer Prototypes
32057 
32058 // ---------------- Private Function Prototypes
32059 
32060 // ---------------- VTables
32061 
32062 const wuffs_base__token_decoder__func_ptrs
32063 wuffs_cbor__decoder__func_ptrs_for__wuffs_base__token_decoder = {
32064   (wuffs_base__status(*)(void*,
32065       wuffs_base__token_buffer*,
32066       wuffs_base__io_buffer*,
32067       wuffs_base__slice_u8))(&wuffs_cbor__decoder__decode_tokens),
32068   (uint64_t(*)(const void*,
32069       uint32_t))(&wuffs_cbor__decoder__get_quirk),
32070   (uint64_t(*)(const void*))(&wuffs_cbor__decoder__history_retain_length),
32071   (wuffs_base__status(*)(void*,
32072       uint32_t,
32073       uint64_t))(&wuffs_cbor__decoder__set_quirk),
32074   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_cbor__decoder__workbuf_len),
32075 };
32076 
32077 // ---------------- Initializer Implementations
32078 
32079 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
wuffs_cbor__decoder__initialize(wuffs_cbor__decoder * self,size_t sizeof_star_self,uint64_t wuffs_version,uint32_t options)32080 wuffs_cbor__decoder__initialize(
32081     wuffs_cbor__decoder* self,
32082     size_t sizeof_star_self,
32083     uint64_t wuffs_version,
32084     uint32_t options){
32085   if (!self) {
32086     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
32087   }
32088   if (sizeof(*self) != sizeof_star_self) {
32089     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
32090   }
32091   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
32092       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
32093     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
32094   }
32095 
32096   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
32097     // The whole point of this if-check is to detect an uninitialized *self.
32098     // We disable the warning on GCC. Clang-5.0 does not have this warning.
32099 #if !defined(__clang__) && defined(__GNUC__)
32100 #pragma GCC diagnostic push
32101 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
32102 #endif
32103     if (self->private_impl.magic != 0) {
32104       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
32105     }
32106 #if !defined(__clang__) && defined(__GNUC__)
32107 #pragma GCC diagnostic pop
32108 #endif
32109   } else {
32110     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
32111       memset(self, 0, sizeof(*self));
32112       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
32113     } else {
32114       memset(&(self->private_impl), 0, sizeof(self->private_impl));
32115     }
32116   }
32117 
32118   self->private_impl.magic = WUFFS_BASE__MAGIC;
32119   self->private_impl.vtable_for__wuffs_base__token_decoder.vtable_name =
32120       wuffs_base__token_decoder__vtable_name;
32121   self->private_impl.vtable_for__wuffs_base__token_decoder.function_pointers =
32122       (const void*)(&wuffs_cbor__decoder__func_ptrs_for__wuffs_base__token_decoder);
32123   return wuffs_base__make_status(NULL);
32124 }
32125 
32126 wuffs_cbor__decoder*
wuffs_cbor__decoder__alloc(void)32127 wuffs_cbor__decoder__alloc(void) {
32128   wuffs_cbor__decoder* x =
32129       (wuffs_cbor__decoder*)(calloc(sizeof(wuffs_cbor__decoder), 1));
32130   if (!x) {
32131     return NULL;
32132   }
32133   if (wuffs_cbor__decoder__initialize(
32134       x, sizeof(wuffs_cbor__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
32135     free(x);
32136     return NULL;
32137   }
32138   return x;
32139 }
32140 
32141 size_t
sizeof__wuffs_cbor__decoder(void)32142 sizeof__wuffs_cbor__decoder(void) {
32143   return sizeof(wuffs_cbor__decoder);
32144 }
32145 
32146 // ---------------- Function Implementations
32147 
32148 // -------- func cbor.decoder.get_quirk
32149 
32150 WUFFS_BASE__GENERATED_C_CODE
32151 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_cbor__decoder__get_quirk(const wuffs_cbor__decoder * self,uint32_t a_key)32152 wuffs_cbor__decoder__get_quirk(
32153     const wuffs_cbor__decoder* self,
32154     uint32_t a_key) {
32155   if (!self) {
32156     return 0;
32157   }
32158   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
32159       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
32160     return 0;
32161   }
32162 
32163   return 0u;
32164 }
32165 
32166 // -------- func cbor.decoder.set_quirk
32167 
32168 WUFFS_BASE__GENERATED_C_CODE
32169 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_cbor__decoder__set_quirk(wuffs_cbor__decoder * self,uint32_t a_key,uint64_t a_value)32170 wuffs_cbor__decoder__set_quirk(
32171     wuffs_cbor__decoder* self,
32172     uint32_t a_key,
32173     uint64_t a_value) {
32174   if (!self) {
32175     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
32176   }
32177   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
32178     return wuffs_base__make_status(
32179         (self->private_impl.magic == WUFFS_BASE__DISABLED)
32180         ? wuffs_base__error__disabled_by_previous_error
32181         : wuffs_base__error__initialize_not_called);
32182   }
32183 
32184   return wuffs_base__make_status(wuffs_base__error__unsupported_option);
32185 }
32186 
32187 // -------- func cbor.decoder.history_retain_length
32188 
32189 WUFFS_BASE__GENERATED_C_CODE
32190 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_cbor__decoder__history_retain_length(const wuffs_cbor__decoder * self)32191 wuffs_cbor__decoder__history_retain_length(
32192     const wuffs_cbor__decoder* self) {
32193   if (!self) {
32194     return 0;
32195   }
32196   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
32197       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
32198     return 0;
32199   }
32200 
32201   return 0u;
32202 }
32203 
32204 // -------- func cbor.decoder.workbuf_len
32205 
32206 WUFFS_BASE__GENERATED_C_CODE
32207 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_cbor__decoder__workbuf_len(const wuffs_cbor__decoder * self)32208 wuffs_cbor__decoder__workbuf_len(
32209     const wuffs_cbor__decoder* self) {
32210   if (!self) {
32211     return wuffs_base__utility__empty_range_ii_u64();
32212   }
32213   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
32214       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
32215     return wuffs_base__utility__empty_range_ii_u64();
32216   }
32217 
32218   return wuffs_base__utility__empty_range_ii_u64();
32219 }
32220 
32221 // -------- func cbor.decoder.decode_tokens
32222 
32223 WUFFS_BASE__GENERATED_C_CODE
32224 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_cbor__decoder__decode_tokens(wuffs_cbor__decoder * self,wuffs_base__token_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__slice_u8 a_workbuf)32225 wuffs_cbor__decoder__decode_tokens(
32226     wuffs_cbor__decoder* self,
32227     wuffs_base__token_buffer* a_dst,
32228     wuffs_base__io_buffer* a_src,
32229     wuffs_base__slice_u8 a_workbuf) {
32230   if (!self) {
32231     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
32232   }
32233   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
32234     return wuffs_base__make_status(
32235         (self->private_impl.magic == WUFFS_BASE__DISABLED)
32236         ? wuffs_base__error__disabled_by_previous_error
32237         : wuffs_base__error__initialize_not_called);
32238   }
32239   if (!a_dst || !a_src) {
32240     self->private_impl.magic = WUFFS_BASE__DISABLED;
32241     return wuffs_base__make_status(wuffs_base__error__bad_argument);
32242   }
32243   if ((self->private_impl.active_coroutine != 0) &&
32244       (self->private_impl.active_coroutine != 1)) {
32245     self->private_impl.magic = WUFFS_BASE__DISABLED;
32246     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
32247   }
32248   self->private_impl.active_coroutine = 0;
32249   wuffs_base__status status = wuffs_base__make_status(NULL);
32250 
32251   uint64_t v_string_length = 0;
32252   uint64_t v_n64 = 0;
32253   uint32_t v_depth = 0;
32254   uint32_t v_stack_byte = 0;
32255   uint32_t v_stack_bit = 0;
32256   uint32_t v_stack_val = 0;
32257   uint32_t v_token_length = 0;
32258   uint32_t v_vminor = 0;
32259   uint32_t v_vminor_alt = 0;
32260   uint32_t v_continued = 0;
32261   uint8_t v_c = 0;
32262   uint8_t v_c_major = 0;
32263   uint8_t v_c_minor = 0;
32264   bool v_tagged = false;
32265   uint8_t v_indefinite_string_major_type = 0;
32266 
32267   wuffs_base__token* iop_a_dst = NULL;
32268   wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32269   wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32270   wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32271   if (a_dst && a_dst->data.ptr) {
32272     io0_a_dst = a_dst->data.ptr;
32273     io1_a_dst = io0_a_dst + a_dst->meta.wi;
32274     iop_a_dst = io1_a_dst;
32275     io2_a_dst = io0_a_dst + a_dst->data.len;
32276     if (a_dst->meta.closed) {
32277       io2_a_dst = iop_a_dst;
32278     }
32279   }
32280   const uint8_t* iop_a_src = NULL;
32281   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32282   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32283   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32284   if (a_src && a_src->data.ptr) {
32285     io0_a_src = a_src->data.ptr;
32286     io1_a_src = io0_a_src + a_src->meta.ri;
32287     iop_a_src = io1_a_src;
32288     io2_a_src = io0_a_src + a_src->meta.wi;
32289   }
32290 
32291   uint32_t coro_susp_point = self->private_impl.p_decode_tokens[0];
32292   if (coro_susp_point) {
32293     v_string_length = self->private_data.s_decode_tokens[0].v_string_length;
32294     v_depth = self->private_data.s_decode_tokens[0].v_depth;
32295     v_tagged = self->private_data.s_decode_tokens[0].v_tagged;
32296     v_indefinite_string_major_type = self->private_data.s_decode_tokens[0].v_indefinite_string_major_type;
32297   }
32298   switch (coro_susp_point) {
32299     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
32300 
32301     if (self->private_impl.f_end_of_data) {
32302       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
32303       goto ok;
32304     }
32305     label__outer__continue:;
32306     while (true) {
32307       while (true) {
32308         do {
32309           if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 1u) {
32310             status = wuffs_base__make_status(wuffs_base__suspension__short_write);
32311             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
32312             goto label__outer__continue;
32313           }
32314           if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
32315             if (a_src && a_src->meta.closed) {
32316               status = wuffs_base__make_status(wuffs_cbor__error__bad_input);
32317               goto exit;
32318             }
32319             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32320             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
32321             goto label__outer__continue;
32322           }
32323           v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
32324           if ((v_indefinite_string_major_type != 0u) && (v_indefinite_string_major_type != (v_c >> 5u))) {
32325             if (v_c != 255u) {
32326               status = wuffs_base__make_status(wuffs_cbor__error__bad_input);
32327               goto exit;
32328             }
32329             v_vminor = 4194560u;
32330             if (v_indefinite_string_major_type == 3u) {
32331               v_vminor |= 19u;
32332             }
32333             v_indefinite_string_major_type = 0u;
32334             iop_a_src += 1u;
32335             *iop_a_dst++ = wuffs_base__make_token(
32336                 (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32337                 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32338             goto label__goto_parsed_a_leaf_value__break;
32339           }
32340           iop_a_src += 1u;
32341           v_c_major = ((uint8_t)((v_c >> 5u)));
32342           v_c_minor = (v_c & 31u);
32343           if (v_c_minor < 24u) {
32344             v_string_length = ((uint64_t)(v_c_minor));
32345           } else {
32346             while (true) {
32347               if (v_c_minor == 24u) {
32348                 if (((uint64_t)(io2_a_src - iop_a_src)) >= 1u) {
32349                   v_string_length = ((uint64_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src)));
32350                   iop_a_src += 1u;
32351                   break;
32352                 }
32353               } else if (v_c_minor == 25u) {
32354                 if (((uint64_t)(io2_a_src - iop_a_src)) >= 2u) {
32355                   v_string_length = ((uint64_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
32356                   iop_a_src += 2u;
32357                   break;
32358                 }
32359               } else if (v_c_minor == 26u) {
32360                 if (((uint64_t)(io2_a_src - iop_a_src)) >= 4u) {
32361                   v_string_length = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
32362                   iop_a_src += 4u;
32363                   break;
32364                 }
32365               } else if (v_c_minor == 27u) {
32366                 if (((uint64_t)(io2_a_src - iop_a_src)) >= 8u) {
32367                   v_string_length = wuffs_base__peek_u64be__no_bounds_check(iop_a_src);
32368                   iop_a_src += 8u;
32369                   break;
32370                 }
32371               } else {
32372                 v_string_length = 0u;
32373                 break;
32374               }
32375               if (iop_a_src > io1_a_src) {
32376                 iop_a_src--;
32377                 if (a_src && a_src->meta.closed) {
32378                   status = wuffs_base__make_status(wuffs_cbor__error__bad_input);
32379                   goto exit;
32380                 }
32381                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32382                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
32383                 goto label__outer__continue;
32384               }
32385               status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_i_o);
32386               goto exit;
32387             }
32388           }
32389           if (v_c_major == 0u) {
32390             if (v_c_minor < 26u) {
32391               *iop_a_dst++ = wuffs_base__make_token(
32392                   (((uint64_t)((14680064u | ((uint32_t)((v_string_length & 65535u)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32393                   (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32394               goto label__goto_parsed_a_leaf_value__break;
32395             } else if (v_c_minor < 28u) {
32396               *iop_a_dst++ = wuffs_base__make_token(
32397                   (((uint64_t)((14680064u | ((uint32_t)((v_string_length >> 46u)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32398                   (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32399                   (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32400               *iop_a_dst++ = wuffs_base__make_token(
32401                   (~(v_string_length & 70368744177663u) << WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT) |
32402                   (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32403               goto label__goto_parsed_a_leaf_value__break;
32404             }
32405           } else if (v_c_major == 1u) {
32406             if (v_c_minor < 26u) {
32407               *iop_a_dst++ = wuffs_base__make_token(
32408                   (((uint64_t)((12582912u | (2097151u - ((uint32_t)((v_string_length & 65535u))))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32409                   (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32410               goto label__goto_parsed_a_leaf_value__break;
32411             } else if (v_c_minor < 28u) {
32412               if (v_string_length < 9223372036854775808u) {
32413                 *iop_a_dst++ = wuffs_base__make_token(
32414                     (((uint64_t)((12582912u | (2097151u - ((uint32_t)((v_string_length >> 46u))))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32415                     (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32416                     (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32417                 *iop_a_dst++ = wuffs_base__make_token(
32418                     (~((18446744073709551615u - v_string_length) & 70368744177663u) << WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT) |
32419                     (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32420               } else {
32421                 *iop_a_dst++ = wuffs_base__make_token(
32422                     (((uint64_t)(787997u)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) |
32423                     (((uint64_t)(16777216u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32424                     (((uint64_t)(9u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32425               }
32426               goto label__goto_parsed_a_leaf_value__break;
32427             }
32428           } else if (v_c_major == 2u) {
32429             if (v_c_minor < 28u) {
32430               if (v_string_length == 0u) {
32431                 *iop_a_dst++ = wuffs_base__make_token(
32432                     (((uint64_t)(4194560u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32433                     (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32434                 goto label__goto_parsed_a_leaf_value__break;
32435               }
32436               *iop_a_dst++ = wuffs_base__make_token(
32437                   (((uint64_t)(4194560u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32438                   (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32439                   (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32440             } else if (v_c_minor == 31u) {
32441               if (v_indefinite_string_major_type != 0u) {
32442                 break;
32443               }
32444               v_indefinite_string_major_type = 2u;
32445               *iop_a_dst++ = wuffs_base__make_token(
32446                   (((uint64_t)(4194560u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32447                   (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32448                   (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32449               goto label__outer__continue;
32450             } else {
32451               break;
32452             }
32453             while (true) {
32454               if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
32455                 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
32456                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
32457                 continue;
32458               }
32459               v_n64 = wuffs_base__u64__min(v_string_length, ((uint64_t)(io2_a_src - iop_a_src)));
32460               v_token_length = ((uint32_t)((v_n64 & 65535u)));
32461               if (v_n64 > 65535u) {
32462                 v_token_length = 65535u;
32463               } else if (v_token_length <= 0u) {
32464                 if (a_src && a_src->meta.closed) {
32465                   status = wuffs_base__make_status(wuffs_cbor__error__bad_input);
32466                   goto exit;
32467                 }
32468                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32469                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
32470                 continue;
32471               }
32472               if (((uint64_t)(io2_a_src - iop_a_src)) < ((uint64_t)(v_token_length))) {
32473                 status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_token_length);
32474                 goto exit;
32475               }
32476               v_string_length -= ((uint64_t)(v_token_length));
32477               v_continued = 0u;
32478               if ((v_string_length > 0u) || (v_indefinite_string_major_type > 0u)) {
32479                 v_continued = 1u;
32480               }
32481               iop_a_src += v_token_length;
32482               *iop_a_dst++ = wuffs_base__make_token(
32483                   (((uint64_t)(4194816u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32484                   (((uint64_t)(v_continued)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32485                   (((uint64_t)(v_token_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32486               if (v_string_length > 0u) {
32487                 continue;
32488               } else if (v_indefinite_string_major_type > 0u) {
32489                 goto label__outer__continue;
32490               }
32491               goto label__goto_parsed_a_leaf_value__break;
32492             }
32493           } else if (v_c_major == 3u) {
32494             if (v_c_minor < 28u) {
32495               if (v_string_length == 0u) {
32496                 *iop_a_dst++ = wuffs_base__make_token(
32497                     (((uint64_t)(4194579u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32498                     (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32499                 goto label__goto_parsed_a_leaf_value__break;
32500               }
32501               *iop_a_dst++ = wuffs_base__make_token(
32502                   (((uint64_t)(4194579u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32503                   (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32504                   (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32505             } else if (v_c_minor == 31u) {
32506               if (v_indefinite_string_major_type != 0u) {
32507                 break;
32508               }
32509               v_indefinite_string_major_type = 3u;
32510               *iop_a_dst++ = wuffs_base__make_token(
32511                   (((uint64_t)(4194579u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32512                   (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32513                   (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32514               goto label__outer__continue;
32515             } else {
32516               break;
32517             }
32518             while (true) {
32519               if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
32520                 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
32521                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
32522                 continue;
32523               }
32524               v_n64 = wuffs_base__u64__min(v_string_length, 65535u);
32525               v_n64 = ((uint64_t)(wuffs_base__utf_8__longest_valid_prefix(iop_a_src,
32526                   ((size_t)(wuffs_base__u64__min(((uint64_t)(io2_a_src - iop_a_src)), v_n64))))));
32527               v_token_length = ((uint32_t)((v_n64 & 65535u)));
32528               if (v_token_length <= 0u) {
32529                 if ((a_src && a_src->meta.closed) || (((uint64_t)(io2_a_src - iop_a_src)) >= 4u)) {
32530                   status = wuffs_base__make_status(wuffs_cbor__error__bad_input);
32531                   goto exit;
32532                 }
32533                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32534                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7);
32535                 continue;
32536               }
32537               if (((uint64_t)(io2_a_src - iop_a_src)) < ((uint64_t)(v_token_length))) {
32538                 status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_token_length);
32539                 goto exit;
32540               }
32541               v_string_length -= ((uint64_t)(v_token_length));
32542               v_continued = 0u;
32543               if ((v_string_length > 0u) || (v_indefinite_string_major_type > 0u)) {
32544                 v_continued = 1u;
32545               }
32546               iop_a_src += v_token_length;
32547               *iop_a_dst++ = wuffs_base__make_token(
32548                   (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32549                   (((uint64_t)(v_continued)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32550                   (((uint64_t)(v_token_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32551               if (v_string_length > 0u) {
32552                 continue;
32553               } else if (v_indefinite_string_major_type > 0u) {
32554                 goto label__outer__continue;
32555               }
32556               goto label__goto_parsed_a_leaf_value__break;
32557             }
32558           } else if (v_c_major == 4u) {
32559             if (WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor] == 0u) {
32560               break;
32561             } else if (v_depth >= 1024u) {
32562               v_token_length = ((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor]));
32563               while ((v_token_length > 0u) && (iop_a_src > io1_a_src)) {
32564                 iop_a_src--;
32565                 v_token_length -= 1u;
32566               }
32567               status = wuffs_base__make_status(wuffs_cbor__error__unsupported_recursion_depth);
32568               goto exit;
32569             }
32570             v_vminor = 2105361u;
32571             v_vminor_alt = 2101282u;
32572             if (v_depth > 0u) {
32573               v_stack_byte = ((v_depth - 1u) / 16u);
32574               v_stack_bit = (((v_depth - 1u) & 15u) * 2u);
32575               if (0u == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1u)) << v_stack_bit))) {
32576                 v_vminor = 2105377u;
32577                 v_vminor_alt = 2105378u;
32578               } else {
32579                 v_vminor = 2105409u;
32580                 v_vminor_alt = 2113570u;
32581               }
32582             }
32583             *iop_a_dst++ = wuffs_base__make_token(
32584                 (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32585                 (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32586             if (v_c_minor == 0u) {
32587               *iop_a_dst++ = wuffs_base__make_token(
32588                   (((uint64_t)(v_vminor_alt)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32589                   (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32590               goto label__goto_parsed_a_leaf_value__break;
32591             }
32592             v_stack_byte = (v_depth / 16u);
32593             v_stack_bit = ((v_depth & 15u) * 2u);
32594             self->private_data.f_stack[v_stack_byte] &= (4294967295u ^ (((uint32_t)(3u)) << v_stack_bit));
32595             self->private_data.f_container_num_remaining[v_depth] = v_string_length;
32596             v_depth += 1u;
32597             v_tagged = false;
32598             goto label__outer__continue;
32599           } else if (v_c_major == 5u) {
32600             if (WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor] == 0u) {
32601               break;
32602             } else if (v_depth >= 1024u) {
32603               v_token_length = ((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor]));
32604               while ((v_token_length > 0u) && (iop_a_src > io1_a_src)) {
32605                 iop_a_src--;
32606                 v_token_length -= 1u;
32607               }
32608               status = wuffs_base__make_status(wuffs_cbor__error__unsupported_recursion_depth);
32609               goto exit;
32610             }
32611             v_vminor = 2113553u;
32612             v_vminor_alt = 2101314u;
32613             if (v_depth > 0u) {
32614               v_stack_byte = ((v_depth - 1u) / 16u);
32615               v_stack_bit = (((v_depth - 1u) & 15u) * 2u);
32616               if (0u == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1u)) << v_stack_bit))) {
32617                 v_vminor = 2113569u;
32618                 v_vminor_alt = 2105410u;
32619               } else {
32620                 v_vminor = 2113601u;
32621                 v_vminor_alt = 2113602u;
32622               }
32623             }
32624             *iop_a_dst++ = wuffs_base__make_token(
32625                 (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32626                 (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32627             if (v_c_minor == 0u) {
32628               *iop_a_dst++ = wuffs_base__make_token(
32629                   (((uint64_t)(v_vminor_alt)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32630                   (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32631               goto label__goto_parsed_a_leaf_value__break;
32632             }
32633             v_stack_byte = (v_depth / 16u);
32634             v_stack_bit = ((v_depth & 15u) * 2u);
32635             self->private_data.f_stack[v_stack_byte] |= (((uint32_t)(3u)) << v_stack_bit);
32636             self->private_data.f_container_num_remaining[v_depth] = v_string_length;
32637             v_depth += 1u;
32638             v_tagged = false;
32639             goto label__outer__continue;
32640           } else if (v_c_major == 6u) {
32641             if (v_c_minor >= 28u) {
32642               break;
32643             }
32644             if (v_string_length < 262144u) {
32645               *iop_a_dst++ = wuffs_base__make_token(
32646                   (((uint64_t)(787997u)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) |
32647                   (((uint64_t)((4194304u | ((uint32_t)(v_string_length))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32648                   (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32649             } else {
32650               *iop_a_dst++ = wuffs_base__make_token(
32651                   (((uint64_t)(787997u)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) |
32652                   (((uint64_t)((4194304u | ((uint32_t)((v_string_length >> 46u)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32653                   (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32654                   (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32655               *iop_a_dst++ = wuffs_base__make_token(
32656                   (~(v_string_length & 70368744177663u) << WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT) |
32657                   (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32658             }
32659             v_tagged = true;
32660             goto label__outer__continue;
32661           } else if (v_c_major == 7u) {
32662             if (v_c_minor < 20u) {
32663               *iop_a_dst++ = wuffs_base__make_token(
32664                   (((uint64_t)(787997u)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) |
32665                   (((uint64_t)((8388608u | ((uint32_t)((v_string_length & 255u)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32666                   (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32667               goto label__goto_parsed_a_leaf_value__break;
32668             } else if (v_c_minor < 24u) {
32669               *iop_a_dst++ = wuffs_base__make_token(
32670                   (((uint64_t)(WUFFS_CBOR__LITERALS[(v_c_minor & 3u)])) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32671                   (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32672               goto label__goto_parsed_a_leaf_value__break;
32673             } else if (v_c_minor == 24u) {
32674               if (v_string_length < 24u) {
32675                 if ( ! (iop_a_src > io1_a_src)) {
32676                   status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_i_o);
32677                   goto exit;
32678                 }
32679                 iop_a_src--;
32680                 break;
32681               }
32682               *iop_a_dst++ = wuffs_base__make_token(
32683                   (((uint64_t)(787997u)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) |
32684                   (((uint64_t)((8388608u | ((uint32_t)((v_string_length & 255u)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32685                   (((uint64_t)(2u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32686               goto label__goto_parsed_a_leaf_value__break;
32687             } else if (v_c_minor < 28u) {
32688               *iop_a_dst++ = wuffs_base__make_token(
32689                   (((uint64_t)(10490113u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32690                   (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32691               goto label__goto_parsed_a_leaf_value__break;
32692             } else if (v_c_minor == 31u) {
32693               if (v_tagged || (v_depth <= 0u)) {
32694                 break;
32695               }
32696               v_depth -= 1u;
32697               if (self->private_data.f_container_num_remaining[v_depth] != 0u) {
32698                 break;
32699               }
32700               v_stack_byte = (v_depth / 16u);
32701               v_stack_bit = ((v_depth & 15u) * 2u);
32702               v_stack_val = (3u & (self->private_data.f_stack[v_stack_byte] >> v_stack_bit));
32703               if (v_stack_val == 1u) {
32704                 break;
32705               }
32706               if (v_stack_val != 3u) {
32707                 v_vminor_alt = 2097186u;
32708               } else {
32709                 v_vminor_alt = 2097218u;
32710               }
32711               if (v_depth <= 0u) {
32712                 v_vminor_alt |= 4096u;
32713               } else {
32714                 v_stack_byte = ((v_depth - 1u) / 16u);
32715                 v_stack_bit = (((v_depth - 1u) & 15u) * 2u);
32716                 if (0u == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1u)) << v_stack_bit))) {
32717                   v_vminor_alt |= 8192u;
32718                 } else {
32719                   v_vminor_alt |= 16384u;
32720                 }
32721               }
32722               *iop_a_dst++ = wuffs_base__make_token(
32723                   (((uint64_t)(v_vminor_alt)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32724                   (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32725               goto label__goto_parsed_a_leaf_value__break;
32726             }
32727           }
32728         } while (0);
32729         if (iop_a_src > io1_a_src) {
32730           iop_a_src--;
32731           status = wuffs_base__make_status(wuffs_cbor__error__bad_input);
32732           goto exit;
32733         }
32734         status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_i_o);
32735         goto exit;
32736       }
32737       label__goto_parsed_a_leaf_value__break:;
32738       v_tagged = false;
32739       while (v_depth > 0u) {
32740         v_stack_byte = ((v_depth - 1u) / 16u);
32741         v_stack_bit = (((v_depth - 1u) & 15u) * 2u);
32742         self->private_data.f_stack[v_stack_byte] ^= (((uint32_t)(1u)) << (v_stack_bit + 1u));
32743         if (1u == (3u & (self->private_data.f_stack[v_stack_byte] >> v_stack_bit))) {
32744           goto label__outer__continue;
32745         }
32746         if (self->private_data.f_container_num_remaining[(v_depth - 1u)] <= 0u) {
32747           goto label__outer__continue;
32748         }
32749         self->private_data.f_container_num_remaining[(v_depth - 1u)] -= 1u;
32750         if (self->private_data.f_container_num_remaining[(v_depth - 1u)] > 0u) {
32751           goto label__outer__continue;
32752         }
32753         while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
32754           status = wuffs_base__make_status(wuffs_base__suspension__short_write);
32755           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8);
32756           continue;
32757         }
32758         v_depth -= 1u;
32759         v_stack_byte = (v_depth / 16u);
32760         v_stack_bit = ((v_depth & 15u) * 2u);
32761         if (0u == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1u)) << v_stack_bit))) {
32762           v_vminor_alt = 2097186u;
32763         } else {
32764           v_vminor_alt = 2097218u;
32765         }
32766         if (v_depth <= 0u) {
32767           v_vminor_alt |= 4096u;
32768         } else {
32769           v_stack_byte = ((v_depth - 1u) / 16u);
32770           v_stack_bit = (((v_depth - 1u) & 15u) * 2u);
32771           if (0u == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1u)) << v_stack_bit))) {
32772             v_vminor_alt |= 8192u;
32773           } else {
32774             v_vminor_alt |= 16384u;
32775           }
32776         }
32777         *iop_a_dst++ = wuffs_base__make_token(
32778             (((uint64_t)(v_vminor_alt)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32779             (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32780       }
32781       break;
32782     }
32783     self->private_impl.f_end_of_data = true;
32784 
32785     ok:
32786     self->private_impl.p_decode_tokens[0] = 0;
32787     goto exit;
32788   }
32789 
32790   goto suspend;
32791   suspend:
32792   self->private_impl.p_decode_tokens[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
32793   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
32794   self->private_data.s_decode_tokens[0].v_string_length = v_string_length;
32795   self->private_data.s_decode_tokens[0].v_depth = v_depth;
32796   self->private_data.s_decode_tokens[0].v_tagged = v_tagged;
32797   self->private_data.s_decode_tokens[0].v_indefinite_string_major_type = v_indefinite_string_major_type;
32798 
32799   goto exit;
32800   exit:
32801   if (a_dst && a_dst->data.ptr) {
32802     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
32803   }
32804   if (a_src && a_src->data.ptr) {
32805     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
32806   }
32807 
32808   if (wuffs_base__status__is_error(&status)) {
32809     self->private_impl.magic = WUFFS_BASE__DISABLED;
32810   }
32811   return status;
32812 }
32813 
32814 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CBOR)
32815 
32816 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CRC32)
32817 
32818 // ---------------- Status Codes Implementations
32819 
32820 // ---------------- Private Consts
32821 
32822 static const uint32_t
32823 WUFFS_CRC32__IEEE_TABLE[16][256] WUFFS_BASE__POTENTIALLY_UNUSED = {
32824   {
32825     0, 1996959894, 3993919788, 2567524794, 124634137, 1886057615, 3915621685, 2657392035,
32826     249268274, 2044508324, 3772115230, 2547177864, 162941995, 2125561021, 3887607047, 2428444049,
32827     498536548, 1789927666, 4089016648, 2227061214, 450548861, 1843258603, 4107580753, 2211677639,
32828     325883990, 1684777152, 4251122042, 2321926636, 335633487, 1661365465, 4195302755, 2366115317,
32829     997073096, 1281953886, 3579855332, 2724688242, 1006888145, 1258607687, 3524101629, 2768942443,
32830     901097722, 1119000684, 3686517206, 2898065728, 853044451, 1172266101, 3705015759, 2882616665,
32831     651767980, 1373503546, 3369554304, 3218104598, 565507253, 1454621731, 3485111705, 3099436303,
32832     671266974, 1594198024, 3322730930, 2970347812, 795835527, 1483230225, 3244367275, 3060149565,
32833     1994146192, 31158534, 2563907772, 4023717930, 1907459465, 112637215, 2680153253, 3904427059,
32834     2013776290, 251722036, 2517215374, 3775830040, 2137656763, 141376813, 2439277719, 3865271297,
32835     1802195444, 476864866, 2238001368, 4066508878, 1812370925, 453092731, 2181625025, 4111451223,
32836     1706088902, 314042704, 2344532202, 4240017532, 1658658271, 366619977, 2362670323, 4224994405,
32837     1303535960, 984961486, 2747007092, 3569037538, 1256170817, 1037604311, 2765210733, 3554079995,
32838     1131014506, 879679996, 2909243462, 3663771856, 1141124467, 855842277, 2852801631, 3708648649,
32839     1342533948, 654459306, 3188396048, 3373015174, 1466479909, 544179635, 3110523913, 3462522015,
32840     1591671054, 702138776, 2966460450, 3352799412, 1504918807, 783551873, 3082640443, 3233442989,
32841     3988292384, 2596254646, 62317068, 1957810842, 3939845945, 2647816111, 81470997, 1943803523,
32842     3814918930, 2489596804, 225274430, 2053790376, 3826175755, 2466906013, 167816743, 2097651377,
32843     4027552580, 2265490386, 503444072, 1762050814, 4150417245, 2154129355, 426522225, 1852507879,
32844     4275313526, 2312317920, 282753626, 1742555852, 4189708143, 2394877945, 397917763, 1622183637,
32845     3604390888, 2714866558, 953729732, 1340076626, 3518719985, 2797360999, 1068828381, 1219638859,
32846     3624741850, 2936675148, 906185462, 1090812512, 3747672003, 2825379669, 829329135, 1181335161,
32847     3412177804, 3160834842, 628085408, 1382605366, 3423369109, 3138078467, 570562233, 1426400815,
32848     3317316542, 2998733608, 733239954, 1555261956, 3268935591, 3050360625, 752459403, 1541320221,
32849     2607071920, 3965973030, 1969922972, 40735498, 2617837225, 3943577151, 1913087877, 83908371,
32850     2512341634, 3803740692, 2075208622, 213261112, 2463272603, 3855990285, 2094854071, 198958881,
32851     2262029012, 4057260610, 1759359992, 534414190, 2176718541, 4139329115, 1873836001, 414664567,
32852     2282248934, 4279200368, 1711684554, 285281116, 2405801727, 4167216745, 1634467795, 376229701,
32853     2685067896, 3608007406, 1308918612, 956543938, 2808555105, 3495958263, 1231636301, 1047427035,
32854     2932959818, 3654703836, 1088359270, 936918000, 2847714899, 3736837829, 1202900863, 817233897,
32855     3183342108, 3401237130, 1404277552, 615818150, 3134207493, 3453421203, 1423857449, 601450431,
32856     3009837614, 3294710456, 1567103746, 711928724, 3020668471, 3272380065, 1510334235, 755167117,
32857   }, {
32858     0, 421212481, 842424962, 724390851, 1684849924, 2105013317, 1448781702, 1329698503,
32859     3369699848, 3519200073, 4210026634, 3824474571, 2897563404, 3048111693, 2659397006, 2274893007,
32860     1254232657, 1406739216, 2029285587, 1643069842, 783210325, 934667796, 479770071, 92505238,
32861     2182846553, 2600511768, 2955803355, 2838940570, 3866582365, 4285295644, 3561045983, 3445231262,
32862     2508465314, 2359236067, 2813478432, 3198777185, 4058571174, 3908292839, 3286139684, 3670389349,
32863     1566420650, 1145479147, 1869335592, 1987116393, 959540142, 539646703, 185010476, 303839341,
32864     3745920755, 3327985586, 3983561841, 4100678960, 3140154359, 2721170102, 2300350837, 2416418868,
32865     396344571, 243568058, 631889529, 1018359608, 1945336319, 1793607870, 1103436669, 1490954812,
32866     4034481925, 3915546180, 3259968903, 3679722694, 2484439553, 2366552896, 2787371139, 3208174018,
32867     950060301, 565965900, 177645455, 328046286, 1556873225, 1171730760, 1861902987, 2011255754,
32868     3132841300, 2745199637, 2290958294, 2442530455, 3738671184, 3352078609, 3974232786, 4126854035,
32869     1919080284, 1803150877, 1079293406, 1498383519, 370020952, 253043481, 607678682, 1025720731,
32870     1711106983, 2095471334, 1472923941, 1322268772, 26324643, 411738082, 866634785, 717028704,
32871     2904875439, 3024081134, 2668790573, 2248782444, 3376948395, 3495106026, 4219356713, 3798300520,
32872     792689142, 908347575, 487136116, 68299317, 1263779058, 1380486579, 2036719216, 1618931505,
32873     3890672638, 4278043327, 3587215740, 3435896893, 2206873338, 2593195963, 2981909624, 2829542713,
32874     998479947, 580430090, 162921161, 279890824, 1609522511, 1190423566, 1842954189, 1958874764,
32875     4082766403, 3930137346, 3245109441, 3631694208, 2536953671, 2385372678, 2768287173, 3155920004,
32876     1900120602, 1750776667, 1131931800, 1517083097, 355290910, 204897887, 656092572, 1040194781,
32877     3113746450, 2692952403, 2343461520, 2461357009, 3723805974, 3304059991, 4022511508, 4141455061,
32878     2919742697, 3072101800, 2620513899, 2234183466, 3396041197, 3547351212, 4166851439, 3779471918,
32879     1725839073, 2143618976, 1424512099, 1307796770, 45282277, 464110244, 813994343, 698327078,
32880     3838160568, 4259225593, 3606301754, 3488152955, 2158586812, 2578602749, 2996767038, 2877569151,
32881     740041904, 889656817, 506086962, 120682355, 1215357364, 1366020341, 2051441462, 1667084919,
32882     3422213966, 3538019855, 4190942668, 3772220557, 2945847882, 3062702859, 2644537544, 2226864521,
32883     52649286, 439905287, 823476164, 672009861, 1733269570, 2119477507, 1434057408, 1281543041,
32884     2167981343, 2552493150, 3004082077, 2853541596, 3847487515, 4233048410, 3613549209, 3464057816,
32885     1239502615, 1358593622, 2077699477, 1657543892, 764250643, 882293586, 532408465, 111204816,
32886     1585378284, 1197851309, 1816695150, 1968414767, 974272232, 587794345, 136598634, 289367339,
32887     2527558116, 2411481253, 2760973158, 3179948583, 4073438432, 3956313505, 3237863010, 3655790371,
32888     347922877, 229101820, 646611775, 1066513022, 1892689081, 1774917112, 1122387515, 1543337850,
32889     3697634229, 3313392372, 3998419255, 4148705398, 3087642289, 2702352368, 2319436851, 2468674930,
32890   }, {
32891     0, 29518391, 59036782, 38190681, 118073564, 114017003, 76381362, 89069189,
32892     236147128, 265370511, 228034006, 206958561, 152762724, 148411219, 178138378, 190596925,
32893     472294256, 501532999, 530741022, 509615401, 456068012, 451764635, 413917122, 426358261,
32894     305525448, 334993663, 296822438, 275991697, 356276756, 352202787, 381193850, 393929805,
32895     944588512, 965684439, 1003065998, 973863097, 1061482044, 1049003019, 1019230802, 1023561829,
32896     912136024, 933002607, 903529270, 874031361, 827834244, 815125939, 852716522, 856752605,
32897     611050896, 631869351, 669987326, 640506825, 593644876, 580921211, 551983394, 556069653,
32898     712553512, 733666847, 704405574, 675154545, 762387700, 749958851, 787859610, 792175277,
32899     1889177024, 1901651959, 1931368878, 1927033753, 2006131996, 1985040171, 1947726194, 1976933189,
32900     2122964088, 2135668303, 2098006038, 2093965857, 2038461604, 2017599123, 2047123658, 2076625661,
32901     1824272048, 1836991623, 1866005214, 1861914857, 1807058540, 1786244187, 1748062722, 1777547317,
32902     1655668488, 1668093247, 1630251878, 1625932113, 1705433044, 1684323811, 1713505210, 1742760333,
32903     1222101792, 1226154263, 1263738702, 1251046777, 1339974652, 1310460363, 1281013650, 1301863845,
32904     1187289752, 1191637167, 1161842422, 1149379777, 1103966788, 1074747507, 1112139306, 1133218845,
32905     1425107024, 1429406311, 1467333694, 1454888457, 1408811148, 1379576507, 1350309090, 1371438805,
32906     1524775400, 1528845279, 1499917702, 1487177649, 1575719220, 1546255107, 1584350554, 1605185389,
32907     3778354048, 3774312887, 3803303918, 3816007129, 3862737756, 3892238699, 3854067506, 3833203973,
32908     4012263992, 4007927823, 3970080342, 3982554209, 3895452388, 3924658387, 3953866378, 3932773565,
32909     4245928176, 4241609415, 4271336606, 4283762345, 4196012076, 4225268251, 4187931714, 4166823541,
32910     4076923208, 4072833919, 4035198246, 4047918865, 4094247316, 4123732899, 4153251322, 4132437965,
32911     3648544096, 3636082519, 3673983246, 3678331705, 3732010428, 3753090955, 3723829714, 3694611429,
32912     3614117080, 3601426159, 3572488374, 3576541825, 3496125444, 3516976691, 3555094634, 3525581405,
32913     3311336976, 3298595879, 3336186494, 3340255305, 3260503756, 3281337595, 3251864226, 3222399125,
32914     3410866088, 3398419871, 3368647622, 3372945905, 3427010420, 3448139075, 3485520666, 3456284973,
32915     2444203584, 2423127159, 2452308526, 2481530905, 2527477404, 2539934891, 2502093554, 2497740997,
32916     2679949304, 2659102159, 2620920726, 2650438049, 2562027300, 2574714131, 2603727690, 2599670141,
32917     2374579504, 2353749767, 2383274334, 2412743529, 2323684844, 2336421851, 2298759554, 2294686645,
32918     2207933576, 2186809023, 2149495014, 2178734801, 2224278612, 2236720739, 2266437690, 2262135309,
32919     2850214048, 2820717207, 2858812622, 2879680249, 2934667388, 2938704459, 2909776914, 2897069605,
32920     2817622296, 2788420399, 2759153014, 2780249921, 2700618180, 2704950259, 2742877610, 2730399645,
32921     3049550800, 3020298727, 3057690558, 3078802825, 2999835404, 3004150075, 2974355298, 2961925461,
32922     3151438440, 3121956959, 3092510214, 3113327665, 3168701108, 3172786307, 3210370778, 3197646061,
32923   }, {
32924     0, 3099354981, 2852767883, 313896942, 2405603159, 937357362, 627793884, 2648127673,
32925     3316918511, 2097696650, 1874714724, 3607201537, 1255587768, 4067088605, 3772741427, 1482887254,
32926     1343838111, 3903140090, 4195393300, 1118632049, 3749429448, 1741137837, 1970407491, 3452858150,
32927     2511175536, 756094997, 1067759611, 2266550430, 449832999, 2725482306, 2965774508, 142231497,
32928     2687676222, 412010587, 171665333, 2995192016, 793786473, 2548850444, 2237264098, 1038456711,
32929     1703315409, 3711623348, 3482275674, 1999841343, 3940814982, 1381529571, 1089329165, 4166106984,
32930     4029413537, 1217896388, 1512189994, 3802027855, 2135519222, 3354724499, 3577784189, 1845280792,
32931     899665998, 2367928107, 2677414085, 657096608, 3137160985, 37822588, 284462994, 2823350519,
32932     2601801789, 598228824, 824021174, 2309093331, 343330666, 2898962447, 3195996129, 113467524,
32933     1587572946, 3860600759, 4104763481, 1276501820, 3519211397, 1769898208, 2076913422, 3279374443,
32934     3406630818, 1941006535, 1627703081, 3652755532, 1148164341, 4241751952, 3999682686, 1457141531,
32935     247015245, 3053797416, 2763059142, 470583459, 2178658330, 963106687, 735213713, 2473467892,
32936     992409347, 2207944806, 2435792776, 697522413, 3024379988, 217581361, 508405983, 2800865210,
32937     4271038444, 1177467017, 1419450215, 3962007554, 1911572667, 3377213406, 3690561584, 1665525589,
32938     1799331996, 3548628985, 3241568279, 2039091058, 3831314379, 1558270126, 1314193216, 4142438437,
32939     2928380019, 372764438, 75645176, 3158189981, 568925988, 2572515393, 2346768303, 861712586,
32940     3982079547, 1441124702, 1196457648, 4293663189, 1648042348, 3666298377, 3358779879, 1888390786,
32941     686661332, 2421291441, 2196002399, 978858298, 2811169155, 523464422, 226935048, 3040519789,
32942     3175145892, 100435649, 390670639, 2952089162, 841119475, 2325614998, 2553003640, 546822429,
32943     2029308235, 3225988654, 3539796416, 1782671013, 4153826844, 1328167289, 1570739863, 3844338162,
32944     1298864389, 4124540512, 3882013070, 1608431339, 3255406162, 2058742071, 1744848601, 3501990332,
32945     2296328682, 811816591, 584513889, 2590678532, 129869501, 3204563416, 2914283062, 352848211,
32946     494030490, 2781751807, 3078325777, 264757620, 2450577869, 715964072, 941166918, 2158327331,
32947     3636881013, 1618608400, 1926213374, 3396585883, 1470427426, 4011365959, 4255988137, 1158766284,
32948     1984818694, 3471935843, 3695453837, 1693991400, 4180638033, 1100160564, 1395044826, 3952793279,
32949     3019491049, 189112716, 435162722, 2706139399, 1016811966, 2217162459, 2526189877, 774831696,
32950     643086745, 2666061564, 2354934034, 887166583, 2838900430, 294275499, 54519365, 3145957664,
32951     3823145334, 1532818963, 1240029693, 4048895640, 1820460577, 3560857924, 3331051178, 2117577167,
32952     3598663992, 1858283101, 2088143283, 3301633750, 1495127663, 3785470218, 4078182116, 1269332353,
32953     332098007, 2876706482, 3116540252, 25085497, 2628386432, 605395429, 916469259, 2384220526,
32954     2254837415, 1054503362, 745528876, 2496903497, 151290352, 2981684885, 2735556987, 464596510,
32955     1137851976, 4218313005, 3923506883, 1365741990, 3434129695, 1946996346, 1723425172, 3724871409,
32956   }, {
32957     0, 1029712304, 2059424608, 1201699536, 4118849216, 3370159984, 2403399072, 2988497936,
32958     812665793, 219177585, 1253054625, 2010132753, 3320900865, 4170237105, 3207642721, 2186319825,
32959     1625331586, 1568718386, 438355170, 658566482, 2506109250, 2818578674, 4020265506, 3535817618,
32960     1351670851, 1844508147, 709922595, 389064339, 2769320579, 2557498163, 3754961379, 3803185235,
32961     3250663172, 4238411444, 3137436772, 2254525908, 876710340, 153198708, 1317132964, 1944187668,
32962     4054934725, 3436268917, 2339452837, 3054575125, 70369797, 961670069, 2129760613, 1133623509,
32963     2703341702, 2621542710, 3689016294, 3867263574, 1419845190, 1774270454, 778128678, 318858390,
32964     2438067015, 2888948471, 3952189479, 3606153623, 1691440519, 1504803895, 504432359, 594620247,
32965     1492342857, 1704161785, 573770537, 525542041, 2910060169, 2417219385, 3618876905, 3939730521,
32966     1753420680, 1440954936, 306397416, 790849880, 2634265928, 2690882808, 3888375336, 3668168600,
32967     940822475, 91481723, 1121164459, 2142483739, 3448989963, 4042473659, 3075684971, 2318603227,
32968     140739594, 889433530, 1923340138, 1338244826, 4259521226, 3229813626, 2267247018, 3124975642,
32969     2570221389, 2756861693, 3824297005, 3734113693, 1823658381, 1372780605, 376603373, 722643805,
32970     2839690380, 2485261628, 3548540908, 4007806556, 1556257356, 1638052860, 637716780, 459464860,
32971     4191346895, 3300051327, 2199040943, 3195181599, 206718479, 825388991, 1989285231, 1274166495,
32972     3382881038, 4106388158, 3009607790, 2382549470, 1008864718, 21111934, 1189240494, 2072147742,
32973     2984685714, 2357631266, 3408323570, 4131834434, 1147541074, 2030452706, 1051084082, 63335554,
32974     2174155603, 3170292451, 4216760371, 3325460867, 1947622803, 1232499747, 248909555, 867575619,
32975     3506841360, 3966111392, 2881909872, 2527485376, 612794832, 434546784, 1581699760, 1663499008,
32976     3782634705, 3692447073, 2612412337, 2799048193, 351717905, 697754529, 1849071985, 1398190273,
32977     1881644950, 1296545318, 182963446, 931652934, 2242328918, 3100053734, 4284967478, 3255255942,
32978     1079497815, 2100821479, 983009079, 133672583, 3050795671, 2293717799, 3474399735, 4067887175,
32979     281479188, 765927844, 1778867060, 1466397380, 3846680276, 3626469220, 2676489652, 2733102084,
32980     548881365, 500656741, 1517752501, 1729575173, 3577210133, 3898068133, 2952246901, 2459410373,
32981     3910527195, 3564487019, 2480257979, 2931134987, 479546907, 569730987, 1716854139, 1530213579,
32982     3647316762, 3825568426, 2745561210, 2663766474, 753206746, 293940330, 1445287610, 1799716618,
32983     2314567513, 3029685993, 4080348217, 3461678473, 2088098201, 1091956777, 112560889, 1003856713,
32984     3112514712, 2229607720, 3276105720, 4263857736, 1275433560, 1902492648, 918929720, 195422344,
32985     685033439, 364179055, 1377080511, 1869921551, 3713294623, 3761522863, 2811507327, 2599689167,
32986     413436958, 633644462, 1650777982, 1594160846, 3978570462, 3494118254, 2548332990, 2860797966,
32987     1211387997, 1968470509, 854852413, 261368461, 3182753437, 2161434413, 3346310653, 4195650637,
32988     2017729436, 1160000044, 42223868, 1071931724, 2378480988, 2963576044, 4144295484, 3395602316,
32989   }, {
32990     0, 3411858341, 1304994059, 2257875630, 2609988118, 1355649459, 3596215069, 486879416,
32991     3964895853, 655315400, 2711298918, 1791488195, 2009251963, 3164476382, 973758832, 4048990933,
32992     64357019, 3364540734, 1310630800, 2235723829, 2554806413, 1394316072, 3582976390, 517157411,
32993     4018503926, 618222419, 2722963965, 1762783832, 1947517664, 3209171269, 970744811, 4068520014,
32994     128714038, 3438335635, 1248109629, 2167961496, 2621261600, 1466012805, 3522553387, 447296910,
32995     3959392091, 547575038, 2788632144, 1835791861, 1886307661, 3140622056, 1034314822, 4143626211,
32996     75106221, 3475428360, 1236444838, 2196665603, 2682996155, 1421317662, 3525567664, 427767573,
32997     3895035328, 594892389, 2782995659, 1857943406, 1941489622, 3101955187, 1047553757, 4113347960,
32998     257428076, 3288652233, 1116777319, 2311878850, 2496219258, 1603640287, 3640781169, 308099796,
32999     3809183745, 676813732, 2932025610, 1704983215, 2023410199, 3016104370, 894593820, 4262377657,
33000     210634999, 3352484690, 1095150076, 2316991065, 2535410401, 1547934020, 3671583722, 294336591,
33001     3772615322, 729897279, 2903845777, 1716123700, 2068629644, 2953845545, 914647431, 4258839074,
33002     150212442, 3282623743, 1161604689, 2388688372, 2472889676, 1480171241, 3735940167, 368132066,
33003     3836185911, 805002898, 2842635324, 1647574937, 2134298401, 3026852996, 855535146, 4188192143,
33004     186781121, 3229539940, 1189784778, 2377547631, 2427670487, 1542429810, 3715886812, 371670393,
33005     3882979244, 741170185, 2864262823, 1642462466, 2095107514, 3082559007, 824732849, 4201955092,
33006     514856152, 3589064573, 1400419795, 2552522358, 2233554638, 1316849003, 3370776517, 62202976,
33007     4075001525, 968836368, 3207280574, 1954014235, 1769133219, 2720925446, 616199592, 4024870413,
33008     493229635, 3594175974, 1353627464, 2616354029, 2264355925, 1303087088, 3409966430, 6498043,
33009     4046820398, 979978123, 3170710821, 2007099008, 1789187640, 2717386141, 661419827, 3962610838,
33010     421269998, 3527459403, 1423225061, 2676515648, 2190300152, 1238466653, 3477467891, 68755798,
33011     4115633027, 1041448998, 3095868040, 1943789869, 1860096405, 2776760880, 588673182, 3897205563,
33012     449450869, 3516317904, 1459794558, 2623431131, 2170245475, 1242006214, 3432247400, 131015629,
33013     4137259288, 1036337853, 3142660115, 1879958454, 1829294862, 2790523051, 549483013, 3952910752,
33014     300424884, 3669282065, 1545650111, 2541513754, 2323209378, 1092980487, 3350330793, 216870412,
33015     4256931033, 921128828, 2960342482, 2066738807, 1714085583, 2910195050, 736264132, 3770592353,
33016     306060335, 3647131530, 1610005796, 2494197377, 2309971513, 1123257756, 3295149874, 255536279,
33017     4268596802, 892423655, 3013951305, 2029645036, 1711070292, 2929725425, 674528607, 3815288570,
33018     373562242, 3709388839, 1535949449, 2429577516, 2379569556, 1183418929, 3223189663, 188820282,
33019     4195850735, 827017802, 3084859620, 2089020225, 1636228089, 2866415708, 743340786, 3876759895,
33020     361896217, 3738094268, 1482340370, 2466671543, 2382584591, 1163888810, 3284924932, 144124321,
33021     4190215028, 849168593, 3020503679, 2136336858, 1649465698, 2836138695, 798521449, 3838094284,
33022   }, {
33023     0, 2792819636, 2543784233, 837294749, 4098827283, 1379413927, 1674589498, 3316072078,
33024     871321191, 2509784531, 2758827854, 34034938, 3349178996, 1641505216, 1346337629, 4131942633,
33025     1742642382, 3249117050, 4030828007, 1446413907, 2475800797, 904311657, 68069876, 2725880384,
33026     1412551337, 4064729373, 3283010432, 1708771380, 2692675258, 101317902, 937551763, 2442587175,
33027     3485284764, 1774858792, 1478633653, 4266992385, 1005723023, 2642744891, 2892827814, 169477906,
33028     4233263099, 1512406095, 1808623314, 3451546982, 136139752, 2926205020, 2676114113, 972376437,
33029     2825102674, 236236518, 1073525883, 2576072655, 1546420545, 4200303349, 3417542760, 1841601500,
33030     2609703733, 1039917185, 202635804, 2858742184, 1875103526, 3384067218, 4166835727, 1579931067,
33031     1141601657, 3799809741, 3549717584, 1977839588, 2957267306, 372464350, 668680259, 2175552503,
33032     2011446046, 3516084394, 3766168119, 1175200131, 2209029901, 635180217, 338955812, 2990736784,
33033     601221559, 2242044419, 3024812190, 306049834, 3617246628, 1911408144, 1074125965, 3866285881,
33034     272279504, 3058543716, 2275784441, 567459149, 3832906691, 1107462263, 1944752874, 3583875422,
33035     2343980261, 767641425, 472473036, 3126744696, 2147051766, 3649987394, 3899029983, 1309766251,
33036     3092841090, 506333494, 801510315, 2310084639, 1276520081, 3932237093, 3683203000, 2113813516,
33037     3966292011, 1243601823, 2079834370, 3716205238, 405271608, 3192979340, 2411259153, 701492901,
33038     3750207052, 2045810168, 1209569125, 4000285905, 734575199, 2378150379, 3159862134, 438345922,
33039     2283203314, 778166598, 529136603, 3120492655, 2086260449, 3660498261, 3955679176, 1303499900,
33040     3153699989, 495890209, 744928700, 2316418568, 1337360518, 3921775410, 3626602927, 2120129051,
33041     4022892092, 1237286280, 2018993941, 3726666913, 461853231, 3186645403, 2350400262, 711936178,
33042     3693557851, 2052076527, 1270360434, 3989775046, 677911624, 2384402428, 3220639073, 427820757,
33043     1202443118, 3789347034, 3493118535, 1984154099, 3018127229, 362020041, 612099668, 2181885408,
33044     1950653705, 3526596285, 3822816288, 1168934804, 2148251930, 645706414, 395618355, 2984485767,
33045     544559008, 2248295444, 3085590153, 295523645, 3560598451, 1917673479, 1134918298, 3855773998,
33046     328860103, 3052210803, 2214924526, 577903450, 3889505748, 1101147744, 1883911421, 3594338121,
33047     3424493451, 1785369663, 1535282850, 4260726038, 944946072, 2653270060, 2949491377, 163225861,
33048     4294103532, 1501944408, 1752023237, 3457862513, 196998655, 2915761739, 2619532502, 978710370,
33049     2881684293, 229902577, 1012666988, 2586515928, 1603020630, 4193987810, 3356702335, 1852063179,
33050     2553040162, 1046169238, 263412747, 2848217023, 1818454321, 3390333573, 4227627032, 1569420204,
33051     60859927, 2782375331, 2487203646, 843627658, 4159668740, 1368951216, 1617990445, 3322386585,
33052     810543216, 2520310724, 2815490393, 27783917, 3288386659, 1652017111, 1402985802, 4125677310,
33053     1685994201, 3255382381, 4091620336, 1435902020, 2419138250, 910562686, 128847843, 2715354199,
33054     1469150398, 4058414858, 3222168983, 1719234083, 2749255853, 94984985, 876691844, 2453031472,
33055   }, {
33056     0, 3433693342, 1109723005, 2391738339, 2219446010, 1222643300, 3329165703, 180685081,
33057     3555007413, 525277995, 2445286600, 1567235158, 1471092047, 2600801745, 361370162, 3642757804,
33058     2092642603, 2953916853, 1050555990, 4063508168, 4176560081, 878395215, 3134470316, 1987983410,
33059     2942184094, 1676945920, 3984272867, 567356797, 722740324, 3887998202, 1764827929, 2778407815,
33060     4185285206, 903635656, 3142804779, 2012833205, 2101111980, 2979425330, 1058630609, 4088621903,
33061     714308067, 3862526333, 1756790430, 2753330688, 2933487385, 1651734407, 3975966820, 542535930,
33062     2244825981, 1231508451, 3353891840, 188896414, 25648519, 3442302233, 1134713594, 2399689316,
33063     1445480648, 2592229462, 336416693, 3634843435, 3529655858, 516441772, 2420588879, 1559052753,
33064     698204909, 3845636723, 1807271312, 2803025166, 2916600855, 1635634313, 4025666410, 593021940,
33065     4202223960, 919787974, 3093159461, 1962401467, 2117261218, 2996361020, 1008193759, 4038971457,
33066     1428616134, 2576151384, 386135227, 3685348389, 3513580860, 499580322, 2471098945, 1608776415,
33067     2260985971, 1248454893, 3303468814, 139259792, 42591881, 3458459159, 1085071860, 2349261162,
33068     3505103035, 474062885, 2463016902, 1583654744, 1419882049, 2550902495, 377792828, 3660491170,
33069     51297038, 3483679632, 1093385331, 2374089965, 2269427188, 1273935210, 3311514249, 164344343,
33070     2890961296, 1627033870, 4000683757, 585078387, 672833386, 3836780532, 1782552599, 2794821769,
33071     2142603813, 3005188795, 1032883544, 4047146438, 4227826911, 928351297, 3118105506, 1970307900,
33072     1396409818, 2677114180, 287212199, 3719594553, 3614542624, 467372990, 2505346141, 1509854403,
33073     2162073199, 1282711281, 3271268626, 240228748, 76845205, 3359543307, 1186043880, 2317064054,
33074     796964081, 3811226735, 1839575948, 2702160658, 2882189835, 1734392469, 3924802934, 625327592,
33075     4234522436, 818917338, 3191908409, 1927981223, 2016387518, 3028656416, 973776579, 4137723485,
33076     2857232268, 1726474002, 3899187441, 616751215, 772270454, 3803048424, 1814228491, 2693328533,
33077     2041117753, 3036871847, 999160644, 4146592730, 4259508931, 826864221, 3217552830, 1936586016,
33078     3606501031, 442291769, 2496909786, 1484378436, 1388107869, 2652297411, 278519584, 3694387134,
33079     85183762, 3384397196, 1194773103, 2342308593, 2170143720, 1307820918, 3279733909, 265733131,
33080     2057717559, 3054258089, 948125770, 4096344276, 4276898253, 843467091, 3167309488, 1885556270,
33081     2839764098, 1709792284, 3949353983, 667704161, 755585656, 3785577190, 1865176325, 2743489947,
33082     102594076, 3401021058, 1144549729, 2291298815, 2186770662, 1325234296, 3228729243, 215514885,
33083     3589828009, 424832311, 2547870420, 1534552650, 1370645331, 2635621325, 328688686, 3745342640,
33084     2211456353, 1333405183, 3254067740, 224338562, 127544219, 3408931589, 1170156774, 2299866232,
33085     1345666772, 2627681866, 303053225, 3736746295, 3565105198, 416624816, 2522494803, 1525692365,
33086     4285207626, 868291796, 3176010551, 1910772649, 2065767088, 3079346734, 956571085, 4121828691,
33087     747507711, 3760459617, 1856702594, 2717976604, 2831417605, 1684930971, 3940615800, 642451174,
33088   },
33089   {
33090     0, 393942083, 787884166, 965557445, 1575768332, 1251427663, 1931114890, 1684106697,
33091     3151536664, 2896410203, 2502855326, 2186649309, 3862229780, 4048545623, 3368213394, 3753496529,
33092     2898281073, 3149616690, 2184604407, 2504883892, 4046197629, 3864463166, 3755621371, 3366006712,
33093     387506281, 6550570, 971950319, 781573292, 1257550181, 1569695014, 1677892067, 1937345952,
33094     2196865699, 2508887776, 2886183461, 3145514598, 3743273903, 3362179052, 4058774313, 3868258154,
33095     958996667, 777139448, 400492605, 10755198, 1690661303, 1941857780, 1244879153, 1565019506,
33096     775012562, 961205393, 13101140, 398261271, 1943900638, 1688634781, 1563146584, 1246801179,
33097     2515100362, 2190636681, 3139390028, 2892258831, 3355784134, 3749586821, 3874691904, 4052225795,
33098     3734110983, 3387496260, 4033096577, 3877584834, 2206093835, 2483373640, 2911402637, 3136515790,
33099     1699389727, 1915860316, 1270647193, 1556585946, 950464531, 803071056, 374397077, 19647702,
33100     1917993334, 1697207605, 1554278896, 1272937907, 800985210, 952435769, 21510396, 372452543,
33101     3381322606, 3740399405, 3883715560, 4027047851, 2489758306, 2199758369, 3130039012, 2917895847,
33102     1550025124, 1259902439, 1922410786, 1710144865, 26202280, 385139947, 796522542, 939715693,
33103     3887801276, 4039129087, 3377269562, 3728088953, 3126293168, 2905368307, 2493602358, 2212122229,
33104     4037264341, 3889747862, 3730172755, 3375300368, 2907673305, 3124004506, 2209987167, 2495786524,
33105     1266377165, 1543533966, 1703758155, 1928748296, 379007169, 32253058, 945887303, 790236164,
33106     1716846671, 1898845196, 1218652361, 1608006794, 1002000707, 750929152, 357530053, 36990342,
33107     3717046871, 3405166100, 4084959953, 3825245842, 2153902939, 2535122712, 2929187805, 3119304606,
33108     3398779454, 3723384445, 3831720632, 4078468859, 2541294386, 2147616625, 3113171892, 2935238647,
33109     1900929062, 1714877541, 1606142112, 1220599011, 748794154, 1004184937, 39295404, 355241455,
33110     3835986668, 4091516591, 3394415210, 3710500393, 3108557792, 2922629027, 2545875814, 2160455461,
33111     1601970420, 1208431799, 1904871538, 1727077425, 43020792, 367748539, 744905086, 991776061,
33112     1214562461, 1595921630, 1720903707, 1911159896, 361271697, 49513938, 998160663, 738569556,
33113     4089209477, 3838277318, 3712633347, 3392233024, 2924491657, 3106613194, 2158369551, 2547846988,
33114     3100050248, 2948339467, 2519804878, 2169126797, 3844821572, 4065347079, 3420289730, 3701894785,
33115     52404560, 342144275, 770279894, 982687125, 1593045084, 1233708063, 1879431386, 1736363161,
33116     336019769, 58479994, 988899775, 764050940, 1240141877, 1586496630, 1729968307, 1885744368,
33117     2950685473, 3097818978, 2166999975, 2522013668, 4063474221, 3846743662, 3703937707, 3418263272,
33118     976650731, 760059304, 348170605, 62635310, 1742393575, 1889649828, 1227683937, 1582820386,
33119     2179867635, 2526361520, 2937588597, 3093503798, 3691148031, 3413731004, 4076100217, 3851374138,
33120     2532754330, 2173556697, 3087067932, 2944139103, 3407516310, 3697379029, 3857496592, 4070026835,
33121     758014338, 978679233, 64506116, 346250567, 1891774606, 1740186829, 1580472328, 1229917259,
33122   }, {
33123     0, 4022496062, 83218493, 3946298115, 166436986, 3861498692, 220098631, 3806075769,
33124     332873972, 4229245898, 388141257, 4175494135, 440197262, 4127099824, 516501683, 4044053389,
33125     665747944, 3362581206, 593187285, 3432594155, 776282514, 3246869164, 716239279, 3312622225,
33126     880394524, 3686509090, 814485793, 3746462239, 1033003366, 3528460888, 963096923, 3601193573,
33127     1331495888, 2694801646, 1269355501, 2758457555, 1186374570, 2843003028, 1111716759, 2910918825,
33128     1552565028, 3007850522, 1484755737, 3082680359, 1432478558, 3131279456, 1368666979, 3193329757,
33129     1760789048, 2268195078, 1812353541, 2210675003, 1628971586, 2396670332, 1710092927, 2318375233,
33130     2066006732, 2498144754, 2144408305, 2417195471, 1926193846, 2634877320, 1983558283, 2583222709,
33131     2662991776, 1903717534, 2588923805, 1972223139, 2538711002, 2022952164, 2477029351, 2087066841,
33132     2372749140, 1655647338, 2308478825, 1717238871, 2223433518, 1799654416, 2155034387, 1873894445,
33133     3105130056, 1456926070, 3185661557, 1378041163, 2969511474, 1597852940, 3020617231, 1539874097,
33134     2864957116, 1157737858, 2922780289, 1106542015, 2737333958, 1290407416, 2816325371, 1210047941,
33135     3521578096, 1042640718, 3574781005, 986759027, 3624707082, 936300340, 3707335735, 859512585,
33136     3257943172, 770846650, 3334837433, 688390023, 3420185854, 605654976, 3475911875, 552361981,
33137     4132013464, 428600998, 4072428965, 494812827, 4288816610, 274747100, 4216845791, 345349857,
33138     3852387692, 173846098, 3781891409, 245988975, 3967116566, 62328360, 3900749099, 121822741,
33139     3859089665, 164061759, 3807435068, 221426178, 4025395579, 2933317, 3944446278, 81334904,
33140     4124199413, 437265099, 4045904328, 518386422, 4231653775, 335250097, 4174133682, 386814604,
33141     3249244393, 778691543, 3311294676, 714879978, 3359647891, 662848429, 3434477742, 595039120,
33142     3531393053, 1035903779, 3599308832, 961245982, 3684132967, 877986649, 3747788890, 815846244,
33143     2841119441, 1184522735, 2913852140, 1114616274, 2696129195, 1332855189, 2756082326, 1266946472,
33144     3129952805, 1431118107, 3195705880, 1371074854, 3009735263, 1554415969, 3079748194, 1481855324,
33145     2398522169, 1630855175, 2315475716, 1707159610, 2266835779, 1759461501, 2213084030, 1814728768,
33146     2636237773, 1927520499, 2580814832, 1981182158, 2496293815, 2064121993, 2420095882, 2147340468,
33147     2025787041, 2541577631, 2085281436, 2475210146, 1901375195, 2660681189, 1973518054, 2590184920,
33148     1801997909, 2225743211, 1872600680, 2153772374, 1652813359, 2369881361, 1719025170, 2310296876,
33149     1594986313, 2966676599, 1541693300, 3022402634, 1459236659, 3107472397, 1376780046, 3184366640,
33150     1288097725, 2734990467, 1211309952, 2817619134, 1160605639, 2867791097, 1104723962, 2920993988,
33151     937561457, 3626001999, 857201996, 3704993394, 1040821515, 3519792693, 989625654, 3577615880,
33152     607473029, 3421972155, 549494200, 3473077894, 769584639, 3256649409, 690699714, 3337180924,
33153     273452185, 4287555495, 347692196, 4219156378, 430386403, 4133832669, 491977950, 4069562336,
33154     60542061, 3965298515, 124656720, 3903616878, 175139863, 3853649705, 243645482, 3779581716,
33155   }, {
33156     0, 3247366080, 1483520449, 2581751297, 2967040898, 1901571138, 3904227907, 691737987,
33157     3133399365, 2068659845, 3803142276, 589399876, 169513671, 3415493895, 1383475974, 2482566342,
33158     2935407819, 1870142219, 4137319690, 924099274, 506443593, 3751897225, 1178799752, 2278412616,
33159     339027342, 3585866318, 1280941135, 2379694991, 2766951948, 1700956620, 4236308429, 1024339981,
33160     2258407383, 1192382487, 3740284438, 528411094, 910556245, 4157285269, 1848198548, 2946996820,
33161     1012887186, 4258378066, 1681119059, 2780629139, 2357599504, 1292419792, 3572147409, 358906641,
33162     678054684, 3924071644, 1879503581, 2978491677, 2561882270, 1497229150, 3235873119, 22109855,
33163     2460592729, 1395094937, 3401913240, 189516888, 577821147, 3825075739, 2048679962, 3146956762,
33164     3595049455, 398902831, 2384764974, 1336573934, 1720805997, 2803873197, 1056822188, 4285729900,
33165     1821112490, 2902796138, 887570795, 4117339819, 3696397096, 500978920, 2218668777, 1169222953,
33166     2025774372, 3106931428, 550659301, 3780950821, 3362238118, 166293862, 2416645991, 1367722151,
33167     3262987361, 66315169, 2584839584, 1537170016, 1923370979, 3005911075, 717813282, 3947244002,
33168     1356109368, 2438613496, 146288633, 3375820857, 3759007162, 562248314, 3093388411, 2045739963,
33169     3927406461, 731490493, 2994458300, 1945440636, 1523451135, 2604718911, 44219710, 3274466046,
33170     4263662323, 1068272947, 2790189874, 1740649714, 1325080945, 2406874801, 379033776, 3608758128,
33171     1155642294, 2238671990, 479005303, 3708016055, 4097359924, 901128180, 2891217397, 1843045941,
33172     2011248031, 3060787807, 797805662, 3993195422, 3342353949, 112630237, 2673147868, 1591353372,
33173     3441611994, 212601626, 2504944923, 1421914843, 2113644376, 3161815192, 630660761, 3826893145,
33174     3642224980, 412692116, 2172340373, 1089836885, 1775141590, 2822790422, 832715543, 4029474007,
33175     1674842129, 2723860433, 1001957840, 4197873168, 3540870035, 310623315, 2338445906, 1257178514,
33176     4051548744, 821257608, 2836464521, 1755307081, 1101318602, 2150241802, 432566283, 3628511179,
33177     1270766349, 2318435533, 332587724, 3529260300, 4217841807, 988411727, 2735444302, 1652903566,
33178     1602977411, 2651169091, 132630338, 3328776322, 4015131905, 786223809, 3074340032, 1991273216,
33179     3846741958, 616972294, 3173262855, 2091579847, 1435626564, 2485072772, 234706309, 3430124101,
33180     2712218736, 1613231024, 4190475697, 944458353, 292577266, 3506339890, 1226630707, 2291284467,
33181     459984181, 3672380149, 1124496628, 2189994804, 2880683703, 1782407543, 4091479926, 844224694,
33182     257943739, 3469817723, 1462980986, 2529005242, 3213269817, 2114471161, 3890881272, 644152632,
33183     3046902270, 1947391550, 3991973951, 746483711, 88439420, 3301680572, 1563018173, 2628197501,
33184     657826727, 3871046759, 2136545894, 3201811878, 2548879397, 1449267173, 3481299428, 235845156,
33185     2650161890, 1551408418, 3315268387, 68429027, 758067552, 3970035360, 1967360161, 3033356129,
33186     2311284588, 1213053100, 3517963949, 270598509, 958010606, 4170500910, 1635167535, 2700636911,
33187     855672361, 4069415401, 1802256360, 2866995240, 2212099499, 1113008747, 3686091882, 440112042,
33188   }, {
33189     0, 2611301487, 3963330207, 2006897392, 50740095, 2560849680, 4013794784, 1956178319,
33190     101480190, 2645113489, 3929532513, 1905435662, 84561281, 2662269422, 3912356638, 1922342769,
33191     202960380, 2545787283, 3760419683, 2072395532, 253679235, 2495322860, 3810871324, 2021655667,
33192     169122562, 2444351341, 3861841309, 2106214898, 152215677, 2461527058, 3844685538, 2123133581,
33193     405920760, 2207553431, 4094313831, 1873742088, 456646791, 2157096168, 4144791064, 1823027831,
33194     507358470, 2241388905, 4060492697, 1772322806, 490444409, 2258557462, 4043311334, 1789215881,
33195     338245124, 2408348267, 4161972379, 1672996084, 388959611, 2357870868, 4212429796, 1622269835,
33196     304431354, 2306870421, 4263435877, 1706791434, 287538053, 2324051946, 4246267162, 1723705717,
33197     811841520, 2881944479, 3696765295, 1207788800, 862293135, 2831204576, 3747484176, 1157324415,
33198     913293582, 2915732833, 3662962577, 1106318334, 896137841, 2932651550, 3646055662, 1123494017,
33199     1014716940, 2816349795, 3493905555, 1273334012, 1065181555, 2765630748, 3544645612, 1222882179,
33200     980888818, 2714919069, 3595350637, 1307180546, 963712909, 2731826146, 3578431762, 1324336509,
33201     676490248, 3019317351, 3295277719, 1607253752, 726947703, 2968591128, 3345992168, 1556776327,
33202     777919222, 3053147801, 3261432937, 1505806342, 760750473, 3070062054, 3244539670, 1522987897,
33203     608862708, 3220163995, 3362856811, 1406423812, 659339915, 3169449700, 3413582868, 1355966587,
33204     575076106, 3118709605, 3464325525, 1440228858, 557894773, 3135602714, 3447411434, 1457397381,
33205     1623683040, 4217512847, 2365387135, 391757072, 1673614495, 4167309552, 2415577600, 341804655,
33206     1724586270, 4251866481, 2331019137, 290835438, 1707942497, 4268256782, 2314648830, 307490961,
33207     1826587164, 4152020595, 2162433155, 457265388, 1876539747, 4101829900, 2212636668, 407333779,
33208     1792275682, 4051089549, 2263378557, 491595282, 1775619997, 4067460082, 2246988034, 508239213,
33209     2029433880, 3813931127, 2496473735, 258500328, 2079362919, 3763716872, 2546668024, 208559511,
33210     2130363110, 3848244873, 2462145657, 157552662, 2113730969, 3864638966, 2445764358, 174205801,
33211     1961777636, 4014675339, 2564147067, 57707284, 2011718299, 3964481268, 2614361092, 7778411,
33212     1927425818, 3913769845, 2665066885, 92077546, 1910772837, 3930150922, 2648673018, 108709525,
33213     1352980496, 3405878399, 3164554895, 658115296, 1403183983, 3355946752, 3214507504, 607924639,
33214     1453895406, 3440239233, 3130208369, 557218846, 1437504913, 3456883198, 3113552654, 573589345,
33215     1555838444, 3340335491, 2961681267, 723707676, 1606028947, 3290383100, 3011612684, 673504355,
33216     1521500946, 3239382909, 3062619533, 758026722, 1505130605, 3256038402, 3045975794, 774417053,
33217     1217725416, 3543158663, 2762906999, 1057739032, 1267939479, 3493229816, 2812847624, 1007544935,
33218     1318679830, 3577493881, 2728586121, 956803046, 1302285929, 3594125830, 2711933174, 973184153,
33219     1150152212, 3743982203, 2830528651, 856898788, 1200346475, 3694041348, 2880457716, 806684571,
33220     1115789546, 3643069573, 2931426933, 891243034, 1099408277, 3659722746, 2914794762, 907637093,
33221   }, {
33222     0, 3717650821, 1616688459, 3184159950, 3233376918, 489665299, 2699419613, 2104690264,
33223     1510200173, 2274691816, 979330598, 3888758691, 2595928571, 1194090622, 4209380528, 661706037,
33224     3020400346, 1771143007, 3562738577, 164481556, 1958661196, 2837976521, 350386439, 3379863682,
33225     3993269687, 865250354, 2388181244, 1406015865, 784146209, 4079732388, 1323412074, 2474079215,
33226     3011398645, 1860735600, 3542286014, 246687547, 1942430051, 2924607718, 328963112, 3456978349,
33227     3917322392, 887832861, 2300653011, 1421341782, 700772878, 4099025803, 1234716485, 2483986112,
33228     125431087, 3673109674, 1730500708, 3132326369, 3351283641, 441867836, 2812031730, 2047535991,
33229     1568292418, 2163009479, 1025936137, 3769651852, 2646824148, 1079348561, 4255113631, 537475098,
33230     3180171691, 1612400686, 3721471200, 4717925, 2100624189, 2694980280, 493375094, 3237910515,
33231     3884860102, 974691139, 2278750093, 1514417672, 657926224, 4204917205, 1198234907, 2600289438,
33232     160053105, 3558665972, 1775665722, 3024116671, 3375586791, 346391650, 2842683564, 1962488105,
33233     1401545756, 2384412057, 869618007, 3997403346, 2469432970, 1319524111, 4083956673, 788193860,
33234     250862174, 3546612699, 1856990997, 3006903952, 3461001416, 333211981, 2920678787, 1937824774,
33235     1425017139, 2305216694, 883735672, 3912918525, 2487837605, 1239398944, 4095071982, 696455019,
33236     3136584836, 1734518017, 3668494799, 121507914, 2051872274, 2816200599, 437363545, 3347544796,
33237     3774328809, 1029797484, 2158697122, 1564328743, 542033279, 4258798842, 1074950196, 2642717105,
33238     2691310871, 2113731730, 3224801372, 497043929, 1624461185, 3175454212, 9435850, 3709412175,
33239     4201248378, 671035391, 2587181873, 1201904308, 986750188, 3880142185, 1519135143, 2266689570,
33240     342721485, 3388693064, 1949382278, 2846355203, 3570723163, 155332830, 3028835344, 1763607957,
33241     1315852448, 2482538789, 775087595, 4087626862, 2396469814, 1396827059, 4002123645, 857560824,
33242     320106210, 3464673127, 1934154665, 2933785132, 3551331444, 238804465, 3018961215, 1852270778,
33243     1226292623, 2491507722, 692783300, 4108177729, 2309936921, 1412959900, 3924976210, 879016919,
33244     2803091512, 2055541181, 3343875443, 450471158, 1739236014, 3124525867, 133568485, 3663777376,
33245     4245691221, 545702608, 2639048222, 1088059291, 1034514883, 3762268230, 1576387720, 2153979149,
33246     501724348, 3228659001, 2109407735, 2687359090, 3713981994, 13109167, 3171052385, 1620357860,
33247     1206151121, 2591211092, 666423962, 4197321503, 2271022407, 1523307714, 3875649548, 982999433,
33248     2850034278, 1953942499, 3384583981, 338329256, 1767471344, 3033506165, 151375291, 3566408766,
33249     4091789579, 779425934, 2478797888, 1311354309, 861580189, 4006375960, 1392910038, 2391852883,
33250     2929327945, 1930372812, 3469036034, 324244359, 1847629279, 3015068762, 243015828, 3555391761,
33251     4103744548, 688715169, 2496043375, 1229996266, 874727090, 3920994103, 1417671673, 2313759356,
33252     446585235, 3339223062, 2059594968, 2807313757, 3660002053, 129100416, 3128657486, 1743609803,
33253     1084066558, 2634765179, 549535669, 4250396208, 2149900392, 1571961325, 3765982499, 1039043750,
33254   }, {
33255     0, 2635063670, 3782132909, 2086741467, 430739227, 2225303149, 4173482934, 1707977408,
33256     861478454, 2924937024, 3526875803, 1329085421, 720736557, 3086643291, 3415954816, 1452586230,
33257     1722956908, 4223524122, 2279405761, 450042295, 2132718455, 3792785921, 2658170842, 58693292,
33258     1441473114, 3370435372, 3028674295, 696911745, 1279765825, 3511176247, 2905172460, 807831706,
33259     3445913816, 1349228974, 738901109, 2969918723, 3569940419, 1237784245, 900084590, 2829701656,
33260     4265436910, 1664255896, 525574723, 2187084597, 3885099509, 2057177219, 117386584, 2616249390,
33261     2882946228, 920233410, 1253605401, 3619119471, 2994391983, 796207833, 1393823490, 3457937012,
33262     2559531650, 92322804, 2044829231, 3840835417, 2166609305, 472659183, 1615663412, 4249022530,
33263     1102706673, 3702920839, 2698457948, 1037619754, 1477802218, 3306854812, 3111894087, 611605809,
33264     1927342535, 4025419953, 2475568490, 243387420, 1800169180, 4131620778, 2317525617, 388842247,
33265     655084445, 3120835307, 3328511792, 1533734470, 1051149446, 2745738736, 3754524715, 1120297309,
33266     340972971, 2304586973, 4114354438, 1748234352, 234773168, 2431761350, 3968900637, 1906278251,
33267     2363330345, 299003487, 1840466820, 4038896370, 2507210802, 142532932, 1948239007, 3910149609,
33268     3213136159, 579563625, 1592415666, 3286611140, 2787646980, 992477042, 1195825833, 3662232543,
33269     3933188933, 2002801203, 184645608, 2517538462, 4089658462, 1858919720, 313391347, 2409765253,
33270     3644239219, 1144605701, 945318366, 2773977256, 3231326824, 1570095902, 569697989, 3170568115,
33271     2205413346, 511446676, 1646078799, 4279421497, 2598330617, 131105167, 2075239508, 3871229218,
33272     2955604436, 757403810, 1363424633, 3427521551, 2844163791, 881434553, 1223211618, 3588709140,
33273     3854685070, 2026779384, 78583587, 2577462869, 4235025557, 1633861091, 486774840, 2148301134,
33274     3600338360, 1268198606, 938871061, 2868504675, 3476308643, 1379640277, 777684494, 3008718712,
33275     1310168890, 3541595724, 2943964055, 846639841, 1471879201, 3400857943, 3067468940, 735723002,
33276     2102298892, 3762382970, 2619362721, 19901655, 1692534295, 4193118049, 2240594618, 411247564,
33277     681945942, 3047836192, 3385552891, 1422167693, 822682701, 2886124859, 3496468704, 1298661782,
33278     469546336, 2264093718, 4203901389, 1738379451, 38812283, 2673859341, 3812556502, 2117148576,
33279     3268024339, 1606809957, 598006974, 3198893512, 3680933640, 1181316734, 973624229, 2802299603,
33280     4052944421, 1822222163, 285065864, 2381456382, 3896478014, 1966106696, 156323219, 2489232613,
33281     2759337087, 964150537, 1159127250, 3625517476, 3184831332, 551242258, 1555722185, 3249901247,
33282     2535537225, 170842943, 1984954084, 3946848146, 2391651666, 327308324, 1877176831, 4075589769,
33283     263086283, 2460058045, 4005602406, 1942963472, 369291216, 2332888742, 4151061373, 1784924683,
33284     1022852861, 2717425547, 3717839440, 1083595558, 626782694, 3092517008, 3291821387, 1497027645,
33285     1763466407, 4094934481, 2289211402, 360544636, 1890636732, 3988730570, 2447251217, 215086695,
33286     1514488465, 3343557607, 3140191804, 639919946, 1139395978, 3739626748, 2726758695, 1065936977,
33287   }, {
33288     0, 3120290792, 2827399569, 293431929, 2323408227, 864534155, 586863858, 2600537882,
33289     3481914503, 1987188591, 1729068310, 3740575486, 1173727716, 4228805132, 3983743093, 1418249117,
33290     1147313999, 4254680231, 3974377182, 1428157750, 3458136620, 2011505092, 1721256893, 3747844181,
33291     2347455432, 839944224, 594403929, 2593536433, 26687147, 3094146371, 2836498234, 283794642,
33292     2294627998, 826205558, 541298447, 2578994407, 45702141, 3141697557, 2856315500, 331624836,
33293     1196225049, 4273416689, 4023010184, 1446090848, 3442513786, 1959480466, 1706436331, 3696098563,
33294     3433538001, 1968994873, 1679888448, 3722103720, 1188807858, 4280295258, 3999102243, 1470541515,
33295     53374294, 3134568126, 2879970503, 307431215, 2303854645, 816436189, 567589284, 2553242188,
33296     3405478781, 1929420949, 1652411116, 3682996484, 1082596894, 4185703926, 3892424591, 1375368295,
33297     91404282, 3163122706, 2918450795, 336584067, 2400113305, 922028401, 663249672, 2658384096,
33298     2392450098, 929185754, 639587747, 2682555979, 82149713, 3172883129, 2892181696, 362343208,
33299     1091578037, 4176212829, 3918960932, 1349337804, 3412872662, 1922537022, 1676344391, 3658557359,
33300     1111377379, 4224032267, 3937989746, 1396912026, 3359776896, 1908013928, 1623494929, 3644803833,
33301     2377615716, 877417100, 623982837, 2630542109, 130804743, 3190831087, 2941083030, 381060734,
33302     106748588, 3215393092, 2933549885, 388083925, 2350956495, 903570471, 614862430, 2640172470,
33303     3386185259, 1882115523, 1632872378, 3634920530, 1135178568, 4199721120, 3945775833, 1389631793,
33304     1317531835, 4152109907, 3858841898, 1610259138, 3304822232, 2097172016, 1820140617, 3582394273,
33305     2165193788, 955639764, 696815021, 2423477829, 192043359, 2995356343, 2750736590, 437203750,
33306     182808564, 3005133852, 2724453989, 462947725, 2157513367, 962777471, 673168134, 2447663342,
33307     3312231283, 2090301595, 1844056802, 3557935370, 1326499344, 4142603768, 3885397889, 1584245865,
33308     3326266917, 2142836173, 1858371508, 3611272284, 1279175494, 4123357358, 3837270743, 1564721471,
33309     164299426, 2955991370, 2706223923, 414607579, 2209834945, 978107433, 724686416, 2462715320,
33310     2183156074, 1004243586, 715579643, 2472360723, 140260361, 2980573153, 2698675608, 421617264,
33311     1302961645, 4099032581, 3845074044, 1557460884, 3352688782, 2116952934, 1867729183, 3601371895,
33312     2222754758, 1032278062, 754596439, 2499928511, 234942117, 3086693709, 2793824052, 528319708,
33313     1274365761, 4061043881, 3816027856, 1518873912, 3246989858, 2020800970, 1762628531, 3505670235,
33314     3223196809, 2045103969, 1754834200, 3512958704, 1247965674, 4086934018, 3806642299, 1528765331,
33315     261609486, 3060532198, 2802936223, 518697591, 2246819181, 1007707781, 762121468, 2492913428,
33316     213497176, 3041029808, 2755593417, 499441441, 2261110843, 1061030867, 776167850, 2545465922,
33317     3274734047, 2060165687, 1807140942, 3528266662, 1229724860, 4038575956, 3788156205, 1479636677,
33318     1222322711, 4045468159, 3764231046, 1504067694, 3265744756, 2069664924, 1780612837, 3554288909,
33319     2270357136, 1051278712, 802445057, 2519698665, 221152243, 3033880603, 2779263586, 475261322,
33320   }, {
33321     0, 2926088593, 2275419491, 701019378, 3560000647, 2052709654, 1402038756, 4261017717,
33322     1930665807, 3715829470, 4105419308, 1524313021, 2804077512, 155861593, 545453739, 2397726522,
33323     3861331614, 1213181711, 1636244477, 3488582252, 840331801, 2625561480, 3048626042, 467584747,
33324     2503254481, 995897408, 311723186, 3170637091, 1090907478, 4016929991, 3332753461, 1758288292,
33325     390036349, 3109546732, 2426363422, 1056427919, 3272488954, 1835443819, 1152258713, 3938878216,
33326     1680663602, 3393484195, 3817652561, 1306808512, 2954733749, 510998820, 935169494, 2580880455,
33327     4044899811, 1601229938, 1991794816, 3637571857, 623446372, 2336332021, 2726898695, 216120726,
33328     2181814956, 744704829, 95158223, 2881711710, 1446680107, 4166125498, 3516576584, 2146575065,
33329     780072698, 2148951915, 2849952665, 129384968, 4199529085, 1411853292, 2112855838, 3548843663,
33330     1567451573, 4077254692, 3670887638, 1957027143, 2304517426, 657765539, 251396177, 2694091200,
33331     3361327204, 1714510325, 1341779207, 3784408214, 476611811, 2986349938, 2613617024, 899690513,
33332     3142211371, 354600634, 1021997640, 2458051545, 1870338988, 3239283261, 3906682575, 1186180958,
33333     960597383, 2536053782, 3202459876, 277428597, 3983589632, 1125666961, 1792074851, 3300423154,
33334     1246892744, 3829039961, 3455203243, 1671079482, 2657312335, 806080478, 432241452, 3081497277,
33335     3748049689, 1896751752, 1489409658, 4138600427, 190316446, 2772397583, 2365053693, 580864876,
33336     2893360214, 35503559, 735381813, 2243795108, 2017747153, 3593269568, 4293150130, 1368183843,
33337     1560145396, 4069882981, 3680356503, 1966430470, 2295112051, 648294626, 258769936, 2701399425,
33338     804156091, 2173100842, 2823706584, 103204425, 4225711676, 1438101421, 2088704863, 3524758222,
33339     3134903146, 347226875, 1031468553, 2467456920, 1860935661, 3229814396, 3914054286, 1193487135,
33340     3385412645, 1738661300, 1315531078, 3758225623, 502792354, 3012596019, 2589468097, 875607120,
33341     1271043721, 3853125400, 3429020650, 1644831355, 2683558414, 832261023, 408158061, 3057348348,
33342     953223622, 2528745559, 3211865253, 286899508, 3974120769, 1116263632, 1799381026, 3307794867,
33343     2917509143, 59586950, 709201268, 2217549029, 2043995280, 3619452161, 4269064691, 1344032866,
33344     3740677976, 1889445577, 1498812987, 4148069290, 180845535, 2762992206, 2372361916, 588238637,
33345     1921194766, 3706423967, 4112727661, 1531686908, 2796705673, 148555288, 554857194, 2407195515,
33346     26248257, 2952271312, 2251333922, 676868275, 3584149702, 2076793175, 1375858085, 4234771508,
33347     2493785488, 986493953, 319029491, 3178008930, 1083533591, 4009621638, 3342158964, 1767759333,
33348     3887577823, 1239362382, 1612160956, 3464433197, 864482904, 2649647049, 3022443323, 441336490,
33349     1706844275, 3419730402, 3793503504, 1282724993, 2978819316, 535149925, 908921239, 2554697734,
33350     380632892, 3100077741, 2433735263, 1063734222, 3265180603, 1828069930, 1161729752, 3948283721,
33351     2207997677, 770953084, 71007118, 2857626143, 1470763626, 4190274555, 3490330377, 2120394392,
33352     4035494306, 1591758899, 1999168705, 3644880208, 616140069, 2328960180, 2736367686, 225524183,
33353   },
33354 };
33355 
33356 static const uint8_t
33357 WUFFS_CRC32__IEEE_X86_SSE42_K1K2[16] WUFFS_BASE__POTENTIALLY_UNUSED = {
33358   212, 43, 68, 84, 1, 0, 0, 0,
33359   150, 21, 228, 198, 1, 0, 0, 0,
33360 };
33361 
33362 static const uint8_t
33363 WUFFS_CRC32__IEEE_X86_SSE42_K3K4[16] WUFFS_BASE__POTENTIALLY_UNUSED = {
33364   208, 151, 25, 117, 1, 0, 0, 0,
33365   158, 0, 170, 204, 0, 0, 0, 0,
33366 };
33367 
33368 static const uint8_t
33369 WUFFS_CRC32__IEEE_X86_SSE42_K5ZZ[16] WUFFS_BASE__POTENTIALLY_UNUSED = {
33370   36, 97, 205, 99, 1, 0, 0, 0,
33371   0, 0, 0, 0, 0, 0, 0, 0,
33372 };
33373 
33374 static const uint8_t
33375 WUFFS_CRC32__IEEE_X86_SSE42_PXMU[16] WUFFS_BASE__POTENTIALLY_UNUSED = {
33376   65, 6, 113, 219, 1, 0, 0, 0,
33377   65, 22, 1, 247, 1, 0, 0, 0,
33378 };
33379 
33380 // ---------------- Private Initializer Prototypes
33381 
33382 // ---------------- Private Function Prototypes
33383 
33384 WUFFS_BASE__GENERATED_C_CODE
33385 static wuffs_base__empty_struct
33386 wuffs_crc32__ieee_hasher__up(
33387     wuffs_crc32__ieee_hasher* self,
33388     wuffs_base__slice_u8 a_x);
33389 
33390 WUFFS_BASE__GENERATED_C_CODE
33391 static wuffs_base__empty_struct
33392 wuffs_crc32__ieee_hasher__up__choosy_default(
33393     wuffs_crc32__ieee_hasher* self,
33394     wuffs_base__slice_u8 a_x);
33395 
33396 #if defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32)
33397 WUFFS_BASE__GENERATED_C_CODE
33398 static wuffs_base__empty_struct
33399 wuffs_crc32__ieee_hasher__up_arm_crc32(
33400     wuffs_crc32__ieee_hasher* self,
33401     wuffs_base__slice_u8 a_x);
33402 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32)
33403 
33404 #if defined(WUFFS_BASE__CPU_ARCH__X86_64)
33405 WUFFS_BASE__GENERATED_C_CODE
33406 static wuffs_base__empty_struct
33407 wuffs_crc32__ieee_hasher__up_x86_avx2(
33408     wuffs_crc32__ieee_hasher* self,
33409     wuffs_base__slice_u8 a_x);
33410 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_64)
33411 
33412 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
33413 WUFFS_BASE__GENERATED_C_CODE
33414 static wuffs_base__empty_struct
33415 wuffs_crc32__ieee_hasher__up_x86_sse42(
33416     wuffs_crc32__ieee_hasher* self,
33417     wuffs_base__slice_u8 a_x);
33418 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
33419 
33420 // ---------------- VTables
33421 
33422 const wuffs_base__hasher_u32__func_ptrs
33423 wuffs_crc32__ieee_hasher__func_ptrs_for__wuffs_base__hasher_u32 = {
33424   (uint32_t(*)(const void*))(&wuffs_crc32__ieee_hasher__checksum_u32),
33425   (uint64_t(*)(const void*,
33426       uint32_t))(&wuffs_crc32__ieee_hasher__get_quirk),
33427   (wuffs_base__status(*)(void*,
33428       uint32_t,
33429       uint64_t))(&wuffs_crc32__ieee_hasher__set_quirk),
33430   (wuffs_base__empty_struct(*)(void*,
33431       wuffs_base__slice_u8))(&wuffs_crc32__ieee_hasher__update),
33432   (uint32_t(*)(void*,
33433       wuffs_base__slice_u8))(&wuffs_crc32__ieee_hasher__update_u32),
33434 };
33435 
33436 // ---------------- Initializer Implementations
33437 
33438 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
wuffs_crc32__ieee_hasher__initialize(wuffs_crc32__ieee_hasher * self,size_t sizeof_star_self,uint64_t wuffs_version,uint32_t options)33439 wuffs_crc32__ieee_hasher__initialize(
33440     wuffs_crc32__ieee_hasher* self,
33441     size_t sizeof_star_self,
33442     uint64_t wuffs_version,
33443     uint32_t options){
33444   if (!self) {
33445     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
33446   }
33447   if (sizeof(*self) != sizeof_star_self) {
33448     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
33449   }
33450   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
33451       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
33452     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
33453   }
33454 
33455   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
33456     // The whole point of this if-check is to detect an uninitialized *self.
33457     // We disable the warning on GCC. Clang-5.0 does not have this warning.
33458 #if !defined(__clang__) && defined(__GNUC__)
33459 #pragma GCC diagnostic push
33460 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
33461 #endif
33462     if (self->private_impl.magic != 0) {
33463       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
33464     }
33465 #if !defined(__clang__) && defined(__GNUC__)
33466 #pragma GCC diagnostic pop
33467 #endif
33468   } else {
33469     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
33470       memset(self, 0, sizeof(*self));
33471       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
33472     } else {
33473       memset(&(self->private_impl), 0, sizeof(self->private_impl));
33474     }
33475   }
33476 
33477   self->private_impl.choosy_up = &wuffs_crc32__ieee_hasher__up__choosy_default;
33478 
33479   self->private_impl.magic = WUFFS_BASE__MAGIC;
33480   self->private_impl.vtable_for__wuffs_base__hasher_u32.vtable_name =
33481       wuffs_base__hasher_u32__vtable_name;
33482   self->private_impl.vtable_for__wuffs_base__hasher_u32.function_pointers =
33483       (const void*)(&wuffs_crc32__ieee_hasher__func_ptrs_for__wuffs_base__hasher_u32);
33484   return wuffs_base__make_status(NULL);
33485 }
33486 
33487 wuffs_crc32__ieee_hasher*
wuffs_crc32__ieee_hasher__alloc(void)33488 wuffs_crc32__ieee_hasher__alloc(void) {
33489   wuffs_crc32__ieee_hasher* x =
33490       (wuffs_crc32__ieee_hasher*)(calloc(sizeof(wuffs_crc32__ieee_hasher), 1));
33491   if (!x) {
33492     return NULL;
33493   }
33494   if (wuffs_crc32__ieee_hasher__initialize(
33495       x, sizeof(wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
33496     free(x);
33497     return NULL;
33498   }
33499   return x;
33500 }
33501 
33502 size_t
sizeof__wuffs_crc32__ieee_hasher(void)33503 sizeof__wuffs_crc32__ieee_hasher(void) {
33504   return sizeof(wuffs_crc32__ieee_hasher);
33505 }
33506 
33507 // ---------------- Function Implementations
33508 
33509 // -------- func crc32.ieee_hasher.get_quirk
33510 
33511 WUFFS_BASE__GENERATED_C_CODE
33512 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_crc32__ieee_hasher__get_quirk(const wuffs_crc32__ieee_hasher * self,uint32_t a_key)33513 wuffs_crc32__ieee_hasher__get_quirk(
33514     const wuffs_crc32__ieee_hasher* self,
33515     uint32_t a_key) {
33516   if (!self) {
33517     return 0;
33518   }
33519   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
33520       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
33521     return 0;
33522   }
33523 
33524   return 0u;
33525 }
33526 
33527 // -------- func crc32.ieee_hasher.set_quirk
33528 
33529 WUFFS_BASE__GENERATED_C_CODE
33530 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_crc32__ieee_hasher__set_quirk(wuffs_crc32__ieee_hasher * self,uint32_t a_key,uint64_t a_value)33531 wuffs_crc32__ieee_hasher__set_quirk(
33532     wuffs_crc32__ieee_hasher* self,
33533     uint32_t a_key,
33534     uint64_t a_value) {
33535   if (!self) {
33536     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
33537   }
33538   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
33539     return wuffs_base__make_status(
33540         (self->private_impl.magic == WUFFS_BASE__DISABLED)
33541         ? wuffs_base__error__disabled_by_previous_error
33542         : wuffs_base__error__initialize_not_called);
33543   }
33544 
33545   return wuffs_base__make_status(wuffs_base__error__unsupported_option);
33546 }
33547 
33548 // -------- func crc32.ieee_hasher.update
33549 
33550 WUFFS_BASE__GENERATED_C_CODE
33551 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_crc32__ieee_hasher__update(wuffs_crc32__ieee_hasher * self,wuffs_base__slice_u8 a_x)33552 wuffs_crc32__ieee_hasher__update(
33553     wuffs_crc32__ieee_hasher* self,
33554     wuffs_base__slice_u8 a_x) {
33555   if (!self) {
33556     return wuffs_base__make_empty_struct();
33557   }
33558   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
33559     return wuffs_base__make_empty_struct();
33560   }
33561 
33562   if (self->private_impl.f_state == 0u) {
33563     self->private_impl.choosy_up = (
33564 #if defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32)
33565         wuffs_base__cpu_arch__have_arm_crc32() ? &wuffs_crc32__ieee_hasher__up_arm_crc32 :
33566 #endif
33567 #if defined(WUFFS_BASE__CPU_ARCH__X86_64)
33568         wuffs_base__cpu_arch__have_x86_avx2() ? &wuffs_crc32__ieee_hasher__up_x86_avx2 :
33569 #endif
33570 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
33571         wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_crc32__ieee_hasher__up_x86_sse42 :
33572 #endif
33573         self->private_impl.choosy_up);
33574   }
33575   wuffs_crc32__ieee_hasher__up(self, a_x);
33576   return wuffs_base__make_empty_struct();
33577 }
33578 
33579 // -------- func crc32.ieee_hasher.update_u32
33580 
33581 WUFFS_BASE__GENERATED_C_CODE
33582 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_crc32__ieee_hasher__update_u32(wuffs_crc32__ieee_hasher * self,wuffs_base__slice_u8 a_x)33583 wuffs_crc32__ieee_hasher__update_u32(
33584     wuffs_crc32__ieee_hasher* self,
33585     wuffs_base__slice_u8 a_x) {
33586   if (!self) {
33587     return 0;
33588   }
33589   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
33590     return 0;
33591   }
33592 
33593   wuffs_crc32__ieee_hasher__update(self, a_x);
33594   return self->private_impl.f_state;
33595 }
33596 
33597 // -------- func crc32.ieee_hasher.up
33598 
33599 WUFFS_BASE__GENERATED_C_CODE
33600 static wuffs_base__empty_struct
wuffs_crc32__ieee_hasher__up(wuffs_crc32__ieee_hasher * self,wuffs_base__slice_u8 a_x)33601 wuffs_crc32__ieee_hasher__up(
33602     wuffs_crc32__ieee_hasher* self,
33603     wuffs_base__slice_u8 a_x) {
33604   return (*self->private_impl.choosy_up)(self, a_x);
33605 }
33606 
33607 WUFFS_BASE__GENERATED_C_CODE
33608 static wuffs_base__empty_struct
wuffs_crc32__ieee_hasher__up__choosy_default(wuffs_crc32__ieee_hasher * self,wuffs_base__slice_u8 a_x)33609 wuffs_crc32__ieee_hasher__up__choosy_default(
33610     wuffs_crc32__ieee_hasher* self,
33611     wuffs_base__slice_u8 a_x) {
33612   uint32_t v_s = 0;
33613   wuffs_base__slice_u8 v_p = {0};
33614 
33615   v_s = (4294967295u ^ self->private_impl.f_state);
33616   {
33617     wuffs_base__slice_u8 i_slice_p = a_x;
33618     v_p.ptr = i_slice_p.ptr;
33619     v_p.len = 16;
33620     uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 32) * 32);
33621     while (v_p.ptr < i_end0_p) {
33622       v_s ^= ((((uint32_t)(v_p.ptr[0u])) << 0u) |
33623           (((uint32_t)(v_p.ptr[1u])) << 8u) |
33624           (((uint32_t)(v_p.ptr[2u])) << 16u) |
33625           (((uint32_t)(v_p.ptr[3u])) << 24u));
33626       v_s = (WUFFS_CRC32__IEEE_TABLE[0u][v_p.ptr[15u]] ^
33627           WUFFS_CRC32__IEEE_TABLE[1u][v_p.ptr[14u]] ^
33628           WUFFS_CRC32__IEEE_TABLE[2u][v_p.ptr[13u]] ^
33629           WUFFS_CRC32__IEEE_TABLE[3u][v_p.ptr[12u]] ^
33630           WUFFS_CRC32__IEEE_TABLE[4u][v_p.ptr[11u]] ^
33631           WUFFS_CRC32__IEEE_TABLE[5u][v_p.ptr[10u]] ^
33632           WUFFS_CRC32__IEEE_TABLE[6u][v_p.ptr[9u]] ^
33633           WUFFS_CRC32__IEEE_TABLE[7u][v_p.ptr[8u]] ^
33634           WUFFS_CRC32__IEEE_TABLE[8u][v_p.ptr[7u]] ^
33635           WUFFS_CRC32__IEEE_TABLE[9u][v_p.ptr[6u]] ^
33636           WUFFS_CRC32__IEEE_TABLE[10u][v_p.ptr[5u]] ^
33637           WUFFS_CRC32__IEEE_TABLE[11u][v_p.ptr[4u]] ^
33638           WUFFS_CRC32__IEEE_TABLE[12u][(255u & (v_s >> 24u))] ^
33639           WUFFS_CRC32__IEEE_TABLE[13u][(255u & (v_s >> 16u))] ^
33640           WUFFS_CRC32__IEEE_TABLE[14u][(255u & (v_s >> 8u))] ^
33641           WUFFS_CRC32__IEEE_TABLE[15u][(255u & (v_s >> 0u))]);
33642       v_p.ptr += 16;
33643       v_s ^= ((((uint32_t)(v_p.ptr[0u])) << 0u) |
33644           (((uint32_t)(v_p.ptr[1u])) << 8u) |
33645           (((uint32_t)(v_p.ptr[2u])) << 16u) |
33646           (((uint32_t)(v_p.ptr[3u])) << 24u));
33647       v_s = (WUFFS_CRC32__IEEE_TABLE[0u][v_p.ptr[15u]] ^
33648           WUFFS_CRC32__IEEE_TABLE[1u][v_p.ptr[14u]] ^
33649           WUFFS_CRC32__IEEE_TABLE[2u][v_p.ptr[13u]] ^
33650           WUFFS_CRC32__IEEE_TABLE[3u][v_p.ptr[12u]] ^
33651           WUFFS_CRC32__IEEE_TABLE[4u][v_p.ptr[11u]] ^
33652           WUFFS_CRC32__IEEE_TABLE[5u][v_p.ptr[10u]] ^
33653           WUFFS_CRC32__IEEE_TABLE[6u][v_p.ptr[9u]] ^
33654           WUFFS_CRC32__IEEE_TABLE[7u][v_p.ptr[8u]] ^
33655           WUFFS_CRC32__IEEE_TABLE[8u][v_p.ptr[7u]] ^
33656           WUFFS_CRC32__IEEE_TABLE[9u][v_p.ptr[6u]] ^
33657           WUFFS_CRC32__IEEE_TABLE[10u][v_p.ptr[5u]] ^
33658           WUFFS_CRC32__IEEE_TABLE[11u][v_p.ptr[4u]] ^
33659           WUFFS_CRC32__IEEE_TABLE[12u][(255u & (v_s >> 24u))] ^
33660           WUFFS_CRC32__IEEE_TABLE[13u][(255u & (v_s >> 16u))] ^
33661           WUFFS_CRC32__IEEE_TABLE[14u][(255u & (v_s >> 8u))] ^
33662           WUFFS_CRC32__IEEE_TABLE[15u][(255u & (v_s >> 0u))]);
33663       v_p.ptr += 16;
33664     }
33665     v_p.len = 16;
33666     uint8_t* i_end1_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 16) * 16);
33667     while (v_p.ptr < i_end1_p) {
33668       v_s ^= ((((uint32_t)(v_p.ptr[0u])) << 0u) |
33669           (((uint32_t)(v_p.ptr[1u])) << 8u) |
33670           (((uint32_t)(v_p.ptr[2u])) << 16u) |
33671           (((uint32_t)(v_p.ptr[3u])) << 24u));
33672       v_s = (WUFFS_CRC32__IEEE_TABLE[0u][v_p.ptr[15u]] ^
33673           WUFFS_CRC32__IEEE_TABLE[1u][v_p.ptr[14u]] ^
33674           WUFFS_CRC32__IEEE_TABLE[2u][v_p.ptr[13u]] ^
33675           WUFFS_CRC32__IEEE_TABLE[3u][v_p.ptr[12u]] ^
33676           WUFFS_CRC32__IEEE_TABLE[4u][v_p.ptr[11u]] ^
33677           WUFFS_CRC32__IEEE_TABLE[5u][v_p.ptr[10u]] ^
33678           WUFFS_CRC32__IEEE_TABLE[6u][v_p.ptr[9u]] ^
33679           WUFFS_CRC32__IEEE_TABLE[7u][v_p.ptr[8u]] ^
33680           WUFFS_CRC32__IEEE_TABLE[8u][v_p.ptr[7u]] ^
33681           WUFFS_CRC32__IEEE_TABLE[9u][v_p.ptr[6u]] ^
33682           WUFFS_CRC32__IEEE_TABLE[10u][v_p.ptr[5u]] ^
33683           WUFFS_CRC32__IEEE_TABLE[11u][v_p.ptr[4u]] ^
33684           WUFFS_CRC32__IEEE_TABLE[12u][(255u & (v_s >> 24u))] ^
33685           WUFFS_CRC32__IEEE_TABLE[13u][(255u & (v_s >> 16u))] ^
33686           WUFFS_CRC32__IEEE_TABLE[14u][(255u & (v_s >> 8u))] ^
33687           WUFFS_CRC32__IEEE_TABLE[15u][(255u & (v_s >> 0u))]);
33688       v_p.ptr += 16;
33689     }
33690     v_p.len = 1;
33691     uint8_t* i_end2_p = i_slice_p.ptr + i_slice_p.len;
33692     while (v_p.ptr < i_end2_p) {
33693       v_s = (WUFFS_CRC32__IEEE_TABLE[0u][(((uint8_t)(v_s)) ^ v_p.ptr[0u])] ^ (v_s >> 8u));
33694       v_p.ptr += 1;
33695     }
33696     v_p.len = 0;
33697   }
33698   self->private_impl.f_state = (4294967295u ^ v_s);
33699   return wuffs_base__make_empty_struct();
33700 }
33701 
33702 // -------- func crc32.ieee_hasher.checksum_u32
33703 
33704 WUFFS_BASE__GENERATED_C_CODE
33705 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_crc32__ieee_hasher__checksum_u32(const wuffs_crc32__ieee_hasher * self)33706 wuffs_crc32__ieee_hasher__checksum_u32(
33707     const wuffs_crc32__ieee_hasher* self) {
33708   if (!self) {
33709     return 0;
33710   }
33711   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
33712       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
33713     return 0;
33714   }
33715 
33716   return self->private_impl.f_state;
33717 }
33718 
33719 // ‼ WUFFS MULTI-FILE SECTION +arm_crc32
33720 // -------- func crc32.ieee_hasher.up_arm_crc32
33721 
33722 #if defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32)
33723 WUFFS_BASE__GENERATED_C_CODE
33724 static wuffs_base__empty_struct
wuffs_crc32__ieee_hasher__up_arm_crc32(wuffs_crc32__ieee_hasher * self,wuffs_base__slice_u8 a_x)33725 wuffs_crc32__ieee_hasher__up_arm_crc32(
33726     wuffs_crc32__ieee_hasher* self,
33727     wuffs_base__slice_u8 a_x) {
33728   wuffs_base__slice_u8 v_p = {0};
33729   uint32_t v_s = 0;
33730 
33731   v_s = (4294967295u ^ self->private_impl.f_state);
33732   while ((((uint64_t)(a_x.len)) > 0u) && ((15u & ((uint32_t)(0xFFFu & (uintptr_t)(a_x.ptr)))) != 0u)) {
33733     v_s = __crc32b(v_s, a_x.ptr[0u]);
33734     a_x = wuffs_base__slice_u8__subslice_i(a_x, 1u);
33735   }
33736   {
33737     wuffs_base__slice_u8 i_slice_p = a_x;
33738     v_p.ptr = i_slice_p.ptr;
33739     v_p.len = 8;
33740     uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 128) * 128);
33741     while (v_p.ptr < i_end0_p) {
33742       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
33743       v_p.ptr += 8;
33744       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
33745       v_p.ptr += 8;
33746       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
33747       v_p.ptr += 8;
33748       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
33749       v_p.ptr += 8;
33750       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
33751       v_p.ptr += 8;
33752       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
33753       v_p.ptr += 8;
33754       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
33755       v_p.ptr += 8;
33756       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
33757       v_p.ptr += 8;
33758       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
33759       v_p.ptr += 8;
33760       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
33761       v_p.ptr += 8;
33762       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
33763       v_p.ptr += 8;
33764       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
33765       v_p.ptr += 8;
33766       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
33767       v_p.ptr += 8;
33768       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
33769       v_p.ptr += 8;
33770       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
33771       v_p.ptr += 8;
33772       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
33773       v_p.ptr += 8;
33774     }
33775     v_p.len = 8;
33776     uint8_t* i_end1_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 8) * 8);
33777     while (v_p.ptr < i_end1_p) {
33778       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
33779       v_p.ptr += 8;
33780     }
33781     v_p.len = 1;
33782     uint8_t* i_end2_p = i_slice_p.ptr + i_slice_p.len;
33783     while (v_p.ptr < i_end2_p) {
33784       v_s = __crc32b(v_s, v_p.ptr[0u]);
33785       v_p.ptr += 1;
33786     }
33787     v_p.len = 0;
33788   }
33789   self->private_impl.f_state = (4294967295u ^ v_s);
33790   return wuffs_base__make_empty_struct();
33791 }
33792 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32)
33793 // ‼ WUFFS MULTI-FILE SECTION -arm_crc32
33794 
33795 // ‼ WUFFS MULTI-FILE SECTION +x86_avx2
33796 // -------- func crc32.ieee_hasher.up_x86_avx2
33797 
33798 #if defined(WUFFS_BASE__CPU_ARCH__X86_64)
33799 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2")
33800 WUFFS_BASE__GENERATED_C_CODE
33801 static wuffs_base__empty_struct
wuffs_crc32__ieee_hasher__up_x86_avx2(wuffs_crc32__ieee_hasher * self,wuffs_base__slice_u8 a_x)33802 wuffs_crc32__ieee_hasher__up_x86_avx2(
33803     wuffs_crc32__ieee_hasher* self,
33804     wuffs_base__slice_u8 a_x) {
33805   uint32_t v_s = 0;
33806   wuffs_base__slice_u8 v_p = {0};
33807   __m128i v_k = {0};
33808   __m128i v_x0 = {0};
33809   __m128i v_x1 = {0};
33810   __m128i v_x2 = {0};
33811   __m128i v_x3 = {0};
33812   __m128i v_y0 = {0};
33813   __m128i v_y1 = {0};
33814   __m128i v_y2 = {0};
33815   __m128i v_y3 = {0};
33816   uint64_t v_tail_index = 0;
33817 
33818   v_s = (4294967295u ^ self->private_impl.f_state);
33819   while ((((uint64_t)(a_x.len)) > 0u) && ((15u & ((uint32_t)(0xFFFu & (uintptr_t)(a_x.ptr)))) != 0u)) {
33820     v_s = (WUFFS_CRC32__IEEE_TABLE[0u][(((uint8_t)(v_s)) ^ a_x.ptr[0u])] ^ (v_s >> 8u));
33821     a_x = wuffs_base__slice_u8__subslice_i(a_x, 1u);
33822   }
33823   if (((uint64_t)(a_x.len)) < 64u) {
33824     {
33825       wuffs_base__slice_u8 i_slice_p = a_x;
33826       v_p.ptr = i_slice_p.ptr;
33827       v_p.len = 1;
33828       uint8_t* i_end0_p = i_slice_p.ptr + i_slice_p.len;
33829       while (v_p.ptr < i_end0_p) {
33830         v_s = (WUFFS_CRC32__IEEE_TABLE[0u][(((uint8_t)(v_s)) ^ v_p.ptr[0u])] ^ (v_s >> 8u));
33831         v_p.ptr += 1;
33832       }
33833       v_p.len = 0;
33834     }
33835     self->private_impl.f_state = (4294967295u ^ v_s);
33836     return wuffs_base__make_empty_struct();
33837   }
33838   v_x0 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 0u));
33839   v_x1 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 16u));
33840   v_x2 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 32u));
33841   v_x3 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 48u));
33842   v_x0 = _mm_xor_si128(v_x0, _mm_cvtsi32_si128((int32_t)(v_s)));
33843   v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_K1K2));
33844   {
33845     wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, 64u);
33846     v_p.ptr = i_slice_p.ptr;
33847     v_p.len = 64;
33848     uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 64) * 64);
33849     while (v_p.ptr < i_end0_p) {
33850       v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0u));
33851       v_y1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(0u));
33852       v_y2 = _mm_clmulepi64_si128(v_x2, v_k, (int32_t)(0u));
33853       v_y3 = _mm_clmulepi64_si128(v_x3, v_k, (int32_t)(0u));
33854       v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17u));
33855       v_x1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(17u));
33856       v_x2 = _mm_clmulepi64_si128(v_x2, v_k, (int32_t)(17u));
33857       v_x3 = _mm_clmulepi64_si128(v_x3, v_k, (int32_t)(17u));
33858       v_x0 = _mm_xor_si128(_mm_xor_si128(v_x0, v_y0), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 0u)));
33859       v_x1 = _mm_xor_si128(_mm_xor_si128(v_x1, v_y1), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 16u)));
33860       v_x2 = _mm_xor_si128(_mm_xor_si128(v_x2, v_y2), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 32u)));
33861       v_x3 = _mm_xor_si128(_mm_xor_si128(v_x3, v_y3), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 48u)));
33862       v_p.ptr += 64;
33863     }
33864     v_p.len = 0;
33865   }
33866   v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_K3K4));
33867   v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0u));
33868   v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17u));
33869   v_x0 = _mm_xor_si128(v_x0, v_x1);
33870   v_x0 = _mm_xor_si128(v_x0, v_y0);
33871   v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0u));
33872   v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17u));
33873   v_x0 = _mm_xor_si128(v_x0, v_x2);
33874   v_x0 = _mm_xor_si128(v_x0, v_y0);
33875   v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0u));
33876   v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17u));
33877   v_x0 = _mm_xor_si128(v_x0, v_x3);
33878   v_x0 = _mm_xor_si128(v_x0, v_y0);
33879   v_x1 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(16u));
33880   v_x2 = _mm_set_epi32((int32_t)(0u), (int32_t)(4294967295u), (int32_t)(0u), (int32_t)(4294967295u));
33881   v_x0 = _mm_srli_si128(v_x0, (int32_t)(8u));
33882   v_x0 = _mm_xor_si128(v_x0, v_x1);
33883   v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_K5ZZ));
33884   v_x1 = _mm_srli_si128(v_x0, (int32_t)(4u));
33885   v_x0 = _mm_and_si128(v_x0, v_x2);
33886   v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0u));
33887   v_x0 = _mm_xor_si128(v_x0, v_x1);
33888   v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_PXMU));
33889   v_x1 = _mm_and_si128(v_x0, v_x2);
33890   v_x1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(16u));
33891   v_x1 = _mm_and_si128(v_x1, v_x2);
33892   v_x1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(0u));
33893   v_x0 = _mm_xor_si128(v_x0, v_x1);
33894   v_s = ((uint32_t)(_mm_extract_epi32(v_x0, (int32_t)(1u))));
33895   v_tail_index = (((uint64_t)(a_x.len)) & 18446744073709551552u);
33896   if (v_tail_index < ((uint64_t)(a_x.len))) {
33897     {
33898       wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, v_tail_index);
33899       v_p.ptr = i_slice_p.ptr;
33900       v_p.len = 1;
33901       uint8_t* i_end0_p = i_slice_p.ptr + i_slice_p.len;
33902       while (v_p.ptr < i_end0_p) {
33903         v_s = (WUFFS_CRC32__IEEE_TABLE[0u][(((uint8_t)(v_s)) ^ v_p.ptr[0u])] ^ (v_s >> 8u));
33904         v_p.ptr += 1;
33905       }
33906       v_p.len = 0;
33907     }
33908   }
33909   self->private_impl.f_state = (4294967295u ^ v_s);
33910   return wuffs_base__make_empty_struct();
33911 }
33912 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_64)
33913 // ‼ WUFFS MULTI-FILE SECTION -x86_avx2
33914 
33915 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
33916 // -------- func crc32.ieee_hasher.up_x86_sse42
33917 
33918 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
33919 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
33920 WUFFS_BASE__GENERATED_C_CODE
33921 static wuffs_base__empty_struct
wuffs_crc32__ieee_hasher__up_x86_sse42(wuffs_crc32__ieee_hasher * self,wuffs_base__slice_u8 a_x)33922 wuffs_crc32__ieee_hasher__up_x86_sse42(
33923     wuffs_crc32__ieee_hasher* self,
33924     wuffs_base__slice_u8 a_x) {
33925   uint32_t v_s = 0;
33926   wuffs_base__slice_u8 v_p = {0};
33927   __m128i v_k = {0};
33928   __m128i v_x0 = {0};
33929   __m128i v_x1 = {0};
33930   __m128i v_x2 = {0};
33931   __m128i v_x3 = {0};
33932   __m128i v_y0 = {0};
33933   __m128i v_y1 = {0};
33934   __m128i v_y2 = {0};
33935   __m128i v_y3 = {0};
33936   uint64_t v_tail_index = 0;
33937 
33938   v_s = (4294967295u ^ self->private_impl.f_state);
33939   while ((((uint64_t)(a_x.len)) > 0u) && ((15u & ((uint32_t)(0xFFFu & (uintptr_t)(a_x.ptr)))) != 0u)) {
33940     v_s = (WUFFS_CRC32__IEEE_TABLE[0u][(((uint8_t)(v_s)) ^ a_x.ptr[0u])] ^ (v_s >> 8u));
33941     a_x = wuffs_base__slice_u8__subslice_i(a_x, 1u);
33942   }
33943   if (((uint64_t)(a_x.len)) < 64u) {
33944     {
33945       wuffs_base__slice_u8 i_slice_p = a_x;
33946       v_p.ptr = i_slice_p.ptr;
33947       v_p.len = 1;
33948       uint8_t* i_end0_p = i_slice_p.ptr + i_slice_p.len;
33949       while (v_p.ptr < i_end0_p) {
33950         v_s = (WUFFS_CRC32__IEEE_TABLE[0u][(((uint8_t)(v_s)) ^ v_p.ptr[0u])] ^ (v_s >> 8u));
33951         v_p.ptr += 1;
33952       }
33953       v_p.len = 0;
33954     }
33955     self->private_impl.f_state = (4294967295u ^ v_s);
33956     return wuffs_base__make_empty_struct();
33957   }
33958   v_x0 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 0u));
33959   v_x1 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 16u));
33960   v_x2 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 32u));
33961   v_x3 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 48u));
33962   v_x0 = _mm_xor_si128(v_x0, _mm_cvtsi32_si128((int32_t)(v_s)));
33963   v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_K1K2));
33964   {
33965     wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, 64u);
33966     v_p.ptr = i_slice_p.ptr;
33967     v_p.len = 64;
33968     uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 64) * 64);
33969     while (v_p.ptr < i_end0_p) {
33970       v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0u));
33971       v_y1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(0u));
33972       v_y2 = _mm_clmulepi64_si128(v_x2, v_k, (int32_t)(0u));
33973       v_y3 = _mm_clmulepi64_si128(v_x3, v_k, (int32_t)(0u));
33974       v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17u));
33975       v_x1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(17u));
33976       v_x2 = _mm_clmulepi64_si128(v_x2, v_k, (int32_t)(17u));
33977       v_x3 = _mm_clmulepi64_si128(v_x3, v_k, (int32_t)(17u));
33978       v_x0 = _mm_xor_si128(_mm_xor_si128(v_x0, v_y0), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 0u)));
33979       v_x1 = _mm_xor_si128(_mm_xor_si128(v_x1, v_y1), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 16u)));
33980       v_x2 = _mm_xor_si128(_mm_xor_si128(v_x2, v_y2), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 32u)));
33981       v_x3 = _mm_xor_si128(_mm_xor_si128(v_x3, v_y3), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 48u)));
33982       v_p.ptr += 64;
33983     }
33984     v_p.len = 0;
33985   }
33986   v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_K3K4));
33987   v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0u));
33988   v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17u));
33989   v_x0 = _mm_xor_si128(v_x0, v_x1);
33990   v_x0 = _mm_xor_si128(v_x0, v_y0);
33991   v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0u));
33992   v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17u));
33993   v_x0 = _mm_xor_si128(v_x0, v_x2);
33994   v_x0 = _mm_xor_si128(v_x0, v_y0);
33995   v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0u));
33996   v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17u));
33997   v_x0 = _mm_xor_si128(v_x0, v_x3);
33998   v_x0 = _mm_xor_si128(v_x0, v_y0);
33999   v_x1 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(16u));
34000   v_x2 = _mm_set_epi32((int32_t)(0u), (int32_t)(4294967295u), (int32_t)(0u), (int32_t)(4294967295u));
34001   v_x0 = _mm_srli_si128(v_x0, (int32_t)(8u));
34002   v_x0 = _mm_xor_si128(v_x0, v_x1);
34003   v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_K5ZZ));
34004   v_x1 = _mm_srli_si128(v_x0, (int32_t)(4u));
34005   v_x0 = _mm_and_si128(v_x0, v_x2);
34006   v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0u));
34007   v_x0 = _mm_xor_si128(v_x0, v_x1);
34008   v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_PXMU));
34009   v_x1 = _mm_and_si128(v_x0, v_x2);
34010   v_x1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(16u));
34011   v_x1 = _mm_and_si128(v_x1, v_x2);
34012   v_x1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(0u));
34013   v_x0 = _mm_xor_si128(v_x0, v_x1);
34014   v_s = ((uint32_t)(_mm_extract_epi32(v_x0, (int32_t)(1u))));
34015   v_tail_index = (((uint64_t)(a_x.len)) & 18446744073709551552u);
34016   if (v_tail_index < ((uint64_t)(a_x.len))) {
34017     {
34018       wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, v_tail_index);
34019       v_p.ptr = i_slice_p.ptr;
34020       v_p.len = 1;
34021       uint8_t* i_end0_p = i_slice_p.ptr + i_slice_p.len;
34022       while (v_p.ptr < i_end0_p) {
34023         v_s = (WUFFS_CRC32__IEEE_TABLE[0u][(((uint8_t)(v_s)) ^ v_p.ptr[0u])] ^ (v_s >> 8u));
34024         v_p.ptr += 1;
34025       }
34026       v_p.len = 0;
34027     }
34028   }
34029   self->private_impl.f_state = (4294967295u ^ v_s);
34030   return wuffs_base__make_empty_struct();
34031 }
34032 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
34033 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
34034 
34035 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CRC32)
34036 
34037 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__DEFLATE)
34038 
34039 // ---------------- Status Codes Implementations
34040 
34041 const char wuffs_deflate__error__bad_huffman_code_over_subscribed[] = "#deflate: bad Huffman code (over-subscribed)";
34042 const char wuffs_deflate__error__bad_huffman_code_under_subscribed[] = "#deflate: bad Huffman code (under-subscribed)";
34043 const char wuffs_deflate__error__bad_huffman_code_length_count[] = "#deflate: bad Huffman code length count";
34044 const char wuffs_deflate__error__bad_huffman_code_length_repetition[] = "#deflate: bad Huffman code length repetition";
34045 const char wuffs_deflate__error__bad_huffman_code[] = "#deflate: bad Huffman code";
34046 const char wuffs_deflate__error__bad_huffman_minimum_code_length[] = "#deflate: bad Huffman minimum code length";
34047 const char wuffs_deflate__error__bad_block[] = "#deflate: bad block";
34048 const char wuffs_deflate__error__bad_distance[] = "#deflate: bad distance";
34049 const char wuffs_deflate__error__bad_distance_code_count[] = "#deflate: bad distance code count";
34050 const char wuffs_deflate__error__bad_literal_length_code_count[] = "#deflate: bad literal/length code count";
34051 const char wuffs_deflate__error__inconsistent_stored_block_length[] = "#deflate: inconsistent stored block length";
34052 const char wuffs_deflate__error__missing_end_of_block_code[] = "#deflate: missing end-of-block code";
34053 const char wuffs_deflate__error__no_huffman_codes[] = "#deflate: no Huffman codes";
34054 const char wuffs_deflate__error__truncated_input[] = "#deflate: truncated input";
34055 const char wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state[] = "#deflate: internal error: inconsistent Huffman decoder state";
34056 const char wuffs_deflate__error__internal_error_inconsistent_i_o[] = "#deflate: internal error: inconsistent I/O";
34057 const char wuffs_deflate__error__internal_error_inconsistent_distance[] = "#deflate: internal error: inconsistent distance";
34058 const char wuffs_deflate__error__internal_error_inconsistent_n_bits[] = "#deflate: internal error: inconsistent n_bits";
34059 
34060 // ---------------- Private Consts
34061 
34062 static const uint8_t
34063 WUFFS_DEFLATE__CODE_ORDER[19] WUFFS_BASE__POTENTIALLY_UNUSED = {
34064   16, 17, 18, 0, 8, 7, 9, 6,
34065   10, 5, 11, 4, 12, 3, 13, 2,
34066   14, 1, 15,
34067 };
34068 
34069 static const uint8_t
34070 WUFFS_DEFLATE__REVERSE8[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
34071   0, 128, 64, 192, 32, 160, 96, 224,
34072   16, 144, 80, 208, 48, 176, 112, 240,
34073   8, 136, 72, 200, 40, 168, 104, 232,
34074   24, 152, 88, 216, 56, 184, 120, 248,
34075   4, 132, 68, 196, 36, 164, 100, 228,
34076   20, 148, 84, 212, 52, 180, 116, 244,
34077   12, 140, 76, 204, 44, 172, 108, 236,
34078   28, 156, 92, 220, 60, 188, 124, 252,
34079   2, 130, 66, 194, 34, 162, 98, 226,
34080   18, 146, 82, 210, 50, 178, 114, 242,
34081   10, 138, 74, 202, 42, 170, 106, 234,
34082   26, 154, 90, 218, 58, 186, 122, 250,
34083   6, 134, 70, 198, 38, 166, 102, 230,
34084   22, 150, 86, 214, 54, 182, 118, 246,
34085   14, 142, 78, 206, 46, 174, 110, 238,
34086   30, 158, 94, 222, 62, 190, 126, 254,
34087   1, 129, 65, 193, 33, 161, 97, 225,
34088   17, 145, 81, 209, 49, 177, 113, 241,
34089   9, 137, 73, 201, 41, 169, 105, 233,
34090   25, 153, 89, 217, 57, 185, 121, 249,
34091   5, 133, 69, 197, 37, 165, 101, 229,
34092   21, 149, 85, 213, 53, 181, 117, 245,
34093   13, 141, 77, 205, 45, 173, 109, 237,
34094   29, 157, 93, 221, 61, 189, 125, 253,
34095   3, 131, 67, 195, 35, 163, 99, 227,
34096   19, 147, 83, 211, 51, 179, 115, 243,
34097   11, 139, 75, 203, 43, 171, 107, 235,
34098   27, 155, 91, 219, 59, 187, 123, 251,
34099   7, 135, 71, 199, 39, 167, 103, 231,
34100   23, 151, 87, 215, 55, 183, 119, 247,
34101   15, 143, 79, 207, 47, 175, 111, 239,
34102   31, 159, 95, 223, 63, 191, 127, 255,
34103 };
34104 
34105 static const uint32_t
34106 WUFFS_DEFLATE__LCODE_MAGIC_NUMBERS[32] WUFFS_BASE__POTENTIALLY_UNUSED = {
34107   1073741824, 1073742080, 1073742336, 1073742592, 1073742848, 1073743104, 1073743360, 1073743616,
34108   1073743888, 1073744400, 1073744912, 1073745424, 1073745952, 1073746976, 1073748000, 1073749024,
34109   1073750064, 1073752112, 1073754160, 1073756208, 1073758272, 1073762368, 1073766464, 1073770560,
34110   1073774672, 1073782864, 1073791056, 1073799248, 1073807104, 134217728, 134217728, 134217728,
34111 };
34112 
34113 static const uint32_t
34114 WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[32] WUFFS_BASE__POTENTIALLY_UNUSED = {
34115   1073741824, 1073742080, 1073742336, 1073742592, 1073742864, 1073743376, 1073743904, 1073744928,
34116   1073745968, 1073748016, 1073750080, 1073754176, 1073758288, 1073766480, 1073774688, 1073791072,
34117   1073807472, 1073840240, 1073873024, 1073938560, 1074004112, 1074135184, 1074266272, 1074528416,
34118   1074790576, 1075314864, 1075839168, 1076887744, 1077936336, 1080033488, 134217728, 134217728,
34119 };
34120 
34121 #define WUFFS_DEFLATE__HUFFS_TABLE_SIZE 1024
34122 
34123 #define WUFFS_DEFLATE__HUFFS_TABLE_MASK 1023
34124 
34125 // ---------------- Private Initializer Prototypes
34126 
34127 // ---------------- Private Function Prototypes
34128 
34129 WUFFS_BASE__GENERATED_C_CODE
34130 static wuffs_base__status
34131 wuffs_deflate__decoder__do_transform_io(
34132     wuffs_deflate__decoder* self,
34133     wuffs_base__io_buffer* a_dst,
34134     wuffs_base__io_buffer* a_src,
34135     wuffs_base__slice_u8 a_workbuf);
34136 
34137 WUFFS_BASE__GENERATED_C_CODE
34138 static wuffs_base__status
34139 wuffs_deflate__decoder__decode_blocks(
34140     wuffs_deflate__decoder* self,
34141     wuffs_base__io_buffer* a_dst,
34142     wuffs_base__io_buffer* a_src);
34143 
34144 WUFFS_BASE__GENERATED_C_CODE
34145 static wuffs_base__status
34146 wuffs_deflate__decoder__decode_uncompressed(
34147     wuffs_deflate__decoder* self,
34148     wuffs_base__io_buffer* a_dst,
34149     wuffs_base__io_buffer* a_src);
34150 
34151 WUFFS_BASE__GENERATED_C_CODE
34152 static wuffs_base__status
34153 wuffs_deflate__decoder__init_fixed_huffman(
34154     wuffs_deflate__decoder* self);
34155 
34156 WUFFS_BASE__GENERATED_C_CODE
34157 static wuffs_base__status
34158 wuffs_deflate__decoder__init_dynamic_huffman(
34159     wuffs_deflate__decoder* self,
34160     wuffs_base__io_buffer* a_src);
34161 
34162 WUFFS_BASE__GENERATED_C_CODE
34163 static wuffs_base__status
34164 wuffs_deflate__decoder__init_huff(
34165     wuffs_deflate__decoder* self,
34166     uint32_t a_which,
34167     uint32_t a_n_codes0,
34168     uint32_t a_n_codes1,
34169     uint32_t a_base_symbol);
34170 
34171 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
34172 WUFFS_BASE__GENERATED_C_CODE
34173 static wuffs_base__status
34174 wuffs_deflate__decoder__decode_huffman_bmi2(
34175     wuffs_deflate__decoder* self,
34176     wuffs_base__io_buffer* a_dst,
34177     wuffs_base__io_buffer* a_src);
34178 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
34179 
34180 WUFFS_BASE__GENERATED_C_CODE
34181 static wuffs_base__status
34182 wuffs_deflate__decoder__decode_huffman_fast32(
34183     wuffs_deflate__decoder* self,
34184     wuffs_base__io_buffer* a_dst,
34185     wuffs_base__io_buffer* a_src);
34186 
34187 WUFFS_BASE__GENERATED_C_CODE
34188 static wuffs_base__status
34189 wuffs_deflate__decoder__decode_huffman_fast64(
34190     wuffs_deflate__decoder* self,
34191     wuffs_base__io_buffer* a_dst,
34192     wuffs_base__io_buffer* a_src);
34193 
34194 WUFFS_BASE__GENERATED_C_CODE
34195 static wuffs_base__status
34196 wuffs_deflate__decoder__decode_huffman_fast64__choosy_default(
34197     wuffs_deflate__decoder* self,
34198     wuffs_base__io_buffer* a_dst,
34199     wuffs_base__io_buffer* a_src);
34200 
34201 WUFFS_BASE__GENERATED_C_CODE
34202 static wuffs_base__status
34203 wuffs_deflate__decoder__decode_huffman_slow(
34204     wuffs_deflate__decoder* self,
34205     wuffs_base__io_buffer* a_dst,
34206     wuffs_base__io_buffer* a_src);
34207 
34208 // ---------------- VTables
34209 
34210 const wuffs_base__io_transformer__func_ptrs
34211 wuffs_deflate__decoder__func_ptrs_for__wuffs_base__io_transformer = {
34212   (uint64_t(*)(const void*,
34213       uint32_t))(&wuffs_deflate__decoder__get_quirk),
34214   (uint64_t(*)(const void*))(&wuffs_deflate__decoder__history_retain_length),
34215   (wuffs_base__status(*)(void*,
34216       uint32_t,
34217       uint64_t))(&wuffs_deflate__decoder__set_quirk),
34218   (wuffs_base__status(*)(void*,
34219       wuffs_base__io_buffer*,
34220       wuffs_base__io_buffer*,
34221       wuffs_base__slice_u8))(&wuffs_deflate__decoder__transform_io),
34222   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_deflate__decoder__workbuf_len),
34223 };
34224 
34225 // ---------------- Initializer Implementations
34226 
34227 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
wuffs_deflate__decoder__initialize(wuffs_deflate__decoder * self,size_t sizeof_star_self,uint64_t wuffs_version,uint32_t options)34228 wuffs_deflate__decoder__initialize(
34229     wuffs_deflate__decoder* self,
34230     size_t sizeof_star_self,
34231     uint64_t wuffs_version,
34232     uint32_t options){
34233   if (!self) {
34234     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
34235   }
34236   if (sizeof(*self) != sizeof_star_self) {
34237     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
34238   }
34239   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
34240       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
34241     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
34242   }
34243 
34244   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
34245     // The whole point of this if-check is to detect an uninitialized *self.
34246     // We disable the warning on GCC. Clang-5.0 does not have this warning.
34247 #if !defined(__clang__) && defined(__GNUC__)
34248 #pragma GCC diagnostic push
34249 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
34250 #endif
34251     if (self->private_impl.magic != 0) {
34252       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
34253     }
34254 #if !defined(__clang__) && defined(__GNUC__)
34255 #pragma GCC diagnostic pop
34256 #endif
34257   } else {
34258     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
34259       memset(self, 0, sizeof(*self));
34260       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
34261     } else {
34262       memset(&(self->private_impl), 0, sizeof(self->private_impl));
34263     }
34264   }
34265 
34266   self->private_impl.choosy_decode_huffman_fast64 = &wuffs_deflate__decoder__decode_huffman_fast64__choosy_default;
34267 
34268   self->private_impl.magic = WUFFS_BASE__MAGIC;
34269   self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name =
34270       wuffs_base__io_transformer__vtable_name;
34271   self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers =
34272       (const void*)(&wuffs_deflate__decoder__func_ptrs_for__wuffs_base__io_transformer);
34273   return wuffs_base__make_status(NULL);
34274 }
34275 
34276 wuffs_deflate__decoder*
wuffs_deflate__decoder__alloc(void)34277 wuffs_deflate__decoder__alloc(void) {
34278   wuffs_deflate__decoder* x =
34279       (wuffs_deflate__decoder*)(calloc(sizeof(wuffs_deflate__decoder), 1));
34280   if (!x) {
34281     return NULL;
34282   }
34283   if (wuffs_deflate__decoder__initialize(
34284       x, sizeof(wuffs_deflate__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
34285     free(x);
34286     return NULL;
34287   }
34288   return x;
34289 }
34290 
34291 size_t
sizeof__wuffs_deflate__decoder(void)34292 sizeof__wuffs_deflate__decoder(void) {
34293   return sizeof(wuffs_deflate__decoder);
34294 }
34295 
34296 // ---------------- Function Implementations
34297 
34298 // -------- func deflate.decoder.add_history
34299 
34300 WUFFS_BASE__GENERATED_C_CODE
34301 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_deflate__decoder__add_history(wuffs_deflate__decoder * self,wuffs_base__slice_u8 a_hist)34302 wuffs_deflate__decoder__add_history(
34303     wuffs_deflate__decoder* self,
34304     wuffs_base__slice_u8 a_hist) {
34305   if (!self) {
34306     return wuffs_base__make_empty_struct();
34307   }
34308   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
34309     return wuffs_base__make_empty_struct();
34310   }
34311 
34312   wuffs_base__slice_u8 v_s = {0};
34313   uint64_t v_n_copied = 0;
34314   uint32_t v_already_full = 0;
34315 
34316   v_s = a_hist;
34317   if (((uint64_t)(v_s.len)) >= 32768u) {
34318     v_s = wuffs_base__slice_u8__suffix(v_s, 32768u);
34319     wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8(self->private_data.f_history, 32768), v_s);
34320     self->private_impl.f_history_index = 32768u;
34321   } else {
34322     v_n_copied = wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8_ij(self->private_data.f_history, (self->private_impl.f_history_index & 32767u), 32768), v_s);
34323     if (v_n_copied < ((uint64_t)(v_s.len))) {
34324       v_s = wuffs_base__slice_u8__subslice_i(v_s, v_n_copied);
34325       v_n_copied = wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8(self->private_data.f_history, 32768), v_s);
34326       self->private_impl.f_history_index = (((uint32_t)((v_n_copied & 32767u))) + 32768u);
34327     } else {
34328       v_already_full = 0u;
34329       if (self->private_impl.f_history_index >= 32768u) {
34330         v_already_full = 32768u;
34331       }
34332       self->private_impl.f_history_index = ((self->private_impl.f_history_index & 32767u) + ((uint32_t)((v_n_copied & 32767u))) + v_already_full);
34333     }
34334   }
34335   wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8_ij(self->private_data.f_history, 32768, 33025), wuffs_base__make_slice_u8(self->private_data.f_history, 33025));
34336   return wuffs_base__make_empty_struct();
34337 }
34338 
34339 // -------- func deflate.decoder.get_quirk
34340 
34341 WUFFS_BASE__GENERATED_C_CODE
34342 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_deflate__decoder__get_quirk(const wuffs_deflate__decoder * self,uint32_t a_key)34343 wuffs_deflate__decoder__get_quirk(
34344     const wuffs_deflate__decoder* self,
34345     uint32_t a_key) {
34346   if (!self) {
34347     return 0;
34348   }
34349   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
34350       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
34351     return 0;
34352   }
34353 
34354   return 0u;
34355 }
34356 
34357 // -------- func deflate.decoder.set_quirk
34358 
34359 WUFFS_BASE__GENERATED_C_CODE
34360 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_deflate__decoder__set_quirk(wuffs_deflate__decoder * self,uint32_t a_key,uint64_t a_value)34361 wuffs_deflate__decoder__set_quirk(
34362     wuffs_deflate__decoder* self,
34363     uint32_t a_key,
34364     uint64_t a_value) {
34365   if (!self) {
34366     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
34367   }
34368   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
34369     return wuffs_base__make_status(
34370         (self->private_impl.magic == WUFFS_BASE__DISABLED)
34371         ? wuffs_base__error__disabled_by_previous_error
34372         : wuffs_base__error__initialize_not_called);
34373   }
34374 
34375   return wuffs_base__make_status(wuffs_base__error__unsupported_option);
34376 }
34377 
34378 // -------- func deflate.decoder.history_retain_length
34379 
34380 WUFFS_BASE__GENERATED_C_CODE
34381 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_deflate__decoder__history_retain_length(const wuffs_deflate__decoder * self)34382 wuffs_deflate__decoder__history_retain_length(
34383     const wuffs_deflate__decoder* self) {
34384   if (!self) {
34385     return 0;
34386   }
34387   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
34388       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
34389     return 0;
34390   }
34391 
34392   return 0u;
34393 }
34394 
34395 // -------- func deflate.decoder.workbuf_len
34396 
34397 WUFFS_BASE__GENERATED_C_CODE
34398 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_deflate__decoder__workbuf_len(const wuffs_deflate__decoder * self)34399 wuffs_deflate__decoder__workbuf_len(
34400     const wuffs_deflate__decoder* self) {
34401   if (!self) {
34402     return wuffs_base__utility__empty_range_ii_u64();
34403   }
34404   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
34405       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
34406     return wuffs_base__utility__empty_range_ii_u64();
34407   }
34408 
34409   return wuffs_base__utility__make_range_ii_u64(1u, 1u);
34410 }
34411 
34412 // -------- func deflate.decoder.transform_io
34413 
34414 WUFFS_BASE__GENERATED_C_CODE
34415 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_deflate__decoder__transform_io(wuffs_deflate__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__slice_u8 a_workbuf)34416 wuffs_deflate__decoder__transform_io(
34417     wuffs_deflate__decoder* self,
34418     wuffs_base__io_buffer* a_dst,
34419     wuffs_base__io_buffer* a_src,
34420     wuffs_base__slice_u8 a_workbuf) {
34421   if (!self) {
34422     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
34423   }
34424   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
34425     return wuffs_base__make_status(
34426         (self->private_impl.magic == WUFFS_BASE__DISABLED)
34427         ? wuffs_base__error__disabled_by_previous_error
34428         : wuffs_base__error__initialize_not_called);
34429   }
34430   if (!a_dst || !a_src) {
34431     self->private_impl.magic = WUFFS_BASE__DISABLED;
34432     return wuffs_base__make_status(wuffs_base__error__bad_argument);
34433   }
34434   if ((self->private_impl.active_coroutine != 0) &&
34435       (self->private_impl.active_coroutine != 1)) {
34436     self->private_impl.magic = WUFFS_BASE__DISABLED;
34437     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
34438   }
34439   self->private_impl.active_coroutine = 0;
34440   wuffs_base__status status = wuffs_base__make_status(NULL);
34441 
34442   wuffs_base__status v_status = wuffs_base__make_status(NULL);
34443 
34444   uint32_t coro_susp_point = self->private_impl.p_transform_io[0];
34445   switch (coro_susp_point) {
34446     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
34447 
34448     while (true) {
34449       {
34450         wuffs_base__status t_0 = wuffs_deflate__decoder__do_transform_io(self, a_dst, a_src, a_workbuf);
34451         v_status = t_0;
34452       }
34453       if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
34454         status = wuffs_base__make_status(wuffs_deflate__error__truncated_input);
34455         goto exit;
34456       }
34457       status = v_status;
34458       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
34459     }
34460 
34461     ok:
34462     self->private_impl.p_transform_io[0] = 0;
34463     goto exit;
34464   }
34465 
34466   goto suspend;
34467   suspend:
34468   self->private_impl.p_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
34469   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
34470 
34471   goto exit;
34472   exit:
34473   if (wuffs_base__status__is_error(&status)) {
34474     self->private_impl.magic = WUFFS_BASE__DISABLED;
34475   }
34476   return status;
34477 }
34478 
34479 // -------- func deflate.decoder.do_transform_io
34480 
34481 WUFFS_BASE__GENERATED_C_CODE
34482 static wuffs_base__status
wuffs_deflate__decoder__do_transform_io(wuffs_deflate__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__slice_u8 a_workbuf)34483 wuffs_deflate__decoder__do_transform_io(
34484     wuffs_deflate__decoder* self,
34485     wuffs_base__io_buffer* a_dst,
34486     wuffs_base__io_buffer* a_src,
34487     wuffs_base__slice_u8 a_workbuf) {
34488   wuffs_base__status status = wuffs_base__make_status(NULL);
34489 
34490   uint64_t v_mark = 0;
34491   wuffs_base__status v_status = wuffs_base__make_status(NULL);
34492 
34493   uint8_t* iop_a_dst = NULL;
34494   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34495   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34496   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34497   if (a_dst && a_dst->data.ptr) {
34498     io0_a_dst = a_dst->data.ptr;
34499     io1_a_dst = io0_a_dst + a_dst->meta.wi;
34500     iop_a_dst = io1_a_dst;
34501     io2_a_dst = io0_a_dst + a_dst->data.len;
34502     if (a_dst->meta.closed) {
34503       io2_a_dst = iop_a_dst;
34504     }
34505   }
34506 
34507   uint32_t coro_susp_point = self->private_impl.p_do_transform_io[0];
34508   switch (coro_susp_point) {
34509     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
34510 
34511     self->private_impl.choosy_decode_huffman_fast64 = (
34512 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
34513         wuffs_base__cpu_arch__have_x86_bmi2() ? &wuffs_deflate__decoder__decode_huffman_bmi2 :
34514 #endif
34515         self->private_impl.choosy_decode_huffman_fast64);
34516     while (true) {
34517       v_mark = ((uint64_t)(iop_a_dst - io0_a_dst));
34518       {
34519         if (a_dst) {
34520           a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
34521         }
34522         wuffs_base__status t_0 = wuffs_deflate__decoder__decode_blocks(self, a_dst, a_src);
34523         v_status = t_0;
34524         if (a_dst) {
34525           iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
34526         }
34527       }
34528       if ( ! wuffs_base__status__is_suspension(&v_status)) {
34529         status = v_status;
34530         if (wuffs_base__status__is_error(&status)) {
34531           goto exit;
34532         } else if (wuffs_base__status__is_suspension(&status)) {
34533           status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
34534           goto exit;
34535         }
34536         goto ok;
34537       }
34538       wuffs_base__u64__sat_add_indirect(&self->private_impl.f_transformed_history_count, wuffs_base__io__count_since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst))));
34539       wuffs_deflate__decoder__add_history(self, wuffs_base__io__since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst));
34540       status = v_status;
34541       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
34542     }
34543 
34544     ok:
34545     self->private_impl.p_do_transform_io[0] = 0;
34546     goto exit;
34547   }
34548 
34549   goto suspend;
34550   suspend:
34551   self->private_impl.p_do_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
34552 
34553   goto exit;
34554   exit:
34555   if (a_dst && a_dst->data.ptr) {
34556     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
34557   }
34558 
34559   return status;
34560 }
34561 
34562 // -------- func deflate.decoder.decode_blocks
34563 
34564 WUFFS_BASE__GENERATED_C_CODE
34565 static wuffs_base__status
wuffs_deflate__decoder__decode_blocks(wuffs_deflate__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__io_buffer * a_src)34566 wuffs_deflate__decoder__decode_blocks(
34567     wuffs_deflate__decoder* self,
34568     wuffs_base__io_buffer* a_dst,
34569     wuffs_base__io_buffer* a_src) {
34570   wuffs_base__status status = wuffs_base__make_status(NULL);
34571 
34572   uint32_t v_final = 0;
34573   uint32_t v_b0 = 0;
34574   uint32_t v_type = 0;
34575   wuffs_base__status v_status = wuffs_base__make_status(NULL);
34576 
34577   const uint8_t* iop_a_src = NULL;
34578   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34579   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34580   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34581   if (a_src && a_src->data.ptr) {
34582     io0_a_src = a_src->data.ptr;
34583     io1_a_src = io0_a_src + a_src->meta.ri;
34584     iop_a_src = io1_a_src;
34585     io2_a_src = io0_a_src + a_src->meta.wi;
34586   }
34587 
34588   uint32_t coro_susp_point = self->private_impl.p_decode_blocks[0];
34589   if (coro_susp_point) {
34590     v_final = self->private_data.s_decode_blocks[0].v_final;
34591   }
34592   switch (coro_susp_point) {
34593     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
34594 
34595     label__outer__continue:;
34596     while (v_final == 0u) {
34597       while (self->private_impl.f_n_bits < 3u) {
34598         {
34599           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
34600           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
34601             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34602             goto suspend;
34603           }
34604           uint32_t t_0 = *iop_a_src++;
34605           v_b0 = t_0;
34606         }
34607         self->private_impl.f_bits |= (v_b0 << (self->private_impl.f_n_bits & 3u));
34608         self->private_impl.f_n_bits = ((self->private_impl.f_n_bits & 3u) + 8u);
34609       }
34610       v_final = (self->private_impl.f_bits & 1u);
34611       v_type = ((self->private_impl.f_bits >> 1u) & 3u);
34612       self->private_impl.f_bits >>= 3u;
34613       self->private_impl.f_n_bits -= 3u;
34614       if (v_type == 0u) {
34615         if (a_src) {
34616           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
34617         }
34618         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
34619         status = wuffs_deflate__decoder__decode_uncompressed(self, a_dst, a_src);
34620         if (a_src) {
34621           iop_a_src = a_src->data.ptr + a_src->meta.ri;
34622         }
34623         if (status.repr) {
34624           goto suspend;
34625         }
34626         continue;
34627       } else if (v_type == 1u) {
34628         v_status = wuffs_deflate__decoder__init_fixed_huffman(self);
34629         if ( ! wuffs_base__status__is_ok(&v_status)) {
34630           status = v_status;
34631           if (wuffs_base__status__is_error(&status)) {
34632             goto exit;
34633           } else if (wuffs_base__status__is_suspension(&status)) {
34634             status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
34635             goto exit;
34636           }
34637           goto ok;
34638         }
34639       } else if (v_type == 2u) {
34640         if (a_src) {
34641           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
34642         }
34643         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
34644         status = wuffs_deflate__decoder__init_dynamic_huffman(self, a_src);
34645         if (a_src) {
34646           iop_a_src = a_src->data.ptr + a_src->meta.ri;
34647         }
34648         if (status.repr) {
34649           goto suspend;
34650         }
34651       } else {
34652         status = wuffs_base__make_status(wuffs_deflate__error__bad_block);
34653         goto exit;
34654       }
34655       self->private_impl.f_end_of_block = false;
34656       while (true) {
34657         if (sizeof(void*) == 4u) {
34658           if (a_src) {
34659             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
34660           }
34661           v_status = wuffs_deflate__decoder__decode_huffman_fast32(self, a_dst, a_src);
34662           if (a_src) {
34663             iop_a_src = a_src->data.ptr + a_src->meta.ri;
34664           }
34665         } else {
34666           if (a_src) {
34667             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
34668           }
34669           v_status = wuffs_deflate__decoder__decode_huffman_fast64(self, a_dst, a_src);
34670           if (a_src) {
34671             iop_a_src = a_src->data.ptr + a_src->meta.ri;
34672           }
34673         }
34674         if (wuffs_base__status__is_error(&v_status)) {
34675           status = v_status;
34676           goto exit;
34677         }
34678         if (self->private_impl.f_end_of_block) {
34679           goto label__outer__continue;
34680         }
34681         if (a_src) {
34682           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
34683         }
34684         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
34685         status = wuffs_deflate__decoder__decode_huffman_slow(self, a_dst, a_src);
34686         if (a_src) {
34687           iop_a_src = a_src->data.ptr + a_src->meta.ri;
34688         }
34689         if (status.repr) {
34690           goto suspend;
34691         }
34692         if (self->private_impl.f_end_of_block) {
34693           goto label__outer__continue;
34694         }
34695       }
34696     }
34697 
34698     ok:
34699     self->private_impl.p_decode_blocks[0] = 0;
34700     goto exit;
34701   }
34702 
34703   goto suspend;
34704   suspend:
34705   self->private_impl.p_decode_blocks[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
34706   self->private_data.s_decode_blocks[0].v_final = v_final;
34707 
34708   goto exit;
34709   exit:
34710   if (a_src && a_src->data.ptr) {
34711     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
34712   }
34713 
34714   return status;
34715 }
34716 
34717 // -------- func deflate.decoder.decode_uncompressed
34718 
34719 WUFFS_BASE__GENERATED_C_CODE
34720 static wuffs_base__status
wuffs_deflate__decoder__decode_uncompressed(wuffs_deflate__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__io_buffer * a_src)34721 wuffs_deflate__decoder__decode_uncompressed(
34722     wuffs_deflate__decoder* self,
34723     wuffs_base__io_buffer* a_dst,
34724     wuffs_base__io_buffer* a_src) {
34725   wuffs_base__status status = wuffs_base__make_status(NULL);
34726 
34727   uint32_t v_length = 0;
34728   uint32_t v_n_copied = 0;
34729 
34730   uint8_t* iop_a_dst = NULL;
34731   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34732   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34733   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34734   if (a_dst && a_dst->data.ptr) {
34735     io0_a_dst = a_dst->data.ptr;
34736     io1_a_dst = io0_a_dst + a_dst->meta.wi;
34737     iop_a_dst = io1_a_dst;
34738     io2_a_dst = io0_a_dst + a_dst->data.len;
34739     if (a_dst->meta.closed) {
34740       io2_a_dst = iop_a_dst;
34741     }
34742   }
34743   const uint8_t* iop_a_src = NULL;
34744   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34745   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34746   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34747   if (a_src && a_src->data.ptr) {
34748     io0_a_src = a_src->data.ptr;
34749     io1_a_src = io0_a_src + a_src->meta.ri;
34750     iop_a_src = io1_a_src;
34751     io2_a_src = io0_a_src + a_src->meta.wi;
34752   }
34753 
34754   uint32_t coro_susp_point = self->private_impl.p_decode_uncompressed[0];
34755   if (coro_susp_point) {
34756     v_length = self->private_data.s_decode_uncompressed[0].v_length;
34757   }
34758   switch (coro_susp_point) {
34759     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
34760 
34761     if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7u)) != 0u)) {
34762       status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
34763       goto exit;
34764     }
34765     self->private_impl.f_n_bits = 0u;
34766     self->private_impl.f_bits = 0u;
34767     {
34768       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
34769       uint32_t t_0;
34770       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
34771         t_0 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
34772         iop_a_src += 4;
34773       } else {
34774         self->private_data.s_decode_uncompressed[0].scratch = 0;
34775         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
34776         while (true) {
34777           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
34778             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34779             goto suspend;
34780           }
34781           uint64_t* scratch = &self->private_data.s_decode_uncompressed[0].scratch;
34782           uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
34783           *scratch <<= 8;
34784           *scratch >>= 8;
34785           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
34786           if (num_bits_0 == 24) {
34787             t_0 = ((uint32_t)(*scratch));
34788             break;
34789           }
34790           num_bits_0 += 8u;
34791           *scratch |= ((uint64_t)(num_bits_0)) << 56;
34792         }
34793       }
34794       v_length = t_0;
34795     }
34796     if ((((v_length) & 0xFFFFu) + ((v_length) >> (32u - 16u))) != 65535u) {
34797       status = wuffs_base__make_status(wuffs_deflate__error__inconsistent_stored_block_length);
34798       goto exit;
34799     }
34800     v_length = ((v_length) & 0xFFFFu);
34801     while (true) {
34802       v_n_copied = wuffs_base__io_writer__limited_copy_u32_from_reader(
34803           &iop_a_dst, io2_a_dst,v_length, &iop_a_src, io2_a_src);
34804       if (v_length <= v_n_copied) {
34805         status = wuffs_base__make_status(NULL);
34806         goto ok;
34807       }
34808       v_length -= v_n_copied;
34809       if (((uint64_t)(io2_a_dst - iop_a_dst)) == 0u) {
34810         status = wuffs_base__make_status(wuffs_base__suspension__short_write);
34811         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
34812       } else {
34813         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34814         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
34815       }
34816     }
34817 
34818     ok:
34819     self->private_impl.p_decode_uncompressed[0] = 0;
34820     goto exit;
34821   }
34822 
34823   goto suspend;
34824   suspend:
34825   self->private_impl.p_decode_uncompressed[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
34826   self->private_data.s_decode_uncompressed[0].v_length = v_length;
34827 
34828   goto exit;
34829   exit:
34830   if (a_dst && a_dst->data.ptr) {
34831     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
34832   }
34833   if (a_src && a_src->data.ptr) {
34834     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
34835   }
34836 
34837   return status;
34838 }
34839 
34840 // -------- func deflate.decoder.init_fixed_huffman
34841 
34842 WUFFS_BASE__GENERATED_C_CODE
34843 static wuffs_base__status
wuffs_deflate__decoder__init_fixed_huffman(wuffs_deflate__decoder * self)34844 wuffs_deflate__decoder__init_fixed_huffman(
34845     wuffs_deflate__decoder* self) {
34846   uint32_t v_i = 0;
34847   wuffs_base__status v_status = wuffs_base__make_status(NULL);
34848 
34849   while (v_i < 144u) {
34850     self->private_data.f_code_lengths[v_i] = 8u;
34851     v_i += 1u;
34852   }
34853   while (v_i < 256u) {
34854     self->private_data.f_code_lengths[v_i] = 9u;
34855     v_i += 1u;
34856   }
34857   while (v_i < 280u) {
34858     self->private_data.f_code_lengths[v_i] = 7u;
34859     v_i += 1u;
34860   }
34861   while (v_i < 288u) {
34862     self->private_data.f_code_lengths[v_i] = 8u;
34863     v_i += 1u;
34864   }
34865   while (v_i < 320u) {
34866     self->private_data.f_code_lengths[v_i] = 5u;
34867     v_i += 1u;
34868   }
34869   v_status = wuffs_deflate__decoder__init_huff(self,
34870       0u,
34871       0u,
34872       288u,
34873       257u);
34874   if (wuffs_base__status__is_error(&v_status)) {
34875     return v_status;
34876   }
34877   v_status = wuffs_deflate__decoder__init_huff(self,
34878       1u,
34879       288u,
34880       320u,
34881       0u);
34882   if (wuffs_base__status__is_error(&v_status)) {
34883     return v_status;
34884   }
34885   return wuffs_base__make_status(NULL);
34886 }
34887 
34888 // -------- func deflate.decoder.init_dynamic_huffman
34889 
34890 WUFFS_BASE__GENERATED_C_CODE
34891 static wuffs_base__status
wuffs_deflate__decoder__init_dynamic_huffman(wuffs_deflate__decoder * self,wuffs_base__io_buffer * a_src)34892 wuffs_deflate__decoder__init_dynamic_huffman(
34893     wuffs_deflate__decoder* self,
34894     wuffs_base__io_buffer* a_src) {
34895   wuffs_base__status status = wuffs_base__make_status(NULL);
34896 
34897   uint32_t v_bits = 0;
34898   uint32_t v_n_bits = 0;
34899   uint32_t v_b0 = 0;
34900   uint32_t v_n_lit = 0;
34901   uint32_t v_n_dist = 0;
34902   uint32_t v_n_clen = 0;
34903   uint32_t v_i = 0;
34904   uint32_t v_b1 = 0;
34905   wuffs_base__status v_status = wuffs_base__make_status(NULL);
34906   uint32_t v_mask = 0;
34907   uint32_t v_table_entry = 0;
34908   uint32_t v_table_entry_n_bits = 0;
34909   uint32_t v_b2 = 0;
34910   uint32_t v_n_extra_bits = 0;
34911   uint8_t v_rep_symbol = 0;
34912   uint32_t v_rep_count = 0;
34913   uint32_t v_b3 = 0;
34914 
34915   const uint8_t* iop_a_src = NULL;
34916   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34917   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34918   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34919   if (a_src && a_src->data.ptr) {
34920     io0_a_src = a_src->data.ptr;
34921     io1_a_src = io0_a_src + a_src->meta.ri;
34922     iop_a_src = io1_a_src;
34923     io2_a_src = io0_a_src + a_src->meta.wi;
34924   }
34925 
34926   uint32_t coro_susp_point = self->private_impl.p_init_dynamic_huffman[0];
34927   if (coro_susp_point) {
34928     v_bits = self->private_data.s_init_dynamic_huffman[0].v_bits;
34929     v_n_bits = self->private_data.s_init_dynamic_huffman[0].v_n_bits;
34930     v_n_lit = self->private_data.s_init_dynamic_huffman[0].v_n_lit;
34931     v_n_dist = self->private_data.s_init_dynamic_huffman[0].v_n_dist;
34932     v_n_clen = self->private_data.s_init_dynamic_huffman[0].v_n_clen;
34933     v_i = self->private_data.s_init_dynamic_huffman[0].v_i;
34934     v_mask = self->private_data.s_init_dynamic_huffman[0].v_mask;
34935     v_n_extra_bits = self->private_data.s_init_dynamic_huffman[0].v_n_extra_bits;
34936     v_rep_symbol = self->private_data.s_init_dynamic_huffman[0].v_rep_symbol;
34937     v_rep_count = self->private_data.s_init_dynamic_huffman[0].v_rep_count;
34938   }
34939   switch (coro_susp_point) {
34940     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
34941 
34942     v_bits = self->private_impl.f_bits;
34943     v_n_bits = self->private_impl.f_n_bits;
34944     while (v_n_bits < 14u) {
34945       {
34946         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
34947         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
34948           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34949           goto suspend;
34950         }
34951         uint32_t t_0 = *iop_a_src++;
34952         v_b0 = t_0;
34953       }
34954       v_bits |= (v_b0 << v_n_bits);
34955       v_n_bits += 8u;
34956     }
34957     v_n_lit = (((v_bits) & 0x1Fu) + 257u);
34958     if (v_n_lit > 286u) {
34959       status = wuffs_base__make_status(wuffs_deflate__error__bad_literal_length_code_count);
34960       goto exit;
34961     }
34962     v_bits >>= 5u;
34963     v_n_dist = (((v_bits) & 0x1Fu) + 1u);
34964     if (v_n_dist > 30u) {
34965       status = wuffs_base__make_status(wuffs_deflate__error__bad_distance_code_count);
34966       goto exit;
34967     }
34968     v_bits >>= 5u;
34969     v_n_clen = (((v_bits) & 0xFu) + 4u);
34970     v_bits >>= 4u;
34971     v_n_bits -= 14u;
34972     v_i = 0u;
34973     while (v_i < v_n_clen) {
34974       while (v_n_bits < 3u) {
34975         {
34976           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
34977           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
34978             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34979             goto suspend;
34980           }
34981           uint32_t t_1 = *iop_a_src++;
34982           v_b1 = t_1;
34983         }
34984         v_bits |= (v_b1 << v_n_bits);
34985         v_n_bits += 8u;
34986       }
34987       self->private_data.f_code_lengths[WUFFS_DEFLATE__CODE_ORDER[v_i]] = ((uint8_t)((v_bits & 7u)));
34988       v_bits >>= 3u;
34989       v_n_bits -= 3u;
34990       v_i += 1u;
34991     }
34992     while (v_i < 19u) {
34993       self->private_data.f_code_lengths[WUFFS_DEFLATE__CODE_ORDER[v_i]] = 0u;
34994       v_i += 1u;
34995     }
34996     v_status = wuffs_deflate__decoder__init_huff(self,
34997         0u,
34998         0u,
34999         19u,
35000         4095u);
35001     if (wuffs_base__status__is_error(&v_status)) {
35002       status = v_status;
35003       goto exit;
35004     }
35005     v_mask = ((((uint32_t)(1u)) << self->private_impl.f_n_huffs_bits[0u]) - 1u);
35006     v_i = 0u;
35007     while (v_i < (v_n_lit + v_n_dist)) {
35008       while (true) {
35009         v_table_entry = self->private_data.f_huffs[0u][(v_bits & v_mask)];
35010         v_table_entry_n_bits = (v_table_entry & 15u);
35011         if (v_n_bits >= v_table_entry_n_bits) {
35012           v_bits >>= v_table_entry_n_bits;
35013           v_n_bits -= v_table_entry_n_bits;
35014           break;
35015         }
35016         {
35017           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
35018           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
35019             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
35020             goto suspend;
35021           }
35022           uint32_t t_2 = *iop_a_src++;
35023           v_b2 = t_2;
35024         }
35025         v_bits |= (v_b2 << v_n_bits);
35026         v_n_bits += 8u;
35027       }
35028       if ((v_table_entry >> 24u) != 128u) {
35029         status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
35030         goto exit;
35031       }
35032       v_table_entry = ((v_table_entry >> 8u) & 255u);
35033       if (v_table_entry < 16u) {
35034         self->private_data.f_code_lengths[v_i] = ((uint8_t)(v_table_entry));
35035         v_i += 1u;
35036         continue;
35037       }
35038       v_n_extra_bits = 0u;
35039       v_rep_symbol = 0u;
35040       v_rep_count = 0u;
35041       if (v_table_entry == 16u) {
35042         v_n_extra_bits = 2u;
35043         if (v_i <= 0u) {
35044           status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_length_repetition);
35045           goto exit;
35046         }
35047         v_rep_symbol = (self->private_data.f_code_lengths[(v_i - 1u)] & 15u);
35048         v_rep_count = 3u;
35049       } else if (v_table_entry == 17u) {
35050         v_n_extra_bits = 3u;
35051         v_rep_symbol = 0u;
35052         v_rep_count = 3u;
35053       } else if (v_table_entry == 18u) {
35054         v_n_extra_bits = 7u;
35055         v_rep_symbol = 0u;
35056         v_rep_count = 11u;
35057       } else {
35058         status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
35059         goto exit;
35060       }
35061       while (v_n_bits < v_n_extra_bits) {
35062         {
35063           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
35064           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
35065             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
35066             goto suspend;
35067           }
35068           uint32_t t_3 = *iop_a_src++;
35069           v_b3 = t_3;
35070         }
35071         v_bits |= (v_b3 << v_n_bits);
35072         v_n_bits += 8u;
35073       }
35074       v_rep_count += ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_n_extra_bits));
35075       v_bits >>= v_n_extra_bits;
35076       v_n_bits -= v_n_extra_bits;
35077       while (v_rep_count > 0u) {
35078         if (v_i >= (v_n_lit + v_n_dist)) {
35079           status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_length_count);
35080           goto exit;
35081         }
35082         self->private_data.f_code_lengths[v_i] = v_rep_symbol;
35083         v_i += 1u;
35084         v_rep_count -= 1u;
35085       }
35086     }
35087     if (v_i != (v_n_lit + v_n_dist)) {
35088       status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_length_count);
35089       goto exit;
35090     }
35091     if (self->private_data.f_code_lengths[256u] == 0u) {
35092       status = wuffs_base__make_status(wuffs_deflate__error__missing_end_of_block_code);
35093       goto exit;
35094     }
35095     v_status = wuffs_deflate__decoder__init_huff(self,
35096         0u,
35097         0u,
35098         v_n_lit,
35099         257u);
35100     if (wuffs_base__status__is_error(&v_status)) {
35101       status = v_status;
35102       goto exit;
35103     }
35104     v_status = wuffs_deflate__decoder__init_huff(self,
35105         1u,
35106         v_n_lit,
35107         (v_n_lit + v_n_dist),
35108         0u);
35109     if (wuffs_base__status__is_error(&v_status)) {
35110       status = v_status;
35111       goto exit;
35112     }
35113     self->private_impl.f_bits = v_bits;
35114     self->private_impl.f_n_bits = v_n_bits;
35115 
35116     goto ok;
35117     ok:
35118     self->private_impl.p_init_dynamic_huffman[0] = 0;
35119     goto exit;
35120   }
35121 
35122   goto suspend;
35123   suspend:
35124   self->private_impl.p_init_dynamic_huffman[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
35125   self->private_data.s_init_dynamic_huffman[0].v_bits = v_bits;
35126   self->private_data.s_init_dynamic_huffman[0].v_n_bits = v_n_bits;
35127   self->private_data.s_init_dynamic_huffman[0].v_n_lit = v_n_lit;
35128   self->private_data.s_init_dynamic_huffman[0].v_n_dist = v_n_dist;
35129   self->private_data.s_init_dynamic_huffman[0].v_n_clen = v_n_clen;
35130   self->private_data.s_init_dynamic_huffman[0].v_i = v_i;
35131   self->private_data.s_init_dynamic_huffman[0].v_mask = v_mask;
35132   self->private_data.s_init_dynamic_huffman[0].v_n_extra_bits = v_n_extra_bits;
35133   self->private_data.s_init_dynamic_huffman[0].v_rep_symbol = v_rep_symbol;
35134   self->private_data.s_init_dynamic_huffman[0].v_rep_count = v_rep_count;
35135 
35136   goto exit;
35137   exit:
35138   if (a_src && a_src->data.ptr) {
35139     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
35140   }
35141 
35142   return status;
35143 }
35144 
35145 // -------- func deflate.decoder.init_huff
35146 
35147 WUFFS_BASE__GENERATED_C_CODE
35148 static wuffs_base__status
wuffs_deflate__decoder__init_huff(wuffs_deflate__decoder * self,uint32_t a_which,uint32_t a_n_codes0,uint32_t a_n_codes1,uint32_t a_base_symbol)35149 wuffs_deflate__decoder__init_huff(
35150     wuffs_deflate__decoder* self,
35151     uint32_t a_which,
35152     uint32_t a_n_codes0,
35153     uint32_t a_n_codes1,
35154     uint32_t a_base_symbol) {
35155   uint16_t v_counts[16] = {0};
35156   uint32_t v_i = 0;
35157   uint32_t v_remaining = 0;
35158   uint16_t v_offsets[16] = {0};
35159   uint32_t v_n_symbols = 0;
35160   uint32_t v_count = 0;
35161   uint16_t v_symbols[320] = {0};
35162   uint32_t v_min_cl = 0;
35163   uint32_t v_max_cl = 0;
35164   uint32_t v_initial_high_bits = 0;
35165   uint32_t v_prev_cl = 0;
35166   uint32_t v_prev_redirect_key = 0;
35167   uint32_t v_top = 0;
35168   uint32_t v_next_top = 0;
35169   uint32_t v_code = 0;
35170   uint32_t v_key = 0;
35171   uint32_t v_value = 0;
35172   uint32_t v_cl = 0;
35173   uint32_t v_redirect_key = 0;
35174   uint32_t v_j = 0;
35175   uint32_t v_reversed_key = 0;
35176   uint32_t v_symbol = 0;
35177   uint32_t v_high_bits = 0;
35178   uint32_t v_delta = 0;
35179 
35180   v_i = a_n_codes0;
35181   while (v_i < a_n_codes1) {
35182     if (v_counts[(self->private_data.f_code_lengths[v_i] & 15u)] >= 320u) {
35183       return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
35184     }
35185 #if defined(__GNUC__)
35186 #pragma GCC diagnostic push
35187 #pragma GCC diagnostic ignored "-Wconversion"
35188 #endif
35189     v_counts[(self->private_data.f_code_lengths[v_i] & 15u)] += 1u;
35190 #if defined(__GNUC__)
35191 #pragma GCC diagnostic pop
35192 #endif
35193     v_i += 1u;
35194   }
35195   if ((((uint32_t)(v_counts[0u])) + a_n_codes0) == a_n_codes1) {
35196     return wuffs_base__make_status(wuffs_deflate__error__no_huffman_codes);
35197   }
35198   v_remaining = 1u;
35199   v_i = 1u;
35200   while (v_i <= 15u) {
35201     if (v_remaining > 1073741824u) {
35202       return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
35203     }
35204     v_remaining <<= 1u;
35205     if (v_remaining < ((uint32_t)(v_counts[v_i]))) {
35206       return wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_over_subscribed);
35207     }
35208     v_remaining -= ((uint32_t)(v_counts[v_i]));
35209     v_i += 1u;
35210   }
35211   if (v_remaining != 0u) {
35212     if ((a_which == 1u) && (v_counts[1u] == 1u) && ((((uint32_t)(v_counts[0u])) + a_n_codes0 + 1u) == a_n_codes1)) {
35213       v_i = 0u;
35214       while (v_i <= 29u) {
35215         if (self->private_data.f_code_lengths[(a_n_codes0 + v_i)] == 1u) {
35216           self->private_impl.f_n_huffs_bits[1u] = 1u;
35217           self->private_data.f_huffs[1u][0u] = (WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[v_i] | 1u);
35218           self->private_data.f_huffs[1u][1u] = (WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[31u] | 1u);
35219           return wuffs_base__make_status(NULL);
35220         }
35221         v_i += 1u;
35222       }
35223     }
35224     return wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_under_subscribed);
35225   }
35226   v_i = 1u;
35227   while (v_i <= 15u) {
35228     v_offsets[v_i] = ((uint16_t)(v_n_symbols));
35229     v_count = ((uint32_t)(v_counts[v_i]));
35230     if (v_n_symbols > (320u - v_count)) {
35231       return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
35232     }
35233     v_n_symbols = (v_n_symbols + v_count);
35234     v_i += 1u;
35235   }
35236   if (v_n_symbols > 288u) {
35237     return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
35238   }
35239   v_i = a_n_codes0;
35240   while (v_i < a_n_codes1) {
35241     if (v_i < a_n_codes0) {
35242       return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
35243     }
35244     if (self->private_data.f_code_lengths[v_i] != 0u) {
35245       if (v_offsets[(self->private_data.f_code_lengths[v_i] & 15u)] >= 320u) {
35246         return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
35247       }
35248       v_symbols[v_offsets[(self->private_data.f_code_lengths[v_i] & 15u)]] = ((uint16_t)((v_i - a_n_codes0)));
35249 #if defined(__GNUC__)
35250 #pragma GCC diagnostic push
35251 #pragma GCC diagnostic ignored "-Wconversion"
35252 #endif
35253       v_offsets[(self->private_data.f_code_lengths[v_i] & 15u)] += 1u;
35254 #if defined(__GNUC__)
35255 #pragma GCC diagnostic pop
35256 #endif
35257     }
35258     v_i += 1u;
35259   }
35260   v_min_cl = 1u;
35261   while (true) {
35262     if (v_counts[v_min_cl] != 0u) {
35263       break;
35264     }
35265     if (v_min_cl >= 9u) {
35266       return wuffs_base__make_status(wuffs_deflate__error__bad_huffman_minimum_code_length);
35267     }
35268     v_min_cl += 1u;
35269   }
35270   v_max_cl = 15u;
35271   while (true) {
35272     if (v_counts[v_max_cl] != 0u) {
35273       break;
35274     }
35275     if (v_max_cl <= 1u) {
35276       return wuffs_base__make_status(wuffs_deflate__error__no_huffman_codes);
35277     }
35278     v_max_cl -= 1u;
35279   }
35280   if (v_max_cl <= 9u) {
35281     self->private_impl.f_n_huffs_bits[a_which] = v_max_cl;
35282   } else {
35283     self->private_impl.f_n_huffs_bits[a_which] = 9u;
35284   }
35285   v_i = 0u;
35286   if ((v_n_symbols != ((uint32_t)(v_offsets[v_max_cl]))) || (v_n_symbols != ((uint32_t)(v_offsets[15u])))) {
35287     return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
35288   }
35289   if ((a_n_codes0 + ((uint32_t)(v_symbols[0u]))) >= 320u) {
35290     return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
35291   }
35292   v_initial_high_bits = 512u;
35293   if (v_max_cl < 9u) {
35294     v_initial_high_bits = (((uint32_t)(1u)) << v_max_cl);
35295   }
35296   v_prev_cl = ((uint32_t)((self->private_data.f_code_lengths[(a_n_codes0 + ((uint32_t)(v_symbols[0u])))] & 15u)));
35297   v_prev_redirect_key = 4294967295u;
35298   v_top = 0u;
35299   v_next_top = 512u;
35300   v_code = 0u;
35301   v_key = 0u;
35302   v_value = 0u;
35303   while (true) {
35304     if ((a_n_codes0 + ((uint32_t)(v_symbols[v_i]))) >= 320u) {
35305       return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
35306     }
35307     v_cl = ((uint32_t)((self->private_data.f_code_lengths[(a_n_codes0 + ((uint32_t)(v_symbols[v_i])))] & 15u)));
35308     if (v_cl > v_prev_cl) {
35309       v_code <<= (v_cl - v_prev_cl);
35310       if (v_code >= 32768u) {
35311         return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
35312       }
35313     }
35314     v_prev_cl = v_cl;
35315     v_key = v_code;
35316     if (v_cl > 9u) {
35317       v_cl -= 9u;
35318       v_redirect_key = ((v_key >> v_cl) & 511u);
35319       v_key = ((v_key) & WUFFS_BASE__LOW_BITS_MASK__U32(v_cl));
35320       if (v_prev_redirect_key != v_redirect_key) {
35321         v_prev_redirect_key = v_redirect_key;
35322         v_remaining = (((uint32_t)(1u)) << v_cl);
35323         v_j = v_prev_cl;
35324         while (v_j <= 15u) {
35325           if (v_remaining <= ((uint32_t)(v_counts[v_j]))) {
35326             break;
35327           }
35328           v_remaining -= ((uint32_t)(v_counts[v_j]));
35329           if (v_remaining > 1073741824u) {
35330             return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
35331           }
35332           v_remaining <<= 1u;
35333           v_j += 1u;
35334         }
35335         if ((v_j <= 9u) || (15u < v_j)) {
35336           return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
35337         }
35338         v_j -= 9u;
35339         v_initial_high_bits = (((uint32_t)(1u)) << v_j);
35340         v_top = v_next_top;
35341         if ((v_top + (((uint32_t)(1u)) << v_j)) > 1024u) {
35342           return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
35343         }
35344         v_next_top = (v_top + (((uint32_t)(1u)) << v_j));
35345         v_redirect_key = (((uint32_t)(WUFFS_DEFLATE__REVERSE8[(v_redirect_key >> 1u)])) | ((v_redirect_key & 1u) << 8u));
35346         self->private_data.f_huffs[a_which][v_redirect_key] = (268435465u | (v_top << 8u) | (v_j << 4u));
35347       }
35348     }
35349     if ((v_key >= 512u) || (v_counts[v_prev_cl] <= 0u)) {
35350       return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
35351     }
35352 #if defined(__GNUC__)
35353 #pragma GCC diagnostic push
35354 #pragma GCC diagnostic ignored "-Wconversion"
35355 #endif
35356     v_counts[v_prev_cl] -= 1u;
35357 #if defined(__GNUC__)
35358 #pragma GCC diagnostic pop
35359 #endif
35360     v_reversed_key = (((uint32_t)(WUFFS_DEFLATE__REVERSE8[(v_key >> 1u)])) | ((v_key & 1u) << 8u));
35361     v_reversed_key >>= (9u - v_cl);
35362     v_symbol = ((uint32_t)(v_symbols[v_i]));
35363     if (v_symbol == 256u) {
35364       v_value = (536870912u | v_cl);
35365     } else if ((v_symbol < 256u) && (a_which == 0u)) {
35366       v_value = (2147483648u | (v_symbol << 8u) | v_cl);
35367     } else if (v_symbol >= a_base_symbol) {
35368       v_symbol -= a_base_symbol;
35369       if (a_which == 0u) {
35370         v_value = (WUFFS_DEFLATE__LCODE_MAGIC_NUMBERS[(v_symbol & 31u)] | v_cl);
35371       } else {
35372         v_value = (WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[(v_symbol & 31u)] | v_cl);
35373       }
35374     } else {
35375       return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
35376     }
35377     v_high_bits = v_initial_high_bits;
35378     v_delta = (((uint32_t)(1u)) << v_cl);
35379     while (v_high_bits >= v_delta) {
35380       v_high_bits -= v_delta;
35381       if ((v_top + ((v_high_bits | v_reversed_key) & 511u)) >= 1024u) {
35382         return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
35383       }
35384       self->private_data.f_huffs[a_which][(v_top + ((v_high_bits | v_reversed_key) & 511u))] = v_value;
35385     }
35386     v_i += 1u;
35387     if (v_i >= v_n_symbols) {
35388       break;
35389     }
35390     v_code += 1u;
35391     if (v_code >= 32768u) {
35392       return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
35393     }
35394   }
35395   return wuffs_base__make_status(NULL);
35396 }
35397 
35398 // ‼ WUFFS MULTI-FILE SECTION +x86_bmi2
35399 // -------- func deflate.decoder.decode_huffman_bmi2
35400 
35401 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
35402 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("bmi2")
35403 WUFFS_BASE__GENERATED_C_CODE
35404 static wuffs_base__status
wuffs_deflate__decoder__decode_huffman_bmi2(wuffs_deflate__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__io_buffer * a_src)35405 wuffs_deflate__decoder__decode_huffman_bmi2(
35406     wuffs_deflate__decoder* self,
35407     wuffs_base__io_buffer* a_dst,
35408     wuffs_base__io_buffer* a_src) {
35409   wuffs_base__status status = wuffs_base__make_status(NULL);
35410 
35411   uint64_t v_bits = 0;
35412   uint32_t v_n_bits = 0;
35413   uint32_t v_table_entry = 0;
35414   uint32_t v_table_entry_n_bits = 0;
35415   uint64_t v_lmask = 0;
35416   uint64_t v_dmask = 0;
35417   uint32_t v_redir_top = 0;
35418   uint32_t v_redir_mask = 0;
35419   uint32_t v_length = 0;
35420   uint32_t v_dist_minus_1 = 0;
35421   uint32_t v_hlen = 0;
35422   uint32_t v_hdist = 0;
35423   uint32_t v_hdist_adjustment = 0;
35424 
35425   uint8_t* iop_a_dst = NULL;
35426   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35427   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35428   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35429   if (a_dst && a_dst->data.ptr) {
35430     io0_a_dst = a_dst->data.ptr;
35431     io1_a_dst = io0_a_dst + a_dst->meta.wi;
35432     iop_a_dst = io1_a_dst;
35433     io2_a_dst = io0_a_dst + a_dst->data.len;
35434     if (a_dst->meta.closed) {
35435       io2_a_dst = iop_a_dst;
35436     }
35437   }
35438   const uint8_t* iop_a_src = NULL;
35439   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35440   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35441   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35442   if (a_src && a_src->data.ptr) {
35443     io0_a_src = a_src->data.ptr;
35444     io1_a_src = io0_a_src + a_src->meta.ri;
35445     iop_a_src = io1_a_src;
35446     io2_a_src = io0_a_src + a_src->meta.wi;
35447   }
35448 
35449   if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7u)) != 0u)) {
35450     status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
35451     goto exit;
35452   }
35453   v_bits = ((uint64_t)(self->private_impl.f_bits));
35454   v_n_bits = self->private_impl.f_n_bits;
35455   v_lmask = ((((uint64_t)(1u)) << self->private_impl.f_n_huffs_bits[0u]) - 1u);
35456   v_dmask = ((((uint64_t)(1u)) << self->private_impl.f_n_huffs_bits[1u]) - 1u);
35457   if (self->private_impl.f_transformed_history_count < (a_dst ? a_dst->meta.pos : 0u)) {
35458     status = wuffs_base__make_status(wuffs_base__error__bad_i_o_position);
35459     goto exit;
35460   }
35461   v_hdist_adjustment = ((uint32_t)((self->private_impl.f_transformed_history_count - (a_dst ? a_dst->meta.pos : 0u))));
35462   label__loop__continue:;
35463   while ((((uint64_t)(io2_a_dst - iop_a_dst)) >= 266u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 8u)) {
35464     v_bits |= ((uint64_t)(wuffs_base__peek_u64le__no_bounds_check(iop_a_src) << (v_n_bits & 63u)));
35465     iop_a_src += ((63u - (v_n_bits & 63u)) >> 3u);
35466     v_n_bits |= 56u;
35467     v_table_entry = self->private_data.f_huffs[0u][(v_bits & v_lmask)];
35468     v_table_entry_n_bits = (v_table_entry & 15u);
35469     v_bits >>= v_table_entry_n_bits;
35470     v_n_bits -= v_table_entry_n_bits;
35471     if ((v_table_entry >> 31u) != 0u) {
35472       (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)((v_table_entry >> 8u)))), iop_a_dst += 1);
35473       continue;
35474     } else if ((v_table_entry >> 30u) != 0u) {
35475     } else if ((v_table_entry >> 29u) != 0u) {
35476       self->private_impl.f_end_of_block = true;
35477       break;
35478     } else if ((v_table_entry >> 28u) != 0u) {
35479       v_redir_top = ((v_table_entry >> 8u) & 65535u);
35480       v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u);
35481       v_table_entry = self->private_data.f_huffs[0u][((v_redir_top + (((uint32_t)(v_bits)) & v_redir_mask)) & 1023u)];
35482       v_table_entry_n_bits = (v_table_entry & 15u);
35483       v_bits >>= v_table_entry_n_bits;
35484       v_n_bits -= v_table_entry_n_bits;
35485       if ((v_table_entry >> 31u) != 0u) {
35486         (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)((v_table_entry >> 8u)))), iop_a_dst += 1);
35487         continue;
35488       } else if ((v_table_entry >> 30u) != 0u) {
35489       } else if ((v_table_entry >> 29u) != 0u) {
35490         self->private_impl.f_end_of_block = true;
35491         break;
35492       } else if ((v_table_entry >> 28u) != 0u) {
35493         status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
35494         goto exit;
35495       } else if ((v_table_entry >> 27u) != 0u) {
35496         status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
35497         goto exit;
35498       } else {
35499         status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
35500         goto exit;
35501       }
35502     } else if ((v_table_entry >> 27u) != 0u) {
35503       status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
35504       goto exit;
35505     } else {
35506       status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
35507       goto exit;
35508     }
35509     v_length = (((v_table_entry >> 8u) & 255u) + 3u);
35510     v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u);
35511     if (v_table_entry_n_bits > 0u) {
35512       v_length = (((v_length + 253u + ((uint32_t)(((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U64(v_table_entry_n_bits))))) & 255u) + 3u);
35513       v_bits >>= v_table_entry_n_bits;
35514       v_n_bits -= v_table_entry_n_bits;
35515     }
35516     v_table_entry = self->private_data.f_huffs[1u][(v_bits & v_dmask)];
35517     v_table_entry_n_bits = (v_table_entry & 15u);
35518     v_bits >>= v_table_entry_n_bits;
35519     v_n_bits -= v_table_entry_n_bits;
35520     if ((v_table_entry >> 28u) == 1u) {
35521       v_redir_top = ((v_table_entry >> 8u) & 65535u);
35522       v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u);
35523       v_table_entry = self->private_data.f_huffs[1u][((v_redir_top + (((uint32_t)(v_bits)) & v_redir_mask)) & 1023u)];
35524       v_table_entry_n_bits = (v_table_entry & 15u);
35525       v_bits >>= v_table_entry_n_bits;
35526       v_n_bits -= v_table_entry_n_bits;
35527     }
35528     if ((v_table_entry >> 24u) != 64u) {
35529       if ((v_table_entry >> 24u) == 8u) {
35530         status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
35531         goto exit;
35532       }
35533       status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
35534       goto exit;
35535     }
35536     v_dist_minus_1 = ((v_table_entry >> 8u) & 32767u);
35537     v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u);
35538     v_dist_minus_1 = ((v_dist_minus_1 + ((uint32_t)(((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U64(v_table_entry_n_bits))))) & 32767u);
35539     v_bits >>= v_table_entry_n_bits;
35540     v_n_bits -= v_table_entry_n_bits;
35541     do {
35542       if (((uint64_t)((v_dist_minus_1 + 1u))) > ((uint64_t)(iop_a_dst - io0_a_dst))) {
35543         v_hlen = 0u;
35544         v_hdist = ((uint32_t)((((uint64_t)((v_dist_minus_1 + 1u))) - ((uint64_t)(iop_a_dst - io0_a_dst)))));
35545         if (v_length > v_hdist) {
35546           v_length -= v_hdist;
35547           v_hlen = v_hdist;
35548         } else {
35549           v_hlen = v_length;
35550           v_length = 0u;
35551         }
35552         v_hdist += v_hdist_adjustment;
35553         if (self->private_impl.f_history_index < v_hdist) {
35554           status = wuffs_base__make_status(wuffs_deflate__error__bad_distance);
35555           goto exit;
35556         }
35557         wuffs_base__io_writer__limited_copy_u32_from_slice(
35558             &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));
35559         if (v_length == 0u) {
35560           goto label__loop__continue;
35561         }
35562         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)))) {
35563           status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_distance);
35564           goto exit;
35565         }
35566       }
35567       if ((v_dist_minus_1 + 1u) >= 8u) {
35568         wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast(
35569             &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u));
35570       } else if ((v_dist_minus_1 + 1u) == 1u) {
35571         wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast(
35572             &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u));
35573       } else {
35574         wuffs_base__io_writer__limited_copy_u32_from_history_fast(
35575             &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u));
35576       }
35577     } while (0);
35578   }
35579   if (v_n_bits > 63u) {
35580     status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
35581     goto exit;
35582   }
35583   while (v_n_bits >= 8u) {
35584     v_n_bits -= 8u;
35585     if (iop_a_src > io1_a_src) {
35586       iop_a_src--;
35587     } else {
35588       status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_i_o);
35589       goto exit;
35590     }
35591   }
35592   self->private_impl.f_bits = ((uint32_t)((v_bits & ((((uint64_t)(1u)) << v_n_bits) - 1u))));
35593   self->private_impl.f_n_bits = v_n_bits;
35594   if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> self->private_impl.f_n_bits) != 0u)) {
35595     status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
35596     goto exit;
35597   }
35598   goto exit;
35599   exit:
35600   if (a_dst && a_dst->data.ptr) {
35601     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
35602   }
35603   if (a_src && a_src->data.ptr) {
35604     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
35605   }
35606 
35607   return status;
35608 }
35609 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
35610 // ‼ WUFFS MULTI-FILE SECTION -x86_bmi2
35611 
35612 // -------- func deflate.decoder.decode_huffman_fast32
35613 
35614 WUFFS_BASE__GENERATED_C_CODE
35615 static wuffs_base__status
wuffs_deflate__decoder__decode_huffman_fast32(wuffs_deflate__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__io_buffer * a_src)35616 wuffs_deflate__decoder__decode_huffman_fast32(
35617     wuffs_deflate__decoder* self,
35618     wuffs_base__io_buffer* a_dst,
35619     wuffs_base__io_buffer* a_src) {
35620   wuffs_base__status status = wuffs_base__make_status(NULL);
35621 
35622   uint32_t v_bits = 0;
35623   uint32_t v_n_bits = 0;
35624   uint32_t v_table_entry = 0;
35625   uint32_t v_table_entry_n_bits = 0;
35626   uint32_t v_lmask = 0;
35627   uint32_t v_dmask = 0;
35628   uint32_t v_redir_top = 0;
35629   uint32_t v_redir_mask = 0;
35630   uint32_t v_length = 0;
35631   uint32_t v_dist_minus_1 = 0;
35632   uint32_t v_hlen = 0;
35633   uint32_t v_hdist = 0;
35634   uint32_t v_hdist_adjustment = 0;
35635 
35636   uint8_t* iop_a_dst = NULL;
35637   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35638   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35639   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35640   if (a_dst && a_dst->data.ptr) {
35641     io0_a_dst = a_dst->data.ptr;
35642     io1_a_dst = io0_a_dst + a_dst->meta.wi;
35643     iop_a_dst = io1_a_dst;
35644     io2_a_dst = io0_a_dst + a_dst->data.len;
35645     if (a_dst->meta.closed) {
35646       io2_a_dst = iop_a_dst;
35647     }
35648   }
35649   const uint8_t* iop_a_src = NULL;
35650   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35651   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35652   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35653   if (a_src && a_src->data.ptr) {
35654     io0_a_src = a_src->data.ptr;
35655     io1_a_src = io0_a_src + a_src->meta.ri;
35656     iop_a_src = io1_a_src;
35657     io2_a_src = io0_a_src + a_src->meta.wi;
35658   }
35659 
35660   if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7u)) != 0u)) {
35661     status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
35662     goto exit;
35663   }
35664   v_bits = self->private_impl.f_bits;
35665   v_n_bits = self->private_impl.f_n_bits;
35666   v_lmask = ((((uint32_t)(1u)) << self->private_impl.f_n_huffs_bits[0u]) - 1u);
35667   v_dmask = ((((uint32_t)(1u)) << self->private_impl.f_n_huffs_bits[1u]) - 1u);
35668   if (self->private_impl.f_transformed_history_count < (a_dst ? a_dst->meta.pos : 0u)) {
35669     status = wuffs_base__make_status(wuffs_base__error__bad_i_o_position);
35670     goto exit;
35671   }
35672   v_hdist_adjustment = ((uint32_t)((self->private_impl.f_transformed_history_count - (a_dst ? a_dst->meta.pos : 0u))));
35673   label__loop__continue:;
35674   while ((((uint64_t)(io2_a_dst - iop_a_dst)) >= 266u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 12u)) {
35675     if (v_n_bits < 15u) {
35676       v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
35677       iop_a_src += 1u;
35678       v_n_bits += 8u;
35679       v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
35680       iop_a_src += 1u;
35681       v_n_bits += 8u;
35682     } else {
35683     }
35684     v_table_entry = self->private_data.f_huffs[0u][(v_bits & v_lmask)];
35685     v_table_entry_n_bits = (v_table_entry & 15u);
35686     v_bits >>= v_table_entry_n_bits;
35687     v_n_bits -= v_table_entry_n_bits;
35688     if ((v_table_entry >> 31u) != 0u) {
35689       (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)((v_table_entry >> 8u)))), iop_a_dst += 1);
35690       continue;
35691     } else if ((v_table_entry >> 30u) != 0u) {
35692     } else if ((v_table_entry >> 29u) != 0u) {
35693       self->private_impl.f_end_of_block = true;
35694       break;
35695     } else if ((v_table_entry >> 28u) != 0u) {
35696       if (v_n_bits < 15u) {
35697         v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
35698         iop_a_src += 1u;
35699         v_n_bits += 8u;
35700         v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
35701         iop_a_src += 1u;
35702         v_n_bits += 8u;
35703       } else {
35704       }
35705       v_redir_top = ((v_table_entry >> 8u) & 65535u);
35706       v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u);
35707       v_table_entry = self->private_data.f_huffs[0u][((v_redir_top + (v_bits & v_redir_mask)) & 1023u)];
35708       v_table_entry_n_bits = (v_table_entry & 15u);
35709       v_bits >>= v_table_entry_n_bits;
35710       v_n_bits -= v_table_entry_n_bits;
35711       if ((v_table_entry >> 31u) != 0u) {
35712         (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)((v_table_entry >> 8u)))), iop_a_dst += 1);
35713         continue;
35714       } else if ((v_table_entry >> 30u) != 0u) {
35715       } else if ((v_table_entry >> 29u) != 0u) {
35716         self->private_impl.f_end_of_block = true;
35717         break;
35718       } else if ((v_table_entry >> 28u) != 0u) {
35719         status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
35720         goto exit;
35721       } else if ((v_table_entry >> 27u) != 0u) {
35722         status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
35723         goto exit;
35724       } else {
35725         status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
35726         goto exit;
35727       }
35728     } else if ((v_table_entry >> 27u) != 0u) {
35729       status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
35730       goto exit;
35731     } else {
35732       status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
35733       goto exit;
35734     }
35735     v_length = (((v_table_entry >> 8u) & 255u) + 3u);
35736     v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u);
35737     if (v_table_entry_n_bits > 0u) {
35738       if (v_n_bits < 15u) {
35739         v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
35740         iop_a_src += 1u;
35741         v_n_bits += 8u;
35742         v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
35743         iop_a_src += 1u;
35744         v_n_bits += 8u;
35745       } else {
35746       }
35747       v_length = (((v_length + 253u + ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_table_entry_n_bits))) & 255u) + 3u);
35748       v_bits >>= v_table_entry_n_bits;
35749       v_n_bits -= v_table_entry_n_bits;
35750     } else {
35751     }
35752     if (v_n_bits < 15u) {
35753       v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
35754       iop_a_src += 1u;
35755       v_n_bits += 8u;
35756       v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
35757       iop_a_src += 1u;
35758       v_n_bits += 8u;
35759     } else {
35760     }
35761     v_table_entry = self->private_data.f_huffs[1u][(v_bits & v_dmask)];
35762     v_table_entry_n_bits = (v_table_entry & 15u);
35763     v_bits >>= v_table_entry_n_bits;
35764     v_n_bits -= v_table_entry_n_bits;
35765     if ((v_table_entry >> 28u) == 1u) {
35766       if (v_n_bits < 15u) {
35767         v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
35768         iop_a_src += 1u;
35769         v_n_bits += 8u;
35770         v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
35771         iop_a_src += 1u;
35772         v_n_bits += 8u;
35773       } else {
35774       }
35775       v_redir_top = ((v_table_entry >> 8u) & 65535u);
35776       v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u);
35777       v_table_entry = self->private_data.f_huffs[1u][((v_redir_top + (v_bits & v_redir_mask)) & 1023u)];
35778       v_table_entry_n_bits = (v_table_entry & 15u);
35779       v_bits >>= v_table_entry_n_bits;
35780       v_n_bits -= v_table_entry_n_bits;
35781     } else {
35782     }
35783     if ((v_table_entry >> 24u) != 64u) {
35784       if ((v_table_entry >> 24u) == 8u) {
35785         status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
35786         goto exit;
35787       }
35788       status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
35789       goto exit;
35790     }
35791     v_dist_minus_1 = ((v_table_entry >> 8u) & 32767u);
35792     v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u);
35793     if (v_n_bits < v_table_entry_n_bits) {
35794       v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
35795       iop_a_src += 1u;
35796       v_n_bits += 8u;
35797       v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
35798       iop_a_src += 1u;
35799       v_n_bits += 8u;
35800     }
35801     v_dist_minus_1 = ((v_dist_minus_1 + ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_table_entry_n_bits))) & 32767u);
35802     v_bits >>= v_table_entry_n_bits;
35803     v_n_bits -= v_table_entry_n_bits;
35804     do {
35805       if (((uint64_t)((v_dist_minus_1 + 1u))) > ((uint64_t)(iop_a_dst - io0_a_dst))) {
35806         v_hlen = 0u;
35807         v_hdist = ((uint32_t)((((uint64_t)((v_dist_minus_1 + 1u))) - ((uint64_t)(iop_a_dst - io0_a_dst)))));
35808         if (v_length > v_hdist) {
35809           v_length -= v_hdist;
35810           v_hlen = v_hdist;
35811         } else {
35812           v_hlen = v_length;
35813           v_length = 0u;
35814         }
35815         v_hdist += v_hdist_adjustment;
35816         if (self->private_impl.f_history_index < v_hdist) {
35817           status = wuffs_base__make_status(wuffs_deflate__error__bad_distance);
35818           goto exit;
35819         }
35820         wuffs_base__io_writer__limited_copy_u32_from_slice(
35821             &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));
35822         if (v_length == 0u) {
35823           goto label__loop__continue;
35824         }
35825         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)))) {
35826           status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_distance);
35827           goto exit;
35828         }
35829       }
35830       if ((v_dist_minus_1 + 1u) >= 8u) {
35831         wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast(
35832             &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u));
35833       } else {
35834         wuffs_base__io_writer__limited_copy_u32_from_history_fast(
35835             &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u));
35836       }
35837     } while (0);
35838   }
35839   while (v_n_bits >= 8u) {
35840     v_n_bits -= 8u;
35841     if (iop_a_src > io1_a_src) {
35842       iop_a_src--;
35843     } else {
35844       status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_i_o);
35845       goto exit;
35846     }
35847   }
35848   self->private_impl.f_bits = (v_bits & ((((uint32_t)(1u)) << v_n_bits) - 1u));
35849   self->private_impl.f_n_bits = v_n_bits;
35850   if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> self->private_impl.f_n_bits) != 0u)) {
35851     status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
35852     goto exit;
35853   }
35854   goto exit;
35855   exit:
35856   if (a_dst && a_dst->data.ptr) {
35857     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
35858   }
35859   if (a_src && a_src->data.ptr) {
35860     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
35861   }
35862 
35863   return status;
35864 }
35865 
35866 // -------- func deflate.decoder.decode_huffman_fast64
35867 
35868 WUFFS_BASE__GENERATED_C_CODE
35869 static wuffs_base__status
wuffs_deflate__decoder__decode_huffman_fast64(wuffs_deflate__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__io_buffer * a_src)35870 wuffs_deflate__decoder__decode_huffman_fast64(
35871     wuffs_deflate__decoder* self,
35872     wuffs_base__io_buffer* a_dst,
35873     wuffs_base__io_buffer* a_src) {
35874   return (*self->private_impl.choosy_decode_huffman_fast64)(self, a_dst, a_src);
35875 }
35876 
35877 WUFFS_BASE__GENERATED_C_CODE
35878 static wuffs_base__status
wuffs_deflate__decoder__decode_huffman_fast64__choosy_default(wuffs_deflate__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__io_buffer * a_src)35879 wuffs_deflate__decoder__decode_huffman_fast64__choosy_default(
35880     wuffs_deflate__decoder* self,
35881     wuffs_base__io_buffer* a_dst,
35882     wuffs_base__io_buffer* a_src) {
35883   wuffs_base__status status = wuffs_base__make_status(NULL);
35884 
35885   uint64_t v_bits = 0;
35886   uint32_t v_n_bits = 0;
35887   uint32_t v_table_entry = 0;
35888   uint32_t v_table_entry_n_bits = 0;
35889   uint64_t v_lmask = 0;
35890   uint64_t v_dmask = 0;
35891   uint32_t v_redir_top = 0;
35892   uint32_t v_redir_mask = 0;
35893   uint32_t v_length = 0;
35894   uint32_t v_dist_minus_1 = 0;
35895   uint32_t v_hlen = 0;
35896   uint32_t v_hdist = 0;
35897   uint32_t v_hdist_adjustment = 0;
35898 
35899   uint8_t* iop_a_dst = NULL;
35900   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35901   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35902   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35903   if (a_dst && a_dst->data.ptr) {
35904     io0_a_dst = a_dst->data.ptr;
35905     io1_a_dst = io0_a_dst + a_dst->meta.wi;
35906     iop_a_dst = io1_a_dst;
35907     io2_a_dst = io0_a_dst + a_dst->data.len;
35908     if (a_dst->meta.closed) {
35909       io2_a_dst = iop_a_dst;
35910     }
35911   }
35912   const uint8_t* iop_a_src = NULL;
35913   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35914   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35915   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35916   if (a_src && a_src->data.ptr) {
35917     io0_a_src = a_src->data.ptr;
35918     io1_a_src = io0_a_src + a_src->meta.ri;
35919     iop_a_src = io1_a_src;
35920     io2_a_src = io0_a_src + a_src->meta.wi;
35921   }
35922 
35923   if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7u)) != 0u)) {
35924     status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
35925     goto exit;
35926   }
35927   v_bits = ((uint64_t)(self->private_impl.f_bits));
35928   v_n_bits = self->private_impl.f_n_bits;
35929   v_lmask = ((((uint64_t)(1u)) << self->private_impl.f_n_huffs_bits[0u]) - 1u);
35930   v_dmask = ((((uint64_t)(1u)) << self->private_impl.f_n_huffs_bits[1u]) - 1u);
35931   if (self->private_impl.f_transformed_history_count < (a_dst ? a_dst->meta.pos : 0u)) {
35932     status = wuffs_base__make_status(wuffs_base__error__bad_i_o_position);
35933     goto exit;
35934   }
35935   v_hdist_adjustment = ((uint32_t)((self->private_impl.f_transformed_history_count - (a_dst ? a_dst->meta.pos : 0u))));
35936   label__loop__continue:;
35937   while ((((uint64_t)(io2_a_dst - iop_a_dst)) >= 266u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 8u)) {
35938     v_bits |= ((uint64_t)(wuffs_base__peek_u64le__no_bounds_check(iop_a_src) << (v_n_bits & 63u)));
35939     iop_a_src += ((63u - (v_n_bits & 63u)) >> 3u);
35940     v_n_bits |= 56u;
35941     v_table_entry = self->private_data.f_huffs[0u][(v_bits & v_lmask)];
35942     v_table_entry_n_bits = (v_table_entry & 15u);
35943     v_bits >>= v_table_entry_n_bits;
35944     v_n_bits -= v_table_entry_n_bits;
35945     if ((v_table_entry >> 31u) != 0u) {
35946       (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)((v_table_entry >> 8u)))), iop_a_dst += 1);
35947       continue;
35948     } else if ((v_table_entry >> 30u) != 0u) {
35949     } else if ((v_table_entry >> 29u) != 0u) {
35950       self->private_impl.f_end_of_block = true;
35951       break;
35952     } else if ((v_table_entry >> 28u) != 0u) {
35953       v_redir_top = ((v_table_entry >> 8u) & 65535u);
35954       v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u);
35955       v_table_entry = self->private_data.f_huffs[0u][((v_redir_top + (((uint32_t)(v_bits)) & v_redir_mask)) & 1023u)];
35956       v_table_entry_n_bits = (v_table_entry & 15u);
35957       v_bits >>= v_table_entry_n_bits;
35958       v_n_bits -= v_table_entry_n_bits;
35959       if ((v_table_entry >> 31u) != 0u) {
35960         (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)((v_table_entry >> 8u)))), iop_a_dst += 1);
35961         continue;
35962       } else if ((v_table_entry >> 30u) != 0u) {
35963       } else if ((v_table_entry >> 29u) != 0u) {
35964         self->private_impl.f_end_of_block = true;
35965         break;
35966       } else if ((v_table_entry >> 28u) != 0u) {
35967         status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
35968         goto exit;
35969       } else if ((v_table_entry >> 27u) != 0u) {
35970         status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
35971         goto exit;
35972       } else {
35973         status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
35974         goto exit;
35975       }
35976     } else if ((v_table_entry >> 27u) != 0u) {
35977       status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
35978       goto exit;
35979     } else {
35980       status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
35981       goto exit;
35982     }
35983     v_length = (((v_table_entry >> 8u) & 255u) + 3u);
35984     v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u);
35985     if (v_table_entry_n_bits > 0u) {
35986       v_length = (((v_length + 253u + ((uint32_t)(((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U64(v_table_entry_n_bits))))) & 255u) + 3u);
35987       v_bits >>= v_table_entry_n_bits;
35988       v_n_bits -= v_table_entry_n_bits;
35989     }
35990     v_table_entry = self->private_data.f_huffs[1u][(v_bits & v_dmask)];
35991     v_table_entry_n_bits = (v_table_entry & 15u);
35992     v_bits >>= v_table_entry_n_bits;
35993     v_n_bits -= v_table_entry_n_bits;
35994     if ((v_table_entry >> 28u) == 1u) {
35995       v_redir_top = ((v_table_entry >> 8u) & 65535u);
35996       v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u);
35997       v_table_entry = self->private_data.f_huffs[1u][((v_redir_top + (((uint32_t)(v_bits)) & v_redir_mask)) & 1023u)];
35998       v_table_entry_n_bits = (v_table_entry & 15u);
35999       v_bits >>= v_table_entry_n_bits;
36000       v_n_bits -= v_table_entry_n_bits;
36001     }
36002     if ((v_table_entry >> 24u) != 64u) {
36003       if ((v_table_entry >> 24u) == 8u) {
36004         status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
36005         goto exit;
36006       }
36007       status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
36008       goto exit;
36009     }
36010     v_dist_minus_1 = ((v_table_entry >> 8u) & 32767u);
36011     v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u);
36012     v_dist_minus_1 = ((v_dist_minus_1 + ((uint32_t)(((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U64(v_table_entry_n_bits))))) & 32767u);
36013     v_bits >>= v_table_entry_n_bits;
36014     v_n_bits -= v_table_entry_n_bits;
36015     do {
36016       if (((uint64_t)((v_dist_minus_1 + 1u))) > ((uint64_t)(iop_a_dst - io0_a_dst))) {
36017         v_hlen = 0u;
36018         v_hdist = ((uint32_t)((((uint64_t)((v_dist_minus_1 + 1u))) - ((uint64_t)(iop_a_dst - io0_a_dst)))));
36019         if (v_length > v_hdist) {
36020           v_length -= v_hdist;
36021           v_hlen = v_hdist;
36022         } else {
36023           v_hlen = v_length;
36024           v_length = 0u;
36025         }
36026         v_hdist += v_hdist_adjustment;
36027         if (self->private_impl.f_history_index < v_hdist) {
36028           status = wuffs_base__make_status(wuffs_deflate__error__bad_distance);
36029           goto exit;
36030         }
36031         wuffs_base__io_writer__limited_copy_u32_from_slice(
36032             &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));
36033         if (v_length == 0u) {
36034           goto label__loop__continue;
36035         }
36036         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)))) {
36037           status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_distance);
36038           goto exit;
36039         }
36040       }
36041       if ((v_dist_minus_1 + 1u) >= 8u) {
36042         wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast(
36043             &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u));
36044       } else if ((v_dist_minus_1 + 1u) == 1u) {
36045         wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast(
36046             &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u));
36047       } else {
36048         wuffs_base__io_writer__limited_copy_u32_from_history_fast(
36049             &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u));
36050       }
36051     } while (0);
36052   }
36053   if (v_n_bits > 63u) {
36054     status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
36055     goto exit;
36056   }
36057   while (v_n_bits >= 8u) {
36058     v_n_bits -= 8u;
36059     if (iop_a_src > io1_a_src) {
36060       iop_a_src--;
36061     } else {
36062       status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_i_o);
36063       goto exit;
36064     }
36065   }
36066   self->private_impl.f_bits = ((uint32_t)((v_bits & ((((uint64_t)(1u)) << v_n_bits) - 1u))));
36067   self->private_impl.f_n_bits = v_n_bits;
36068   if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> self->private_impl.f_n_bits) != 0u)) {
36069     status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
36070     goto exit;
36071   }
36072   goto exit;
36073   exit:
36074   if (a_dst && a_dst->data.ptr) {
36075     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
36076   }
36077   if (a_src && a_src->data.ptr) {
36078     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
36079   }
36080 
36081   return status;
36082 }
36083 
36084 // -------- func deflate.decoder.decode_huffman_slow
36085 
36086 WUFFS_BASE__GENERATED_C_CODE
36087 static wuffs_base__status
wuffs_deflate__decoder__decode_huffman_slow(wuffs_deflate__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__io_buffer * a_src)36088 wuffs_deflate__decoder__decode_huffman_slow(
36089     wuffs_deflate__decoder* self,
36090     wuffs_base__io_buffer* a_dst,
36091     wuffs_base__io_buffer* a_src) {
36092   wuffs_base__status status = wuffs_base__make_status(NULL);
36093 
36094   uint32_t v_bits = 0;
36095   uint32_t v_n_bits = 0;
36096   uint32_t v_table_entry = 0;
36097   uint32_t v_table_entry_n_bits = 0;
36098   uint32_t v_lmask = 0;
36099   uint32_t v_dmask = 0;
36100   uint32_t v_b0 = 0;
36101   uint32_t v_redir_top = 0;
36102   uint32_t v_redir_mask = 0;
36103   uint32_t v_b1 = 0;
36104   uint32_t v_length = 0;
36105   uint32_t v_b2 = 0;
36106   uint32_t v_b3 = 0;
36107   uint32_t v_b4 = 0;
36108   uint32_t v_dist_minus_1 = 0;
36109   uint32_t v_b5 = 0;
36110   uint32_t v_n_copied = 0;
36111   uint32_t v_hlen = 0;
36112   uint32_t v_hdist = 0;
36113 
36114   uint8_t* iop_a_dst = NULL;
36115   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
36116   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
36117   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
36118   if (a_dst && a_dst->data.ptr) {
36119     io0_a_dst = a_dst->data.ptr;
36120     io1_a_dst = io0_a_dst + a_dst->meta.wi;
36121     iop_a_dst = io1_a_dst;
36122     io2_a_dst = io0_a_dst + a_dst->data.len;
36123     if (a_dst->meta.closed) {
36124       io2_a_dst = iop_a_dst;
36125     }
36126   }
36127   const uint8_t* iop_a_src = NULL;
36128   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
36129   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
36130   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
36131   if (a_src && a_src->data.ptr) {
36132     io0_a_src = a_src->data.ptr;
36133     io1_a_src = io0_a_src + a_src->meta.ri;
36134     iop_a_src = io1_a_src;
36135     io2_a_src = io0_a_src + a_src->meta.wi;
36136   }
36137 
36138   uint32_t coro_susp_point = self->private_impl.p_decode_huffman_slow[0];
36139   if (coro_susp_point) {
36140     v_bits = self->private_data.s_decode_huffman_slow[0].v_bits;
36141     v_n_bits = self->private_data.s_decode_huffman_slow[0].v_n_bits;
36142     v_table_entry_n_bits = self->private_data.s_decode_huffman_slow[0].v_table_entry_n_bits;
36143     v_lmask = self->private_data.s_decode_huffman_slow[0].v_lmask;
36144     v_dmask = self->private_data.s_decode_huffman_slow[0].v_dmask;
36145     v_redir_top = self->private_data.s_decode_huffman_slow[0].v_redir_top;
36146     v_redir_mask = self->private_data.s_decode_huffman_slow[0].v_redir_mask;
36147     v_length = self->private_data.s_decode_huffman_slow[0].v_length;
36148     v_dist_minus_1 = self->private_data.s_decode_huffman_slow[0].v_dist_minus_1;
36149   }
36150   switch (coro_susp_point) {
36151     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
36152 
36153     if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7u)) != 0u)) {
36154       status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
36155       goto exit;
36156     }
36157     v_bits = self->private_impl.f_bits;
36158     v_n_bits = self->private_impl.f_n_bits;
36159     v_lmask = ((((uint32_t)(1u)) << self->private_impl.f_n_huffs_bits[0u]) - 1u);
36160     v_dmask = ((((uint32_t)(1u)) << self->private_impl.f_n_huffs_bits[1u]) - 1u);
36161     label__loop__continue:;
36162     while ( ! (self->private_impl.p_decode_huffman_slow[0] != 0)) {
36163       while (true) {
36164         v_table_entry = self->private_data.f_huffs[0u][(v_bits & v_lmask)];
36165         v_table_entry_n_bits = (v_table_entry & 15u);
36166         if (v_n_bits >= v_table_entry_n_bits) {
36167           v_bits >>= v_table_entry_n_bits;
36168           v_n_bits -= v_table_entry_n_bits;
36169           break;
36170         }
36171         {
36172           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
36173           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
36174             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
36175             goto suspend;
36176           }
36177           uint32_t t_0 = *iop_a_src++;
36178           v_b0 = t_0;
36179         }
36180         v_bits |= (v_b0 << v_n_bits);
36181         v_n_bits += 8u;
36182       }
36183       if ((v_table_entry >> 31u) != 0u) {
36184         self->private_data.s_decode_huffman_slow[0].scratch = ((uint8_t)((v_table_entry >> 8u)));
36185         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
36186         if (iop_a_dst == io2_a_dst) {
36187           status = wuffs_base__make_status(wuffs_base__suspension__short_write);
36188           goto suspend;
36189         }
36190         *iop_a_dst++ = ((uint8_t)(self->private_data.s_decode_huffman_slow[0].scratch));
36191         continue;
36192       } else if ((v_table_entry >> 30u) != 0u) {
36193       } else if ((v_table_entry >> 29u) != 0u) {
36194         self->private_impl.f_end_of_block = true;
36195         break;
36196       } else if ((v_table_entry >> 28u) != 0u) {
36197         v_redir_top = ((v_table_entry >> 8u) & 65535u);
36198         v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u);
36199         while (true) {
36200           v_table_entry = self->private_data.f_huffs[0u][((v_redir_top + (v_bits & v_redir_mask)) & 1023u)];
36201           v_table_entry_n_bits = (v_table_entry & 15u);
36202           if (v_n_bits >= v_table_entry_n_bits) {
36203             v_bits >>= v_table_entry_n_bits;
36204             v_n_bits -= v_table_entry_n_bits;
36205             break;
36206           }
36207           {
36208             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
36209             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
36210               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
36211               goto suspend;
36212             }
36213             uint32_t t_1 = *iop_a_src++;
36214             v_b1 = t_1;
36215           }
36216           v_bits |= (v_b1 << v_n_bits);
36217           v_n_bits += 8u;
36218         }
36219         if ((v_table_entry >> 31u) != 0u) {
36220           self->private_data.s_decode_huffman_slow[0].scratch = ((uint8_t)((v_table_entry >> 8u)));
36221           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
36222           if (iop_a_dst == io2_a_dst) {
36223             status = wuffs_base__make_status(wuffs_base__suspension__short_write);
36224             goto suspend;
36225           }
36226           *iop_a_dst++ = ((uint8_t)(self->private_data.s_decode_huffman_slow[0].scratch));
36227           continue;
36228         } else if ((v_table_entry >> 30u) != 0u) {
36229         } else if ((v_table_entry >> 29u) != 0u) {
36230           self->private_impl.f_end_of_block = true;
36231           break;
36232         } else if ((v_table_entry >> 28u) != 0u) {
36233           status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
36234           goto exit;
36235         } else if ((v_table_entry >> 27u) != 0u) {
36236           status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
36237           goto exit;
36238         } else {
36239           status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
36240           goto exit;
36241         }
36242       } else if ((v_table_entry >> 27u) != 0u) {
36243         status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
36244         goto exit;
36245       } else {
36246         status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
36247         goto exit;
36248       }
36249       v_length = (((v_table_entry >> 8u) & 255u) + 3u);
36250       v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u);
36251       if (v_table_entry_n_bits > 0u) {
36252         while (v_n_bits < v_table_entry_n_bits) {
36253           {
36254             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
36255             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
36256               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
36257               goto suspend;
36258             }
36259             uint32_t t_2 = *iop_a_src++;
36260             v_b2 = t_2;
36261           }
36262           v_bits |= (v_b2 << v_n_bits);
36263           v_n_bits += 8u;
36264         }
36265         v_length = (((v_length + 253u + ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_table_entry_n_bits))) & 255u) + 3u);
36266         v_bits >>= v_table_entry_n_bits;
36267         v_n_bits -= v_table_entry_n_bits;
36268       }
36269       while (true) {
36270         v_table_entry = self->private_data.f_huffs[1u][(v_bits & v_dmask)];
36271         v_table_entry_n_bits = (v_table_entry & 15u);
36272         if (v_n_bits >= v_table_entry_n_bits) {
36273           v_bits >>= v_table_entry_n_bits;
36274           v_n_bits -= v_table_entry_n_bits;
36275           break;
36276         }
36277         {
36278           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
36279           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
36280             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
36281             goto suspend;
36282           }
36283           uint32_t t_3 = *iop_a_src++;
36284           v_b3 = t_3;
36285         }
36286         v_bits |= (v_b3 << v_n_bits);
36287         v_n_bits += 8u;
36288       }
36289       if ((v_table_entry >> 28u) == 1u) {
36290         v_redir_top = ((v_table_entry >> 8u) & 65535u);
36291         v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u);
36292         while (true) {
36293           v_table_entry = self->private_data.f_huffs[1u][((v_redir_top + (v_bits & v_redir_mask)) & 1023u)];
36294           v_table_entry_n_bits = (v_table_entry & 15u);
36295           if (v_n_bits >= v_table_entry_n_bits) {
36296             v_bits >>= v_table_entry_n_bits;
36297             v_n_bits -= v_table_entry_n_bits;
36298             break;
36299           }
36300           {
36301             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
36302             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
36303               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
36304               goto suspend;
36305             }
36306             uint32_t t_4 = *iop_a_src++;
36307             v_b4 = t_4;
36308           }
36309           v_bits |= (v_b4 << v_n_bits);
36310           v_n_bits += 8u;
36311         }
36312       }
36313       if ((v_table_entry >> 24u) != 64u) {
36314         if ((v_table_entry >> 24u) == 8u) {
36315           status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
36316           goto exit;
36317         }
36318         status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
36319         goto exit;
36320       }
36321       v_dist_minus_1 = ((v_table_entry >> 8u) & 32767u);
36322       v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u);
36323       if (v_table_entry_n_bits > 0u) {
36324         while (v_n_bits < v_table_entry_n_bits) {
36325           {
36326             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
36327             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
36328               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
36329               goto suspend;
36330             }
36331             uint32_t t_5 = *iop_a_src++;
36332             v_b5 = t_5;
36333           }
36334           v_bits |= (v_b5 << v_n_bits);
36335           v_n_bits += 8u;
36336         }
36337         v_dist_minus_1 = ((v_dist_minus_1 + ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_table_entry_n_bits))) & 32767u);
36338         v_bits >>= v_table_entry_n_bits;
36339         v_n_bits -= v_table_entry_n_bits;
36340       }
36341       while (true) {
36342         if (((uint64_t)((v_dist_minus_1 + 1u))) > ((uint64_t)(iop_a_dst - io0_a_dst))) {
36343           v_hdist = ((uint32_t)((((uint64_t)((v_dist_minus_1 + 1u))) - ((uint64_t)(iop_a_dst - io0_a_dst)))));
36344           if (v_hdist < v_length) {
36345             v_hlen = v_hdist;
36346           } else {
36347             v_hlen = v_length;
36348           }
36349           v_hdist += ((uint32_t)(((uint64_t)(self->private_impl.f_transformed_history_count - (a_dst ? a_dst->meta.pos : 0u)))));
36350           if (self->private_impl.f_history_index < v_hdist) {
36351             status = wuffs_base__make_status(wuffs_deflate__error__bad_distance);
36352             goto exit;
36353           }
36354           v_n_copied = wuffs_base__io_writer__limited_copy_u32_from_slice(
36355               &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));
36356           if (v_n_copied < v_hlen) {
36357             v_length -= v_n_copied;
36358             status = wuffs_base__make_status(wuffs_base__suspension__short_write);
36359             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9);
36360             continue;
36361           }
36362           v_length -= v_hlen;
36363           if (v_length == 0u) {
36364             goto label__loop__continue;
36365           }
36366         }
36367         v_n_copied = wuffs_base__io_writer__limited_copy_u32_from_history(
36368             &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u));
36369         if (v_length <= v_n_copied) {
36370           goto label__loop__continue;
36371         }
36372         v_length -= v_n_copied;
36373         status = wuffs_base__make_status(wuffs_base__suspension__short_write);
36374         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10);
36375       }
36376     }
36377     self->private_impl.f_bits = v_bits;
36378     self->private_impl.f_n_bits = v_n_bits;
36379     if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7u)) != 0u)) {
36380       status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
36381       goto exit;
36382     }
36383 
36384     ok:
36385     self->private_impl.p_decode_huffman_slow[0] = 0;
36386     goto exit;
36387   }
36388 
36389   goto suspend;
36390   suspend:
36391   self->private_impl.p_decode_huffman_slow[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
36392   self->private_data.s_decode_huffman_slow[0].v_bits = v_bits;
36393   self->private_data.s_decode_huffman_slow[0].v_n_bits = v_n_bits;
36394   self->private_data.s_decode_huffman_slow[0].v_table_entry_n_bits = v_table_entry_n_bits;
36395   self->private_data.s_decode_huffman_slow[0].v_lmask = v_lmask;
36396   self->private_data.s_decode_huffman_slow[0].v_dmask = v_dmask;
36397   self->private_data.s_decode_huffman_slow[0].v_redir_top = v_redir_top;
36398   self->private_data.s_decode_huffman_slow[0].v_redir_mask = v_redir_mask;
36399   self->private_data.s_decode_huffman_slow[0].v_length = v_length;
36400   self->private_data.s_decode_huffman_slow[0].v_dist_minus_1 = v_dist_minus_1;
36401 
36402   goto exit;
36403   exit:
36404   if (a_dst && a_dst->data.ptr) {
36405     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
36406   }
36407   if (a_src && a_src->data.ptr) {
36408     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
36409   }
36410 
36411   return status;
36412 }
36413 
36414 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__DEFLATE)
36415 
36416 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GIF)
36417 
36418 // ---------------- Status Codes Implementations
36419 
36420 const char wuffs_gif__error__bad_lzw_code[] = "#gif: bad LZW code";
36421 const char wuffs_gif__error__bad_extension_label[] = "#gif: bad extension label";
36422 const char wuffs_gif__error__bad_frame_size[] = "#gif: bad frame size";
36423 const char wuffs_gif__error__bad_graphic_control[] = "#gif: bad graphic control";
36424 const char wuffs_gif__error__bad_header[] = "#gif: bad header";
36425 const char wuffs_gif__error__bad_literal_width[] = "#gif: bad literal width";
36426 const char wuffs_gif__error__bad_palette[] = "#gif: bad palette";
36427 const char wuffs_gif__error__truncated_input[] = "#gif: truncated input";
36428 const char wuffs_gif__error__internal_error_inconsistent_i_o[] = "#gif: internal error: inconsistent I/O";
36429 
36430 // ---------------- Private Consts
36431 
36432 static const uint32_t
36433 WUFFS_GIF__INTERLACE_START[5] WUFFS_BASE__POTENTIALLY_UNUSED = {
36434   4294967295, 1, 2, 4, 0,
36435 };
36436 
36437 static const uint8_t
36438 WUFFS_GIF__INTERLACE_DELTA[5] WUFFS_BASE__POTENTIALLY_UNUSED = {
36439   1, 2, 4, 8, 8,
36440 };
36441 
36442 static const uint8_t
36443 WUFFS_GIF__INTERLACE_COUNT[5] WUFFS_BASE__POTENTIALLY_UNUSED = {
36444   0, 1, 2, 4, 8,
36445 };
36446 
36447 static const uint8_t
36448 WUFFS_GIF__ANIMEXTS1DOT0[11] WUFFS_BASE__POTENTIALLY_UNUSED = {
36449   65, 78, 73, 77, 69, 88, 84, 83,
36450   49, 46, 48,
36451 };
36452 
36453 static const uint8_t
36454 WUFFS_GIF__NETSCAPE2DOT0[11] WUFFS_BASE__POTENTIALLY_UNUSED = {
36455   78, 69, 84, 83, 67, 65, 80, 69,
36456   50, 46, 48,
36457 };
36458 
36459 static const uint8_t
36460 WUFFS_GIF__ICCRGBG1012[11] WUFFS_BASE__POTENTIALLY_UNUSED = {
36461   73, 67, 67, 82, 71, 66, 71, 49,
36462   48, 49, 50,
36463 };
36464 
36465 static const uint8_t
36466 WUFFS_GIF__XMPDATAXMP[11] WUFFS_BASE__POTENTIALLY_UNUSED = {
36467   88, 77, 80, 32, 68, 97, 116, 97,
36468   88, 77, 80,
36469 };
36470 
36471 #define WUFFS_GIF__QUIRKS_BASE 1041635328
36472 
36473 #define WUFFS_GIF__QUIRKS_COUNT 7
36474 
36475 // ---------------- Private Initializer Prototypes
36476 
36477 // ---------------- Private Function Prototypes
36478 
36479 WUFFS_BASE__GENERATED_C_CODE
36480 static wuffs_base__status
36481 wuffs_gif__decoder__do_decode_image_config(
36482     wuffs_gif__decoder* self,
36483     wuffs_base__image_config* a_dst,
36484     wuffs_base__io_buffer* a_src);
36485 
36486 WUFFS_BASE__GENERATED_C_CODE
36487 static wuffs_base__status
36488 wuffs_gif__decoder__do_tell_me_more(
36489     wuffs_gif__decoder* self,
36490     wuffs_base__io_buffer* a_dst,
36491     wuffs_base__more_information* a_minfo,
36492     wuffs_base__io_buffer* a_src);
36493 
36494 WUFFS_BASE__GENERATED_C_CODE
36495 static wuffs_base__status
36496 wuffs_gif__decoder__do_decode_frame_config(
36497     wuffs_gif__decoder* self,
36498     wuffs_base__frame_config* a_dst,
36499     wuffs_base__io_buffer* a_src);
36500 
36501 WUFFS_BASE__GENERATED_C_CODE
36502 static wuffs_base__status
36503 wuffs_gif__decoder__skip_frame(
36504     wuffs_gif__decoder* self,
36505     wuffs_base__io_buffer* a_src);
36506 
36507 WUFFS_BASE__GENERATED_C_CODE
36508 static wuffs_base__status
36509 wuffs_gif__decoder__do_decode_frame(
36510     wuffs_gif__decoder* self,
36511     wuffs_base__pixel_buffer* a_dst,
36512     wuffs_base__io_buffer* a_src,
36513     wuffs_base__pixel_blend a_blend,
36514     wuffs_base__slice_u8 a_workbuf,
36515     wuffs_base__decode_frame_options* a_opts);
36516 
36517 WUFFS_BASE__GENERATED_C_CODE
36518 static wuffs_base__empty_struct
36519 wuffs_gif__decoder__reset_gc(
36520     wuffs_gif__decoder* self);
36521 
36522 WUFFS_BASE__GENERATED_C_CODE
36523 static wuffs_base__status
36524 wuffs_gif__decoder__decode_up_to_id_part1(
36525     wuffs_gif__decoder* self,
36526     wuffs_base__io_buffer* a_src);
36527 
36528 WUFFS_BASE__GENERATED_C_CODE
36529 static wuffs_base__status
36530 wuffs_gif__decoder__decode_header(
36531     wuffs_gif__decoder* self,
36532     wuffs_base__io_buffer* a_src);
36533 
36534 WUFFS_BASE__GENERATED_C_CODE
36535 static wuffs_base__status
36536 wuffs_gif__decoder__decode_lsd(
36537     wuffs_gif__decoder* self,
36538     wuffs_base__io_buffer* a_src);
36539 
36540 WUFFS_BASE__GENERATED_C_CODE
36541 static wuffs_base__status
36542 wuffs_gif__decoder__decode_extension(
36543     wuffs_gif__decoder* self,
36544     wuffs_base__io_buffer* a_src);
36545 
36546 WUFFS_BASE__GENERATED_C_CODE
36547 static wuffs_base__status
36548 wuffs_gif__decoder__skip_blocks(
36549     wuffs_gif__decoder* self,
36550     wuffs_base__io_buffer* a_src);
36551 
36552 WUFFS_BASE__GENERATED_C_CODE
36553 static wuffs_base__status
36554 wuffs_gif__decoder__decode_ae(
36555     wuffs_gif__decoder* self,
36556     wuffs_base__io_buffer* a_src);
36557 
36558 WUFFS_BASE__GENERATED_C_CODE
36559 static wuffs_base__status
36560 wuffs_gif__decoder__decode_gc(
36561     wuffs_gif__decoder* self,
36562     wuffs_base__io_buffer* a_src);
36563 
36564 WUFFS_BASE__GENERATED_C_CODE
36565 static wuffs_base__status
36566 wuffs_gif__decoder__decode_id_part0(
36567     wuffs_gif__decoder* self,
36568     wuffs_base__io_buffer* a_src);
36569 
36570 WUFFS_BASE__GENERATED_C_CODE
36571 static wuffs_base__status
36572 wuffs_gif__decoder__decode_id_part1(
36573     wuffs_gif__decoder* self,
36574     wuffs_base__pixel_buffer* a_dst,
36575     wuffs_base__io_buffer* a_src,
36576     wuffs_base__pixel_blend a_blend);
36577 
36578 WUFFS_BASE__GENERATED_C_CODE
36579 static wuffs_base__status
36580 wuffs_gif__decoder__decode_id_part2(
36581     wuffs_gif__decoder* self,
36582     wuffs_base__pixel_buffer* a_dst,
36583     wuffs_base__io_buffer* a_src,
36584     wuffs_base__slice_u8 a_workbuf);
36585 
36586 WUFFS_BASE__GENERATED_C_CODE
36587 static wuffs_base__status
36588 wuffs_gif__decoder__copy_to_image_buffer(
36589     wuffs_gif__decoder* self,
36590     wuffs_base__pixel_buffer* a_pb,
36591     wuffs_base__slice_u8 a_src);
36592 
36593 WUFFS_BASE__GENERATED_C_CODE
36594 static wuffs_base__empty_struct
36595 wuffs_gif__decoder__lzw_init(
36596     wuffs_gif__decoder* self);
36597 
36598 WUFFS_BASE__GENERATED_C_CODE
36599 static wuffs_base__empty_struct
36600 wuffs_gif__decoder__lzw_read_from(
36601     wuffs_gif__decoder* self,
36602     wuffs_base__io_buffer* a_src);
36603 
36604 // ---------------- VTables
36605 
36606 const wuffs_base__image_decoder__func_ptrs
36607 wuffs_gif__decoder__func_ptrs_for__wuffs_base__image_decoder = {
36608   (wuffs_base__status(*)(void*,
36609       wuffs_base__pixel_buffer*,
36610       wuffs_base__io_buffer*,
36611       wuffs_base__pixel_blend,
36612       wuffs_base__slice_u8,
36613       wuffs_base__decode_frame_options*))(&wuffs_gif__decoder__decode_frame),
36614   (wuffs_base__status(*)(void*,
36615       wuffs_base__frame_config*,
36616       wuffs_base__io_buffer*))(&wuffs_gif__decoder__decode_frame_config),
36617   (wuffs_base__status(*)(void*,
36618       wuffs_base__image_config*,
36619       wuffs_base__io_buffer*))(&wuffs_gif__decoder__decode_image_config),
36620   (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_gif__decoder__frame_dirty_rect),
36621   (uint64_t(*)(const void*,
36622       uint32_t))(&wuffs_gif__decoder__get_quirk),
36623   (uint64_t(*)(const void*))(&wuffs_gif__decoder__history_retain_length),
36624   (uint32_t(*)(const void*))(&wuffs_gif__decoder__num_animation_loops),
36625   (uint64_t(*)(const void*))(&wuffs_gif__decoder__num_decoded_frame_configs),
36626   (uint64_t(*)(const void*))(&wuffs_gif__decoder__num_decoded_frames),
36627   (wuffs_base__status(*)(void*,
36628       uint64_t,
36629       uint64_t))(&wuffs_gif__decoder__restart_frame),
36630   (wuffs_base__status(*)(void*,
36631       uint32_t,
36632       uint64_t))(&wuffs_gif__decoder__set_quirk),
36633   (wuffs_base__empty_struct(*)(void*,
36634       uint32_t,
36635       bool))(&wuffs_gif__decoder__set_report_metadata),
36636   (wuffs_base__status(*)(void*,
36637       wuffs_base__io_buffer*,
36638       wuffs_base__more_information*,
36639       wuffs_base__io_buffer*))(&wuffs_gif__decoder__tell_me_more),
36640   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_gif__decoder__workbuf_len),
36641 };
36642 
36643 // ---------------- Initializer Implementations
36644 
36645 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
wuffs_gif__decoder__initialize(wuffs_gif__decoder * self,size_t sizeof_star_self,uint64_t wuffs_version,uint32_t options)36646 wuffs_gif__decoder__initialize(
36647     wuffs_gif__decoder* self,
36648     size_t sizeof_star_self,
36649     uint64_t wuffs_version,
36650     uint32_t options){
36651   if (!self) {
36652     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
36653   }
36654   if (sizeof(*self) != sizeof_star_self) {
36655     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
36656   }
36657   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
36658       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
36659     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
36660   }
36661 
36662   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
36663     // The whole point of this if-check is to detect an uninitialized *self.
36664     // We disable the warning on GCC. Clang-5.0 does not have this warning.
36665 #if !defined(__clang__) && defined(__GNUC__)
36666 #pragma GCC diagnostic push
36667 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
36668 #endif
36669     if (self->private_impl.magic != 0) {
36670       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
36671     }
36672 #if !defined(__clang__) && defined(__GNUC__)
36673 #pragma GCC diagnostic pop
36674 #endif
36675   } else {
36676     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
36677       memset(self, 0, sizeof(*self));
36678       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
36679     } else {
36680       memset(&(self->private_impl), 0, sizeof(self->private_impl));
36681     }
36682   }
36683 
36684   self->private_impl.magic = WUFFS_BASE__MAGIC;
36685   self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
36686       wuffs_base__image_decoder__vtable_name;
36687   self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
36688       (const void*)(&wuffs_gif__decoder__func_ptrs_for__wuffs_base__image_decoder);
36689   return wuffs_base__make_status(NULL);
36690 }
36691 
36692 wuffs_gif__decoder*
wuffs_gif__decoder__alloc(void)36693 wuffs_gif__decoder__alloc(void) {
36694   wuffs_gif__decoder* x =
36695       (wuffs_gif__decoder*)(calloc(sizeof(wuffs_gif__decoder), 1));
36696   if (!x) {
36697     return NULL;
36698   }
36699   if (wuffs_gif__decoder__initialize(
36700       x, sizeof(wuffs_gif__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
36701     free(x);
36702     return NULL;
36703   }
36704   return x;
36705 }
36706 
36707 size_t
sizeof__wuffs_gif__decoder(void)36708 sizeof__wuffs_gif__decoder(void) {
36709   return sizeof(wuffs_gif__decoder);
36710 }
36711 
36712 // ---------------- Function Implementations
36713 
36714 // -------- func gif.decoder.get_quirk
36715 
36716 WUFFS_BASE__GENERATED_C_CODE
36717 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_gif__decoder__get_quirk(const wuffs_gif__decoder * self,uint32_t a_key)36718 wuffs_gif__decoder__get_quirk(
36719     const wuffs_gif__decoder* self,
36720     uint32_t a_key) {
36721   if (!self) {
36722     return 0;
36723   }
36724   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
36725       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
36726     return 0;
36727   }
36728 
36729   uint32_t v_key = 0;
36730 
36731   if (a_key >= 1041635328u) {
36732     v_key = (a_key - 1041635328u);
36733     if (v_key < 7u) {
36734       if (self->private_impl.f_quirks[v_key]) {
36735         return 1u;
36736       }
36737     }
36738   }
36739   return 0u;
36740 }
36741 
36742 // -------- func gif.decoder.set_quirk
36743 
36744 WUFFS_BASE__GENERATED_C_CODE
36745 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_gif__decoder__set_quirk(wuffs_gif__decoder * self,uint32_t a_key,uint64_t a_value)36746 wuffs_gif__decoder__set_quirk(
36747     wuffs_gif__decoder* self,
36748     uint32_t a_key,
36749     uint64_t a_value) {
36750   if (!self) {
36751     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
36752   }
36753   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
36754     return wuffs_base__make_status(
36755         (self->private_impl.magic == WUFFS_BASE__DISABLED)
36756         ? wuffs_base__error__disabled_by_previous_error
36757         : wuffs_base__error__initialize_not_called);
36758   }
36759 
36760   if ((self->private_impl.f_call_sequence == 0u) && (a_key >= 1041635328u)) {
36761     a_key -= 1041635328u;
36762     if (a_key < 7u) {
36763       self->private_impl.f_quirks[a_key] = (a_value > 0u);
36764       return wuffs_base__make_status(NULL);
36765     }
36766   }
36767   return wuffs_base__make_status(wuffs_base__error__unsupported_option);
36768 }
36769 
36770 // -------- func gif.decoder.decode_image_config
36771 
36772 WUFFS_BASE__GENERATED_C_CODE
36773 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_gif__decoder__decode_image_config(wuffs_gif__decoder * self,wuffs_base__image_config * a_dst,wuffs_base__io_buffer * a_src)36774 wuffs_gif__decoder__decode_image_config(
36775     wuffs_gif__decoder* self,
36776     wuffs_base__image_config* a_dst,
36777     wuffs_base__io_buffer* a_src) {
36778   if (!self) {
36779     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
36780   }
36781   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
36782     return wuffs_base__make_status(
36783         (self->private_impl.magic == WUFFS_BASE__DISABLED)
36784         ? wuffs_base__error__disabled_by_previous_error
36785         : wuffs_base__error__initialize_not_called);
36786   }
36787   if (!a_src) {
36788     self->private_impl.magic = WUFFS_BASE__DISABLED;
36789     return wuffs_base__make_status(wuffs_base__error__bad_argument);
36790   }
36791   if ((self->private_impl.active_coroutine != 0) &&
36792       (self->private_impl.active_coroutine != 1)) {
36793     self->private_impl.magic = WUFFS_BASE__DISABLED;
36794     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
36795   }
36796   self->private_impl.active_coroutine = 0;
36797   wuffs_base__status status = wuffs_base__make_status(NULL);
36798 
36799   wuffs_base__status v_status = wuffs_base__make_status(NULL);
36800 
36801   uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
36802   switch (coro_susp_point) {
36803     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
36804 
36805     while (true) {
36806       {
36807         wuffs_base__status t_0 = wuffs_gif__decoder__do_decode_image_config(self, a_dst, a_src);
36808         v_status = t_0;
36809       }
36810       if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
36811         status = wuffs_base__make_status(wuffs_gif__error__truncated_input);
36812         goto exit;
36813       }
36814       status = v_status;
36815       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
36816     }
36817 
36818     ok:
36819     self->private_impl.p_decode_image_config[0] = 0;
36820     goto exit;
36821   }
36822 
36823   goto suspend;
36824   suspend:
36825   self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
36826   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
36827 
36828   goto exit;
36829   exit:
36830   if (wuffs_base__status__is_error(&status)) {
36831     self->private_impl.magic = WUFFS_BASE__DISABLED;
36832   }
36833   return status;
36834 }
36835 
36836 // -------- func gif.decoder.do_decode_image_config
36837 
36838 WUFFS_BASE__GENERATED_C_CODE
36839 static wuffs_base__status
wuffs_gif__decoder__do_decode_image_config(wuffs_gif__decoder * self,wuffs_base__image_config * a_dst,wuffs_base__io_buffer * a_src)36840 wuffs_gif__decoder__do_decode_image_config(
36841     wuffs_gif__decoder* self,
36842     wuffs_base__image_config* a_dst,
36843     wuffs_base__io_buffer* a_src) {
36844   wuffs_base__status status = wuffs_base__make_status(NULL);
36845 
36846   bool v_ffio = false;
36847 
36848   uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config[0];
36849   switch (coro_susp_point) {
36850     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
36851 
36852     if (self->private_impl.f_call_sequence != 0u) {
36853       status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
36854       goto exit;
36855     } else if ( ! self->private_impl.f_seen_header) {
36856       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
36857       status = wuffs_gif__decoder__decode_header(self, a_src);
36858       if (status.repr) {
36859         goto suspend;
36860       }
36861       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
36862       status = wuffs_gif__decoder__decode_lsd(self, a_src);
36863       if (status.repr) {
36864         goto suspend;
36865       }
36866       self->private_impl.f_seen_header = true;
36867     }
36868     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
36869     status = wuffs_gif__decoder__decode_up_to_id_part1(self, a_src);
36870     if (status.repr) {
36871       goto suspend;
36872     }
36873     v_ffio =  ! self->private_impl.f_gc_has_transparent_index;
36874     if ( ! self->private_impl.f_quirks[2u]) {
36875       v_ffio = (v_ffio &&
36876           (self->private_impl.f_frame_rect_x0 == 0u) &&
36877           (self->private_impl.f_frame_rect_y0 == 0u) &&
36878           (self->private_impl.f_frame_rect_x1 == self->private_impl.f_width) &&
36879           (self->private_impl.f_frame_rect_y1 == self->private_impl.f_height));
36880     } else if (v_ffio) {
36881       self->private_impl.f_black_color_u32_argb_premul = 4278190080u;
36882     }
36883     if (self->private_impl.f_background_color_u32_argb_premul == 77u) {
36884       self->private_impl.f_background_color_u32_argb_premul = self->private_impl.f_black_color_u32_argb_premul;
36885     }
36886     if (a_dst != NULL) {
36887       wuffs_base__image_config__set(
36888           a_dst,
36889           2198077448u,
36890           0u,
36891           self->private_impl.f_width,
36892           self->private_impl.f_height,
36893           self->private_impl.f_frame_config_io_position,
36894           v_ffio);
36895     }
36896     if (self->private_impl.f_call_sequence == 0u) {
36897       self->private_impl.f_call_sequence = 32u;
36898     }
36899 
36900     goto ok;
36901     ok:
36902     self->private_impl.p_do_decode_image_config[0] = 0;
36903     goto exit;
36904   }
36905 
36906   goto suspend;
36907   suspend:
36908   self->private_impl.p_do_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
36909 
36910   goto exit;
36911   exit:
36912   return status;
36913 }
36914 
36915 // -------- func gif.decoder.set_report_metadata
36916 
36917 WUFFS_BASE__GENERATED_C_CODE
36918 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_gif__decoder__set_report_metadata(wuffs_gif__decoder * self,uint32_t a_fourcc,bool a_report)36919 wuffs_gif__decoder__set_report_metadata(
36920     wuffs_gif__decoder* self,
36921     uint32_t a_fourcc,
36922     bool a_report) {
36923   if (!self) {
36924     return wuffs_base__make_empty_struct();
36925   }
36926   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
36927     return wuffs_base__make_empty_struct();
36928   }
36929 
36930   if (a_fourcc == 1229144912u) {
36931     self->private_impl.f_report_metadata_iccp = a_report;
36932   } else if (a_fourcc == 1481461792u) {
36933     self->private_impl.f_report_metadata_xmp = a_report;
36934   }
36935   return wuffs_base__make_empty_struct();
36936 }
36937 
36938 // -------- func gif.decoder.tell_me_more
36939 
36940 WUFFS_BASE__GENERATED_C_CODE
36941 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_gif__decoder__tell_me_more(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__more_information * a_minfo,wuffs_base__io_buffer * a_src)36942 wuffs_gif__decoder__tell_me_more(
36943     wuffs_gif__decoder* self,
36944     wuffs_base__io_buffer* a_dst,
36945     wuffs_base__more_information* a_minfo,
36946     wuffs_base__io_buffer* a_src) {
36947   if (!self) {
36948     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
36949   }
36950   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
36951     return wuffs_base__make_status(
36952         (self->private_impl.magic == WUFFS_BASE__DISABLED)
36953         ? wuffs_base__error__disabled_by_previous_error
36954         : wuffs_base__error__initialize_not_called);
36955   }
36956   if (!a_dst || !a_src) {
36957     self->private_impl.magic = WUFFS_BASE__DISABLED;
36958     return wuffs_base__make_status(wuffs_base__error__bad_argument);
36959   }
36960   if ((self->private_impl.active_coroutine != 0) &&
36961       (self->private_impl.active_coroutine != 2)) {
36962     self->private_impl.magic = WUFFS_BASE__DISABLED;
36963     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
36964   }
36965   self->private_impl.active_coroutine = 0;
36966   wuffs_base__status status = wuffs_base__make_status(NULL);
36967 
36968   wuffs_base__status v_status = wuffs_base__make_status(NULL);
36969 
36970   uint32_t coro_susp_point = self->private_impl.p_tell_me_more[0];
36971   switch (coro_susp_point) {
36972     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
36973 
36974     while (true) {
36975       {
36976         wuffs_base__status t_0 = wuffs_gif__decoder__do_tell_me_more(self, a_dst, a_minfo, a_src);
36977         v_status = t_0;
36978       }
36979       if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
36980         status = wuffs_base__make_status(wuffs_gif__error__truncated_input);
36981         goto exit;
36982       }
36983       status = v_status;
36984       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
36985     }
36986 
36987     ok:
36988     self->private_impl.p_tell_me_more[0] = 0;
36989     goto exit;
36990   }
36991 
36992   goto suspend;
36993   suspend:
36994   self->private_impl.p_tell_me_more[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
36995   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
36996 
36997   goto exit;
36998   exit:
36999   if (wuffs_base__status__is_error(&status)) {
37000     self->private_impl.magic = WUFFS_BASE__DISABLED;
37001   }
37002   return status;
37003 }
37004 
37005 // -------- func gif.decoder.do_tell_me_more
37006 
37007 WUFFS_BASE__GENERATED_C_CODE
37008 static wuffs_base__status
wuffs_gif__decoder__do_tell_me_more(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__more_information * a_minfo,wuffs_base__io_buffer * a_src)37009 wuffs_gif__decoder__do_tell_me_more(
37010     wuffs_gif__decoder* self,
37011     wuffs_base__io_buffer* a_dst,
37012     wuffs_base__more_information* a_minfo,
37013     wuffs_base__io_buffer* a_src) {
37014   wuffs_base__status status = wuffs_base__make_status(NULL);
37015 
37016   uint64_t v_chunk_length = 0;
37017 
37018   const uint8_t* iop_a_src = NULL;
37019   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
37020   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
37021   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
37022   if (a_src && a_src->data.ptr) {
37023     io0_a_src = a_src->data.ptr;
37024     io1_a_src = io0_a_src + a_src->meta.ri;
37025     iop_a_src = io1_a_src;
37026     io2_a_src = io0_a_src + a_src->meta.wi;
37027   }
37028 
37029   uint32_t coro_susp_point = self->private_impl.p_do_tell_me_more[0];
37030   switch (coro_susp_point) {
37031     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
37032 
37033     if ((self->private_impl.f_call_sequence & 16u) == 0u) {
37034       status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
37035       goto exit;
37036     }
37037     if (self->private_impl.f_metadata_fourcc == 0u) {
37038       status = wuffs_base__make_status(wuffs_base__error__no_more_information);
37039       goto exit;
37040     }
37041     while (true) {
37042       while (true) {
37043         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) {
37044           if (a_minfo != NULL) {
37045             wuffs_base__more_information__set(a_minfo,
37046                 2u,
37047                 0u,
37048                 self->private_impl.f_metadata_io_position,
37049                 0u,
37050                 0u);
37051           }
37052           status = wuffs_base__make_status(wuffs_base__suspension__mispositioned_read);
37053           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
37054           continue;
37055         }
37056         if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
37057           if (a_minfo != NULL) {
37058             wuffs_base__more_information__set(a_minfo,
37059                 0u,
37060                 0u,
37061                 0u,
37062                 0u,
37063                 0u);
37064           }
37065           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
37066           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
37067           continue;
37068         }
37069         break;
37070       }
37071       v_chunk_length = ((uint64_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src)));
37072       if (v_chunk_length <= 0u) {
37073         iop_a_src += 1u;
37074         break;
37075       }
37076       if (self->private_impl.f_metadata_fourcc == 1481461792u) {
37077         v_chunk_length += 1u;
37078       } else {
37079         iop_a_src += 1u;
37080       }
37081       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);
37082       if (a_minfo != NULL) {
37083         wuffs_base__more_information__set(a_minfo,
37084             3u,
37085             self->private_impl.f_metadata_fourcc,
37086             0u,
37087             wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))),
37088             self->private_impl.f_metadata_io_position);
37089       }
37090       status = wuffs_base__make_status(wuffs_base__suspension__even_more_information);
37091       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
37092     }
37093     if (a_minfo != NULL) {
37094       wuffs_base__more_information__set(a_minfo,
37095           3u,
37096           self->private_impl.f_metadata_fourcc,
37097           0u,
37098           self->private_impl.f_metadata_io_position,
37099           self->private_impl.f_metadata_io_position);
37100     }
37101     self->private_impl.f_call_sequence &= 239u;
37102     self->private_impl.f_metadata_fourcc = 0u;
37103     self->private_impl.f_metadata_io_position = 0u;
37104     status = wuffs_base__make_status(NULL);
37105     goto ok;
37106 
37107     ok:
37108     self->private_impl.p_do_tell_me_more[0] = 0;
37109     goto exit;
37110   }
37111 
37112   goto suspend;
37113   suspend:
37114   self->private_impl.p_do_tell_me_more[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
37115 
37116   goto exit;
37117   exit:
37118   if (a_src && a_src->data.ptr) {
37119     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
37120   }
37121 
37122   return status;
37123 }
37124 
37125 // -------- func gif.decoder.num_animation_loops
37126 
37127 WUFFS_BASE__GENERATED_C_CODE
37128 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_gif__decoder__num_animation_loops(const wuffs_gif__decoder * self)37129 wuffs_gif__decoder__num_animation_loops(
37130     const wuffs_gif__decoder* self) {
37131   if (!self) {
37132     return 0;
37133   }
37134   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
37135       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
37136     return 0;
37137   }
37138 
37139   if (self->private_impl.f_seen_num_animation_loops_value) {
37140     return self->private_impl.f_num_animation_loops_value;
37141   }
37142   if (self->private_impl.f_num_decoded_frame_configs_value > 1u) {
37143     return 1u;
37144   }
37145   return 0u;
37146 }
37147 
37148 // -------- func gif.decoder.num_decoded_frame_configs
37149 
37150 WUFFS_BASE__GENERATED_C_CODE
37151 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_gif__decoder__num_decoded_frame_configs(const wuffs_gif__decoder * self)37152 wuffs_gif__decoder__num_decoded_frame_configs(
37153     const wuffs_gif__decoder* self) {
37154   if (!self) {
37155     return 0;
37156   }
37157   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
37158       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
37159     return 0;
37160   }
37161 
37162   return self->private_impl.f_num_decoded_frame_configs_value;
37163 }
37164 
37165 // -------- func gif.decoder.num_decoded_frames
37166 
37167 WUFFS_BASE__GENERATED_C_CODE
37168 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_gif__decoder__num_decoded_frames(const wuffs_gif__decoder * self)37169 wuffs_gif__decoder__num_decoded_frames(
37170     const wuffs_gif__decoder* self) {
37171   if (!self) {
37172     return 0;
37173   }
37174   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
37175       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
37176     return 0;
37177   }
37178 
37179   return self->private_impl.f_num_decoded_frames_value;
37180 }
37181 
37182 // -------- func gif.decoder.frame_dirty_rect
37183 
37184 WUFFS_BASE__GENERATED_C_CODE
37185 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
wuffs_gif__decoder__frame_dirty_rect(const wuffs_gif__decoder * self)37186 wuffs_gif__decoder__frame_dirty_rect(
37187     const wuffs_gif__decoder* self) {
37188   if (!self) {
37189     return wuffs_base__utility__empty_rect_ie_u32();
37190   }
37191   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
37192       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
37193     return wuffs_base__utility__empty_rect_ie_u32();
37194   }
37195 
37196   return wuffs_base__utility__make_rect_ie_u32(
37197       wuffs_base__u32__min(self->private_impl.f_frame_rect_x0, self->private_impl.f_width),
37198       wuffs_base__u32__min(self->private_impl.f_frame_rect_y0, self->private_impl.f_height),
37199       wuffs_base__u32__min(self->private_impl.f_frame_rect_x1, self->private_impl.f_width),
37200       wuffs_base__u32__min(self->private_impl.f_dirty_max_excl_y, self->private_impl.f_height));
37201 }
37202 
37203 // -------- func gif.decoder.history_retain_length
37204 
37205 WUFFS_BASE__GENERATED_C_CODE
37206 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_gif__decoder__history_retain_length(const wuffs_gif__decoder * self)37207 wuffs_gif__decoder__history_retain_length(
37208     const wuffs_gif__decoder* self) {
37209   if (!self) {
37210     return 0;
37211   }
37212   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
37213       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
37214     return 0;
37215   }
37216 
37217   return 0u;
37218 }
37219 
37220 // -------- func gif.decoder.workbuf_len
37221 
37222 WUFFS_BASE__GENERATED_C_CODE
37223 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_gif__decoder__workbuf_len(const wuffs_gif__decoder * self)37224 wuffs_gif__decoder__workbuf_len(
37225     const wuffs_gif__decoder* self) {
37226   if (!self) {
37227     return wuffs_base__utility__empty_range_ii_u64();
37228   }
37229   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
37230       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
37231     return wuffs_base__utility__empty_range_ii_u64();
37232   }
37233 
37234   return wuffs_base__utility__make_range_ii_u64(0u, 0u);
37235 }
37236 
37237 // -------- func gif.decoder.restart_frame
37238 
37239 WUFFS_BASE__GENERATED_C_CODE
37240 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_gif__decoder__restart_frame(wuffs_gif__decoder * self,uint64_t a_index,uint64_t a_io_position)37241 wuffs_gif__decoder__restart_frame(
37242     wuffs_gif__decoder* self,
37243     uint64_t a_index,
37244     uint64_t a_io_position) {
37245   if (!self) {
37246     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
37247   }
37248   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
37249     return wuffs_base__make_status(
37250         (self->private_impl.magic == WUFFS_BASE__DISABLED)
37251         ? wuffs_base__error__disabled_by_previous_error
37252         : wuffs_base__error__initialize_not_called);
37253   }
37254 
37255   if (self->private_impl.f_call_sequence < 32u) {
37256     return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
37257   } else if (a_io_position == 0u) {
37258     return wuffs_base__make_status(wuffs_base__error__bad_argument);
37259   }
37260   self->private_impl.f_delayed_num_decoded_frames = false;
37261   self->private_impl.f_frame_config_io_position = a_io_position;
37262   self->private_impl.f_num_decoded_frame_configs_value = a_index;
37263   self->private_impl.f_num_decoded_frames_value = a_index;
37264   wuffs_gif__decoder__reset_gc(self);
37265   self->private_impl.f_call_sequence = 40u;
37266   return wuffs_base__make_status(NULL);
37267 }
37268 
37269 // -------- func gif.decoder.decode_frame_config
37270 
37271 WUFFS_BASE__GENERATED_C_CODE
37272 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_gif__decoder__decode_frame_config(wuffs_gif__decoder * self,wuffs_base__frame_config * a_dst,wuffs_base__io_buffer * a_src)37273 wuffs_gif__decoder__decode_frame_config(
37274     wuffs_gif__decoder* self,
37275     wuffs_base__frame_config* a_dst,
37276     wuffs_base__io_buffer* a_src) {
37277   if (!self) {
37278     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
37279   }
37280   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
37281     return wuffs_base__make_status(
37282         (self->private_impl.magic == WUFFS_BASE__DISABLED)
37283         ? wuffs_base__error__disabled_by_previous_error
37284         : wuffs_base__error__initialize_not_called);
37285   }
37286   if (!a_src) {
37287     self->private_impl.magic = WUFFS_BASE__DISABLED;
37288     return wuffs_base__make_status(wuffs_base__error__bad_argument);
37289   }
37290   if ((self->private_impl.active_coroutine != 0) &&
37291       (self->private_impl.active_coroutine != 3)) {
37292     self->private_impl.magic = WUFFS_BASE__DISABLED;
37293     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
37294   }
37295   self->private_impl.active_coroutine = 0;
37296   wuffs_base__status status = wuffs_base__make_status(NULL);
37297 
37298   wuffs_base__status v_status = wuffs_base__make_status(NULL);
37299 
37300   uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
37301   switch (coro_susp_point) {
37302     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
37303 
37304     while (true) {
37305       {
37306         wuffs_base__status t_0 = wuffs_gif__decoder__do_decode_frame_config(self, a_dst, a_src);
37307         v_status = t_0;
37308       }
37309       if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
37310         status = wuffs_base__make_status(wuffs_gif__error__truncated_input);
37311         goto exit;
37312       }
37313       status = v_status;
37314       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
37315     }
37316 
37317     ok:
37318     self->private_impl.p_decode_frame_config[0] = 0;
37319     goto exit;
37320   }
37321 
37322   goto suspend;
37323   suspend:
37324   self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
37325   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
37326 
37327   goto exit;
37328   exit:
37329   if (wuffs_base__status__is_error(&status)) {
37330     self->private_impl.magic = WUFFS_BASE__DISABLED;
37331   }
37332   return status;
37333 }
37334 
37335 // -------- func gif.decoder.do_decode_frame_config
37336 
37337 WUFFS_BASE__GENERATED_C_CODE
37338 static wuffs_base__status
wuffs_gif__decoder__do_decode_frame_config(wuffs_gif__decoder * self,wuffs_base__frame_config * a_dst,wuffs_base__io_buffer * a_src)37339 wuffs_gif__decoder__do_decode_frame_config(
37340     wuffs_gif__decoder* self,
37341     wuffs_base__frame_config* a_dst,
37342     wuffs_base__io_buffer* a_src) {
37343   wuffs_base__status status = wuffs_base__make_status(NULL);
37344 
37345   uint32_t v_background_color = 0;
37346   uint8_t v_flags = 0;
37347 
37348   const uint8_t* iop_a_src = NULL;
37349   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
37350   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
37351   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
37352   if (a_src && a_src->data.ptr) {
37353     io0_a_src = a_src->data.ptr;
37354     io1_a_src = io0_a_src + a_src->meta.ri;
37355     iop_a_src = io1_a_src;
37356     io2_a_src = io0_a_src + a_src->meta.wi;
37357   }
37358 
37359   uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config[0];
37360   if (coro_susp_point) {
37361     v_background_color = self->private_data.s_do_decode_frame_config[0].v_background_color;
37362   }
37363   switch (coro_susp_point) {
37364     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
37365 
37366     self->private_impl.f_dirty_max_excl_y = 0u;
37367     if ((self->private_impl.f_call_sequence & 16u) != 0u) {
37368       status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
37369       goto exit;
37370     } else if (self->private_impl.f_call_sequence == 32u) {
37371     } else if (self->private_impl.f_call_sequence < 32u) {
37372       if (a_src) {
37373         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
37374       }
37375       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
37376       status = wuffs_gif__decoder__do_decode_image_config(self, NULL, a_src);
37377       if (a_src) {
37378         iop_a_src = a_src->data.ptr + a_src->meta.ri;
37379       }
37380       if (status.repr) {
37381         goto suspend;
37382       }
37383     } else if (self->private_impl.f_call_sequence == 40u) {
37384       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)))) {
37385         status = wuffs_base__make_status(wuffs_base__error__bad_restart);
37386         goto exit;
37387       }
37388     } else if (self->private_impl.f_call_sequence == 64u) {
37389       if (a_src) {
37390         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
37391       }
37392       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
37393       status = wuffs_gif__decoder__skip_frame(self, a_src);
37394       if (a_src) {
37395         iop_a_src = a_src->data.ptr + a_src->meta.ri;
37396       }
37397       if (status.repr) {
37398         goto suspend;
37399       }
37400       if (self->private_impl.f_call_sequence >= 96u) {
37401         status = wuffs_base__make_status(wuffs_base__note__end_of_data);
37402         goto ok;
37403       }
37404     } else {
37405       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
37406       goto ok;
37407     }
37408     if ((self->private_impl.f_num_decoded_frame_configs_value > 0u) || (self->private_impl.f_call_sequence == 40u)) {
37409       if (a_src) {
37410         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
37411       }
37412       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
37413       status = wuffs_gif__decoder__decode_up_to_id_part1(self, a_src);
37414       if (a_src) {
37415         iop_a_src = a_src->data.ptr + a_src->meta.ri;
37416       }
37417       if (status.repr) {
37418         goto suspend;
37419       }
37420       if (self->private_impl.f_call_sequence >= 96u) {
37421         status = wuffs_base__make_status(wuffs_base__note__end_of_data);
37422         goto ok;
37423       }
37424     }
37425     v_background_color = self->private_impl.f_black_color_u32_argb_premul;
37426     if ( ! self->private_impl.f_gc_has_transparent_index) {
37427       v_background_color = self->private_impl.f_background_color_u32_argb_premul;
37428       if (self->private_impl.f_quirks[1u] && (self->private_impl.f_num_decoded_frame_configs_value == 0u)) {
37429         while (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
37430           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
37431           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
37432         }
37433         v_flags = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
37434         if ((v_flags & 128u) != 0u) {
37435           v_background_color = self->private_impl.f_black_color_u32_argb_premul;
37436         }
37437       }
37438     }
37439     if (a_dst != NULL) {
37440       wuffs_base__frame_config__set(
37441           a_dst,
37442           wuffs_base__utility__make_rect_ie_u32(
37443           wuffs_base__u32__min(self->private_impl.f_frame_rect_x0, self->private_impl.f_width),
37444           wuffs_base__u32__min(self->private_impl.f_frame_rect_y0, self->private_impl.f_height),
37445           wuffs_base__u32__min(self->private_impl.f_frame_rect_x1, self->private_impl.f_width),
37446           wuffs_base__u32__min(self->private_impl.f_frame_rect_y1, self->private_impl.f_height)),
37447           ((wuffs_base__flicks)(self->private_impl.f_gc_duration)),
37448           self->private_impl.f_num_decoded_frame_configs_value,
37449           self->private_impl.f_frame_config_io_position,
37450           self->private_impl.f_gc_disposal,
37451           ! self->private_impl.f_gc_has_transparent_index,
37452           false,
37453           v_background_color);
37454     }
37455     wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frame_configs_value, 1u);
37456     self->private_impl.f_call_sequence = 64u;
37457 
37458     ok:
37459     self->private_impl.p_do_decode_frame_config[0] = 0;
37460     goto exit;
37461   }
37462 
37463   goto suspend;
37464   suspend:
37465   self->private_impl.p_do_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
37466   self->private_data.s_do_decode_frame_config[0].v_background_color = v_background_color;
37467 
37468   goto exit;
37469   exit:
37470   if (a_src && a_src->data.ptr) {
37471     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
37472   }
37473 
37474   return status;
37475 }
37476 
37477 // -------- func gif.decoder.skip_frame
37478 
37479 WUFFS_BASE__GENERATED_C_CODE
37480 static wuffs_base__status
wuffs_gif__decoder__skip_frame(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)37481 wuffs_gif__decoder__skip_frame(
37482     wuffs_gif__decoder* self,
37483     wuffs_base__io_buffer* a_src) {
37484   wuffs_base__status status = wuffs_base__make_status(NULL);
37485 
37486   uint8_t v_flags = 0;
37487   uint8_t v_lw = 0;
37488 
37489   const uint8_t* iop_a_src = NULL;
37490   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
37491   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
37492   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
37493   if (a_src && a_src->data.ptr) {
37494     io0_a_src = a_src->data.ptr;
37495     io1_a_src = io0_a_src + a_src->meta.ri;
37496     iop_a_src = io1_a_src;
37497     io2_a_src = io0_a_src + a_src->meta.wi;
37498   }
37499 
37500   uint32_t coro_susp_point = self->private_impl.p_skip_frame[0];
37501   switch (coro_susp_point) {
37502     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
37503 
37504     {
37505       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
37506       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
37507         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
37508         goto suspend;
37509       }
37510       uint8_t t_0 = *iop_a_src++;
37511       v_flags = t_0;
37512     }
37513     if ((v_flags & 128u) != 0u) {
37514       self->private_data.s_skip_frame[0].scratch = (((uint32_t)(3u)) << (1u + (v_flags & 7u)));
37515       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
37516       if (self->private_data.s_skip_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
37517         self->private_data.s_skip_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
37518         iop_a_src = io2_a_src;
37519         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
37520         goto suspend;
37521       }
37522       iop_a_src += self->private_data.s_skip_frame[0].scratch;
37523     }
37524     {
37525       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
37526       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
37527         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
37528         goto suspend;
37529       }
37530       uint8_t t_1 = *iop_a_src++;
37531       v_lw = t_1;
37532     }
37533     if (v_lw > 8u) {
37534       status = wuffs_base__make_status(wuffs_gif__error__bad_literal_width);
37535       goto exit;
37536     }
37537     if (a_src) {
37538       a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
37539     }
37540     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
37541     status = wuffs_gif__decoder__skip_blocks(self, a_src);
37542     if (a_src) {
37543       iop_a_src = a_src->data.ptr + a_src->meta.ri;
37544     }
37545     if (status.repr) {
37546       goto suspend;
37547     }
37548     if (self->private_impl.f_quirks[0u]) {
37549       self->private_impl.f_delayed_num_decoded_frames = true;
37550     } else {
37551       wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1u);
37552     }
37553     wuffs_gif__decoder__reset_gc(self);
37554     self->private_impl.f_call_sequence = 32u;
37555 
37556     goto ok;
37557     ok:
37558     self->private_impl.p_skip_frame[0] = 0;
37559     goto exit;
37560   }
37561 
37562   goto suspend;
37563   suspend:
37564   self->private_impl.p_skip_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
37565 
37566   goto exit;
37567   exit:
37568   if (a_src && a_src->data.ptr) {
37569     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
37570   }
37571 
37572   return status;
37573 }
37574 
37575 // -------- func gif.decoder.decode_frame
37576 
37577 WUFFS_BASE__GENERATED_C_CODE
37578 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_gif__decoder__decode_frame(wuffs_gif__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__pixel_blend a_blend,wuffs_base__slice_u8 a_workbuf,wuffs_base__decode_frame_options * a_opts)37579 wuffs_gif__decoder__decode_frame(
37580     wuffs_gif__decoder* self,
37581     wuffs_base__pixel_buffer* a_dst,
37582     wuffs_base__io_buffer* a_src,
37583     wuffs_base__pixel_blend a_blend,
37584     wuffs_base__slice_u8 a_workbuf,
37585     wuffs_base__decode_frame_options* a_opts) {
37586   if (!self) {
37587     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
37588   }
37589   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
37590     return wuffs_base__make_status(
37591         (self->private_impl.magic == WUFFS_BASE__DISABLED)
37592         ? wuffs_base__error__disabled_by_previous_error
37593         : wuffs_base__error__initialize_not_called);
37594   }
37595   if (!a_dst || !a_src) {
37596     self->private_impl.magic = WUFFS_BASE__DISABLED;
37597     return wuffs_base__make_status(wuffs_base__error__bad_argument);
37598   }
37599   if ((self->private_impl.active_coroutine != 0) &&
37600       (self->private_impl.active_coroutine != 4)) {
37601     self->private_impl.magic = WUFFS_BASE__DISABLED;
37602     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
37603   }
37604   self->private_impl.active_coroutine = 0;
37605   wuffs_base__status status = wuffs_base__make_status(NULL);
37606 
37607   wuffs_base__status v_status = wuffs_base__make_status(NULL);
37608 
37609   uint32_t coro_susp_point = self->private_impl.p_decode_frame[0];
37610   switch (coro_susp_point) {
37611     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
37612 
37613     while (true) {
37614       {
37615         wuffs_base__status t_0 = wuffs_gif__decoder__do_decode_frame(self,
37616             a_dst,
37617             a_src,
37618             a_blend,
37619             a_workbuf,
37620             a_opts);
37621         v_status = t_0;
37622       }
37623       if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
37624         status = wuffs_base__make_status(wuffs_gif__error__truncated_input);
37625         goto exit;
37626       }
37627       status = v_status;
37628       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
37629     }
37630 
37631     ok:
37632     self->private_impl.p_decode_frame[0] = 0;
37633     goto exit;
37634   }
37635 
37636   goto suspend;
37637   suspend:
37638   self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
37639   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 4 : 0;
37640 
37641   goto exit;
37642   exit:
37643   if (wuffs_base__status__is_error(&status)) {
37644     self->private_impl.magic = WUFFS_BASE__DISABLED;
37645   }
37646   return status;
37647 }
37648 
37649 // -------- func gif.decoder.do_decode_frame
37650 
37651 WUFFS_BASE__GENERATED_C_CODE
37652 static wuffs_base__status
wuffs_gif__decoder__do_decode_frame(wuffs_gif__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__pixel_blend a_blend,wuffs_base__slice_u8 a_workbuf,wuffs_base__decode_frame_options * a_opts)37653 wuffs_gif__decoder__do_decode_frame(
37654     wuffs_gif__decoder* self,
37655     wuffs_base__pixel_buffer* a_dst,
37656     wuffs_base__io_buffer* a_src,
37657     wuffs_base__pixel_blend a_blend,
37658     wuffs_base__slice_u8 a_workbuf,
37659     wuffs_base__decode_frame_options* a_opts) {
37660   wuffs_base__status status = wuffs_base__make_status(NULL);
37661 
37662   uint32_t coro_susp_point = self->private_impl.p_do_decode_frame[0];
37663   switch (coro_susp_point) {
37664     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
37665 
37666     if (self->private_impl.f_call_sequence == 64u) {
37667     } else if (self->private_impl.f_call_sequence < 64u) {
37668       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
37669       status = wuffs_gif__decoder__do_decode_frame_config(self, NULL, a_src);
37670       if (status.repr) {
37671         goto suspend;
37672       }
37673     } else {
37674       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
37675       goto ok;
37676     }
37677     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))) {
37678       status = wuffs_base__make_status(wuffs_gif__error__bad_frame_size);
37679       goto exit;
37680     }
37681     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
37682     status = wuffs_gif__decoder__decode_id_part1(self, a_dst, a_src, a_blend);
37683     if (status.repr) {
37684       goto suspend;
37685     }
37686     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
37687     status = wuffs_gif__decoder__decode_id_part2(self, a_dst, a_src, a_workbuf);
37688     if (status.repr) {
37689       goto suspend;
37690     }
37691     wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1u);
37692     wuffs_gif__decoder__reset_gc(self);
37693     self->private_impl.f_call_sequence = 32u;
37694 
37695     ok:
37696     self->private_impl.p_do_decode_frame[0] = 0;
37697     goto exit;
37698   }
37699 
37700   goto suspend;
37701   suspend:
37702   self->private_impl.p_do_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
37703 
37704   goto exit;
37705   exit:
37706   return status;
37707 }
37708 
37709 // -------- func gif.decoder.reset_gc
37710 
37711 WUFFS_BASE__GENERATED_C_CODE
37712 static wuffs_base__empty_struct
wuffs_gif__decoder__reset_gc(wuffs_gif__decoder * self)37713 wuffs_gif__decoder__reset_gc(
37714     wuffs_gif__decoder* self) {
37715   self->private_impl.f_gc_has_transparent_index = false;
37716   self->private_impl.f_gc_transparent_index = 0u;
37717   self->private_impl.f_gc_disposal = 0u;
37718   self->private_impl.f_gc_duration = 0u;
37719   return wuffs_base__make_empty_struct();
37720 }
37721 
37722 // -------- func gif.decoder.decode_up_to_id_part1
37723 
37724 WUFFS_BASE__GENERATED_C_CODE
37725 static wuffs_base__status
wuffs_gif__decoder__decode_up_to_id_part1(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)37726 wuffs_gif__decoder__decode_up_to_id_part1(
37727     wuffs_gif__decoder* self,
37728     wuffs_base__io_buffer* a_src) {
37729   wuffs_base__status status = wuffs_base__make_status(NULL);
37730 
37731   uint8_t v_block_type = 0;
37732 
37733   const uint8_t* iop_a_src = NULL;
37734   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
37735   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
37736   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
37737   if (a_src && a_src->data.ptr) {
37738     io0_a_src = a_src->data.ptr;
37739     io1_a_src = io0_a_src + a_src->meta.ri;
37740     iop_a_src = io1_a_src;
37741     io2_a_src = io0_a_src + a_src->meta.wi;
37742   }
37743 
37744   uint32_t coro_susp_point = self->private_impl.p_decode_up_to_id_part1[0];
37745   switch (coro_susp_point) {
37746     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
37747 
37748     if ((self->private_impl.f_frame_config_io_position == 0u) || (self->private_impl.f_num_decoded_frame_configs_value > 0u)) {
37749       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)));
37750     }
37751     while (true) {
37752       {
37753         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
37754         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
37755           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
37756           goto suspend;
37757         }
37758         uint8_t t_0 = *iop_a_src++;
37759         v_block_type = t_0;
37760       }
37761       if (v_block_type == 33u) {
37762         if (a_src) {
37763           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
37764         }
37765         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
37766         status = wuffs_gif__decoder__decode_extension(self, a_src);
37767         if (a_src) {
37768           iop_a_src = a_src->data.ptr + a_src->meta.ri;
37769         }
37770         if (status.repr) {
37771           goto suspend;
37772         }
37773       } else if (v_block_type == 44u) {
37774         if (self->private_impl.f_delayed_num_decoded_frames) {
37775           self->private_impl.f_delayed_num_decoded_frames = false;
37776           wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1u);
37777         }
37778         if (a_src) {
37779           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
37780         }
37781         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
37782         status = wuffs_gif__decoder__decode_id_part0(self, a_src);
37783         if (a_src) {
37784           iop_a_src = a_src->data.ptr + a_src->meta.ri;
37785         }
37786         if (status.repr) {
37787           goto suspend;
37788         }
37789         break;
37790       } else {
37791         if (self->private_impl.f_delayed_num_decoded_frames) {
37792           self->private_impl.f_delayed_num_decoded_frames = false;
37793           wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1u);
37794         }
37795         self->private_impl.f_call_sequence = 96u;
37796         break;
37797       }
37798     }
37799 
37800     goto ok;
37801     ok:
37802     self->private_impl.p_decode_up_to_id_part1[0] = 0;
37803     goto exit;
37804   }
37805 
37806   goto suspend;
37807   suspend:
37808   self->private_impl.p_decode_up_to_id_part1[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
37809 
37810   goto exit;
37811   exit:
37812   if (a_src && a_src->data.ptr) {
37813     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
37814   }
37815 
37816   return status;
37817 }
37818 
37819 // -------- func gif.decoder.decode_header
37820 
37821 WUFFS_BASE__GENERATED_C_CODE
37822 static wuffs_base__status
wuffs_gif__decoder__decode_header(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)37823 wuffs_gif__decoder__decode_header(
37824     wuffs_gif__decoder* self,
37825     wuffs_base__io_buffer* a_src) {
37826   wuffs_base__status status = wuffs_base__make_status(NULL);
37827 
37828   uint8_t v_c[6] = {0};
37829   uint32_t v_i = 0;
37830 
37831   const uint8_t* iop_a_src = NULL;
37832   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
37833   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
37834   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
37835   if (a_src && a_src->data.ptr) {
37836     io0_a_src = a_src->data.ptr;
37837     io1_a_src = io0_a_src + a_src->meta.ri;
37838     iop_a_src = io1_a_src;
37839     io2_a_src = io0_a_src + a_src->meta.wi;
37840   }
37841 
37842   uint32_t coro_susp_point = self->private_impl.p_decode_header[0];
37843   if (coro_susp_point) {
37844     memcpy(v_c, self->private_data.s_decode_header[0].v_c, sizeof(v_c));
37845     v_i = self->private_data.s_decode_header[0].v_i;
37846   }
37847   switch (coro_susp_point) {
37848     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
37849 
37850     while (v_i < 6u) {
37851       {
37852         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
37853         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
37854           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
37855           goto suspend;
37856         }
37857         uint8_t t_0 = *iop_a_src++;
37858         v_c[v_i] = t_0;
37859       }
37860       v_i += 1u;
37861     }
37862     if ((v_c[0u] != 71u) ||
37863         (v_c[1u] != 73u) ||
37864         (v_c[2u] != 70u) ||
37865         (v_c[3u] != 56u) ||
37866         ((v_c[4u] != 55u) && (v_c[4u] != 57u)) ||
37867         (v_c[5u] != 97u)) {
37868       status = wuffs_base__make_status(wuffs_gif__error__bad_header);
37869       goto exit;
37870     }
37871 
37872     goto ok;
37873     ok:
37874     self->private_impl.p_decode_header[0] = 0;
37875     goto exit;
37876   }
37877 
37878   goto suspend;
37879   suspend:
37880   self->private_impl.p_decode_header[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
37881   memcpy(self->private_data.s_decode_header[0].v_c, v_c, sizeof(v_c));
37882   self->private_data.s_decode_header[0].v_i = v_i;
37883 
37884   goto exit;
37885   exit:
37886   if (a_src && a_src->data.ptr) {
37887     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
37888   }
37889 
37890   return status;
37891 }
37892 
37893 // -------- func gif.decoder.decode_lsd
37894 
37895 WUFFS_BASE__GENERATED_C_CODE
37896 static wuffs_base__status
wuffs_gif__decoder__decode_lsd(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)37897 wuffs_gif__decoder__decode_lsd(
37898     wuffs_gif__decoder* self,
37899     wuffs_base__io_buffer* a_src) {
37900   wuffs_base__status status = wuffs_base__make_status(NULL);
37901 
37902   uint8_t v_flags = 0;
37903   uint8_t v_background_color_index = 0;
37904   uint32_t v_num_palette_entries = 0;
37905   uint32_t v_i = 0;
37906   uint32_t v_j = 0;
37907   uint32_t v_argb = 0;
37908 
37909   const uint8_t* iop_a_src = NULL;
37910   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
37911   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
37912   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
37913   if (a_src && a_src->data.ptr) {
37914     io0_a_src = a_src->data.ptr;
37915     io1_a_src = io0_a_src + a_src->meta.ri;
37916     iop_a_src = io1_a_src;
37917     io2_a_src = io0_a_src + a_src->meta.wi;
37918   }
37919 
37920   uint32_t coro_susp_point = self->private_impl.p_decode_lsd[0];
37921   if (coro_susp_point) {
37922     v_flags = self->private_data.s_decode_lsd[0].v_flags;
37923     v_background_color_index = self->private_data.s_decode_lsd[0].v_background_color_index;
37924     v_num_palette_entries = self->private_data.s_decode_lsd[0].v_num_palette_entries;
37925     v_i = self->private_data.s_decode_lsd[0].v_i;
37926   }
37927   switch (coro_susp_point) {
37928     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
37929 
37930     {
37931       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
37932       uint32_t t_0;
37933       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
37934         t_0 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
37935         iop_a_src += 2;
37936       } else {
37937         self->private_data.s_decode_lsd[0].scratch = 0;
37938         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
37939         while (true) {
37940           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
37941             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
37942             goto suspend;
37943           }
37944           uint64_t* scratch = &self->private_data.s_decode_lsd[0].scratch;
37945           uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
37946           *scratch <<= 8;
37947           *scratch >>= 8;
37948           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
37949           if (num_bits_0 == 8) {
37950             t_0 = ((uint32_t)(*scratch));
37951             break;
37952           }
37953           num_bits_0 += 8u;
37954           *scratch |= ((uint64_t)(num_bits_0)) << 56;
37955         }
37956       }
37957       self->private_impl.f_width = t_0;
37958     }
37959     {
37960       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
37961       uint32_t t_1;
37962       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
37963         t_1 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
37964         iop_a_src += 2;
37965       } else {
37966         self->private_data.s_decode_lsd[0].scratch = 0;
37967         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
37968         while (true) {
37969           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
37970             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
37971             goto suspend;
37972           }
37973           uint64_t* scratch = &self->private_data.s_decode_lsd[0].scratch;
37974           uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
37975           *scratch <<= 8;
37976           *scratch >>= 8;
37977           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
37978           if (num_bits_1 == 8) {
37979             t_1 = ((uint32_t)(*scratch));
37980             break;
37981           }
37982           num_bits_1 += 8u;
37983           *scratch |= ((uint64_t)(num_bits_1)) << 56;
37984         }
37985       }
37986       self->private_impl.f_height = t_1;
37987     }
37988     {
37989       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
37990       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
37991         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
37992         goto suspend;
37993       }
37994       uint8_t t_2 = *iop_a_src++;
37995       v_flags = t_2;
37996     }
37997     {
37998       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
37999       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38000         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38001         goto suspend;
38002       }
38003       uint8_t t_3 = *iop_a_src++;
38004       v_background_color_index = t_3;
38005     }
38006     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
38007     if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38008       status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38009       goto suspend;
38010     }
38011     iop_a_src++;
38012     v_i = 0u;
38013     self->private_impl.f_has_global_palette = ((v_flags & 128u) != 0u);
38014     if (self->private_impl.f_has_global_palette) {
38015       v_num_palette_entries = (((uint32_t)(1u)) << (1u + (v_flags & 7u)));
38016       while (v_i < v_num_palette_entries) {
38017         {
38018           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
38019           uint32_t t_4;
38020           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) {
38021             t_4 = ((uint32_t)(wuffs_base__peek_u24be__no_bounds_check(iop_a_src)));
38022             iop_a_src += 3;
38023           } else {
38024             self->private_data.s_decode_lsd[0].scratch = 0;
38025             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
38026             while (true) {
38027               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38028                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38029                 goto suspend;
38030               }
38031               uint64_t* scratch = &self->private_data.s_decode_lsd[0].scratch;
38032               uint32_t num_bits_4 = ((uint32_t)(*scratch & 0xFFu));
38033               *scratch >>= 8;
38034               *scratch <<= 8;
38035               *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_4);
38036               if (num_bits_4 == 16) {
38037                 t_4 = ((uint32_t)(*scratch >> 40));
38038                 break;
38039               }
38040               num_bits_4 += 8u;
38041               *scratch |= ((uint64_t)(num_bits_4));
38042             }
38043           }
38044           v_argb = t_4;
38045         }
38046         v_argb |= 4278190080u;
38047         self->private_data.f_palettes[0u][((4u * v_i) + 0u)] = ((uint8_t)((v_argb >> 0u)));
38048         self->private_data.f_palettes[0u][((4u * v_i) + 1u)] = ((uint8_t)((v_argb >> 8u)));
38049         self->private_data.f_palettes[0u][((4u * v_i) + 2u)] = ((uint8_t)((v_argb >> 16u)));
38050         self->private_data.f_palettes[0u][((4u * v_i) + 3u)] = ((uint8_t)((v_argb >> 24u)));
38051         v_i += 1u;
38052       }
38053       if (self->private_impl.f_quirks[2u]) {
38054         if ((v_background_color_index != 0u) && (((uint32_t)(v_background_color_index)) < v_num_palette_entries)) {
38055           v_j = (4u * ((uint32_t)(v_background_color_index)));
38056           self->private_impl.f_background_color_u32_argb_premul = ((((uint32_t)(self->private_data.f_palettes[0u][(v_j + 0u)])) << 0u) |
38057               (((uint32_t)(self->private_data.f_palettes[0u][(v_j + 1u)])) << 8u) |
38058               (((uint32_t)(self->private_data.f_palettes[0u][(v_j + 2u)])) << 16u) |
38059               (((uint32_t)(self->private_data.f_palettes[0u][(v_j + 3u)])) << 24u));
38060         } else {
38061           self->private_impl.f_background_color_u32_argb_premul = 77u;
38062         }
38063       }
38064     }
38065     while (v_i < 256u) {
38066       self->private_data.f_palettes[0u][((4u * v_i) + 0u)] = 0u;
38067       self->private_data.f_palettes[0u][((4u * v_i) + 1u)] = 0u;
38068       self->private_data.f_palettes[0u][((4u * v_i) + 2u)] = 0u;
38069       self->private_data.f_palettes[0u][((4u * v_i) + 3u)] = 255u;
38070       v_i += 1u;
38071     }
38072 
38073     goto ok;
38074     ok:
38075     self->private_impl.p_decode_lsd[0] = 0;
38076     goto exit;
38077   }
38078 
38079   goto suspend;
38080   suspend:
38081   self->private_impl.p_decode_lsd[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
38082   self->private_data.s_decode_lsd[0].v_flags = v_flags;
38083   self->private_data.s_decode_lsd[0].v_background_color_index = v_background_color_index;
38084   self->private_data.s_decode_lsd[0].v_num_palette_entries = v_num_palette_entries;
38085   self->private_data.s_decode_lsd[0].v_i = v_i;
38086 
38087   goto exit;
38088   exit:
38089   if (a_src && a_src->data.ptr) {
38090     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38091   }
38092 
38093   return status;
38094 }
38095 
38096 // -------- func gif.decoder.decode_extension
38097 
38098 WUFFS_BASE__GENERATED_C_CODE
38099 static wuffs_base__status
wuffs_gif__decoder__decode_extension(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)38100 wuffs_gif__decoder__decode_extension(
38101     wuffs_gif__decoder* self,
38102     wuffs_base__io_buffer* a_src) {
38103   wuffs_base__status status = wuffs_base__make_status(NULL);
38104 
38105   uint8_t v_label = 0;
38106 
38107   const uint8_t* iop_a_src = NULL;
38108   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38109   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38110   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38111   if (a_src && a_src->data.ptr) {
38112     io0_a_src = a_src->data.ptr;
38113     io1_a_src = io0_a_src + a_src->meta.ri;
38114     iop_a_src = io1_a_src;
38115     io2_a_src = io0_a_src + a_src->meta.wi;
38116   }
38117 
38118   uint32_t coro_susp_point = self->private_impl.p_decode_extension[0];
38119   switch (coro_susp_point) {
38120     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
38121 
38122     {
38123       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
38124       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38125         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38126         goto suspend;
38127       }
38128       uint8_t t_0 = *iop_a_src++;
38129       v_label = t_0;
38130     }
38131     if (v_label == 249u) {
38132       if (a_src) {
38133         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38134       }
38135       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
38136       status = wuffs_gif__decoder__decode_gc(self, a_src);
38137       if (a_src) {
38138         iop_a_src = a_src->data.ptr + a_src->meta.ri;
38139       }
38140       if (status.repr) {
38141         goto suspend;
38142       }
38143       status = wuffs_base__make_status(NULL);
38144       goto ok;
38145     } else if (v_label == 255u) {
38146       if (a_src) {
38147         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38148       }
38149       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
38150       status = wuffs_gif__decoder__decode_ae(self, a_src);
38151       if (a_src) {
38152         iop_a_src = a_src->data.ptr + a_src->meta.ri;
38153       }
38154       if (status.repr) {
38155         goto suspend;
38156       }
38157       status = wuffs_base__make_status(NULL);
38158       goto ok;
38159     }
38160     if (a_src) {
38161       a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38162     }
38163     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
38164     status = wuffs_gif__decoder__skip_blocks(self, a_src);
38165     if (a_src) {
38166       iop_a_src = a_src->data.ptr + a_src->meta.ri;
38167     }
38168     if (status.repr) {
38169       goto suspend;
38170     }
38171 
38172     ok:
38173     self->private_impl.p_decode_extension[0] = 0;
38174     goto exit;
38175   }
38176 
38177   goto suspend;
38178   suspend:
38179   self->private_impl.p_decode_extension[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
38180 
38181   goto exit;
38182   exit:
38183   if (a_src && a_src->data.ptr) {
38184     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38185   }
38186 
38187   return status;
38188 }
38189 
38190 // -------- func gif.decoder.skip_blocks
38191 
38192 WUFFS_BASE__GENERATED_C_CODE
38193 static wuffs_base__status
wuffs_gif__decoder__skip_blocks(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)38194 wuffs_gif__decoder__skip_blocks(
38195     wuffs_gif__decoder* self,
38196     wuffs_base__io_buffer* a_src) {
38197   wuffs_base__status status = wuffs_base__make_status(NULL);
38198 
38199   uint8_t v_block_size = 0;
38200 
38201   const uint8_t* iop_a_src = NULL;
38202   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38203   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38204   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38205   if (a_src && a_src->data.ptr) {
38206     io0_a_src = a_src->data.ptr;
38207     io1_a_src = io0_a_src + a_src->meta.ri;
38208     iop_a_src = io1_a_src;
38209     io2_a_src = io0_a_src + a_src->meta.wi;
38210   }
38211 
38212   uint32_t coro_susp_point = self->private_impl.p_skip_blocks[0];
38213   switch (coro_susp_point) {
38214     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
38215 
38216     while (true) {
38217       {
38218         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
38219         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38220           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38221           goto suspend;
38222         }
38223         uint8_t t_0 = *iop_a_src++;
38224         v_block_size = t_0;
38225       }
38226       if (v_block_size == 0u) {
38227         status = wuffs_base__make_status(NULL);
38228         goto ok;
38229       }
38230       self->private_data.s_skip_blocks[0].scratch = ((uint32_t)(v_block_size));
38231       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
38232       if (self->private_data.s_skip_blocks[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
38233         self->private_data.s_skip_blocks[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
38234         iop_a_src = io2_a_src;
38235         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38236         goto suspend;
38237       }
38238       iop_a_src += self->private_data.s_skip_blocks[0].scratch;
38239     }
38240 
38241     ok:
38242     self->private_impl.p_skip_blocks[0] = 0;
38243     goto exit;
38244   }
38245 
38246   goto suspend;
38247   suspend:
38248   self->private_impl.p_skip_blocks[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
38249 
38250   goto exit;
38251   exit:
38252   if (a_src && a_src->data.ptr) {
38253     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38254   }
38255 
38256   return status;
38257 }
38258 
38259 // -------- func gif.decoder.decode_ae
38260 
38261 WUFFS_BASE__GENERATED_C_CODE
38262 static wuffs_base__status
wuffs_gif__decoder__decode_ae(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)38263 wuffs_gif__decoder__decode_ae(
38264     wuffs_gif__decoder* self,
38265     wuffs_base__io_buffer* a_src) {
38266   wuffs_base__status status = wuffs_base__make_status(NULL);
38267 
38268   uint8_t v_c = 0;
38269   uint8_t v_block_size = 0;
38270   bool v_is_animexts = false;
38271   bool v_is_netscape = false;
38272   bool v_is_iccp = false;
38273   bool v_is_xmp = false;
38274 
38275   const uint8_t* iop_a_src = NULL;
38276   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38277   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38278   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38279   if (a_src && a_src->data.ptr) {
38280     io0_a_src = a_src->data.ptr;
38281     io1_a_src = io0_a_src + a_src->meta.ri;
38282     iop_a_src = io1_a_src;
38283     io2_a_src = io0_a_src + a_src->meta.wi;
38284   }
38285 
38286   uint32_t coro_susp_point = self->private_impl.p_decode_ae[0];
38287   if (coro_susp_point) {
38288     v_block_size = self->private_data.s_decode_ae[0].v_block_size;
38289     v_is_animexts = self->private_data.s_decode_ae[0].v_is_animexts;
38290     v_is_netscape = self->private_data.s_decode_ae[0].v_is_netscape;
38291     v_is_iccp = self->private_data.s_decode_ae[0].v_is_iccp;
38292     v_is_xmp = self->private_data.s_decode_ae[0].v_is_xmp;
38293   }
38294   switch (coro_susp_point) {
38295     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
38296 
38297     do {
38298       if (self->private_impl.f_metadata_fourcc != 0u) {
38299         status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
38300         goto ok;
38301       }
38302       {
38303         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
38304         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38305           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38306           goto suspend;
38307         }
38308         uint8_t t_0 = *iop_a_src++;
38309         v_block_size = t_0;
38310       }
38311       if (v_block_size == 0u) {
38312         status = wuffs_base__make_status(NULL);
38313         goto ok;
38314       }
38315       if (v_block_size != 11u) {
38316         self->private_data.s_decode_ae[0].scratch = ((uint32_t)(v_block_size));
38317         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
38318         if (self->private_data.s_decode_ae[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
38319           self->private_data.s_decode_ae[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
38320           iop_a_src = io2_a_src;
38321           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38322           goto suspend;
38323         }
38324         iop_a_src += self->private_data.s_decode_ae[0].scratch;
38325         break;
38326       }
38327       v_is_animexts = true;
38328       v_is_netscape = true;
38329       v_is_iccp = true;
38330       v_is_xmp = true;
38331       v_block_size = 0u;
38332       while (v_block_size < 11u) {
38333         {
38334           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
38335           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38336             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38337             goto suspend;
38338           }
38339           uint8_t t_1 = *iop_a_src++;
38340           v_c = t_1;
38341         }
38342         v_is_animexts = (v_is_animexts && (v_c == WUFFS_GIF__ANIMEXTS1DOT0[v_block_size]));
38343         v_is_netscape = (v_is_netscape && (v_c == WUFFS_GIF__NETSCAPE2DOT0[v_block_size]));
38344         v_is_iccp = (v_is_iccp && (v_c == WUFFS_GIF__ICCRGBG1012[v_block_size]));
38345         v_is_xmp = (v_is_xmp && (v_c == WUFFS_GIF__XMPDATAXMP[v_block_size]));
38346 #if defined(__GNUC__)
38347 #pragma GCC diagnostic push
38348 #pragma GCC diagnostic ignored "-Wconversion"
38349 #endif
38350         v_block_size += 1u;
38351 #if defined(__GNUC__)
38352 #pragma GCC diagnostic pop
38353 #endif
38354       }
38355       if (v_is_animexts || v_is_netscape) {
38356         {
38357           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
38358           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38359             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38360             goto suspend;
38361           }
38362           uint8_t t_2 = *iop_a_src++;
38363           v_block_size = t_2;
38364         }
38365         if (v_block_size != 3u) {
38366           self->private_data.s_decode_ae[0].scratch = ((uint32_t)(v_block_size));
38367           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
38368           if (self->private_data.s_decode_ae[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
38369             self->private_data.s_decode_ae[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
38370             iop_a_src = io2_a_src;
38371             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38372             goto suspend;
38373           }
38374           iop_a_src += self->private_data.s_decode_ae[0].scratch;
38375           break;
38376         }
38377         {
38378           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
38379           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38380             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38381             goto suspend;
38382           }
38383           uint8_t t_3 = *iop_a_src++;
38384           v_c = t_3;
38385         }
38386         if (v_c != 1u) {
38387           self->private_data.s_decode_ae[0].scratch = 2u;
38388           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
38389           if (self->private_data.s_decode_ae[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
38390             self->private_data.s_decode_ae[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
38391             iop_a_src = io2_a_src;
38392             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38393             goto suspend;
38394           }
38395           iop_a_src += self->private_data.s_decode_ae[0].scratch;
38396           break;
38397         }
38398         {
38399           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
38400           uint32_t t_4;
38401           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
38402             t_4 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
38403             iop_a_src += 2;
38404           } else {
38405             self->private_data.s_decode_ae[0].scratch = 0;
38406             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
38407             while (true) {
38408               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38409                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38410                 goto suspend;
38411               }
38412               uint64_t* scratch = &self->private_data.s_decode_ae[0].scratch;
38413               uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
38414               *scratch <<= 8;
38415               *scratch >>= 8;
38416               *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
38417               if (num_bits_4 == 8) {
38418                 t_4 = ((uint32_t)(*scratch));
38419                 break;
38420               }
38421               num_bits_4 += 8u;
38422               *scratch |= ((uint64_t)(num_bits_4)) << 56;
38423             }
38424           }
38425           self->private_impl.f_num_animation_loops_value = t_4;
38426         }
38427         self->private_impl.f_seen_num_animation_loops_value = true;
38428         if ((0u < self->private_impl.f_num_animation_loops_value) && (self->private_impl.f_num_animation_loops_value <= 65535u)) {
38429           self->private_impl.f_num_animation_loops_value += 1u;
38430         }
38431       } else if (self->private_impl.f_call_sequence >= 32u) {
38432       } else if (v_is_iccp && self->private_impl.f_report_metadata_iccp) {
38433         self->private_impl.f_metadata_fourcc = 1229144912u;
38434         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)));
38435         self->private_impl.f_call_sequence = 16u;
38436         status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
38437         goto ok;
38438       } else if (v_is_xmp && self->private_impl.f_report_metadata_xmp) {
38439         self->private_impl.f_metadata_fourcc = 1481461792u;
38440         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)));
38441         self->private_impl.f_call_sequence = 16u;
38442         status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
38443         goto ok;
38444       }
38445     } while (0);
38446     if (a_src) {
38447       a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38448     }
38449     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
38450     status = wuffs_gif__decoder__skip_blocks(self, a_src);
38451     if (a_src) {
38452       iop_a_src = a_src->data.ptr + a_src->meta.ri;
38453     }
38454     if (status.repr) {
38455       goto suspend;
38456     }
38457 
38458     ok:
38459     self->private_impl.p_decode_ae[0] = 0;
38460     goto exit;
38461   }
38462 
38463   goto suspend;
38464   suspend:
38465   self->private_impl.p_decode_ae[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
38466   self->private_data.s_decode_ae[0].v_block_size = v_block_size;
38467   self->private_data.s_decode_ae[0].v_is_animexts = v_is_animexts;
38468   self->private_data.s_decode_ae[0].v_is_netscape = v_is_netscape;
38469   self->private_data.s_decode_ae[0].v_is_iccp = v_is_iccp;
38470   self->private_data.s_decode_ae[0].v_is_xmp = v_is_xmp;
38471 
38472   goto exit;
38473   exit:
38474   if (a_src && a_src->data.ptr) {
38475     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38476   }
38477 
38478   return status;
38479 }
38480 
38481 // -------- func gif.decoder.decode_gc
38482 
38483 WUFFS_BASE__GENERATED_C_CODE
38484 static wuffs_base__status
wuffs_gif__decoder__decode_gc(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)38485 wuffs_gif__decoder__decode_gc(
38486     wuffs_gif__decoder* self,
38487     wuffs_base__io_buffer* a_src) {
38488   wuffs_base__status status = wuffs_base__make_status(NULL);
38489 
38490   uint8_t v_c = 0;
38491   uint8_t v_flags = 0;
38492   uint16_t v_gc_duration_centiseconds = 0;
38493 
38494   const uint8_t* iop_a_src = NULL;
38495   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38496   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38497   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38498   if (a_src && a_src->data.ptr) {
38499     io0_a_src = a_src->data.ptr;
38500     io1_a_src = io0_a_src + a_src->meta.ri;
38501     iop_a_src = io1_a_src;
38502     io2_a_src = io0_a_src + a_src->meta.wi;
38503   }
38504 
38505   uint32_t coro_susp_point = self->private_impl.p_decode_gc[0];
38506   switch (coro_susp_point) {
38507     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
38508 
38509     {
38510       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
38511       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38512         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38513         goto suspend;
38514       }
38515       uint8_t t_0 = *iop_a_src++;
38516       v_c = t_0;
38517     }
38518     if (v_c != 4u) {
38519       status = wuffs_base__make_status(wuffs_gif__error__bad_graphic_control);
38520       goto exit;
38521     }
38522     {
38523       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
38524       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38525         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38526         goto suspend;
38527       }
38528       uint8_t t_1 = *iop_a_src++;
38529       v_flags = t_1;
38530     }
38531     self->private_impl.f_gc_has_transparent_index = ((v_flags & 1u) != 0u);
38532     v_flags = ((v_flags >> 2u) & 7u);
38533     if (v_flags == 2u) {
38534       self->private_impl.f_gc_disposal = 1u;
38535     } else if ((v_flags == 3u) || (v_flags == 4u)) {
38536       self->private_impl.f_gc_disposal = 2u;
38537     } else {
38538       self->private_impl.f_gc_disposal = 0u;
38539     }
38540     {
38541       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
38542       uint16_t t_2;
38543       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
38544         t_2 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src);
38545         iop_a_src += 2;
38546       } else {
38547         self->private_data.s_decode_gc[0].scratch = 0;
38548         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
38549         while (true) {
38550           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38551             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38552             goto suspend;
38553           }
38554           uint64_t* scratch = &self->private_data.s_decode_gc[0].scratch;
38555           uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
38556           *scratch <<= 8;
38557           *scratch >>= 8;
38558           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
38559           if (num_bits_2 == 8) {
38560             t_2 = ((uint16_t)(*scratch));
38561             break;
38562           }
38563           num_bits_2 += 8u;
38564           *scratch |= ((uint64_t)(num_bits_2)) << 56;
38565         }
38566       }
38567       v_gc_duration_centiseconds = t_2;
38568     }
38569     self->private_impl.f_gc_duration = (((uint64_t)(v_gc_duration_centiseconds)) * 7056000u);
38570     {
38571       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
38572       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38573         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38574         goto suspend;
38575       }
38576       uint8_t t_3 = *iop_a_src++;
38577       self->private_impl.f_gc_transparent_index = t_3;
38578     }
38579     {
38580       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
38581       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38582         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38583         goto suspend;
38584       }
38585       uint8_t t_4 = *iop_a_src++;
38586       v_c = t_4;
38587     }
38588     if (v_c != 0u) {
38589       status = wuffs_base__make_status(wuffs_gif__error__bad_graphic_control);
38590       goto exit;
38591     }
38592 
38593     goto ok;
38594     ok:
38595     self->private_impl.p_decode_gc[0] = 0;
38596     goto exit;
38597   }
38598 
38599   goto suspend;
38600   suspend:
38601   self->private_impl.p_decode_gc[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
38602 
38603   goto exit;
38604   exit:
38605   if (a_src && a_src->data.ptr) {
38606     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38607   }
38608 
38609   return status;
38610 }
38611 
38612 // -------- func gif.decoder.decode_id_part0
38613 
38614 WUFFS_BASE__GENERATED_C_CODE
38615 static wuffs_base__status
wuffs_gif__decoder__decode_id_part0(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)38616 wuffs_gif__decoder__decode_id_part0(
38617     wuffs_gif__decoder* self,
38618     wuffs_base__io_buffer* a_src) {
38619   wuffs_base__status status = wuffs_base__make_status(NULL);
38620 
38621   const uint8_t* iop_a_src = NULL;
38622   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38623   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38624   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38625   if (a_src && a_src->data.ptr) {
38626     io0_a_src = a_src->data.ptr;
38627     io1_a_src = io0_a_src + a_src->meta.ri;
38628     iop_a_src = io1_a_src;
38629     io2_a_src = io0_a_src + a_src->meta.wi;
38630   }
38631 
38632   uint32_t coro_susp_point = self->private_impl.p_decode_id_part0[0];
38633   switch (coro_susp_point) {
38634     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
38635 
38636     {
38637       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
38638       uint32_t t_0;
38639       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
38640         t_0 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
38641         iop_a_src += 2;
38642       } else {
38643         self->private_data.s_decode_id_part0[0].scratch = 0;
38644         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
38645         while (true) {
38646           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38647             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38648             goto suspend;
38649           }
38650           uint64_t* scratch = &self->private_data.s_decode_id_part0[0].scratch;
38651           uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
38652           *scratch <<= 8;
38653           *scratch >>= 8;
38654           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
38655           if (num_bits_0 == 8) {
38656             t_0 = ((uint32_t)(*scratch));
38657             break;
38658           }
38659           num_bits_0 += 8u;
38660           *scratch |= ((uint64_t)(num_bits_0)) << 56;
38661         }
38662       }
38663       self->private_impl.f_frame_rect_x0 = t_0;
38664     }
38665     {
38666       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
38667       uint32_t t_1;
38668       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
38669         t_1 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
38670         iop_a_src += 2;
38671       } else {
38672         self->private_data.s_decode_id_part0[0].scratch = 0;
38673         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
38674         while (true) {
38675           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38676             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38677             goto suspend;
38678           }
38679           uint64_t* scratch = &self->private_data.s_decode_id_part0[0].scratch;
38680           uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
38681           *scratch <<= 8;
38682           *scratch >>= 8;
38683           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
38684           if (num_bits_1 == 8) {
38685             t_1 = ((uint32_t)(*scratch));
38686             break;
38687           }
38688           num_bits_1 += 8u;
38689           *scratch |= ((uint64_t)(num_bits_1)) << 56;
38690         }
38691       }
38692       self->private_impl.f_frame_rect_y0 = t_1;
38693     }
38694     {
38695       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
38696       uint32_t t_2;
38697       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
38698         t_2 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
38699         iop_a_src += 2;
38700       } else {
38701         self->private_data.s_decode_id_part0[0].scratch = 0;
38702         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
38703         while (true) {
38704           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38705             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38706             goto suspend;
38707           }
38708           uint64_t* scratch = &self->private_data.s_decode_id_part0[0].scratch;
38709           uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
38710           *scratch <<= 8;
38711           *scratch >>= 8;
38712           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
38713           if (num_bits_2 == 8) {
38714             t_2 = ((uint32_t)(*scratch));
38715             break;
38716           }
38717           num_bits_2 += 8u;
38718           *scratch |= ((uint64_t)(num_bits_2)) << 56;
38719         }
38720       }
38721       self->private_impl.f_frame_rect_x1 = t_2;
38722     }
38723     self->private_impl.f_frame_rect_x1 += self->private_impl.f_frame_rect_x0;
38724     {
38725       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
38726       uint32_t t_3;
38727       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
38728         t_3 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
38729         iop_a_src += 2;
38730       } else {
38731         self->private_data.s_decode_id_part0[0].scratch = 0;
38732         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
38733         while (true) {
38734           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38735             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38736             goto suspend;
38737           }
38738           uint64_t* scratch = &self->private_data.s_decode_id_part0[0].scratch;
38739           uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56));
38740           *scratch <<= 8;
38741           *scratch >>= 8;
38742           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3;
38743           if (num_bits_3 == 8) {
38744             t_3 = ((uint32_t)(*scratch));
38745             break;
38746           }
38747           num_bits_3 += 8u;
38748           *scratch |= ((uint64_t)(num_bits_3)) << 56;
38749         }
38750       }
38751       self->private_impl.f_frame_rect_y1 = t_3;
38752     }
38753     self->private_impl.f_frame_rect_y1 += self->private_impl.f_frame_rect_y0;
38754     self->private_impl.f_dst_x = self->private_impl.f_frame_rect_x0;
38755     self->private_impl.f_dst_y = self->private_impl.f_frame_rect_y0;
38756     if ((self->private_impl.f_num_decoded_frame_configs_value == 0u) &&  ! self->private_impl.f_quirks[4u]) {
38757       self->private_impl.f_width = wuffs_base__u32__max(self->private_impl.f_width, self->private_impl.f_frame_rect_x1);
38758       self->private_impl.f_height = wuffs_base__u32__max(self->private_impl.f_height, self->private_impl.f_frame_rect_y1);
38759     }
38760 
38761     goto ok;
38762     ok:
38763     self->private_impl.p_decode_id_part0[0] = 0;
38764     goto exit;
38765   }
38766 
38767   goto suspend;
38768   suspend:
38769   self->private_impl.p_decode_id_part0[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
38770 
38771   goto exit;
38772   exit:
38773   if (a_src && a_src->data.ptr) {
38774     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38775   }
38776 
38777   return status;
38778 }
38779 
38780 // -------- func gif.decoder.decode_id_part1
38781 
38782 WUFFS_BASE__GENERATED_C_CODE
38783 static wuffs_base__status
wuffs_gif__decoder__decode_id_part1(wuffs_gif__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__pixel_blend a_blend)38784 wuffs_gif__decoder__decode_id_part1(
38785     wuffs_gif__decoder* self,
38786     wuffs_base__pixel_buffer* a_dst,
38787     wuffs_base__io_buffer* a_src,
38788     wuffs_base__pixel_blend a_blend) {
38789   wuffs_base__status status = wuffs_base__make_status(NULL);
38790 
38791   uint8_t v_flags = 0;
38792   uint8_t v_which_palette = 0;
38793   uint32_t v_num_palette_entries = 0;
38794   uint32_t v_i = 0;
38795   uint32_t v_argb = 0;
38796   wuffs_base__status v_status = wuffs_base__make_status(NULL);
38797   uint8_t v_lw = 0;
38798 
38799   const uint8_t* iop_a_src = NULL;
38800   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38801   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38802   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38803   if (a_src && a_src->data.ptr) {
38804     io0_a_src = a_src->data.ptr;
38805     io1_a_src = io0_a_src + a_src->meta.ri;
38806     iop_a_src = io1_a_src;
38807     io2_a_src = io0_a_src + a_src->meta.wi;
38808   }
38809 
38810   uint32_t coro_susp_point = self->private_impl.p_decode_id_part1[0];
38811   if (coro_susp_point) {
38812     v_which_palette = self->private_data.s_decode_id_part1[0].v_which_palette;
38813     v_num_palette_entries = self->private_data.s_decode_id_part1[0].v_num_palette_entries;
38814     v_i = self->private_data.s_decode_id_part1[0].v_i;
38815   }
38816   switch (coro_susp_point) {
38817     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
38818 
38819     {
38820       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
38821       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38822         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38823         goto suspend;
38824       }
38825       uint8_t t_0 = *iop_a_src++;
38826       v_flags = t_0;
38827     }
38828     if ((v_flags & 64u) != 0u) {
38829       self->private_impl.f_interlace = 4u;
38830     } else {
38831       self->private_impl.f_interlace = 0u;
38832     }
38833     v_which_palette = 1u;
38834     if ((v_flags & 128u) != 0u) {
38835       v_num_palette_entries = (((uint32_t)(1u)) << (1u + (v_flags & 7u)));
38836       v_i = 0u;
38837       while (v_i < v_num_palette_entries) {
38838         {
38839           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
38840           uint32_t t_1;
38841           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) {
38842             t_1 = ((uint32_t)(wuffs_base__peek_u24be__no_bounds_check(iop_a_src)));
38843             iop_a_src += 3;
38844           } else {
38845             self->private_data.s_decode_id_part1[0].scratch = 0;
38846             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
38847             while (true) {
38848               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38849                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38850                 goto suspend;
38851               }
38852               uint64_t* scratch = &self->private_data.s_decode_id_part1[0].scratch;
38853               uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu));
38854               *scratch >>= 8;
38855               *scratch <<= 8;
38856               *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
38857               if (num_bits_1 == 16) {
38858                 t_1 = ((uint32_t)(*scratch >> 40));
38859                 break;
38860               }
38861               num_bits_1 += 8u;
38862               *scratch |= ((uint64_t)(num_bits_1));
38863             }
38864           }
38865           v_argb = t_1;
38866         }
38867         v_argb |= 4278190080u;
38868         self->private_data.f_palettes[1u][((4u * v_i) + 0u)] = ((uint8_t)((v_argb >> 0u)));
38869         self->private_data.f_palettes[1u][((4u * v_i) + 1u)] = ((uint8_t)((v_argb >> 8u)));
38870         self->private_data.f_palettes[1u][((4u * v_i) + 2u)] = ((uint8_t)((v_argb >> 16u)));
38871         self->private_data.f_palettes[1u][((4u * v_i) + 3u)] = ((uint8_t)((v_argb >> 24u)));
38872         v_i += 1u;
38873       }
38874       while (v_i < 256u) {
38875         self->private_data.f_palettes[1u][((4u * v_i) + 0u)] = 0u;
38876         self->private_data.f_palettes[1u][((4u * v_i) + 1u)] = 0u;
38877         self->private_data.f_palettes[1u][((4u * v_i) + 2u)] = 0u;
38878         self->private_data.f_palettes[1u][((4u * v_i) + 3u)] = 255u;
38879         v_i += 1u;
38880       }
38881     } else if (self->private_impl.f_quirks[6u] &&  ! self->private_impl.f_has_global_palette) {
38882       status = wuffs_base__make_status(wuffs_gif__error__bad_palette);
38883       goto exit;
38884     } else if (self->private_impl.f_gc_has_transparent_index) {
38885       wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8(self->private_data.f_palettes[1u], 1024), wuffs_base__make_slice_u8(self->private_data.f_palettes[0u], 1024));
38886     } else {
38887       v_which_palette = 0u;
38888     }
38889     if (self->private_impl.f_gc_has_transparent_index) {
38890       self->private_data.f_palettes[1u][((4u * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 0u)] = 0u;
38891       self->private_data.f_palettes[1u][((4u * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 1u)] = 0u;
38892       self->private_data.f_palettes[1u][((4u * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 2u)] = 0u;
38893       self->private_data.f_palettes[1u][((4u * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 3u)] = 0u;
38894     }
38895     v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
38896         wuffs_base__pixel_buffer__pixel_format(a_dst),
38897         wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)),
38898         wuffs_base__utility__make_pixel_format(2198077448u),
38899         wuffs_base__make_slice_u8(self->private_data.f_palettes[v_which_palette], 1024),
38900         a_blend);
38901     if ( ! wuffs_base__status__is_ok(&v_status)) {
38902       status = v_status;
38903       if (wuffs_base__status__is_error(&status)) {
38904         goto exit;
38905       } else if (wuffs_base__status__is_suspension(&status)) {
38906         status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
38907         goto exit;
38908       }
38909       goto ok;
38910     }
38911     if (self->private_impl.f_ignored_but_affects_benchmarks) {
38912     }
38913     {
38914       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
38915       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38916         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38917         goto suspend;
38918       }
38919       uint8_t t_2 = *iop_a_src++;
38920       v_lw = t_2;
38921     }
38922     if (v_lw > 8u) {
38923       status = wuffs_base__make_status(wuffs_gif__error__bad_literal_width);
38924       goto exit;
38925     }
38926     self->private_impl.f_lzw_pending_literal_width_plus_one = ((uint32_t)((1u + v_lw)));
38927     self->private_impl.f_ignored_but_affects_benchmarks = true;
38928 
38929     ok:
38930     self->private_impl.p_decode_id_part1[0] = 0;
38931     goto exit;
38932   }
38933 
38934   goto suspend;
38935   suspend:
38936   self->private_impl.p_decode_id_part1[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
38937   self->private_data.s_decode_id_part1[0].v_which_palette = v_which_palette;
38938   self->private_data.s_decode_id_part1[0].v_num_palette_entries = v_num_palette_entries;
38939   self->private_data.s_decode_id_part1[0].v_i = v_i;
38940 
38941   goto exit;
38942   exit:
38943   if (a_src && a_src->data.ptr) {
38944     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38945   }
38946 
38947   return status;
38948 }
38949 
38950 // -------- func gif.decoder.decode_id_part2
38951 
38952 WUFFS_BASE__GENERATED_C_CODE
38953 static wuffs_base__status
wuffs_gif__decoder__decode_id_part2(wuffs_gif__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__slice_u8 a_workbuf)38954 wuffs_gif__decoder__decode_id_part2(
38955     wuffs_gif__decoder* self,
38956     wuffs_base__pixel_buffer* a_dst,
38957     wuffs_base__io_buffer* a_src,
38958     wuffs_base__slice_u8 a_workbuf) {
38959   wuffs_base__status status = wuffs_base__make_status(NULL);
38960 
38961   uint64_t v_block_size = 0;
38962   bool v_need_block_size = false;
38963   uint32_t v_n_copied = 0;
38964   uint64_t v_n_compressed = 0;
38965   wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer();
38966   wuffs_base__io_buffer* v_r = &u_r;
38967   const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38968   const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38969   const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38970   const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38971   uint64_t v_mark = 0;
38972   wuffs_base__status v_copy_status = wuffs_base__make_status(NULL);
38973 
38974   const uint8_t* iop_a_src = NULL;
38975   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38976   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38977   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38978   if (a_src && a_src->data.ptr) {
38979     io0_a_src = a_src->data.ptr;
38980     io1_a_src = io0_a_src + a_src->meta.ri;
38981     iop_a_src = io1_a_src;
38982     io2_a_src = io0_a_src + a_src->meta.wi;
38983   }
38984 
38985   uint32_t coro_susp_point = self->private_impl.p_decode_id_part2[0];
38986   if (coro_susp_point) {
38987     v_block_size = self->private_data.s_decode_id_part2[0].v_block_size;
38988     v_need_block_size = self->private_data.s_decode_id_part2[0].v_need_block_size;
38989   }
38990   switch (coro_susp_point) {
38991     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
38992 
38993     wuffs_gif__decoder__lzw_init(self);
38994     v_need_block_size = true;
38995     label__outer__continue:;
38996     while (true) {
38997       if (v_need_block_size) {
38998         v_need_block_size = false;
38999         {
39000           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
39001           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39002             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39003             goto suspend;
39004           }
39005           uint64_t t_0 = *iop_a_src++;
39006           v_block_size = t_0;
39007         }
39008       }
39009       if (v_block_size == 0u) {
39010         break;
39011       }
39012       while (((uint64_t)(io2_a_src - iop_a_src)) == 0u) {
39013         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39014         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
39015       }
39016       if (self->private_impl.f_compressed_ri == self->private_impl.f_compressed_wi) {
39017         self->private_impl.f_compressed_ri = 0u;
39018         self->private_impl.f_compressed_wi = 0u;
39019       }
39020       while (self->private_impl.f_compressed_wi <= 3841u) {
39021         v_n_compressed = wuffs_base__u64__min(v_block_size, ((uint64_t)(io2_a_src - iop_a_src)));
39022         if (v_n_compressed <= 0u) {
39023           break;
39024         }
39025         v_n_copied = wuffs_base__io_reader__limited_copy_u32_to_slice(
39026             &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));
39027         wuffs_base__u64__sat_add_indirect(&self->private_impl.f_compressed_wi, ((uint64_t)(v_n_copied)));
39028         wuffs_base__u64__sat_sub_indirect(&v_block_size, ((uint64_t)(v_n_copied)));
39029         if (v_block_size > 0u) {
39030           break;
39031         }
39032         if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
39033           v_need_block_size = true;
39034           break;
39035         }
39036         v_block_size = ((uint64_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src)));
39037         iop_a_src += 1u;
39038       }
39039       while (true) {
39040         if ((self->private_impl.f_compressed_ri > self->private_impl.f_compressed_wi) || (self->private_impl.f_compressed_wi > 4096u)) {
39041           status = wuffs_base__make_status(wuffs_gif__error__internal_error_inconsistent_i_o);
39042           goto exit;
39043         }
39044         {
39045           wuffs_base__io_buffer* o_0_v_r = v_r;
39046           const uint8_t *o_0_iop_v_r = iop_v_r;
39047           const uint8_t *o_0_io0_v_r = io0_v_r;
39048           const uint8_t *o_0_io1_v_r = io1_v_r;
39049           const uint8_t *o_0_io2_v_r = io2_v_r;
39050           v_r = wuffs_base__io_reader__set(
39051               &u_r,
39052               &iop_v_r,
39053               &io0_v_r,
39054               &io1_v_r,
39055               &io2_v_r,
39056               wuffs_base__make_slice_u8_ij(self->private_data.f_compressed,
39057               self->private_impl.f_compressed_ri,
39058               self->private_impl.f_compressed_wi),
39059               0u);
39060           v_mark = ((uint64_t)(iop_v_r - io0_v_r));
39061           u_r.meta.ri = ((size_t)(iop_v_r - u_r.data.ptr));
39062           wuffs_gif__decoder__lzw_read_from(self, v_r);
39063           iop_v_r = u_r.data.ptr + u_r.meta.ri;
39064           wuffs_base__u64__sat_add_indirect(&self->private_impl.f_compressed_ri, wuffs_base__io__count_since(v_mark, ((uint64_t)(iop_v_r - io0_v_r))));
39065           v_r = o_0_v_r;
39066           iop_v_r = o_0_iop_v_r;
39067           io0_v_r = o_0_io0_v_r;
39068           io1_v_r = o_0_io1_v_r;
39069           io2_v_r = o_0_io2_v_r;
39070         }
39071         if (self->private_impl.f_lzw_output_ri < self->private_impl.f_lzw_output_wi) {
39072           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,
39073               self->private_impl.f_lzw_output_ri,
39074               self->private_impl.f_lzw_output_wi));
39075           if (wuffs_base__status__is_error(&v_copy_status)) {
39076             status = v_copy_status;
39077             goto exit;
39078           }
39079           self->private_impl.f_lzw_output_ri = 0u;
39080           self->private_impl.f_lzw_output_wi = 0u;
39081         }
39082         if (self->private_impl.f_lzw_read_from_return_value == 0u) {
39083           self->private_impl.f_ignored_but_affects_benchmarks = false;
39084           if (v_need_block_size || (v_block_size > 0u)) {
39085             self->private_data.s_decode_id_part2[0].scratch = ((uint32_t)(v_block_size));
39086             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
39087             if (self->private_data.s_decode_id_part2[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
39088               self->private_data.s_decode_id_part2[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
39089               iop_a_src = io2_a_src;
39090               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39091               goto suspend;
39092             }
39093             iop_a_src += self->private_data.s_decode_id_part2[0].scratch;
39094             if (a_src) {
39095               a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
39096             }
39097             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
39098             status = wuffs_gif__decoder__skip_blocks(self, a_src);
39099             if (a_src) {
39100               iop_a_src = a_src->data.ptr + a_src->meta.ri;
39101             }
39102             if (status.repr) {
39103               goto suspend;
39104             }
39105           }
39106           goto label__outer__break;
39107         } else if (self->private_impl.f_lzw_read_from_return_value == 1u) {
39108           continue;
39109         } else if (self->private_impl.f_lzw_read_from_return_value == 2u) {
39110           goto label__outer__continue;
39111         } 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)) {
39112           if (v_need_block_size || (v_block_size > 0u)) {
39113             self->private_data.s_decode_id_part2[0].scratch = ((uint32_t)(v_block_size));
39114             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
39115             if (self->private_data.s_decode_id_part2[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
39116               self->private_data.s_decode_id_part2[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
39117               iop_a_src = io2_a_src;
39118               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39119               goto suspend;
39120             }
39121             iop_a_src += self->private_data.s_decode_id_part2[0].scratch;
39122             if (a_src) {
39123               a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
39124             }
39125             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
39126             status = wuffs_gif__decoder__skip_blocks(self, a_src);
39127             if (a_src) {
39128               iop_a_src = a_src->data.ptr + a_src->meta.ri;
39129             }
39130             if (status.repr) {
39131               goto suspend;
39132             }
39133           }
39134           goto label__outer__break;
39135         } else if (self->private_impl.f_lzw_read_from_return_value == 3u) {
39136           status = wuffs_base__make_status(wuffs_gif__error__truncated_input);
39137           goto exit;
39138         } else if (self->private_impl.f_lzw_read_from_return_value == 4u) {
39139           status = wuffs_base__make_status(wuffs_gif__error__bad_lzw_code);
39140           goto exit;
39141         }
39142         status = wuffs_base__make_status(wuffs_gif__error__internal_error_inconsistent_i_o);
39143         goto exit;
39144       }
39145     }
39146     label__outer__break:;
39147     self->private_impl.f_compressed_ri = 0u;
39148     self->private_impl.f_compressed_wi = 0u;
39149     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)) {
39150       status = wuffs_base__make_status(wuffs_base__error__not_enough_data);
39151       goto exit;
39152     }
39153 
39154     ok:
39155     self->private_impl.p_decode_id_part2[0] = 0;
39156     goto exit;
39157   }
39158 
39159   goto suspend;
39160   suspend:
39161   self->private_impl.p_decode_id_part2[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
39162   self->private_data.s_decode_id_part2[0].v_block_size = v_block_size;
39163   self->private_data.s_decode_id_part2[0].v_need_block_size = v_need_block_size;
39164 
39165   goto exit;
39166   exit:
39167   if (a_src && a_src->data.ptr) {
39168     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
39169   }
39170 
39171   return status;
39172 }
39173 
39174 // -------- func gif.decoder.copy_to_image_buffer
39175 
39176 WUFFS_BASE__GENERATED_C_CODE
39177 static wuffs_base__status
wuffs_gif__decoder__copy_to_image_buffer(wuffs_gif__decoder * self,wuffs_base__pixel_buffer * a_pb,wuffs_base__slice_u8 a_src)39178 wuffs_gif__decoder__copy_to_image_buffer(
39179     wuffs_gif__decoder* self,
39180     wuffs_base__pixel_buffer* a_pb,
39181     wuffs_base__slice_u8 a_src) {
39182   wuffs_base__slice_u8 v_dst = {0};
39183   wuffs_base__slice_u8 v_src = {0};
39184   uint64_t v_width_in_bytes = 0;
39185   uint64_t v_n = 0;
39186   uint64_t v_src_ri = 0;
39187   wuffs_base__pixel_format v_pixfmt = {0};
39188   uint32_t v_bytes_per_pixel = 0;
39189   uint32_t v_bits_per_pixel = 0;
39190   wuffs_base__table_u8 v_tab = {0};
39191   uint64_t v_i = 0;
39192   uint64_t v_j = 0;
39193   uint32_t v_replicate_y0 = 0;
39194   uint32_t v_replicate_y1 = 0;
39195   wuffs_base__slice_u8 v_replicate_dst = {0};
39196   wuffs_base__slice_u8 v_replicate_src = {0};
39197 
39198   v_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_pb);
39199   v_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_pixfmt);
39200   if ((v_bits_per_pixel & 7u) != 0u) {
39201     return wuffs_base__make_status(wuffs_base__error__unsupported_option);
39202   }
39203   v_bytes_per_pixel = (v_bits_per_pixel >> 3u);
39204   v_width_in_bytes = ((uint64_t)((self->private_impl.f_width * v_bytes_per_pixel)));
39205   v_tab = wuffs_base__pixel_buffer__plane(a_pb, 0u);
39206   while (v_src_ri < ((uint64_t)(a_src.len))) {
39207     v_src = wuffs_base__slice_u8__subslice_i(a_src, v_src_ri);
39208     if (self->private_impl.f_dst_y >= self->private_impl.f_frame_rect_y1) {
39209       if (self->private_impl.f_quirks[3u]) {
39210         return wuffs_base__make_status(NULL);
39211       }
39212       return wuffs_base__make_status(wuffs_base__error__too_much_data);
39213     }
39214     v_dst = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
39215     if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
39216       v_dst = wuffs_base__slice_u8__subslice_j(v_dst, 0u);
39217     } else if (v_width_in_bytes < ((uint64_t)(v_dst.len))) {
39218       v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_width_in_bytes);
39219     }
39220     v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_bytes_per_pixel)));
39221     if (v_i < ((uint64_t)(v_dst.len))) {
39222       v_j = (((uint64_t)(self->private_impl.f_frame_rect_x1)) * ((uint64_t)(v_bytes_per_pixel)));
39223       if ((v_i <= v_j) && (v_j <= ((uint64_t)(v_dst.len)))) {
39224         v_dst = wuffs_base__slice_u8__subslice_ij(v_dst, v_i, v_j);
39225       } else {
39226         v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_i);
39227       }
39228       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);
39229       wuffs_base__u64__sat_add_indirect(&v_src_ri, v_n);
39230       wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n)));
39231       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));
39232     }
39233     if (self->private_impl.f_frame_rect_x1 <= self->private_impl.f_dst_x) {
39234       self->private_impl.f_dst_x = self->private_impl.f_frame_rect_x0;
39235       if (self->private_impl.f_interlace == 0u) {
39236         wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_y, 1u);
39237         continue;
39238       }
39239       if ((self->private_impl.f_num_decoded_frames_value == 0u) &&  ! self->private_impl.f_gc_has_transparent_index && (self->private_impl.f_interlace > 1u)) {
39240         v_replicate_src = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
39241         v_replicate_y0 = wuffs_base__u32__sat_add(self->private_impl.f_dst_y, 1u);
39242         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])));
39243         v_replicate_y1 = wuffs_base__u32__min(v_replicate_y1, self->private_impl.f_frame_rect_y1);
39244         while (v_replicate_y0 < v_replicate_y1) {
39245           v_replicate_dst = wuffs_base__table_u8__row_u32(v_tab, v_replicate_y0);
39246           wuffs_base__slice_u8__copy_from_slice(v_replicate_dst, v_replicate_src);
39247           v_replicate_y0 += 1u;
39248         }
39249         self->private_impl.f_dirty_max_excl_y = wuffs_base__u32__max(self->private_impl.f_dirty_max_excl_y, v_replicate_y1);
39250       }
39251       wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_y, ((uint32_t)(WUFFS_GIF__INTERLACE_DELTA[self->private_impl.f_interlace])));
39252       while ((self->private_impl.f_interlace > 0u) && (self->private_impl.f_dst_y >= self->private_impl.f_frame_rect_y1)) {
39253 #if defined(__GNUC__)
39254 #pragma GCC diagnostic push
39255 #pragma GCC diagnostic ignored "-Wconversion"
39256 #endif
39257         self->private_impl.f_interlace -= 1u;
39258 #if defined(__GNUC__)
39259 #pragma GCC diagnostic pop
39260 #endif
39261         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]);
39262       }
39263       continue;
39264     }
39265     if (((uint64_t)(a_src.len)) == v_src_ri) {
39266       break;
39267     } else if (((uint64_t)(a_src.len)) < v_src_ri) {
39268       return wuffs_base__make_status(wuffs_gif__error__internal_error_inconsistent_i_o);
39269     }
39270     v_n = ((uint64_t)((self->private_impl.f_frame_rect_x1 - self->private_impl.f_dst_x)));
39271     v_n = wuffs_base__u64__min(v_n, (((uint64_t)(a_src.len)) - v_src_ri));
39272     wuffs_base__u64__sat_add_indirect(&v_src_ri, v_n);
39273     wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n)));
39274     if (self->private_impl.f_frame_rect_x1 <= self->private_impl.f_dst_x) {
39275       self->private_impl.f_dst_x = self->private_impl.f_frame_rect_x0;
39276       wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_y, ((uint32_t)(WUFFS_GIF__INTERLACE_DELTA[self->private_impl.f_interlace])));
39277       while ((self->private_impl.f_interlace > 0u) && (self->private_impl.f_dst_y >= self->private_impl.f_frame_rect_y1)) {
39278 #if defined(__GNUC__)
39279 #pragma GCC diagnostic push
39280 #pragma GCC diagnostic ignored "-Wconversion"
39281 #endif
39282         self->private_impl.f_interlace -= 1u;
39283 #if defined(__GNUC__)
39284 #pragma GCC diagnostic pop
39285 #endif
39286         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]);
39287       }
39288       continue;
39289     }
39290     if (v_src_ri != ((uint64_t)(a_src.len))) {
39291       return wuffs_base__make_status(wuffs_gif__error__internal_error_inconsistent_i_o);
39292     }
39293     break;
39294   }
39295   return wuffs_base__make_status(NULL);
39296 }
39297 
39298 // -------- func gif.decoder.lzw_init
39299 
39300 WUFFS_BASE__GENERATED_C_CODE
39301 static wuffs_base__empty_struct
wuffs_gif__decoder__lzw_init(wuffs_gif__decoder * self)39302 wuffs_gif__decoder__lzw_init(
39303     wuffs_gif__decoder* self) {
39304   uint32_t v_i = 0;
39305 
39306   self->private_impl.f_lzw_literal_width = 8u;
39307   if (self->private_impl.f_lzw_pending_literal_width_plus_one > 0u) {
39308     self->private_impl.f_lzw_literal_width = (self->private_impl.f_lzw_pending_literal_width_plus_one - 1u);
39309   }
39310   self->private_impl.f_lzw_clear_code = (((uint32_t)(1u)) << self->private_impl.f_lzw_literal_width);
39311   self->private_impl.f_lzw_end_code = (self->private_impl.f_lzw_clear_code + 1u);
39312   self->private_impl.f_lzw_save_code = self->private_impl.f_lzw_end_code;
39313   self->private_impl.f_lzw_prev_code = self->private_impl.f_lzw_end_code;
39314   self->private_impl.f_lzw_width = (self->private_impl.f_lzw_literal_width + 1u);
39315   self->private_impl.f_lzw_bits = 0u;
39316   self->private_impl.f_lzw_n_bits = 0u;
39317   self->private_impl.f_lzw_output_ri = 0u;
39318   self->private_impl.f_lzw_output_wi = 0u;
39319   v_i = 0u;
39320   while (v_i < self->private_impl.f_lzw_clear_code) {
39321     self->private_data.f_lzw_lm1s[v_i] = 0u;
39322     self->private_data.f_lzw_suffixes[v_i][0u] = ((uint8_t)(v_i));
39323     v_i += 1u;
39324   }
39325   return wuffs_base__make_empty_struct();
39326 }
39327 
39328 // -------- func gif.decoder.lzw_read_from
39329 
39330 WUFFS_BASE__GENERATED_C_CODE
39331 static wuffs_base__empty_struct
wuffs_gif__decoder__lzw_read_from(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)39332 wuffs_gif__decoder__lzw_read_from(
39333     wuffs_gif__decoder* self,
39334     wuffs_base__io_buffer* a_src) {
39335   uint32_t v_clear_code = 0;
39336   uint32_t v_end_code = 0;
39337   uint32_t v_save_code = 0;
39338   uint32_t v_prev_code = 0;
39339   uint32_t v_width = 0;
39340   uint32_t v_bits = 0;
39341   uint32_t v_n_bits = 0;
39342   uint32_t v_output_wi = 0;
39343   uint32_t v_code = 0;
39344   uint32_t v_c = 0;
39345   uint32_t v_o = 0;
39346   uint32_t v_steps = 0;
39347   uint8_t v_first_byte = 0;
39348   uint16_t v_lm1_b = 0;
39349   uint16_t v_lm1_a = 0;
39350 
39351   const uint8_t* iop_a_src = NULL;
39352   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39353   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39354   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39355   if (a_src && a_src->data.ptr) {
39356     io0_a_src = a_src->data.ptr;
39357     io1_a_src = io0_a_src + a_src->meta.ri;
39358     iop_a_src = io1_a_src;
39359     io2_a_src = io0_a_src + a_src->meta.wi;
39360   }
39361 
39362   v_clear_code = self->private_impl.f_lzw_clear_code;
39363   v_end_code = self->private_impl.f_lzw_end_code;
39364   v_save_code = self->private_impl.f_lzw_save_code;
39365   v_prev_code = self->private_impl.f_lzw_prev_code;
39366   v_width = self->private_impl.f_lzw_width;
39367   v_bits = self->private_impl.f_lzw_bits;
39368   v_n_bits = self->private_impl.f_lzw_n_bits;
39369   v_output_wi = self->private_impl.f_lzw_output_wi;
39370   while (true) {
39371     if (v_n_bits < v_width) {
39372       if (((uint64_t)(io2_a_src - iop_a_src)) >= 4u) {
39373         v_bits |= ((uint32_t)(wuffs_base__peek_u32le__no_bounds_check(iop_a_src) << v_n_bits));
39374         iop_a_src += ((31u - v_n_bits) >> 3u);
39375         v_n_bits |= 24u;
39376       } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
39377         if (a_src && a_src->meta.closed) {
39378           self->private_impl.f_lzw_read_from_return_value = 3u;
39379         } else {
39380           self->private_impl.f_lzw_read_from_return_value = 2u;
39381         }
39382         break;
39383       } else {
39384         v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
39385         iop_a_src += 1u;
39386         v_n_bits += 8u;
39387         if (v_n_bits >= v_width) {
39388         } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
39389           if (a_src && a_src->meta.closed) {
39390             self->private_impl.f_lzw_read_from_return_value = 3u;
39391           } else {
39392             self->private_impl.f_lzw_read_from_return_value = 2u;
39393           }
39394           break;
39395         } else {
39396           v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
39397           iop_a_src += 1u;
39398           v_n_bits += 8u;
39399           if (v_n_bits < v_width) {
39400             self->private_impl.f_lzw_read_from_return_value = 5u;
39401             break;
39402           }
39403         }
39404       }
39405     }
39406     v_code = ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_width));
39407     v_bits >>= v_width;
39408     v_n_bits -= v_width;
39409     if (v_code < v_clear_code) {
39410       self->private_data.f_lzw_output[v_output_wi] = ((uint8_t)(v_code));
39411       v_output_wi = ((v_output_wi + 1u) & 8191u);
39412       if (v_save_code <= 4095u) {
39413         v_lm1_a = (((uint16_t)(self->private_data.f_lzw_lm1s[v_prev_code] + 1u)) & 4095u);
39414         self->private_data.f_lzw_lm1s[v_save_code] = v_lm1_a;
39415         if ((v_lm1_a % 8u) != 0u) {
39416           self->private_impl.f_lzw_prefixes[v_save_code] = self->private_impl.f_lzw_prefixes[v_prev_code];
39417           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]));
39418           self->private_data.f_lzw_suffixes[v_save_code][(v_lm1_a % 8u)] = ((uint8_t)(v_code));
39419         } else {
39420           self->private_impl.f_lzw_prefixes[v_save_code] = ((uint16_t)(v_prev_code));
39421           self->private_data.f_lzw_suffixes[v_save_code][0u] = ((uint8_t)(v_code));
39422         }
39423         v_save_code += 1u;
39424         if (v_width < 12u) {
39425           v_width += (1u & (v_save_code >> v_width));
39426         }
39427         v_prev_code = v_code;
39428       }
39429     } else if (v_code <= v_end_code) {
39430       if (v_code == v_end_code) {
39431         self->private_impl.f_lzw_read_from_return_value = 0u;
39432         break;
39433       }
39434       v_save_code = v_end_code;
39435       v_prev_code = v_end_code;
39436       v_width = (self->private_impl.f_lzw_literal_width + 1u);
39437     } else if (v_code <= v_save_code) {
39438       v_c = v_code;
39439       if (v_code == v_save_code) {
39440         v_c = v_prev_code;
39441       }
39442       v_o = ((v_output_wi + (((uint32_t)(self->private_data.f_lzw_lm1s[v_c])) & 4294967288u)) & 8191u);
39443       v_output_wi = ((v_output_wi + 1u + ((uint32_t)(self->private_data.f_lzw_lm1s[v_c]))) & 8191u);
39444       v_steps = (((uint32_t)(self->private_data.f_lzw_lm1s[v_c])) >> 3u);
39445       while (true) {
39446         memcpy((self->private_data.f_lzw_output)+(v_o), (self->private_data.f_lzw_suffixes[v_c]), 8u);
39447         if (v_steps <= 0u) {
39448           break;
39449         }
39450         v_steps -= 1u;
39451         v_o = (((uint32_t)(v_o - 8u)) & 8191u);
39452         v_c = ((uint32_t)(self->private_impl.f_lzw_prefixes[v_c]));
39453       }
39454       v_first_byte = self->private_data.f_lzw_suffixes[v_c][0u];
39455       if (v_code == v_save_code) {
39456         self->private_data.f_lzw_output[v_output_wi] = v_first_byte;
39457         v_output_wi = ((v_output_wi + 1u) & 8191u);
39458       }
39459       if (v_save_code <= 4095u) {
39460         v_lm1_b = (((uint16_t)(self->private_data.f_lzw_lm1s[v_prev_code] + 1u)) & 4095u);
39461         self->private_data.f_lzw_lm1s[v_save_code] = v_lm1_b;
39462         if ((v_lm1_b % 8u) != 0u) {
39463           self->private_impl.f_lzw_prefixes[v_save_code] = self->private_impl.f_lzw_prefixes[v_prev_code];
39464           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]));
39465           self->private_data.f_lzw_suffixes[v_save_code][(v_lm1_b % 8u)] = v_first_byte;
39466         } else {
39467           self->private_impl.f_lzw_prefixes[v_save_code] = ((uint16_t)(v_prev_code));
39468           self->private_data.f_lzw_suffixes[v_save_code][0u] = ((uint8_t)(v_first_byte));
39469         }
39470         v_save_code += 1u;
39471         if (v_width < 12u) {
39472           v_width += (1u & (v_save_code >> v_width));
39473         }
39474         v_prev_code = v_code;
39475       }
39476     } else {
39477       self->private_impl.f_lzw_read_from_return_value = 4u;
39478       break;
39479     }
39480     if (v_output_wi > 4095u) {
39481       self->private_impl.f_lzw_read_from_return_value = 1u;
39482       break;
39483     }
39484   }
39485   if (self->private_impl.f_lzw_read_from_return_value != 2u) {
39486     while (v_n_bits >= 8u) {
39487       v_n_bits -= 8u;
39488       if (iop_a_src > io1_a_src) {
39489         iop_a_src--;
39490       } else {
39491         self->private_impl.f_lzw_read_from_return_value = 5u;
39492         break;
39493       }
39494     }
39495   }
39496   self->private_impl.f_lzw_save_code = v_save_code;
39497   self->private_impl.f_lzw_prev_code = v_prev_code;
39498   self->private_impl.f_lzw_width = v_width;
39499   self->private_impl.f_lzw_bits = v_bits;
39500   self->private_impl.f_lzw_n_bits = v_n_bits;
39501   self->private_impl.f_lzw_output_wi = v_output_wi;
39502   if (a_src && a_src->data.ptr) {
39503     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
39504   }
39505 
39506   return wuffs_base__make_empty_struct();
39507 }
39508 
39509 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GIF)
39510 
39511 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GZIP)
39512 
39513 // ---------------- Status Codes Implementations
39514 
39515 const char wuffs_gzip__error__bad_checksum[] = "#gzip: bad checksum";
39516 const char wuffs_gzip__error__bad_compression_method[] = "#gzip: bad compression method";
39517 const char wuffs_gzip__error__bad_encoding_flags[] = "#gzip: bad encoding flags";
39518 const char wuffs_gzip__error__bad_header[] = "#gzip: bad header";
39519 const char wuffs_gzip__error__truncated_input[] = "#gzip: truncated input";
39520 
39521 // ---------------- Private Consts
39522 
39523 // ---------------- Private Initializer Prototypes
39524 
39525 // ---------------- Private Function Prototypes
39526 
39527 WUFFS_BASE__GENERATED_C_CODE
39528 static wuffs_base__status
39529 wuffs_gzip__decoder__do_transform_io(
39530     wuffs_gzip__decoder* self,
39531     wuffs_base__io_buffer* a_dst,
39532     wuffs_base__io_buffer* a_src,
39533     wuffs_base__slice_u8 a_workbuf);
39534 
39535 // ---------------- VTables
39536 
39537 const wuffs_base__io_transformer__func_ptrs
39538 wuffs_gzip__decoder__func_ptrs_for__wuffs_base__io_transformer = {
39539   (uint64_t(*)(const void*,
39540       uint32_t))(&wuffs_gzip__decoder__get_quirk),
39541   (uint64_t(*)(const void*))(&wuffs_gzip__decoder__history_retain_length),
39542   (wuffs_base__status(*)(void*,
39543       uint32_t,
39544       uint64_t))(&wuffs_gzip__decoder__set_quirk),
39545   (wuffs_base__status(*)(void*,
39546       wuffs_base__io_buffer*,
39547       wuffs_base__io_buffer*,
39548       wuffs_base__slice_u8))(&wuffs_gzip__decoder__transform_io),
39549   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_gzip__decoder__workbuf_len),
39550 };
39551 
39552 // ---------------- Initializer Implementations
39553 
39554 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
wuffs_gzip__decoder__initialize(wuffs_gzip__decoder * self,size_t sizeof_star_self,uint64_t wuffs_version,uint32_t options)39555 wuffs_gzip__decoder__initialize(
39556     wuffs_gzip__decoder* self,
39557     size_t sizeof_star_self,
39558     uint64_t wuffs_version,
39559     uint32_t options){
39560   if (!self) {
39561     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
39562   }
39563   if (sizeof(*self) != sizeof_star_self) {
39564     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
39565   }
39566   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
39567       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
39568     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
39569   }
39570 
39571   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
39572     // The whole point of this if-check is to detect an uninitialized *self.
39573     // We disable the warning on GCC. Clang-5.0 does not have this warning.
39574 #if !defined(__clang__) && defined(__GNUC__)
39575 #pragma GCC diagnostic push
39576 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
39577 #endif
39578     if (self->private_impl.magic != 0) {
39579       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
39580     }
39581 #if !defined(__clang__) && defined(__GNUC__)
39582 #pragma GCC diagnostic pop
39583 #endif
39584   } else {
39585     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
39586       memset(self, 0, sizeof(*self));
39587       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
39588     } else {
39589       memset(&(self->private_impl), 0, sizeof(self->private_impl));
39590     }
39591   }
39592 
39593   {
39594     wuffs_base__status z = wuffs_crc32__ieee_hasher__initialize(
39595         &self->private_data.f_checksum, sizeof(self->private_data.f_checksum), WUFFS_VERSION, options);
39596     if (z.repr) {
39597       return z;
39598     }
39599   }
39600   {
39601     wuffs_base__status z = wuffs_deflate__decoder__initialize(
39602         &self->private_data.f_flate, sizeof(self->private_data.f_flate), WUFFS_VERSION, options);
39603     if (z.repr) {
39604       return z;
39605     }
39606   }
39607   self->private_impl.magic = WUFFS_BASE__MAGIC;
39608   self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name =
39609       wuffs_base__io_transformer__vtable_name;
39610   self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers =
39611       (const void*)(&wuffs_gzip__decoder__func_ptrs_for__wuffs_base__io_transformer);
39612   return wuffs_base__make_status(NULL);
39613 }
39614 
39615 wuffs_gzip__decoder*
wuffs_gzip__decoder__alloc(void)39616 wuffs_gzip__decoder__alloc(void) {
39617   wuffs_gzip__decoder* x =
39618       (wuffs_gzip__decoder*)(calloc(sizeof(wuffs_gzip__decoder), 1));
39619   if (!x) {
39620     return NULL;
39621   }
39622   if (wuffs_gzip__decoder__initialize(
39623       x, sizeof(wuffs_gzip__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
39624     free(x);
39625     return NULL;
39626   }
39627   return x;
39628 }
39629 
39630 size_t
sizeof__wuffs_gzip__decoder(void)39631 sizeof__wuffs_gzip__decoder(void) {
39632   return sizeof(wuffs_gzip__decoder);
39633 }
39634 
39635 // ---------------- Function Implementations
39636 
39637 // -------- func gzip.decoder.get_quirk
39638 
39639 WUFFS_BASE__GENERATED_C_CODE
39640 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_gzip__decoder__get_quirk(const wuffs_gzip__decoder * self,uint32_t a_key)39641 wuffs_gzip__decoder__get_quirk(
39642     const wuffs_gzip__decoder* self,
39643     uint32_t a_key) {
39644   if (!self) {
39645     return 0;
39646   }
39647   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
39648       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
39649     return 0;
39650   }
39651 
39652   if ((a_key == 1u) && self->private_impl.f_ignore_checksum) {
39653     return 1u;
39654   }
39655   return 0u;
39656 }
39657 
39658 // -------- func gzip.decoder.set_quirk
39659 
39660 WUFFS_BASE__GENERATED_C_CODE
39661 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_gzip__decoder__set_quirk(wuffs_gzip__decoder * self,uint32_t a_key,uint64_t a_value)39662 wuffs_gzip__decoder__set_quirk(
39663     wuffs_gzip__decoder* self,
39664     uint32_t a_key,
39665     uint64_t a_value) {
39666   if (!self) {
39667     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
39668   }
39669   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
39670     return wuffs_base__make_status(
39671         (self->private_impl.magic == WUFFS_BASE__DISABLED)
39672         ? wuffs_base__error__disabled_by_previous_error
39673         : wuffs_base__error__initialize_not_called);
39674   }
39675 
39676   if (a_key == 1u) {
39677     self->private_impl.f_ignore_checksum = (a_value > 0u);
39678     return wuffs_base__make_status(NULL);
39679   }
39680   return wuffs_base__make_status(wuffs_base__error__unsupported_option);
39681 }
39682 
39683 // -------- func gzip.decoder.history_retain_length
39684 
39685 WUFFS_BASE__GENERATED_C_CODE
39686 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_gzip__decoder__history_retain_length(const wuffs_gzip__decoder * self)39687 wuffs_gzip__decoder__history_retain_length(
39688     const wuffs_gzip__decoder* self) {
39689   if (!self) {
39690     return 0;
39691   }
39692   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
39693       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
39694     return 0;
39695   }
39696 
39697   return 0u;
39698 }
39699 
39700 // -------- func gzip.decoder.workbuf_len
39701 
39702 WUFFS_BASE__GENERATED_C_CODE
39703 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_gzip__decoder__workbuf_len(const wuffs_gzip__decoder * self)39704 wuffs_gzip__decoder__workbuf_len(
39705     const wuffs_gzip__decoder* self) {
39706   if (!self) {
39707     return wuffs_base__utility__empty_range_ii_u64();
39708   }
39709   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
39710       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
39711     return wuffs_base__utility__empty_range_ii_u64();
39712   }
39713 
39714   return wuffs_base__utility__make_range_ii_u64(1u, 1u);
39715 }
39716 
39717 // -------- func gzip.decoder.transform_io
39718 
39719 WUFFS_BASE__GENERATED_C_CODE
39720 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_gzip__decoder__transform_io(wuffs_gzip__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__slice_u8 a_workbuf)39721 wuffs_gzip__decoder__transform_io(
39722     wuffs_gzip__decoder* self,
39723     wuffs_base__io_buffer* a_dst,
39724     wuffs_base__io_buffer* a_src,
39725     wuffs_base__slice_u8 a_workbuf) {
39726   if (!self) {
39727     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
39728   }
39729   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
39730     return wuffs_base__make_status(
39731         (self->private_impl.magic == WUFFS_BASE__DISABLED)
39732         ? wuffs_base__error__disabled_by_previous_error
39733         : wuffs_base__error__initialize_not_called);
39734   }
39735   if (!a_dst || !a_src) {
39736     self->private_impl.magic = WUFFS_BASE__DISABLED;
39737     return wuffs_base__make_status(wuffs_base__error__bad_argument);
39738   }
39739   if ((self->private_impl.active_coroutine != 0) &&
39740       (self->private_impl.active_coroutine != 1)) {
39741     self->private_impl.magic = WUFFS_BASE__DISABLED;
39742     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
39743   }
39744   self->private_impl.active_coroutine = 0;
39745   wuffs_base__status status = wuffs_base__make_status(NULL);
39746 
39747   wuffs_base__status v_status = wuffs_base__make_status(NULL);
39748 
39749   uint32_t coro_susp_point = self->private_impl.p_transform_io[0];
39750   switch (coro_susp_point) {
39751     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
39752 
39753     while (true) {
39754       {
39755         wuffs_base__status t_0 = wuffs_gzip__decoder__do_transform_io(self, a_dst, a_src, a_workbuf);
39756         v_status = t_0;
39757       }
39758       if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
39759         status = wuffs_base__make_status(wuffs_gzip__error__truncated_input);
39760         goto exit;
39761       }
39762       status = v_status;
39763       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
39764     }
39765 
39766     ok:
39767     self->private_impl.p_transform_io[0] = 0;
39768     goto exit;
39769   }
39770 
39771   goto suspend;
39772   suspend:
39773   self->private_impl.p_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
39774   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
39775 
39776   goto exit;
39777   exit:
39778   if (wuffs_base__status__is_error(&status)) {
39779     self->private_impl.magic = WUFFS_BASE__DISABLED;
39780   }
39781   return status;
39782 }
39783 
39784 // -------- func gzip.decoder.do_transform_io
39785 
39786 WUFFS_BASE__GENERATED_C_CODE
39787 static wuffs_base__status
wuffs_gzip__decoder__do_transform_io(wuffs_gzip__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__slice_u8 a_workbuf)39788 wuffs_gzip__decoder__do_transform_io(
39789     wuffs_gzip__decoder* self,
39790     wuffs_base__io_buffer* a_dst,
39791     wuffs_base__io_buffer* a_src,
39792     wuffs_base__slice_u8 a_workbuf) {
39793   wuffs_base__status status = wuffs_base__make_status(NULL);
39794 
39795   uint8_t v_c = 0;
39796   uint8_t v_flags = 0;
39797   uint16_t v_xlen = 0;
39798   uint64_t v_mark = 0;
39799   uint32_t v_checksum_got = 0;
39800   uint32_t v_decoded_length_got = 0;
39801   wuffs_base__status v_status = wuffs_base__make_status(NULL);
39802   uint32_t v_checksum_want = 0;
39803   uint32_t v_decoded_length_want = 0;
39804 
39805   uint8_t* iop_a_dst = NULL;
39806   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39807   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39808   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39809   if (a_dst && a_dst->data.ptr) {
39810     io0_a_dst = a_dst->data.ptr;
39811     io1_a_dst = io0_a_dst + a_dst->meta.wi;
39812     iop_a_dst = io1_a_dst;
39813     io2_a_dst = io0_a_dst + a_dst->data.len;
39814     if (a_dst->meta.closed) {
39815       io2_a_dst = iop_a_dst;
39816     }
39817   }
39818   const uint8_t* iop_a_src = NULL;
39819   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39820   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39821   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39822   if (a_src && a_src->data.ptr) {
39823     io0_a_src = a_src->data.ptr;
39824     io1_a_src = io0_a_src + a_src->meta.ri;
39825     iop_a_src = io1_a_src;
39826     io2_a_src = io0_a_src + a_src->meta.wi;
39827   }
39828 
39829   uint32_t coro_susp_point = self->private_impl.p_do_transform_io[0];
39830   if (coro_susp_point) {
39831     v_flags = self->private_data.s_do_transform_io[0].v_flags;
39832     v_checksum_got = self->private_data.s_do_transform_io[0].v_checksum_got;
39833     v_decoded_length_got = self->private_data.s_do_transform_io[0].v_decoded_length_got;
39834     v_checksum_want = self->private_data.s_do_transform_io[0].v_checksum_want;
39835   }
39836   switch (coro_susp_point) {
39837     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
39838 
39839     {
39840       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
39841       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39842         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39843         goto suspend;
39844       }
39845       uint8_t t_0 = *iop_a_src++;
39846       v_c = t_0;
39847     }
39848     if (v_c != 31u) {
39849       status = wuffs_base__make_status(wuffs_gzip__error__bad_header);
39850       goto exit;
39851     }
39852     {
39853       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
39854       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39855         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39856         goto suspend;
39857       }
39858       uint8_t t_1 = *iop_a_src++;
39859       v_c = t_1;
39860     }
39861     if (v_c != 139u) {
39862       status = wuffs_base__make_status(wuffs_gzip__error__bad_header);
39863       goto exit;
39864     }
39865     {
39866       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
39867       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39868         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39869         goto suspend;
39870       }
39871       uint8_t t_2 = *iop_a_src++;
39872       v_c = t_2;
39873     }
39874     if (v_c != 8u) {
39875       status = wuffs_base__make_status(wuffs_gzip__error__bad_compression_method);
39876       goto exit;
39877     }
39878     {
39879       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
39880       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39881         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39882         goto suspend;
39883       }
39884       uint8_t t_3 = *iop_a_src++;
39885       v_flags = t_3;
39886     }
39887     self->private_data.s_do_transform_io[0].scratch = 6u;
39888     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
39889     if (self->private_data.s_do_transform_io[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
39890       self->private_data.s_do_transform_io[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
39891       iop_a_src = io2_a_src;
39892       status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39893       goto suspend;
39894     }
39895     iop_a_src += self->private_data.s_do_transform_io[0].scratch;
39896     if ((v_flags & 4u) != 0u) {
39897       {
39898         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
39899         uint16_t t_4;
39900         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
39901           t_4 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src);
39902           iop_a_src += 2;
39903         } else {
39904           self->private_data.s_do_transform_io[0].scratch = 0;
39905           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
39906           while (true) {
39907             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39908               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39909               goto suspend;
39910             }
39911             uint64_t* scratch = &self->private_data.s_do_transform_io[0].scratch;
39912             uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
39913             *scratch <<= 8;
39914             *scratch >>= 8;
39915             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
39916             if (num_bits_4 == 8) {
39917               t_4 = ((uint16_t)(*scratch));
39918               break;
39919             }
39920             num_bits_4 += 8u;
39921             *scratch |= ((uint64_t)(num_bits_4)) << 56;
39922           }
39923         }
39924         v_xlen = t_4;
39925       }
39926       self->private_data.s_do_transform_io[0].scratch = ((uint32_t)(v_xlen));
39927       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
39928       if (self->private_data.s_do_transform_io[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
39929         self->private_data.s_do_transform_io[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
39930         iop_a_src = io2_a_src;
39931         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39932         goto suspend;
39933       }
39934       iop_a_src += self->private_data.s_do_transform_io[0].scratch;
39935     }
39936     if ((v_flags & 8u) != 0u) {
39937       while (true) {
39938         {
39939           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
39940           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39941             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39942             goto suspend;
39943           }
39944           uint8_t t_5 = *iop_a_src++;
39945           v_c = t_5;
39946         }
39947         if (v_c == 0u) {
39948           break;
39949         }
39950       }
39951     }
39952     if ((v_flags & 16u) != 0u) {
39953       while (true) {
39954         {
39955           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
39956           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39957             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39958             goto suspend;
39959           }
39960           uint8_t t_6 = *iop_a_src++;
39961           v_c = t_6;
39962         }
39963         if (v_c == 0u) {
39964           break;
39965         }
39966       }
39967     }
39968     if ((v_flags & 2u) != 0u) {
39969       self->private_data.s_do_transform_io[0].scratch = 2u;
39970       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
39971       if (self->private_data.s_do_transform_io[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
39972         self->private_data.s_do_transform_io[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
39973         iop_a_src = io2_a_src;
39974         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39975         goto suspend;
39976       }
39977       iop_a_src += self->private_data.s_do_transform_io[0].scratch;
39978     }
39979     if ((v_flags & 224u) != 0u) {
39980       status = wuffs_base__make_status(wuffs_gzip__error__bad_encoding_flags);
39981       goto exit;
39982     }
39983     while (true) {
39984       v_mark = ((uint64_t)(iop_a_dst - io0_a_dst));
39985       {
39986         if (a_dst) {
39987           a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
39988         }
39989         if (a_src) {
39990           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
39991         }
39992         wuffs_base__status t_7 = wuffs_deflate__decoder__transform_io(&self->private_data.f_flate, a_dst, a_src, a_workbuf);
39993         v_status = t_7;
39994         if (a_dst) {
39995           iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
39996         }
39997         if (a_src) {
39998           iop_a_src = a_src->data.ptr + a_src->meta.ri;
39999         }
40000       }
40001       if ( ! self->private_impl.f_ignore_checksum) {
40002         v_checksum_got = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_checksum, wuffs_base__io__since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst));
40003         v_decoded_length_got += ((uint32_t)(wuffs_base__io__count_since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst)))));
40004       }
40005       if (wuffs_base__status__is_ok(&v_status)) {
40006         break;
40007       }
40008       status = v_status;
40009       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(12);
40010     }
40011     {
40012       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
40013       uint32_t t_8;
40014       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
40015         t_8 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
40016         iop_a_src += 4;
40017       } else {
40018         self->private_data.s_do_transform_io[0].scratch = 0;
40019         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
40020         while (true) {
40021           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
40022             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40023             goto suspend;
40024           }
40025           uint64_t* scratch = &self->private_data.s_do_transform_io[0].scratch;
40026           uint32_t num_bits_8 = ((uint32_t)(*scratch >> 56));
40027           *scratch <<= 8;
40028           *scratch >>= 8;
40029           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_8;
40030           if (num_bits_8 == 24) {
40031             t_8 = ((uint32_t)(*scratch));
40032             break;
40033           }
40034           num_bits_8 += 8u;
40035           *scratch |= ((uint64_t)(num_bits_8)) << 56;
40036         }
40037       }
40038       v_checksum_want = t_8;
40039     }
40040     {
40041       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
40042       uint32_t t_9;
40043       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
40044         t_9 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
40045         iop_a_src += 4;
40046       } else {
40047         self->private_data.s_do_transform_io[0].scratch = 0;
40048         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
40049         while (true) {
40050           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
40051             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40052             goto suspend;
40053           }
40054           uint64_t* scratch = &self->private_data.s_do_transform_io[0].scratch;
40055           uint32_t num_bits_9 = ((uint32_t)(*scratch >> 56));
40056           *scratch <<= 8;
40057           *scratch >>= 8;
40058           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_9;
40059           if (num_bits_9 == 24) {
40060             t_9 = ((uint32_t)(*scratch));
40061             break;
40062           }
40063           num_bits_9 += 8u;
40064           *scratch |= ((uint64_t)(num_bits_9)) << 56;
40065         }
40066       }
40067       v_decoded_length_want = t_9;
40068     }
40069     if ( ! self->private_impl.f_ignore_checksum && ((v_checksum_got != v_checksum_want) || (v_decoded_length_got != v_decoded_length_want))) {
40070       status = wuffs_base__make_status(wuffs_gzip__error__bad_checksum);
40071       goto exit;
40072     }
40073 
40074     ok:
40075     self->private_impl.p_do_transform_io[0] = 0;
40076     goto exit;
40077   }
40078 
40079   goto suspend;
40080   suspend:
40081   self->private_impl.p_do_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
40082   self->private_data.s_do_transform_io[0].v_flags = v_flags;
40083   self->private_data.s_do_transform_io[0].v_checksum_got = v_checksum_got;
40084   self->private_data.s_do_transform_io[0].v_decoded_length_got = v_decoded_length_got;
40085   self->private_data.s_do_transform_io[0].v_checksum_want = v_checksum_want;
40086 
40087   goto exit;
40088   exit:
40089   if (a_dst && a_dst->data.ptr) {
40090     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
40091   }
40092   if (a_src && a_src->data.ptr) {
40093     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
40094   }
40095 
40096   return status;
40097 }
40098 
40099 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GZIP)
40100 
40101 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JPEG)
40102 
40103 // ---------------- Status Codes Implementations
40104 
40105 const char wuffs_jpeg__error__bad_dht_marker[] = "#jpeg: bad DHT marker";
40106 const char wuffs_jpeg__error__bad_dqt_marker[] = "#jpeg: bad DQT marker";
40107 const char wuffs_jpeg__error__bad_dri_marker[] = "#jpeg: bad DRI marker";
40108 const char wuffs_jpeg__error__bad_sof_marker[] = "#jpeg: bad SOF marker";
40109 const char wuffs_jpeg__error__bad_sos_marker[] = "#jpeg: bad SOS marker";
40110 const char wuffs_jpeg__error__bad_header[] = "#jpeg: bad header";
40111 const char wuffs_jpeg__error__bad_marker[] = "#jpeg: bad marker";
40112 const char wuffs_jpeg__error__missing_huffman_table[] = "#jpeg: missing Huffman table";
40113 const char wuffs_jpeg__error__missing_quantization_table[] = "#jpeg: missing Quantization table";
40114 const char wuffs_jpeg__error__truncated_input[] = "#jpeg: truncated input";
40115 const char wuffs_jpeg__error__unsupported_arithmetic_coding[] = "#jpeg: unsupported arithmetic coding";
40116 const char wuffs_jpeg__error__unsupported_color_model[] = "#jpeg: unsupported color model";
40117 const char wuffs_jpeg__error__unsupported_fractional_sampling[] = "#jpeg: unsupported fractional sampling";
40118 const char wuffs_jpeg__error__unsupported_hierarchical_coding[] = "#jpeg: unsupported hierarchical coding";
40119 const char wuffs_jpeg__error__unsupported_implicit_height[] = "#jpeg: unsupported implicit height";
40120 const char wuffs_jpeg__error__unsupported_lossless_coding[] = "#jpeg: unsupported lossless coding";
40121 const char wuffs_jpeg__error__unsupported_marker[] = "#jpeg: unsupported marker";
40122 const char wuffs_jpeg__error__unsupported_precision_12_bits[] = "#jpeg: unsupported precision (12 bits)";
40123 const char wuffs_jpeg__error__unsupported_precision_16_bits[] = "#jpeg: unsupported precision (16 bits)";
40124 const char wuffs_jpeg__error__unsupported_precision[] = "#jpeg: unsupported precision";
40125 const char wuffs_jpeg__error__unsupported_scan_count[] = "#jpeg: unsupported scan count";
40126 const char wuffs_jpeg__error__internal_error_inconsistent_decoder_state[] = "#jpeg: internal error: inconsistent decoder state";
40127 
40128 // ---------------- Private Consts
40129 
40130 static const uint8_t
40131 WUFFS_JPEG__UNZIG[80] WUFFS_BASE__POTENTIALLY_UNUSED = {
40132   0, 0, 1, 8, 16, 9, 2, 3,
40133   10, 17, 24, 32, 25, 18, 11, 4,
40134   5, 12, 19, 26, 33, 40, 48, 41,
40135   34, 27, 20, 13, 6, 7, 14, 21,
40136   28, 35, 42, 49, 56, 57, 50, 43,
40137   36, 29, 22, 15, 23, 30, 37, 44,
40138   51, 58, 59, 52, 45, 38, 31, 39,
40139   46, 53, 60, 61, 54, 47, 55, 62,
40140   63, 63, 63, 63, 63, 63, 63, 63,
40141   63, 63, 63, 63, 63, 63, 63, 63,
40142 };
40143 
40144 static const uint8_t
40145 WUFFS_JPEG__BIAS_AND_CLAMP[1024] WUFFS_BASE__POTENTIALLY_UNUSED = {
40146   128, 129, 130, 131, 132, 133, 134, 135,
40147   136, 137, 138, 139, 140, 141, 142, 143,
40148   144, 145, 146, 147, 148, 149, 150, 151,
40149   152, 153, 154, 155, 156, 157, 158, 159,
40150   160, 161, 162, 163, 164, 165, 166, 167,
40151   168, 169, 170, 171, 172, 173, 174, 175,
40152   176, 177, 178, 179, 180, 181, 182, 183,
40153   184, 185, 186, 187, 188, 189, 190, 191,
40154   192, 193, 194, 195, 196, 197, 198, 199,
40155   200, 201, 202, 203, 204, 205, 206, 207,
40156   208, 209, 210, 211, 212, 213, 214, 215,
40157   216, 217, 218, 219, 220, 221, 222, 223,
40158   224, 225, 226, 227, 228, 229, 230, 231,
40159   232, 233, 234, 235, 236, 237, 238, 239,
40160   240, 241, 242, 243, 244, 245, 246, 247,
40161   248, 249, 250, 251, 252, 253, 254, 255,
40162   255, 255, 255, 255, 255, 255, 255, 255,
40163   255, 255, 255, 255, 255, 255, 255, 255,
40164   255, 255, 255, 255, 255, 255, 255, 255,
40165   255, 255, 255, 255, 255, 255, 255, 255,
40166   255, 255, 255, 255, 255, 255, 255, 255,
40167   255, 255, 255, 255, 255, 255, 255, 255,
40168   255, 255, 255, 255, 255, 255, 255, 255,
40169   255, 255, 255, 255, 255, 255, 255, 255,
40170   255, 255, 255, 255, 255, 255, 255, 255,
40171   255, 255, 255, 255, 255, 255, 255, 255,
40172   255, 255, 255, 255, 255, 255, 255, 255,
40173   255, 255, 255, 255, 255, 255, 255, 255,
40174   255, 255, 255, 255, 255, 255, 255, 255,
40175   255, 255, 255, 255, 255, 255, 255, 255,
40176   255, 255, 255, 255, 255, 255, 255, 255,
40177   255, 255, 255, 255, 255, 255, 255, 255,
40178   255, 255, 255, 255, 255, 255, 255, 255,
40179   255, 255, 255, 255, 255, 255, 255, 255,
40180   255, 255, 255, 255, 255, 255, 255, 255,
40181   255, 255, 255, 255, 255, 255, 255, 255,
40182   255, 255, 255, 255, 255, 255, 255, 255,
40183   255, 255, 255, 255, 255, 255, 255, 255,
40184   255, 255, 255, 255, 255, 255, 255, 255,
40185   255, 255, 255, 255, 255, 255, 255, 255,
40186   255, 255, 255, 255, 255, 255, 255, 255,
40187   255, 255, 255, 255, 255, 255, 255, 255,
40188   255, 255, 255, 255, 255, 255, 255, 255,
40189   255, 255, 255, 255, 255, 255, 255, 255,
40190   255, 255, 255, 255, 255, 255, 255, 255,
40191   255, 255, 255, 255, 255, 255, 255, 255,
40192   255, 255, 255, 255, 255, 255, 255, 255,
40193   255, 255, 255, 255, 255, 255, 255, 255,
40194   255, 255, 255, 255, 255, 255, 255, 255,
40195   255, 255, 255, 255, 255, 255, 255, 255,
40196   255, 255, 255, 255, 255, 255, 255, 255,
40197   255, 255, 255, 255, 255, 255, 255, 255,
40198   255, 255, 255, 255, 255, 255, 255, 255,
40199   255, 255, 255, 255, 255, 255, 255, 255,
40200   255, 255, 255, 255, 255, 255, 255, 255,
40201   255, 255, 255, 255, 255, 255, 255, 255,
40202   255, 255, 255, 255, 255, 255, 255, 255,
40203   255, 255, 255, 255, 255, 255, 255, 255,
40204   255, 255, 255, 255, 255, 255, 255, 255,
40205   255, 255, 255, 255, 255, 255, 255, 255,
40206   255, 255, 255, 255, 255, 255, 255, 255,
40207   255, 255, 255, 255, 255, 255, 255, 255,
40208   255, 255, 255, 255, 255, 255, 255, 255,
40209   255, 255, 255, 255, 255, 255, 255, 255,
40210   0, 0, 0, 0, 0, 0, 0, 0,
40211   0, 0, 0, 0, 0, 0, 0, 0,
40212   0, 0, 0, 0, 0, 0, 0, 0,
40213   0, 0, 0, 0, 0, 0, 0, 0,
40214   0, 0, 0, 0, 0, 0, 0, 0,
40215   0, 0, 0, 0, 0, 0, 0, 0,
40216   0, 0, 0, 0, 0, 0, 0, 0,
40217   0, 0, 0, 0, 0, 0, 0, 0,
40218   0, 0, 0, 0, 0, 0, 0, 0,
40219   0, 0, 0, 0, 0, 0, 0, 0,
40220   0, 0, 0, 0, 0, 0, 0, 0,
40221   0, 0, 0, 0, 0, 0, 0, 0,
40222   0, 0, 0, 0, 0, 0, 0, 0,
40223   0, 0, 0, 0, 0, 0, 0, 0,
40224   0, 0, 0, 0, 0, 0, 0, 0,
40225   0, 0, 0, 0, 0, 0, 0, 0,
40226   0, 0, 0, 0, 0, 0, 0, 0,
40227   0, 0, 0, 0, 0, 0, 0, 0,
40228   0, 0, 0, 0, 0, 0, 0, 0,
40229   0, 0, 0, 0, 0, 0, 0, 0,
40230   0, 0, 0, 0, 0, 0, 0, 0,
40231   0, 0, 0, 0, 0, 0, 0, 0,
40232   0, 0, 0, 0, 0, 0, 0, 0,
40233   0, 0, 0, 0, 0, 0, 0, 0,
40234   0, 0, 0, 0, 0, 0, 0, 0,
40235   0, 0, 0, 0, 0, 0, 0, 0,
40236   0, 0, 0, 0, 0, 0, 0, 0,
40237   0, 0, 0, 0, 0, 0, 0, 0,
40238   0, 0, 0, 0, 0, 0, 0, 0,
40239   0, 0, 0, 0, 0, 0, 0, 0,
40240   0, 0, 0, 0, 0, 0, 0, 0,
40241   0, 0, 0, 0, 0, 0, 0, 0,
40242   0, 0, 0, 0, 0, 0, 0, 0,
40243   0, 0, 0, 0, 0, 0, 0, 0,
40244   0, 0, 0, 0, 0, 0, 0, 0,
40245   0, 0, 0, 0, 0, 0, 0, 0,
40246   0, 0, 0, 0, 0, 0, 0, 0,
40247   0, 0, 0, 0, 0, 0, 0, 0,
40248   0, 0, 0, 0, 0, 0, 0, 0,
40249   0, 0, 0, 0, 0, 0, 0, 0,
40250   0, 0, 0, 0, 0, 0, 0, 0,
40251   0, 0, 0, 0, 0, 0, 0, 0,
40252   0, 0, 0, 0, 0, 0, 0, 0,
40253   0, 0, 0, 0, 0, 0, 0, 0,
40254   0, 0, 0, 0, 0, 0, 0, 0,
40255   0, 0, 0, 0, 0, 0, 0, 0,
40256   0, 0, 0, 0, 0, 0, 0, 0,
40257   0, 0, 0, 0, 0, 0, 0, 0,
40258   0, 1, 2, 3, 4, 5, 6, 7,
40259   8, 9, 10, 11, 12, 13, 14, 15,
40260   16, 17, 18, 19, 20, 21, 22, 23,
40261   24, 25, 26, 27, 28, 29, 30, 31,
40262   32, 33, 34, 35, 36, 37, 38, 39,
40263   40, 41, 42, 43, 44, 45, 46, 47,
40264   48, 49, 50, 51, 52, 53, 54, 55,
40265   56, 57, 58, 59, 60, 61, 62, 63,
40266   64, 65, 66, 67, 68, 69, 70, 71,
40267   72, 73, 74, 75, 76, 77, 78, 79,
40268   80, 81, 82, 83, 84, 85, 86, 87,
40269   88, 89, 90, 91, 92, 93, 94, 95,
40270   96, 97, 98, 99, 100, 101, 102, 103,
40271   104, 105, 106, 107, 108, 109, 110, 111,
40272   112, 113, 114, 115, 116, 117, 118, 119,
40273   120, 121, 122, 123, 124, 125, 126, 127,
40274 };
40275 
40276 static const uint16_t
40277 WUFFS_JPEG__EXTEND[16] WUFFS_BASE__POTENTIALLY_UNUSED = {
40278   0, 65535, 65533, 65529, 65521, 65505, 65473, 65409,
40279   65281, 65025, 64513, 63489, 61441, 57345, 49153, 32769,
40280 };
40281 
40282 static const uint8_t
40283 WUFFS_JPEG__DEFAULT_HUFF_TABLE_DC_LUMA[29] WUFFS_BASE__POTENTIALLY_UNUSED = {
40284   0, 0, 1, 5, 1, 1, 1, 1,
40285   1, 1, 0, 0, 0, 0, 0, 0,
40286   0, 0, 1, 2, 3, 4, 5, 6,
40287   7, 8, 9, 10, 11,
40288 };
40289 
40290 static const uint8_t
40291 WUFFS_JPEG__DEFAULT_HUFF_TABLE_DC_CHROMA[29] WUFFS_BASE__POTENTIALLY_UNUSED = {
40292   1, 0, 3, 1, 1, 1, 1, 1,
40293   1, 1, 1, 1, 0, 0, 0, 0,
40294   0, 0, 1, 2, 3, 4, 5, 6,
40295   7, 8, 9, 10, 11,
40296 };
40297 
40298 static const uint8_t
40299 WUFFS_JPEG__DEFAULT_HUFF_TABLE_AC_LUMA[179] WUFFS_BASE__POTENTIALLY_UNUSED = {
40300   16, 0, 2, 1, 3, 3, 2, 4,
40301   3, 5, 5, 4, 4, 0, 0, 1,
40302   125, 1, 2, 3, 0, 4, 17, 5,
40303   18, 33, 49, 65, 6, 19, 81, 97,
40304   7, 34, 113, 20, 50, 129, 145, 161,
40305   8, 35, 66, 177, 193, 21, 82, 209,
40306   240, 36, 51, 98, 114, 130, 9, 10,
40307   22, 23, 24, 25, 26, 37, 38, 39,
40308   40, 41, 42, 52, 53, 54, 55, 56,
40309   57, 58, 67, 68, 69, 70, 71, 72,
40310   73, 74, 83, 84, 85, 86, 87, 88,
40311   89, 90, 99, 100, 101, 102, 103, 104,
40312   105, 106, 115, 116, 117, 118, 119, 120,
40313   121, 122, 131, 132, 133, 134, 135, 136,
40314   137, 138, 146, 147, 148, 149, 150, 151,
40315   152, 153, 154, 162, 163, 164, 165, 166,
40316   167, 168, 169, 170, 178, 179, 180, 181,
40317   182, 183, 184, 185, 186, 194, 195, 196,
40318   197, 198, 199, 200, 201, 202, 210, 211,
40319   212, 213, 214, 215, 216, 217, 218, 225,
40320   226, 227, 228, 229, 230, 231, 232, 233,
40321   234, 241, 242, 243, 244, 245, 246, 247,
40322   248, 249, 250,
40323 };
40324 
40325 static const uint8_t
40326 WUFFS_JPEG__DEFAULT_HUFF_TABLE_AC_CHROMA[179] WUFFS_BASE__POTENTIALLY_UNUSED = {
40327   17, 0, 2, 1, 2, 4, 4, 3,
40328   4, 7, 5, 4, 4, 0, 1, 2,
40329   119, 0, 1, 2, 3, 17, 4, 5,
40330   33, 49, 6, 18, 65, 81, 7, 97,
40331   113, 19, 34, 50, 129, 8, 20, 66,
40332   145, 161, 177, 193, 9, 35, 51, 82,
40333   240, 21, 98, 114, 209, 10, 22, 36,
40334   52, 225, 37, 241, 23, 24, 25, 26,
40335   38, 39, 40, 41, 42, 53, 54, 55,
40336   56, 57, 58, 67, 68, 69, 70, 71,
40337   72, 73, 74, 83, 84, 85, 86, 87,
40338   88, 89, 90, 99, 100, 101, 102, 103,
40339   104, 105, 106, 115, 116, 117, 118, 119,
40340   120, 121, 122, 130, 131, 132, 133, 134,
40341   135, 136, 137, 138, 146, 147, 148, 149,
40342   150, 151, 152, 153, 154, 162, 163, 164,
40343   165, 166, 167, 168, 169, 170, 178, 179,
40344   180, 181, 182, 183, 184, 185, 186, 194,
40345   195, 196, 197, 198, 199, 200, 201, 202,
40346   210, 211, 212, 213, 214, 215, 216, 217,
40347   218, 226, 227, 228, 229, 230, 231, 232,
40348   233, 234, 242, 243, 244, 245, 246, 247,
40349   248, 249, 250,
40350 };
40351 
40352 // ---------------- Private Initializer Prototypes
40353 
40354 // ---------------- Private Function Prototypes
40355 
40356 WUFFS_BASE__GENERATED_C_CODE
40357 static wuffs_base__empty_struct
40358 wuffs_jpeg__decoder__decode_idct(
40359     wuffs_jpeg__decoder* self,
40360     wuffs_base__slice_u8 a_dst_buffer,
40361     uint64_t a_dst_stride,
40362     uint32_t a_q);
40363 
40364 WUFFS_BASE__GENERATED_C_CODE
40365 static wuffs_base__empty_struct
40366 wuffs_jpeg__decoder__decode_idct__choosy_default(
40367     wuffs_jpeg__decoder* self,
40368     wuffs_base__slice_u8 a_dst_buffer,
40369     uint64_t a_dst_stride,
40370     uint32_t a_q);
40371 
40372 #if defined(WUFFS_BASE__CPU_ARCH__X86_64)
40373 WUFFS_BASE__GENERATED_C_CODE
40374 static wuffs_base__empty_struct
40375 wuffs_jpeg__decoder__decode_idct_x86_avx2(
40376     wuffs_jpeg__decoder* self,
40377     wuffs_base__slice_u8 a_dst_buffer,
40378     uint64_t a_dst_stride,
40379     uint32_t a_q);
40380 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_64)
40381 
40382 WUFFS_BASE__GENERATED_C_CODE
40383 static wuffs_base__status
40384 wuffs_jpeg__decoder__do_decode_image_config(
40385     wuffs_jpeg__decoder* self,
40386     wuffs_base__image_config* a_dst,
40387     wuffs_base__io_buffer* a_src);
40388 
40389 WUFFS_BASE__GENERATED_C_CODE
40390 static wuffs_base__status
40391 wuffs_jpeg__decoder__decode_dqt(
40392     wuffs_jpeg__decoder* self,
40393     wuffs_base__io_buffer* a_src);
40394 
40395 WUFFS_BASE__GENERATED_C_CODE
40396 static wuffs_base__status
40397 wuffs_jpeg__decoder__decode_dri(
40398     wuffs_jpeg__decoder* self,
40399     wuffs_base__io_buffer* a_src);
40400 
40401 WUFFS_BASE__GENERATED_C_CODE
40402 static wuffs_base__status
40403 wuffs_jpeg__decoder__decode_appn(
40404     wuffs_jpeg__decoder* self,
40405     wuffs_base__io_buffer* a_src,
40406     uint8_t a_marker);
40407 
40408 WUFFS_BASE__GENERATED_C_CODE
40409 static wuffs_base__status
40410 wuffs_jpeg__decoder__decode_sof(
40411     wuffs_jpeg__decoder* self,
40412     wuffs_base__io_buffer* a_src);
40413 
40414 WUFFS_BASE__GENERATED_C_CODE
40415 static uint32_t
40416 wuffs_jpeg__decoder__quantize_dimension(
40417     const wuffs_jpeg__decoder* self,
40418     uint32_t a_width,
40419     uint8_t a_h,
40420     uint8_t a_max_incl_h);
40421 
40422 WUFFS_BASE__GENERATED_C_CODE
40423 static wuffs_base__status
40424 wuffs_jpeg__decoder__do_decode_frame_config(
40425     wuffs_jpeg__decoder* self,
40426     wuffs_base__frame_config* a_dst,
40427     wuffs_base__io_buffer* a_src);
40428 
40429 WUFFS_BASE__GENERATED_C_CODE
40430 static wuffs_base__status
40431 wuffs_jpeg__decoder__do_decode_frame(
40432     wuffs_jpeg__decoder* self,
40433     wuffs_base__pixel_buffer* a_dst,
40434     wuffs_base__io_buffer* a_src,
40435     wuffs_base__pixel_blend a_blend,
40436     wuffs_base__slice_u8 a_workbuf,
40437     wuffs_base__decode_frame_options* a_opts);
40438 
40439 WUFFS_BASE__GENERATED_C_CODE
40440 static wuffs_base__status
40441 wuffs_jpeg__decoder__decode_dht(
40442     wuffs_jpeg__decoder* self,
40443     wuffs_base__io_buffer* a_src);
40444 
40445 WUFFS_BASE__GENERATED_C_CODE
40446 static bool
40447 wuffs_jpeg__decoder__calculate_huff_tables(
40448     wuffs_jpeg__decoder* self,
40449     uint8_t a_tc4_th,
40450     uint32_t a_total_count);
40451 
40452 WUFFS_BASE__GENERATED_C_CODE
40453 static wuffs_base__status
40454 wuffs_jpeg__decoder__decode_sos(
40455     wuffs_jpeg__decoder* self,
40456     wuffs_base__io_buffer* a_src,
40457     wuffs_base__slice_u8 a_workbuf);
40458 
40459 WUFFS_BASE__GENERATED_C_CODE
40460 static wuffs_base__status
40461 wuffs_jpeg__decoder__prepare_scan(
40462     wuffs_jpeg__decoder* self,
40463     wuffs_base__io_buffer* a_src);
40464 
40465 WUFFS_BASE__GENERATED_C_CODE
40466 static wuffs_base__status
40467 wuffs_jpeg__decoder__use_default_huffman_table(
40468     wuffs_jpeg__decoder* self,
40469     uint8_t a_tc4_th);
40470 
40471 WUFFS_BASE__GENERATED_C_CODE
40472 static wuffs_base__empty_struct
40473 wuffs_jpeg__decoder__calculate_single_component_scan_fields(
40474     wuffs_jpeg__decoder* self);
40475 
40476 WUFFS_BASE__GENERATED_C_CODE
40477 static bool
40478 wuffs_jpeg__decoder__calculate_multiple_component_scan_fields(
40479     wuffs_jpeg__decoder* self);
40480 
40481 WUFFS_BASE__GENERATED_C_CODE
40482 static wuffs_base__empty_struct
40483 wuffs_jpeg__decoder__fill_bitstream(
40484     wuffs_jpeg__decoder* self,
40485     wuffs_base__io_buffer* a_src);
40486 
40487 WUFFS_BASE__GENERATED_C_CODE
40488 static wuffs_base__empty_struct
40489 wuffs_jpeg__decoder__load_mcu_blocks_for_single_component(
40490     wuffs_jpeg__decoder* self,
40491     uint32_t a_mx,
40492     uint32_t a_my,
40493     wuffs_base__slice_u8 a_workbuf,
40494     uint32_t a_csel);
40495 
40496 WUFFS_BASE__GENERATED_C_CODE
40497 static wuffs_base__empty_struct
40498 wuffs_jpeg__decoder__load_mcu_blocks_for_single_component__choosy_default(
40499     wuffs_jpeg__decoder* self,
40500     uint32_t a_mx,
40501     uint32_t a_my,
40502     wuffs_base__slice_u8 a_workbuf,
40503     uint32_t a_csel);
40504 
40505 WUFFS_BASE__GENERATED_C_CODE
40506 static wuffs_base__empty_struct
40507 wuffs_jpeg__decoder__load_mcu_blocks(
40508     wuffs_jpeg__decoder* self,
40509     uint32_t a_mx,
40510     uint32_t a_my,
40511     wuffs_base__slice_u8 a_workbuf);
40512 
40513 WUFFS_BASE__GENERATED_C_CODE
40514 static wuffs_base__empty_struct
40515 wuffs_jpeg__decoder__save_mcu_blocks(
40516     wuffs_jpeg__decoder* self,
40517     uint32_t a_mx,
40518     uint32_t a_my,
40519     wuffs_base__slice_u8 a_workbuf);
40520 
40521 WUFFS_BASE__GENERATED_C_CODE
40522 static wuffs_base__status
40523 wuffs_jpeg__decoder__skip_past_the_next_restart_marker(
40524     wuffs_jpeg__decoder* self,
40525     wuffs_base__io_buffer* a_src);
40526 
40527 WUFFS_BASE__GENERATED_C_CODE
40528 static wuffs_base__empty_struct
40529 wuffs_jpeg__decoder__apply_progressive_idct(
40530     wuffs_jpeg__decoder* self,
40531     wuffs_base__slice_u8 a_workbuf);
40532 
40533 WUFFS_BASE__GENERATED_C_CODE
40534 static wuffs_base__status
40535 wuffs_jpeg__decoder__swizzle_gray(
40536     wuffs_jpeg__decoder* self,
40537     wuffs_base__pixel_buffer* a_dst,
40538     wuffs_base__slice_u8 a_workbuf);
40539 
40540 WUFFS_BASE__GENERATED_C_CODE
40541 static wuffs_base__status
40542 wuffs_jpeg__decoder__swizzle_colorful(
40543     wuffs_jpeg__decoder* self,
40544     wuffs_base__pixel_buffer* a_dst,
40545     wuffs_base__slice_u8 a_workbuf);
40546 
40547 WUFFS_BASE__GENERATED_C_CODE
40548 static bool
40549 wuffs_jpeg__decoder__top_left_quants_has_zero(
40550     const wuffs_jpeg__decoder* self,
40551     uint32_t a_q);
40552 
40553 WUFFS_BASE__GENERATED_C_CODE
40554 static wuffs_base__empty_struct
40555 wuffs_jpeg__decoder__load_mcu_blocks_for_single_component_smooth(
40556     wuffs_jpeg__decoder* self,
40557     uint32_t a_mx,
40558     uint32_t a_my,
40559     wuffs_base__slice_u8 a_workbuf,
40560     uint32_t a_csel);
40561 
40562 WUFFS_BASE__GENERATED_C_CODE
40563 static uint32_t
40564 wuffs_jpeg__decoder__decode_mcu(
40565     wuffs_jpeg__decoder* self,
40566     wuffs_base__slice_u8 a_workbuf,
40567     uint32_t a_mx,
40568     uint32_t a_my);
40569 
40570 WUFFS_BASE__GENERATED_C_CODE
40571 static uint32_t
40572 wuffs_jpeg__decoder__decode_mcu__choosy_default(
40573     wuffs_jpeg__decoder* self,
40574     wuffs_base__slice_u8 a_workbuf,
40575     uint32_t a_mx,
40576     uint32_t a_my);
40577 
40578 WUFFS_BASE__GENERATED_C_CODE
40579 static uint32_t
40580 wuffs_jpeg__decoder__decode_mcu_progressive_ac_high_bits(
40581     wuffs_jpeg__decoder* self,
40582     wuffs_base__slice_u8 a_workbuf,
40583     uint32_t a_mx,
40584     uint32_t a_my);
40585 
40586 WUFFS_BASE__GENERATED_C_CODE
40587 static uint32_t
40588 wuffs_jpeg__decoder__decode_mcu_progressive_ac_low_bit(
40589     wuffs_jpeg__decoder* self,
40590     wuffs_base__slice_u8 a_workbuf,
40591     uint32_t a_mx,
40592     uint32_t a_my);
40593 
40594 WUFFS_BASE__GENERATED_C_CODE
40595 static uint32_t
40596 wuffs_jpeg__decoder__decode_mcu_progressive_dc_high_bits(
40597     wuffs_jpeg__decoder* self,
40598     wuffs_base__slice_u8 a_workbuf,
40599     uint32_t a_mx,
40600     uint32_t a_my);
40601 
40602 WUFFS_BASE__GENERATED_C_CODE
40603 static uint32_t
40604 wuffs_jpeg__decoder__decode_mcu_progressive_dc_low_bit(
40605     wuffs_jpeg__decoder* self,
40606     wuffs_base__slice_u8 a_workbuf,
40607     uint32_t a_mx,
40608     uint32_t a_my);
40609 
40610 // ---------------- VTables
40611 
40612 const wuffs_base__image_decoder__func_ptrs
40613 wuffs_jpeg__decoder__func_ptrs_for__wuffs_base__image_decoder = {
40614   (wuffs_base__status(*)(void*,
40615       wuffs_base__pixel_buffer*,
40616       wuffs_base__io_buffer*,
40617       wuffs_base__pixel_blend,
40618       wuffs_base__slice_u8,
40619       wuffs_base__decode_frame_options*))(&wuffs_jpeg__decoder__decode_frame),
40620   (wuffs_base__status(*)(void*,
40621       wuffs_base__frame_config*,
40622       wuffs_base__io_buffer*))(&wuffs_jpeg__decoder__decode_frame_config),
40623   (wuffs_base__status(*)(void*,
40624       wuffs_base__image_config*,
40625       wuffs_base__io_buffer*))(&wuffs_jpeg__decoder__decode_image_config),
40626   (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_jpeg__decoder__frame_dirty_rect),
40627   (uint64_t(*)(const void*,
40628       uint32_t))(&wuffs_jpeg__decoder__get_quirk),
40629   (uint64_t(*)(const void*))(&wuffs_jpeg__decoder__history_retain_length),
40630   (uint32_t(*)(const void*))(&wuffs_jpeg__decoder__num_animation_loops),
40631   (uint64_t(*)(const void*))(&wuffs_jpeg__decoder__num_decoded_frame_configs),
40632   (uint64_t(*)(const void*))(&wuffs_jpeg__decoder__num_decoded_frames),
40633   (wuffs_base__status(*)(void*,
40634       uint64_t,
40635       uint64_t))(&wuffs_jpeg__decoder__restart_frame),
40636   (wuffs_base__status(*)(void*,
40637       uint32_t,
40638       uint64_t))(&wuffs_jpeg__decoder__set_quirk),
40639   (wuffs_base__empty_struct(*)(void*,
40640       uint32_t,
40641       bool))(&wuffs_jpeg__decoder__set_report_metadata),
40642   (wuffs_base__status(*)(void*,
40643       wuffs_base__io_buffer*,
40644       wuffs_base__more_information*,
40645       wuffs_base__io_buffer*))(&wuffs_jpeg__decoder__tell_me_more),
40646   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_jpeg__decoder__workbuf_len),
40647 };
40648 
40649 // ---------------- Initializer Implementations
40650 
40651 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
wuffs_jpeg__decoder__initialize(wuffs_jpeg__decoder * self,size_t sizeof_star_self,uint64_t wuffs_version,uint32_t options)40652 wuffs_jpeg__decoder__initialize(
40653     wuffs_jpeg__decoder* self,
40654     size_t sizeof_star_self,
40655     uint64_t wuffs_version,
40656     uint32_t options){
40657   if (!self) {
40658     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
40659   }
40660   if (sizeof(*self) != sizeof_star_self) {
40661     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
40662   }
40663   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
40664       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
40665     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
40666   }
40667 
40668   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
40669     // The whole point of this if-check is to detect an uninitialized *self.
40670     // We disable the warning on GCC. Clang-5.0 does not have this warning.
40671 #if !defined(__clang__) && defined(__GNUC__)
40672 #pragma GCC diagnostic push
40673 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
40674 #endif
40675     if (self->private_impl.magic != 0) {
40676       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
40677     }
40678 #if !defined(__clang__) && defined(__GNUC__)
40679 #pragma GCC diagnostic pop
40680 #endif
40681   } else {
40682     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
40683       memset(self, 0, sizeof(*self));
40684       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
40685     } else {
40686       memset(&(self->private_impl), 0, sizeof(self->private_impl));
40687     }
40688   }
40689 
40690   self->private_impl.choosy_decode_idct = &wuffs_jpeg__decoder__decode_idct__choosy_default;
40691   self->private_impl.choosy_load_mcu_blocks_for_single_component = &wuffs_jpeg__decoder__load_mcu_blocks_for_single_component__choosy_default;
40692   self->private_impl.choosy_decode_mcu = &wuffs_jpeg__decoder__decode_mcu__choosy_default;
40693 
40694   self->private_impl.magic = WUFFS_BASE__MAGIC;
40695   self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
40696       wuffs_base__image_decoder__vtable_name;
40697   self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
40698       (const void*)(&wuffs_jpeg__decoder__func_ptrs_for__wuffs_base__image_decoder);
40699   return wuffs_base__make_status(NULL);
40700 }
40701 
40702 wuffs_jpeg__decoder*
wuffs_jpeg__decoder__alloc(void)40703 wuffs_jpeg__decoder__alloc(void) {
40704   wuffs_jpeg__decoder* x =
40705       (wuffs_jpeg__decoder*)(calloc(sizeof(wuffs_jpeg__decoder), 1));
40706   if (!x) {
40707     return NULL;
40708   }
40709   if (wuffs_jpeg__decoder__initialize(
40710       x, sizeof(wuffs_jpeg__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
40711     free(x);
40712     return NULL;
40713   }
40714   return x;
40715 }
40716 
40717 size_t
sizeof__wuffs_jpeg__decoder(void)40718 sizeof__wuffs_jpeg__decoder(void) {
40719   return sizeof(wuffs_jpeg__decoder);
40720 }
40721 
40722 // ---------------- Function Implementations
40723 
40724 // -------- func jpeg.decoder.decode_idct
40725 
40726 WUFFS_BASE__GENERATED_C_CODE
40727 static wuffs_base__empty_struct
wuffs_jpeg__decoder__decode_idct(wuffs_jpeg__decoder * self,wuffs_base__slice_u8 a_dst_buffer,uint64_t a_dst_stride,uint32_t a_q)40728 wuffs_jpeg__decoder__decode_idct(
40729     wuffs_jpeg__decoder* self,
40730     wuffs_base__slice_u8 a_dst_buffer,
40731     uint64_t a_dst_stride,
40732     uint32_t a_q) {
40733   return (*self->private_impl.choosy_decode_idct)(self, a_dst_buffer, a_dst_stride, a_q);
40734 }
40735 
40736 WUFFS_BASE__GENERATED_C_CODE
40737 static wuffs_base__empty_struct
wuffs_jpeg__decoder__decode_idct__choosy_default(wuffs_jpeg__decoder * self,wuffs_base__slice_u8 a_dst_buffer,uint64_t a_dst_stride,uint32_t a_q)40738 wuffs_jpeg__decoder__decode_idct__choosy_default(
40739     wuffs_jpeg__decoder* self,
40740     wuffs_base__slice_u8 a_dst_buffer,
40741     uint64_t a_dst_stride,
40742     uint32_t a_q) {
40743   uint32_t v_bq0 = 0;
40744   uint32_t v_bq2 = 0;
40745   uint32_t v_bq4 = 0;
40746   uint32_t v_bq6 = 0;
40747   uint32_t v_ca = 0;
40748   uint32_t v_cb2 = 0;
40749   uint32_t v_cb6 = 0;
40750   uint32_t v_ccp = 0;
40751   uint32_t v_ccm = 0;
40752   uint32_t v_cd0 = 0;
40753   uint32_t v_cd1 = 0;
40754   uint32_t v_cd2 = 0;
40755   uint32_t v_cd3 = 0;
40756   uint32_t v_bq1 = 0;
40757   uint32_t v_bq3 = 0;
40758   uint32_t v_bq5 = 0;
40759   uint32_t v_bq7 = 0;
40760   uint32_t v_ci51 = 0;
40761   uint32_t v_ci53 = 0;
40762   uint32_t v_ci71 = 0;
40763   uint32_t v_ci73 = 0;
40764   uint32_t v_cj = 0;
40765   uint32_t v_ck1 = 0;
40766   uint32_t v_ck3 = 0;
40767   uint32_t v_ck5 = 0;
40768   uint32_t v_ck7 = 0;
40769   uint32_t v_cl51 = 0;
40770   uint32_t v_cl73 = 0;
40771   uint32_t v_in0 = 0;
40772   uint32_t v_in2 = 0;
40773   uint32_t v_in4 = 0;
40774   uint32_t v_in6 = 0;
40775   uint32_t v_ra = 0;
40776   uint32_t v_rb2 = 0;
40777   uint32_t v_rb6 = 0;
40778   uint32_t v_rcp = 0;
40779   uint32_t v_rcm = 0;
40780   uint32_t v_rd0 = 0;
40781   uint32_t v_rd1 = 0;
40782   uint32_t v_rd2 = 0;
40783   uint32_t v_rd3 = 0;
40784   uint32_t v_in1 = 0;
40785   uint32_t v_in3 = 0;
40786   uint32_t v_in5 = 0;
40787   uint32_t v_in7 = 0;
40788   uint32_t v_ri51 = 0;
40789   uint32_t v_ri53 = 0;
40790   uint32_t v_ri71 = 0;
40791   uint32_t v_ri73 = 0;
40792   uint32_t v_rj = 0;
40793   uint32_t v_rk1 = 0;
40794   uint32_t v_rk3 = 0;
40795   uint32_t v_rk5 = 0;
40796   uint32_t v_rk7 = 0;
40797   uint32_t v_rl51 = 0;
40798   uint32_t v_rl73 = 0;
40799   uint32_t v_intermediate[64] = {0};
40800 
40801   if (8u > a_dst_stride) {
40802     return wuffs_base__make_empty_struct();
40803   }
40804   if (0u == (self->private_data.f_mcu_blocks[0u][8u] |
40805       self->private_data.f_mcu_blocks[0u][16u] |
40806       self->private_data.f_mcu_blocks[0u][24u] |
40807       self->private_data.f_mcu_blocks[0u][32u] |
40808       self->private_data.f_mcu_blocks[0u][40u] |
40809       self->private_data.f_mcu_blocks[0u][48u] |
40810       self->private_data.f_mcu_blocks[0u][56u])) {
40811     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));
40812     v_intermediate[8u] = v_intermediate[0u];
40813     v_intermediate[16u] = v_intermediate[0u];
40814     v_intermediate[24u] = v_intermediate[0u];
40815     v_intermediate[32u] = v_intermediate[0u];
40816     v_intermediate[40u] = v_intermediate[0u];
40817     v_intermediate[48u] = v_intermediate[0u];
40818     v_intermediate[56u] = v_intermediate[0u];
40819   } else {
40820     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]))));
40821     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]))));
40822     v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u));
40823     v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u))));
40824     v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u))));
40825     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]))));
40826     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]))));
40827     v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u));
40828     v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u));
40829     v_cd0 = ((uint32_t)(v_ccp + v_cb2));
40830     v_cd1 = ((uint32_t)(v_ccm + v_cb6));
40831     v_cd2 = ((uint32_t)(v_ccm - v_cb6));
40832     v_cd3 = ((uint32_t)(v_ccp - v_cb2));
40833     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]))));
40834     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]))));
40835     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]))));
40836     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]))));
40837     v_ci51 = ((uint32_t)(v_bq5 + v_bq1));
40838     v_ci53 = ((uint32_t)(v_bq5 + v_bq3));
40839     v_ci71 = ((uint32_t)(v_bq7 + v_bq1));
40840     v_ci73 = ((uint32_t)(v_bq7 + v_bq3));
40841     v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u));
40842     v_ck1 = ((uint32_t)(v_bq1 * 12299u));
40843     v_ck3 = ((uint32_t)(v_bq3 * 25172u));
40844     v_ck5 = ((uint32_t)(v_bq5 * 16819u));
40845     v_ck7 = ((uint32_t)(v_bq7 * 2446u));
40846     v_ci51 *= 4294964100u;
40847     v_ci53 *= 4294946301u;
40848     v_ci71 *= 4294959923u;
40849     v_ci73 *= 4294951227u;
40850     v_cl51 = ((uint32_t)(v_ci51 + v_cj));
40851     v_cl73 = ((uint32_t)(v_ci73 + v_cj));
40852     v_ck1 += ((uint32_t)(v_ci71 + v_cl51));
40853     v_ck3 += ((uint32_t)(v_ci53 + v_cl73));
40854     v_ck5 += ((uint32_t)(v_ci53 + v_cl51));
40855     v_ck7 += ((uint32_t)(v_ci71 + v_cl73));
40856     v_intermediate[0u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u);
40857     v_intermediate[56u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u);
40858     v_intermediate[8u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u);
40859     v_intermediate[48u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u);
40860     v_intermediate[16u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u);
40861     v_intermediate[40u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u);
40862     v_intermediate[24u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u);
40863     v_intermediate[32u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u);
40864   }
40865   if (0u == (self->private_data.f_mcu_blocks[0u][9u] |
40866       self->private_data.f_mcu_blocks[0u][17u] |
40867       self->private_data.f_mcu_blocks[0u][25u] |
40868       self->private_data.f_mcu_blocks[0u][33u] |
40869       self->private_data.f_mcu_blocks[0u][41u] |
40870       self->private_data.f_mcu_blocks[0u][49u] |
40871       self->private_data.f_mcu_blocks[0u][57u])) {
40872     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));
40873     v_intermediate[9u] = v_intermediate[1u];
40874     v_intermediate[17u] = v_intermediate[1u];
40875     v_intermediate[25u] = v_intermediate[1u];
40876     v_intermediate[33u] = v_intermediate[1u];
40877     v_intermediate[41u] = v_intermediate[1u];
40878     v_intermediate[49u] = v_intermediate[1u];
40879     v_intermediate[57u] = v_intermediate[1u];
40880   } else {
40881     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]))));
40882     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]))));
40883     v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u));
40884     v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u))));
40885     v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u))));
40886     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]))));
40887     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]))));
40888     v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u));
40889     v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u));
40890     v_cd0 = ((uint32_t)(v_ccp + v_cb2));
40891     v_cd1 = ((uint32_t)(v_ccm + v_cb6));
40892     v_cd2 = ((uint32_t)(v_ccm - v_cb6));
40893     v_cd3 = ((uint32_t)(v_ccp - v_cb2));
40894     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]))));
40895     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]))));
40896     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]))));
40897     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]))));
40898     v_ci51 = ((uint32_t)(v_bq5 + v_bq1));
40899     v_ci53 = ((uint32_t)(v_bq5 + v_bq3));
40900     v_ci71 = ((uint32_t)(v_bq7 + v_bq1));
40901     v_ci73 = ((uint32_t)(v_bq7 + v_bq3));
40902     v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u));
40903     v_ck1 = ((uint32_t)(v_bq1 * 12299u));
40904     v_ck3 = ((uint32_t)(v_bq3 * 25172u));
40905     v_ck5 = ((uint32_t)(v_bq5 * 16819u));
40906     v_ck7 = ((uint32_t)(v_bq7 * 2446u));
40907     v_ci51 *= 4294964100u;
40908     v_ci53 *= 4294946301u;
40909     v_ci71 *= 4294959923u;
40910     v_ci73 *= 4294951227u;
40911     v_cl51 = ((uint32_t)(v_ci51 + v_cj));
40912     v_cl73 = ((uint32_t)(v_ci73 + v_cj));
40913     v_ck1 += ((uint32_t)(v_ci71 + v_cl51));
40914     v_ck3 += ((uint32_t)(v_ci53 + v_cl73));
40915     v_ck5 += ((uint32_t)(v_ci53 + v_cl51));
40916     v_ck7 += ((uint32_t)(v_ci71 + v_cl73));
40917     v_intermediate[1u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u);
40918     v_intermediate[57u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u);
40919     v_intermediate[9u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u);
40920     v_intermediate[49u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u);
40921     v_intermediate[17u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u);
40922     v_intermediate[41u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u);
40923     v_intermediate[25u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u);
40924     v_intermediate[33u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u);
40925   }
40926   if (0u == (self->private_data.f_mcu_blocks[0u][10u] |
40927       self->private_data.f_mcu_blocks[0u][18u] |
40928       self->private_data.f_mcu_blocks[0u][26u] |
40929       self->private_data.f_mcu_blocks[0u][34u] |
40930       self->private_data.f_mcu_blocks[0u][42u] |
40931       self->private_data.f_mcu_blocks[0u][50u] |
40932       self->private_data.f_mcu_blocks[0u][58u])) {
40933     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));
40934     v_intermediate[10u] = v_intermediate[2u];
40935     v_intermediate[18u] = v_intermediate[2u];
40936     v_intermediate[26u] = v_intermediate[2u];
40937     v_intermediate[34u] = v_intermediate[2u];
40938     v_intermediate[42u] = v_intermediate[2u];
40939     v_intermediate[50u] = v_intermediate[2u];
40940     v_intermediate[58u] = v_intermediate[2u];
40941   } else {
40942     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]))));
40943     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]))));
40944     v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u));
40945     v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u))));
40946     v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u))));
40947     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]))));
40948     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]))));
40949     v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u));
40950     v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u));
40951     v_cd0 = ((uint32_t)(v_ccp + v_cb2));
40952     v_cd1 = ((uint32_t)(v_ccm + v_cb6));
40953     v_cd2 = ((uint32_t)(v_ccm - v_cb6));
40954     v_cd3 = ((uint32_t)(v_ccp - v_cb2));
40955     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]))));
40956     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]))));
40957     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]))));
40958     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]))));
40959     v_ci51 = ((uint32_t)(v_bq5 + v_bq1));
40960     v_ci53 = ((uint32_t)(v_bq5 + v_bq3));
40961     v_ci71 = ((uint32_t)(v_bq7 + v_bq1));
40962     v_ci73 = ((uint32_t)(v_bq7 + v_bq3));
40963     v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u));
40964     v_ck1 = ((uint32_t)(v_bq1 * 12299u));
40965     v_ck3 = ((uint32_t)(v_bq3 * 25172u));
40966     v_ck5 = ((uint32_t)(v_bq5 * 16819u));
40967     v_ck7 = ((uint32_t)(v_bq7 * 2446u));
40968     v_ci51 *= 4294964100u;
40969     v_ci53 *= 4294946301u;
40970     v_ci71 *= 4294959923u;
40971     v_ci73 *= 4294951227u;
40972     v_cl51 = ((uint32_t)(v_ci51 + v_cj));
40973     v_cl73 = ((uint32_t)(v_ci73 + v_cj));
40974     v_ck1 += ((uint32_t)(v_ci71 + v_cl51));
40975     v_ck3 += ((uint32_t)(v_ci53 + v_cl73));
40976     v_ck5 += ((uint32_t)(v_ci53 + v_cl51));
40977     v_ck7 += ((uint32_t)(v_ci71 + v_cl73));
40978     v_intermediate[2u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u);
40979     v_intermediate[58u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u);
40980     v_intermediate[10u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u);
40981     v_intermediate[50u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u);
40982     v_intermediate[18u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u);
40983     v_intermediate[42u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u);
40984     v_intermediate[26u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u);
40985     v_intermediate[34u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u);
40986   }
40987   if (0u == (self->private_data.f_mcu_blocks[0u][11u] |
40988       self->private_data.f_mcu_blocks[0u][19u] |
40989       self->private_data.f_mcu_blocks[0u][27u] |
40990       self->private_data.f_mcu_blocks[0u][35u] |
40991       self->private_data.f_mcu_blocks[0u][43u] |
40992       self->private_data.f_mcu_blocks[0u][51u] |
40993       self->private_data.f_mcu_blocks[0u][59u])) {
40994     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));
40995     v_intermediate[11u] = v_intermediate[3u];
40996     v_intermediate[19u] = v_intermediate[3u];
40997     v_intermediate[27u] = v_intermediate[3u];
40998     v_intermediate[35u] = v_intermediate[3u];
40999     v_intermediate[43u] = v_intermediate[3u];
41000     v_intermediate[51u] = v_intermediate[3u];
41001     v_intermediate[59u] = v_intermediate[3u];
41002   } else {
41003     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]))));
41004     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]))));
41005     v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u));
41006     v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u))));
41007     v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u))));
41008     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]))));
41009     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]))));
41010     v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u));
41011     v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u));
41012     v_cd0 = ((uint32_t)(v_ccp + v_cb2));
41013     v_cd1 = ((uint32_t)(v_ccm + v_cb6));
41014     v_cd2 = ((uint32_t)(v_ccm - v_cb6));
41015     v_cd3 = ((uint32_t)(v_ccp - v_cb2));
41016     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]))));
41017     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]))));
41018     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]))));
41019     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]))));
41020     v_ci51 = ((uint32_t)(v_bq5 + v_bq1));
41021     v_ci53 = ((uint32_t)(v_bq5 + v_bq3));
41022     v_ci71 = ((uint32_t)(v_bq7 + v_bq1));
41023     v_ci73 = ((uint32_t)(v_bq7 + v_bq3));
41024     v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u));
41025     v_ck1 = ((uint32_t)(v_bq1 * 12299u));
41026     v_ck3 = ((uint32_t)(v_bq3 * 25172u));
41027     v_ck5 = ((uint32_t)(v_bq5 * 16819u));
41028     v_ck7 = ((uint32_t)(v_bq7 * 2446u));
41029     v_ci51 *= 4294964100u;
41030     v_ci53 *= 4294946301u;
41031     v_ci71 *= 4294959923u;
41032     v_ci73 *= 4294951227u;
41033     v_cl51 = ((uint32_t)(v_ci51 + v_cj));
41034     v_cl73 = ((uint32_t)(v_ci73 + v_cj));
41035     v_ck1 += ((uint32_t)(v_ci71 + v_cl51));
41036     v_ck3 += ((uint32_t)(v_ci53 + v_cl73));
41037     v_ck5 += ((uint32_t)(v_ci53 + v_cl51));
41038     v_ck7 += ((uint32_t)(v_ci71 + v_cl73));
41039     v_intermediate[3u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u);
41040     v_intermediate[59u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u);
41041     v_intermediate[11u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u);
41042     v_intermediate[51u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u);
41043     v_intermediate[19u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u);
41044     v_intermediate[43u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u);
41045     v_intermediate[27u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u);
41046     v_intermediate[35u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u);
41047   }
41048   if (0u == (self->private_data.f_mcu_blocks[0u][12u] |
41049       self->private_data.f_mcu_blocks[0u][20u] |
41050       self->private_data.f_mcu_blocks[0u][28u] |
41051       self->private_data.f_mcu_blocks[0u][36u] |
41052       self->private_data.f_mcu_blocks[0u][44u] |
41053       self->private_data.f_mcu_blocks[0u][52u] |
41054       self->private_data.f_mcu_blocks[0u][60u])) {
41055     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));
41056     v_intermediate[12u] = v_intermediate[4u];
41057     v_intermediate[20u] = v_intermediate[4u];
41058     v_intermediate[28u] = v_intermediate[4u];
41059     v_intermediate[36u] = v_intermediate[4u];
41060     v_intermediate[44u] = v_intermediate[4u];
41061     v_intermediate[52u] = v_intermediate[4u];
41062     v_intermediate[60u] = v_intermediate[4u];
41063   } else {
41064     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]))));
41065     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]))));
41066     v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u));
41067     v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u))));
41068     v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u))));
41069     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]))));
41070     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]))));
41071     v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u));
41072     v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u));
41073     v_cd0 = ((uint32_t)(v_ccp + v_cb2));
41074     v_cd1 = ((uint32_t)(v_ccm + v_cb6));
41075     v_cd2 = ((uint32_t)(v_ccm - v_cb6));
41076     v_cd3 = ((uint32_t)(v_ccp - v_cb2));
41077     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]))));
41078     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]))));
41079     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]))));
41080     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]))));
41081     v_ci51 = ((uint32_t)(v_bq5 + v_bq1));
41082     v_ci53 = ((uint32_t)(v_bq5 + v_bq3));
41083     v_ci71 = ((uint32_t)(v_bq7 + v_bq1));
41084     v_ci73 = ((uint32_t)(v_bq7 + v_bq3));
41085     v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u));
41086     v_ck1 = ((uint32_t)(v_bq1 * 12299u));
41087     v_ck3 = ((uint32_t)(v_bq3 * 25172u));
41088     v_ck5 = ((uint32_t)(v_bq5 * 16819u));
41089     v_ck7 = ((uint32_t)(v_bq7 * 2446u));
41090     v_ci51 *= 4294964100u;
41091     v_ci53 *= 4294946301u;
41092     v_ci71 *= 4294959923u;
41093     v_ci73 *= 4294951227u;
41094     v_cl51 = ((uint32_t)(v_ci51 + v_cj));
41095     v_cl73 = ((uint32_t)(v_ci73 + v_cj));
41096     v_ck1 += ((uint32_t)(v_ci71 + v_cl51));
41097     v_ck3 += ((uint32_t)(v_ci53 + v_cl73));
41098     v_ck5 += ((uint32_t)(v_ci53 + v_cl51));
41099     v_ck7 += ((uint32_t)(v_ci71 + v_cl73));
41100     v_intermediate[4u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u);
41101     v_intermediate[60u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u);
41102     v_intermediate[12u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u);
41103     v_intermediate[52u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u);
41104     v_intermediate[20u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u);
41105     v_intermediate[44u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u);
41106     v_intermediate[28u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u);
41107     v_intermediate[36u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u);
41108   }
41109   if (0u == (self->private_data.f_mcu_blocks[0u][13u] |
41110       self->private_data.f_mcu_blocks[0u][21u] |
41111       self->private_data.f_mcu_blocks[0u][29u] |
41112       self->private_data.f_mcu_blocks[0u][37u] |
41113       self->private_data.f_mcu_blocks[0u][45u] |
41114       self->private_data.f_mcu_blocks[0u][53u] |
41115       self->private_data.f_mcu_blocks[0u][61u])) {
41116     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));
41117     v_intermediate[13u] = v_intermediate[5u];
41118     v_intermediate[21u] = v_intermediate[5u];
41119     v_intermediate[29u] = v_intermediate[5u];
41120     v_intermediate[37u] = v_intermediate[5u];
41121     v_intermediate[45u] = v_intermediate[5u];
41122     v_intermediate[53u] = v_intermediate[5u];
41123     v_intermediate[61u] = v_intermediate[5u];
41124   } else {
41125     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]))));
41126     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]))));
41127     v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u));
41128     v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u))));
41129     v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u))));
41130     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]))));
41131     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]))));
41132     v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u));
41133     v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u));
41134     v_cd0 = ((uint32_t)(v_ccp + v_cb2));
41135     v_cd1 = ((uint32_t)(v_ccm + v_cb6));
41136     v_cd2 = ((uint32_t)(v_ccm - v_cb6));
41137     v_cd3 = ((uint32_t)(v_ccp - v_cb2));
41138     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]))));
41139     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]))));
41140     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]))));
41141     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]))));
41142     v_ci51 = ((uint32_t)(v_bq5 + v_bq1));
41143     v_ci53 = ((uint32_t)(v_bq5 + v_bq3));
41144     v_ci71 = ((uint32_t)(v_bq7 + v_bq1));
41145     v_ci73 = ((uint32_t)(v_bq7 + v_bq3));
41146     v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u));
41147     v_ck1 = ((uint32_t)(v_bq1 * 12299u));
41148     v_ck3 = ((uint32_t)(v_bq3 * 25172u));
41149     v_ck5 = ((uint32_t)(v_bq5 * 16819u));
41150     v_ck7 = ((uint32_t)(v_bq7 * 2446u));
41151     v_ci51 *= 4294964100u;
41152     v_ci53 *= 4294946301u;
41153     v_ci71 *= 4294959923u;
41154     v_ci73 *= 4294951227u;
41155     v_cl51 = ((uint32_t)(v_ci51 + v_cj));
41156     v_cl73 = ((uint32_t)(v_ci73 + v_cj));
41157     v_ck1 += ((uint32_t)(v_ci71 + v_cl51));
41158     v_ck3 += ((uint32_t)(v_ci53 + v_cl73));
41159     v_ck5 += ((uint32_t)(v_ci53 + v_cl51));
41160     v_ck7 += ((uint32_t)(v_ci71 + v_cl73));
41161     v_intermediate[5u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u);
41162     v_intermediate[61u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u);
41163     v_intermediate[13u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u);
41164     v_intermediate[53u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u);
41165     v_intermediate[21u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u);
41166     v_intermediate[45u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u);
41167     v_intermediate[29u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u);
41168     v_intermediate[37u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u);
41169   }
41170   if (0u == (self->private_data.f_mcu_blocks[0u][14u] |
41171       self->private_data.f_mcu_blocks[0u][22u] |
41172       self->private_data.f_mcu_blocks[0u][30u] |
41173       self->private_data.f_mcu_blocks[0u][38u] |
41174       self->private_data.f_mcu_blocks[0u][46u] |
41175       self->private_data.f_mcu_blocks[0u][54u] |
41176       self->private_data.f_mcu_blocks[0u][62u])) {
41177     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));
41178     v_intermediate[14u] = v_intermediate[6u];
41179     v_intermediate[22u] = v_intermediate[6u];
41180     v_intermediate[30u] = v_intermediate[6u];
41181     v_intermediate[38u] = v_intermediate[6u];
41182     v_intermediate[46u] = v_intermediate[6u];
41183     v_intermediate[54u] = v_intermediate[6u];
41184     v_intermediate[62u] = v_intermediate[6u];
41185   } else {
41186     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]))));
41187     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]))));
41188     v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u));
41189     v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u))));
41190     v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u))));
41191     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]))));
41192     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]))));
41193     v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u));
41194     v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u));
41195     v_cd0 = ((uint32_t)(v_ccp + v_cb2));
41196     v_cd1 = ((uint32_t)(v_ccm + v_cb6));
41197     v_cd2 = ((uint32_t)(v_ccm - v_cb6));
41198     v_cd3 = ((uint32_t)(v_ccp - v_cb2));
41199     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]))));
41200     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]))));
41201     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]))));
41202     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]))));
41203     v_ci51 = ((uint32_t)(v_bq5 + v_bq1));
41204     v_ci53 = ((uint32_t)(v_bq5 + v_bq3));
41205     v_ci71 = ((uint32_t)(v_bq7 + v_bq1));
41206     v_ci73 = ((uint32_t)(v_bq7 + v_bq3));
41207     v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u));
41208     v_ck1 = ((uint32_t)(v_bq1 * 12299u));
41209     v_ck3 = ((uint32_t)(v_bq3 * 25172u));
41210     v_ck5 = ((uint32_t)(v_bq5 * 16819u));
41211     v_ck7 = ((uint32_t)(v_bq7 * 2446u));
41212     v_ci51 *= 4294964100u;
41213     v_ci53 *= 4294946301u;
41214     v_ci71 *= 4294959923u;
41215     v_ci73 *= 4294951227u;
41216     v_cl51 = ((uint32_t)(v_ci51 + v_cj));
41217     v_cl73 = ((uint32_t)(v_ci73 + v_cj));
41218     v_ck1 += ((uint32_t)(v_ci71 + v_cl51));
41219     v_ck3 += ((uint32_t)(v_ci53 + v_cl73));
41220     v_ck5 += ((uint32_t)(v_ci53 + v_cl51));
41221     v_ck7 += ((uint32_t)(v_ci71 + v_cl73));
41222     v_intermediate[6u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u);
41223     v_intermediate[62u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u);
41224     v_intermediate[14u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u);
41225     v_intermediate[54u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u);
41226     v_intermediate[22u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u);
41227     v_intermediate[46u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u);
41228     v_intermediate[30u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u);
41229     v_intermediate[38u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u);
41230   }
41231   if (0u == (self->private_data.f_mcu_blocks[0u][15u] |
41232       self->private_data.f_mcu_blocks[0u][23u] |
41233       self->private_data.f_mcu_blocks[0u][31u] |
41234       self->private_data.f_mcu_blocks[0u][39u] |
41235       self->private_data.f_mcu_blocks[0u][47u] |
41236       self->private_data.f_mcu_blocks[0u][55u] |
41237       self->private_data.f_mcu_blocks[0u][63u])) {
41238     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));
41239     v_intermediate[15u] = v_intermediate[7u];
41240     v_intermediate[23u] = v_intermediate[7u];
41241     v_intermediate[31u] = v_intermediate[7u];
41242     v_intermediate[39u] = v_intermediate[7u];
41243     v_intermediate[47u] = v_intermediate[7u];
41244     v_intermediate[55u] = v_intermediate[7u];
41245     v_intermediate[63u] = v_intermediate[7u];
41246   } else {
41247     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]))));
41248     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]))));
41249     v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u));
41250     v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u))));
41251     v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u))));
41252     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]))));
41253     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]))));
41254     v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u));
41255     v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u));
41256     v_cd0 = ((uint32_t)(v_ccp + v_cb2));
41257     v_cd1 = ((uint32_t)(v_ccm + v_cb6));
41258     v_cd2 = ((uint32_t)(v_ccm - v_cb6));
41259     v_cd3 = ((uint32_t)(v_ccp - v_cb2));
41260     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]))));
41261     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]))));
41262     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]))));
41263     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]))));
41264     v_ci51 = ((uint32_t)(v_bq5 + v_bq1));
41265     v_ci53 = ((uint32_t)(v_bq5 + v_bq3));
41266     v_ci71 = ((uint32_t)(v_bq7 + v_bq1));
41267     v_ci73 = ((uint32_t)(v_bq7 + v_bq3));
41268     v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u));
41269     v_ck1 = ((uint32_t)(v_bq1 * 12299u));
41270     v_ck3 = ((uint32_t)(v_bq3 * 25172u));
41271     v_ck5 = ((uint32_t)(v_bq5 * 16819u));
41272     v_ck7 = ((uint32_t)(v_bq7 * 2446u));
41273     v_ci51 *= 4294964100u;
41274     v_ci53 *= 4294946301u;
41275     v_ci71 *= 4294959923u;
41276     v_ci73 *= 4294951227u;
41277     v_cl51 = ((uint32_t)(v_ci51 + v_cj));
41278     v_cl73 = ((uint32_t)(v_ci73 + v_cj));
41279     v_ck1 += ((uint32_t)(v_ci71 + v_cl51));
41280     v_ck3 += ((uint32_t)(v_ci53 + v_cl73));
41281     v_ck5 += ((uint32_t)(v_ci53 + v_cl51));
41282     v_ck7 += ((uint32_t)(v_ci71 + v_cl73));
41283     v_intermediate[7u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u);
41284     v_intermediate[63u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u);
41285     v_intermediate[15u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u);
41286     v_intermediate[55u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u);
41287     v_intermediate[23u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u);
41288     v_intermediate[47u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u);
41289     v_intermediate[31u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u);
41290     v_intermediate[39u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u);
41291   }
41292   if (0u == (v_intermediate[1u] |
41293       v_intermediate[2u] |
41294       v_intermediate[3u] |
41295       v_intermediate[4u] |
41296       v_intermediate[5u] |
41297       v_intermediate[6u] |
41298       v_intermediate[7u])) {
41299     if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
41300       return wuffs_base__make_empty_struct();
41301     }
41302     a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[0u] + 16u)) >> 5u) & 1023u)];
41303     a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u];
41304     a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u];
41305     a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u];
41306     a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u];
41307     a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u];
41308     a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u];
41309     a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u];
41310     a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
41311   } else {
41312     v_in2 = v_intermediate[2u];
41313     v_in6 = v_intermediate[6u];
41314     v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u));
41315     v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u))));
41316     v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u))));
41317     v_in0 = v_intermediate[0u];
41318     v_in4 = v_intermediate[4u];
41319     v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u));
41320     v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u));
41321     v_rd0 = ((uint32_t)(v_rcp + v_rb2));
41322     v_rd1 = ((uint32_t)(v_rcm + v_rb6));
41323     v_rd2 = ((uint32_t)(v_rcm - v_rb6));
41324     v_rd3 = ((uint32_t)(v_rcp - v_rb2));
41325     v_in1 = v_intermediate[1u];
41326     v_in3 = v_intermediate[3u];
41327     v_in5 = v_intermediate[5u];
41328     v_in7 = v_intermediate[7u];
41329     v_ri51 = ((uint32_t)(v_in5 + v_in1));
41330     v_ri53 = ((uint32_t)(v_in5 + v_in3));
41331     v_ri71 = ((uint32_t)(v_in7 + v_in1));
41332     v_ri73 = ((uint32_t)(v_in7 + v_in3));
41333     v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u));
41334     v_rk1 = ((uint32_t)(v_in1 * 12299u));
41335     v_rk3 = ((uint32_t)(v_in3 * 25172u));
41336     v_rk5 = ((uint32_t)(v_in5 * 16819u));
41337     v_rk7 = ((uint32_t)(v_in7 * 2446u));
41338     v_ri51 *= 4294964100u;
41339     v_ri53 *= 4294946301u;
41340     v_ri71 *= 4294959923u;
41341     v_ri73 *= 4294951227u;
41342     v_rl51 = ((uint32_t)(v_ri51 + v_rj));
41343     v_rl73 = ((uint32_t)(v_ri73 + v_rj));
41344     v_rk1 += ((uint32_t)(v_ri71 + v_rl51));
41345     v_rk3 += ((uint32_t)(v_ri53 + v_rl73));
41346     v_rk5 += ((uint32_t)(v_ri53 + v_rl51));
41347     v_rk7 += ((uint32_t)(v_ri71 + v_rl73));
41348     if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
41349       return wuffs_base__make_empty_struct();
41350     }
41351     a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)];
41352     a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)];
41353     a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)];
41354     a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)];
41355     a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)];
41356     a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)];
41357     a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)];
41358     a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)];
41359     a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
41360   }
41361   if (0u == (v_intermediate[9u] |
41362       v_intermediate[10u] |
41363       v_intermediate[11u] |
41364       v_intermediate[12u] |
41365       v_intermediate[13u] |
41366       v_intermediate[14u] |
41367       v_intermediate[15u])) {
41368     if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
41369       return wuffs_base__make_empty_struct();
41370     }
41371     a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[8u] + 16u)) >> 5u) & 1023u)];
41372     a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u];
41373     a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u];
41374     a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u];
41375     a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u];
41376     a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u];
41377     a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u];
41378     a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u];
41379     a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
41380   } else {
41381     v_in2 = v_intermediate[10u];
41382     v_in6 = v_intermediate[14u];
41383     v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u));
41384     v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u))));
41385     v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u))));
41386     v_in0 = v_intermediate[8u];
41387     v_in4 = v_intermediate[12u];
41388     v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u));
41389     v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u));
41390     v_rd0 = ((uint32_t)(v_rcp + v_rb2));
41391     v_rd1 = ((uint32_t)(v_rcm + v_rb6));
41392     v_rd2 = ((uint32_t)(v_rcm - v_rb6));
41393     v_rd3 = ((uint32_t)(v_rcp - v_rb2));
41394     v_in1 = v_intermediate[9u];
41395     v_in3 = v_intermediate[11u];
41396     v_in5 = v_intermediate[13u];
41397     v_in7 = v_intermediate[15u];
41398     v_ri51 = ((uint32_t)(v_in5 + v_in1));
41399     v_ri53 = ((uint32_t)(v_in5 + v_in3));
41400     v_ri71 = ((uint32_t)(v_in7 + v_in1));
41401     v_ri73 = ((uint32_t)(v_in7 + v_in3));
41402     v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u));
41403     v_rk1 = ((uint32_t)(v_in1 * 12299u));
41404     v_rk3 = ((uint32_t)(v_in3 * 25172u));
41405     v_rk5 = ((uint32_t)(v_in5 * 16819u));
41406     v_rk7 = ((uint32_t)(v_in7 * 2446u));
41407     v_ri51 *= 4294964100u;
41408     v_ri53 *= 4294946301u;
41409     v_ri71 *= 4294959923u;
41410     v_ri73 *= 4294951227u;
41411     v_rl51 = ((uint32_t)(v_ri51 + v_rj));
41412     v_rl73 = ((uint32_t)(v_ri73 + v_rj));
41413     v_rk1 += ((uint32_t)(v_ri71 + v_rl51));
41414     v_rk3 += ((uint32_t)(v_ri53 + v_rl73));
41415     v_rk5 += ((uint32_t)(v_ri53 + v_rl51));
41416     v_rk7 += ((uint32_t)(v_ri71 + v_rl73));
41417     if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
41418       return wuffs_base__make_empty_struct();
41419     }
41420     a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)];
41421     a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)];
41422     a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)];
41423     a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)];
41424     a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)];
41425     a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)];
41426     a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)];
41427     a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)];
41428     a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
41429   }
41430   if (0u == (v_intermediate[17u] |
41431       v_intermediate[18u] |
41432       v_intermediate[19u] |
41433       v_intermediate[20u] |
41434       v_intermediate[21u] |
41435       v_intermediate[22u] |
41436       v_intermediate[23u])) {
41437     if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
41438       return wuffs_base__make_empty_struct();
41439     }
41440     a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[16u] + 16u)) >> 5u) & 1023u)];
41441     a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u];
41442     a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u];
41443     a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u];
41444     a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u];
41445     a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u];
41446     a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u];
41447     a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u];
41448     a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
41449   } else {
41450     v_in2 = v_intermediate[18u];
41451     v_in6 = v_intermediate[22u];
41452     v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u));
41453     v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u))));
41454     v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u))));
41455     v_in0 = v_intermediate[16u];
41456     v_in4 = v_intermediate[20u];
41457     v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u));
41458     v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u));
41459     v_rd0 = ((uint32_t)(v_rcp + v_rb2));
41460     v_rd1 = ((uint32_t)(v_rcm + v_rb6));
41461     v_rd2 = ((uint32_t)(v_rcm - v_rb6));
41462     v_rd3 = ((uint32_t)(v_rcp - v_rb2));
41463     v_in1 = v_intermediate[17u];
41464     v_in3 = v_intermediate[19u];
41465     v_in5 = v_intermediate[21u];
41466     v_in7 = v_intermediate[23u];
41467     v_ri51 = ((uint32_t)(v_in5 + v_in1));
41468     v_ri53 = ((uint32_t)(v_in5 + v_in3));
41469     v_ri71 = ((uint32_t)(v_in7 + v_in1));
41470     v_ri73 = ((uint32_t)(v_in7 + v_in3));
41471     v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u));
41472     v_rk1 = ((uint32_t)(v_in1 * 12299u));
41473     v_rk3 = ((uint32_t)(v_in3 * 25172u));
41474     v_rk5 = ((uint32_t)(v_in5 * 16819u));
41475     v_rk7 = ((uint32_t)(v_in7 * 2446u));
41476     v_ri51 *= 4294964100u;
41477     v_ri53 *= 4294946301u;
41478     v_ri71 *= 4294959923u;
41479     v_ri73 *= 4294951227u;
41480     v_rl51 = ((uint32_t)(v_ri51 + v_rj));
41481     v_rl73 = ((uint32_t)(v_ri73 + v_rj));
41482     v_rk1 += ((uint32_t)(v_ri71 + v_rl51));
41483     v_rk3 += ((uint32_t)(v_ri53 + v_rl73));
41484     v_rk5 += ((uint32_t)(v_ri53 + v_rl51));
41485     v_rk7 += ((uint32_t)(v_ri71 + v_rl73));
41486     if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
41487       return wuffs_base__make_empty_struct();
41488     }
41489     a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)];
41490     a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)];
41491     a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)];
41492     a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)];
41493     a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)];
41494     a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)];
41495     a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)];
41496     a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)];
41497     a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
41498   }
41499   if (0u == (v_intermediate[25u] |
41500       v_intermediate[26u] |
41501       v_intermediate[27u] |
41502       v_intermediate[28u] |
41503       v_intermediate[29u] |
41504       v_intermediate[30u] |
41505       v_intermediate[31u])) {
41506     if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
41507       return wuffs_base__make_empty_struct();
41508     }
41509     a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[24u] + 16u)) >> 5u) & 1023u)];
41510     a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u];
41511     a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u];
41512     a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u];
41513     a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u];
41514     a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u];
41515     a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u];
41516     a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u];
41517     a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
41518   } else {
41519     v_in2 = v_intermediate[26u];
41520     v_in6 = v_intermediate[30u];
41521     v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u));
41522     v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u))));
41523     v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u))));
41524     v_in0 = v_intermediate[24u];
41525     v_in4 = v_intermediate[28u];
41526     v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u));
41527     v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u));
41528     v_rd0 = ((uint32_t)(v_rcp + v_rb2));
41529     v_rd1 = ((uint32_t)(v_rcm + v_rb6));
41530     v_rd2 = ((uint32_t)(v_rcm - v_rb6));
41531     v_rd3 = ((uint32_t)(v_rcp - v_rb2));
41532     v_in1 = v_intermediate[25u];
41533     v_in3 = v_intermediate[27u];
41534     v_in5 = v_intermediate[29u];
41535     v_in7 = v_intermediate[31u];
41536     v_ri51 = ((uint32_t)(v_in5 + v_in1));
41537     v_ri53 = ((uint32_t)(v_in5 + v_in3));
41538     v_ri71 = ((uint32_t)(v_in7 + v_in1));
41539     v_ri73 = ((uint32_t)(v_in7 + v_in3));
41540     v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u));
41541     v_rk1 = ((uint32_t)(v_in1 * 12299u));
41542     v_rk3 = ((uint32_t)(v_in3 * 25172u));
41543     v_rk5 = ((uint32_t)(v_in5 * 16819u));
41544     v_rk7 = ((uint32_t)(v_in7 * 2446u));
41545     v_ri51 *= 4294964100u;
41546     v_ri53 *= 4294946301u;
41547     v_ri71 *= 4294959923u;
41548     v_ri73 *= 4294951227u;
41549     v_rl51 = ((uint32_t)(v_ri51 + v_rj));
41550     v_rl73 = ((uint32_t)(v_ri73 + v_rj));
41551     v_rk1 += ((uint32_t)(v_ri71 + v_rl51));
41552     v_rk3 += ((uint32_t)(v_ri53 + v_rl73));
41553     v_rk5 += ((uint32_t)(v_ri53 + v_rl51));
41554     v_rk7 += ((uint32_t)(v_ri71 + v_rl73));
41555     if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
41556       return wuffs_base__make_empty_struct();
41557     }
41558     a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)];
41559     a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)];
41560     a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)];
41561     a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)];
41562     a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)];
41563     a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)];
41564     a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)];
41565     a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)];
41566     a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
41567   }
41568   if (0u == (v_intermediate[33u] |
41569       v_intermediate[34u] |
41570       v_intermediate[35u] |
41571       v_intermediate[36u] |
41572       v_intermediate[37u] |
41573       v_intermediate[38u] |
41574       v_intermediate[39u])) {
41575     if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
41576       return wuffs_base__make_empty_struct();
41577     }
41578     a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[32u] + 16u)) >> 5u) & 1023u)];
41579     a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u];
41580     a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u];
41581     a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u];
41582     a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u];
41583     a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u];
41584     a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u];
41585     a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u];
41586     a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
41587   } else {
41588     v_in2 = v_intermediate[34u];
41589     v_in6 = v_intermediate[38u];
41590     v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u));
41591     v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u))));
41592     v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u))));
41593     v_in0 = v_intermediate[32u];
41594     v_in4 = v_intermediate[36u];
41595     v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u));
41596     v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u));
41597     v_rd0 = ((uint32_t)(v_rcp + v_rb2));
41598     v_rd1 = ((uint32_t)(v_rcm + v_rb6));
41599     v_rd2 = ((uint32_t)(v_rcm - v_rb6));
41600     v_rd3 = ((uint32_t)(v_rcp - v_rb2));
41601     v_in1 = v_intermediate[33u];
41602     v_in3 = v_intermediate[35u];
41603     v_in5 = v_intermediate[37u];
41604     v_in7 = v_intermediate[39u];
41605     v_ri51 = ((uint32_t)(v_in5 + v_in1));
41606     v_ri53 = ((uint32_t)(v_in5 + v_in3));
41607     v_ri71 = ((uint32_t)(v_in7 + v_in1));
41608     v_ri73 = ((uint32_t)(v_in7 + v_in3));
41609     v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u));
41610     v_rk1 = ((uint32_t)(v_in1 * 12299u));
41611     v_rk3 = ((uint32_t)(v_in3 * 25172u));
41612     v_rk5 = ((uint32_t)(v_in5 * 16819u));
41613     v_rk7 = ((uint32_t)(v_in7 * 2446u));
41614     v_ri51 *= 4294964100u;
41615     v_ri53 *= 4294946301u;
41616     v_ri71 *= 4294959923u;
41617     v_ri73 *= 4294951227u;
41618     v_rl51 = ((uint32_t)(v_ri51 + v_rj));
41619     v_rl73 = ((uint32_t)(v_ri73 + v_rj));
41620     v_rk1 += ((uint32_t)(v_ri71 + v_rl51));
41621     v_rk3 += ((uint32_t)(v_ri53 + v_rl73));
41622     v_rk5 += ((uint32_t)(v_ri53 + v_rl51));
41623     v_rk7 += ((uint32_t)(v_ri71 + v_rl73));
41624     if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
41625       return wuffs_base__make_empty_struct();
41626     }
41627     a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)];
41628     a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)];
41629     a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)];
41630     a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)];
41631     a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)];
41632     a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)];
41633     a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)];
41634     a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)];
41635     a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
41636   }
41637   if (0u == (v_intermediate[41u] |
41638       v_intermediate[42u] |
41639       v_intermediate[43u] |
41640       v_intermediate[44u] |
41641       v_intermediate[45u] |
41642       v_intermediate[46u] |
41643       v_intermediate[47u])) {
41644     if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
41645       return wuffs_base__make_empty_struct();
41646     }
41647     a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[40u] + 16u)) >> 5u) & 1023u)];
41648     a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u];
41649     a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u];
41650     a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u];
41651     a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u];
41652     a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u];
41653     a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u];
41654     a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u];
41655     a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
41656   } else {
41657     v_in2 = v_intermediate[42u];
41658     v_in6 = v_intermediate[46u];
41659     v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u));
41660     v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u))));
41661     v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u))));
41662     v_in0 = v_intermediate[40u];
41663     v_in4 = v_intermediate[44u];
41664     v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u));
41665     v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u));
41666     v_rd0 = ((uint32_t)(v_rcp + v_rb2));
41667     v_rd1 = ((uint32_t)(v_rcm + v_rb6));
41668     v_rd2 = ((uint32_t)(v_rcm - v_rb6));
41669     v_rd3 = ((uint32_t)(v_rcp - v_rb2));
41670     v_in1 = v_intermediate[41u];
41671     v_in3 = v_intermediate[43u];
41672     v_in5 = v_intermediate[45u];
41673     v_in7 = v_intermediate[47u];
41674     v_ri51 = ((uint32_t)(v_in5 + v_in1));
41675     v_ri53 = ((uint32_t)(v_in5 + v_in3));
41676     v_ri71 = ((uint32_t)(v_in7 + v_in1));
41677     v_ri73 = ((uint32_t)(v_in7 + v_in3));
41678     v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u));
41679     v_rk1 = ((uint32_t)(v_in1 * 12299u));
41680     v_rk3 = ((uint32_t)(v_in3 * 25172u));
41681     v_rk5 = ((uint32_t)(v_in5 * 16819u));
41682     v_rk7 = ((uint32_t)(v_in7 * 2446u));
41683     v_ri51 *= 4294964100u;
41684     v_ri53 *= 4294946301u;
41685     v_ri71 *= 4294959923u;
41686     v_ri73 *= 4294951227u;
41687     v_rl51 = ((uint32_t)(v_ri51 + v_rj));
41688     v_rl73 = ((uint32_t)(v_ri73 + v_rj));
41689     v_rk1 += ((uint32_t)(v_ri71 + v_rl51));
41690     v_rk3 += ((uint32_t)(v_ri53 + v_rl73));
41691     v_rk5 += ((uint32_t)(v_ri53 + v_rl51));
41692     v_rk7 += ((uint32_t)(v_ri71 + v_rl73));
41693     if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
41694       return wuffs_base__make_empty_struct();
41695     }
41696     a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)];
41697     a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)];
41698     a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)];
41699     a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)];
41700     a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)];
41701     a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)];
41702     a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)];
41703     a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)];
41704     a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
41705   }
41706   if (0u == (v_intermediate[49u] |
41707       v_intermediate[50u] |
41708       v_intermediate[51u] |
41709       v_intermediate[52u] |
41710       v_intermediate[53u] |
41711       v_intermediate[54u] |
41712       v_intermediate[55u])) {
41713     if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
41714       return wuffs_base__make_empty_struct();
41715     }
41716     a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[48u] + 16u)) >> 5u) & 1023u)];
41717     a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u];
41718     a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u];
41719     a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u];
41720     a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u];
41721     a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u];
41722     a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u];
41723     a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u];
41724     a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
41725   } else {
41726     v_in2 = v_intermediate[50u];
41727     v_in6 = v_intermediate[54u];
41728     v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u));
41729     v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u))));
41730     v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u))));
41731     v_in0 = v_intermediate[48u];
41732     v_in4 = v_intermediate[52u];
41733     v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u));
41734     v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u));
41735     v_rd0 = ((uint32_t)(v_rcp + v_rb2));
41736     v_rd1 = ((uint32_t)(v_rcm + v_rb6));
41737     v_rd2 = ((uint32_t)(v_rcm - v_rb6));
41738     v_rd3 = ((uint32_t)(v_rcp - v_rb2));
41739     v_in1 = v_intermediate[49u];
41740     v_in3 = v_intermediate[51u];
41741     v_in5 = v_intermediate[53u];
41742     v_in7 = v_intermediate[55u];
41743     v_ri51 = ((uint32_t)(v_in5 + v_in1));
41744     v_ri53 = ((uint32_t)(v_in5 + v_in3));
41745     v_ri71 = ((uint32_t)(v_in7 + v_in1));
41746     v_ri73 = ((uint32_t)(v_in7 + v_in3));
41747     v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u));
41748     v_rk1 = ((uint32_t)(v_in1 * 12299u));
41749     v_rk3 = ((uint32_t)(v_in3 * 25172u));
41750     v_rk5 = ((uint32_t)(v_in5 * 16819u));
41751     v_rk7 = ((uint32_t)(v_in7 * 2446u));
41752     v_ri51 *= 4294964100u;
41753     v_ri53 *= 4294946301u;
41754     v_ri71 *= 4294959923u;
41755     v_ri73 *= 4294951227u;
41756     v_rl51 = ((uint32_t)(v_ri51 + v_rj));
41757     v_rl73 = ((uint32_t)(v_ri73 + v_rj));
41758     v_rk1 += ((uint32_t)(v_ri71 + v_rl51));
41759     v_rk3 += ((uint32_t)(v_ri53 + v_rl73));
41760     v_rk5 += ((uint32_t)(v_ri53 + v_rl51));
41761     v_rk7 += ((uint32_t)(v_ri71 + v_rl73));
41762     if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
41763       return wuffs_base__make_empty_struct();
41764     }
41765     a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)];
41766     a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)];
41767     a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)];
41768     a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)];
41769     a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)];
41770     a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)];
41771     a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)];
41772     a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)];
41773     a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
41774   }
41775   if (0u == (v_intermediate[57u] |
41776       v_intermediate[58u] |
41777       v_intermediate[59u] |
41778       v_intermediate[60u] |
41779       v_intermediate[61u] |
41780       v_intermediate[62u] |
41781       v_intermediate[63u])) {
41782     if (8u > ((uint64_t)(a_dst_buffer.len))) {
41783       return wuffs_base__make_empty_struct();
41784     }
41785     a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[56u] + 16u)) >> 5u) & 1023u)];
41786     a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u];
41787     a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u];
41788     a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u];
41789     a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u];
41790     a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u];
41791     a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u];
41792     a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u];
41793   } else {
41794     v_in2 = v_intermediate[58u];
41795     v_in6 = v_intermediate[62u];
41796     v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u));
41797     v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u))));
41798     v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u))));
41799     v_in0 = v_intermediate[56u];
41800     v_in4 = v_intermediate[60u];
41801     v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u));
41802     v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u));
41803     v_rd0 = ((uint32_t)(v_rcp + v_rb2));
41804     v_rd1 = ((uint32_t)(v_rcm + v_rb6));
41805     v_rd2 = ((uint32_t)(v_rcm - v_rb6));
41806     v_rd3 = ((uint32_t)(v_rcp - v_rb2));
41807     v_in1 = v_intermediate[57u];
41808     v_in3 = v_intermediate[59u];
41809     v_in5 = v_intermediate[61u];
41810     v_in7 = v_intermediate[63u];
41811     v_ri51 = ((uint32_t)(v_in5 + v_in1));
41812     v_ri53 = ((uint32_t)(v_in5 + v_in3));
41813     v_ri71 = ((uint32_t)(v_in7 + v_in1));
41814     v_ri73 = ((uint32_t)(v_in7 + v_in3));
41815     v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u));
41816     v_rk1 = ((uint32_t)(v_in1 * 12299u));
41817     v_rk3 = ((uint32_t)(v_in3 * 25172u));
41818     v_rk5 = ((uint32_t)(v_in5 * 16819u));
41819     v_rk7 = ((uint32_t)(v_in7 * 2446u));
41820     v_ri51 *= 4294964100u;
41821     v_ri53 *= 4294946301u;
41822     v_ri71 *= 4294959923u;
41823     v_ri73 *= 4294951227u;
41824     v_rl51 = ((uint32_t)(v_ri51 + v_rj));
41825     v_rl73 = ((uint32_t)(v_ri73 + v_rj));
41826     v_rk1 += ((uint32_t)(v_ri71 + v_rl51));
41827     v_rk3 += ((uint32_t)(v_ri53 + v_rl73));
41828     v_rk5 += ((uint32_t)(v_ri53 + v_rl51));
41829     v_rk7 += ((uint32_t)(v_ri71 + v_rl73));
41830     if (8u > ((uint64_t)(a_dst_buffer.len))) {
41831       return wuffs_base__make_empty_struct();
41832     }
41833     a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)];
41834     a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)];
41835     a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)];
41836     a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)];
41837     a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)];
41838     a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)];
41839     a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)];
41840     a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)];
41841   }
41842   return wuffs_base__make_empty_struct();
41843 }
41844 
41845 // ‼ WUFFS MULTI-FILE SECTION +x86_avx2
41846 // -------- func jpeg.decoder.decode_idct_x86_avx2
41847 
41848 #if defined(WUFFS_BASE__CPU_ARCH__X86_64)
41849 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2")
41850 WUFFS_BASE__GENERATED_C_CODE
41851 static wuffs_base__empty_struct
wuffs_jpeg__decoder__decode_idct_x86_avx2(wuffs_jpeg__decoder * self,wuffs_base__slice_u8 a_dst_buffer,uint64_t a_dst_stride,uint32_t a_q)41852 wuffs_jpeg__decoder__decode_idct_x86_avx2(
41853     wuffs_jpeg__decoder* self,
41854     wuffs_base__slice_u8 a_dst_buffer,
41855     uint64_t a_dst_stride,
41856     uint32_t a_q) {
41857   __m256i v_k_0000 = {0};
41858   __m256i v_k_8080 = {0};
41859   __m256i v_k_0000_0002 = {0};
41860   __m256i v_k_0001_FFFF = {0};
41861   __m256i v_k_0400_0000 = {0};
41862   __m256i v_k_29CF_1151_D630_1151 = {0};
41863   __m256i v_k_E333_133E_ADFD_1051 = {0};
41864   __m256i v_k_E6DC_25A1_1925_25A1 = {0};
41865   __m256i v_k_ECC1_E333_EFB0_ADFD = {0};
41866   __m128i v_az_coeffs = {0};
41867   __m256i v_az_ah00 = {0};
41868   __m256i v_az_ad00 = {0};
41869   __m256i v_az_eh00 = {0};
41870   __m256i v_az_adeh = {0};
41871   __m256i v_rows01 = {0};
41872   __m256i v_rows23 = {0};
41873   __m256i v_rows45 = {0};
41874   __m256i v_rows67 = {0};
41875   __m256i v_quants01 = {0};
41876   __m256i v_quants23 = {0};
41877   __m256i v_quants45 = {0};
41878   __m256i v_quants67 = {0};
41879   __m256i v_rows04 = {0};
41880   __m256i v_rows31 = {0};
41881   __m256i v_rows26 = {0};
41882   __m256i v_rows75 = {0};
41883   __m256i v_fp_rows62 = {0};
41884   __m256i v_fp_bq2662ad = {0};
41885   __m256i v_fp_bq2662eh = {0};
41886   __m256i v_fp_cb26ad = {0};
41887   __m256i v_fp_cb26eh = {0};
41888   __m256i v_fp_rows40pos = {0};
41889   __m256i v_fp_rows04neg = {0};
41890   __m256i v_fp_rows0pm4 = {0};
41891   __m256i v_fp_ccpmad = {0};
41892   __m256i v_fp_ccpmeh = {0};
41893   __m256i v_fp_cd01ad = {0};
41894   __m256i v_fp_cd01eh = {0};
41895   __m256i v_fp_cd32ad = {0};
41896   __m256i v_fp_cd32eh = {0};
41897   __m256i v_fp_sums7351 = {0};
41898   __m256i v_fp_sums5173 = {0};
41899   __m256i v_fp_ci73515173ad = {0};
41900   __m256i v_fp_ci73515173eh = {0};
41901   __m256i v_fp_cl7351ad = {0};
41902   __m256i v_fp_cl7351eh = {0};
41903   __m256i v_fp_rows13 = {0};
41904   __m256i v_fp_bq7153ad = {0};
41905   __m256i v_fp_bq7153eh = {0};
41906   __m256i v_fp_ck75ad = {0};
41907   __m256i v_fp_ck75eh = {0};
41908   __m256i v_fp_cl5173ad = {0};
41909   __m256i v_fp_cl5173eh = {0};
41910   __m256i v_fp_ck13ad = {0};
41911   __m256i v_fp_ck13eh = {0};
41912   __m256i v_intermediate01ad = {0};
41913   __m256i v_intermediate01eh = {0};
41914   __m256i v_intermediate01 = {0};
41915   __m256i v_intermediate32ad = {0};
41916   __m256i v_intermediate32eh = {0};
41917   __m256i v_intermediate32 = {0};
41918   __m256i v_intermediate45ad = {0};
41919   __m256i v_intermediate45eh = {0};
41920   __m256i v_intermediate45 = {0};
41921   __m256i v_intermediate76ad = {0};
41922   __m256i v_intermediate76eh = {0};
41923   __m256i v_intermediate76 = {0};
41924   __m256i v_ita0a1e0e1 = {0};
41925   __m256i v_ita2a3e2e3 = {0};
41926   __m256i v_ita4a5e4e5 = {0};
41927   __m256i v_ita6a7e6e7 = {0};
41928   __m256i v_ita0c0e0g0 = {0};
41929   __m256i v_ita1c1e1g1 = {0};
41930   __m256i v_ita4c4e4g4 = {0};
41931   __m256i v_ita5c5e5g5 = {0};
41932   __m256i v_ita0b0e0f0 = {0};
41933   __m256i v_ita4b4e4f4 = {0};
41934   __m256i v_itc0d0g0h0 = {0};
41935   __m256i v_itc4d4g4h4 = {0};
41936   __m256i v_intermediateae = {0};
41937   __m256i v_intermediatebf = {0};
41938   __m256i v_intermediatecg = {0};
41939   __m256i v_intermediatedh = {0};
41940   __m256i v_intermediatedb = {0};
41941   __m256i v_intermediatehf = {0};
41942   __m256i v_sp_cols62 = {0};
41943   __m256i v_sp_bq2662ad = {0};
41944   __m256i v_sp_bq2662eh = {0};
41945   __m256i v_sp_rb26ad = {0};
41946   __m256i v_sp_rb26eh = {0};
41947   __m256i v_sp_cols40pos = {0};
41948   __m256i v_sp_cols04neg = {0};
41949   __m256i v_sp_cols0pm4 = {0};
41950   __m256i v_sp_rcpmad = {0};
41951   __m256i v_sp_rcpmeh = {0};
41952   __m256i v_sp_rd01ad = {0};
41953   __m256i v_sp_rd01eh = {0};
41954   __m256i v_sp_rd32ad = {0};
41955   __m256i v_sp_rd32eh = {0};
41956   __m256i v_sp_sums7351 = {0};
41957   __m256i v_sp_sums5173 = {0};
41958   __m256i v_sp_ri73515173ad = {0};
41959   __m256i v_sp_ri73515173eh = {0};
41960   __m256i v_sp_rl7351ad = {0};
41961   __m256i v_sp_rl7351eh = {0};
41962   __m256i v_sp_cols13 = {0};
41963   __m256i v_sp_bq7153ad = {0};
41964   __m256i v_sp_bq7153eh = {0};
41965   __m256i v_sp_rk75ad = {0};
41966   __m256i v_sp_rk75eh = {0};
41967   __m256i v_sp_rl5173ad = {0};
41968   __m256i v_sp_rl5173eh = {0};
41969   __m256i v_sp_rk13ad = {0};
41970   __m256i v_sp_rk13eh = {0};
41971   __m256i v_final01ad = {0};
41972   __m256i v_final01eh = {0};
41973   __m256i v_final01 = {0};
41974   __m256i v_final32ad = {0};
41975   __m256i v_final32eh = {0};
41976   __m256i v_final32 = {0};
41977   __m256i v_final45ad = {0};
41978   __m256i v_final45eh = {0};
41979   __m256i v_final45 = {0};
41980   __m256i v_final76ad = {0};
41981   __m256i v_final76eh = {0};
41982   __m256i v_final76 = {0};
41983   __m256i v_fta0a1e0e1 = {0};
41984   __m256i v_fta2a3e2e3 = {0};
41985   __m256i v_fta4a5e4e5 = {0};
41986   __m256i v_fta6a7e6e7 = {0};
41987   __m256i v_fta0c0e0g0 = {0};
41988   __m256i v_fta1c1e1g1 = {0};
41989   __m256i v_fta4c4e4g4 = {0};
41990   __m256i v_fta5c5e5g5 = {0};
41991   __m256i v_fta0b0e0f0 = {0};
41992   __m256i v_ftc0d0g0h0 = {0};
41993   __m256i v_fta4b4e4f4 = {0};
41994   __m256i v_ftc4d4g4h4 = {0};
41995   __m256i v_finalae = {0};
41996   __m256i v_finalbf = {0};
41997   __m256i v_finalcg = {0};
41998   __m256i v_finaldh = {0};
41999   __m256i v_final0145 = {0};
42000   __m256i v_final2367 = {0};
42001   uint64_t v_final0 = 0;
42002   uint64_t v_final1 = 0;
42003   uint64_t v_final2 = 0;
42004   uint64_t v_final3 = 0;
42005   uint64_t v_final4 = 0;
42006   uint64_t v_final5 = 0;
42007   uint64_t v_final6 = 0;
42008   uint64_t v_final7 = 0;
42009   wuffs_base__slice_u8 v_remaining = {0};
42010 
42011   if (8u > a_dst_stride) {
42012     return wuffs_base__make_empty_struct();
42013   }
42014   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));
42015   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));
42016   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));
42017   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));
42018   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));
42019   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));
42020   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));
42021   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));
42022   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));
42023   do {
42024     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)))) {
42025       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)));
42026       if (0u == ((uint64_t)(_mm_cvtsi128_si64(_mm_packs_epi16(v_az_coeffs, v_az_coeffs))))) {
42027         v_rows01 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 0u));
42028         v_quants01 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_impl.f_quant_tables[a_q] + 0u));
42029         v_rows01 = _mm256_mullo_epi16(v_rows01, v_quants01);
42030         v_az_ah00 = _mm256_slli_epi16(v_rows01, (int32_t)(2u));
42031         v_az_ad00 = _mm256_unpacklo_epi16(v_az_ah00, v_az_ah00);
42032         v_az_eh00 = _mm256_unpackhi_epi16(v_az_ah00, v_az_ah00);
42033         v_az_adeh = _mm256_inserti128_si256(v_az_ad00, _mm256_castsi256_si128(v_az_eh00), (int32_t)(1u));
42034         v_intermediateae = _mm256_shuffle_epi32(v_az_adeh, (int32_t)(0u));
42035         v_intermediatebf = _mm256_shuffle_epi32(v_az_adeh, (int32_t)(85u));
42036         v_intermediatecg = _mm256_shuffle_epi32(v_az_adeh, (int32_t)(170u));
42037         v_intermediatedh = _mm256_shuffle_epi32(v_az_adeh, (int32_t)(255u));
42038         break;
42039       }
42040     }
42041     v_rows01 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 0u));
42042     v_rows23 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 16u));
42043     v_rows45 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 32u));
42044     v_rows67 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 48u));
42045     v_quants01 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_impl.f_quant_tables[a_q] + 0u));
42046     v_quants23 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_impl.f_quant_tables[a_q] + 16u));
42047     v_quants45 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_impl.f_quant_tables[a_q] + 32u));
42048     v_quants67 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_impl.f_quant_tables[a_q] + 48u));
42049     v_rows01 = _mm256_mullo_epi16(v_rows01, v_quants01);
42050     v_rows23 = _mm256_mullo_epi16(v_rows23, v_quants23);
42051     v_rows45 = _mm256_mullo_epi16(v_rows45, v_quants45);
42052     v_rows67 = _mm256_mullo_epi16(v_rows67, v_quants67);
42053     v_rows04 = _mm256_permute2x128_si256(v_rows01, v_rows45, (int32_t)(32u));
42054     v_rows31 = _mm256_permute2x128_si256(v_rows23, v_rows01, (int32_t)(49u));
42055     v_rows26 = _mm256_permute2x128_si256(v_rows23, v_rows67, (int32_t)(32u));
42056     v_rows75 = _mm256_permute2x128_si256(v_rows67, v_rows45, (int32_t)(49u));
42057     v_fp_rows62 = _mm256_permute2x128_si256(v_rows26, v_rows26, (int32_t)(1u));
42058     v_fp_bq2662ad = _mm256_unpacklo_epi16(v_rows26, v_fp_rows62);
42059     v_fp_bq2662eh = _mm256_unpackhi_epi16(v_rows26, v_fp_rows62);
42060     v_fp_cb26ad = _mm256_madd_epi16(v_fp_bq2662ad, v_k_29CF_1151_D630_1151);
42061     v_fp_cb26eh = _mm256_madd_epi16(v_fp_bq2662eh, v_k_29CF_1151_D630_1151);
42062     v_fp_rows40pos = _mm256_permute2x128_si256(v_rows04, v_rows04, (int32_t)(1u));
42063     v_fp_rows04neg = _mm256_sign_epi16(v_rows04, v_k_0001_FFFF);
42064     v_fp_rows0pm4 = _mm256_add_epi16(v_fp_rows40pos, v_fp_rows04neg);
42065     v_fp_ccpmad = _mm256_srai_epi32(_mm256_unpacklo_epi16(v_k_0000, v_fp_rows0pm4), (int32_t)(3u));
42066     v_fp_ccpmeh = _mm256_srai_epi32(_mm256_unpackhi_epi16(v_k_0000, v_fp_rows0pm4), (int32_t)(3u));
42067     v_fp_cd01ad = _mm256_add_epi32(v_fp_ccpmad, v_fp_cb26ad);
42068     v_fp_cd01eh = _mm256_add_epi32(v_fp_ccpmeh, v_fp_cb26eh);
42069     v_fp_cd32ad = _mm256_sub_epi32(v_fp_ccpmad, v_fp_cb26ad);
42070     v_fp_cd32eh = _mm256_sub_epi32(v_fp_ccpmeh, v_fp_cb26eh);
42071     v_fp_sums7351 = _mm256_add_epi16(v_rows75, v_rows31);
42072     v_fp_sums5173 = _mm256_permute2x128_si256(v_fp_sums7351, v_fp_sums7351, (int32_t)(1u));
42073     v_fp_ci73515173ad = _mm256_unpacklo_epi16(v_fp_sums7351, v_fp_sums5173);
42074     v_fp_ci73515173eh = _mm256_unpackhi_epi16(v_fp_sums7351, v_fp_sums5173);
42075     v_fp_cl7351ad = _mm256_madd_epi16(v_fp_ci73515173ad, v_k_E6DC_25A1_1925_25A1);
42076     v_fp_cl7351eh = _mm256_madd_epi16(v_fp_ci73515173eh, v_k_E6DC_25A1_1925_25A1);
42077     v_fp_rows13 = _mm256_permute2x128_si256(v_rows31, v_rows31, (int32_t)(1u));
42078     v_fp_bq7153ad = _mm256_unpacklo_epi16(v_rows75, v_fp_rows13);
42079     v_fp_bq7153eh = _mm256_unpackhi_epi16(v_rows75, v_fp_rows13);
42080     v_fp_ck75ad = _mm256_add_epi32(_mm256_madd_epi16(v_fp_bq7153ad, v_k_ECC1_E333_EFB0_ADFD), v_fp_cl7351ad);
42081     v_fp_ck75eh = _mm256_add_epi32(_mm256_madd_epi16(v_fp_bq7153eh, v_k_ECC1_E333_EFB0_ADFD), v_fp_cl7351eh);
42082     v_fp_cl5173ad = _mm256_permute2x128_si256(v_fp_cl7351ad, v_fp_cl7351ad, (int32_t)(1u));
42083     v_fp_cl5173eh = _mm256_permute2x128_si256(v_fp_cl7351eh, v_fp_cl7351eh, (int32_t)(1u));
42084     v_fp_ck13ad = _mm256_add_epi32(v_fp_cl5173ad, _mm256_madd_epi16(v_fp_bq7153ad, v_k_E333_133E_ADFD_1051));
42085     v_fp_ck13eh = _mm256_add_epi32(v_fp_cl5173eh, _mm256_madd_epi16(v_fp_bq7153eh, v_k_E333_133E_ADFD_1051));
42086     v_intermediate01ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_fp_cd01ad, v_fp_ck13ad), v_k_0400_0000), (int32_t)(11u));
42087     v_intermediate01eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_fp_cd01eh, v_fp_ck13eh), v_k_0400_0000), (int32_t)(11u));
42088     v_intermediate01 = _mm256_packs_epi32(v_intermediate01ad, v_intermediate01eh);
42089     v_intermediate32ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_fp_cd32ad, v_fp_ck75ad), v_k_0400_0000), (int32_t)(11u));
42090     v_intermediate32eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_fp_cd32eh, v_fp_ck75eh), v_k_0400_0000), (int32_t)(11u));
42091     v_intermediate32 = _mm256_packs_epi32(v_intermediate32ad, v_intermediate32eh);
42092     v_intermediate45ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_fp_cd32ad, v_fp_ck75ad), v_k_0400_0000), (int32_t)(11u));
42093     v_intermediate45eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_fp_cd32eh, v_fp_ck75eh), v_k_0400_0000), (int32_t)(11u));
42094     v_intermediate45 = _mm256_packs_epi32(v_intermediate45ad, v_intermediate45eh);
42095     v_intermediate76ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_fp_cd01ad, v_fp_ck13ad), v_k_0400_0000), (int32_t)(11u));
42096     v_intermediate76eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_fp_cd01eh, v_fp_ck13eh), v_k_0400_0000), (int32_t)(11u));
42097     v_intermediate76 = _mm256_packs_epi32(v_intermediate76ad, v_intermediate76eh);
42098     v_ita0a1e0e1 = _mm256_permute4x64_epi64(v_intermediate01, (int32_t)(216u));
42099     v_ita2a3e2e3 = _mm256_permute4x64_epi64(v_intermediate32, (int32_t)(114u));
42100     v_ita4a5e4e5 = _mm256_permute4x64_epi64(v_intermediate45, (int32_t)(216u));
42101     v_ita6a7e6e7 = _mm256_permute4x64_epi64(v_intermediate76, (int32_t)(114u));
42102     v_ita0c0e0g0 = _mm256_unpacklo_epi16(v_ita0a1e0e1, v_ita2a3e2e3);
42103     v_ita1c1e1g1 = _mm256_unpackhi_epi16(v_ita0a1e0e1, v_ita2a3e2e3);
42104     v_ita4c4e4g4 = _mm256_unpacklo_epi16(v_ita4a5e4e5, v_ita6a7e6e7);
42105     v_ita5c5e5g5 = _mm256_unpackhi_epi16(v_ita4a5e4e5, v_ita6a7e6e7);
42106     v_ita0b0e0f0 = _mm256_unpacklo_epi16(v_ita0c0e0g0, v_ita1c1e1g1);
42107     v_itc0d0g0h0 = _mm256_unpackhi_epi16(v_ita0c0e0g0, v_ita1c1e1g1);
42108     v_ita4b4e4f4 = _mm256_unpacklo_epi16(v_ita4c4e4g4, v_ita5c5e5g5);
42109     v_itc4d4g4h4 = _mm256_unpackhi_epi16(v_ita4c4e4g4, v_ita5c5e5g5);
42110     v_intermediateae = _mm256_unpacklo_epi64(v_ita0b0e0f0, v_ita4b4e4f4);
42111     v_intermediatebf = _mm256_unpackhi_epi64(v_ita0b0e0f0, v_ita4b4e4f4);
42112     v_intermediatecg = _mm256_unpacklo_epi64(v_itc0d0g0h0, v_itc4d4g4h4);
42113     v_intermediatedh = _mm256_unpackhi_epi64(v_itc0d0g0h0, v_itc4d4g4h4);
42114   } while (0);
42115   v_intermediatedb = _mm256_permute2x128_si256(v_intermediatedh, v_intermediatebf, (int32_t)(32u));
42116   v_intermediatehf = _mm256_permute2x128_si256(v_intermediatedh, v_intermediatebf, (int32_t)(49u));
42117   v_sp_cols62 = _mm256_permute2x128_si256(v_intermediatecg, v_intermediatecg, (int32_t)(1u));
42118   v_sp_bq2662ad = _mm256_unpacklo_epi16(v_intermediatecg, v_sp_cols62);
42119   v_sp_bq2662eh = _mm256_unpackhi_epi16(v_intermediatecg, v_sp_cols62);
42120   v_sp_rb26ad = _mm256_madd_epi16(v_sp_bq2662ad, v_k_29CF_1151_D630_1151);
42121   v_sp_rb26eh = _mm256_madd_epi16(v_sp_bq2662eh, v_k_29CF_1151_D630_1151);
42122   v_sp_cols40pos = _mm256_permute2x128_si256(v_intermediateae, v_intermediateae, (int32_t)(1u));
42123   v_sp_cols04neg = _mm256_sign_epi16(v_intermediateae, v_k_0001_FFFF);
42124   v_sp_cols0pm4 = _mm256_add_epi16(v_sp_cols40pos, v_sp_cols04neg);
42125   v_sp_rcpmad = _mm256_srai_epi32(_mm256_unpacklo_epi16(v_k_0000, v_sp_cols0pm4), (int32_t)(3u));
42126   v_sp_rcpmeh = _mm256_srai_epi32(_mm256_unpackhi_epi16(v_k_0000, v_sp_cols0pm4), (int32_t)(3u));
42127   v_sp_rd01ad = _mm256_add_epi32(v_sp_rcpmad, v_sp_rb26ad);
42128   v_sp_rd01eh = _mm256_add_epi32(v_sp_rcpmeh, v_sp_rb26eh);
42129   v_sp_rd32ad = _mm256_sub_epi32(v_sp_rcpmad, v_sp_rb26ad);
42130   v_sp_rd32eh = _mm256_sub_epi32(v_sp_rcpmeh, v_sp_rb26eh);
42131   v_sp_sums7351 = _mm256_add_epi16(v_intermediatehf, v_intermediatedb);
42132   v_sp_sums5173 = _mm256_permute2x128_si256(v_sp_sums7351, v_sp_sums7351, (int32_t)(1u));
42133   v_sp_ri73515173ad = _mm256_unpacklo_epi16(v_sp_sums7351, v_sp_sums5173);
42134   v_sp_ri73515173eh = _mm256_unpackhi_epi16(v_sp_sums7351, v_sp_sums5173);
42135   v_sp_rl7351ad = _mm256_madd_epi16(v_sp_ri73515173ad, v_k_E6DC_25A1_1925_25A1);
42136   v_sp_rl7351eh = _mm256_madd_epi16(v_sp_ri73515173eh, v_k_E6DC_25A1_1925_25A1);
42137   v_sp_cols13 = _mm256_permute2x128_si256(v_intermediatedb, v_intermediatedb, (int32_t)(1u));
42138   v_sp_bq7153ad = _mm256_unpacklo_epi16(v_intermediatehf, v_sp_cols13);
42139   v_sp_bq7153eh = _mm256_unpackhi_epi16(v_intermediatehf, v_sp_cols13);
42140   v_sp_rk75ad = _mm256_add_epi32(_mm256_madd_epi16(v_sp_bq7153ad, v_k_ECC1_E333_EFB0_ADFD), v_sp_rl7351ad);
42141   v_sp_rk75eh = _mm256_add_epi32(_mm256_madd_epi16(v_sp_bq7153eh, v_k_ECC1_E333_EFB0_ADFD), v_sp_rl7351eh);
42142   v_sp_rl5173ad = _mm256_permute2x128_si256(v_sp_rl7351ad, v_sp_rl7351ad, (int32_t)(1u));
42143   v_sp_rl5173eh = _mm256_permute2x128_si256(v_sp_rl7351eh, v_sp_rl7351eh, (int32_t)(1u));
42144   v_sp_rk13ad = _mm256_add_epi32(v_sp_rl5173ad, _mm256_madd_epi16(v_sp_bq7153ad, v_k_E333_133E_ADFD_1051));
42145   v_sp_rk13eh = _mm256_add_epi32(v_sp_rl5173eh, _mm256_madd_epi16(v_sp_bq7153eh, v_k_E333_133E_ADFD_1051));
42146   v_final01ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_sp_rd01ad, v_sp_rk13ad), v_k_0000_0002), (int32_t)(18u));
42147   v_final01eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_sp_rd01eh, v_sp_rk13eh), v_k_0000_0002), (int32_t)(18u));
42148   v_final01 = _mm256_packs_epi32(v_final01ad, v_final01eh);
42149   v_final32ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_sp_rd32ad, v_sp_rk75ad), v_k_0000_0002), (int32_t)(18u));
42150   v_final32eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_sp_rd32eh, v_sp_rk75eh), v_k_0000_0002), (int32_t)(18u));
42151   v_final32 = _mm256_packs_epi32(v_final32ad, v_final32eh);
42152   v_final45ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_sp_rd32ad, v_sp_rk75ad), v_k_0000_0002), (int32_t)(18u));
42153   v_final45eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_sp_rd32eh, v_sp_rk75eh), v_k_0000_0002), (int32_t)(18u));
42154   v_final45 = _mm256_packs_epi32(v_final45ad, v_final45eh);
42155   v_final76ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_sp_rd01ad, v_sp_rk13ad), v_k_0000_0002), (int32_t)(18u));
42156   v_final76eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_sp_rd01eh, v_sp_rk13eh), v_k_0000_0002), (int32_t)(18u));
42157   v_final76 = _mm256_packs_epi32(v_final76ad, v_final76eh);
42158   v_fta0a1e0e1 = _mm256_permute4x64_epi64(v_final01, (int32_t)(216u));
42159   v_fta2a3e2e3 = _mm256_permute4x64_epi64(v_final32, (int32_t)(114u));
42160   v_fta4a5e4e5 = _mm256_permute4x64_epi64(v_final45, (int32_t)(216u));
42161   v_fta6a7e6e7 = _mm256_permute4x64_epi64(v_final76, (int32_t)(114u));
42162   v_fta0c0e0g0 = _mm256_unpacklo_epi16(v_fta0a1e0e1, v_fta2a3e2e3);
42163   v_fta1c1e1g1 = _mm256_unpackhi_epi16(v_fta0a1e0e1, v_fta2a3e2e3);
42164   v_fta4c4e4g4 = _mm256_unpacklo_epi16(v_fta4a5e4e5, v_fta6a7e6e7);
42165   v_fta5c5e5g5 = _mm256_unpackhi_epi16(v_fta4a5e4e5, v_fta6a7e6e7);
42166   v_fta0b0e0f0 = _mm256_unpacklo_epi16(v_fta0c0e0g0, v_fta1c1e1g1);
42167   v_ftc0d0g0h0 = _mm256_unpackhi_epi16(v_fta0c0e0g0, v_fta1c1e1g1);
42168   v_fta4b4e4f4 = _mm256_unpacklo_epi16(v_fta4c4e4g4, v_fta5c5e5g5);
42169   v_ftc4d4g4h4 = _mm256_unpackhi_epi16(v_fta4c4e4g4, v_fta5c5e5g5);
42170   v_finalae = _mm256_unpacklo_epi64(v_fta0b0e0f0, v_fta4b4e4f4);
42171   v_finalbf = _mm256_unpackhi_epi64(v_fta0b0e0f0, v_fta4b4e4f4);
42172   v_finalcg = _mm256_unpacklo_epi64(v_ftc0d0g0h0, v_ftc4d4g4h4);
42173   v_finaldh = _mm256_unpackhi_epi64(v_ftc0d0g0h0, v_ftc4d4g4h4);
42174   v_final0145 = _mm256_add_epi8(_mm256_packs_epi16(v_finalae, v_finalbf), v_k_8080);
42175   v_final2367 = _mm256_add_epi8(_mm256_packs_epi16(v_finalcg, v_finaldh), v_k_8080);
42176   v_final0 = ((uint64_t)(_mm256_extract_epi64(v_final0145, (int32_t)(0u))));
42177   v_final1 = ((uint64_t)(_mm256_extract_epi64(v_final0145, (int32_t)(1u))));
42178   v_final2 = ((uint64_t)(_mm256_extract_epi64(v_final2367, (int32_t)(0u))));
42179   v_final3 = ((uint64_t)(_mm256_extract_epi64(v_final2367, (int32_t)(1u))));
42180   v_final4 = ((uint64_t)(_mm256_extract_epi64(v_final0145, (int32_t)(2u))));
42181   v_final5 = ((uint64_t)(_mm256_extract_epi64(v_final0145, (int32_t)(3u))));
42182   v_final6 = ((uint64_t)(_mm256_extract_epi64(v_final2367, (int32_t)(2u))));
42183   v_final7 = ((uint64_t)(_mm256_extract_epi64(v_final2367, (int32_t)(3u))));
42184   if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
42185     return wuffs_base__make_empty_struct();
42186   }
42187   v_remaining = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
42188   wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final0);
42189   a_dst_buffer = v_remaining;
42190   if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
42191     return wuffs_base__make_empty_struct();
42192   }
42193   v_remaining = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
42194   wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final1);
42195   a_dst_buffer = v_remaining;
42196   if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
42197     return wuffs_base__make_empty_struct();
42198   }
42199   v_remaining = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
42200   wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final2);
42201   a_dst_buffer = v_remaining;
42202   if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
42203     return wuffs_base__make_empty_struct();
42204   }
42205   v_remaining = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
42206   wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final3);
42207   a_dst_buffer = v_remaining;
42208   if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
42209     return wuffs_base__make_empty_struct();
42210   }
42211   v_remaining = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
42212   wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final4);
42213   a_dst_buffer = v_remaining;
42214   if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
42215     return wuffs_base__make_empty_struct();
42216   }
42217   v_remaining = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
42218   wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final5);
42219   a_dst_buffer = v_remaining;
42220   if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
42221     return wuffs_base__make_empty_struct();
42222   }
42223   v_remaining = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
42224   wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final6);
42225   a_dst_buffer = v_remaining;
42226   if (8u > ((uint64_t)(a_dst_buffer.len))) {
42227     return wuffs_base__make_empty_struct();
42228   }
42229   wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final7);
42230   return wuffs_base__make_empty_struct();
42231 }
42232 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_64)
42233 // ‼ WUFFS MULTI-FILE SECTION -x86_avx2
42234 
42235 // -------- func jpeg.decoder.get_quirk
42236 
42237 WUFFS_BASE__GENERATED_C_CODE
42238 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_jpeg__decoder__get_quirk(const wuffs_jpeg__decoder * self,uint32_t a_key)42239 wuffs_jpeg__decoder__get_quirk(
42240     const wuffs_jpeg__decoder* self,
42241     uint32_t a_key) {
42242   if (!self) {
42243     return 0;
42244   }
42245   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
42246       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
42247     return 0;
42248   }
42249 
42250   return 0u;
42251 }
42252 
42253 // -------- func jpeg.decoder.set_quirk
42254 
42255 WUFFS_BASE__GENERATED_C_CODE
42256 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_jpeg__decoder__set_quirk(wuffs_jpeg__decoder * self,uint32_t a_key,uint64_t a_value)42257 wuffs_jpeg__decoder__set_quirk(
42258     wuffs_jpeg__decoder* self,
42259     uint32_t a_key,
42260     uint64_t a_value) {
42261   if (!self) {
42262     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
42263   }
42264   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
42265     return wuffs_base__make_status(
42266         (self->private_impl.magic == WUFFS_BASE__DISABLED)
42267         ? wuffs_base__error__disabled_by_previous_error
42268         : wuffs_base__error__initialize_not_called);
42269   }
42270 
42271   return wuffs_base__make_status(wuffs_base__error__unsupported_option);
42272 }
42273 
42274 // -------- func jpeg.decoder.decode_image_config
42275 
42276 WUFFS_BASE__GENERATED_C_CODE
42277 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_jpeg__decoder__decode_image_config(wuffs_jpeg__decoder * self,wuffs_base__image_config * a_dst,wuffs_base__io_buffer * a_src)42278 wuffs_jpeg__decoder__decode_image_config(
42279     wuffs_jpeg__decoder* self,
42280     wuffs_base__image_config* a_dst,
42281     wuffs_base__io_buffer* a_src) {
42282   if (!self) {
42283     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
42284   }
42285   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
42286     return wuffs_base__make_status(
42287         (self->private_impl.magic == WUFFS_BASE__DISABLED)
42288         ? wuffs_base__error__disabled_by_previous_error
42289         : wuffs_base__error__initialize_not_called);
42290   }
42291   if (!a_src) {
42292     self->private_impl.magic = WUFFS_BASE__DISABLED;
42293     return wuffs_base__make_status(wuffs_base__error__bad_argument);
42294   }
42295   if ((self->private_impl.active_coroutine != 0) &&
42296       (self->private_impl.active_coroutine != 1)) {
42297     self->private_impl.magic = WUFFS_BASE__DISABLED;
42298     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
42299   }
42300   self->private_impl.active_coroutine = 0;
42301   wuffs_base__status status = wuffs_base__make_status(NULL);
42302 
42303   wuffs_base__status v_status = wuffs_base__make_status(NULL);
42304 
42305   uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
42306   switch (coro_susp_point) {
42307     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
42308 
42309     while (true) {
42310       {
42311         wuffs_base__status t_0 = wuffs_jpeg__decoder__do_decode_image_config(self, a_dst, a_src);
42312         v_status = t_0;
42313       }
42314       if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
42315         status = wuffs_base__make_status(wuffs_jpeg__error__truncated_input);
42316         goto exit;
42317       }
42318       status = v_status;
42319       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
42320     }
42321 
42322     ok:
42323     self->private_impl.p_decode_image_config[0] = 0;
42324     goto exit;
42325   }
42326 
42327   goto suspend;
42328   suspend:
42329   self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
42330   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
42331 
42332   goto exit;
42333   exit:
42334   if (wuffs_base__status__is_error(&status)) {
42335     self->private_impl.magic = WUFFS_BASE__DISABLED;
42336   }
42337   return status;
42338 }
42339 
42340 // -------- func jpeg.decoder.do_decode_image_config
42341 
42342 WUFFS_BASE__GENERATED_C_CODE
42343 static wuffs_base__status
wuffs_jpeg__decoder__do_decode_image_config(wuffs_jpeg__decoder * self,wuffs_base__image_config * a_dst,wuffs_base__io_buffer * a_src)42344 wuffs_jpeg__decoder__do_decode_image_config(
42345     wuffs_jpeg__decoder* self,
42346     wuffs_base__image_config* a_dst,
42347     wuffs_base__io_buffer* a_src) {
42348   wuffs_base__status status = wuffs_base__make_status(NULL);
42349 
42350   uint8_t v_c = 0;
42351   uint8_t v_marker = 0;
42352   uint32_t v_pixfmt = 0;
42353 
42354   const uint8_t* iop_a_src = NULL;
42355   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42356   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42357   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42358   if (a_src && a_src->data.ptr) {
42359     io0_a_src = a_src->data.ptr;
42360     io1_a_src = io0_a_src + a_src->meta.ri;
42361     iop_a_src = io1_a_src;
42362     io2_a_src = io0_a_src + a_src->meta.wi;
42363   }
42364 
42365   uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config[0];
42366   if (coro_susp_point) {
42367     v_marker = self->private_data.s_do_decode_image_config[0].v_marker;
42368   }
42369   switch (coro_susp_point) {
42370     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
42371 
42372     if (self->private_impl.f_call_sequence != 0u) {
42373       status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
42374       goto exit;
42375     }
42376     {
42377       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
42378       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42379         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42380         goto suspend;
42381       }
42382       uint8_t t_0 = *iop_a_src++;
42383       v_c = t_0;
42384     }
42385     if (v_c != 255u) {
42386       status = wuffs_base__make_status(wuffs_jpeg__error__bad_header);
42387       goto exit;
42388     }
42389     {
42390       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
42391       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42392         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42393         goto suspend;
42394       }
42395       uint8_t t_1 = *iop_a_src++;
42396       v_c = t_1;
42397     }
42398     if (v_c != 216u) {
42399       status = wuffs_base__make_status(wuffs_jpeg__error__bad_header);
42400       goto exit;
42401     }
42402     while (true) {
42403       while (true) {
42404         {
42405           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
42406           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42407             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42408             goto suspend;
42409           }
42410           uint8_t t_2 = *iop_a_src++;
42411           v_c = t_2;
42412         }
42413         if (v_c == 255u) {
42414           break;
42415         }
42416       }
42417       while (true) {
42418         {
42419           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
42420           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42421             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42422             goto suspend;
42423           }
42424           uint8_t t_3 = *iop_a_src++;
42425           v_c = t_3;
42426         }
42427         if (v_c != 255u) {
42428           v_marker = v_c;
42429           break;
42430         }
42431       }
42432       if (v_marker == 0u) {
42433         continue;
42434       } else if ((208u <= v_marker) && (v_marker <= 217u)) {
42435         if (v_marker <= 215u) {
42436           continue;
42437         }
42438       } else {
42439         {
42440           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
42441           uint32_t t_4;
42442           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
42443             t_4 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
42444             iop_a_src += 2;
42445           } else {
42446             self->private_data.s_do_decode_image_config[0].scratch = 0;
42447             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
42448             while (true) {
42449               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42450                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42451                 goto suspend;
42452               }
42453               uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
42454               uint32_t num_bits_4 = ((uint32_t)(*scratch & 0xFFu));
42455               *scratch >>= 8;
42456               *scratch <<= 8;
42457               *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_4);
42458               if (num_bits_4 == 8) {
42459                 t_4 = ((uint32_t)(*scratch >> 48));
42460                 break;
42461               }
42462               num_bits_4 += 8u;
42463               *scratch |= ((uint64_t)(num_bits_4));
42464             }
42465           }
42466           self->private_impl.f_payload_length = t_4;
42467         }
42468         if (self->private_impl.f_payload_length < 2u) {
42469           status = wuffs_base__make_status(wuffs_jpeg__error__bad_marker);
42470           goto exit;
42471         }
42472         self->private_impl.f_payload_length -= 2u;
42473       }
42474       if (v_marker < 192u) {
42475         status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker);
42476         goto exit;
42477       } else if (v_marker < 208u) {
42478         if (v_marker <= 194u) {
42479           if (self->private_impl.f_sof_marker != 0u) {
42480             status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker);
42481             goto exit;
42482           }
42483           self->private_impl.f_sof_marker = v_marker;
42484           if (a_src) {
42485             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
42486           }
42487           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
42488           status = wuffs_jpeg__decoder__decode_sof(self, a_src);
42489           if (a_src) {
42490             iop_a_src = a_src->data.ptr + a_src->meta.ri;
42491           }
42492           if (status.repr) {
42493             goto suspend;
42494           }
42495           break;
42496         } else if (v_marker == 195u) {
42497           status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_lossless_coding);
42498           goto exit;
42499         } else if (v_marker == 196u) {
42500           status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker);
42501           goto exit;
42502         } else if ((197u <= v_marker) && (v_marker <= 199u)) {
42503           status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_hierarchical_coding);
42504           goto exit;
42505         } else if (v_marker == 200u) {
42506           status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker);
42507           goto exit;
42508         } else {
42509           status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_arithmetic_coding);
42510           goto exit;
42511         }
42512       } else if (v_marker < 224u) {
42513         if (v_marker < 218u) {
42514           status = wuffs_base__make_status(wuffs_jpeg__error__bad_marker);
42515           goto exit;
42516         } else if (v_marker == 218u) {
42517           status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
42518           goto exit;
42519         } else if (v_marker == 219u) {
42520           if (a_src) {
42521             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
42522           }
42523           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
42524           status = wuffs_jpeg__decoder__decode_dqt(self, a_src);
42525           if (a_src) {
42526             iop_a_src = a_src->data.ptr + a_src->meta.ri;
42527           }
42528           if (status.repr) {
42529             goto suspend;
42530           }
42531           continue;
42532         } else if (v_marker == 221u) {
42533           if (a_src) {
42534             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
42535           }
42536           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
42537           status = wuffs_jpeg__decoder__decode_dri(self, a_src);
42538           if (a_src) {
42539             iop_a_src = a_src->data.ptr + a_src->meta.ri;
42540           }
42541           if (status.repr) {
42542             goto suspend;
42543           }
42544           continue;
42545         } else {
42546           status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker);
42547           goto exit;
42548         }
42549       } else if (v_marker < 240u) {
42550         if (a_src) {
42551           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
42552         }
42553         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
42554         status = wuffs_jpeg__decoder__decode_appn(self, a_src, v_marker);
42555         if (a_src) {
42556           iop_a_src = a_src->data.ptr + a_src->meta.ri;
42557         }
42558         if (status.repr) {
42559           goto suspend;
42560         }
42561         continue;
42562       } else {
42563         if (v_marker == 254u) {
42564         } else {
42565           status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker);
42566           goto exit;
42567         }
42568       }
42569       self->private_data.s_do_decode_image_config[0].scratch = self->private_impl.f_payload_length;
42570       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
42571       if (self->private_data.s_do_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
42572         self->private_data.s_do_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
42573         iop_a_src = io2_a_src;
42574         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42575         goto suspend;
42576       }
42577       iop_a_src += self->private_data.s_do_decode_image_config[0].scratch;
42578       self->private_impl.f_payload_length = 0u;
42579     }
42580     self->private_impl.choosy_decode_idct = (
42581 #if defined(WUFFS_BASE__CPU_ARCH__X86_64)
42582         wuffs_base__cpu_arch__have_x86_avx2() ? &wuffs_jpeg__decoder__decode_idct_x86_avx2 :
42583 #endif
42584         self->private_impl.choosy_decode_idct);
42585     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)));
42586     if (a_dst != NULL) {
42587       v_pixfmt = 536870920u;
42588       if (self->private_impl.f_num_components > 1u) {
42589         v_pixfmt = 2415954056u;
42590       }
42591       wuffs_base__image_config__set(
42592           a_dst,
42593           v_pixfmt,
42594           0u,
42595           self->private_impl.f_width,
42596           self->private_impl.f_height,
42597           self->private_impl.f_frame_config_io_position,
42598           true);
42599     }
42600     self->private_impl.f_call_sequence = 32u;
42601 
42602     goto ok;
42603     ok:
42604     self->private_impl.p_do_decode_image_config[0] = 0;
42605     goto exit;
42606   }
42607 
42608   goto suspend;
42609   suspend:
42610   self->private_impl.p_do_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
42611   self->private_data.s_do_decode_image_config[0].v_marker = v_marker;
42612 
42613   goto exit;
42614   exit:
42615   if (a_src && a_src->data.ptr) {
42616     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
42617   }
42618 
42619   return status;
42620 }
42621 
42622 // -------- func jpeg.decoder.decode_dqt
42623 
42624 WUFFS_BASE__GENERATED_C_CODE
42625 static wuffs_base__status
wuffs_jpeg__decoder__decode_dqt(wuffs_jpeg__decoder * self,wuffs_base__io_buffer * a_src)42626 wuffs_jpeg__decoder__decode_dqt(
42627     wuffs_jpeg__decoder* self,
42628     wuffs_base__io_buffer* a_src) {
42629   wuffs_base__status status = wuffs_base__make_status(NULL);
42630 
42631   uint8_t v_c = 0;
42632   uint8_t v_q = 0;
42633   uint32_t v_i = 0;
42634 
42635   const uint8_t* iop_a_src = NULL;
42636   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42637   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42638   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42639   if (a_src && a_src->data.ptr) {
42640     io0_a_src = a_src->data.ptr;
42641     io1_a_src = io0_a_src + a_src->meta.ri;
42642     iop_a_src = io1_a_src;
42643     io2_a_src = io0_a_src + a_src->meta.wi;
42644   }
42645 
42646   uint32_t coro_susp_point = self->private_impl.p_decode_dqt[0];
42647   if (coro_susp_point) {
42648     v_q = self->private_data.s_decode_dqt[0].v_q;
42649     v_i = self->private_data.s_decode_dqt[0].v_i;
42650   }
42651   switch (coro_susp_point) {
42652     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
42653 
42654     while (self->private_impl.f_payload_length > 0u) {
42655       self->private_impl.f_payload_length -= 1u;
42656       {
42657         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
42658         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42659           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42660           goto suspend;
42661         }
42662         uint8_t t_0 = *iop_a_src++;
42663         v_c = t_0;
42664       }
42665       if ((v_c & 15u) > 3u) {
42666         status = wuffs_base__make_status(wuffs_jpeg__error__bad_dqt_marker);
42667         goto exit;
42668       }
42669       v_q = (v_c & 15u);
42670       if ((v_c >> 4u) == 1u) {
42671         status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_precision);
42672         goto exit;
42673       } else if (((v_c >> 4u) > 1u) || (self->private_impl.f_payload_length < 64u)) {
42674         status = wuffs_base__make_status(wuffs_jpeg__error__bad_dqt_marker);
42675         goto exit;
42676       }
42677       self->private_impl.f_payload_length -= 64u;
42678       v_i = 0u;
42679       while (v_i < 64u) {
42680         v_i += 1u;
42681         {
42682           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
42683           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42684             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42685             goto suspend;
42686           }
42687           uint16_t t_1 = *iop_a_src++;
42688           self->private_impl.f_quant_tables[v_q][WUFFS_JPEG__UNZIG[v_i]] = t_1;
42689         }
42690       }
42691       self->private_impl.f_seen_dqt[v_q] = true;
42692       if (self->private_impl.f_sof_marker == 0u) {
42693         v_i = 0u;
42694         while (v_i < 64u) {
42695           self->private_impl.f_saved_quant_tables[v_q][v_i] = self->private_impl.f_quant_tables[v_q][v_i];
42696           v_i += 1u;
42697         }
42698         self->private_impl.f_saved_seen_dqt[v_q] = true;
42699       }
42700     }
42701 
42702     goto ok;
42703     ok:
42704     self->private_impl.p_decode_dqt[0] = 0;
42705     goto exit;
42706   }
42707 
42708   goto suspend;
42709   suspend:
42710   self->private_impl.p_decode_dqt[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
42711   self->private_data.s_decode_dqt[0].v_q = v_q;
42712   self->private_data.s_decode_dqt[0].v_i = v_i;
42713 
42714   goto exit;
42715   exit:
42716   if (a_src && a_src->data.ptr) {
42717     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
42718   }
42719 
42720   return status;
42721 }
42722 
42723 // -------- func jpeg.decoder.decode_dri
42724 
42725 WUFFS_BASE__GENERATED_C_CODE
42726 static wuffs_base__status
wuffs_jpeg__decoder__decode_dri(wuffs_jpeg__decoder * self,wuffs_base__io_buffer * a_src)42727 wuffs_jpeg__decoder__decode_dri(
42728     wuffs_jpeg__decoder* self,
42729     wuffs_base__io_buffer* a_src) {
42730   wuffs_base__status status = wuffs_base__make_status(NULL);
42731 
42732   const uint8_t* iop_a_src = NULL;
42733   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42734   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42735   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42736   if (a_src && a_src->data.ptr) {
42737     io0_a_src = a_src->data.ptr;
42738     io1_a_src = io0_a_src + a_src->meta.ri;
42739     iop_a_src = io1_a_src;
42740     io2_a_src = io0_a_src + a_src->meta.wi;
42741   }
42742 
42743   uint32_t coro_susp_point = self->private_impl.p_decode_dri[0];
42744   switch (coro_susp_point) {
42745     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
42746 
42747     if (self->private_impl.f_payload_length != 2u) {
42748       status = wuffs_base__make_status(wuffs_jpeg__error__bad_dri_marker);
42749       goto exit;
42750     }
42751     self->private_impl.f_payload_length = 0u;
42752     {
42753       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
42754       uint16_t t_0;
42755       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
42756         t_0 = wuffs_base__peek_u16be__no_bounds_check(iop_a_src);
42757         iop_a_src += 2;
42758       } else {
42759         self->private_data.s_decode_dri[0].scratch = 0;
42760         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
42761         while (true) {
42762           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42763             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42764             goto suspend;
42765           }
42766           uint64_t* scratch = &self->private_data.s_decode_dri[0].scratch;
42767           uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu));
42768           *scratch >>= 8;
42769           *scratch <<= 8;
42770           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
42771           if (num_bits_0 == 8) {
42772             t_0 = ((uint16_t)(*scratch >> 48));
42773             break;
42774           }
42775           num_bits_0 += 8u;
42776           *scratch |= ((uint64_t)(num_bits_0));
42777         }
42778       }
42779       self->private_impl.f_restart_interval = t_0;
42780     }
42781     if (self->private_impl.f_sof_marker == 0u) {
42782       self->private_impl.f_saved_restart_interval = self->private_impl.f_restart_interval;
42783     }
42784 
42785     goto ok;
42786     ok:
42787     self->private_impl.p_decode_dri[0] = 0;
42788     goto exit;
42789   }
42790 
42791   goto suspend;
42792   suspend:
42793   self->private_impl.p_decode_dri[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
42794 
42795   goto exit;
42796   exit:
42797   if (a_src && a_src->data.ptr) {
42798     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
42799   }
42800 
42801   return status;
42802 }
42803 
42804 // -------- func jpeg.decoder.decode_appn
42805 
42806 WUFFS_BASE__GENERATED_C_CODE
42807 static wuffs_base__status
wuffs_jpeg__decoder__decode_appn(wuffs_jpeg__decoder * self,wuffs_base__io_buffer * a_src,uint8_t a_marker)42808 wuffs_jpeg__decoder__decode_appn(
42809     wuffs_jpeg__decoder* self,
42810     wuffs_base__io_buffer* a_src,
42811     uint8_t a_marker) {
42812   wuffs_base__status status = wuffs_base__make_status(NULL);
42813 
42814   uint8_t v_c8 = 0;
42815   uint32_t v_c32 = 0;
42816 
42817   const uint8_t* iop_a_src = NULL;
42818   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42819   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42820   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42821   if (a_src && a_src->data.ptr) {
42822     io0_a_src = a_src->data.ptr;
42823     io1_a_src = io0_a_src + a_src->meta.ri;
42824     iop_a_src = io1_a_src;
42825     io2_a_src = io0_a_src + a_src->meta.wi;
42826   }
42827 
42828   uint32_t coro_susp_point = self->private_impl.p_decode_appn[0];
42829   switch (coro_susp_point) {
42830     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
42831 
42832     do {
42833       if (a_marker == 224u) {
42834         if (self->private_impl.f_payload_length >= 5u) {
42835           self->private_impl.f_payload_length -= 5u;
42836           {
42837             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
42838             uint32_t t_0;
42839             if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
42840               t_0 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
42841               iop_a_src += 4;
42842             } else {
42843               self->private_data.s_decode_appn[0].scratch = 0;
42844               WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
42845               while (true) {
42846                 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42847                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42848                   goto suspend;
42849                 }
42850                 uint64_t* scratch = &self->private_data.s_decode_appn[0].scratch;
42851                 uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
42852                 *scratch <<= 8;
42853                 *scratch >>= 8;
42854                 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
42855                 if (num_bits_0 == 24) {
42856                   t_0 = ((uint32_t)(*scratch));
42857                   break;
42858                 }
42859                 num_bits_0 += 8u;
42860                 *scratch |= ((uint64_t)(num_bits_0)) << 56;
42861               }
42862             }
42863             v_c32 = t_0;
42864           }
42865           if (v_c32 != 1179207242u) {
42866             self->private_impl.f_payload_length = (65535u & (self->private_impl.f_payload_length + 1u));
42867             break;
42868           }
42869           {
42870             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
42871             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42872               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42873               goto suspend;
42874             }
42875             uint8_t t_1 = *iop_a_src++;
42876             v_c8 = t_1;
42877           }
42878           self->private_impl.f_is_jfif = (v_c8 == 0u);
42879         }
42880       } else if (a_marker == 238u) {
42881         if (self->private_impl.f_payload_length >= 12u) {
42882           self->private_impl.f_payload_length -= 12u;
42883           {
42884             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
42885             uint32_t t_2;
42886             if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
42887               t_2 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
42888               iop_a_src += 4;
42889             } else {
42890               self->private_data.s_decode_appn[0].scratch = 0;
42891               WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
42892               while (true) {
42893                 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42894                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42895                   goto suspend;
42896                 }
42897                 uint64_t* scratch = &self->private_data.s_decode_appn[0].scratch;
42898                 uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
42899                 *scratch <<= 8;
42900                 *scratch >>= 8;
42901                 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
42902                 if (num_bits_2 == 24) {
42903                   t_2 = ((uint32_t)(*scratch));
42904                   break;
42905                 }
42906                 num_bits_2 += 8u;
42907                 *scratch |= ((uint64_t)(num_bits_2)) << 56;
42908               }
42909             }
42910             v_c32 = t_2;
42911           }
42912           if (v_c32 != 1651467329u) {
42913             self->private_impl.f_payload_length = (65535u & (self->private_impl.f_payload_length + 8u));
42914             break;
42915           }
42916           {
42917             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
42918             uint32_t t_3;
42919             if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
42920               t_3 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
42921               iop_a_src += 4;
42922             } else {
42923               self->private_data.s_decode_appn[0].scratch = 0;
42924               WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
42925               while (true) {
42926                 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42927                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42928                   goto suspend;
42929                 }
42930                 uint64_t* scratch = &self->private_data.s_decode_appn[0].scratch;
42931                 uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56));
42932                 *scratch <<= 8;
42933                 *scratch >>= 8;
42934                 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3;
42935                 if (num_bits_3 == 24) {
42936                   t_3 = ((uint32_t)(*scratch));
42937                   break;
42938                 }
42939                 num_bits_3 += 8u;
42940                 *scratch |= ((uint64_t)(num_bits_3)) << 56;
42941               }
42942             }
42943             v_c32 = t_3;
42944           }
42945           if ((255u & v_c32) != 101u) {
42946             self->private_impl.f_payload_length = (65535u & (self->private_impl.f_payload_length + 4u));
42947             break;
42948           }
42949           {
42950             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
42951             uint32_t t_4;
42952             if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
42953               t_4 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
42954               iop_a_src += 4;
42955             } else {
42956               self->private_data.s_decode_appn[0].scratch = 0;
42957               WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
42958               while (true) {
42959                 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42960                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42961                   goto suspend;
42962                 }
42963                 uint64_t* scratch = &self->private_data.s_decode_appn[0].scratch;
42964                 uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
42965                 *scratch <<= 8;
42966                 *scratch >>= 8;
42967                 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
42968                 if (num_bits_4 == 24) {
42969                   t_4 = ((uint32_t)(*scratch));
42970                   break;
42971                 }
42972                 num_bits_4 += 8u;
42973                 *scratch |= ((uint64_t)(num_bits_4)) << 56;
42974               }
42975             }
42976             v_c32 = t_4;
42977           }
42978           if ((v_c32 >> 24u) == 0u) {
42979             self->private_impl.f_is_adobe = 1u;
42980           } else {
42981             self->private_impl.f_is_adobe = 2u;
42982           }
42983         }
42984       }
42985     } while (0);
42986     self->private_data.s_decode_appn[0].scratch = self->private_impl.f_payload_length;
42987     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
42988     if (self->private_data.s_decode_appn[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
42989       self->private_data.s_decode_appn[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
42990       iop_a_src = io2_a_src;
42991       status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42992       goto suspend;
42993     }
42994     iop_a_src += self->private_data.s_decode_appn[0].scratch;
42995     self->private_impl.f_payload_length = 0u;
42996 
42997     goto ok;
42998     ok:
42999     self->private_impl.p_decode_appn[0] = 0;
43000     goto exit;
43001   }
43002 
43003   goto suspend;
43004   suspend:
43005   self->private_impl.p_decode_appn[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
43006 
43007   goto exit;
43008   exit:
43009   if (a_src && a_src->data.ptr) {
43010     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
43011   }
43012 
43013   return status;
43014 }
43015 
43016 // -------- func jpeg.decoder.decode_sof
43017 
43018 WUFFS_BASE__GENERATED_C_CODE
43019 static wuffs_base__status
wuffs_jpeg__decoder__decode_sof(wuffs_jpeg__decoder * self,wuffs_base__io_buffer * a_src)43020 wuffs_jpeg__decoder__decode_sof(
43021     wuffs_jpeg__decoder* self,
43022     wuffs_base__io_buffer* a_src) {
43023   wuffs_base__status status = wuffs_base__make_status(NULL);
43024 
43025   uint8_t v_c = 0;
43026   uint8_t v_comp_h = 0;
43027   uint8_t v_comp_v = 0;
43028   uint32_t v_i = 0;
43029   uint32_t v_j = 0;
43030   bool v_has_h24 = false;
43031   bool v_has_h3 = false;
43032   bool v_has_v24 = false;
43033   bool v_has_v3 = false;
43034   uint32_t v_upper_bound = 0;
43035   uint64_t v_wh0 = 0;
43036   uint64_t v_wh1 = 0;
43037   uint64_t v_wh2 = 0;
43038   uint64_t v_wh3 = 0;
43039   uint64_t v_progressive = 0;
43040 
43041   const uint8_t* iop_a_src = NULL;
43042   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43043   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43044   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43045   if (a_src && a_src->data.ptr) {
43046     io0_a_src = a_src->data.ptr;
43047     io1_a_src = io0_a_src + a_src->meta.ri;
43048     iop_a_src = io1_a_src;
43049     io2_a_src = io0_a_src + a_src->meta.wi;
43050   }
43051 
43052   uint32_t coro_susp_point = self->private_impl.p_decode_sof[0];
43053   if (coro_susp_point) {
43054     v_i = self->private_data.s_decode_sof[0].v_i;
43055   }
43056   switch (coro_susp_point) {
43057     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
43058 
43059     if (self->private_impl.f_payload_length < 6u) {
43060       status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker);
43061       goto exit;
43062     }
43063     self->private_impl.f_payload_length -= 6u;
43064     {
43065       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
43066       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
43067         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
43068         goto suspend;
43069       }
43070       uint8_t t_0 = *iop_a_src++;
43071       v_c = t_0;
43072     }
43073     if (v_c == 8u) {
43074     } else if (v_c == 12u) {
43075       status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_precision_12_bits);
43076       goto exit;
43077     } else if (v_c == 16u) {
43078       status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_precision_16_bits);
43079       goto exit;
43080     } else {
43081       status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_precision);
43082       goto exit;
43083     }
43084     {
43085       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
43086       uint32_t t_1;
43087       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
43088         t_1 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
43089         iop_a_src += 2;
43090       } else {
43091         self->private_data.s_decode_sof[0].scratch = 0;
43092         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
43093         while (true) {
43094           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
43095             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
43096             goto suspend;
43097           }
43098           uint64_t* scratch = &self->private_data.s_decode_sof[0].scratch;
43099           uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu));
43100           *scratch >>= 8;
43101           *scratch <<= 8;
43102           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
43103           if (num_bits_1 == 8) {
43104             t_1 = ((uint32_t)(*scratch >> 48));
43105             break;
43106           }
43107           num_bits_1 += 8u;
43108           *scratch |= ((uint64_t)(num_bits_1));
43109         }
43110       }
43111       self->private_impl.f_height = t_1;
43112     }
43113     if (self->private_impl.f_height == 0u) {
43114       status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_implicit_height);
43115       goto exit;
43116     }
43117     {
43118       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
43119       uint32_t t_2;
43120       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
43121         t_2 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
43122         iop_a_src += 2;
43123       } else {
43124         self->private_data.s_decode_sof[0].scratch = 0;
43125         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
43126         while (true) {
43127           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
43128             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
43129             goto suspend;
43130           }
43131           uint64_t* scratch = &self->private_data.s_decode_sof[0].scratch;
43132           uint32_t num_bits_2 = ((uint32_t)(*scratch & 0xFFu));
43133           *scratch >>= 8;
43134           *scratch <<= 8;
43135           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_2);
43136           if (num_bits_2 == 8) {
43137             t_2 = ((uint32_t)(*scratch >> 48));
43138             break;
43139           }
43140           num_bits_2 += 8u;
43141           *scratch |= ((uint64_t)(num_bits_2));
43142         }
43143       }
43144       self->private_impl.f_width = t_2;
43145     }
43146     if (self->private_impl.f_width == 0u) {
43147       status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension);
43148       goto exit;
43149     }
43150     {
43151       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
43152       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
43153         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
43154         goto suspend;
43155       }
43156       uint8_t t_3 = *iop_a_src++;
43157       v_c = t_3;
43158     }
43159     if ((v_c == 0u) || (v_c > 4u)) {
43160       status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker);
43161       goto exit;
43162     } else if (v_c == 2u) {
43163       status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_color_model);
43164       goto exit;
43165     }
43166     self->private_impl.f_num_components = ((uint32_t)(v_c));
43167     if (self->private_impl.f_payload_length != (3u * self->private_impl.f_num_components)) {
43168       status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker);
43169       goto exit;
43170     }
43171     self->private_impl.f_payload_length = 0u;
43172     v_i = 0u;
43173     while (v_i < self->private_impl.f_num_components) {
43174       {
43175         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
43176         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
43177           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
43178           goto suspend;
43179         }
43180         uint8_t t_4 = *iop_a_src++;
43181         self->private_impl.f_components_c[v_i] = t_4;
43182       }
43183       {
43184         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
43185         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
43186           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
43187           goto suspend;
43188         }
43189         uint8_t t_5 = *iop_a_src++;
43190         v_c = t_5;
43191       }
43192       v_comp_h = (v_c >> 4u);
43193       v_comp_v = (v_c & 15u);
43194       if ((v_comp_h == 0u) ||
43195           (v_comp_h > 4u) ||
43196           (v_comp_v == 0u) ||
43197           (v_comp_v > 4u)) {
43198         status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker);
43199         goto exit;
43200       }
43201       self->private_impl.f_components_h[v_i] = v_comp_h;
43202       if (self->private_impl.f_max_incl_components_h < self->private_impl.f_components_h[v_i]) {
43203         self->private_impl.f_max_incl_components_h = self->private_impl.f_components_h[v_i];
43204       }
43205       self->private_impl.f_components_v[v_i] = v_comp_v;
43206       if (self->private_impl.f_max_incl_components_v < self->private_impl.f_components_v[v_i]) {
43207         self->private_impl.f_max_incl_components_v = self->private_impl.f_components_v[v_i];
43208       }
43209       {
43210         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
43211         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
43212           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
43213           goto suspend;
43214         }
43215         uint8_t t_6 = *iop_a_src++;
43216         v_c = t_6;
43217       }
43218       if (v_c >= 4u) {
43219         status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker);
43220         goto exit;
43221       }
43222       self->private_impl.f_components_tq[v_i] = v_c;
43223       v_j = 0u;
43224       while (v_j < v_i) {
43225         if (self->private_impl.f_components_c[v_j] == self->private_impl.f_components_c[v_i]) {
43226           status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker);
43227           goto exit;
43228         }
43229         v_j += 1u;
43230       }
43231       v_i += 1u;
43232     }
43233     if (self->private_impl.f_num_components == 1u) {
43234       self->private_impl.f_max_incl_components_h = 1u;
43235       self->private_impl.f_max_incl_components_v = 1u;
43236       self->private_impl.f_components_h[0u] = 1u;
43237       self->private_impl.f_components_v[0u] = 1u;
43238     } else {
43239       v_has_h24 = false;
43240       v_has_h3 = false;
43241       v_has_v24 = false;
43242       v_has_v3 = false;
43243       v_i = 0u;
43244       while (v_i < self->private_impl.f_num_components) {
43245         v_has_h24 = (v_has_h24 || (self->private_impl.f_components_h[v_i] == 2u) || (self->private_impl.f_components_h[v_i] == 4u));
43246         v_has_h3 = (v_has_h3 || (self->private_impl.f_components_h[v_i] == 3u));
43247         v_has_v24 = (v_has_v24 || (self->private_impl.f_components_v[v_i] == 2u) || (self->private_impl.f_components_v[v_i] == 4u));
43248         v_has_v3 = (v_has_v3 || (self->private_impl.f_components_v[v_i] == 3u));
43249         v_i += 1u;
43250       }
43251       if ((v_has_h24 && v_has_h3) || (v_has_v24 && v_has_v3)) {
43252         status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_fractional_sampling);
43253         goto exit;
43254       }
43255       if (self->private_impl.f_num_components == 4u) {
43256         self->private_impl.f_is_rgb_or_cmyk = (self->private_impl.f_is_adobe < 2u);
43257       } else {
43258         if (self->private_impl.f_is_jfif) {
43259           self->private_impl.f_is_rgb_or_cmyk = false;
43260         } else if (self->private_impl.f_is_adobe > 0u) {
43261           self->private_impl.f_is_rgb_or_cmyk = (self->private_impl.f_is_adobe == 1u);
43262         } else {
43263           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));
43264         }
43265       }
43266     }
43267     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);
43268     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);
43269     v_upper_bound = 65544u;
43270     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]))));
43271     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]))));
43272     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]))));
43273     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]))));
43274     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]))));
43275     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]))));
43276     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]))));
43277     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]))));
43278     v_wh0 = (((uint64_t)(self->private_impl.f_components_workbuf_widths[0u])) * ((uint64_t)(self->private_impl.f_components_workbuf_heights[0u])));
43279     v_wh1 = (((uint64_t)(self->private_impl.f_components_workbuf_widths[1u])) * ((uint64_t)(self->private_impl.f_components_workbuf_heights[1u])));
43280     v_wh2 = (((uint64_t)(self->private_impl.f_components_workbuf_widths[2u])) * ((uint64_t)(self->private_impl.f_components_workbuf_heights[2u])));
43281     v_wh3 = (((uint64_t)(self->private_impl.f_components_workbuf_widths[3u])) * ((uint64_t)(self->private_impl.f_components_workbuf_heights[3u])));
43282     v_progressive = 0u;
43283     if (self->private_impl.f_sof_marker >= 194u) {
43284       v_progressive = 2u;
43285       v_i = 0u;
43286       while (v_i < 4u) {
43287         v_j = 0u;
43288         while (v_j < 10u) {
43289           self->private_impl.f_block_smoothing_lowest_scan_al[v_i][v_j] = 16u;
43290           v_j += 1u;
43291         }
43292         v_i += 1u;
43293       }
43294     }
43295     self->private_impl.f_components_workbuf_offsets[0u] = 0u;
43296     self->private_impl.f_components_workbuf_offsets[1u] = (self->private_impl.f_components_workbuf_offsets[0u] + v_wh0);
43297     self->private_impl.f_components_workbuf_offsets[2u] = (self->private_impl.f_components_workbuf_offsets[1u] + v_wh1);
43298     self->private_impl.f_components_workbuf_offsets[3u] = (self->private_impl.f_components_workbuf_offsets[2u] + v_wh2);
43299     self->private_impl.f_components_workbuf_offsets[4u] = (self->private_impl.f_components_workbuf_offsets[3u] + v_wh3);
43300     self->private_impl.f_components_workbuf_offsets[5u] = (self->private_impl.f_components_workbuf_offsets[4u] + (v_wh0 * v_progressive));
43301     self->private_impl.f_components_workbuf_offsets[6u] = (self->private_impl.f_components_workbuf_offsets[5u] + (v_wh1 * v_progressive));
43302     self->private_impl.f_components_workbuf_offsets[7u] = (self->private_impl.f_components_workbuf_offsets[6u] + (v_wh2 * v_progressive));
43303     self->private_impl.f_components_workbuf_offsets[8u] = (self->private_impl.f_components_workbuf_offsets[7u] + (v_wh3 * v_progressive));
43304 
43305     goto ok;
43306     ok:
43307     self->private_impl.p_decode_sof[0] = 0;
43308     goto exit;
43309   }
43310 
43311   goto suspend;
43312   suspend:
43313   self->private_impl.p_decode_sof[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
43314   self->private_data.s_decode_sof[0].v_i = v_i;
43315 
43316   goto exit;
43317   exit:
43318   if (a_src && a_src->data.ptr) {
43319     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
43320   }
43321 
43322   return status;
43323 }
43324 
43325 // -------- func jpeg.decoder.quantize_dimension
43326 
43327 WUFFS_BASE__GENERATED_C_CODE
43328 static uint32_t
wuffs_jpeg__decoder__quantize_dimension(const wuffs_jpeg__decoder * self,uint32_t a_width,uint8_t a_h,uint8_t a_max_incl_h)43329 wuffs_jpeg__decoder__quantize_dimension(
43330     const wuffs_jpeg__decoder* self,
43331     uint32_t a_width,
43332     uint8_t a_h,
43333     uint8_t a_max_incl_h) {
43334   uint32_t v_ratio = 0;
43335 
43336   v_ratio = 0u;
43337   if (a_h > 0u) {
43338     v_ratio = ((uint32_t)((a_max_incl_h / a_h)));
43339   }
43340   if (v_ratio == 1u) {
43341     return ((a_width + 7u) / 8u);
43342   } else if (v_ratio == 2u) {
43343     return ((a_width + 15u) / 16u);
43344   } else if (v_ratio == 3u) {
43345     return ((a_width + 23u) / 24u);
43346   }
43347   return ((a_width + 31u) / 32u);
43348 }
43349 
43350 // -------- func jpeg.decoder.decode_frame_config
43351 
43352 WUFFS_BASE__GENERATED_C_CODE
43353 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_jpeg__decoder__decode_frame_config(wuffs_jpeg__decoder * self,wuffs_base__frame_config * a_dst,wuffs_base__io_buffer * a_src)43354 wuffs_jpeg__decoder__decode_frame_config(
43355     wuffs_jpeg__decoder* self,
43356     wuffs_base__frame_config* a_dst,
43357     wuffs_base__io_buffer* a_src) {
43358   if (!self) {
43359     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
43360   }
43361   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
43362     return wuffs_base__make_status(
43363         (self->private_impl.magic == WUFFS_BASE__DISABLED)
43364         ? wuffs_base__error__disabled_by_previous_error
43365         : wuffs_base__error__initialize_not_called);
43366   }
43367   if (!a_src) {
43368     self->private_impl.magic = WUFFS_BASE__DISABLED;
43369     return wuffs_base__make_status(wuffs_base__error__bad_argument);
43370   }
43371   if ((self->private_impl.active_coroutine != 0) &&
43372       (self->private_impl.active_coroutine != 2)) {
43373     self->private_impl.magic = WUFFS_BASE__DISABLED;
43374     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
43375   }
43376   self->private_impl.active_coroutine = 0;
43377   wuffs_base__status status = wuffs_base__make_status(NULL);
43378 
43379   wuffs_base__status v_status = wuffs_base__make_status(NULL);
43380 
43381   uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
43382   switch (coro_susp_point) {
43383     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
43384 
43385     while (true) {
43386       {
43387         wuffs_base__status t_0 = wuffs_jpeg__decoder__do_decode_frame_config(self, a_dst, a_src);
43388         v_status = t_0;
43389       }
43390       if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
43391         status = wuffs_base__make_status(wuffs_jpeg__error__truncated_input);
43392         goto exit;
43393       }
43394       status = v_status;
43395       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
43396     }
43397 
43398     ok:
43399     self->private_impl.p_decode_frame_config[0] = 0;
43400     goto exit;
43401   }
43402 
43403   goto suspend;
43404   suspend:
43405   self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
43406   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
43407 
43408   goto exit;
43409   exit:
43410   if (wuffs_base__status__is_error(&status)) {
43411     self->private_impl.magic = WUFFS_BASE__DISABLED;
43412   }
43413   return status;
43414 }
43415 
43416 // -------- func jpeg.decoder.do_decode_frame_config
43417 
43418 WUFFS_BASE__GENERATED_C_CODE
43419 static wuffs_base__status
wuffs_jpeg__decoder__do_decode_frame_config(wuffs_jpeg__decoder * self,wuffs_base__frame_config * a_dst,wuffs_base__io_buffer * a_src)43420 wuffs_jpeg__decoder__do_decode_frame_config(
43421     wuffs_jpeg__decoder* self,
43422     wuffs_base__frame_config* a_dst,
43423     wuffs_base__io_buffer* a_src) {
43424   wuffs_base__status status = wuffs_base__make_status(NULL);
43425 
43426   const uint8_t* iop_a_src = NULL;
43427   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43428   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43429   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43430   if (a_src && a_src->data.ptr) {
43431     io0_a_src = a_src->data.ptr;
43432     io1_a_src = io0_a_src + a_src->meta.ri;
43433     iop_a_src = io1_a_src;
43434     io2_a_src = io0_a_src + a_src->meta.wi;
43435   }
43436 
43437   uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config[0];
43438   switch (coro_susp_point) {
43439     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
43440 
43441     if (self->private_impl.f_call_sequence == 32u) {
43442     } else if (self->private_impl.f_call_sequence < 32u) {
43443       if (a_src) {
43444         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
43445       }
43446       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
43447       status = wuffs_jpeg__decoder__do_decode_image_config(self, NULL, a_src);
43448       if (a_src) {
43449         iop_a_src = a_src->data.ptr + a_src->meta.ri;
43450       }
43451       if (status.repr) {
43452         goto suspend;
43453       }
43454     } else if (self->private_impl.f_call_sequence == 40u) {
43455       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)))) {
43456         status = wuffs_base__make_status(wuffs_base__error__bad_restart);
43457         goto exit;
43458       }
43459     } else if (self->private_impl.f_call_sequence == 64u) {
43460       self->private_impl.f_call_sequence = 96u;
43461       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
43462       goto ok;
43463     } else {
43464       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
43465       goto ok;
43466     }
43467     if (a_dst != NULL) {
43468       wuffs_base__frame_config__set(
43469           a_dst,
43470           wuffs_base__utility__make_rect_ie_u32(
43471           0u,
43472           0u,
43473           self->private_impl.f_width,
43474           self->private_impl.f_height),
43475           ((wuffs_base__flicks)(0u)),
43476           0u,
43477           self->private_impl.f_frame_config_io_position,
43478           0u,
43479           true,
43480           false,
43481           4278190080u);
43482     }
43483     self->private_impl.f_call_sequence = 64u;
43484 
43485     ok:
43486     self->private_impl.p_do_decode_frame_config[0] = 0;
43487     goto exit;
43488   }
43489 
43490   goto suspend;
43491   suspend:
43492   self->private_impl.p_do_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
43493 
43494   goto exit;
43495   exit:
43496   if (a_src && a_src->data.ptr) {
43497     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
43498   }
43499 
43500   return status;
43501 }
43502 
43503 // -------- func jpeg.decoder.decode_frame
43504 
43505 WUFFS_BASE__GENERATED_C_CODE
43506 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_jpeg__decoder__decode_frame(wuffs_jpeg__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__pixel_blend a_blend,wuffs_base__slice_u8 a_workbuf,wuffs_base__decode_frame_options * a_opts)43507 wuffs_jpeg__decoder__decode_frame(
43508     wuffs_jpeg__decoder* self,
43509     wuffs_base__pixel_buffer* a_dst,
43510     wuffs_base__io_buffer* a_src,
43511     wuffs_base__pixel_blend a_blend,
43512     wuffs_base__slice_u8 a_workbuf,
43513     wuffs_base__decode_frame_options* a_opts) {
43514   if (!self) {
43515     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
43516   }
43517   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
43518     return wuffs_base__make_status(
43519         (self->private_impl.magic == WUFFS_BASE__DISABLED)
43520         ? wuffs_base__error__disabled_by_previous_error
43521         : wuffs_base__error__initialize_not_called);
43522   }
43523   if (!a_dst || !a_src) {
43524     self->private_impl.magic = WUFFS_BASE__DISABLED;
43525     return wuffs_base__make_status(wuffs_base__error__bad_argument);
43526   }
43527   if ((self->private_impl.active_coroutine != 0) &&
43528       (self->private_impl.active_coroutine != 3)) {
43529     self->private_impl.magic = WUFFS_BASE__DISABLED;
43530     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
43531   }
43532   self->private_impl.active_coroutine = 0;
43533   wuffs_base__status status = wuffs_base__make_status(NULL);
43534 
43535   wuffs_base__status v_ddf_status = wuffs_base__make_status(NULL);
43536   wuffs_base__status v_swizzle_status = wuffs_base__make_status(NULL);
43537   uint32_t v_scan_count = 0;
43538 
43539   uint32_t coro_susp_point = self->private_impl.p_decode_frame[0];
43540   switch (coro_susp_point) {
43541     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
43542 
43543     while (true) {
43544       v_scan_count = self->private_impl.f_scan_count;
43545       {
43546         wuffs_base__status t_0 = wuffs_jpeg__decoder__do_decode_frame(self,
43547             a_dst,
43548             a_src,
43549             a_blend,
43550             a_workbuf,
43551             a_opts);
43552         v_ddf_status = t_0;
43553       }
43554       if ((v_ddf_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
43555         v_ddf_status = wuffs_base__make_status(wuffs_jpeg__error__truncated_input);
43556       }
43557       if (wuffs_base__status__is_error(&v_ddf_status) || (v_scan_count < self->private_impl.f_scan_count)) {
43558         if (self->private_impl.f_sof_marker >= 194u) {
43559           wuffs_jpeg__decoder__apply_progressive_idct(self, a_workbuf);
43560         }
43561         if (self->private_impl.f_num_components == 1u) {
43562           v_swizzle_status = wuffs_jpeg__decoder__swizzle_gray(self, a_dst, a_workbuf);
43563         } else {
43564           v_swizzle_status = wuffs_jpeg__decoder__swizzle_colorful(self, a_dst, a_workbuf);
43565         }
43566         if (wuffs_base__status__is_error(&v_ddf_status)) {
43567           status = v_ddf_status;
43568           goto exit;
43569         } else if (wuffs_base__status__is_error(&v_swizzle_status)) {
43570           status = v_swizzle_status;
43571           goto exit;
43572         }
43573       }
43574       status = v_ddf_status;
43575       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
43576     }
43577 
43578     ok:
43579     self->private_impl.p_decode_frame[0] = 0;
43580     goto exit;
43581   }
43582 
43583   goto suspend;
43584   suspend:
43585   self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
43586   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
43587 
43588   goto exit;
43589   exit:
43590   if (wuffs_base__status__is_error(&status)) {
43591     self->private_impl.magic = WUFFS_BASE__DISABLED;
43592   }
43593   return status;
43594 }
43595 
43596 // -------- func jpeg.decoder.do_decode_frame
43597 
43598 WUFFS_BASE__GENERATED_C_CODE
43599 static wuffs_base__status
wuffs_jpeg__decoder__do_decode_frame(wuffs_jpeg__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__pixel_blend a_blend,wuffs_base__slice_u8 a_workbuf,wuffs_base__decode_frame_options * a_opts)43600 wuffs_jpeg__decoder__do_decode_frame(
43601     wuffs_jpeg__decoder* self,
43602     wuffs_base__pixel_buffer* a_dst,
43603     wuffs_base__io_buffer* a_src,
43604     wuffs_base__pixel_blend a_blend,
43605     wuffs_base__slice_u8 a_workbuf,
43606     wuffs_base__decode_frame_options* a_opts) {
43607   wuffs_base__status status = wuffs_base__make_status(NULL);
43608 
43609   uint32_t v_pixfmt = 0;
43610   wuffs_base__status v_status = wuffs_base__make_status(NULL);
43611   uint8_t v_c = 0;
43612   uint8_t v_marker = 0;
43613 
43614   const uint8_t* iop_a_src = NULL;
43615   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43616   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43617   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43618   if (a_src && a_src->data.ptr) {
43619     io0_a_src = a_src->data.ptr;
43620     io1_a_src = io0_a_src + a_src->meta.ri;
43621     iop_a_src = io1_a_src;
43622     io2_a_src = io0_a_src + a_src->meta.wi;
43623   }
43624 
43625   uint32_t coro_susp_point = self->private_impl.p_do_decode_frame[0];
43626   if (coro_susp_point) {
43627     v_marker = self->private_data.s_do_decode_frame[0].v_marker;
43628   }
43629   switch (coro_susp_point) {
43630     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
43631 
43632     if (self->private_impl.f_call_sequence == 64u) {
43633     } else if (self->private_impl.f_call_sequence < 64u) {
43634       if (a_src) {
43635         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
43636       }
43637       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
43638       status = wuffs_jpeg__decoder__do_decode_frame_config(self, NULL, a_src);
43639       if (a_src) {
43640         iop_a_src = a_src->data.ptr + a_src->meta.ri;
43641       }
43642       if (status.repr) {
43643         goto suspend;
43644       }
43645     } else {
43646       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
43647       goto ok;
43648     }
43649     v_pixfmt = 536870920u;
43650     if (self->private_impl.f_num_components > 1u) {
43651       v_pixfmt = 2415954056u;
43652     }
43653     v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
43654         wuffs_base__pixel_buffer__pixel_format(a_dst),
43655         wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)),
43656         wuffs_base__utility__make_pixel_format(v_pixfmt),
43657         wuffs_base__utility__empty_slice_u8(),
43658         a_blend);
43659     if ( ! wuffs_base__status__is_ok(&v_status)) {
43660       status = v_status;
43661       if (wuffs_base__status__is_error(&status)) {
43662         goto exit;
43663       } else if (wuffs_base__status__is_suspension(&status)) {
43664         status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
43665         goto exit;
43666       }
43667       goto ok;
43668     }
43669     if (self->private_impl.f_components_workbuf_offsets[8u] > ((uint64_t)(a_workbuf.len))) {
43670       status = wuffs_base__make_status(wuffs_base__error__bad_workbuf_length);
43671       goto exit;
43672     } else if (self->private_impl.f_components_workbuf_offsets[4u] < self->private_impl.f_components_workbuf_offsets[8u]) {
43673       wuffs_base__bulk_memset(a_workbuf.ptr + self->private_impl.f_components_workbuf_offsets[4u], (self->private_impl.f_components_workbuf_offsets[8u] - self->private_impl.f_components_workbuf_offsets[4u]), 0u);
43674     }
43675     if (self->private_impl.f_components_workbuf_offsets[4u] <= ((uint64_t)(a_workbuf.len))) {
43676       wuffs_base__bulk_memset(a_workbuf.ptr, self->private_impl.f_components_workbuf_offsets[4u], 128u);
43677     }
43678     while (true) {
43679       while (true) {
43680         {
43681           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
43682           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
43683             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
43684             goto suspend;
43685           }
43686           uint8_t t_0 = *iop_a_src++;
43687           v_c = t_0;
43688         }
43689         if (v_c == 255u) {
43690           break;
43691         }
43692       }
43693       while (true) {
43694         {
43695           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
43696           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
43697             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
43698             goto suspend;
43699           }
43700           uint8_t t_1 = *iop_a_src++;
43701           v_c = t_1;
43702         }
43703         if (v_c != 255u) {
43704           v_marker = v_c;
43705           break;
43706         }
43707       }
43708       if (v_marker == 0u) {
43709         continue;
43710       } else if ((208u <= v_marker) && (v_marker <= 217u)) {
43711         if (v_marker <= 215u) {
43712           continue;
43713         }
43714       } else {
43715         {
43716           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
43717           uint32_t t_2;
43718           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
43719             t_2 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
43720             iop_a_src += 2;
43721           } else {
43722             self->private_data.s_do_decode_frame[0].scratch = 0;
43723             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
43724             while (true) {
43725               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
43726                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
43727                 goto suspend;
43728               }
43729               uint64_t* scratch = &self->private_data.s_do_decode_frame[0].scratch;
43730               uint32_t num_bits_2 = ((uint32_t)(*scratch & 0xFFu));
43731               *scratch >>= 8;
43732               *scratch <<= 8;
43733               *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_2);
43734               if (num_bits_2 == 8) {
43735                 t_2 = ((uint32_t)(*scratch >> 48));
43736                 break;
43737               }
43738               num_bits_2 += 8u;
43739               *scratch |= ((uint64_t)(num_bits_2));
43740             }
43741           }
43742           self->private_impl.f_payload_length = t_2;
43743         }
43744         if (self->private_impl.f_payload_length < 2u) {
43745           status = wuffs_base__make_status(wuffs_jpeg__error__bad_marker);
43746           goto exit;
43747         }
43748         self->private_impl.f_payload_length -= 2u;
43749       }
43750       if (v_marker < 192u) {
43751         status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker);
43752         goto exit;
43753       } else if (v_marker < 208u) {
43754         if (v_marker == 196u) {
43755           if (a_src) {
43756             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
43757           }
43758           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
43759           status = wuffs_jpeg__decoder__decode_dht(self, a_src);
43760           if (a_src) {
43761             iop_a_src = a_src->data.ptr + a_src->meta.ri;
43762           }
43763           if (status.repr) {
43764             goto suspend;
43765           }
43766           continue;
43767         } else if (v_marker == 200u) {
43768           status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker);
43769           goto exit;
43770         }
43771         status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker);
43772         goto exit;
43773       } else if (v_marker < 224u) {
43774         if (v_marker < 217u) {
43775           status = wuffs_base__make_status(wuffs_jpeg__error__bad_marker);
43776           goto exit;
43777         } else if (v_marker == 217u) {
43778           break;
43779         } else if (v_marker == 218u) {
43780           if (a_src) {
43781             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
43782           }
43783           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
43784           status = wuffs_jpeg__decoder__decode_sos(self, a_src, a_workbuf);
43785           if (a_src) {
43786             iop_a_src = a_src->data.ptr + a_src->meta.ri;
43787           }
43788           if (status.repr) {
43789             goto suspend;
43790           }
43791           continue;
43792         } else if (v_marker == 219u) {
43793           if (a_src) {
43794             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
43795           }
43796           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
43797           status = wuffs_jpeg__decoder__decode_dqt(self, a_src);
43798           if (a_src) {
43799             iop_a_src = a_src->data.ptr + a_src->meta.ri;
43800           }
43801           if (status.repr) {
43802             goto suspend;
43803           }
43804           continue;
43805         } else if (v_marker == 221u) {
43806           if (a_src) {
43807             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
43808           }
43809           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
43810           status = wuffs_jpeg__decoder__decode_dri(self, a_src);
43811           if (a_src) {
43812             iop_a_src = a_src->data.ptr + a_src->meta.ri;
43813           }
43814           if (status.repr) {
43815             goto suspend;
43816           }
43817           continue;
43818         } else {
43819           status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker);
43820           goto exit;
43821         }
43822       } else if (v_marker < 240u) {
43823       } else {
43824         if (v_marker == 254u) {
43825         } else {
43826           status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker);
43827           goto exit;
43828         }
43829       }
43830       self->private_data.s_do_decode_frame[0].scratch = self->private_impl.f_payload_length;
43831       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
43832       if (self->private_data.s_do_decode_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
43833         self->private_data.s_do_decode_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
43834         iop_a_src = io2_a_src;
43835         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
43836         goto suspend;
43837       }
43838       iop_a_src += self->private_data.s_do_decode_frame[0].scratch;
43839       self->private_impl.f_payload_length = 0u;
43840     }
43841     self->private_impl.f_call_sequence = 96u;
43842 
43843     ok:
43844     self->private_impl.p_do_decode_frame[0] = 0;
43845     goto exit;
43846   }
43847 
43848   goto suspend;
43849   suspend:
43850   self->private_impl.p_do_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
43851   self->private_data.s_do_decode_frame[0].v_marker = v_marker;
43852 
43853   goto exit;
43854   exit:
43855   if (a_src && a_src->data.ptr) {
43856     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
43857   }
43858 
43859   return status;
43860 }
43861 
43862 // -------- func jpeg.decoder.decode_dht
43863 
43864 WUFFS_BASE__GENERATED_C_CODE
43865 static wuffs_base__status
wuffs_jpeg__decoder__decode_dht(wuffs_jpeg__decoder * self,wuffs_base__io_buffer * a_src)43866 wuffs_jpeg__decoder__decode_dht(
43867     wuffs_jpeg__decoder* self,
43868     wuffs_base__io_buffer* a_src) {
43869   wuffs_base__status status = wuffs_base__make_status(NULL);
43870 
43871   uint8_t v_c = 0;
43872   uint8_t v_tc = 0;
43873   uint8_t v_th = 0;
43874   uint8_t v_tc4_th = 0;
43875   uint32_t v_working_total_count = 0;
43876   uint32_t v_total_count = 0;
43877   uint32_t v_i = 0;
43878   bool v_failed = false;
43879 
43880   const uint8_t* iop_a_src = NULL;
43881   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43882   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43883   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43884   if (a_src && a_src->data.ptr) {
43885     io0_a_src = a_src->data.ptr;
43886     io1_a_src = io0_a_src + a_src->meta.ri;
43887     iop_a_src = io1_a_src;
43888     io2_a_src = io0_a_src + a_src->meta.wi;
43889   }
43890 
43891   uint32_t coro_susp_point = self->private_impl.p_decode_dht[0];
43892   if (coro_susp_point) {
43893     v_tc4_th = self->private_data.s_decode_dht[0].v_tc4_th;
43894     v_total_count = self->private_data.s_decode_dht[0].v_total_count;
43895     v_i = self->private_data.s_decode_dht[0].v_i;
43896   }
43897   switch (coro_susp_point) {
43898     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
43899 
43900     if (self->private_impl.f_sof_marker == 0u) {
43901       status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker);
43902       goto exit;
43903     }
43904     while (self->private_impl.f_payload_length > 0u) {
43905       if (self->private_impl.f_payload_length < 17u) {
43906         status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker);
43907         goto exit;
43908       }
43909       self->private_impl.f_payload_length -= 17u;
43910       {
43911         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
43912         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
43913           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
43914           goto suspend;
43915         }
43916         uint8_t t_0 = *iop_a_src++;
43917         v_c = t_0;
43918       }
43919       if (((v_c >> 4u) > 1u) || ((v_c & 15u) > 3u)) {
43920         status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker);
43921         goto exit;
43922       }
43923       v_tc = (v_c >> 4u);
43924       v_th = (v_c & 15u);
43925       v_tc4_th = ((uint8_t)(((v_tc * 4u) | v_th)));
43926       if ((self->private_impl.f_sof_marker == 192u) && ((v_tc4_th & 3u) > 1u)) {
43927         status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker);
43928         goto exit;
43929       }
43930       v_i = 0u;
43931       while (v_i < 16u) {
43932         {
43933           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
43934           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
43935             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
43936             goto suspend;
43937           }
43938           uint8_t t_1 = *iop_a_src++;
43939           self->private_data.f_dht_temp_counts[v_i] = t_1;
43940         }
43941         v_i += 1u;
43942       }
43943       v_working_total_count = 0u;
43944       v_i = 0u;
43945       while (v_i < 16u) {
43946         v_working_total_count = ((v_working_total_count + ((uint32_t)(self->private_data.f_dht_temp_counts[v_i]))) & 65535u);
43947         v_i += 1u;
43948       }
43949       if ((v_working_total_count <= 0u) || (256u < v_working_total_count)) {
43950         status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker);
43951         goto exit;
43952       }
43953       v_total_count = v_working_total_count;
43954       if (self->private_impl.f_payload_length < v_total_count) {
43955         status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker);
43956         goto exit;
43957       }
43958       self->private_impl.f_payload_length -= v_total_count;
43959       v_i = 0u;
43960       while (v_i < v_total_count) {
43961         {
43962           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
43963           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
43964             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
43965             goto suspend;
43966           }
43967           uint8_t t_2 = *iop_a_src++;
43968           self->private_impl.f_huff_tables_symbols[v_tc4_th][v_i] = t_2;
43969         }
43970         v_i += 1u;
43971       }
43972       while (v_i < 256u) {
43973         self->private_impl.f_huff_tables_symbols[v_tc4_th][v_i] = 0u;
43974         v_i += 1u;
43975       }
43976       if ((v_tc4_th & 4u) == 0u) {
43977         v_i = 0u;
43978         while (v_i < v_total_count) {
43979           if (self->private_impl.f_huff_tables_symbols[v_tc4_th][v_i] > 15u) {
43980             status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker);
43981             goto exit;
43982           }
43983           v_i += 1u;
43984         }
43985       }
43986       v_failed = wuffs_jpeg__decoder__calculate_huff_tables(self, v_tc4_th, v_total_count);
43987       if (v_failed) {
43988         status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker);
43989         goto exit;
43990       }
43991       self->private_impl.f_seen_dht[v_tc4_th] = true;
43992     }
43993 
43994     goto ok;
43995     ok:
43996     self->private_impl.p_decode_dht[0] = 0;
43997     goto exit;
43998   }
43999 
44000   goto suspend;
44001   suspend:
44002   self->private_impl.p_decode_dht[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
44003   self->private_data.s_decode_dht[0].v_tc4_th = v_tc4_th;
44004   self->private_data.s_decode_dht[0].v_total_count = v_total_count;
44005   self->private_data.s_decode_dht[0].v_i = v_i;
44006 
44007   goto exit;
44008   exit:
44009   if (a_src && a_src->data.ptr) {
44010     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
44011   }
44012 
44013   return status;
44014 }
44015 
44016 // -------- func jpeg.decoder.calculate_huff_tables
44017 
44018 WUFFS_BASE__GENERATED_C_CODE
44019 static bool
wuffs_jpeg__decoder__calculate_huff_tables(wuffs_jpeg__decoder * self,uint8_t a_tc4_th,uint32_t a_total_count)44020 wuffs_jpeg__decoder__calculate_huff_tables(
44021     wuffs_jpeg__decoder* self,
44022     uint8_t a_tc4_th,
44023     uint32_t a_total_count) {
44024   uint32_t v_i = 0;
44025   uint8_t v_j = 0;
44026   uint8_t v_k = 0;
44027   uint32_t v_bit_length_minus_one = 0;
44028   uint8_t v_bit_length = 0;
44029   uint32_t v_bit_string = 0;
44030   uint32_t v_slow = 0;
44031   uint8_t v_prefix = 0;
44032   uint16_t v_fast = 0;
44033   uint32_t v_reps = 0;
44034 
44035   v_i = 0u;
44036   v_k = 0u;
44037   v_bit_length_minus_one = 0u;
44038   while (v_i < a_total_count) {
44039     while (v_k >= self->private_data.f_dht_temp_counts[v_bit_length_minus_one]) {
44040       v_k = 0u;
44041       v_bit_length_minus_one = ((v_bit_length_minus_one + 1u) & 15u);
44042     }
44043 #if defined(__GNUC__)
44044 #pragma GCC diagnostic push
44045 #pragma GCC diagnostic ignored "-Wconversion"
44046 #endif
44047     v_k += 1u;
44048 #if defined(__GNUC__)
44049 #pragma GCC diagnostic pop
44050 #endif
44051     self->private_data.f_dht_temp_bit_lengths[v_i] = ((uint8_t)((v_bit_length_minus_one + 1u)));
44052     v_i += 1u;
44053   }
44054   v_bit_length = 0u;
44055   v_bit_string = 0u;
44056   v_i = 0u;
44057   while (v_i < a_total_count) {
44058     while (v_bit_length < self->private_data.f_dht_temp_bit_lengths[v_i]) {
44059       if (v_bit_length >= 16u) {
44060         return true;
44061       }
44062 #if defined(__GNUC__)
44063 #pragma GCC diagnostic push
44064 #pragma GCC diagnostic ignored "-Wconversion"
44065 #endif
44066       v_bit_length += 1u;
44067 #if defined(__GNUC__)
44068 #pragma GCC diagnostic pop
44069 #endif
44070       v_bit_string <<= 1u;
44071     }
44072     self->private_data.f_dht_temp_bit_strings[v_i] = ((uint16_t)(v_bit_string));
44073     v_bit_string += 1u;
44074     if ((v_bit_string >> v_bit_length) > 0u) {
44075       return true;
44076     }
44077     v_i += 1u;
44078   }
44079   v_k = 0u;
44080   v_bit_length_minus_one = 0u;
44081   while (true) {
44082     if (self->private_data.f_dht_temp_counts[v_bit_length_minus_one] == 0u) {
44083       self->private_impl.f_huff_tables_slow[a_tc4_th][v_bit_length_minus_one] = 0u;
44084     } else {
44085       v_slow = (255u & ((uint32_t)(((uint32_t)(v_k)) - ((uint32_t)(self->private_data.f_dht_temp_bit_strings[v_k])))));
44086       v_k += self->private_data.f_dht_temp_counts[v_bit_length_minus_one];
44087       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));
44088     }
44089     v_bit_length_minus_one = ((v_bit_length_minus_one + 1u) & 15u);
44090     if (v_bit_length_minus_one == 0u) {
44091       break;
44092     }
44093   }
44094   v_i = 0u;
44095   while (v_i < 256u) {
44096     self->private_impl.f_huff_tables_fast[a_tc4_th][v_i] = 65535u;
44097     v_i += 1u;
44098   }
44099   v_j = 0u;
44100   v_bit_length_minus_one = 0u;
44101   while (v_bit_length_minus_one < 8u) {
44102     v_k = 0u;
44103     while (v_k < self->private_data.f_dht_temp_counts[v_bit_length_minus_one]) {
44104       v_prefix = ((uint8_t)((((uint32_t)(self->private_data.f_dht_temp_bit_strings[v_j])) << (7u - v_bit_length_minus_one))));
44105       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])))));
44106       v_reps = (((uint32_t)(1u)) << (7u - v_bit_length_minus_one));
44107       while (v_reps > 0u) {
44108         self->private_impl.f_huff_tables_fast[a_tc4_th][v_prefix] = v_fast;
44109         v_prefix += 1u;
44110         v_reps -= 1u;
44111       }
44112 #if defined(__GNUC__)
44113 #pragma GCC diagnostic push
44114 #pragma GCC diagnostic ignored "-Wconversion"
44115 #endif
44116       v_k += 1u;
44117 #if defined(__GNUC__)
44118 #pragma GCC diagnostic pop
44119 #endif
44120       v_j += 1u;
44121     }
44122     v_bit_length_minus_one += 1u;
44123   }
44124   return false;
44125 }
44126 
44127 // -------- func jpeg.decoder.decode_sos
44128 
44129 WUFFS_BASE__GENERATED_C_CODE
44130 static wuffs_base__status
wuffs_jpeg__decoder__decode_sos(wuffs_jpeg__decoder * self,wuffs_base__io_buffer * a_src,wuffs_base__slice_u8 a_workbuf)44131 wuffs_jpeg__decoder__decode_sos(
44132     wuffs_jpeg__decoder* self,
44133     wuffs_base__io_buffer* a_src,
44134     wuffs_base__slice_u8 a_workbuf) {
44135   wuffs_base__status status = wuffs_base__make_status(NULL);
44136 
44137   uint32_t v_my = 0;
44138   uint32_t v_mx = 0;
44139   uint32_t v_decode_mcu_result = 0;
44140   uint32_t v_bitstream_length = 0;
44141 
44142   uint32_t coro_susp_point = self->private_impl.p_decode_sos[0];
44143   if (coro_susp_point) {
44144     v_my = self->private_data.s_decode_sos[0].v_my;
44145     v_mx = self->private_data.s_decode_sos[0].v_mx;
44146   }
44147   switch (coro_susp_point) {
44148     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
44149 
44150     if (self->private_impl.f_scan_count >= 64u) {
44151       status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_scan_count);
44152       goto exit;
44153     }
44154     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
44155     status = wuffs_jpeg__decoder__prepare_scan(self, a_src);
44156     if (status.repr) {
44157       goto suspend;
44158     }
44159     self->private_impl.f_next_restart_marker = 0u;
44160     self->private_impl.f_mcu_previous_dc_values[0u] = 0u;
44161     self->private_impl.f_mcu_previous_dc_values[1u] = 0u;
44162     self->private_impl.f_mcu_previous_dc_values[2u] = 0u;
44163     self->private_impl.f_mcu_previous_dc_values[3u] = 0u;
44164     self->private_impl.f_restarts_remaining = self->private_impl.f_restart_interval;
44165     self->private_impl.f_eob_run = 0u;
44166     self->private_impl.f_bitstream_bits = 0u;
44167     self->private_impl.f_bitstream_n_bits = 0u;
44168     self->private_impl.f_bitstream_ri = 0u;
44169     self->private_impl.f_bitstream_wi = 0u;
44170     self->private_impl.f_bitstream_padding = 12345u;
44171     wuffs_jpeg__decoder__fill_bitstream(self, a_src);
44172     v_my = 0u;
44173     while (v_my < self->private_impl.f_scan_height_in_mcus) {
44174       v_mx = 0u;
44175       while (v_mx < self->private_impl.f_scan_width_in_mcus) {
44176         self->private_impl.f_mcu_current_block = 0u;
44177         self->private_impl.f_mcu_zig_index = ((uint32_t)(self->private_impl.f_scan_ss));
44178         if (self->private_impl.f_sof_marker >= 194u) {
44179           wuffs_jpeg__decoder__load_mcu_blocks(self, v_mx, v_my, a_workbuf);
44180         }
44181         while (true) {
44182           v_decode_mcu_result = wuffs_jpeg__decoder__decode_mcu(self, a_workbuf, v_mx, v_my);
44183           if (v_decode_mcu_result == 0u) {
44184             break;
44185           } else if (v_decode_mcu_result != 1u) {
44186             status = wuffs_base__make_status(wuffs_jpeg__error__internal_error_inconsistent_decoder_state);
44187             goto exit;
44188           }
44189           while (true) {
44190             v_bitstream_length = ((uint32_t)(self->private_impl.f_bitstream_wi - self->private_impl.f_bitstream_ri));
44191             wuffs_jpeg__decoder__fill_bitstream(self, a_src);
44192             if (v_bitstream_length < ((uint32_t)(self->private_impl.f_bitstream_wi - self->private_impl.f_bitstream_ri))) {
44193               break;
44194             } else if (self->private_impl.f_bitstream_padding == 0u) {
44195               status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
44196               goto exit;
44197             } else if ((a_src && a_src->meta.closed) &&  ! self->private_impl.f_bitstream_is_closed) {
44198               if (self->private_impl.f_bitstream_wi < 1024u) {
44199                 wuffs_base__bulk_memset(&self->private_data.f_bitstream_buffer[self->private_impl.f_bitstream_wi], 264u, 0u);
44200                 self->private_impl.f_bitstream_wi += 264u;
44201                 self->private_impl.f_bitstream_is_closed = true;
44202               }
44203               break;
44204             }
44205             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
44206             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
44207           }
44208         }
44209         if (self->private_impl.f_sof_marker >= 194u) {
44210           wuffs_jpeg__decoder__save_mcu_blocks(self, v_mx, v_my, a_workbuf);
44211         }
44212         if (self->private_impl.f_restarts_remaining > 0u) {
44213 #if defined(__GNUC__)
44214 #pragma GCC diagnostic push
44215 #pragma GCC diagnostic ignored "-Wconversion"
44216 #endif
44217           self->private_impl.f_restarts_remaining -= 1u;
44218 #if defined(__GNUC__)
44219 #pragma GCC diagnostic pop
44220 #endif
44221           if (self->private_impl.f_restarts_remaining == 0u) {
44222             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
44223             status = wuffs_jpeg__decoder__skip_past_the_next_restart_marker(self, a_src);
44224             if (status.repr) {
44225               goto suspend;
44226             }
44227             self->private_impl.f_mcu_previous_dc_values[0u] = 0u;
44228             self->private_impl.f_mcu_previous_dc_values[1u] = 0u;
44229             self->private_impl.f_mcu_previous_dc_values[2u] = 0u;
44230             self->private_impl.f_mcu_previous_dc_values[3u] = 0u;
44231             self->private_impl.f_restarts_remaining = self->private_impl.f_restart_interval;
44232             self->private_impl.f_eob_run = 0u;
44233             self->private_impl.f_bitstream_bits = 0u;
44234             self->private_impl.f_bitstream_n_bits = 0u;
44235             self->private_impl.f_bitstream_ri = 0u;
44236             self->private_impl.f_bitstream_wi = 0u;
44237             self->private_impl.f_bitstream_padding = 12345u;
44238           }
44239         }
44240         v_mx += 1u;
44241       }
44242       v_my += 1u;
44243     }
44244     wuffs_base__u32__sat_add_indirect(&self->private_impl.f_scan_count, 1u);
44245 
44246     ok:
44247     self->private_impl.p_decode_sos[0] = 0;
44248     goto exit;
44249   }
44250 
44251   goto suspend;
44252   suspend:
44253   self->private_impl.p_decode_sos[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
44254   self->private_data.s_decode_sos[0].v_my = v_my;
44255   self->private_data.s_decode_sos[0].v_mx = v_mx;
44256 
44257   goto exit;
44258   exit:
44259   return status;
44260 }
44261 
44262 // -------- func jpeg.decoder.prepare_scan
44263 
44264 WUFFS_BASE__GENERATED_C_CODE
44265 static wuffs_base__status
wuffs_jpeg__decoder__prepare_scan(wuffs_jpeg__decoder * self,wuffs_base__io_buffer * a_src)44266 wuffs_jpeg__decoder__prepare_scan(
44267     wuffs_jpeg__decoder* self,
44268     wuffs_base__io_buffer* a_src) {
44269   wuffs_base__status status = wuffs_base__make_status(NULL);
44270 
44271   uint8_t v_c = 0;
44272   uint32_t v_i = 0;
44273   uint32_t v_j = 0;
44274   uint32_t v_j_max_incl = 0;
44275   bool v_failed = false;
44276 
44277   const uint8_t* iop_a_src = NULL;
44278   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
44279   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
44280   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
44281   if (a_src && a_src->data.ptr) {
44282     io0_a_src = a_src->data.ptr;
44283     io1_a_src = io0_a_src + a_src->meta.ri;
44284     iop_a_src = io1_a_src;
44285     io2_a_src = io0_a_src + a_src->meta.wi;
44286   }
44287 
44288   uint32_t coro_susp_point = self->private_impl.p_prepare_scan[0];
44289   if (coro_susp_point) {
44290     v_i = self->private_data.s_prepare_scan[0].v_i;
44291   }
44292   switch (coro_susp_point) {
44293     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
44294 
44295     if ((self->private_impl.f_payload_length < 6u) || (self->private_impl.f_payload_length > 12u)) {
44296       status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
44297       goto exit;
44298     }
44299     {
44300       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
44301       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
44302         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
44303         goto suspend;
44304       }
44305       uint8_t t_0 = *iop_a_src++;
44306       v_c = t_0;
44307     }
44308     if ((v_c < 1u) || (v_c > 4u)) {
44309       status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
44310       goto exit;
44311     }
44312     self->private_impl.f_scan_num_components = ((uint32_t)(v_c));
44313     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)))) {
44314       status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
44315       goto exit;
44316     }
44317     self->private_impl.f_payload_length = 0u;
44318     v_i = 0u;
44319     while (v_i < self->private_impl.f_scan_num_components) {
44320       {
44321         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
44322         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
44323           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
44324           goto suspend;
44325         }
44326         uint8_t t_1 = *iop_a_src++;
44327         v_c = t_1;
44328       }
44329       v_j = 0u;
44330       while (true) {
44331         if (v_j >= self->private_impl.f_num_components) {
44332           status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
44333           goto exit;
44334         }
44335         if (v_c == self->private_impl.f_components_c[v_j]) {
44336           if ( ! self->private_impl.f_seen_dqt[self->private_impl.f_components_tq[v_j]]) {
44337             status = wuffs_base__make_status(wuffs_jpeg__error__missing_quantization_table);
44338             goto exit;
44339           }
44340           self->private_impl.f_scan_comps_cselector[v_i] = ((uint8_t)(v_j));
44341           break;
44342         }
44343         v_j += 1u;
44344       }
44345       v_j = 0u;
44346       while (v_j < v_i) {
44347         if (self->private_impl.f_scan_comps_cselector[v_i] == self->private_impl.f_scan_comps_cselector[v_j]) {
44348           status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
44349           goto exit;
44350         }
44351         v_j += 1u;
44352       }
44353       {
44354         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
44355         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
44356           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
44357           goto suspend;
44358         }
44359         uint8_t t_2 = *iop_a_src++;
44360         v_c = t_2;
44361       }
44362       if (((v_c >> 4u) > 3u) || ((v_c & 15u) > 3u)) {
44363         status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
44364         goto exit;
44365       }
44366       self->private_impl.f_scan_comps_td[v_i] = (v_c >> 4u);
44367       self->private_impl.f_scan_comps_ta[v_i] = (v_c & 15u);
44368       if (self->private_impl.f_sof_marker == 192u) {
44369         if ((self->private_impl.f_scan_comps_td[v_i] > 1u) || (self->private_impl.f_scan_comps_ta[v_i] > 1u)) {
44370           status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
44371           goto exit;
44372         }
44373       }
44374       v_i += 1u;
44375     }
44376     if (self->private_impl.f_sof_marker < 194u) {
44377       self->private_data.s_prepare_scan[0].scratch = 3u;
44378       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
44379       if (self->private_data.s_prepare_scan[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
44380         self->private_data.s_prepare_scan[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
44381         iop_a_src = io2_a_src;
44382         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
44383         goto suspend;
44384       }
44385       iop_a_src += self->private_data.s_prepare_scan[0].scratch;
44386       self->private_impl.f_scan_ss = 0u;
44387       self->private_impl.f_scan_se = 63u;
44388       self->private_impl.f_scan_ah = 0u;
44389       self->private_impl.f_scan_al = 0u;
44390     } else {
44391       {
44392         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
44393         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
44394           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
44395           goto suspend;
44396         }
44397         uint8_t t_3 = *iop_a_src++;
44398         v_c = t_3;
44399       }
44400       if (v_c > 63u) {
44401         status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
44402         goto exit;
44403       }
44404       self->private_impl.f_scan_ss = v_c;
44405       {
44406         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
44407         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
44408           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
44409           goto suspend;
44410         }
44411         uint8_t t_4 = *iop_a_src++;
44412         v_c = t_4;
44413       }
44414       if ((v_c > 63u) || (v_c < self->private_impl.f_scan_ss)) {
44415         status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
44416         goto exit;
44417       }
44418       self->private_impl.f_scan_se = v_c;
44419       {
44420         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
44421         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
44422           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
44423           goto suspend;
44424         }
44425         uint8_t t_5 = *iop_a_src++;
44426         v_c = t_5;
44427       }
44428       if (((v_c >> 4u) > 14u) || ((v_c & 15u) > 13u)) {
44429         status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
44430         goto exit;
44431       }
44432       self->private_impl.f_scan_ah = (v_c >> 4u);
44433       self->private_impl.f_scan_al = (v_c & 15u);
44434       if (self->private_impl.f_scan_ah > 0u) {
44435         if ((self->private_impl.f_scan_ah - 1u) != self->private_impl.f_scan_al) {
44436           status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
44437           goto exit;
44438         }
44439       }
44440       if (self->private_impl.f_scan_ss == 0u) {
44441         if (self->private_impl.f_scan_se != 0u) {
44442           status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
44443           goto exit;
44444         } else if (self->private_impl.f_scan_ah == 0u) {
44445           self->private_impl.choosy_decode_mcu = (
44446               &wuffs_jpeg__decoder__decode_mcu_progressive_dc_high_bits);
44447         } else {
44448           self->private_impl.choosy_decode_mcu = (
44449               &wuffs_jpeg__decoder__decode_mcu_progressive_dc_low_bit);
44450         }
44451       } else {
44452         if (self->private_impl.f_scan_num_components != 1u) {
44453           status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
44454           goto exit;
44455         } else if (self->private_impl.f_scan_ah == 0u) {
44456           self->private_impl.choosy_decode_mcu = (
44457               &wuffs_jpeg__decoder__decode_mcu_progressive_ac_high_bits);
44458         } else {
44459           self->private_impl.choosy_decode_mcu = (
44460               &wuffs_jpeg__decoder__decode_mcu_progressive_ac_low_bit);
44461         }
44462       }
44463     }
44464     v_i = 0u;
44465     while (v_i < self->private_impl.f_scan_num_components) {
44466       if ((self->private_impl.f_scan_ss == 0u) &&  ! self->private_impl.f_seen_dht[(0u | self->private_impl.f_scan_comps_td[v_i])]) {
44467         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
44468         status = wuffs_jpeg__decoder__use_default_huffman_table(self, (0u | self->private_impl.f_scan_comps_td[v_i]));
44469         if (status.repr) {
44470           goto suspend;
44471         }
44472       }
44473       if ((self->private_impl.f_scan_se != 0u) &&  ! self->private_impl.f_seen_dht[(4u | self->private_impl.f_scan_comps_ta[v_i])]) {
44474         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
44475         status = wuffs_jpeg__decoder__use_default_huffman_table(self, (4u | self->private_impl.f_scan_comps_ta[v_i]));
44476         if (status.repr) {
44477           goto suspend;
44478         }
44479       }
44480       v_j = ((uint32_t)(self->private_impl.f_scan_ss));
44481       v_j_max_incl = ((uint32_t)(wuffs_base__u8__min(self->private_impl.f_scan_se, 9u)));
44482       while (v_j <= v_j_max_incl) {
44483         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;
44484         v_j += 1u;
44485       }
44486       v_i += 1u;
44487     }
44488     if (self->private_impl.f_scan_num_components == 1u) {
44489       wuffs_jpeg__decoder__calculate_single_component_scan_fields(self);
44490     } else {
44491       v_failed = wuffs_jpeg__decoder__calculate_multiple_component_scan_fields(self);
44492       if (v_failed) {
44493         status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
44494         goto exit;
44495       }
44496     }
44497 
44498     goto ok;
44499     ok:
44500     self->private_impl.p_prepare_scan[0] = 0;
44501     goto exit;
44502   }
44503 
44504   goto suspend;
44505   suspend:
44506   self->private_impl.p_prepare_scan[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
44507   self->private_data.s_prepare_scan[0].v_i = v_i;
44508 
44509   goto exit;
44510   exit:
44511   if (a_src && a_src->data.ptr) {
44512     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
44513   }
44514 
44515   return status;
44516 }
44517 
44518 // -------- func jpeg.decoder.use_default_huffman_table
44519 
44520 WUFFS_BASE__GENERATED_C_CODE
44521 static wuffs_base__status
wuffs_jpeg__decoder__use_default_huffman_table(wuffs_jpeg__decoder * self,uint8_t a_tc4_th)44522 wuffs_jpeg__decoder__use_default_huffman_table(
44523     wuffs_jpeg__decoder* self,
44524     uint8_t a_tc4_th) {
44525   wuffs_base__status status = wuffs_base__make_status(NULL);
44526 
44527   wuffs_base__slice_u8 v_data = {0};
44528   wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer();
44529   wuffs_base__io_buffer* v_r = &u_r;
44530   const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
44531   const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
44532   const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
44533   const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
44534   wuffs_base__status v_status = wuffs_base__make_status(NULL);
44535 
44536   if (a_tc4_th == 0u) {
44537     v_data = wuffs_base__make_slice_u8(wuffs_base__strip_const_from_u8_ptr(WUFFS_JPEG__DEFAULT_HUFF_TABLE_DC_LUMA), 29);
44538   } else if (a_tc4_th == 1u) {
44539     v_data = wuffs_base__make_slice_u8(wuffs_base__strip_const_from_u8_ptr(WUFFS_JPEG__DEFAULT_HUFF_TABLE_DC_CHROMA), 29);
44540   } else if (a_tc4_th == 4u) {
44541     v_data = wuffs_base__make_slice_u8(wuffs_base__strip_const_from_u8_ptr(WUFFS_JPEG__DEFAULT_HUFF_TABLE_AC_LUMA), 179);
44542   } else if (a_tc4_th == 5u) {
44543     v_data = wuffs_base__make_slice_u8(wuffs_base__strip_const_from_u8_ptr(WUFFS_JPEG__DEFAULT_HUFF_TABLE_AC_CHROMA), 179);
44544   } else {
44545     status = wuffs_base__make_status(wuffs_jpeg__error__missing_huffman_table);
44546     goto exit;
44547   }
44548   {
44549     wuffs_base__io_buffer* o_0_v_r = v_r;
44550     const uint8_t *o_0_iop_v_r = iop_v_r;
44551     const uint8_t *o_0_io0_v_r = io0_v_r;
44552     const uint8_t *o_0_io1_v_r = io1_v_r;
44553     const uint8_t *o_0_io2_v_r = io2_v_r;
44554     v_r = wuffs_base__io_reader__set(
44555         &u_r,
44556         &iop_v_r,
44557         &io0_v_r,
44558         &io1_v_r,
44559         &io2_v_r,
44560         v_data,
44561         0u);
44562     self->private_impl.f_payload_length = ((uint32_t)((((uint64_t)(v_data.len)) & 65535u)));
44563     {
44564       wuffs_base__status t_0 = wuffs_jpeg__decoder__decode_dht(self, v_r);
44565       v_status = t_0;
44566     }
44567     v_r = o_0_v_r;
44568     iop_v_r = o_0_iop_v_r;
44569     io0_v_r = o_0_io0_v_r;
44570     io1_v_r = o_0_io1_v_r;
44571     io2_v_r = o_0_io2_v_r;
44572   }
44573   status = v_status;
44574   if (wuffs_base__status__is_error(&status)) {
44575     goto exit;
44576   } else if (wuffs_base__status__is_suspension(&status)) {
44577     status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
44578     goto exit;
44579   }
44580   goto ok;
44581 
44582   ok:
44583   goto exit;
44584   exit:
44585   return status;
44586 }
44587 
44588 // -------- func jpeg.decoder.calculate_single_component_scan_fields
44589 
44590 WUFFS_BASE__GENERATED_C_CODE
44591 static wuffs_base__empty_struct
wuffs_jpeg__decoder__calculate_single_component_scan_fields(wuffs_jpeg__decoder * self)44592 wuffs_jpeg__decoder__calculate_single_component_scan_fields(
44593     wuffs_jpeg__decoder* self) {
44594   uint8_t v_csel = 0;
44595 
44596   self->private_impl.f_scan_comps_bx_offset[0u] = 0u;
44597   self->private_impl.f_scan_comps_by_offset[0u] = 0u;
44598   self->private_impl.f_mcu_num_blocks = 1u;
44599   self->private_impl.f_mcu_blocks_sselector[0u] = 0u;
44600   v_csel = self->private_impl.f_scan_comps_cselector[0u];
44601   self->private_impl.f_mcu_blocks_offset[0u] = self->private_impl.f_components_workbuf_offsets[v_csel];
44602   self->private_impl.f_mcu_blocks_mx_mul[0u] = 8u;
44603   self->private_impl.f_mcu_blocks_my_mul[0u] = (8u * self->private_impl.f_components_workbuf_widths[v_csel]);
44604   self->private_impl.f_mcu_blocks_dc_hselector[0u] = (0u | self->private_impl.f_scan_comps_td[0u]);
44605   self->private_impl.f_mcu_blocks_ac_hselector[0u] = (4u | self->private_impl.f_scan_comps_ta[0u]);
44606   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);
44607   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);
44608   return wuffs_base__make_empty_struct();
44609 }
44610 
44611 // -------- func jpeg.decoder.calculate_multiple_component_scan_fields
44612 
44613 WUFFS_BASE__GENERATED_C_CODE
44614 static bool
wuffs_jpeg__decoder__calculate_multiple_component_scan_fields(wuffs_jpeg__decoder * self)44615 wuffs_jpeg__decoder__calculate_multiple_component_scan_fields(
44616     wuffs_jpeg__decoder* self) {
44617   uint32_t v_i = 0;
44618   uint32_t v_h = 0;
44619   uint32_t v_v = 0;
44620   uint32_t v_hv = 0;
44621   uint32_t v_total_hv = 0;
44622   uint32_t v_b = 0;
44623   uint32_t v_bx_offset = 0;
44624   uint32_t v_by_offset = 0;
44625   uint8_t v_ssel = 0;
44626   uint8_t v_csel = 0;
44627 
44628   v_total_hv = 0u;
44629   v_i = 0u;
44630   v_b = 0u;
44631   v_bx_offset = 0u;
44632   v_by_offset = 0u;
44633   while (v_i < self->private_impl.f_scan_num_components) {
44634     v_h = ((uint32_t)(self->private_impl.f_components_h[self->private_impl.f_scan_comps_cselector[v_i]]));
44635     v_v = ((uint32_t)(self->private_impl.f_components_v[self->private_impl.f_scan_comps_cselector[v_i]]));
44636     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]])));
44637     v_total_hv += v_hv;
44638     while (v_hv > 0u) {
44639       self->private_impl.f_scan_comps_bx_offset[(v_b & 15u)] = ((uint8_t)((v_bx_offset & 3u)));
44640       self->private_impl.f_scan_comps_by_offset[(v_b & 15u)] = ((uint8_t)((v_by_offset & 3u)));
44641       self->private_impl.f_mcu_blocks_sselector[(v_b & 15u)] = ((uint8_t)(v_i));
44642       v_b += 1u;
44643       v_bx_offset += 1u;
44644       if (v_bx_offset == v_h) {
44645         v_bx_offset = 0u;
44646         v_by_offset += 1u;
44647         if (v_by_offset == v_v) {
44648           v_by_offset = 0u;
44649         }
44650       }
44651       v_hv -= 1u;
44652     }
44653     v_i += 1u;
44654   }
44655   if (v_total_hv > 10u) {
44656     return true;
44657   }
44658   self->private_impl.f_mcu_num_blocks = v_total_hv;
44659   v_b = 0u;
44660   while (v_b < self->private_impl.f_mcu_num_blocks) {
44661     v_ssel = self->private_impl.f_mcu_blocks_sselector[v_b];
44662     v_csel = self->private_impl.f_scan_comps_cselector[v_ssel];
44663     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]))));
44664     self->private_impl.f_mcu_blocks_mx_mul[v_b] = (8u * ((uint32_t)(self->private_impl.f_components_h[v_csel])));
44665     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]);
44666     self->private_impl.f_mcu_blocks_dc_hselector[v_b] = (0u | self->private_impl.f_scan_comps_td[v_ssel]);
44667     self->private_impl.f_mcu_blocks_ac_hselector[v_b] = (4u | self->private_impl.f_scan_comps_ta[v_ssel]);
44668     v_b += 1u;
44669   }
44670   self->private_impl.f_scan_width_in_mcus = self->private_impl.f_width_in_mcus;
44671   self->private_impl.f_scan_height_in_mcus = self->private_impl.f_height_in_mcus;
44672   return false;
44673 }
44674 
44675 // -------- func jpeg.decoder.fill_bitstream
44676 
44677 WUFFS_BASE__GENERATED_C_CODE
44678 static wuffs_base__empty_struct
wuffs_jpeg__decoder__fill_bitstream(wuffs_jpeg__decoder * self,wuffs_base__io_buffer * a_src)44679 wuffs_jpeg__decoder__fill_bitstream(
44680     wuffs_jpeg__decoder* self,
44681     wuffs_base__io_buffer* a_src) {
44682   uint32_t v_wi = 0;
44683   uint8_t v_c = 0;
44684   uint32_t v_new_wi = 0;
44685 
44686   const uint8_t* iop_a_src = NULL;
44687   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
44688   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
44689   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
44690   if (a_src && a_src->data.ptr) {
44691     io0_a_src = a_src->data.ptr;
44692     io1_a_src = io0_a_src + a_src->meta.ri;
44693     iop_a_src = io1_a_src;
44694     io2_a_src = io0_a_src + a_src->meta.wi;
44695   }
44696 
44697   if (self->private_impl.f_bitstream_ri <= 0u) {
44698   } else if (self->private_impl.f_bitstream_ri >= self->private_impl.f_bitstream_wi) {
44699     self->private_impl.f_bitstream_ri = 0u;
44700     self->private_impl.f_bitstream_wi = 0u;
44701   } else {
44702     v_wi = (self->private_impl.f_bitstream_wi - self->private_impl.f_bitstream_ri);
44703     wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8(self->private_data.f_bitstream_buffer, 2048), wuffs_base__make_slice_u8_ij(self->private_data.f_bitstream_buffer,
44704         self->private_impl.f_bitstream_ri,
44705         self->private_impl.f_bitstream_wi));
44706     self->private_impl.f_bitstream_ri = 0u;
44707     self->private_impl.f_bitstream_wi = v_wi;
44708   }
44709   v_wi = self->private_impl.f_bitstream_wi;
44710   while ((v_wi < 2048u) && (((uint64_t)(io2_a_src - iop_a_src)) > 0u)) {
44711     v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
44712     if (v_c < 255u) {
44713       self->private_data.f_bitstream_buffer[v_wi] = v_c;
44714       v_wi += 1u;
44715       iop_a_src += 1u;
44716       continue;
44717     } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 1u) {
44718       break;
44719     } else if ((wuffs_base__peek_u16le__no_bounds_check(iop_a_src) >> 8u) > 0u) {
44720       break;
44721     } else {
44722       self->private_data.f_bitstream_buffer[v_wi] = 255u;
44723       v_wi += 1u;
44724       iop_a_src += 2u;
44725     }
44726   }
44727   if (((uint64_t)(io2_a_src - iop_a_src)) > 1u) {
44728     if ((wuffs_base__peek_u8be__no_bounds_check(iop_a_src) >= 255u) && ((wuffs_base__peek_u16le__no_bounds_check(iop_a_src) >> 8u) > 0u)) {
44729       v_new_wi = (wuffs_base__u32__min(v_wi, 1784u) + 264u);
44730       v_new_wi = wuffs_base__u32__min(v_new_wi, (v_wi + self->private_impl.f_bitstream_padding));
44731       if (v_wi < v_new_wi) {
44732         wuffs_base__u32__sat_sub_indirect(&self->private_impl.f_bitstream_padding, (v_new_wi - v_wi));
44733         wuffs_base__bulk_memset(&self->private_data.f_bitstream_buffer[v_wi], (v_new_wi - v_wi), 0u);
44734         v_wi = v_new_wi;
44735       }
44736     }
44737   }
44738   self->private_impl.f_bitstream_wi = v_wi;
44739   if (a_src && a_src->data.ptr) {
44740     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
44741   }
44742 
44743   return wuffs_base__make_empty_struct();
44744 }
44745 
44746 // -------- func jpeg.decoder.load_mcu_blocks_for_single_component
44747 
44748 WUFFS_BASE__GENERATED_C_CODE
44749 static wuffs_base__empty_struct
wuffs_jpeg__decoder__load_mcu_blocks_for_single_component(wuffs_jpeg__decoder * self,uint32_t a_mx,uint32_t a_my,wuffs_base__slice_u8 a_workbuf,uint32_t a_csel)44750 wuffs_jpeg__decoder__load_mcu_blocks_for_single_component(
44751     wuffs_jpeg__decoder* self,
44752     uint32_t a_mx,
44753     uint32_t a_my,
44754     wuffs_base__slice_u8 a_workbuf,
44755     uint32_t a_csel) {
44756   return (*self->private_impl.choosy_load_mcu_blocks_for_single_component)(self, a_mx, a_my, a_workbuf, a_csel);
44757 }
44758 
44759 WUFFS_BASE__GENERATED_C_CODE
44760 static wuffs_base__empty_struct
wuffs_jpeg__decoder__load_mcu_blocks_for_single_component__choosy_default(wuffs_jpeg__decoder * self,uint32_t a_mx,uint32_t a_my,wuffs_base__slice_u8 a_workbuf,uint32_t a_csel)44761 wuffs_jpeg__decoder__load_mcu_blocks_for_single_component__choosy_default(
44762     wuffs_jpeg__decoder* self,
44763     uint32_t a_mx,
44764     uint32_t a_my,
44765     wuffs_base__slice_u8 a_workbuf,
44766     uint32_t a_csel) {
44767   uint64_t v_stride16 = 0;
44768   uint64_t v_offset = 0;
44769 
44770   v_stride16 = ((uint64_t)((self->private_impl.f_components_workbuf_widths[a_csel] * 16u)));
44771   v_offset = (self->private_impl.f_components_workbuf_offsets[(a_csel | 4u)] + (((uint64_t)(a_mx)) * 128u) + (((uint64_t)(a_my)) * v_stride16));
44772   if (v_offset <= ((uint64_t)(a_workbuf.len))) {
44773     wuffs_base__bulk_load_host_endian(&self->private_data.f_mcu_blocks[0], 1u * (size_t)128u, wuffs_base__slice_u8__subslice_i(a_workbuf, v_offset));
44774   }
44775   return wuffs_base__make_empty_struct();
44776 }
44777 
44778 // -------- func jpeg.decoder.load_mcu_blocks
44779 
44780 WUFFS_BASE__GENERATED_C_CODE
44781 static wuffs_base__empty_struct
wuffs_jpeg__decoder__load_mcu_blocks(wuffs_jpeg__decoder * self,uint32_t a_mx,uint32_t a_my,wuffs_base__slice_u8 a_workbuf)44782 wuffs_jpeg__decoder__load_mcu_blocks(
44783     wuffs_jpeg__decoder* self,
44784     uint32_t a_mx,
44785     uint32_t a_my,
44786     wuffs_base__slice_u8 a_workbuf) {
44787   uint32_t v_b = 0;
44788   uint8_t v_csel = 0;
44789   uint64_t v_h = 0;
44790   uint64_t v_v = 0;
44791   uint64_t v_stride16 = 0;
44792   uint64_t v_offset = 0;
44793 
44794   v_h = 1u;
44795   v_v = 1u;
44796   v_b = 0u;
44797   while (v_b < self->private_impl.f_mcu_num_blocks) {
44798     v_csel = self->private_impl.f_scan_comps_cselector[self->private_impl.f_mcu_blocks_sselector[v_b]];
44799     if (self->private_impl.f_scan_num_components > 1u) {
44800       v_h = ((uint64_t)(self->private_impl.f_components_h[v_csel]));
44801       v_v = ((uint64_t)(self->private_impl.f_components_v[v_csel]));
44802     }
44803     v_stride16 = ((uint64_t)((self->private_impl.f_components_workbuf_widths[v_csel] * 16u)));
44804     v_offset = (self->private_impl.f_components_workbuf_offsets[(v_csel | 4u)] + (((v_h * ((uint64_t)(a_mx))) + ((uint64_t)(self->private_impl.f_scan_comps_bx_offset[v_b]))) * 128u) + (((v_v * ((uint64_t)(a_my))) + ((uint64_t)(self->private_impl.f_scan_comps_by_offset[v_b]))) * v_stride16));
44805     if (v_offset <= ((uint64_t)(a_workbuf.len))) {
44806       wuffs_base__bulk_load_host_endian(&self->private_data.f_mcu_blocks[v_b], 1u * (size_t)128u, wuffs_base__slice_u8__subslice_i(a_workbuf, v_offset));
44807     }
44808     v_b += 1u;
44809   }
44810   return wuffs_base__make_empty_struct();
44811 }
44812 
44813 // -------- func jpeg.decoder.save_mcu_blocks
44814 
44815 WUFFS_BASE__GENERATED_C_CODE
44816 static wuffs_base__empty_struct
wuffs_jpeg__decoder__save_mcu_blocks(wuffs_jpeg__decoder * self,uint32_t a_mx,uint32_t a_my,wuffs_base__slice_u8 a_workbuf)44817 wuffs_jpeg__decoder__save_mcu_blocks(
44818     wuffs_jpeg__decoder* self,
44819     uint32_t a_mx,
44820     uint32_t a_my,
44821     wuffs_base__slice_u8 a_workbuf) {
44822   uint32_t v_b = 0;
44823   uint8_t v_csel = 0;
44824   uint64_t v_h = 0;
44825   uint64_t v_v = 0;
44826   uint64_t v_stride16 = 0;
44827   uint64_t v_offset = 0;
44828 
44829   v_h = 1u;
44830   v_v = 1u;
44831   v_b = 0u;
44832   while (v_b < self->private_impl.f_mcu_num_blocks) {
44833     v_csel = self->private_impl.f_scan_comps_cselector[self->private_impl.f_mcu_blocks_sselector[v_b]];
44834     if (self->private_impl.f_scan_num_components > 1u) {
44835       v_h = ((uint64_t)(self->private_impl.f_components_h[v_csel]));
44836       v_v = ((uint64_t)(self->private_impl.f_components_v[v_csel]));
44837     }
44838     v_stride16 = ((uint64_t)((self->private_impl.f_components_workbuf_widths[v_csel] * 16u)));
44839     v_offset = (self->private_impl.f_components_workbuf_offsets[(v_csel | 4u)] + (((v_h * ((uint64_t)(a_mx))) + ((uint64_t)(self->private_impl.f_scan_comps_bx_offset[v_b]))) * 128u) + (((v_v * ((uint64_t)(a_my))) + ((uint64_t)(self->private_impl.f_scan_comps_by_offset[v_b]))) * v_stride16));
44840     if (v_offset <= ((uint64_t)(a_workbuf.len))) {
44841       wuffs_base__bulk_save_host_endian(&self->private_data.f_mcu_blocks[v_b], 1u * (size_t)128u, wuffs_base__slice_u8__subslice_i(a_workbuf, v_offset));
44842     }
44843     v_b += 1u;
44844   }
44845   return wuffs_base__make_empty_struct();
44846 }
44847 
44848 // -------- func jpeg.decoder.skip_past_the_next_restart_marker
44849 
44850 WUFFS_BASE__GENERATED_C_CODE
44851 static wuffs_base__status
wuffs_jpeg__decoder__skip_past_the_next_restart_marker(wuffs_jpeg__decoder * self,wuffs_base__io_buffer * a_src)44852 wuffs_jpeg__decoder__skip_past_the_next_restart_marker(
44853     wuffs_jpeg__decoder* self,
44854     wuffs_base__io_buffer* a_src) {
44855   wuffs_base__status status = wuffs_base__make_status(NULL);
44856 
44857   uint8_t v_c = 0;
44858 
44859   const uint8_t* iop_a_src = NULL;
44860   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
44861   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
44862   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
44863   if (a_src && a_src->data.ptr) {
44864     io0_a_src = a_src->data.ptr;
44865     io1_a_src = io0_a_src + a_src->meta.ri;
44866     iop_a_src = io1_a_src;
44867     io2_a_src = io0_a_src + a_src->meta.wi;
44868   }
44869 
44870   uint32_t coro_susp_point = self->private_impl.p_skip_past_the_next_restart_marker[0];
44871   switch (coro_susp_point) {
44872     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
44873 
44874     while (true) {
44875       if (((uint64_t)(io2_a_src - iop_a_src)) < 2u) {
44876         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
44877         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
44878         continue;
44879       } else if (wuffs_base__peek_u8be__no_bounds_check(iop_a_src) < 255u) {
44880         iop_a_src += 1u;
44881         continue;
44882       }
44883       v_c = ((uint8_t)((wuffs_base__peek_u16le__no_bounds_check(iop_a_src) >> 8u)));
44884       if (v_c < 192u) {
44885         iop_a_src += 2u;
44886         continue;
44887       } else if ((v_c < 208u) || (215u < v_c)) {
44888         break;
44889       }
44890       v_c &= 7u;
44891       if ((self->private_impl.f_next_restart_marker == ((v_c + 1u) & 7u)) || (self->private_impl.f_next_restart_marker == ((v_c + 2u) & 7u))) {
44892         break;
44893       } else if ((self->private_impl.f_next_restart_marker == ((v_c + 7u) & 7u)) || (self->private_impl.f_next_restart_marker == ((v_c + 6u) & 7u))) {
44894         iop_a_src += 2u;
44895         continue;
44896       } else {
44897         iop_a_src += 2u;
44898         break;
44899       }
44900     }
44901     self->private_impl.f_next_restart_marker = (((uint8_t)(self->private_impl.f_next_restart_marker + 1u)) & 7u);
44902 
44903     ok:
44904     self->private_impl.p_skip_past_the_next_restart_marker[0] = 0;
44905     goto exit;
44906   }
44907 
44908   goto suspend;
44909   suspend:
44910   self->private_impl.p_skip_past_the_next_restart_marker[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
44911 
44912   goto exit;
44913   exit:
44914   if (a_src && a_src->data.ptr) {
44915     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
44916   }
44917 
44918   return status;
44919 }
44920 
44921 // -------- func jpeg.decoder.apply_progressive_idct
44922 
44923 WUFFS_BASE__GENERATED_C_CODE
44924 static wuffs_base__empty_struct
wuffs_jpeg__decoder__apply_progressive_idct(wuffs_jpeg__decoder * self,wuffs_base__slice_u8 a_workbuf)44925 wuffs_jpeg__decoder__apply_progressive_idct(
44926     wuffs_jpeg__decoder* self,
44927     wuffs_base__slice_u8 a_workbuf) {
44928   uint32_t v_csel = 0;
44929   bool v_block_smoothing_applicable = false;
44930   uint32_t v_scan_width_in_mcus = 0;
44931   uint32_t v_scan_height_in_mcus = 0;
44932   uint32_t v_mcu_blocks_mx_mul_0 = 0;
44933   uint32_t v_mcu_blocks_my_mul_0 = 0;
44934   uint32_t v_my = 0;
44935   uint32_t v_mx = 0;
44936   uint64_t v_stride = 0;
44937   uint64_t v_offset = 0;
44938   uint8_t v_stashed_mcu_blocks_0[128] = {0};
44939 
44940   wuffs_base__bulk_save_host_endian(&self->private_data.f_mcu_blocks[0], 1u * (size_t)128u, wuffs_base__make_slice_u8(v_stashed_mcu_blocks_0, 128));
44941   v_block_smoothing_applicable = true;
44942   v_csel = 0u;
44943   while (v_csel < self->private_impl.f_num_components) {
44944     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])))) {
44945       v_block_smoothing_applicable = false;
44946     }
44947     v_csel += 1u;
44948   }
44949   v_csel = 0u;
44950   while (v_csel < self->private_impl.f_num_components) {
44951     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);
44952     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);
44953     v_mcu_blocks_mx_mul_0 = 8u;
44954     v_mcu_blocks_my_mul_0 = (8u * self->private_impl.f_components_workbuf_widths[v_csel]);
44955     if (v_block_smoothing_applicable && (0u != (self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][1u] |
44956         self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][2u] |
44957         self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][3u] |
44958         self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][4u] |
44959         self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][5u] |
44960         self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][6u] |
44961         self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][8u] |
44962         self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][8u] |
44963         self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][9u]))) {
44964       self->private_impl.choosy_load_mcu_blocks_for_single_component = (
44965           &wuffs_jpeg__decoder__load_mcu_blocks_for_single_component_smooth);
44966       self->private_impl.f_block_smoothing_mx_max_incl = wuffs_base__u32__sat_sub(v_scan_width_in_mcus, 1u);
44967       self->private_impl.f_block_smoothing_my_max_incl = wuffs_base__u32__sat_sub(v_scan_height_in_mcus, 1u);
44968     } else {
44969       self->private_impl.choosy_load_mcu_blocks_for_single_component = (
44970           &wuffs_jpeg__decoder__load_mcu_blocks_for_single_component__choosy_default);
44971     }
44972     v_my = 0u;
44973     while (v_my < v_scan_height_in_mcus) {
44974       v_mx = 0u;
44975       while (v_mx < v_scan_width_in_mcus) {
44976         wuffs_jpeg__decoder__load_mcu_blocks_for_single_component(self,
44977             v_mx,
44978             v_my,
44979             a_workbuf,
44980             v_csel);
44981         v_stride = ((uint64_t)(self->private_impl.f_components_workbuf_widths[v_csel]));
44982         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))));
44983         if (v_offset <= ((uint64_t)(a_workbuf.len))) {
44984           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])));
44985         }
44986         v_mx += 1u;
44987       }
44988       v_my += 1u;
44989     }
44990     v_csel += 1u;
44991   }
44992   wuffs_base__bulk_load_host_endian(&self->private_data.f_mcu_blocks[0], 1u * (size_t)128u, wuffs_base__make_slice_u8(v_stashed_mcu_blocks_0, 128));
44993   return wuffs_base__make_empty_struct();
44994 }
44995 
44996 // -------- func jpeg.decoder.swizzle_gray
44997 
44998 WUFFS_BASE__GENERATED_C_CODE
44999 static wuffs_base__status
wuffs_jpeg__decoder__swizzle_gray(wuffs_jpeg__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__slice_u8 a_workbuf)45000 wuffs_jpeg__decoder__swizzle_gray(
45001     wuffs_jpeg__decoder* self,
45002     wuffs_base__pixel_buffer* a_dst,
45003     wuffs_base__slice_u8 a_workbuf) {
45004   wuffs_base__pixel_format v_dst_pixfmt = {0};
45005   uint32_t v_dst_bits_per_pixel = 0;
45006   uint32_t v_dst_bytes_per_pixel = 0;
45007   uint64_t v_dst_length = 0;
45008   wuffs_base__table_u8 v_tab = {0};
45009   wuffs_base__slice_u8 v_dst = {0};
45010   uint32_t v_y = 0;
45011   uint64_t v_stride = 0;
45012 
45013   v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
45014   v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
45015   if ((v_dst_bits_per_pixel & 7u) != 0u) {
45016     return wuffs_base__make_status(wuffs_base__error__unsupported_option);
45017   }
45018   v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u);
45019   v_dst_length = ((uint64_t)((v_dst_bytes_per_pixel * self->private_impl.f_width)));
45020   v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
45021   v_y = 0u;
45022   while (v_y < self->private_impl.f_height) {
45023     v_dst = wuffs_base__table_u8__row_u32(v_tab, v_y);
45024     if (v_dst_length < ((uint64_t)(v_dst.len))) {
45025       v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_length);
45026     }
45027     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);
45028     v_stride = ((uint64_t)(self->private_impl.f_components_workbuf_widths[0u]));
45029     if (v_stride <= ((uint64_t)(a_workbuf.len))) {
45030       a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, v_stride);
45031     } else {
45032       a_workbuf = wuffs_base__utility__empty_slice_u8();
45033     }
45034     v_y += 1u;
45035   }
45036   return wuffs_base__make_status(NULL);
45037 }
45038 
45039 // -------- func jpeg.decoder.swizzle_colorful
45040 
45041 WUFFS_BASE__GENERATED_C_CODE
45042 static wuffs_base__status
wuffs_jpeg__decoder__swizzle_colorful(wuffs_jpeg__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__slice_u8 a_workbuf)45043 wuffs_jpeg__decoder__swizzle_colorful(
45044     wuffs_jpeg__decoder* self,
45045     wuffs_base__pixel_buffer* a_dst,
45046     wuffs_base__slice_u8 a_workbuf) {
45047   wuffs_base__slice_u8 v_src0 = {0};
45048   wuffs_base__slice_u8 v_src1 = {0};
45049   wuffs_base__slice_u8 v_src2 = {0};
45050   wuffs_base__slice_u8 v_src3 = {0};
45051   wuffs_base__status v_status = wuffs_base__make_status(NULL);
45052 
45053   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)))) {
45054     v_src0 = wuffs_base__slice_u8__subslice_ij(a_workbuf,
45055         self->private_impl.f_components_workbuf_offsets[0u],
45056         self->private_impl.f_components_workbuf_offsets[1u]);
45057   }
45058   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)))) {
45059     v_src1 = wuffs_base__slice_u8__subslice_ij(a_workbuf,
45060         self->private_impl.f_components_workbuf_offsets[1u],
45061         self->private_impl.f_components_workbuf_offsets[2u]);
45062   }
45063   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)))) {
45064     v_src2 = wuffs_base__slice_u8__subslice_ij(a_workbuf,
45065         self->private_impl.f_components_workbuf_offsets[2u],
45066         self->private_impl.f_components_workbuf_offsets[3u]);
45067   }
45068   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)))) {
45069     v_src3 = wuffs_base__slice_u8__subslice_ij(a_workbuf,
45070         self->private_impl.f_components_workbuf_offsets[3u],
45071         self->private_impl.f_components_workbuf_offsets[4u]);
45072   }
45073   v_status = wuffs_base__pixel_swizzler__swizzle_ycck(&self->private_impl.f_swizzler,
45074       a_dst,
45075       wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)),
45076       self->private_impl.f_width,
45077       self->private_impl.f_height,
45078       v_src0,
45079       v_src1,
45080       v_src2,
45081       v_src3,
45082       self->private_impl.f_components_workbuf_widths[0u],
45083       self->private_impl.f_components_workbuf_widths[1u],
45084       self->private_impl.f_components_workbuf_widths[2u],
45085       self->private_impl.f_components_workbuf_widths[3u],
45086       self->private_impl.f_components_workbuf_heights[0u],
45087       self->private_impl.f_components_workbuf_heights[1u],
45088       self->private_impl.f_components_workbuf_heights[2u],
45089       self->private_impl.f_components_workbuf_heights[3u],
45090       self->private_impl.f_components_workbuf_widths[0u],
45091       self->private_impl.f_components_workbuf_widths[1u],
45092       self->private_impl.f_components_workbuf_widths[2u],
45093       self->private_impl.f_components_workbuf_widths[3u],
45094       self->private_impl.f_components_h[0u],
45095       self->private_impl.f_components_h[1u],
45096       self->private_impl.f_components_h[2u],
45097       self->private_impl.f_components_h[3u],
45098       self->private_impl.f_components_v[0u],
45099       self->private_impl.f_components_v[1u],
45100       self->private_impl.f_components_v[2u],
45101       self->private_impl.f_components_v[3u],
45102       self->private_impl.f_is_rgb_or_cmyk,
45103       true,
45104       wuffs_base__make_slice_u8(self->private_data.f_swizzle_ycck_scratch_buffer_2k, 2048));
45105   return wuffs_base__status__ensure_not_a_suspension(v_status);
45106 }
45107 
45108 // -------- func jpeg.decoder.frame_dirty_rect
45109 
45110 WUFFS_BASE__GENERATED_C_CODE
45111 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
wuffs_jpeg__decoder__frame_dirty_rect(const wuffs_jpeg__decoder * self)45112 wuffs_jpeg__decoder__frame_dirty_rect(
45113     const wuffs_jpeg__decoder* self) {
45114   if (!self) {
45115     return wuffs_base__utility__empty_rect_ie_u32();
45116   }
45117   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
45118       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
45119     return wuffs_base__utility__empty_rect_ie_u32();
45120   }
45121 
45122   return wuffs_base__utility__make_rect_ie_u32(
45123       0u,
45124       0u,
45125       self->private_impl.f_width,
45126       self->private_impl.f_height);
45127 }
45128 
45129 // -------- func jpeg.decoder.num_animation_loops
45130 
45131 WUFFS_BASE__GENERATED_C_CODE
45132 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_jpeg__decoder__num_animation_loops(const wuffs_jpeg__decoder * self)45133 wuffs_jpeg__decoder__num_animation_loops(
45134     const wuffs_jpeg__decoder* self) {
45135   if (!self) {
45136     return 0;
45137   }
45138   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
45139       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
45140     return 0;
45141   }
45142 
45143   return 0u;
45144 }
45145 
45146 // -------- func jpeg.decoder.num_decoded_frame_configs
45147 
45148 WUFFS_BASE__GENERATED_C_CODE
45149 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_jpeg__decoder__num_decoded_frame_configs(const wuffs_jpeg__decoder * self)45150 wuffs_jpeg__decoder__num_decoded_frame_configs(
45151     const wuffs_jpeg__decoder* self) {
45152   if (!self) {
45153     return 0;
45154   }
45155   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
45156       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
45157     return 0;
45158   }
45159 
45160   if (self->private_impl.f_call_sequence > 32u) {
45161     return 1u;
45162   }
45163   return 0u;
45164 }
45165 
45166 // -------- func jpeg.decoder.num_decoded_frames
45167 
45168 WUFFS_BASE__GENERATED_C_CODE
45169 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_jpeg__decoder__num_decoded_frames(const wuffs_jpeg__decoder * self)45170 wuffs_jpeg__decoder__num_decoded_frames(
45171     const wuffs_jpeg__decoder* self) {
45172   if (!self) {
45173     return 0;
45174   }
45175   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
45176       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
45177     return 0;
45178   }
45179 
45180   if (self->private_impl.f_call_sequence > 64u) {
45181     return 1u;
45182   }
45183   return 0u;
45184 }
45185 
45186 // -------- func jpeg.decoder.restart_frame
45187 
45188 WUFFS_BASE__GENERATED_C_CODE
45189 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_jpeg__decoder__restart_frame(wuffs_jpeg__decoder * self,uint64_t a_index,uint64_t a_io_position)45190 wuffs_jpeg__decoder__restart_frame(
45191     wuffs_jpeg__decoder* self,
45192     uint64_t a_index,
45193     uint64_t a_io_position) {
45194   if (!self) {
45195     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
45196   }
45197   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
45198     return wuffs_base__make_status(
45199         (self->private_impl.magic == WUFFS_BASE__DISABLED)
45200         ? wuffs_base__error__disabled_by_previous_error
45201         : wuffs_base__error__initialize_not_called);
45202   }
45203 
45204   uint32_t v_i = 0;
45205   uint32_t v_j = 0;
45206 
45207   if (self->private_impl.f_call_sequence < 32u) {
45208     return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
45209   }
45210   if (a_index != 0u) {
45211     return wuffs_base__make_status(wuffs_base__error__bad_argument);
45212   }
45213   self->private_impl.f_call_sequence = 40u;
45214   self->private_impl.f_bitstream_is_closed = false;
45215   self->private_impl.f_frame_config_io_position = a_io_position;
45216   self->private_impl.f_scan_count = 0u;
45217   self->private_impl.f_restart_interval = self->private_impl.f_saved_restart_interval;
45218   v_i = 0u;
45219   while (v_i < 4u) {
45220     self->private_impl.f_seen_dqt[v_i] = self->private_impl.f_saved_seen_dqt[v_i];
45221     v_j = 0u;
45222     while (v_j < 64u) {
45223       self->private_impl.f_quant_tables[v_i][v_j] = self->private_impl.f_saved_quant_tables[v_i][v_j];
45224       v_j += 1u;
45225     }
45226     v_i += 1u;
45227   }
45228   v_i = 0u;
45229   while (v_i < 4u) {
45230     v_j = 0u;
45231     while (v_j < 10u) {
45232       self->private_impl.f_block_smoothing_lowest_scan_al[v_i][v_j] = 16u;
45233       v_j += 1u;
45234     }
45235     v_i += 1u;
45236   }
45237   v_i = 0u;
45238   while (v_i < 8u) {
45239     self->private_impl.f_seen_dht[v_i] = false;
45240     v_i += 1u;
45241   }
45242   return wuffs_base__make_status(NULL);
45243 }
45244 
45245 // -------- func jpeg.decoder.set_report_metadata
45246 
45247 WUFFS_BASE__GENERATED_C_CODE
45248 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_jpeg__decoder__set_report_metadata(wuffs_jpeg__decoder * self,uint32_t a_fourcc,bool a_report)45249 wuffs_jpeg__decoder__set_report_metadata(
45250     wuffs_jpeg__decoder* self,
45251     uint32_t a_fourcc,
45252     bool a_report) {
45253   return wuffs_base__make_empty_struct();
45254 }
45255 
45256 // -------- func jpeg.decoder.tell_me_more
45257 
45258 WUFFS_BASE__GENERATED_C_CODE
45259 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_jpeg__decoder__tell_me_more(wuffs_jpeg__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__more_information * a_minfo,wuffs_base__io_buffer * a_src)45260 wuffs_jpeg__decoder__tell_me_more(
45261     wuffs_jpeg__decoder* self,
45262     wuffs_base__io_buffer* a_dst,
45263     wuffs_base__more_information* a_minfo,
45264     wuffs_base__io_buffer* a_src) {
45265   if (!self) {
45266     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
45267   }
45268   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
45269     return wuffs_base__make_status(
45270         (self->private_impl.magic == WUFFS_BASE__DISABLED)
45271         ? wuffs_base__error__disabled_by_previous_error
45272         : wuffs_base__error__initialize_not_called);
45273   }
45274   if (!a_dst || !a_src) {
45275     self->private_impl.magic = WUFFS_BASE__DISABLED;
45276     return wuffs_base__make_status(wuffs_base__error__bad_argument);
45277   }
45278   if ((self->private_impl.active_coroutine != 0) &&
45279       (self->private_impl.active_coroutine != 4)) {
45280     self->private_impl.magic = WUFFS_BASE__DISABLED;
45281     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
45282   }
45283   self->private_impl.active_coroutine = 0;
45284   wuffs_base__status status = wuffs_base__make_status(NULL);
45285 
45286   status = wuffs_base__make_status(wuffs_base__error__no_more_information);
45287   goto exit;
45288 
45289   goto ok;
45290   ok:
45291   goto exit;
45292   exit:
45293   if (wuffs_base__status__is_error(&status)) {
45294     self->private_impl.magic = WUFFS_BASE__DISABLED;
45295   }
45296   return status;
45297 }
45298 
45299 // -------- func jpeg.decoder.history_retain_length
45300 
45301 WUFFS_BASE__GENERATED_C_CODE
45302 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_jpeg__decoder__history_retain_length(const wuffs_jpeg__decoder * self)45303 wuffs_jpeg__decoder__history_retain_length(
45304     const wuffs_jpeg__decoder* self) {
45305   if (!self) {
45306     return 0;
45307   }
45308   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
45309       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
45310     return 0;
45311   }
45312 
45313   return 0u;
45314 }
45315 
45316 // -------- func jpeg.decoder.workbuf_len
45317 
45318 WUFFS_BASE__GENERATED_C_CODE
45319 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_jpeg__decoder__workbuf_len(const wuffs_jpeg__decoder * self)45320 wuffs_jpeg__decoder__workbuf_len(
45321     const wuffs_jpeg__decoder* self) {
45322   if (!self) {
45323     return wuffs_base__utility__empty_range_ii_u64();
45324   }
45325   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
45326       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
45327     return wuffs_base__utility__empty_range_ii_u64();
45328   }
45329 
45330   return wuffs_base__utility__make_range_ii_u64(self->private_impl.f_components_workbuf_offsets[8u], self->private_impl.f_components_workbuf_offsets[8u]);
45331 }
45332 
45333 // -------- func jpeg.decoder.top_left_quants_has_zero
45334 
45335 WUFFS_BASE__GENERATED_C_CODE
45336 static bool
wuffs_jpeg__decoder__top_left_quants_has_zero(const wuffs_jpeg__decoder * self,uint32_t a_q)45337 wuffs_jpeg__decoder__top_left_quants_has_zero(
45338     const wuffs_jpeg__decoder* self,
45339     uint32_t a_q) {
45340   return ((self->private_impl.f_quant_tables[a_q][0u] == 0u) ||
45341       (self->private_impl.f_quant_tables[a_q][1u] == 0u) ||
45342       (self->private_impl.f_quant_tables[a_q][2u] == 0u) ||
45343       (self->private_impl.f_quant_tables[a_q][3u] == 0u) ||
45344       (self->private_impl.f_quant_tables[a_q][8u] == 0u) ||
45345       (self->private_impl.f_quant_tables[a_q][9u] == 0u) ||
45346       (self->private_impl.f_quant_tables[a_q][10u] == 0u) ||
45347       (self->private_impl.f_quant_tables[a_q][16u] == 0u) ||
45348       (self->private_impl.f_quant_tables[a_q][17u] == 0u) ||
45349       (self->private_impl.f_quant_tables[a_q][24u] == 0u));
45350 }
45351 
45352 // -------- func jpeg.decoder.load_mcu_blocks_for_single_component_smooth
45353 
45354 WUFFS_BASE__GENERATED_C_CODE
45355 static wuffs_base__empty_struct
wuffs_jpeg__decoder__load_mcu_blocks_for_single_component_smooth(wuffs_jpeg__decoder * self,uint32_t a_mx,uint32_t a_my,wuffs_base__slice_u8 a_workbuf,uint32_t a_csel)45356 wuffs_jpeg__decoder__load_mcu_blocks_for_single_component_smooth(
45357     wuffs_jpeg__decoder* self,
45358     uint32_t a_mx,
45359     uint32_t a_my,
45360     wuffs_base__slice_u8 a_workbuf,
45361     uint32_t a_csel) {
45362   uint64_t v_stride16 = 0;
45363   uint64_t v_offset = 0;
45364   uint32_t v_dx = 0;
45365   uint32_t v_dy = 0;
45366   uint32_t v_mx = 0;
45367   uint32_t v_my = 0;
45368   uint8_t v_q = 0;
45369   uint32_t v_q_00 = 0;
45370   uint32_t v_q_xy = 0;
45371   uint8_t v_al = 0;
45372   uint32_t v_scratch = 0;
45373   uint32_t v_limit = 0;
45374 
45375   v_stride16 = ((uint64_t)((self->private_impl.f_components_workbuf_widths[a_csel] * 16u)));
45376   v_offset = (self->private_impl.f_components_workbuf_offsets[(a_csel | 4u)] + (((uint64_t)(a_mx)) * 128u) + (((uint64_t)(a_my)) * v_stride16));
45377   if (v_offset <= ((uint64_t)(a_workbuf.len))) {
45378     wuffs_base__bulk_load_host_endian(&self->private_data.f_mcu_blocks[0], 1u * (size_t)128u, wuffs_base__slice_u8__subslice_i(a_workbuf, v_offset));
45379   }
45380   v_dy = 0u;
45381   while (v_dy < 5u) {
45382     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));
45383     v_dx = 0u;
45384     while (v_dx < 5u) {
45385       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));
45386       v_offset = (self->private_impl.f_components_workbuf_offsets[(a_csel | 4u)] + (((uint64_t)(v_mx)) * 128u) + (((uint64_t)(v_my)) * v_stride16));
45387       if (v_offset <= ((uint64_t)(a_workbuf.len))) {
45388         wuffs_base__bulk_load_host_endian(&self->private_impl.f_block_smoothing_dc_values[v_dy][v_dx], 1u * (size_t)2u, wuffs_base__slice_u8__subslice_i(a_workbuf, v_offset));
45389       }
45390       v_dx += 1u;
45391     }
45392     v_dy += 1u;
45393   }
45394   v_q = self->private_impl.f_components_tq[a_csel];
45395   v_q_00 = ((uint32_t)(self->private_impl.f_quant_tables[v_q][0u]));
45396   if (v_q_00 <= 0u) {
45397     return wuffs_base__make_empty_struct();
45398   }
45399   if (0u != (16u &
45400       self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][1u] &
45401       self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][2u] &
45402       self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][3u] &
45403       self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][4u] &
45404       self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][5u] &
45405       self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][6u] &
45406       self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][7u] &
45407       self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][8u] &
45408       self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][9u])) {
45409     v_scratch = 0u;
45410     v_scratch += ((uint32_t)(4294967294u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
45411     v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
45412     v_scratch += ((uint32_t)(4294967288u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
45413     v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
45414     v_scratch += ((uint32_t)(4294967294u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
45415     v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
45416     v_scratch += ((uint32_t)(6u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
45417     v_scratch += ((uint32_t)(42u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
45418     v_scratch += ((uint32_t)(6u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
45419     v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
45420     v_scratch += ((uint32_t)(4294967288u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
45421     v_scratch += ((uint32_t)(42u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
45422     v_scratch += ((uint32_t)(152u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
45423     v_scratch += ((uint32_t)(42u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
45424     v_scratch += ((uint32_t)(4294967288u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
45425     v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
45426     v_scratch += ((uint32_t)(6u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
45427     v_scratch += ((uint32_t)(42u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
45428     v_scratch += ((uint32_t)(6u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
45429     v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
45430     v_scratch += ((uint32_t)(4294967294u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
45431     v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
45432     v_scratch += ((uint32_t)(4294967288u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
45433     v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
45434     v_scratch += ((uint32_t)(4294967294u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
45435     if (v_scratch < 2147483648u) {
45436       v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + 128u)) / 256u)));
45437     } else {
45438       v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + 128u)) / 256u)));
45439     }
45440     self->private_data.f_mcu_blocks[0u][0u] = ((uint16_t)(v_scratch));
45441     v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][1u]));
45442     if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][1u] == 0u)) {
45443       v_scratch = 0u;
45444       v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
45445       v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
45446       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
45447       v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
45448       v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
45449       v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
45450       v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
45451       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
45452       v_scratch += ((uint32_t)(4294967283u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
45453       v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
45454       v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
45455       v_scratch += ((uint32_t)(38u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
45456       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
45457       v_scratch += ((uint32_t)(4294967258u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
45458       v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
45459       v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
45460       v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
45461       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
45462       v_scratch += ((uint32_t)(4294967283u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
45463       v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
45464       v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
45465       v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
45466       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
45467       v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
45468       v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
45469       v_scratch *= v_q_00;
45470       if (v_scratch < 2147483648u) {
45471         v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
45472       } else {
45473         v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
45474       }
45475       self->private_data.f_mcu_blocks[0u][1u] = ((uint16_t)(v_scratch));
45476     }
45477     v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][2u]));
45478     if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][2u] == 0u)) {
45479       v_scratch = 0u;
45480       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
45481       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
45482       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
45483       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
45484       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
45485       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
45486       v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
45487       v_scratch += ((uint32_t)(4294967291u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
45488       v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
45489       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
45490       v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
45491       v_scratch += ((uint32_t)(7u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
45492       v_scratch += ((uint32_t)(4294967282u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
45493       v_scratch += ((uint32_t)(7u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
45494       v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
45495       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
45496       v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
45497       v_scratch += ((uint32_t)(4294967291u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
45498       v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
45499       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
45500       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
45501       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
45502       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
45503       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
45504       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
45505       v_scratch *= v_q_00;
45506       if (v_scratch < 2147483648u) {
45507         v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
45508       } else {
45509         v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
45510       }
45511       self->private_data.f_mcu_blocks[0u][2u] = ((uint16_t)(v_scratch));
45512     }
45513     v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][3u]));
45514     if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][3u] == 0u)) {
45515       v_scratch = 0u;
45516       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
45517       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
45518       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
45519       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
45520       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
45521       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
45522       v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
45523       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
45524       v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
45525       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
45526       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
45527       v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
45528       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
45529       v_scratch += ((uint32_t)(4294967294u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
45530       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
45531       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
45532       v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
45533       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
45534       v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
45535       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
45536       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
45537       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
45538       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
45539       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
45540       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
45541       v_scratch *= v_q_00;
45542       if (v_scratch < 2147483648u) {
45543         v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
45544       } else {
45545         v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
45546       }
45547       self->private_data.f_mcu_blocks[0u][3u] = ((uint16_t)(v_scratch));
45548     }
45549     v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][8u]));
45550     if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][8u] == 0u)) {
45551       v_scratch = 0u;
45552       v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
45553       v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
45554       v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
45555       v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
45556       v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
45557       v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
45558       v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
45559       v_scratch += ((uint32_t)(38u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
45560       v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
45561       v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
45562       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
45563       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
45564       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
45565       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
45566       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
45567       v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
45568       v_scratch += ((uint32_t)(4294967283u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
45569       v_scratch += ((uint32_t)(4294967258u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
45570       v_scratch += ((uint32_t)(4294967283u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
45571       v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
45572       v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
45573       v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
45574       v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
45575       v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
45576       v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
45577       v_scratch *= v_q_00;
45578       if (v_scratch < 2147483648u) {
45579         v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
45580       } else {
45581         v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
45582       }
45583       self->private_data.f_mcu_blocks[0u][8u] = ((uint16_t)(v_scratch));
45584     }
45585     v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][9u]));
45586     if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][9u] == 0u)) {
45587       v_scratch = 0u;
45588       v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
45589       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
45590       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
45591       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
45592       v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
45593       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
45594       v_scratch += ((uint32_t)(9u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
45595       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
45596       v_scratch += ((uint32_t)(4294967287u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
45597       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
45598       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
45599       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
45600       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
45601       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
45602       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
45603       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
45604       v_scratch += ((uint32_t)(4294967287u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
45605       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
45606       v_scratch += ((uint32_t)(9u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
45607       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
45608       v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
45609       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
45610       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
45611       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
45612       v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
45613       v_scratch *= v_q_00;
45614       if (v_scratch < 2147483648u) {
45615         v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
45616       } else {
45617         v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
45618       }
45619       self->private_data.f_mcu_blocks[0u][9u] = ((uint16_t)(v_scratch));
45620     }
45621     v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][10u]));
45622     if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][10u] == 0u)) {
45623       v_scratch = 0u;
45624       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
45625       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
45626       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
45627       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
45628       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
45629       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
45630       v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
45631       v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
45632       v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
45633       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
45634       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
45635       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
45636       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
45637       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
45638       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
45639       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
45640       v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
45641       v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
45642       v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
45643       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
45644       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
45645       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
45646       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
45647       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
45648       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
45649       v_scratch *= v_q_00;
45650       if (v_scratch < 2147483648u) {
45651         v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
45652       } else {
45653         v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
45654       }
45655       self->private_data.f_mcu_blocks[0u][10u] = ((uint16_t)(v_scratch));
45656     }
45657     v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][16u]));
45658     if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][16u] == 0u)) {
45659       v_scratch = 0u;
45660       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
45661       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
45662       v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
45663       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
45664       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
45665       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
45666       v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
45667       v_scratch += ((uint32_t)(7u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
45668       v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
45669       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
45670       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
45671       v_scratch += ((uint32_t)(4294967291u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
45672       v_scratch += ((uint32_t)(4294967282u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
45673       v_scratch += ((uint32_t)(4294967291u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
45674       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
45675       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
45676       v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
45677       v_scratch += ((uint32_t)(7u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
45678       v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
45679       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
45680       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
45681       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
45682       v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
45683       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
45684       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
45685       v_scratch *= v_q_00;
45686       if (v_scratch < 2147483648u) {
45687         v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
45688       } else {
45689         v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
45690       }
45691       self->private_data.f_mcu_blocks[0u][16u] = ((uint16_t)(v_scratch));
45692     }
45693     v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][17u]));
45694     if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][17u] == 0u)) {
45695       v_scratch = 0u;
45696       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
45697       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
45698       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
45699       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
45700       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
45701       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
45702       v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
45703       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
45704       v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
45705       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
45706       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
45707       v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
45708       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
45709       v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
45710       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
45711       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
45712       v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
45713       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
45714       v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
45715       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
45716       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
45717       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
45718       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
45719       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
45720       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
45721       v_scratch *= v_q_00;
45722       if (v_scratch < 2147483648u) {
45723         v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
45724       } else {
45725         v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
45726       }
45727       self->private_data.f_mcu_blocks[0u][17u] = ((uint16_t)(v_scratch));
45728     }
45729     v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][24u]));
45730     if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][24u] == 0u)) {
45731       v_scratch = 0u;
45732       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
45733       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
45734       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
45735       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
45736       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
45737       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
45738       v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
45739       v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
45740       v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
45741       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
45742       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
45743       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
45744       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
45745       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
45746       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
45747       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
45748       v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
45749       v_scratch += ((uint32_t)(4294967294u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
45750       v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
45751       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
45752       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
45753       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
45754       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
45755       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
45756       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
45757       v_scratch *= v_q_00;
45758       if (v_scratch < 2147483648u) {
45759         v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
45760       } else {
45761         v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
45762       }
45763       self->private_data.f_mcu_blocks[0u][24u] = ((uint16_t)(v_scratch));
45764     }
45765   } else {
45766     v_al = self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][1u];
45767     v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][1u]));
45768     if ((v_al > 0u) && (v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][1u] == 0u)) {
45769       v_limit = ((((uint32_t)(1u)) << v_al) - 1u);
45770       v_scratch = 0u;
45771       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
45772       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
45773       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
45774       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
45775       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
45776       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
45777       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
45778       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
45779       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
45780       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
45781       v_scratch += ((uint32_t)(4294967289u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
45782       v_scratch += ((uint32_t)(50u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
45783       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
45784       v_scratch += ((uint32_t)(4294967246u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
45785       v_scratch += ((uint32_t)(7u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
45786       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
45787       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
45788       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
45789       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
45790       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
45791       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
45792       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
45793       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
45794       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
45795       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
45796       v_scratch *= v_q_00;
45797       if (v_scratch < 2147483648u) {
45798         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)))));
45799       } else {
45800         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)))));
45801       }
45802       self->private_data.f_mcu_blocks[0u][1u] = ((uint16_t)(v_scratch));
45803     }
45804     v_al = self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][5u];
45805     v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][2u]));
45806     if ((v_al > 0u) && (v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][2u] == 0u)) {
45807       v_limit = ((((uint32_t)(1u)) << v_al) - 1u);
45808       v_scratch = 0u;
45809       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
45810       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
45811       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
45812       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
45813       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
45814       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
45815       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
45816       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
45817       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
45818       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
45819       v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
45820       v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
45821       v_scratch += ((uint32_t)(4294967272u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
45822       v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
45823       v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
45824       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
45825       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
45826       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
45827       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
45828       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
45829       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
45830       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
45831       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
45832       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
45833       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
45834       v_scratch *= v_q_00;
45835       if (v_scratch < 2147483648u) {
45836         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)))));
45837       } else {
45838         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)))));
45839       }
45840       self->private_data.f_mcu_blocks[0u][2u] = ((uint16_t)(v_scratch));
45841     }
45842     v_al = self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][2u];
45843     v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][8u]));
45844     if ((v_al > 0u) && (v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][8u] == 0u)) {
45845       v_limit = ((((uint32_t)(1u)) << v_al) - 1u);
45846       v_scratch = 0u;
45847       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
45848       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
45849       v_scratch += ((uint32_t)(4294967289u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
45850       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
45851       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
45852       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
45853       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
45854       v_scratch += ((uint32_t)(50u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
45855       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
45856       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
45857       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
45858       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
45859       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
45860       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
45861       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
45862       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
45863       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
45864       v_scratch += ((uint32_t)(4294967246u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
45865       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
45866       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
45867       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
45868       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
45869       v_scratch += ((uint32_t)(7u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
45870       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
45871       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
45872       v_scratch *= v_q_00;
45873       if (v_scratch < 2147483648u) {
45874         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)))));
45875       } else {
45876         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)))));
45877       }
45878       self->private_data.f_mcu_blocks[0u][8u] = ((uint16_t)(v_scratch));
45879     }
45880     v_al = self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][4u];
45881     v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][9u]));
45882     if ((v_al > 0u) && (v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][9u] == 0u)) {
45883       v_limit = ((((uint32_t)(1u)) << v_al) - 1u);
45884       v_scratch = 0u;
45885       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
45886       v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
45887       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
45888       v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
45889       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
45890       v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
45891       v_scratch += ((uint32_t)(10u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
45892       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
45893       v_scratch += ((uint32_t)(4294967286u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
45894       v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
45895       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
45896       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
45897       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
45898       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
45899       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
45900       v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
45901       v_scratch += ((uint32_t)(4294967286u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
45902       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
45903       v_scratch += ((uint32_t)(10u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
45904       v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
45905       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
45906       v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
45907       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
45908       v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
45909       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
45910       v_scratch *= v_q_00;
45911       if (v_scratch < 2147483648u) {
45912         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)))));
45913       } else {
45914         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)))));
45915       }
45916       self->private_data.f_mcu_blocks[0u][9u] = ((uint16_t)(v_scratch));
45917     }
45918     v_al = self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][3u];
45919     v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][16u]));
45920     if ((v_al > 0u) && (v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][16u] == 0u)) {
45921       v_limit = ((((uint32_t)(1u)) << v_al) - 1u);
45922       v_scratch = 0u;
45923       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
45924       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
45925       v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
45926       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
45927       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
45928       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
45929       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
45930       v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
45931       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
45932       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
45933       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
45934       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
45935       v_scratch += ((uint32_t)(4294967272u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
45936       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
45937       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
45938       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
45939       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
45940       v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
45941       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
45942       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
45943       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
45944       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
45945       v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
45946       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
45947       v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
45948       v_scratch *= v_q_00;
45949       if (v_scratch < 2147483648u) {
45950         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)))));
45951       } else {
45952         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)))));
45953       }
45954       self->private_data.f_mcu_blocks[0u][16u] = ((uint16_t)(v_scratch));
45955     }
45956   }
45957   return wuffs_base__make_empty_struct();
45958 }
45959 
45960 // -------- func jpeg.decoder.decode_mcu
45961 
45962 WUFFS_BASE__GENERATED_C_CODE
45963 static uint32_t
wuffs_jpeg__decoder__decode_mcu(wuffs_jpeg__decoder * self,wuffs_base__slice_u8 a_workbuf,uint32_t a_mx,uint32_t a_my)45964 wuffs_jpeg__decoder__decode_mcu(
45965     wuffs_jpeg__decoder* self,
45966     wuffs_base__slice_u8 a_workbuf,
45967     uint32_t a_mx,
45968     uint32_t a_my) {
45969   return (*self->private_impl.choosy_decode_mcu)(self, a_workbuf, a_mx, a_my);
45970 }
45971 
45972 WUFFS_BASE__GENERATED_C_CODE
45973 static uint32_t
wuffs_jpeg__decoder__decode_mcu__choosy_default(wuffs_jpeg__decoder * self,wuffs_base__slice_u8 a_workbuf,uint32_t a_mx,uint32_t a_my)45974 wuffs_jpeg__decoder__decode_mcu__choosy_default(
45975     wuffs_jpeg__decoder* self,
45976     wuffs_base__slice_u8 a_workbuf,
45977     uint32_t a_mx,
45978     uint32_t a_my) {
45979   uint32_t v_ret = 0;
45980   uint64_t v_bits = 0;
45981   uint32_t v_n_bits = 0;
45982   uint8_t v_csel = 0;
45983   wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer();
45984   wuffs_base__io_buffer* v_r = &u_r;
45985   const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
45986   const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
45987   const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
45988   const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
45989   uint32_t v_pos = 0;
45990   uint8_t v_dc_h = 0;
45991   uint32_t v_dc_symbol = 0;
45992   uint32_t v_dc_ht_fast = 0;
45993   uint32_t v_dc_bl = 0;
45994   uint32_t v_dc_code = 0;
45995   uint32_t v_dc_blm1 = 0;
45996   uint32_t v_dc_ht_slow = 0;
45997   uint16_t v_dc_value = 0;
45998   uint16_t v_dc_extend = 0;
45999   const uint16_t* v_ac_huff_table_fast = NULL;
46000   uint8_t v_ac_h = 0;
46001   uint32_t v_ac_symbol = 0;
46002   uint32_t v_ac_ht_fast = 0;
46003   uint32_t v_ac_bl = 0;
46004   uint32_t v_ac_code = 0;
46005   uint32_t v_ac_blm1 = 0;
46006   uint32_t v_ac_ht_slow = 0;
46007   uint16_t v_ac_value = 0;
46008   uint16_t v_ac_extend = 0;
46009   uint32_t v_ac_rrrr = 0;
46010   uint32_t v_ac_ssss = 0;
46011   uint32_t v_z = 0;
46012   uint32_t v_mcb = 0;
46013   uint64_t v_stride = 0;
46014   uint64_t v_offset = 0;
46015 
46016   v_bits = self->private_impl.f_bitstream_bits;
46017   v_n_bits = self->private_impl.f_bitstream_n_bits;
46018   if (self->private_impl.f_bitstream_ri > self->private_impl.f_bitstream_wi) {
46019     return 2u;
46020   }
46021   {
46022     wuffs_base__io_buffer* o_0_v_r = v_r;
46023     const uint8_t *o_0_iop_v_r = iop_v_r;
46024     const uint8_t *o_0_io0_v_r = io0_v_r;
46025     const uint8_t *o_0_io1_v_r = io1_v_r;
46026     const uint8_t *o_0_io2_v_r = io2_v_r;
46027     v_r = wuffs_base__io_reader__set(
46028         &u_r,
46029         &iop_v_r,
46030         &io0_v_r,
46031         &io1_v_r,
46032         &io2_v_r,
46033         wuffs_base__make_slice_u8_ij(self->private_data.f_bitstream_buffer,
46034         self->private_impl.f_bitstream_ri,
46035         self->private_impl.f_bitstream_wi),
46036         ((uint64_t)(self->private_impl.f_bitstream_ri)));
46037     do {
46038       while (self->private_impl.f_mcu_current_block < self->private_impl.f_mcu_num_blocks) {
46039         while (self->private_impl.f_mcu_zig_index <= 0u) {
46040           wuffs_base__bulk_memset(&self->private_data.f_mcu_blocks[0], 1u * (size_t)128u, 0u);
46041           if (((uint64_t)(io2_v_r - iop_v_r)) < 264u) {
46042             v_ret = 1u;
46043             goto label__goto_done__break;
46044           }
46045           v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u));
46046           iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u);
46047           v_n_bits |= 56u;
46048           v_dc_h = self->private_impl.f_mcu_blocks_dc_hselector[self->private_impl.f_mcu_current_block];
46049           v_dc_ht_fast = ((uint32_t)(self->private_impl.f_huff_tables_fast[v_dc_h][(v_bits >> 56u)]));
46050           v_dc_bl = (v_dc_ht_fast >> 8u);
46051           if (v_n_bits >= v_dc_bl) {
46052             v_dc_symbol = (15u & v_dc_ht_fast);
46053             v_dc_extend = WUFFS_JPEG__EXTEND[v_dc_symbol];
46054             v_bits <<= (v_dc_bl & 63u);
46055             v_n_bits -= v_dc_bl;
46056           } else {
46057             v_dc_code = ((uint32_t)((v_bits >> 55u)));
46058             v_dc_blm1 = 8u;
46059             v_bits <<= 9u;
46060             v_n_bits -= 9u;
46061             while (true) {
46062               v_dc_ht_slow = self->private_impl.f_huff_tables_slow[v_dc_h][v_dc_blm1];
46063               if (v_dc_code < (v_dc_ht_slow >> 8u)) {
46064                 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)))])));
46065                 v_dc_extend = WUFFS_JPEG__EXTEND[v_dc_symbol];
46066                 break;
46067               }
46068               v_dc_code = (((uint32_t)(v_dc_code << 1u)) | ((uint32_t)((v_bits >> 63u))));
46069               v_bits <<= 1u;
46070               v_n_bits -= 1u;
46071               v_dc_blm1 = ((v_dc_blm1 + 1u) & 15u);
46072               if (v_dc_blm1 == 0u) {
46073                 v_dc_symbol = 0u;
46074                 v_dc_extend = WUFFS_JPEG__EXTEND[v_dc_symbol];
46075                 break;
46076               }
46077             }
46078           }
46079           v_dc_value = ((uint16_t)(((v_bits >> 32u) >> (32u - v_dc_symbol))));
46080           v_dc_value += (v_dc_extend & (((uint16_t)(wuffs_base__utility__sign_extend_rshift_u64(v_bits, 63u))) ^ 65535u));
46081           v_bits <<= v_dc_symbol;
46082           v_n_bits -= v_dc_symbol;
46083           v_csel = self->private_impl.f_scan_comps_cselector[self->private_impl.f_mcu_blocks_sselector[self->private_impl.f_mcu_current_block]];
46084           self->private_impl.f_mcu_previous_dc_values[v_csel] += v_dc_value;
46085           self->private_data.f_mcu_blocks[0u][0u] = self->private_impl.f_mcu_previous_dc_values[v_csel];
46086           self->private_impl.f_mcu_zig_index = 1u;
46087           break;
46088         }
46089         if (((uint64_t)(io2_v_r - iop_v_r)) < 264u) {
46090           v_ret = 1u;
46091           goto label__goto_done__break;
46092         }
46093         if (v_n_bits < 16u) {
46094           v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u));
46095         }
46096         v_z = 1u;
46097         self->private_impl.f_mcu_zig_index = 0u;
46098         v_ac_h = self->private_impl.f_mcu_blocks_ac_hselector[self->private_impl.f_mcu_current_block];
46099         v_ac_huff_table_fast = &self->private_impl.f_huff_tables_fast[v_ac_h][0u];
46100         while (v_z < 64u) {
46101           v_ac_ht_fast = ((uint32_t)(v_ac_huff_table_fast[(v_bits >> 56u)]));
46102           if (((uint64_t)(io2_v_r - iop_v_r)) < 8u) {
46103             v_ret = 2u;
46104             goto label__goto_done__break;
46105           }
46106           v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u));
46107           iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u);
46108           v_n_bits |= 56u;
46109           v_ac_bl = (v_ac_ht_fast >> 8u);
46110           if (v_n_bits >= v_ac_bl) {
46111             v_ac_symbol = (255u & v_ac_ht_fast);
46112             v_bits <<= (v_ac_bl & 63u);
46113             v_n_bits -= v_ac_bl;
46114           } else {
46115             v_ac_code = ((uint32_t)((v_bits >> 55u)));
46116             v_ac_blm1 = 8u;
46117             v_bits <<= 9u;
46118             v_n_bits -= 9u;
46119             while (true) {
46120               v_ac_ht_slow = self->private_impl.f_huff_tables_slow[v_ac_h][v_ac_blm1];
46121               if (v_ac_code < (v_ac_ht_slow >> 8u)) {
46122                 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)))]));
46123                 break;
46124               }
46125               v_ac_code = (((uint32_t)(v_ac_code << 1u)) | ((uint32_t)((v_bits >> 63u))));
46126               v_bits <<= 1u;
46127               v_n_bits -= 1u;
46128               v_ac_blm1 = ((v_ac_blm1 + 1u) & 15u);
46129               if (v_ac_blm1 == 0u) {
46130                 v_ac_symbol = 0u;
46131                 break;
46132               }
46133             }
46134           }
46135           v_ac_rrrr = (v_ac_symbol >> 4u);
46136           v_z += (v_ac_rrrr + 1u);
46137           v_ac_ssss = (v_ac_symbol & 15u);
46138           v_ac_extend = WUFFS_JPEG__EXTEND[v_ac_ssss];
46139           if (v_ac_ssss > 0u) {
46140             v_ac_value = ((uint16_t)((v_bits >> (64u - v_ac_ssss))));
46141             v_ac_value += (v_ac_extend & (((uint16_t)(wuffs_base__utility__sign_extend_rshift_u64(v_bits, 63u))) ^ 65535u));
46142             v_bits <<= v_ac_ssss;
46143             v_n_bits -= v_ac_ssss;
46144             self->private_data.f_mcu_blocks[0u][WUFFS_JPEG__UNZIG[v_z]] = v_ac_value;
46145           } else if (v_ac_rrrr < 15u) {
46146             break;
46147           }
46148         }
46149         v_mcb = self->private_impl.f_mcu_current_block;
46150         self->private_impl.f_mcu_current_block += 1u;
46151         if (self->private_impl.f_test_only_interrupt_decode_mcu) {
46152           goto label__goto_done__break;
46153         }
46154         v_csel = self->private_impl.f_scan_comps_cselector[self->private_impl.f_mcu_blocks_sselector[v_mcb]];
46155         v_stride = ((uint64_t)(self->private_impl.f_components_workbuf_widths[v_csel]));
46156         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))));
46157         if (v_offset <= ((uint64_t)(a_workbuf.len))) {
46158           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])));
46159         }
46160       }
46161       self->private_impl.f_mcu_current_block = 0u;
46162     } while (0);
46163     label__goto_done__break:;
46164     v_pos = ((uint32_t)(wuffs_base__u64__sat_add((v_r ? v_r->meta.pos : 0), ((uint64_t)(iop_v_r - io0_v_r)))));
46165     if (v_pos > self->private_impl.f_bitstream_wi) {
46166       v_ret = 2u;
46167     } else {
46168       self->private_impl.f_bitstream_ri = v_pos;
46169     }
46170     v_r = o_0_v_r;
46171     iop_v_r = o_0_iop_v_r;
46172     io0_v_r = o_0_io0_v_r;
46173     io1_v_r = o_0_io1_v_r;
46174     io2_v_r = o_0_io2_v_r;
46175   }
46176   self->private_impl.f_bitstream_bits = v_bits;
46177   self->private_impl.f_bitstream_n_bits = v_n_bits;
46178   return v_ret;
46179 }
46180 
46181 // -------- func jpeg.decoder.decode_mcu_progressive_ac_high_bits
46182 
46183 WUFFS_BASE__GENERATED_C_CODE
46184 static uint32_t
wuffs_jpeg__decoder__decode_mcu_progressive_ac_high_bits(wuffs_jpeg__decoder * self,wuffs_base__slice_u8 a_workbuf,uint32_t a_mx,uint32_t a_my)46185 wuffs_jpeg__decoder__decode_mcu_progressive_ac_high_bits(
46186     wuffs_jpeg__decoder* self,
46187     wuffs_base__slice_u8 a_workbuf,
46188     uint32_t a_mx,
46189     uint32_t a_my) {
46190   uint32_t v_ret = 0;
46191   uint64_t v_bits = 0;
46192   uint32_t v_n_bits = 0;
46193   wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer();
46194   wuffs_base__io_buffer* v_r = &u_r;
46195   const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
46196   const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
46197   const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
46198   const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
46199   uint32_t v_pos = 0;
46200   const uint16_t* v_ac_huff_table_fast = NULL;
46201   uint8_t v_ac_h = 0;
46202   uint32_t v_ac_symbol = 0;
46203   uint32_t v_ac_ht_fast = 0;
46204   uint32_t v_ac_bl = 0;
46205   uint32_t v_ac_code = 0;
46206   uint32_t v_ac_blm1 = 0;
46207   uint32_t v_ac_ht_slow = 0;
46208   uint16_t v_ac_value = 0;
46209   uint16_t v_ac_extend = 0;
46210   uint32_t v_ac_rrrr = 0;
46211   uint32_t v_ac_ssss = 0;
46212   uint32_t v_z = 0;
46213 
46214   if (self->private_impl.f_eob_run > 0u) {
46215 #if defined(__GNUC__)
46216 #pragma GCC diagnostic push
46217 #pragma GCC diagnostic ignored "-Wconversion"
46218 #endif
46219     self->private_impl.f_eob_run -= 1u;
46220 #if defined(__GNUC__)
46221 #pragma GCC diagnostic pop
46222 #endif
46223     return 0u;
46224   }
46225   v_bits = self->private_impl.f_bitstream_bits;
46226   v_n_bits = self->private_impl.f_bitstream_n_bits;
46227   if (self->private_impl.f_bitstream_ri > self->private_impl.f_bitstream_wi) {
46228     return 2u;
46229   }
46230   {
46231     wuffs_base__io_buffer* o_0_v_r = v_r;
46232     const uint8_t *o_0_iop_v_r = iop_v_r;
46233     const uint8_t *o_0_io0_v_r = io0_v_r;
46234     const uint8_t *o_0_io1_v_r = io1_v_r;
46235     const uint8_t *o_0_io2_v_r = io2_v_r;
46236     v_r = wuffs_base__io_reader__set(
46237         &u_r,
46238         &iop_v_r,
46239         &io0_v_r,
46240         &io1_v_r,
46241         &io2_v_r,
46242         wuffs_base__make_slice_u8_ij(self->private_data.f_bitstream_buffer,
46243         self->private_impl.f_bitstream_ri,
46244         self->private_impl.f_bitstream_wi),
46245         ((uint64_t)(self->private_impl.f_bitstream_ri)));
46246     do {
46247       do {
46248         if (((uint64_t)(io2_v_r - iop_v_r)) < 264u) {
46249           v_ret = 1u;
46250           goto label__goto_done__break;
46251         }
46252         if (v_n_bits < 16u) {
46253           v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u));
46254         }
46255         v_z = self->private_impl.f_mcu_zig_index;
46256         self->private_impl.f_mcu_zig_index = 0u;
46257         v_ac_h = self->private_impl.f_mcu_blocks_ac_hselector[0u];
46258         v_ac_huff_table_fast = &self->private_impl.f_huff_tables_fast[v_ac_h][0u];
46259         while (v_z <= ((uint32_t)(self->private_impl.f_scan_se))) {
46260           v_ac_ht_fast = ((uint32_t)(v_ac_huff_table_fast[(v_bits >> 56u)]));
46261           if (((uint64_t)(io2_v_r - iop_v_r)) < 8u) {
46262             v_ret = 2u;
46263             goto label__goto_done__break;
46264           }
46265           v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u));
46266           iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u);
46267           v_n_bits |= 56u;
46268           v_ac_bl = (v_ac_ht_fast >> 8u);
46269           if (v_n_bits >= v_ac_bl) {
46270             v_ac_symbol = (255u & v_ac_ht_fast);
46271             v_bits <<= (v_ac_bl & 63u);
46272             v_n_bits -= v_ac_bl;
46273           } else {
46274             v_ac_code = ((uint32_t)((v_bits >> 55u)));
46275             v_ac_blm1 = 8u;
46276             v_bits <<= 9u;
46277             v_n_bits -= 9u;
46278             while (true) {
46279               v_ac_ht_slow = self->private_impl.f_huff_tables_slow[v_ac_h][v_ac_blm1];
46280               if (v_ac_code < (v_ac_ht_slow >> 8u)) {
46281                 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)))]));
46282                 break;
46283               }
46284               v_ac_code = (((uint32_t)(v_ac_code << 1u)) | ((uint32_t)((v_bits >> 63u))));
46285               v_bits <<= 1u;
46286               v_n_bits -= 1u;
46287               v_ac_blm1 = ((v_ac_blm1 + 1u) & 15u);
46288               if (v_ac_blm1 == 0u) {
46289                 v_ac_symbol = 0u;
46290                 break;
46291               }
46292             }
46293           }
46294           v_ac_rrrr = (v_ac_symbol >> 4u);
46295           v_z += (v_ac_rrrr + 1u);
46296           v_ac_ssss = (v_ac_symbol & 15u);
46297           v_ac_extend = WUFFS_JPEG__EXTEND[v_ac_ssss];
46298           if (v_ac_ssss > 0u) {
46299             v_ac_value = ((uint16_t)((v_bits >> (64u - v_ac_ssss))));
46300             v_ac_value += (v_ac_extend & (((uint16_t)(wuffs_base__utility__sign_extend_rshift_u64(v_bits, 63u))) ^ 65535u));
46301             v_bits <<= v_ac_ssss;
46302             v_n_bits -= v_ac_ssss;
46303             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))));
46304           } else if (v_ac_rrrr < 15u) {
46305             self->private_impl.f_eob_run = ((uint16_t)(((((uint16_t)(1u)) << v_ac_rrrr) - 1u)));
46306             if (v_ac_rrrr > 0u) {
46307               self->private_impl.f_eob_run += ((uint16_t)((v_bits >> (64u - v_ac_rrrr))));
46308               v_bits <<= v_ac_rrrr;
46309               v_n_bits -= v_ac_rrrr;
46310             }
46311             break;
46312           }
46313         }
46314       } while (0);
46315     } while (0);
46316     label__goto_done__break:;
46317     v_pos = ((uint32_t)(wuffs_base__u64__sat_add((v_r ? v_r->meta.pos : 0), ((uint64_t)(iop_v_r - io0_v_r)))));
46318     if (v_pos > self->private_impl.f_bitstream_wi) {
46319       v_ret = 2u;
46320     } else {
46321       self->private_impl.f_bitstream_ri = v_pos;
46322     }
46323     v_r = o_0_v_r;
46324     iop_v_r = o_0_iop_v_r;
46325     io0_v_r = o_0_io0_v_r;
46326     io1_v_r = o_0_io1_v_r;
46327     io2_v_r = o_0_io2_v_r;
46328   }
46329   self->private_impl.f_bitstream_bits = v_bits;
46330   self->private_impl.f_bitstream_n_bits = v_n_bits;
46331   return v_ret;
46332 }
46333 
46334 // -------- func jpeg.decoder.decode_mcu_progressive_ac_low_bit
46335 
46336 WUFFS_BASE__GENERATED_C_CODE
46337 static uint32_t
wuffs_jpeg__decoder__decode_mcu_progressive_ac_low_bit(wuffs_jpeg__decoder * self,wuffs_base__slice_u8 a_workbuf,uint32_t a_mx,uint32_t a_my)46338 wuffs_jpeg__decoder__decode_mcu_progressive_ac_low_bit(
46339     wuffs_jpeg__decoder* self,
46340     wuffs_base__slice_u8 a_workbuf,
46341     uint32_t a_mx,
46342     uint32_t a_my) {
46343   uint32_t v_ret = 0;
46344   uint64_t v_bits = 0;
46345   uint32_t v_n_bits = 0;
46346   uint16_t v_one_lshift_scan_al = 0;
46347   wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer();
46348   wuffs_base__io_buffer* v_r = &u_r;
46349   const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
46350   const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
46351   const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
46352   const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
46353   uint32_t v_pos = 0;
46354   const uint16_t* v_ac_huff_table_fast = NULL;
46355   uint8_t v_ac_h = 0;
46356   uint32_t v_ac_symbol = 0;
46357   uint32_t v_ac_ht_fast = 0;
46358   uint32_t v_ac_bl = 0;
46359   uint32_t v_ac_code = 0;
46360   uint32_t v_ac_blm1 = 0;
46361   uint32_t v_ac_ht_slow = 0;
46362   uint16_t v_ac_value = 0;
46363   uint32_t v_ac_rrrr = 0;
46364   uint32_t v_ac_ssss = 0;
46365   uint8_t v_unzig = 0;
46366   bool v_bit = false;
46367 
46368   v_bits = self->private_impl.f_bitstream_bits;
46369   v_n_bits = self->private_impl.f_bitstream_n_bits;
46370   v_one_lshift_scan_al = (((uint16_t)(1u)) << self->private_impl.f_scan_al);
46371   if (self->private_impl.f_bitstream_ri > self->private_impl.f_bitstream_wi) {
46372     return 2u;
46373   }
46374   {
46375     wuffs_base__io_buffer* o_0_v_r = v_r;
46376     const uint8_t *o_0_iop_v_r = iop_v_r;
46377     const uint8_t *o_0_io0_v_r = io0_v_r;
46378     const uint8_t *o_0_io1_v_r = io1_v_r;
46379     const uint8_t *o_0_io2_v_r = io2_v_r;
46380     v_r = wuffs_base__io_reader__set(
46381         &u_r,
46382         &iop_v_r,
46383         &io0_v_r,
46384         &io1_v_r,
46385         &io2_v_r,
46386         wuffs_base__make_slice_u8_ij(self->private_data.f_bitstream_buffer,
46387         self->private_impl.f_bitstream_ri,
46388         self->private_impl.f_bitstream_wi),
46389         ((uint64_t)(self->private_impl.f_bitstream_ri)));
46390     do {
46391       do {
46392         if (((uint64_t)(io2_v_r - iop_v_r)) < 264u) {
46393           v_ret = 1u;
46394           goto label__goto_done__break;
46395         }
46396         while (true) {
46397           if (self->private_impl.f_eob_run > 0u) {
46398             break;
46399           }
46400           v_ac_h = self->private_impl.f_mcu_blocks_ac_hselector[0u];
46401           v_ac_huff_table_fast = &self->private_impl.f_huff_tables_fast[v_ac_h][0u];
46402           while (true) {
46403             if (((uint64_t)(io2_v_r - iop_v_r)) < 8u) {
46404               v_ret = 2u;
46405               goto label__goto_done__break;
46406             }
46407             v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u));
46408             iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u);
46409             v_n_bits |= 56u;
46410             v_ac_ht_fast = ((uint32_t)(v_ac_huff_table_fast[(v_bits >> 56u)]));
46411             v_ac_bl = (v_ac_ht_fast >> 8u);
46412             if (v_n_bits >= v_ac_bl) {
46413               v_ac_symbol = (255u & v_ac_ht_fast);
46414               v_bits <<= (v_ac_bl & 63u);
46415               v_n_bits -= v_ac_bl;
46416             } else {
46417               v_ac_code = ((uint32_t)((v_bits >> 55u)));
46418               v_ac_blm1 = 8u;
46419               v_bits <<= 9u;
46420               v_n_bits -= 9u;
46421               while (true) {
46422                 v_ac_ht_slow = self->private_impl.f_huff_tables_slow[v_ac_h][v_ac_blm1];
46423                 if (v_ac_code < (v_ac_ht_slow >> 8u)) {
46424                   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)))]));
46425                   break;
46426                 }
46427                 v_ac_code = (((uint32_t)(v_ac_code << 1u)) | ((uint32_t)((v_bits >> 63u))));
46428                 v_bits <<= 1u;
46429                 v_n_bits -= 1u;
46430                 v_ac_blm1 = ((v_ac_blm1 + 1u) & 15u);
46431                 if (v_ac_blm1 == 0u) {
46432                   v_ac_symbol = 0u;
46433                   break;
46434                 }
46435               }
46436             }
46437             v_ac_rrrr = (v_ac_symbol >> 4u);
46438             v_ac_ssss = (v_ac_symbol & 15u);
46439             v_ac_value = 0u;
46440             if (v_ac_ssss > 0u) {
46441               v_ac_value = (((uint16_t)(1u)) << self->private_impl.f_scan_al);
46442               if ((v_bits >> 63u) == 0u) {
46443                 v_ac_value = ((uint16_t)(((uint16_t)(65535u)) << self->private_impl.f_scan_al));
46444               }
46445               v_bits <<= 1u;
46446               v_n_bits -= 1u;
46447             } else if (v_ac_rrrr < 15u) {
46448               self->private_impl.f_eob_run = (((uint16_t)(1u)) << v_ac_rrrr);
46449               if (v_ac_rrrr > 0u) {
46450                 self->private_impl.f_eob_run += ((uint16_t)((v_bits >> (64u - v_ac_rrrr))));
46451                 v_bits <<= v_ac_rrrr;
46452                 v_n_bits -= v_ac_rrrr;
46453               }
46454               goto label__goto_do_eob__break;
46455             }
46456             while (true) {
46457               v_unzig = WUFFS_JPEG__UNZIG[(1u + self->private_impl.f_mcu_zig_index)];
46458               if (self->private_data.f_mcu_blocks[0u][v_unzig] != 0u) {
46459                 if (v_n_bits == 0u) {
46460                   if (((uint64_t)(io2_v_r - iop_v_r)) < 8u) {
46461                     v_ret = 2u;
46462                     goto label__goto_done__break;
46463                   }
46464                   v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u));
46465                   iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u);
46466                   v_n_bits |= 56u;
46467                 }
46468                 v_bit = ((v_bits >> 63u) > 0u);
46469                 v_bits <<= 1u;
46470                 v_n_bits -= 1u;
46471                 if (v_bit) {
46472                   if (self->private_data.f_mcu_blocks[0u][v_unzig] < 32768u) {
46473 #if defined(__GNUC__)
46474 #pragma GCC diagnostic push
46475 #pragma GCC diagnostic ignored "-Wconversion"
46476 #endif
46477                     self->private_data.f_mcu_blocks[0u][v_unzig] += v_one_lshift_scan_al;
46478 #if defined(__GNUC__)
46479 #pragma GCC diagnostic pop
46480 #endif
46481                   } else {
46482 #if defined(__GNUC__)
46483 #pragma GCC diagnostic push
46484 #pragma GCC diagnostic ignored "-Wconversion"
46485 #endif
46486                     self->private_data.f_mcu_blocks[0u][v_unzig] -= v_one_lshift_scan_al;
46487 #if defined(__GNUC__)
46488 #pragma GCC diagnostic pop
46489 #endif
46490                   }
46491                 }
46492               } else if (v_ac_rrrr <= 0u) {
46493                 break;
46494               } else {
46495                 v_ac_rrrr -= 1u;
46496               }
46497               if (self->private_impl.f_mcu_zig_index >= ((uint32_t)(self->private_impl.f_scan_se))) {
46498                 break;
46499               }
46500               self->private_impl.f_mcu_zig_index += 1u;
46501             }
46502             if (v_ac_value != 0u) {
46503               self->private_data.f_mcu_blocks[0u][WUFFS_JPEG__UNZIG[(1u + self->private_impl.f_mcu_zig_index)]] = v_ac_value;
46504             }
46505             if (self->private_impl.f_mcu_zig_index >= ((uint32_t)(self->private_impl.f_scan_se))) {
46506               break;
46507             }
46508             self->private_impl.f_mcu_zig_index += 1u;
46509           }
46510           goto label__block__break;
46511         }
46512         label__goto_do_eob__break:;
46513         if (self->private_impl.f_eob_run <= 0u) {
46514           v_ret = 2u;
46515           goto label__goto_done__break;
46516         }
46517         while (true) {
46518           v_unzig = WUFFS_JPEG__UNZIG[(1u + self->private_impl.f_mcu_zig_index)];
46519           if (self->private_data.f_mcu_blocks[0u][v_unzig] != 0u) {
46520             if (v_n_bits == 0u) {
46521               if (((uint64_t)(io2_v_r - iop_v_r)) < 8u) {
46522                 v_ret = 2u;
46523                 goto label__goto_done__break;
46524               }
46525               v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u));
46526               iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u);
46527               v_n_bits |= 56u;
46528             }
46529             v_bit = ((v_bits >> 63u) > 0u);
46530             v_bits <<= 1u;
46531             v_n_bits -= 1u;
46532             if (v_bit) {
46533               if (self->private_data.f_mcu_blocks[0u][v_unzig] < 32768u) {
46534 #if defined(__GNUC__)
46535 #pragma GCC diagnostic push
46536 #pragma GCC diagnostic ignored "-Wconversion"
46537 #endif
46538                 self->private_data.f_mcu_blocks[0u][v_unzig] += v_one_lshift_scan_al;
46539 #if defined(__GNUC__)
46540 #pragma GCC diagnostic pop
46541 #endif
46542               } else {
46543 #if defined(__GNUC__)
46544 #pragma GCC diagnostic push
46545 #pragma GCC diagnostic ignored "-Wconversion"
46546 #endif
46547                 self->private_data.f_mcu_blocks[0u][v_unzig] -= v_one_lshift_scan_al;
46548 #if defined(__GNUC__)
46549 #pragma GCC diagnostic pop
46550 #endif
46551               }
46552             }
46553           }
46554           if (self->private_impl.f_mcu_zig_index >= ((uint32_t)(self->private_impl.f_scan_se))) {
46555             break;
46556           }
46557           self->private_impl.f_mcu_zig_index += 1u;
46558         }
46559 #if defined(__GNUC__)
46560 #pragma GCC diagnostic push
46561 #pragma GCC diagnostic ignored "-Wconversion"
46562 #endif
46563         self->private_impl.f_eob_run -= 1u;
46564 #if defined(__GNUC__)
46565 #pragma GCC diagnostic pop
46566 #endif
46567       } while (0);
46568       label__block__break:;
46569     } while (0);
46570     label__goto_done__break:;
46571     v_pos = ((uint32_t)(wuffs_base__u64__sat_add((v_r ? v_r->meta.pos : 0), ((uint64_t)(iop_v_r - io0_v_r)))));
46572     if (v_pos > self->private_impl.f_bitstream_wi) {
46573       v_ret = 2u;
46574     } else {
46575       self->private_impl.f_bitstream_ri = v_pos;
46576     }
46577     v_r = o_0_v_r;
46578     iop_v_r = o_0_iop_v_r;
46579     io0_v_r = o_0_io0_v_r;
46580     io1_v_r = o_0_io1_v_r;
46581     io2_v_r = o_0_io2_v_r;
46582   }
46583   self->private_impl.f_bitstream_bits = v_bits;
46584   self->private_impl.f_bitstream_n_bits = v_n_bits;
46585   return v_ret;
46586 }
46587 
46588 // -------- func jpeg.decoder.decode_mcu_progressive_dc_high_bits
46589 
46590 WUFFS_BASE__GENERATED_C_CODE
46591 static uint32_t
wuffs_jpeg__decoder__decode_mcu_progressive_dc_high_bits(wuffs_jpeg__decoder * self,wuffs_base__slice_u8 a_workbuf,uint32_t a_mx,uint32_t a_my)46592 wuffs_jpeg__decoder__decode_mcu_progressive_dc_high_bits(
46593     wuffs_jpeg__decoder* self,
46594     wuffs_base__slice_u8 a_workbuf,
46595     uint32_t a_mx,
46596     uint32_t a_my) {
46597   uint32_t v_ret = 0;
46598   uint64_t v_bits = 0;
46599   uint32_t v_n_bits = 0;
46600   uint8_t v_csel = 0;
46601   wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer();
46602   wuffs_base__io_buffer* v_r = &u_r;
46603   const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
46604   const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
46605   const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
46606   const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
46607   uint32_t v_pos = 0;
46608   uint8_t v_dc_h = 0;
46609   uint32_t v_dc_symbol = 0;
46610   uint32_t v_dc_ht_fast = 0;
46611   uint32_t v_dc_bl = 0;
46612   uint32_t v_dc_code = 0;
46613   uint32_t v_dc_blm1 = 0;
46614   uint32_t v_dc_ht_slow = 0;
46615   uint16_t v_dc_value = 0;
46616   uint16_t v_dc_extend = 0;
46617 
46618   v_bits = self->private_impl.f_bitstream_bits;
46619   v_n_bits = self->private_impl.f_bitstream_n_bits;
46620   if (self->private_impl.f_bitstream_ri > self->private_impl.f_bitstream_wi) {
46621     return 2u;
46622   }
46623   {
46624     wuffs_base__io_buffer* o_0_v_r = v_r;
46625     const uint8_t *o_0_iop_v_r = iop_v_r;
46626     const uint8_t *o_0_io0_v_r = io0_v_r;
46627     const uint8_t *o_0_io1_v_r = io1_v_r;
46628     const uint8_t *o_0_io2_v_r = io2_v_r;
46629     v_r = wuffs_base__io_reader__set(
46630         &u_r,
46631         &iop_v_r,
46632         &io0_v_r,
46633         &io1_v_r,
46634         &io2_v_r,
46635         wuffs_base__make_slice_u8_ij(self->private_data.f_bitstream_buffer,
46636         self->private_impl.f_bitstream_ri,
46637         self->private_impl.f_bitstream_wi),
46638         ((uint64_t)(self->private_impl.f_bitstream_ri)));
46639     do {
46640       while (self->private_impl.f_mcu_current_block < self->private_impl.f_mcu_num_blocks) {
46641         if (((uint64_t)(io2_v_r - iop_v_r)) < 264u) {
46642           v_ret = 1u;
46643           goto label__goto_done__break;
46644         }
46645         do {
46646           if (((uint64_t)(io2_v_r - iop_v_r)) < 8u) {
46647             v_ret = 2u;
46648             goto label__goto_done__break;
46649           }
46650           v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u));
46651           iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u);
46652           v_n_bits |= 56u;
46653           v_dc_h = self->private_impl.f_mcu_blocks_dc_hselector[self->private_impl.f_mcu_current_block];
46654           v_dc_ht_fast = ((uint32_t)(self->private_impl.f_huff_tables_fast[v_dc_h][(v_bits >> 56u)]));
46655           v_dc_bl = (v_dc_ht_fast >> 8u);
46656           if (v_n_bits >= v_dc_bl) {
46657             v_dc_symbol = (15u & v_dc_ht_fast);
46658             v_dc_extend = WUFFS_JPEG__EXTEND[v_dc_symbol];
46659             v_bits <<= (v_dc_bl & 63u);
46660             v_n_bits -= v_dc_bl;
46661           } else {
46662             v_dc_code = ((uint32_t)((v_bits >> 55u)));
46663             v_dc_blm1 = 8u;
46664             v_bits <<= 9u;
46665             v_n_bits -= 9u;
46666             while (true) {
46667               v_dc_ht_slow = self->private_impl.f_huff_tables_slow[v_dc_h][v_dc_blm1];
46668               if (v_dc_code < (v_dc_ht_slow >> 8u)) {
46669                 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)))])));
46670                 v_dc_extend = WUFFS_JPEG__EXTEND[v_dc_symbol];
46671                 break;
46672               }
46673               v_dc_code = (((uint32_t)(v_dc_code << 1u)) | ((uint32_t)((v_bits >> 63u))));
46674               v_bits <<= 1u;
46675               v_n_bits -= 1u;
46676               v_dc_blm1 = ((v_dc_blm1 + 1u) & 15u);
46677               if (v_dc_blm1 == 0u) {
46678                 v_dc_symbol = 0u;
46679                 v_dc_extend = WUFFS_JPEG__EXTEND[v_dc_symbol];
46680                 break;
46681               }
46682             }
46683           }
46684           v_dc_value = ((uint16_t)(((v_bits >> 32u) >> (32u - v_dc_symbol))));
46685           v_dc_value += (v_dc_extend & (((uint16_t)(wuffs_base__utility__sign_extend_rshift_u64(v_bits, 63u))) ^ 65535u));
46686           v_bits <<= v_dc_symbol;
46687           v_n_bits -= v_dc_symbol;
46688           v_csel = self->private_impl.f_scan_comps_cselector[self->private_impl.f_mcu_blocks_sselector[self->private_impl.f_mcu_current_block]];
46689           self->private_impl.f_mcu_previous_dc_values[v_csel] += v_dc_value;
46690           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));
46691         } while (0);
46692         self->private_impl.f_mcu_current_block += 1u;
46693       }
46694       self->private_impl.f_mcu_current_block = 0u;
46695     } while (0);
46696     label__goto_done__break:;
46697     v_pos = ((uint32_t)(wuffs_base__u64__sat_add((v_r ? v_r->meta.pos : 0), ((uint64_t)(iop_v_r - io0_v_r)))));
46698     if (v_pos > self->private_impl.f_bitstream_wi) {
46699       v_ret = 2u;
46700     } else {
46701       self->private_impl.f_bitstream_ri = v_pos;
46702     }
46703     v_r = o_0_v_r;
46704     iop_v_r = o_0_iop_v_r;
46705     io0_v_r = o_0_io0_v_r;
46706     io1_v_r = o_0_io1_v_r;
46707     io2_v_r = o_0_io2_v_r;
46708   }
46709   self->private_impl.f_bitstream_bits = v_bits;
46710   self->private_impl.f_bitstream_n_bits = v_n_bits;
46711   return v_ret;
46712 }
46713 
46714 // -------- func jpeg.decoder.decode_mcu_progressive_dc_low_bit
46715 
46716 WUFFS_BASE__GENERATED_C_CODE
46717 static uint32_t
wuffs_jpeg__decoder__decode_mcu_progressive_dc_low_bit(wuffs_jpeg__decoder * self,wuffs_base__slice_u8 a_workbuf,uint32_t a_mx,uint32_t a_my)46718 wuffs_jpeg__decoder__decode_mcu_progressive_dc_low_bit(
46719     wuffs_jpeg__decoder* self,
46720     wuffs_base__slice_u8 a_workbuf,
46721     uint32_t a_mx,
46722     uint32_t a_my) {
46723   uint32_t v_ret = 0;
46724   uint64_t v_bits = 0;
46725   uint32_t v_n_bits = 0;
46726   uint16_t v_one_lshift_scan_al = 0;
46727   wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer();
46728   wuffs_base__io_buffer* v_r = &u_r;
46729   const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
46730   const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
46731   const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
46732   const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
46733   uint32_t v_pos = 0;
46734 
46735   v_bits = self->private_impl.f_bitstream_bits;
46736   v_n_bits = self->private_impl.f_bitstream_n_bits;
46737   v_one_lshift_scan_al = (((uint16_t)(1u)) << self->private_impl.f_scan_al);
46738   if (self->private_impl.f_bitstream_ri > self->private_impl.f_bitstream_wi) {
46739     return 2u;
46740   }
46741   {
46742     wuffs_base__io_buffer* o_0_v_r = v_r;
46743     const uint8_t *o_0_iop_v_r = iop_v_r;
46744     const uint8_t *o_0_io0_v_r = io0_v_r;
46745     const uint8_t *o_0_io1_v_r = io1_v_r;
46746     const uint8_t *o_0_io2_v_r = io2_v_r;
46747     v_r = wuffs_base__io_reader__set(
46748         &u_r,
46749         &iop_v_r,
46750         &io0_v_r,
46751         &io1_v_r,
46752         &io2_v_r,
46753         wuffs_base__make_slice_u8_ij(self->private_data.f_bitstream_buffer,
46754         self->private_impl.f_bitstream_ri,
46755         self->private_impl.f_bitstream_wi),
46756         ((uint64_t)(self->private_impl.f_bitstream_ri)));
46757     do {
46758       while (self->private_impl.f_mcu_current_block < self->private_impl.f_mcu_num_blocks) {
46759         if (((uint64_t)(io2_v_r - iop_v_r)) < 264u) {
46760           v_ret = 1u;
46761           goto label__goto_done__break;
46762         }
46763         do {
46764           if (((uint64_t)(io2_v_r - iop_v_r)) < 8u) {
46765             v_ret = 2u;
46766             goto label__goto_done__break;
46767           }
46768           v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u));
46769           iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u);
46770           v_n_bits |= 56u;
46771           if ((v_bits >> 63u) != 0u) {
46772             self->private_data.f_mcu_blocks[self->private_impl.f_mcu_current_block][0u] |= v_one_lshift_scan_al;
46773           }
46774           v_bits <<= 1u;
46775           v_n_bits -= 1u;
46776         } while (0);
46777         self->private_impl.f_mcu_current_block += 1u;
46778       }
46779       self->private_impl.f_mcu_current_block = 0u;
46780     } while (0);
46781     label__goto_done__break:;
46782     v_pos = ((uint32_t)(wuffs_base__u64__sat_add((v_r ? v_r->meta.pos : 0), ((uint64_t)(iop_v_r - io0_v_r)))));
46783     if (v_pos > self->private_impl.f_bitstream_wi) {
46784       v_ret = 2u;
46785     } else {
46786       self->private_impl.f_bitstream_ri = v_pos;
46787     }
46788     v_r = o_0_v_r;
46789     iop_v_r = o_0_iop_v_r;
46790     io0_v_r = o_0_io0_v_r;
46791     io1_v_r = o_0_io1_v_r;
46792     io2_v_r = o_0_io2_v_r;
46793   }
46794   self->private_impl.f_bitstream_bits = v_bits;
46795   self->private_impl.f_bitstream_n_bits = v_n_bits;
46796   return v_ret;
46797 }
46798 
46799 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JPEG)
46800 
46801 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JSON)
46802 
46803 // ---------------- Status Codes Implementations
46804 
46805 const char wuffs_json__error__bad_c0_control_code[] = "#json: bad C0 control code";
46806 const char wuffs_json__error__bad_utf_8[] = "#json: bad UTF-8";
46807 const char wuffs_json__error__bad_backslash_escape[] = "#json: bad backslash-escape";
46808 const char wuffs_json__error__bad_input[] = "#json: bad input";
46809 const char wuffs_json__error__bad_new_line_in_a_string[] = "#json: bad new-line in a string";
46810 const char wuffs_json__error__bad_quirk_combination[] = "#json: bad quirk combination";
46811 const char wuffs_json__error__unsupported_number_length[] = "#json: unsupported number length";
46812 const char wuffs_json__error__unsupported_recursion_depth[] = "#json: unsupported recursion depth";
46813 const char wuffs_json__error__internal_error_inconsistent_i_o[] = "#json: internal error: inconsistent I/O";
46814 
46815 // ---------------- Private Consts
46816 
46817 #define WUFFS_JSON__DECODER_NUMBER_LENGTH_MAX_INCL 99
46818 
46819 static const uint8_t
46820 WUFFS_JSON__LUT_BACKSLASHES[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
46821   0, 0, 0, 0, 0, 0, 0, 0,
46822   0, 0, 3, 0, 0, 0, 0, 0,
46823   0, 0, 0, 0, 0, 0, 0, 0,
46824   0, 0, 0, 0, 0, 0, 0, 0,
46825   0, 0, 162, 0, 0, 0, 0, 5,
46826   0, 0, 0, 0, 0, 0, 0, 175,
46827   7, 0, 0, 0, 0, 0, 0, 0,
46828   0, 0, 0, 0, 0, 0, 0, 4,
46829   0, 0, 0, 0, 0, 0, 0, 0,
46830   0, 0, 0, 0, 0, 0, 0, 0,
46831   0, 0, 0, 0, 0, 0, 0, 0,
46832   0, 0, 0, 0, 220, 0, 0, 0,
46833   0, 1, 136, 0, 0, 2, 140, 0,
46834   0, 0, 0, 0, 0, 0, 138, 0,
46835   0, 0, 141, 0, 137, 0, 6, 0,
46836   0, 0, 0, 0, 0, 0, 0, 0,
46837   0, 0, 0, 0, 0, 0, 0, 0,
46838   0, 0, 0, 0, 0, 0, 0, 0,
46839   0, 0, 0, 0, 0, 0, 0, 0,
46840   0, 0, 0, 0, 0, 0, 0, 0,
46841   0, 0, 0, 0, 0, 0, 0, 0,
46842   0, 0, 0, 0, 0, 0, 0, 0,
46843   0, 0, 0, 0, 0, 0, 0, 0,
46844   0, 0, 0, 0, 0, 0, 0, 0,
46845   0, 0, 0, 0, 0, 0, 0, 0,
46846   0, 0, 0, 0, 0, 0, 0, 0,
46847   0, 0, 0, 0, 0, 0, 0, 0,
46848   0, 0, 0, 0, 0, 0, 0, 0,
46849   0, 0, 0, 0, 0, 0, 0, 0,
46850   0, 0, 0, 0, 0, 0, 0, 0,
46851   0, 0, 0, 0, 0, 0, 0, 0,
46852   0, 0, 0, 0, 0, 0, 0, 0,
46853 };
46854 
46855 static const uint8_t
46856 WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_QUIRKS[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
46857   0, 1, 3, 4, 5, 6, 7, 10,
46858 };
46859 
46860 static const uint8_t
46861 WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_CHARS[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
46862   0, 7, 27, 10, 63, 39, 11, 0,
46863 };
46864 
46865 static const uint8_t
46866 WUFFS_JSON__LUT_CHARS[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
46867   128, 129, 130, 131, 132, 133, 134, 135,
46868   136, 137, 138, 139, 140, 141, 142, 143,
46869   144, 145, 146, 147, 148, 149, 150, 151,
46870   152, 153, 154, 155, 156, 157, 158, 159,
46871   0, 0, 1, 0, 0, 0, 0, 0,
46872   0, 0, 0, 0, 0, 0, 0, 0,
46873   0, 0, 0, 0, 0, 0, 0, 0,
46874   0, 0, 0, 0, 0, 0, 0, 0,
46875   0, 0, 0, 0, 0, 0, 0, 0,
46876   0, 0, 0, 0, 0, 0, 0, 0,
46877   0, 0, 0, 0, 0, 0, 0, 0,
46878   0, 0, 0, 0, 2, 0, 0, 0,
46879   0, 0, 0, 0, 0, 0, 0, 0,
46880   0, 0, 0, 0, 0, 0, 0, 0,
46881   0, 0, 0, 0, 0, 0, 0, 0,
46882   0, 0, 0, 0, 0, 0, 0, 0,
46883   16, 16, 16, 16, 16, 16, 16, 16,
46884   16, 16, 16, 16, 16, 16, 16, 16,
46885   16, 16, 16, 16, 16, 16, 16, 16,
46886   16, 16, 16, 16, 16, 16, 16, 16,
46887   16, 16, 16, 16, 16, 16, 16, 16,
46888   16, 16, 16, 16, 16, 16, 16, 16,
46889   16, 16, 16, 16, 16, 16, 16, 16,
46890   16, 16, 16, 16, 16, 16, 16, 16,
46891   32, 32, 3, 3, 3, 3, 3, 3,
46892   3, 3, 3, 3, 3, 3, 3, 3,
46893   3, 3, 3, 3, 3, 3, 3, 3,
46894   3, 3, 3, 3, 3, 3, 3, 3,
46895   4, 4, 4, 4, 4, 4, 4, 4,
46896   4, 4, 4, 4, 4, 4, 4, 4,
46897   5, 5, 5, 5, 5, 32, 32, 32,
46898   32, 32, 32, 32, 32, 32, 32, 32,
46899 };
46900 
46901 #define WUFFS_JSON__CLASS_WHITESPACE 0
46902 
46903 #define WUFFS_JSON__CLASS_STRING 1
46904 
46905 #define WUFFS_JSON__CLASS_COMMA 2
46906 
46907 #define WUFFS_JSON__CLASS_COLON 3
46908 
46909 #define WUFFS_JSON__CLASS_NUMBER 4
46910 
46911 #define WUFFS_JSON__CLASS_OPEN_CURLY_BRACE 5
46912 
46913 #define WUFFS_JSON__CLASS_CLOSE_CURLY_BRACE 6
46914 
46915 #define WUFFS_JSON__CLASS_OPEN_SQUARE_BRACKET 7
46916 
46917 #define WUFFS_JSON__CLASS_CLOSE_SQUARE_BRACKET 8
46918 
46919 #define WUFFS_JSON__CLASS_FALSE 9
46920 
46921 #define WUFFS_JSON__CLASS_TRUE 10
46922 
46923 #define WUFFS_JSON__CLASS_NULL_NAN_INF 11
46924 
46925 #define WUFFS_JSON__CLASS_COMMENT 12
46926 
46927 #define WUFFS_JSON__EXPECT_VALUE 7858
46928 
46929 #define WUFFS_JSON__EXPECT_NON_STRING_VALUE 7856
46930 
46931 #define WUFFS_JSON__EXPECT_STRING 4098
46932 
46933 #define WUFFS_JSON__EXPECT_COMMA 4100
46934 
46935 #define WUFFS_JSON__EXPECT_COLON 4104
46936 
46937 #define WUFFS_JSON__EXPECT_NUMBER 4112
46938 
46939 #define WUFFS_JSON__EXPECT_CLOSE_CURLY_BRACE 4160
46940 
46941 #define WUFFS_JSON__EXPECT_CLOSE_SQUARE_BRACKET 4352
46942 
46943 static const uint8_t
46944 WUFFS_JSON__LUT_CLASSES[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
46945   15, 15, 15, 15, 15, 15, 15, 15,
46946   15, 0, 0, 15, 15, 0, 15, 15,
46947   15, 15, 15, 15, 15, 15, 15, 15,
46948   15, 15, 15, 15, 15, 15, 15, 15,
46949   0, 15, 1, 15, 15, 15, 15, 15,
46950   15, 15, 15, 11, 2, 4, 15, 12,
46951   4, 4, 4, 4, 4, 4, 4, 4,
46952   4, 4, 3, 15, 15, 15, 15, 15,
46953   15, 15, 15, 15, 15, 15, 15, 15,
46954   15, 11, 15, 15, 15, 15, 11, 15,
46955   15, 15, 15, 15, 15, 15, 15, 15,
46956   15, 15, 15, 7, 15, 8, 15, 15,
46957   15, 15, 15, 15, 15, 15, 9, 15,
46958   15, 11, 15, 15, 15, 15, 11, 15,
46959   15, 15, 15, 15, 10, 15, 15, 15,
46960   15, 15, 15, 5, 15, 6, 15, 15,
46961   15, 15, 15, 15, 15, 15, 15, 15,
46962   15, 15, 15, 15, 15, 15, 15, 15,
46963   15, 15, 15, 15, 15, 15, 15, 15,
46964   15, 15, 15, 15, 15, 15, 15, 15,
46965   15, 15, 15, 15, 15, 15, 15, 15,
46966   15, 15, 15, 15, 15, 15, 15, 15,
46967   15, 15, 15, 15, 15, 15, 15, 15,
46968   15, 15, 15, 15, 15, 15, 15, 15,
46969   15, 15, 15, 15, 15, 15, 15, 15,
46970   15, 15, 15, 15, 15, 15, 15, 15,
46971   15, 15, 15, 15, 15, 15, 15, 15,
46972   15, 15, 15, 15, 15, 15, 15, 15,
46973   15, 15, 15, 15, 15, 15, 15, 15,
46974   15, 15, 15, 15, 15, 15, 15, 15,
46975   15, 15, 15, 15, 15, 15, 15, 15,
46976   15, 15, 15, 15, 15, 15, 15, 15,
46977 };
46978 
46979 static const uint8_t
46980 WUFFS_JSON__LUT_DECIMAL_DIGITS[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
46981   0, 0, 0, 0, 0, 0, 0, 0,
46982   0, 0, 0, 0, 0, 0, 0, 0,
46983   0, 0, 0, 0, 0, 0, 0, 0,
46984   0, 0, 0, 0, 0, 0, 0, 0,
46985   0, 0, 0, 0, 0, 0, 0, 0,
46986   0, 0, 0, 0, 0, 0, 0, 0,
46987   128, 129, 130, 131, 132, 133, 134, 135,
46988   136, 137, 0, 0, 0, 0, 0, 0,
46989   0, 0, 0, 0, 0, 0, 0, 0,
46990   0, 0, 0, 0, 0, 0, 0, 0,
46991   0, 0, 0, 0, 0, 0, 0, 0,
46992   0, 0, 0, 0, 0, 0, 0, 0,
46993   0, 0, 0, 0, 0, 0, 0, 0,
46994   0, 0, 0, 0, 0, 0, 0, 0,
46995   0, 0, 0, 0, 0, 0, 0, 0,
46996   0, 0, 0, 0, 0, 0, 0, 0,
46997   0, 0, 0, 0, 0, 0, 0, 0,
46998   0, 0, 0, 0, 0, 0, 0, 0,
46999   0, 0, 0, 0, 0, 0, 0, 0,
47000   0, 0, 0, 0, 0, 0, 0, 0,
47001   0, 0, 0, 0, 0, 0, 0, 0,
47002   0, 0, 0, 0, 0, 0, 0, 0,
47003   0, 0, 0, 0, 0, 0, 0, 0,
47004   0, 0, 0, 0, 0, 0, 0, 0,
47005   0, 0, 0, 0, 0, 0, 0, 0,
47006   0, 0, 0, 0, 0, 0, 0, 0,
47007   0, 0, 0, 0, 0, 0, 0, 0,
47008   0, 0, 0, 0, 0, 0, 0, 0,
47009   0, 0, 0, 0, 0, 0, 0, 0,
47010   0, 0, 0, 0, 0, 0, 0, 0,
47011   0, 0, 0, 0, 0, 0, 0, 0,
47012   0, 0, 0, 0, 0, 0, 0, 0,
47013 };
47014 
47015 static const uint8_t
47016 WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
47017   0, 0, 0, 0, 0, 0, 0, 0,
47018   0, 0, 0, 0, 0, 0, 0, 0,
47019   0, 0, 0, 0, 0, 0, 0, 0,
47020   0, 0, 0, 0, 0, 0, 0, 0,
47021   0, 0, 0, 0, 0, 0, 0, 0,
47022   0, 0, 0, 0, 0, 0, 0, 0,
47023   128, 129, 130, 131, 132, 133, 134, 135,
47024   136, 137, 0, 0, 0, 0, 0, 0,
47025   0, 138, 139, 140, 141, 142, 143, 0,
47026   0, 0, 0, 0, 0, 0, 0, 0,
47027   0, 0, 0, 0, 0, 0, 0, 0,
47028   0, 0, 0, 0, 0, 0, 0, 0,
47029   0, 138, 139, 140, 141, 142, 143, 0,
47030   0, 0, 0, 0, 0, 0, 0, 0,
47031   0, 0, 0, 0, 0, 0, 0, 0,
47032   0, 0, 0, 0, 0, 0, 0, 0,
47033   0, 0, 0, 0, 0, 0, 0, 0,
47034   0, 0, 0, 0, 0, 0, 0, 0,
47035   0, 0, 0, 0, 0, 0, 0, 0,
47036   0, 0, 0, 0, 0, 0, 0, 0,
47037   0, 0, 0, 0, 0, 0, 0, 0,
47038   0, 0, 0, 0, 0, 0, 0, 0,
47039   0, 0, 0, 0, 0, 0, 0, 0,
47040   0, 0, 0, 0, 0, 0, 0, 0,
47041   0, 0, 0, 0, 0, 0, 0, 0,
47042   0, 0, 0, 0, 0, 0, 0, 0,
47043   0, 0, 0, 0, 0, 0, 0, 0,
47044   0, 0, 0, 0, 0, 0, 0, 0,
47045   0, 0, 0, 0, 0, 0, 0, 0,
47046   0, 0, 0, 0, 0, 0, 0, 0,
47047   0, 0, 0, 0, 0, 0, 0, 0,
47048   0, 0, 0, 0, 0, 0, 0, 0,
47049 };
47050 
47051 #define WUFFS_JSON__QUIRKS_BASE 1225364480
47052 
47053 #define WUFFS_JSON__QUIRKS_COUNT 21
47054 
47055 // ---------------- Private Initializer Prototypes
47056 
47057 // ---------------- Private Function Prototypes
47058 
47059 WUFFS_BASE__GENERATED_C_CODE
47060 static uint32_t
47061 wuffs_json__decoder__decode_number(
47062     wuffs_json__decoder* self,
47063     wuffs_base__io_buffer* a_src);
47064 
47065 WUFFS_BASE__GENERATED_C_CODE
47066 static uint32_t
47067 wuffs_json__decoder__decode_digits(
47068     wuffs_json__decoder* self,
47069     wuffs_base__io_buffer* a_src,
47070     uint32_t a_n);
47071 
47072 WUFFS_BASE__GENERATED_C_CODE
47073 static wuffs_base__status
47074 wuffs_json__decoder__decode_leading(
47075     wuffs_json__decoder* self,
47076     wuffs_base__token_buffer* a_dst,
47077     wuffs_base__io_buffer* a_src);
47078 
47079 WUFFS_BASE__GENERATED_C_CODE
47080 static wuffs_base__status
47081 wuffs_json__decoder__decode_comment(
47082     wuffs_json__decoder* self,
47083     wuffs_base__token_buffer* a_dst,
47084     wuffs_base__io_buffer* a_src);
47085 
47086 WUFFS_BASE__GENERATED_C_CODE
47087 static wuffs_base__status
47088 wuffs_json__decoder__decode_inf_nan(
47089     wuffs_json__decoder* self,
47090     wuffs_base__token_buffer* a_dst,
47091     wuffs_base__io_buffer* a_src);
47092 
47093 WUFFS_BASE__GENERATED_C_CODE
47094 static wuffs_base__status
47095 wuffs_json__decoder__decode_trailer(
47096     wuffs_json__decoder* self,
47097     wuffs_base__token_buffer* a_dst,
47098     wuffs_base__io_buffer* a_src);
47099 
47100 // ---------------- VTables
47101 
47102 const wuffs_base__token_decoder__func_ptrs
47103 wuffs_json__decoder__func_ptrs_for__wuffs_base__token_decoder = {
47104   (wuffs_base__status(*)(void*,
47105       wuffs_base__token_buffer*,
47106       wuffs_base__io_buffer*,
47107       wuffs_base__slice_u8))(&wuffs_json__decoder__decode_tokens),
47108   (uint64_t(*)(const void*,
47109       uint32_t))(&wuffs_json__decoder__get_quirk),
47110   (uint64_t(*)(const void*))(&wuffs_json__decoder__history_retain_length),
47111   (wuffs_base__status(*)(void*,
47112       uint32_t,
47113       uint64_t))(&wuffs_json__decoder__set_quirk),
47114   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_json__decoder__workbuf_len),
47115 };
47116 
47117 // ---------------- Initializer Implementations
47118 
47119 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
wuffs_json__decoder__initialize(wuffs_json__decoder * self,size_t sizeof_star_self,uint64_t wuffs_version,uint32_t options)47120 wuffs_json__decoder__initialize(
47121     wuffs_json__decoder* self,
47122     size_t sizeof_star_self,
47123     uint64_t wuffs_version,
47124     uint32_t options){
47125   if (!self) {
47126     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
47127   }
47128   if (sizeof(*self) != sizeof_star_self) {
47129     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
47130   }
47131   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
47132       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
47133     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
47134   }
47135 
47136   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
47137     // The whole point of this if-check is to detect an uninitialized *self.
47138     // We disable the warning on GCC. Clang-5.0 does not have this warning.
47139 #if !defined(__clang__) && defined(__GNUC__)
47140 #pragma GCC diagnostic push
47141 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
47142 #endif
47143     if (self->private_impl.magic != 0) {
47144       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
47145     }
47146 #if !defined(__clang__) && defined(__GNUC__)
47147 #pragma GCC diagnostic pop
47148 #endif
47149   } else {
47150     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
47151       memset(self, 0, sizeof(*self));
47152       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
47153     } else {
47154       memset(&(self->private_impl), 0, sizeof(self->private_impl));
47155     }
47156   }
47157 
47158   self->private_impl.magic = WUFFS_BASE__MAGIC;
47159   self->private_impl.vtable_for__wuffs_base__token_decoder.vtable_name =
47160       wuffs_base__token_decoder__vtable_name;
47161   self->private_impl.vtable_for__wuffs_base__token_decoder.function_pointers =
47162       (const void*)(&wuffs_json__decoder__func_ptrs_for__wuffs_base__token_decoder);
47163   return wuffs_base__make_status(NULL);
47164 }
47165 
47166 wuffs_json__decoder*
wuffs_json__decoder__alloc(void)47167 wuffs_json__decoder__alloc(void) {
47168   wuffs_json__decoder* x =
47169       (wuffs_json__decoder*)(calloc(sizeof(wuffs_json__decoder), 1));
47170   if (!x) {
47171     return NULL;
47172   }
47173   if (wuffs_json__decoder__initialize(
47174       x, sizeof(wuffs_json__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
47175     free(x);
47176     return NULL;
47177   }
47178   return x;
47179 }
47180 
47181 size_t
sizeof__wuffs_json__decoder(void)47182 sizeof__wuffs_json__decoder(void) {
47183   return sizeof(wuffs_json__decoder);
47184 }
47185 
47186 // ---------------- Function Implementations
47187 
47188 // -------- func json.decoder.get_quirk
47189 
47190 WUFFS_BASE__GENERATED_C_CODE
47191 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_json__decoder__get_quirk(const wuffs_json__decoder * self,uint32_t a_key)47192 wuffs_json__decoder__get_quirk(
47193     const wuffs_json__decoder* self,
47194     uint32_t a_key) {
47195   if (!self) {
47196     return 0;
47197   }
47198   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
47199       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
47200     return 0;
47201   }
47202 
47203   uint32_t v_key = 0;
47204 
47205   if (a_key >= 1225364480u) {
47206     v_key = (a_key - 1225364480u);
47207     if (v_key < 21u) {
47208       if (self->private_impl.f_quirks[v_key]) {
47209         return 1u;
47210       }
47211     }
47212   }
47213   return 0u;
47214 }
47215 
47216 // -------- func json.decoder.set_quirk
47217 
47218 WUFFS_BASE__GENERATED_C_CODE
47219 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_json__decoder__set_quirk(wuffs_json__decoder * self,uint32_t a_key,uint64_t a_value)47220 wuffs_json__decoder__set_quirk(
47221     wuffs_json__decoder* self,
47222     uint32_t a_key,
47223     uint64_t a_value) {
47224   if (!self) {
47225     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
47226   }
47227   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
47228     return wuffs_base__make_status(
47229         (self->private_impl.magic == WUFFS_BASE__DISABLED)
47230         ? wuffs_base__error__disabled_by_previous_error
47231         : wuffs_base__error__initialize_not_called);
47232   }
47233 
47234   if (a_key >= 1225364480u) {
47235     a_key -= 1225364480u;
47236     if (a_key < 21u) {
47237       self->private_impl.f_quirks[a_key] = (a_value > 0u);
47238       return wuffs_base__make_status(NULL);
47239     }
47240   }
47241   return wuffs_base__make_status(wuffs_base__error__unsupported_option);
47242 }
47243 
47244 // -------- func json.decoder.history_retain_length
47245 
47246 WUFFS_BASE__GENERATED_C_CODE
47247 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_json__decoder__history_retain_length(const wuffs_json__decoder * self)47248 wuffs_json__decoder__history_retain_length(
47249     const wuffs_json__decoder* self) {
47250   if (!self) {
47251     return 0;
47252   }
47253   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
47254       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
47255     return 0;
47256   }
47257 
47258   return 0u;
47259 }
47260 
47261 // -------- func json.decoder.workbuf_len
47262 
47263 WUFFS_BASE__GENERATED_C_CODE
47264 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_json__decoder__workbuf_len(const wuffs_json__decoder * self)47265 wuffs_json__decoder__workbuf_len(
47266     const wuffs_json__decoder* self) {
47267   if (!self) {
47268     return wuffs_base__utility__empty_range_ii_u64();
47269   }
47270   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
47271       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
47272     return wuffs_base__utility__empty_range_ii_u64();
47273   }
47274 
47275   return wuffs_base__utility__empty_range_ii_u64();
47276 }
47277 
47278 // -------- func json.decoder.decode_tokens
47279 
47280 WUFFS_BASE__GENERATED_C_CODE
47281 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_json__decoder__decode_tokens(wuffs_json__decoder * self,wuffs_base__token_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__slice_u8 a_workbuf)47282 wuffs_json__decoder__decode_tokens(
47283     wuffs_json__decoder* self,
47284     wuffs_base__token_buffer* a_dst,
47285     wuffs_base__io_buffer* a_src,
47286     wuffs_base__slice_u8 a_workbuf) {
47287   if (!self) {
47288     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
47289   }
47290   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
47291     return wuffs_base__make_status(
47292         (self->private_impl.magic == WUFFS_BASE__DISABLED)
47293         ? wuffs_base__error__disabled_by_previous_error
47294         : wuffs_base__error__initialize_not_called);
47295   }
47296   if (!a_dst || !a_src) {
47297     self->private_impl.magic = WUFFS_BASE__DISABLED;
47298     return wuffs_base__make_status(wuffs_base__error__bad_argument);
47299   }
47300   if ((self->private_impl.active_coroutine != 0) &&
47301       (self->private_impl.active_coroutine != 1)) {
47302     self->private_impl.magic = WUFFS_BASE__DISABLED;
47303     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
47304   }
47305   self->private_impl.active_coroutine = 0;
47306   wuffs_base__status status = wuffs_base__make_status(NULL);
47307 
47308   uint32_t v_vminor = 0;
47309   uint32_t v_number_length = 0;
47310   uint32_t v_number_status = 0;
47311   uint32_t v_string_length = 0;
47312   uint32_t v_whitespace_length = 0;
47313   uint32_t v_depth = 0;
47314   uint32_t v_stack_byte = 0;
47315   uint32_t v_stack_bit = 0;
47316   uint32_t v_match = 0;
47317   uint32_t v_c4 = 0;
47318   uint8_t v_c = 0;
47319   uint8_t v_backslash = 0;
47320   uint8_t v_char = 0;
47321   uint8_t v_class = 0;
47322   uint32_t v_multi_byte_utf8 = 0;
47323   uint8_t v_backslash_x_ok = 0;
47324   uint8_t v_backslash_x_value = 0;
47325   uint32_t v_backslash_x_string = 0;
47326   uint8_t v_uni4_ok = 0;
47327   uint64_t v_uni4_string = 0;
47328   uint32_t v_uni4_value = 0;
47329   uint32_t v_uni4_high_surrogate = 0;
47330   uint8_t v_uni8_ok = 0;
47331   uint64_t v_uni8_string = 0;
47332   uint32_t v_uni8_value = 0;
47333   uint32_t v_expect = 0;
47334   uint32_t v_expect_after_value = 0;
47335 
47336   wuffs_base__token* iop_a_dst = NULL;
47337   wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
47338   wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
47339   wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
47340   if (a_dst && a_dst->data.ptr) {
47341     io0_a_dst = a_dst->data.ptr;
47342     io1_a_dst = io0_a_dst + a_dst->meta.wi;
47343     iop_a_dst = io1_a_dst;
47344     io2_a_dst = io0_a_dst + a_dst->data.len;
47345     if (a_dst->meta.closed) {
47346       io2_a_dst = iop_a_dst;
47347     }
47348   }
47349   const uint8_t* iop_a_src = NULL;
47350   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
47351   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
47352   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
47353   if (a_src && a_src->data.ptr) {
47354     io0_a_src = a_src->data.ptr;
47355     io1_a_src = io0_a_src + a_src->meta.ri;
47356     iop_a_src = io1_a_src;
47357     io2_a_src = io0_a_src + a_src->meta.wi;
47358   }
47359 
47360   uint32_t coro_susp_point = self->private_impl.p_decode_tokens[0];
47361   if (coro_susp_point) {
47362     v_depth = self->private_data.s_decode_tokens[0].v_depth;
47363     v_expect = self->private_data.s_decode_tokens[0].v_expect;
47364     v_expect_after_value = self->private_data.s_decode_tokens[0].v_expect_after_value;
47365   }
47366   switch (coro_susp_point) {
47367     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
47368 
47369     if (self->private_impl.f_end_of_data) {
47370       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
47371       goto ok;
47372     }
47373     if (self->private_impl.f_quirks[18u]) {
47374       if (self->private_impl.f_quirks[11u] || self->private_impl.f_quirks[12u] || self->private_impl.f_quirks[17u]) {
47375         status = wuffs_base__make_status(wuffs_json__error__bad_quirk_combination);
47376         goto exit;
47377       }
47378     }
47379     if (self->private_impl.f_quirks[15u] || self->private_impl.f_quirks[16u]) {
47380       if (a_dst) {
47381         a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
47382       }
47383       if (a_src) {
47384         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
47385       }
47386       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
47387       status = wuffs_json__decoder__decode_leading(self, a_dst, a_src);
47388       if (a_dst) {
47389         iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
47390       }
47391       if (a_src) {
47392         iop_a_src = a_src->data.ptr + a_src->meta.ri;
47393       }
47394       if (status.repr) {
47395         goto suspend;
47396       }
47397     }
47398     v_expect = 7858u;
47399     label__outer__continue:;
47400     while (true) {
47401       while (true) {
47402         if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
47403           status = wuffs_base__make_status(wuffs_base__suspension__short_write);
47404           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
47405           goto label__outer__continue;
47406         }
47407         v_whitespace_length = 0u;
47408         v_c = 0u;
47409         v_class = 0u;
47410         while (true) {
47411           if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
47412             if (v_whitespace_length > 0u) {
47413               *iop_a_dst++ = wuffs_base__make_token(
47414                   (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
47415                   (((uint64_t)(v_whitespace_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
47416               v_whitespace_length = 0u;
47417             }
47418             if (a_src && a_src->meta.closed) {
47419               status = wuffs_base__make_status(wuffs_json__error__bad_input);
47420               goto exit;
47421             }
47422             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
47423             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
47424             goto label__outer__continue;
47425           }
47426           v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
47427           v_class = WUFFS_JSON__LUT_CLASSES[v_c];
47428           if (v_class != 0u) {
47429             break;
47430           }
47431           iop_a_src += 1u;
47432           if (v_whitespace_length >= 65534u) {
47433             *iop_a_dst++ = wuffs_base__make_token(
47434                 (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
47435                 (((uint64_t)(65535u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
47436             v_whitespace_length = 0u;
47437             goto label__outer__continue;
47438           }
47439           v_whitespace_length += 1u;
47440         }
47441         if (v_whitespace_length > 0u) {
47442           *iop_a_dst++ = wuffs_base__make_token(
47443               (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
47444               (((uint64_t)(v_whitespace_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
47445           v_whitespace_length = 0u;
47446           if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
47447             goto label__outer__continue;
47448           }
47449         }
47450         if (0u == (v_expect & (((uint32_t)(1u)) << v_class))) {
47451           status = wuffs_base__make_status(wuffs_json__error__bad_input);
47452           goto exit;
47453         }
47454         if (v_class == 1u) {
47455           *iop_a_dst++ = wuffs_base__make_token(
47456               (((uint64_t)(4194579u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
47457               (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
47458               (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
47459           iop_a_src += 1u;
47460           label__string_loop_outer__continue:;
47461           while (true) {
47462             if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
47463               status = wuffs_base__make_status(wuffs_base__suspension__short_write);
47464               WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
47465               continue;
47466             }
47467             v_string_length = 0u;
47468             while (true) {
47469               if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
47470                 if (v_string_length > 0u) {
47471                   *iop_a_dst++ = wuffs_base__make_token(
47472                       (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
47473                       (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
47474                       (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
47475                   v_string_length = 0u;
47476                 }
47477                 if (a_src && a_src->meta.closed) {
47478                   status = wuffs_base__make_status(wuffs_json__error__bad_input);
47479                   goto exit;
47480                 }
47481                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
47482                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
47483                 goto label__string_loop_outer__continue;
47484               }
47485               while (((uint64_t)(io2_a_src - iop_a_src)) > 4u) {
47486                 v_c4 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
47487                 if (0u != (WUFFS_JSON__LUT_CHARS[(255u & (v_c4 >> 0u))] |
47488                     WUFFS_JSON__LUT_CHARS[(255u & (v_c4 >> 8u))] |
47489                     WUFFS_JSON__LUT_CHARS[(255u & (v_c4 >> 16u))] |
47490                     WUFFS_JSON__LUT_CHARS[(255u & (v_c4 >> 24u))])) {
47491                   break;
47492                 }
47493                 iop_a_src += 4u;
47494                 if (v_string_length > 65527u) {
47495                   *iop_a_dst++ = wuffs_base__make_token(
47496                       (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
47497                       (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
47498                       (((uint64_t)((v_string_length + 4u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
47499                   v_string_length = 0u;
47500                   goto label__string_loop_outer__continue;
47501                 }
47502                 v_string_length += 4u;
47503               }
47504               v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
47505               v_char = WUFFS_JSON__LUT_CHARS[v_c];
47506               if (v_char == 0u) {
47507                 iop_a_src += 1u;
47508                 if (v_string_length >= 65531u) {
47509                   *iop_a_dst++ = wuffs_base__make_token(
47510                       (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
47511                       (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
47512                       (((uint64_t)(65532u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
47513                   v_string_length = 0u;
47514                   goto label__string_loop_outer__continue;
47515                 }
47516                 v_string_length += 1u;
47517                 continue;
47518               } else if (v_char == 1u) {
47519                 if (v_string_length != 0u) {
47520                   *iop_a_dst++ = wuffs_base__make_token(
47521                       (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
47522                       (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
47523                       (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
47524                   v_string_length = 0u;
47525                 }
47526                 goto label__string_loop_outer__break;
47527               } else if (v_char == 2u) {
47528                 if (v_string_length > 0u) {
47529                   *iop_a_dst++ = wuffs_base__make_token(
47530                       (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
47531                       (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
47532                       (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
47533                   v_string_length = 0u;
47534                   if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
47535                     goto label__string_loop_outer__continue;
47536                   }
47537                 }
47538                 if (((uint64_t)(io2_a_src - iop_a_src)) < 2u) {
47539                   if (a_src && a_src->meta.closed) {
47540                     status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
47541                     goto exit;
47542                   }
47543                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
47544                   WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
47545                   goto label__string_loop_outer__continue;
47546                 }
47547                 v_c = ((uint8_t)((wuffs_base__peek_u16le__no_bounds_check(iop_a_src) >> 8u)));
47548                 v_backslash = WUFFS_JSON__LUT_BACKSLASHES[v_c];
47549                 if ((v_backslash & 128u) != 0u) {
47550                   iop_a_src += 2u;
47551                   *iop_a_dst++ = wuffs_base__make_token(
47552                       (((uint64_t)((6291456u | ((uint32_t)((v_backslash & 127u)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
47553                       (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
47554                       (((uint64_t)(2u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
47555                   goto label__string_loop_outer__continue;
47556                 } else if (v_backslash != 0u) {
47557                   if (self->private_impl.f_quirks[WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_QUIRKS[(v_backslash & 7u)]]) {
47558                     iop_a_src += 2u;
47559                     *iop_a_dst++ = wuffs_base__make_token(
47560                         (((uint64_t)((6291456u | ((uint32_t)(WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_CHARS[(v_backslash & 7u)]))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
47561                         (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
47562                         (((uint64_t)(2u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
47563                     goto label__string_loop_outer__continue;
47564                   }
47565                 } else if (v_c == 117u) {
47566                   if (((uint64_t)(io2_a_src - iop_a_src)) < 6u) {
47567                     if (a_src && a_src->meta.closed) {
47568                       status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
47569                       goto exit;
47570                     }
47571                     status = wuffs_base__make_status(wuffs_base__suspension__short_read);
47572                     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7);
47573                     goto label__string_loop_outer__continue;
47574                   }
47575                   v_uni4_string = (((uint64_t)(wuffs_base__peek_u48le__no_bounds_check(iop_a_src))) >> 16u);
47576                   v_uni4_value = 0u;
47577                   v_uni4_ok = 128u;
47578                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 0u))];
47579                   v_uni4_ok &= v_c;
47580                   v_uni4_value |= (((uint32_t)((v_c & 15u))) << 12u);
47581                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 8u))];
47582                   v_uni4_ok &= v_c;
47583                   v_uni4_value |= (((uint32_t)((v_c & 15u))) << 8u);
47584                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 16u))];
47585                   v_uni4_ok &= v_c;
47586                   v_uni4_value |= (((uint32_t)((v_c & 15u))) << 4u);
47587                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 24u))];
47588                   v_uni4_ok &= v_c;
47589                   v_uni4_value |= (((uint32_t)((v_c & 15u))) << 0u);
47590                   if (v_uni4_ok == 0u) {
47591                   } else if ((v_uni4_value < 55296u) || (57343u < v_uni4_value)) {
47592                     iop_a_src += 6u;
47593                     *iop_a_dst++ = wuffs_base__make_token(
47594                         (((uint64_t)((6291456u | v_uni4_value))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
47595                         (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
47596                         (((uint64_t)(6u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
47597                     goto label__string_loop_outer__continue;
47598                   } else if (v_uni4_value >= 56320u) {
47599                   } else {
47600                     if (((uint64_t)(io2_a_src - iop_a_src)) < 12u) {
47601                       if (a_src && a_src->meta.closed) {
47602                         if (self->private_impl.f_quirks[20u]) {
47603                           iop_a_src += 6u;
47604                           *iop_a_dst++ = wuffs_base__make_token(
47605                               (((uint64_t)(6356989u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
47606                               (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
47607                               (((uint64_t)(6u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
47608                           goto label__string_loop_outer__continue;
47609                         }
47610                         status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
47611                         goto exit;
47612                       }
47613                       status = wuffs_base__make_status(wuffs_base__suspension__short_read);
47614                       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8);
47615                       goto label__string_loop_outer__continue;
47616                     }
47617                     v_uni4_string = (wuffs_base__peek_u64le__no_bounds_check(iop_a_src + 4u) >> 16u);
47618                     if (((255u & (v_uni4_string >> 0u)) != 92u) || ((255u & (v_uni4_string >> 8u)) != 117u)) {
47619                       v_uni4_high_surrogate = 0u;
47620                       v_uni4_value = 0u;
47621                       v_uni4_ok = 0u;
47622                     } else {
47623                       v_uni4_high_surrogate = (65536u + ((v_uni4_value - 55296u) << 10u));
47624                       v_uni4_value = 0u;
47625                       v_uni4_ok = 128u;
47626                       v_uni4_string >>= 16u;
47627                       v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 0u))];
47628                       v_uni4_ok &= v_c;
47629                       v_uni4_value |= (((uint32_t)((v_c & 15u))) << 12u);
47630                       v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 8u))];
47631                       v_uni4_ok &= v_c;
47632                       v_uni4_value |= (((uint32_t)((v_c & 15u))) << 8u);
47633                       v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 16u))];
47634                       v_uni4_ok &= v_c;
47635                       v_uni4_value |= (((uint32_t)((v_c & 15u))) << 4u);
47636                       v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 24u))];
47637                       v_uni4_ok &= v_c;
47638                       v_uni4_value |= (((uint32_t)((v_c & 15u))) << 0u);
47639                     }
47640                     if ((v_uni4_ok != 0u) && (56320u <= v_uni4_value) && (v_uni4_value <= 57343u)) {
47641                       v_uni4_value -= 56320u;
47642                       iop_a_src += 12u;
47643                       *iop_a_dst++ = wuffs_base__make_token(
47644                           (((uint64_t)((6291456u | v_uni4_high_surrogate | v_uni4_value))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
47645                           (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
47646                           (((uint64_t)(12u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
47647                       goto label__string_loop_outer__continue;
47648                     }
47649                   }
47650                   if (self->private_impl.f_quirks[20u]) {
47651                     if (((uint64_t)(io2_a_src - iop_a_src)) < 6u) {
47652                       status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o);
47653                       goto exit;
47654                     }
47655                     iop_a_src += 6u;
47656                     *iop_a_dst++ = wuffs_base__make_token(
47657                         (((uint64_t)(6356989u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
47658                         (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
47659                         (((uint64_t)(6u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
47660                     goto label__string_loop_outer__continue;
47661                   }
47662                 } else if ((v_c == 85u) && self->private_impl.f_quirks[2u]) {
47663                   if (((uint64_t)(io2_a_src - iop_a_src)) < 10u) {
47664                     if (a_src && a_src->meta.closed) {
47665                       status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
47666                       goto exit;
47667                     }
47668                     status = wuffs_base__make_status(wuffs_base__suspension__short_read);
47669                     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9);
47670                     goto label__string_loop_outer__continue;
47671                   }
47672                   v_uni8_string = wuffs_base__peek_u64le__no_bounds_check(iop_a_src + 2u);
47673                   v_uni8_value = 0u;
47674                   v_uni8_ok = 128u;
47675                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 0u))];
47676                   v_uni8_ok &= v_c;
47677                   v_uni8_value |= (((uint32_t)((v_c & 15u))) << 28u);
47678                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 8u))];
47679                   v_uni8_ok &= v_c;
47680                   v_uni8_value |= (((uint32_t)((v_c & 15u))) << 24u);
47681                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 16u))];
47682                   v_uni8_ok &= v_c;
47683                   v_uni8_value |= (((uint32_t)((v_c & 15u))) << 20u);
47684                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 24u))];
47685                   v_uni8_ok &= v_c;
47686                   v_uni8_value |= (((uint32_t)((v_c & 15u))) << 16u);
47687                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 32u))];
47688                   v_uni8_ok &= v_c;
47689                   v_uni8_value |= (((uint32_t)((v_c & 15u))) << 12u);
47690                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 40u))];
47691                   v_uni8_ok &= v_c;
47692                   v_uni8_value |= (((uint32_t)((v_c & 15u))) << 8u);
47693                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 48u))];
47694                   v_uni8_ok &= v_c;
47695                   v_uni8_value |= (((uint32_t)((v_c & 15u))) << 4u);
47696                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 56u))];
47697                   v_uni8_ok &= v_c;
47698                   v_uni8_value |= (((uint32_t)((v_c & 15u))) << 0u);
47699                   if (v_uni8_ok == 0u) {
47700                   } else if ((v_uni8_value < 55296u) || ((57343u < v_uni8_value) && (v_uni8_value <= 1114111u))) {
47701                     iop_a_src += 10u;
47702                     *iop_a_dst++ = wuffs_base__make_token(
47703                         (((uint64_t)((6291456u | (v_uni8_value & 2097151u)))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
47704                         (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
47705                         (((uint64_t)(10u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
47706                     goto label__string_loop_outer__continue;
47707                   } else if (self->private_impl.f_quirks[20u]) {
47708                     iop_a_src += 10u;
47709                     *iop_a_dst++ = wuffs_base__make_token(
47710                         (((uint64_t)(6356989u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
47711                         (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
47712                         (((uint64_t)(10u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
47713                     goto label__string_loop_outer__continue;
47714                   }
47715                 } else if ((v_c == 120u) && self->private_impl.f_quirks[9u]) {
47716                   if (((uint64_t)(io2_a_src - iop_a_src)) < 4u) {
47717                     if (a_src && a_src->meta.closed) {
47718                       status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
47719                       goto exit;
47720                     }
47721                     status = wuffs_base__make_status(wuffs_base__suspension__short_read);
47722                     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10);
47723                     goto label__string_loop_outer__continue;
47724                   }
47725                   v_backslash_x_string = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
47726                   v_backslash_x_ok = 128u;
47727                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_backslash_x_string >> 16u))];
47728                   v_backslash_x_ok &= v_c;
47729                   v_backslash_x_value = ((uint8_t)(((v_c & 15u) << 4u)));
47730                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_backslash_x_string >> 24u))];
47731                   v_backslash_x_ok &= v_c;
47732                   v_backslash_x_value = ((uint8_t)((v_backslash_x_value | (v_c & 15u))));
47733                   if ((v_backslash_x_ok == 0u) || ((v_backslash_x_string & 65535u) != 30812u)) {
47734                     status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
47735                     goto exit;
47736                   }
47737                   iop_a_src += 4u;
47738                   *iop_a_dst++ = wuffs_base__make_token(
47739                       (((uint64_t)((6291456u | ((uint32_t)(v_backslash_x_value))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
47740                       (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
47741                       (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
47742                   goto label__string_loop_outer__continue;
47743                 }
47744                 status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
47745                 goto exit;
47746               } else if (v_char == 3u) {
47747                 if (((uint64_t)(io2_a_src - iop_a_src)) < 2u) {
47748                   if (v_string_length > 0u) {
47749                     *iop_a_dst++ = wuffs_base__make_token(
47750                         (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
47751                         (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
47752                         (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
47753                     v_string_length = 0u;
47754                     if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
47755                       goto label__string_loop_outer__continue;
47756                     }
47757                   }
47758                   if (a_src && a_src->meta.closed) {
47759                     if (self->private_impl.f_quirks[20u]) {
47760                       *iop_a_dst++ = wuffs_base__make_token(
47761                           (((uint64_t)(6356989u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
47762                           (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
47763                           (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
47764                       iop_a_src += 1u;
47765                       goto label__string_loop_outer__continue;
47766                     }
47767                     status = wuffs_base__make_status(wuffs_json__error__bad_utf_8);
47768                     goto exit;
47769                   }
47770                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
47771                   WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(11);
47772                   goto label__string_loop_outer__continue;
47773                 }
47774                 v_multi_byte_utf8 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
47775                 if ((v_multi_byte_utf8 & 49152u) == 32768u) {
47776                   v_multi_byte_utf8 = ((1984u & ((uint32_t)(v_multi_byte_utf8 << 6u))) | (63u & (v_multi_byte_utf8 >> 8u)));
47777                   iop_a_src += 2u;
47778                   if (v_string_length >= 65528u) {
47779                     *iop_a_dst++ = wuffs_base__make_token(
47780                         (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
47781                         (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
47782                         (((uint64_t)((v_string_length + 2u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
47783                     v_string_length = 0u;
47784                     goto label__string_loop_outer__continue;
47785                   }
47786                   v_string_length += 2u;
47787                   continue;
47788                 }
47789               } else if (v_char == 4u) {
47790                 if (((uint64_t)(io2_a_src - iop_a_src)) < 3u) {
47791                   if (v_string_length > 0u) {
47792                     *iop_a_dst++ = wuffs_base__make_token(
47793                         (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
47794                         (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
47795                         (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
47796                     v_string_length = 0u;
47797                     if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
47798                       goto label__string_loop_outer__continue;
47799                     }
47800                   }
47801                   if (a_src && a_src->meta.closed) {
47802                     if (self->private_impl.f_quirks[20u]) {
47803                       *iop_a_dst++ = wuffs_base__make_token(
47804                           (((uint64_t)(6356989u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
47805                           (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
47806                           (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
47807                       iop_a_src += 1u;
47808                       goto label__string_loop_outer__continue;
47809                     }
47810                     status = wuffs_base__make_status(wuffs_json__error__bad_utf_8);
47811                     goto exit;
47812                   }
47813                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
47814                   WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(12);
47815                   goto label__string_loop_outer__continue;
47816                 }
47817                 v_multi_byte_utf8 = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src)));
47818                 if ((v_multi_byte_utf8 & 12632064u) == 8421376u) {
47819                   v_multi_byte_utf8 = ((61440u & ((uint32_t)(v_multi_byte_utf8 << 12u))) | (4032u & (v_multi_byte_utf8 >> 2u)) | (63u & (v_multi_byte_utf8 >> 16u)));
47820                   if ((2047u < v_multi_byte_utf8) && ((v_multi_byte_utf8 < 55296u) || (57343u < v_multi_byte_utf8))) {
47821                     iop_a_src += 3u;
47822                     if (v_string_length >= 65528u) {
47823                       *iop_a_dst++ = wuffs_base__make_token(
47824                           (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
47825                           (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
47826                           (((uint64_t)((v_string_length + 3u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
47827                       v_string_length = 0u;
47828                       goto label__string_loop_outer__continue;
47829                     }
47830                     v_string_length += 3u;
47831                     continue;
47832                   }
47833                 }
47834               } else if (v_char == 5u) {
47835                 if (((uint64_t)(io2_a_src - iop_a_src)) < 4u) {
47836                   if (v_string_length > 0u) {
47837                     *iop_a_dst++ = wuffs_base__make_token(
47838                         (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
47839                         (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
47840                         (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
47841                     v_string_length = 0u;
47842                     if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
47843                       goto label__string_loop_outer__continue;
47844                     }
47845                   }
47846                   if (a_src && a_src->meta.closed) {
47847                     if (self->private_impl.f_quirks[20u]) {
47848                       *iop_a_dst++ = wuffs_base__make_token(
47849                           (((uint64_t)(6356989u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
47850                           (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
47851                           (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
47852                       iop_a_src += 1u;
47853                       goto label__string_loop_outer__continue;
47854                     }
47855                     status = wuffs_base__make_status(wuffs_json__error__bad_utf_8);
47856                     goto exit;
47857                   }
47858                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
47859                   WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(13);
47860                   goto label__string_loop_outer__continue;
47861                 }
47862                 v_multi_byte_utf8 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
47863                 if ((v_multi_byte_utf8 & 3233857536u) == 2155905024u) {
47864                   v_multi_byte_utf8 = ((1835008u & ((uint32_t)(v_multi_byte_utf8 << 18u))) |
47865                       (258048u & ((uint32_t)(v_multi_byte_utf8 << 4u))) |
47866                       (4032u & (v_multi_byte_utf8 >> 10u)) |
47867                       (63u & (v_multi_byte_utf8 >> 24u)));
47868                   if ((65535u < v_multi_byte_utf8) && (v_multi_byte_utf8 <= 1114111u)) {
47869                     iop_a_src += 4u;
47870                     if (v_string_length >= 65528u) {
47871                       *iop_a_dst++ = wuffs_base__make_token(
47872                           (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
47873                           (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
47874                           (((uint64_t)((v_string_length + 4u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
47875                       v_string_length = 0u;
47876                       goto label__string_loop_outer__continue;
47877                     }
47878                     v_string_length += 4u;
47879                     continue;
47880                   }
47881                 }
47882               }
47883               if (v_string_length > 0u) {
47884                 *iop_a_dst++ = wuffs_base__make_token(
47885                     (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
47886                     (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
47887                     (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
47888                 v_string_length = 0u;
47889                 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
47890                   goto label__string_loop_outer__continue;
47891                 }
47892               }
47893               if ((v_char & 128u) != 0u) {
47894                 if (self->private_impl.f_quirks[0u]) {
47895                   *iop_a_dst++ = wuffs_base__make_token(
47896                       (((uint64_t)((6291456u | ((uint32_t)((v_char & 127u)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
47897                       (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
47898                       (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
47899                   iop_a_src += 1u;
47900                   goto label__string_loop_outer__continue;
47901                 }
47902                 if (v_char == 138u) {
47903                   status = wuffs_base__make_status(wuffs_json__error__bad_new_line_in_a_string);
47904                   goto exit;
47905                 }
47906                 status = wuffs_base__make_status(wuffs_json__error__bad_c0_control_code);
47907                 goto exit;
47908               }
47909               if (self->private_impl.f_quirks[20u]) {
47910                 *iop_a_dst++ = wuffs_base__make_token(
47911                     (((uint64_t)(6356989u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
47912                     (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
47913                     (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
47914                 iop_a_src += 1u;
47915                 goto label__string_loop_outer__continue;
47916               }
47917               status = wuffs_base__make_status(wuffs_json__error__bad_utf_8);
47918               goto exit;
47919             }
47920           }
47921           label__string_loop_outer__break:;
47922           while (true) {
47923             if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
47924               if (a_src && a_src->meta.closed) {
47925                 status = wuffs_base__make_status(wuffs_json__error__bad_input);
47926                 goto exit;
47927               }
47928               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
47929               WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(14);
47930               continue;
47931             }
47932             if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
47933               status = wuffs_base__make_status(wuffs_base__suspension__short_write);
47934               WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(15);
47935               continue;
47936             }
47937             iop_a_src += 1u;
47938             *iop_a_dst++ = wuffs_base__make_token(
47939                 (((uint64_t)(4194579u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
47940                 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
47941             break;
47942           }
47943           if (0u == (v_expect & (((uint32_t)(1u)) << 4u))) {
47944             v_expect = 4104u;
47945             goto label__outer__continue;
47946           }
47947           break;
47948         } else if (v_class == 2u) {
47949           iop_a_src += 1u;
47950           *iop_a_dst++ = wuffs_base__make_token(
47951               (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
47952               (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
47953           if (0u == (v_expect & (((uint32_t)(1u)) << 8u))) {
47954             if (self->private_impl.f_quirks[13u]) {
47955               v_expect = 4162u;
47956             } else {
47957               v_expect = 4098u;
47958             }
47959           } else {
47960             if (self->private_impl.f_quirks[13u]) {
47961               v_expect = 8114u;
47962             } else {
47963               v_expect = 7858u;
47964             }
47965           }
47966           goto label__outer__continue;
47967         } else if (v_class == 3u) {
47968           iop_a_src += 1u;
47969           *iop_a_dst++ = wuffs_base__make_token(
47970               (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
47971               (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
47972           v_expect = 7858u;
47973           goto label__outer__continue;
47974         } else if (v_class == 4u) {
47975           while (true) {
47976             if (a_src) {
47977               a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
47978             }
47979             v_number_length = wuffs_json__decoder__decode_number(self, a_src);
47980             if (a_src) {
47981               iop_a_src = a_src->data.ptr + a_src->meta.ri;
47982             }
47983             v_number_status = (v_number_length >> 8u);
47984             v_vminor = 10486787u;
47985             if ((v_number_length & 128u) != 0u) {
47986               v_vminor = 10486785u;
47987             }
47988             v_number_length = (v_number_length & 127u);
47989             if (v_number_status == 0u) {
47990               *iop_a_dst++ = wuffs_base__make_token(
47991                   (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
47992                   (((uint64_t)(v_number_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
47993               break;
47994             }
47995             while (v_number_length > 0u) {
47996               v_number_length -= 1u;
47997               if (iop_a_src > io1_a_src) {
47998                 iop_a_src--;
47999               } else {
48000                 status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o);
48001                 goto exit;
48002               }
48003             }
48004             if (v_number_status == 1u) {
48005               if (self->private_impl.f_quirks[14u]) {
48006                 if (a_dst) {
48007                   a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
48008                 }
48009                 if (a_src) {
48010                   a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
48011                 }
48012                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
48013                 status = wuffs_json__decoder__decode_inf_nan(self, a_dst, a_src);
48014                 if (a_dst) {
48015                   iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
48016                 }
48017                 if (a_src) {
48018                   iop_a_src = a_src->data.ptr + a_src->meta.ri;
48019                 }
48020                 if (status.repr) {
48021                   goto suspend;
48022                 }
48023                 break;
48024               }
48025               status = wuffs_base__make_status(wuffs_json__error__bad_input);
48026               goto exit;
48027             } else if (v_number_status == 2u) {
48028               status = wuffs_base__make_status(wuffs_json__error__unsupported_number_length);
48029               goto exit;
48030             } else {
48031               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
48032               WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(17);
48033               while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
48034                 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
48035                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(18);
48036               }
48037             }
48038           }
48039           break;
48040         } else if (v_class == 5u) {
48041           v_vminor = 2113553u;
48042           if (v_depth == 0u) {
48043           } else if (0u != (v_expect_after_value & (((uint32_t)(1u)) << 6u))) {
48044             v_vminor = 2113601u;
48045           } else {
48046             v_vminor = 2113569u;
48047           }
48048           if (v_depth >= 1024u) {
48049             status = wuffs_base__make_status(wuffs_json__error__unsupported_recursion_depth);
48050             goto exit;
48051           }
48052           v_stack_byte = (v_depth / 32u);
48053           v_stack_bit = (v_depth & 31u);
48054           self->private_data.f_stack[v_stack_byte] |= (((uint32_t)(1u)) << v_stack_bit);
48055           v_depth += 1u;
48056           iop_a_src += 1u;
48057           *iop_a_dst++ = wuffs_base__make_token(
48058               (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
48059               (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
48060           v_expect = 4162u;
48061           v_expect_after_value = 4164u;
48062           goto label__outer__continue;
48063         } else if (v_class == 6u) {
48064           iop_a_src += 1u;
48065           if (v_depth <= 1u) {
48066             *iop_a_dst++ = wuffs_base__make_token(
48067                 (((uint64_t)(2101314u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
48068                 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
48069             goto label__outer__break;
48070           }
48071           v_depth -= 1u;
48072           v_stack_byte = ((v_depth - 1u) / 32u);
48073           v_stack_bit = ((v_depth - 1u) & 31u);
48074           if (0u == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1u)) << v_stack_bit))) {
48075             *iop_a_dst++ = wuffs_base__make_token(
48076                 (((uint64_t)(2105410u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
48077                 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
48078             v_expect = 4356u;
48079             v_expect_after_value = 4356u;
48080           } else {
48081             *iop_a_dst++ = wuffs_base__make_token(
48082                 (((uint64_t)(2113602u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
48083                 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
48084             v_expect = 4164u;
48085             v_expect_after_value = 4164u;
48086           }
48087           goto label__outer__continue;
48088         } else if (v_class == 7u) {
48089           v_vminor = 2105361u;
48090           if (v_depth == 0u) {
48091           } else if (0u != (v_expect_after_value & (((uint32_t)(1u)) << 6u))) {
48092             v_vminor = 2105409u;
48093           } else {
48094             v_vminor = 2105377u;
48095           }
48096           if (v_depth >= 1024u) {
48097             status = wuffs_base__make_status(wuffs_json__error__unsupported_recursion_depth);
48098             goto exit;
48099           }
48100           v_stack_byte = (v_depth / 32u);
48101           v_stack_bit = (v_depth & 31u);
48102           self->private_data.f_stack[v_stack_byte] &= (4294967295u ^ (((uint32_t)(1u)) << v_stack_bit));
48103           v_depth += 1u;
48104           iop_a_src += 1u;
48105           *iop_a_dst++ = wuffs_base__make_token(
48106               (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
48107               (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
48108           v_expect = 8114u;
48109           v_expect_after_value = 4356u;
48110           goto label__outer__continue;
48111         } else if (v_class == 8u) {
48112           iop_a_src += 1u;
48113           if (v_depth <= 1u) {
48114             *iop_a_dst++ = wuffs_base__make_token(
48115                 (((uint64_t)(2101282u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
48116                 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
48117             goto label__outer__break;
48118           }
48119           v_depth -= 1u;
48120           v_stack_byte = ((v_depth - 1u) / 32u);
48121           v_stack_bit = ((v_depth - 1u) & 31u);
48122           if (0u == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1u)) << v_stack_bit))) {
48123             *iop_a_dst++ = wuffs_base__make_token(
48124                 (((uint64_t)(2105378u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
48125                 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
48126             v_expect = 4356u;
48127             v_expect_after_value = 4356u;
48128           } else {
48129             *iop_a_dst++ = wuffs_base__make_token(
48130                 (((uint64_t)(2113570u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
48131                 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
48132             v_expect = 4164u;
48133             v_expect_after_value = 4164u;
48134           }
48135           goto label__outer__continue;
48136         } else if (v_class == 9u) {
48137           v_match = wuffs_base__io_reader__match7(iop_a_src, io2_a_src, a_src, 111546413966853u);
48138           if (v_match == 0u) {
48139             *iop_a_dst++ = wuffs_base__make_token(
48140                 (((uint64_t)(8388612u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
48141                 (((uint64_t)(5u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
48142             if (((uint64_t)(io2_a_src - iop_a_src)) < 5u) {
48143               status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o);
48144               goto exit;
48145             }
48146             iop_a_src += 5u;
48147             break;
48148           } else if (v_match == 1u) {
48149             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
48150             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(19);
48151             goto label__outer__continue;
48152           }
48153         } else if (v_class == 10u) {
48154           v_match = wuffs_base__io_reader__match7(iop_a_src, io2_a_src, a_src, 435762131972u);
48155           if (v_match == 0u) {
48156             *iop_a_dst++ = wuffs_base__make_token(
48157                 (((uint64_t)(8388616u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
48158                 (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
48159             if (((uint64_t)(io2_a_src - iop_a_src)) < 4u) {
48160               status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o);
48161               goto exit;
48162             }
48163             iop_a_src += 4u;
48164             break;
48165           } else if (v_match == 1u) {
48166             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
48167             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(20);
48168             goto label__outer__continue;
48169           }
48170         } else if (v_class == 11u) {
48171           v_match = wuffs_base__io_reader__match7(iop_a_src, io2_a_src, a_src, 465676103172u);
48172           if (v_match == 0u) {
48173             *iop_a_dst++ = wuffs_base__make_token(
48174                 (((uint64_t)(8388610u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
48175                 (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
48176             if (((uint64_t)(io2_a_src - iop_a_src)) < 4u) {
48177               status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o);
48178               goto exit;
48179             }
48180             iop_a_src += 4u;
48181             break;
48182           } else if (v_match == 1u) {
48183             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
48184             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(21);
48185             goto label__outer__continue;
48186           }
48187           if (self->private_impl.f_quirks[14u]) {
48188             if (a_dst) {
48189               a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
48190             }
48191             if (a_src) {
48192               a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
48193             }
48194             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(22);
48195             status = wuffs_json__decoder__decode_inf_nan(self, a_dst, a_src);
48196             if (a_dst) {
48197               iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
48198             }
48199             if (a_src) {
48200               iop_a_src = a_src->data.ptr + a_src->meta.ri;
48201             }
48202             if (status.repr) {
48203               goto suspend;
48204             }
48205             break;
48206           }
48207         } else if (v_class == 12u) {
48208           if (self->private_impl.f_quirks[11u] || self->private_impl.f_quirks[12u]) {
48209             if (a_dst) {
48210               a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
48211             }
48212             if (a_src) {
48213               a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
48214             }
48215             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(23);
48216             status = wuffs_json__decoder__decode_comment(self, a_dst, a_src);
48217             if (a_dst) {
48218               iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
48219             }
48220             if (a_src) {
48221               iop_a_src = a_src->data.ptr + a_src->meta.ri;
48222             }
48223             if (status.repr) {
48224               goto suspend;
48225             }
48226             if (self->private_impl.f_comment_type > 0u) {
48227               goto label__outer__continue;
48228             }
48229           }
48230         }
48231         status = wuffs_base__make_status(wuffs_json__error__bad_input);
48232         goto exit;
48233       }
48234       if (v_depth == 0u) {
48235         break;
48236       }
48237       v_expect = v_expect_after_value;
48238     }
48239     label__outer__break:;
48240     if (self->private_impl.f_quirks[17u] || self->private_impl.f_quirks[18u]) {
48241       if (a_dst) {
48242         a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
48243       }
48244       if (a_src) {
48245         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
48246       }
48247       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(24);
48248       status = wuffs_json__decoder__decode_trailer(self, a_dst, a_src);
48249       if (a_dst) {
48250         iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
48251       }
48252       if (a_src) {
48253         iop_a_src = a_src->data.ptr + a_src->meta.ri;
48254       }
48255       if (status.repr) {
48256         goto suspend;
48257       }
48258     }
48259     self->private_impl.f_end_of_data = true;
48260 
48261     ok:
48262     self->private_impl.p_decode_tokens[0] = 0;
48263     goto exit;
48264   }
48265 
48266   goto suspend;
48267   suspend:
48268   self->private_impl.p_decode_tokens[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
48269   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
48270   self->private_data.s_decode_tokens[0].v_depth = v_depth;
48271   self->private_data.s_decode_tokens[0].v_expect = v_expect;
48272   self->private_data.s_decode_tokens[0].v_expect_after_value = v_expect_after_value;
48273 
48274   goto exit;
48275   exit:
48276   if (a_dst && a_dst->data.ptr) {
48277     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
48278   }
48279   if (a_src && a_src->data.ptr) {
48280     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
48281   }
48282 
48283   if (wuffs_base__status__is_error(&status)) {
48284     self->private_impl.magic = WUFFS_BASE__DISABLED;
48285   }
48286   return status;
48287 }
48288 
48289 // -------- func json.decoder.decode_number
48290 
48291 WUFFS_BASE__GENERATED_C_CODE
48292 static uint32_t
wuffs_json__decoder__decode_number(wuffs_json__decoder * self,wuffs_base__io_buffer * a_src)48293 wuffs_json__decoder__decode_number(
48294     wuffs_json__decoder* self,
48295     wuffs_base__io_buffer* a_src) {
48296   uint8_t v_c = 0;
48297   uint32_t v_n = 0;
48298   uint32_t v_floating_point = 0;
48299 
48300   const uint8_t* iop_a_src = NULL;
48301   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48302   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48303   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48304   if (a_src && a_src->data.ptr) {
48305     io0_a_src = a_src->data.ptr;
48306     io1_a_src = io0_a_src + a_src->meta.ri;
48307     iop_a_src = io1_a_src;
48308     io2_a_src = io0_a_src + a_src->meta.wi;
48309   }
48310 
48311   do {
48312     v_n = 0u;
48313     if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
48314       if ( ! (a_src && a_src->meta.closed)) {
48315         v_n |= 768u;
48316       }
48317       break;
48318     }
48319     v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
48320     if (v_c != 45u) {
48321     } else {
48322       v_n += 1u;
48323       iop_a_src += 1u;
48324       if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
48325         if ( ! (a_src && a_src->meta.closed)) {
48326           v_n |= 768u;
48327         }
48328         v_n |= 256u;
48329         break;
48330       }
48331       v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
48332     }
48333     if (v_c == 48u) {
48334       v_n += 1u;
48335       iop_a_src += 1u;
48336     } else {
48337       if (a_src) {
48338         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
48339       }
48340       v_n = wuffs_json__decoder__decode_digits(self, a_src, v_n);
48341       if (a_src) {
48342         iop_a_src = a_src->data.ptr + a_src->meta.ri;
48343       }
48344       if (v_n > 99u) {
48345         break;
48346       }
48347     }
48348     if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
48349       if ( ! (a_src && a_src->meta.closed)) {
48350         v_n |= 768u;
48351       }
48352       break;
48353     }
48354     v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
48355     if (v_c != 46u) {
48356     } else {
48357       if (v_n >= 99u) {
48358         v_n |= 512u;
48359         break;
48360       }
48361       v_n += 1u;
48362       iop_a_src += 1u;
48363       v_floating_point = 128u;
48364       if (a_src) {
48365         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
48366       }
48367       v_n = wuffs_json__decoder__decode_digits(self, a_src, v_n);
48368       if (a_src) {
48369         iop_a_src = a_src->data.ptr + a_src->meta.ri;
48370       }
48371       if (v_n > 99u) {
48372         break;
48373       }
48374       if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
48375         if ( ! (a_src && a_src->meta.closed)) {
48376           v_n |= 768u;
48377         }
48378         break;
48379       }
48380       v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
48381     }
48382     if ((v_c != 69u) && (v_c != 101u)) {
48383       break;
48384     }
48385     if (v_n >= 99u) {
48386       v_n |= 512u;
48387       break;
48388     }
48389     v_n += 1u;
48390     iop_a_src += 1u;
48391     v_floating_point = 128u;
48392     if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
48393       if ( ! (a_src && a_src->meta.closed)) {
48394         v_n |= 768u;
48395       }
48396       v_n |= 256u;
48397       break;
48398     }
48399     v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
48400     if ((v_c != 43u) && (v_c != 45u)) {
48401     } else {
48402       if (v_n >= 99u) {
48403         v_n |= 512u;
48404         break;
48405       }
48406       v_n += 1u;
48407       iop_a_src += 1u;
48408     }
48409     if (a_src) {
48410       a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
48411     }
48412     v_n = wuffs_json__decoder__decode_digits(self, a_src, v_n);
48413     if (a_src) {
48414       iop_a_src = a_src->data.ptr + a_src->meta.ri;
48415     }
48416   } while (0);
48417   if (a_src && a_src->data.ptr) {
48418     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
48419   }
48420   return (v_n | v_floating_point);
48421 }
48422 
48423 // -------- func json.decoder.decode_digits
48424 
48425 WUFFS_BASE__GENERATED_C_CODE
48426 static uint32_t
wuffs_json__decoder__decode_digits(wuffs_json__decoder * self,wuffs_base__io_buffer * a_src,uint32_t a_n)48427 wuffs_json__decoder__decode_digits(
48428     wuffs_json__decoder* self,
48429     wuffs_base__io_buffer* a_src,
48430     uint32_t a_n) {
48431   uint8_t v_c = 0;
48432   uint32_t v_n = 0;
48433 
48434   const uint8_t* iop_a_src = NULL;
48435   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48436   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48437   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48438   if (a_src && a_src->data.ptr) {
48439     io0_a_src = a_src->data.ptr;
48440     io1_a_src = io0_a_src + a_src->meta.ri;
48441     iop_a_src = io1_a_src;
48442     io2_a_src = io0_a_src + a_src->meta.wi;
48443   }
48444 
48445   v_n = a_n;
48446   while (true) {
48447     if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
48448       if ( ! (a_src && a_src->meta.closed)) {
48449         v_n |= 768u;
48450       }
48451       break;
48452     }
48453     v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
48454     if (0u == WUFFS_JSON__LUT_DECIMAL_DIGITS[v_c]) {
48455       break;
48456     }
48457     if (v_n >= 99u) {
48458       v_n |= 512u;
48459       break;
48460     }
48461     v_n += 1u;
48462     iop_a_src += 1u;
48463   }
48464   if (v_n == a_n) {
48465     v_n |= 256u;
48466   }
48467   if (a_src && a_src->data.ptr) {
48468     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
48469   }
48470   return v_n;
48471 }
48472 
48473 // -------- func json.decoder.decode_leading
48474 
48475 WUFFS_BASE__GENERATED_C_CODE
48476 static wuffs_base__status
wuffs_json__decoder__decode_leading(wuffs_json__decoder * self,wuffs_base__token_buffer * a_dst,wuffs_base__io_buffer * a_src)48477 wuffs_json__decoder__decode_leading(
48478     wuffs_json__decoder* self,
48479     wuffs_base__token_buffer* a_dst,
48480     wuffs_base__io_buffer* a_src) {
48481   wuffs_base__status status = wuffs_base__make_status(NULL);
48482 
48483   uint8_t v_c = 0;
48484   uint32_t v_u = 0;
48485 
48486   wuffs_base__token* iop_a_dst = NULL;
48487   wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48488   wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48489   wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48490   if (a_dst && a_dst->data.ptr) {
48491     io0_a_dst = a_dst->data.ptr;
48492     io1_a_dst = io0_a_dst + a_dst->meta.wi;
48493     iop_a_dst = io1_a_dst;
48494     io2_a_dst = io0_a_dst + a_dst->data.len;
48495     if (a_dst->meta.closed) {
48496       io2_a_dst = iop_a_dst;
48497     }
48498   }
48499   const uint8_t* iop_a_src = NULL;
48500   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48501   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48502   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48503   if (a_src && a_src->data.ptr) {
48504     io0_a_src = a_src->data.ptr;
48505     io1_a_src = io0_a_src + a_src->meta.ri;
48506     iop_a_src = io1_a_src;
48507     io2_a_src = io0_a_src + a_src->meta.wi;
48508   }
48509 
48510   uint32_t coro_susp_point = self->private_impl.p_decode_leading[0];
48511   switch (coro_susp_point) {
48512     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
48513 
48514     self->private_impl.f_allow_leading_ars = self->private_impl.f_quirks[15u];
48515     self->private_impl.f_allow_leading_ubom = self->private_impl.f_quirks[16u];
48516     while (self->private_impl.f_allow_leading_ars || self->private_impl.f_allow_leading_ubom) {
48517       if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
48518         status = wuffs_base__make_status(wuffs_base__suspension__short_write);
48519         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
48520         continue;
48521       }
48522       if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
48523         if (a_src && a_src->meta.closed) {
48524           break;
48525         }
48526         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
48527         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
48528         continue;
48529       }
48530       v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
48531       if ((v_c == 30u) && self->private_impl.f_allow_leading_ars) {
48532         self->private_impl.f_allow_leading_ars = false;
48533         iop_a_src += 1u;
48534         *iop_a_dst++ = wuffs_base__make_token(
48535             (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
48536             (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
48537         continue;
48538       } else if ((v_c == 239u) && self->private_impl.f_allow_leading_ubom) {
48539         if (((uint64_t)(io2_a_src - iop_a_src)) < 3u) {
48540           if (a_src && a_src->meta.closed) {
48541             break;
48542           }
48543           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
48544           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
48545           continue;
48546         }
48547         v_u = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src)));
48548         if (v_u == 12565487u) {
48549           self->private_impl.f_allow_leading_ubom = false;
48550           iop_a_src += 3u;
48551           *iop_a_dst++ = wuffs_base__make_token(
48552               (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
48553               (((uint64_t)(3u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
48554           continue;
48555         }
48556       }
48557       break;
48558     }
48559 
48560     ok:
48561     self->private_impl.p_decode_leading[0] = 0;
48562     goto exit;
48563   }
48564 
48565   goto suspend;
48566   suspend:
48567   self->private_impl.p_decode_leading[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
48568 
48569   goto exit;
48570   exit:
48571   if (a_dst && a_dst->data.ptr) {
48572     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
48573   }
48574   if (a_src && a_src->data.ptr) {
48575     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
48576   }
48577 
48578   return status;
48579 }
48580 
48581 // -------- func json.decoder.decode_comment
48582 
48583 WUFFS_BASE__GENERATED_C_CODE
48584 static wuffs_base__status
wuffs_json__decoder__decode_comment(wuffs_json__decoder * self,wuffs_base__token_buffer * a_dst,wuffs_base__io_buffer * a_src)48585 wuffs_json__decoder__decode_comment(
48586     wuffs_json__decoder* self,
48587     wuffs_base__token_buffer* a_dst,
48588     wuffs_base__io_buffer* a_src) {
48589   wuffs_base__status status = wuffs_base__make_status(NULL);
48590 
48591   uint8_t v_c = 0;
48592   uint16_t v_c2 = 0;
48593   uint32_t v_length = 0;
48594 
48595   wuffs_base__token* iop_a_dst = NULL;
48596   wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48597   wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48598   wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48599   if (a_dst && a_dst->data.ptr) {
48600     io0_a_dst = a_dst->data.ptr;
48601     io1_a_dst = io0_a_dst + a_dst->meta.wi;
48602     iop_a_dst = io1_a_dst;
48603     io2_a_dst = io0_a_dst + a_dst->data.len;
48604     if (a_dst->meta.closed) {
48605       io2_a_dst = iop_a_dst;
48606     }
48607   }
48608   const uint8_t* iop_a_src = NULL;
48609   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48610   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48611   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48612   if (a_src && a_src->data.ptr) {
48613     io0_a_src = a_src->data.ptr;
48614     io1_a_src = io0_a_src + a_src->meta.ri;
48615     iop_a_src = io1_a_src;
48616     io2_a_src = io0_a_src + a_src->meta.wi;
48617   }
48618 
48619   uint32_t coro_susp_point = self->private_impl.p_decode_comment[0];
48620   switch (coro_susp_point) {
48621     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
48622 
48623     self->private_impl.f_comment_type = 0u;
48624     while ((((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) || (((uint64_t)(io2_a_src - iop_a_src)) <= 1u)) {
48625       if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
48626         status = wuffs_base__make_status(wuffs_base__suspension__short_write);
48627         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
48628         continue;
48629       }
48630       if (a_src && a_src->meta.closed) {
48631         status = wuffs_base__make_status(NULL);
48632         goto ok;
48633       }
48634       status = wuffs_base__make_status(wuffs_base__suspension__short_read);
48635       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
48636     }
48637     v_c2 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src);
48638     if ((v_c2 == 10799u) && self->private_impl.f_quirks[11u]) {
48639       iop_a_src += 2u;
48640       v_length = 2u;
48641       while (true) {
48642         if (((uint64_t)(io2_a_src - iop_a_src)) <= 1u) {
48643           if (v_length > 0u) {
48644             *iop_a_dst++ = wuffs_base__make_token(
48645                 (((uint64_t)(2u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
48646                 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
48647                 (((uint64_t)(v_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
48648           }
48649           if (a_src && a_src->meta.closed) {
48650             status = wuffs_base__make_status(wuffs_json__error__bad_input);
48651             goto exit;
48652           }
48653           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
48654           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
48655           while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
48656             status = wuffs_base__make_status(wuffs_base__suspension__short_write);
48657             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
48658           }
48659           v_length = 0u;
48660           continue;
48661         }
48662         v_c2 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src);
48663         if (v_c2 == 12074u) {
48664           iop_a_src += 2u;
48665           *iop_a_dst++ = wuffs_base__make_token(
48666               (((uint64_t)(2u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
48667               (((uint64_t)((v_length + 2u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
48668           self->private_impl.f_comment_type = 1u;
48669           status = wuffs_base__make_status(NULL);
48670           goto ok;
48671         }
48672         iop_a_src += 1u;
48673         if (v_length >= 65533u) {
48674           *iop_a_dst++ = wuffs_base__make_token(
48675               (((uint64_t)(2u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
48676               (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
48677               (((uint64_t)((v_length + 1u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
48678           while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
48679             status = wuffs_base__make_status(wuffs_base__suspension__short_write);
48680             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
48681           }
48682           v_length = 0u;
48683           continue;
48684         }
48685         v_length += 1u;
48686       }
48687     } else if ((v_c2 == 12079u) && self->private_impl.f_quirks[12u]) {
48688       iop_a_src += 2u;
48689       v_length = 2u;
48690       while (true) {
48691         if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
48692           if (a_src && a_src->meta.closed) {
48693             *iop_a_dst++ = wuffs_base__make_token(
48694                 (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
48695                 (((uint64_t)(v_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
48696             self->private_impl.f_comment_type = 2u;
48697             status = wuffs_base__make_status(NULL);
48698             goto ok;
48699           } else if (v_length > 0u) {
48700             *iop_a_dst++ = wuffs_base__make_token(
48701                 (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
48702                 (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
48703                 (((uint64_t)(v_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
48704           }
48705           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
48706           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
48707           while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
48708             status = wuffs_base__make_status(wuffs_base__suspension__short_write);
48709             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7);
48710           }
48711           v_length = 0u;
48712           continue;
48713         }
48714         v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
48715         if (v_c == 10u) {
48716           *iop_a_dst++ = wuffs_base__make_token(
48717               (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
48718               (((uint64_t)(v_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
48719           self->private_impl.f_comment_type = 2u;
48720           status = wuffs_base__make_status(NULL);
48721           goto ok;
48722         }
48723         iop_a_src += 1u;
48724         if (v_length >= 65533u) {
48725           *iop_a_dst++ = wuffs_base__make_token(
48726               (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
48727               (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
48728               (((uint64_t)((v_length + 1u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
48729           while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
48730             status = wuffs_base__make_status(wuffs_base__suspension__short_write);
48731             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8);
48732           }
48733           v_length = 0u;
48734           continue;
48735         }
48736         v_length += 1u;
48737       }
48738     }
48739 
48740     ok:
48741     self->private_impl.p_decode_comment[0] = 0;
48742     goto exit;
48743   }
48744 
48745   goto suspend;
48746   suspend:
48747   self->private_impl.p_decode_comment[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
48748 
48749   goto exit;
48750   exit:
48751   if (a_dst && a_dst->data.ptr) {
48752     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
48753   }
48754   if (a_src && a_src->data.ptr) {
48755     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
48756   }
48757 
48758   return status;
48759 }
48760 
48761 // -------- func json.decoder.decode_inf_nan
48762 
48763 WUFFS_BASE__GENERATED_C_CODE
48764 static wuffs_base__status
wuffs_json__decoder__decode_inf_nan(wuffs_json__decoder * self,wuffs_base__token_buffer * a_dst,wuffs_base__io_buffer * a_src)48765 wuffs_json__decoder__decode_inf_nan(
48766     wuffs_json__decoder* self,
48767     wuffs_base__token_buffer* a_dst,
48768     wuffs_base__io_buffer* a_src) {
48769   wuffs_base__status status = wuffs_base__make_status(NULL);
48770 
48771   uint32_t v_c4 = 0;
48772   uint32_t v_neg = 0;
48773 
48774   wuffs_base__token* iop_a_dst = NULL;
48775   wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48776   wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48777   wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48778   if (a_dst && a_dst->data.ptr) {
48779     io0_a_dst = a_dst->data.ptr;
48780     io1_a_dst = io0_a_dst + a_dst->meta.wi;
48781     iop_a_dst = io1_a_dst;
48782     io2_a_dst = io0_a_dst + a_dst->data.len;
48783     if (a_dst->meta.closed) {
48784       io2_a_dst = iop_a_dst;
48785     }
48786   }
48787   const uint8_t* iop_a_src = NULL;
48788   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48789   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48790   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48791   if (a_src && a_src->data.ptr) {
48792     io0_a_src = a_src->data.ptr;
48793     io1_a_src = io0_a_src + a_src->meta.ri;
48794     iop_a_src = io1_a_src;
48795     io2_a_src = io0_a_src + a_src->meta.wi;
48796   }
48797 
48798   uint32_t coro_susp_point = self->private_impl.p_decode_inf_nan[0];
48799   switch (coro_susp_point) {
48800     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
48801 
48802     while (true) {
48803       if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
48804         status = wuffs_base__make_status(wuffs_base__suspension__short_write);
48805         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
48806         continue;
48807       }
48808       if (((uint64_t)(io2_a_src - iop_a_src)) <= 2u) {
48809         if (a_src && a_src->meta.closed) {
48810           status = wuffs_base__make_status(wuffs_json__error__bad_input);
48811           goto exit;
48812         }
48813         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
48814         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
48815         continue;
48816       }
48817       v_c4 = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src)));
48818       if ((v_c4 | 2105376u) == 6712937u) {
48819         if (((uint64_t)(io2_a_src - iop_a_src)) > 7u) {
48820           if ((wuffs_base__peek_u64le__no_bounds_check(iop_a_src) | 2314885530818453536u) == 8751735898823356009u) {
48821             *iop_a_dst++ = wuffs_base__make_token(
48822                 (((uint64_t)(10485792u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
48823                 (((uint64_t)(8u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
48824             iop_a_src += 8u;
48825             status = wuffs_base__make_status(NULL);
48826             goto ok;
48827           }
48828         } else if ( ! (a_src && a_src->meta.closed)) {
48829           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
48830           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
48831           continue;
48832         }
48833         *iop_a_dst++ = wuffs_base__make_token(
48834             (((uint64_t)(10485792u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
48835             (((uint64_t)(3u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
48836         iop_a_src += 3u;
48837         status = wuffs_base__make_status(NULL);
48838         goto ok;
48839       } else if ((v_c4 | 2105376u) == 7233902u) {
48840         *iop_a_dst++ = wuffs_base__make_token(
48841             (((uint64_t)(10485888u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
48842             (((uint64_t)(3u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
48843         iop_a_src += 3u;
48844         status = wuffs_base__make_status(NULL);
48845         goto ok;
48846       } else if ((v_c4 & 255u) == 43u) {
48847         v_neg = 0u;
48848       } else if ((v_c4 & 255u) == 45u) {
48849         v_neg = 1u;
48850       } else {
48851         status = wuffs_base__make_status(wuffs_json__error__bad_input);
48852         goto exit;
48853       }
48854       if (((uint64_t)(io2_a_src - iop_a_src)) <= 3u) {
48855         if (a_src && a_src->meta.closed) {
48856           status = wuffs_base__make_status(wuffs_json__error__bad_input);
48857           goto exit;
48858         }
48859         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
48860         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
48861         continue;
48862       }
48863       v_c4 = (wuffs_base__peek_u32le__no_bounds_check(iop_a_src) >> 8u);
48864       if ((v_c4 | 2105376u) == 6712937u) {
48865         if (((uint64_t)(io2_a_src - iop_a_src)) > 8u) {
48866           if ((wuffs_base__peek_u64le__no_bounds_check(iop_a_src + 1u) | 2314885530818453536u) == 8751735898823356009u) {
48867             *iop_a_dst++ = wuffs_base__make_token(
48868                 (((uint64_t)((10485760u | (((uint32_t)(32u)) >> v_neg)))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
48869                 (((uint64_t)(9u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
48870             iop_a_src += 9u;
48871             status = wuffs_base__make_status(NULL);
48872             goto ok;
48873           }
48874         } else if ( ! (a_src && a_src->meta.closed)) {
48875           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
48876           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
48877           continue;
48878         }
48879         *iop_a_dst++ = wuffs_base__make_token(
48880             (((uint64_t)((10485760u | (((uint32_t)(32u)) >> v_neg)))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
48881             (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
48882         iop_a_src += 4u;
48883         status = wuffs_base__make_status(NULL);
48884         goto ok;
48885       } else if ((v_c4 | 2105376u) == 7233902u) {
48886         *iop_a_dst++ = wuffs_base__make_token(
48887             (((uint64_t)((10485760u | (((uint32_t)(128u)) >> v_neg)))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
48888             (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
48889         iop_a_src += 4u;
48890         status = wuffs_base__make_status(NULL);
48891         goto ok;
48892       }
48893       status = wuffs_base__make_status(wuffs_json__error__bad_input);
48894       goto exit;
48895     }
48896 
48897     ok:
48898     self->private_impl.p_decode_inf_nan[0] = 0;
48899     goto exit;
48900   }
48901 
48902   goto suspend;
48903   suspend:
48904   self->private_impl.p_decode_inf_nan[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
48905 
48906   goto exit;
48907   exit:
48908   if (a_dst && a_dst->data.ptr) {
48909     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
48910   }
48911   if (a_src && a_src->data.ptr) {
48912     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
48913   }
48914 
48915   return status;
48916 }
48917 
48918 // -------- func json.decoder.decode_trailer
48919 
48920 WUFFS_BASE__GENERATED_C_CODE
48921 static wuffs_base__status
wuffs_json__decoder__decode_trailer(wuffs_json__decoder * self,wuffs_base__token_buffer * a_dst,wuffs_base__io_buffer * a_src)48922 wuffs_json__decoder__decode_trailer(
48923     wuffs_json__decoder* self,
48924     wuffs_base__token_buffer* a_dst,
48925     wuffs_base__io_buffer* a_src) {
48926   wuffs_base__status status = wuffs_base__make_status(NULL);
48927 
48928   uint8_t v_c = 0;
48929   uint32_t v_whitespace_length = 0;
48930 
48931   wuffs_base__token* iop_a_dst = NULL;
48932   wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48933   wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48934   wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48935   if (a_dst && a_dst->data.ptr) {
48936     io0_a_dst = a_dst->data.ptr;
48937     io1_a_dst = io0_a_dst + a_dst->meta.wi;
48938     iop_a_dst = io1_a_dst;
48939     io2_a_dst = io0_a_dst + a_dst->data.len;
48940     if (a_dst->meta.closed) {
48941       io2_a_dst = iop_a_dst;
48942     }
48943   }
48944   const uint8_t* iop_a_src = NULL;
48945   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48946   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48947   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
48948   if (a_src && a_src->data.ptr) {
48949     io0_a_src = a_src->data.ptr;
48950     io1_a_src = io0_a_src + a_src->meta.ri;
48951     iop_a_src = io1_a_src;
48952     io2_a_src = io0_a_src + a_src->meta.wi;
48953   }
48954 
48955   uint32_t coro_susp_point = self->private_impl.p_decode_trailer[0];
48956   switch (coro_susp_point) {
48957     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
48958 
48959     if (self->private_impl.f_quirks[18u]) {
48960       self->private_impl.f_trailer_stop = 10u;
48961     } else {
48962       self->private_impl.f_trailer_stop = 0u;
48963     }
48964     label__outer__continue:;
48965     while (true) {
48966       if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
48967         status = wuffs_base__make_status(wuffs_base__suspension__short_write);
48968         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
48969         continue;
48970       }
48971       v_whitespace_length = 0u;
48972       while (true) {
48973         if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
48974           if (v_whitespace_length > 0u) {
48975             *iop_a_dst++ = wuffs_base__make_token(
48976                 (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
48977                 (((uint64_t)(v_whitespace_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
48978           }
48979           if (a_src && a_src->meta.closed) {
48980             goto label__outer__break;
48981           }
48982           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
48983           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
48984           goto label__outer__continue;
48985         }
48986         v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
48987         if (WUFFS_JSON__LUT_CLASSES[v_c] != 0u) {
48988           if (v_whitespace_length > 0u) {
48989             *iop_a_dst++ = wuffs_base__make_token(
48990                 (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
48991                 (((uint64_t)(v_whitespace_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
48992           }
48993           if (self->private_impl.f_trailer_stop > 0u) {
48994             status = wuffs_base__make_status(wuffs_json__error__bad_input);
48995             goto exit;
48996           }
48997           if (a_dst) {
48998             a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
48999           }
49000           if (a_src) {
49001             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
49002           }
49003           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
49004           status = wuffs_json__decoder__decode_comment(self, a_dst, a_src);
49005           if (a_dst) {
49006             iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
49007           }
49008           if (a_src) {
49009             iop_a_src = a_src->data.ptr + a_src->meta.ri;
49010           }
49011           if (status.repr) {
49012             goto suspend;
49013           }
49014           if (self->private_impl.f_comment_type > 0u) {
49015             goto label__outer__continue;
49016           }
49017           status = wuffs_base__make_status(NULL);
49018           goto ok;
49019         }
49020         iop_a_src += 1u;
49021         if ((v_whitespace_length >= 65534u) || (v_c == self->private_impl.f_trailer_stop)) {
49022           *iop_a_dst++ = wuffs_base__make_token(
49023               (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
49024               (((uint64_t)((v_whitespace_length + 1u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
49025           if (v_c == self->private_impl.f_trailer_stop) {
49026             status = wuffs_base__make_status(NULL);
49027             goto ok;
49028           }
49029           goto label__outer__continue;
49030         }
49031         v_whitespace_length += 1u;
49032       }
49033     }
49034     label__outer__break:;
49035 
49036     ok:
49037     self->private_impl.p_decode_trailer[0] = 0;
49038     goto exit;
49039   }
49040 
49041   goto suspend;
49042   suspend:
49043   self->private_impl.p_decode_trailer[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
49044 
49045   goto exit;
49046   exit:
49047   if (a_dst && a_dst->data.ptr) {
49048     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
49049   }
49050   if (a_src && a_src->data.ptr) {
49051     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
49052   }
49053 
49054   return status;
49055 }
49056 
49057 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JSON)
49058 
49059 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZW)
49060 
49061 // ---------------- Status Codes Implementations
49062 
49063 const char wuffs_lzw__error__bad_code[] = "#lzw: bad code";
49064 const char wuffs_lzw__error__truncated_input[] = "#lzw: truncated input";
49065 const char wuffs_lzw__error__internal_error_inconsistent_i_o[] = "#lzw: internal error: inconsistent I/O";
49066 
49067 // ---------------- Private Consts
49068 
49069 #define WUFFS_LZW__QUIRKS_BASE 1348378624
49070 
49071 // ---------------- Private Initializer Prototypes
49072 
49073 // ---------------- Private Function Prototypes
49074 
49075 WUFFS_BASE__GENERATED_C_CODE
49076 static wuffs_base__empty_struct
49077 wuffs_lzw__decoder__read_from(
49078     wuffs_lzw__decoder* self,
49079     wuffs_base__io_buffer* a_src);
49080 
49081 WUFFS_BASE__GENERATED_C_CODE
49082 static wuffs_base__status
49083 wuffs_lzw__decoder__write_to(
49084     wuffs_lzw__decoder* self,
49085     wuffs_base__io_buffer* a_dst);
49086 
49087 // ---------------- VTables
49088 
49089 const wuffs_base__io_transformer__func_ptrs
49090 wuffs_lzw__decoder__func_ptrs_for__wuffs_base__io_transformer = {
49091   (uint64_t(*)(const void*,
49092       uint32_t))(&wuffs_lzw__decoder__get_quirk),
49093   (uint64_t(*)(const void*))(&wuffs_lzw__decoder__history_retain_length),
49094   (wuffs_base__status(*)(void*,
49095       uint32_t,
49096       uint64_t))(&wuffs_lzw__decoder__set_quirk),
49097   (wuffs_base__status(*)(void*,
49098       wuffs_base__io_buffer*,
49099       wuffs_base__io_buffer*,
49100       wuffs_base__slice_u8))(&wuffs_lzw__decoder__transform_io),
49101   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_lzw__decoder__workbuf_len),
49102 };
49103 
49104 // ---------------- Initializer Implementations
49105 
49106 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
wuffs_lzw__decoder__initialize(wuffs_lzw__decoder * self,size_t sizeof_star_self,uint64_t wuffs_version,uint32_t options)49107 wuffs_lzw__decoder__initialize(
49108     wuffs_lzw__decoder* self,
49109     size_t sizeof_star_self,
49110     uint64_t wuffs_version,
49111     uint32_t options){
49112   if (!self) {
49113     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
49114   }
49115   if (sizeof(*self) != sizeof_star_self) {
49116     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
49117   }
49118   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
49119       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
49120     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
49121   }
49122 
49123   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
49124     // The whole point of this if-check is to detect an uninitialized *self.
49125     // We disable the warning on GCC. Clang-5.0 does not have this warning.
49126 #if !defined(__clang__) && defined(__GNUC__)
49127 #pragma GCC diagnostic push
49128 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
49129 #endif
49130     if (self->private_impl.magic != 0) {
49131       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
49132     }
49133 #if !defined(__clang__) && defined(__GNUC__)
49134 #pragma GCC diagnostic pop
49135 #endif
49136   } else {
49137     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
49138       memset(self, 0, sizeof(*self));
49139       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
49140     } else {
49141       memset(&(self->private_impl), 0, sizeof(self->private_impl));
49142     }
49143   }
49144 
49145   self->private_impl.magic = WUFFS_BASE__MAGIC;
49146   self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name =
49147       wuffs_base__io_transformer__vtable_name;
49148   self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers =
49149       (const void*)(&wuffs_lzw__decoder__func_ptrs_for__wuffs_base__io_transformer);
49150   return wuffs_base__make_status(NULL);
49151 }
49152 
49153 wuffs_lzw__decoder*
wuffs_lzw__decoder__alloc(void)49154 wuffs_lzw__decoder__alloc(void) {
49155   wuffs_lzw__decoder* x =
49156       (wuffs_lzw__decoder*)(calloc(sizeof(wuffs_lzw__decoder), 1));
49157   if (!x) {
49158     return NULL;
49159   }
49160   if (wuffs_lzw__decoder__initialize(
49161       x, sizeof(wuffs_lzw__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
49162     free(x);
49163     return NULL;
49164   }
49165   return x;
49166 }
49167 
49168 size_t
sizeof__wuffs_lzw__decoder(void)49169 sizeof__wuffs_lzw__decoder(void) {
49170   return sizeof(wuffs_lzw__decoder);
49171 }
49172 
49173 // ---------------- Function Implementations
49174 
49175 // -------- func lzw.decoder.get_quirk
49176 
49177 WUFFS_BASE__GENERATED_C_CODE
49178 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_lzw__decoder__get_quirk(const wuffs_lzw__decoder * self,uint32_t a_key)49179 wuffs_lzw__decoder__get_quirk(
49180     const wuffs_lzw__decoder* self,
49181     uint32_t a_key) {
49182   if (!self) {
49183     return 0;
49184   }
49185   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
49186       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
49187     return 0;
49188   }
49189 
49190   if (a_key == 1348378624u) {
49191     return ((uint64_t)(self->private_impl.f_pending_literal_width_plus_one));
49192   }
49193   return 0u;
49194 }
49195 
49196 // -------- func lzw.decoder.set_quirk
49197 
49198 WUFFS_BASE__GENERATED_C_CODE
49199 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_lzw__decoder__set_quirk(wuffs_lzw__decoder * self,uint32_t a_key,uint64_t a_value)49200 wuffs_lzw__decoder__set_quirk(
49201     wuffs_lzw__decoder* self,
49202     uint32_t a_key,
49203     uint64_t a_value) {
49204   if (!self) {
49205     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
49206   }
49207   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
49208     return wuffs_base__make_status(
49209         (self->private_impl.magic == WUFFS_BASE__DISABLED)
49210         ? wuffs_base__error__disabled_by_previous_error
49211         : wuffs_base__error__initialize_not_called);
49212   }
49213 
49214   if (a_key == 1348378624u) {
49215     if (a_value > 9u) {
49216       return wuffs_base__make_status(wuffs_base__error__bad_argument);
49217     }
49218     self->private_impl.f_pending_literal_width_plus_one = ((uint32_t)(a_value));
49219     return wuffs_base__make_status(NULL);
49220   }
49221   return wuffs_base__make_status(wuffs_base__error__unsupported_option);
49222 }
49223 
49224 // -------- func lzw.decoder.history_retain_length
49225 
49226 WUFFS_BASE__GENERATED_C_CODE
49227 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_lzw__decoder__history_retain_length(const wuffs_lzw__decoder * self)49228 wuffs_lzw__decoder__history_retain_length(
49229     const wuffs_lzw__decoder* self) {
49230   if (!self) {
49231     return 0;
49232   }
49233   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
49234       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
49235     return 0;
49236   }
49237 
49238   return 0u;
49239 }
49240 
49241 // -------- func lzw.decoder.workbuf_len
49242 
49243 WUFFS_BASE__GENERATED_C_CODE
49244 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_lzw__decoder__workbuf_len(const wuffs_lzw__decoder * self)49245 wuffs_lzw__decoder__workbuf_len(
49246     const wuffs_lzw__decoder* self) {
49247   if (!self) {
49248     return wuffs_base__utility__empty_range_ii_u64();
49249   }
49250   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
49251       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
49252     return wuffs_base__utility__empty_range_ii_u64();
49253   }
49254 
49255   return wuffs_base__utility__make_range_ii_u64(0u, 0u);
49256 }
49257 
49258 // -------- func lzw.decoder.transform_io
49259 
49260 WUFFS_BASE__GENERATED_C_CODE
49261 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_lzw__decoder__transform_io(wuffs_lzw__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__slice_u8 a_workbuf)49262 wuffs_lzw__decoder__transform_io(
49263     wuffs_lzw__decoder* self,
49264     wuffs_base__io_buffer* a_dst,
49265     wuffs_base__io_buffer* a_src,
49266     wuffs_base__slice_u8 a_workbuf) {
49267   if (!self) {
49268     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
49269   }
49270   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
49271     return wuffs_base__make_status(
49272         (self->private_impl.magic == WUFFS_BASE__DISABLED)
49273         ? wuffs_base__error__disabled_by_previous_error
49274         : wuffs_base__error__initialize_not_called);
49275   }
49276   if (!a_dst || !a_src) {
49277     self->private_impl.magic = WUFFS_BASE__DISABLED;
49278     return wuffs_base__make_status(wuffs_base__error__bad_argument);
49279   }
49280   if ((self->private_impl.active_coroutine != 0) &&
49281       (self->private_impl.active_coroutine != 1)) {
49282     self->private_impl.magic = WUFFS_BASE__DISABLED;
49283     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
49284   }
49285   self->private_impl.active_coroutine = 0;
49286   wuffs_base__status status = wuffs_base__make_status(NULL);
49287 
49288   uint32_t v_i = 0;
49289 
49290   uint32_t coro_susp_point = self->private_impl.p_transform_io[0];
49291   switch (coro_susp_point) {
49292     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
49293 
49294     self->private_impl.f_literal_width = 8u;
49295     if (self->private_impl.f_pending_literal_width_plus_one > 0u) {
49296       self->private_impl.f_literal_width = (self->private_impl.f_pending_literal_width_plus_one - 1u);
49297     }
49298     self->private_impl.f_clear_code = (((uint32_t)(1u)) << self->private_impl.f_literal_width);
49299     self->private_impl.f_end_code = (self->private_impl.f_clear_code + 1u);
49300     self->private_impl.f_save_code = self->private_impl.f_end_code;
49301     self->private_impl.f_prev_code = self->private_impl.f_end_code;
49302     self->private_impl.f_width = (self->private_impl.f_literal_width + 1u);
49303     self->private_impl.f_bits = 0u;
49304     self->private_impl.f_n_bits = 0u;
49305     self->private_impl.f_output_ri = 0u;
49306     self->private_impl.f_output_wi = 0u;
49307     v_i = 0u;
49308     while (v_i < self->private_impl.f_clear_code) {
49309       self->private_data.f_lm1s[v_i] = 0u;
49310       self->private_data.f_suffixes[v_i][0u] = ((uint8_t)(v_i));
49311       v_i += 1u;
49312     }
49313     while (true) {
49314       wuffs_lzw__decoder__read_from(self, a_src);
49315       if (self->private_impl.f_output_wi > 0u) {
49316         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
49317         status = wuffs_lzw__decoder__write_to(self, a_dst);
49318         if (status.repr) {
49319           goto suspend;
49320         }
49321       }
49322       if (self->private_impl.f_read_from_return_value == 0u) {
49323         break;
49324       } else if (self->private_impl.f_read_from_return_value == 1u) {
49325         continue;
49326       } else if (self->private_impl.f_read_from_return_value == 2u) {
49327         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
49328         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
49329       } else if (self->private_impl.f_read_from_return_value == 3u) {
49330         status = wuffs_base__make_status(wuffs_lzw__error__truncated_input);
49331         goto exit;
49332       } else if (self->private_impl.f_read_from_return_value == 4u) {
49333         status = wuffs_base__make_status(wuffs_lzw__error__bad_code);
49334         goto exit;
49335       } else {
49336         status = wuffs_base__make_status(wuffs_lzw__error__internal_error_inconsistent_i_o);
49337         goto exit;
49338       }
49339     }
49340 
49341     ok:
49342     self->private_impl.p_transform_io[0] = 0;
49343     goto exit;
49344   }
49345 
49346   goto suspend;
49347   suspend:
49348   self->private_impl.p_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
49349   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
49350 
49351   goto exit;
49352   exit:
49353   if (wuffs_base__status__is_error(&status)) {
49354     self->private_impl.magic = WUFFS_BASE__DISABLED;
49355   }
49356   return status;
49357 }
49358 
49359 // -------- func lzw.decoder.read_from
49360 
49361 WUFFS_BASE__GENERATED_C_CODE
49362 static wuffs_base__empty_struct
wuffs_lzw__decoder__read_from(wuffs_lzw__decoder * self,wuffs_base__io_buffer * a_src)49363 wuffs_lzw__decoder__read_from(
49364     wuffs_lzw__decoder* self,
49365     wuffs_base__io_buffer* a_src) {
49366   uint32_t v_clear_code = 0;
49367   uint32_t v_end_code = 0;
49368   uint32_t v_save_code = 0;
49369   uint32_t v_prev_code = 0;
49370   uint32_t v_width = 0;
49371   uint32_t v_bits = 0;
49372   uint32_t v_n_bits = 0;
49373   uint32_t v_output_wi = 0;
49374   uint32_t v_code = 0;
49375   uint32_t v_c = 0;
49376   uint32_t v_o = 0;
49377   uint32_t v_steps = 0;
49378   uint8_t v_first_byte = 0;
49379   uint16_t v_lm1_b = 0;
49380   uint16_t v_lm1_a = 0;
49381 
49382   const uint8_t* iop_a_src = NULL;
49383   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
49384   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
49385   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
49386   if (a_src && a_src->data.ptr) {
49387     io0_a_src = a_src->data.ptr;
49388     io1_a_src = io0_a_src + a_src->meta.ri;
49389     iop_a_src = io1_a_src;
49390     io2_a_src = io0_a_src + a_src->meta.wi;
49391   }
49392 
49393   v_clear_code = self->private_impl.f_clear_code;
49394   v_end_code = self->private_impl.f_end_code;
49395   v_save_code = self->private_impl.f_save_code;
49396   v_prev_code = self->private_impl.f_prev_code;
49397   v_width = self->private_impl.f_width;
49398   v_bits = self->private_impl.f_bits;
49399   v_n_bits = self->private_impl.f_n_bits;
49400   v_output_wi = self->private_impl.f_output_wi;
49401   while (true) {
49402     if (v_n_bits < v_width) {
49403       if (((uint64_t)(io2_a_src - iop_a_src)) >= 4u) {
49404         v_bits |= ((uint32_t)(wuffs_base__peek_u32le__no_bounds_check(iop_a_src) << v_n_bits));
49405         iop_a_src += ((31u - v_n_bits) >> 3u);
49406         v_n_bits |= 24u;
49407       } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
49408         if (a_src && a_src->meta.closed) {
49409           self->private_impl.f_read_from_return_value = 3u;
49410         } else {
49411           self->private_impl.f_read_from_return_value = 2u;
49412         }
49413         break;
49414       } else {
49415         v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
49416         iop_a_src += 1u;
49417         v_n_bits += 8u;
49418         if (v_n_bits >= v_width) {
49419         } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
49420           if (a_src && a_src->meta.closed) {
49421             self->private_impl.f_read_from_return_value = 3u;
49422           } else {
49423             self->private_impl.f_read_from_return_value = 2u;
49424           }
49425           break;
49426         } else {
49427           v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
49428           iop_a_src += 1u;
49429           v_n_bits += 8u;
49430           if (v_n_bits < v_width) {
49431             self->private_impl.f_read_from_return_value = 5u;
49432             break;
49433           }
49434         }
49435       }
49436     }
49437     v_code = ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_width));
49438     v_bits >>= v_width;
49439     v_n_bits -= v_width;
49440     if (v_code < v_clear_code) {
49441       self->private_data.f_output[v_output_wi] = ((uint8_t)(v_code));
49442       v_output_wi = ((v_output_wi + 1u) & 8191u);
49443       if (v_save_code <= 4095u) {
49444         v_lm1_a = (((uint16_t)(self->private_data.f_lm1s[v_prev_code] + 1u)) & 4095u);
49445         self->private_data.f_lm1s[v_save_code] = v_lm1_a;
49446         if ((v_lm1_a % 8u) != 0u) {
49447           self->private_impl.f_prefixes[v_save_code] = self->private_impl.f_prefixes[v_prev_code];
49448           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]));
49449           self->private_data.f_suffixes[v_save_code][(v_lm1_a % 8u)] = ((uint8_t)(v_code));
49450         } else {
49451           self->private_impl.f_prefixes[v_save_code] = ((uint16_t)(v_prev_code));
49452           self->private_data.f_suffixes[v_save_code][0u] = ((uint8_t)(v_code));
49453         }
49454         v_save_code += 1u;
49455         if (v_width < 12u) {
49456           v_width += (1u & (v_save_code >> v_width));
49457         }
49458         v_prev_code = v_code;
49459       }
49460     } else if (v_code <= v_end_code) {
49461       if (v_code == v_end_code) {
49462         self->private_impl.f_read_from_return_value = 0u;
49463         break;
49464       }
49465       v_save_code = v_end_code;
49466       v_prev_code = v_end_code;
49467       v_width = (self->private_impl.f_literal_width + 1u);
49468     } else if (v_code <= v_save_code) {
49469       v_c = v_code;
49470       if (v_code == v_save_code) {
49471         v_c = v_prev_code;
49472       }
49473       v_o = ((v_output_wi + (((uint32_t)(self->private_data.f_lm1s[v_c])) & 4294967288u)) & 8191u);
49474       v_output_wi = ((v_output_wi + 1u + ((uint32_t)(self->private_data.f_lm1s[v_c]))) & 8191u);
49475       v_steps = (((uint32_t)(self->private_data.f_lm1s[v_c])) >> 3u);
49476       while (true) {
49477         memcpy((self->private_data.f_output)+(v_o), (self->private_data.f_suffixes[v_c]), 8u);
49478         if (v_steps <= 0u) {
49479           break;
49480         }
49481         v_steps -= 1u;
49482         v_o = (((uint32_t)(v_o - 8u)) & 8191u);
49483         v_c = ((uint32_t)(self->private_impl.f_prefixes[v_c]));
49484       }
49485       v_first_byte = self->private_data.f_suffixes[v_c][0u];
49486       if (v_code == v_save_code) {
49487         self->private_data.f_output[v_output_wi] = v_first_byte;
49488         v_output_wi = ((v_output_wi + 1u) & 8191u);
49489       }
49490       if (v_save_code <= 4095u) {
49491         v_lm1_b = (((uint16_t)(self->private_data.f_lm1s[v_prev_code] + 1u)) & 4095u);
49492         self->private_data.f_lm1s[v_save_code] = v_lm1_b;
49493         if ((v_lm1_b % 8u) != 0u) {
49494           self->private_impl.f_prefixes[v_save_code] = self->private_impl.f_prefixes[v_prev_code];
49495           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]));
49496           self->private_data.f_suffixes[v_save_code][(v_lm1_b % 8u)] = v_first_byte;
49497         } else {
49498           self->private_impl.f_prefixes[v_save_code] = ((uint16_t)(v_prev_code));
49499           self->private_data.f_suffixes[v_save_code][0u] = ((uint8_t)(v_first_byte));
49500         }
49501         v_save_code += 1u;
49502         if (v_width < 12u) {
49503           v_width += (1u & (v_save_code >> v_width));
49504         }
49505         v_prev_code = v_code;
49506       }
49507     } else {
49508       self->private_impl.f_read_from_return_value = 4u;
49509       break;
49510     }
49511     if (v_output_wi > 4095u) {
49512       self->private_impl.f_read_from_return_value = 1u;
49513       break;
49514     }
49515   }
49516   if (self->private_impl.f_read_from_return_value != 2u) {
49517     while (v_n_bits >= 8u) {
49518       v_n_bits -= 8u;
49519       if (iop_a_src > io1_a_src) {
49520         iop_a_src--;
49521       } else {
49522         self->private_impl.f_read_from_return_value = 5u;
49523         break;
49524       }
49525     }
49526   }
49527   self->private_impl.f_save_code = v_save_code;
49528   self->private_impl.f_prev_code = v_prev_code;
49529   self->private_impl.f_width = v_width;
49530   self->private_impl.f_bits = v_bits;
49531   self->private_impl.f_n_bits = v_n_bits;
49532   self->private_impl.f_output_wi = v_output_wi;
49533   if (a_src && a_src->data.ptr) {
49534     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
49535   }
49536 
49537   return wuffs_base__make_empty_struct();
49538 }
49539 
49540 // -------- func lzw.decoder.write_to
49541 
49542 WUFFS_BASE__GENERATED_C_CODE
49543 static wuffs_base__status
wuffs_lzw__decoder__write_to(wuffs_lzw__decoder * self,wuffs_base__io_buffer * a_dst)49544 wuffs_lzw__decoder__write_to(
49545     wuffs_lzw__decoder* self,
49546     wuffs_base__io_buffer* a_dst) {
49547   wuffs_base__status status = wuffs_base__make_status(NULL);
49548 
49549   wuffs_base__slice_u8 v_s = {0};
49550   uint64_t v_n = 0;
49551 
49552   uint8_t* iop_a_dst = NULL;
49553   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
49554   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
49555   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
49556   if (a_dst && a_dst->data.ptr) {
49557     io0_a_dst = a_dst->data.ptr;
49558     io1_a_dst = io0_a_dst + a_dst->meta.wi;
49559     iop_a_dst = io1_a_dst;
49560     io2_a_dst = io0_a_dst + a_dst->data.len;
49561     if (a_dst->meta.closed) {
49562       io2_a_dst = iop_a_dst;
49563     }
49564   }
49565 
49566   uint32_t coro_susp_point = self->private_impl.p_write_to[0];
49567   switch (coro_susp_point) {
49568     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
49569 
49570     while (self->private_impl.f_output_wi > 0u) {
49571       if (self->private_impl.f_output_ri > self->private_impl.f_output_wi) {
49572         status = wuffs_base__make_status(wuffs_lzw__error__internal_error_inconsistent_i_o);
49573         goto exit;
49574       }
49575       v_s = wuffs_base__make_slice_u8_ij(self->private_data.f_output,
49576           self->private_impl.f_output_ri,
49577           self->private_impl.f_output_wi);
49578       v_n = wuffs_base__io_writer__copy_from_slice(&iop_a_dst, io2_a_dst,v_s);
49579       if (v_n == ((uint64_t)(v_s.len))) {
49580         self->private_impl.f_output_ri = 0u;
49581         self->private_impl.f_output_wi = 0u;
49582         status = wuffs_base__make_status(NULL);
49583         goto ok;
49584       }
49585       self->private_impl.f_output_ri = (((uint32_t)(self->private_impl.f_output_ri + ((uint32_t)(v_n)))) & 8191u);
49586       status = wuffs_base__make_status(wuffs_base__suspension__short_write);
49587       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
49588     }
49589 
49590     ok:
49591     self->private_impl.p_write_to[0] = 0;
49592     goto exit;
49593   }
49594 
49595   goto suspend;
49596   suspend:
49597   self->private_impl.p_write_to[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
49598 
49599   goto exit;
49600   exit:
49601   if (a_dst && a_dst->data.ptr) {
49602     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
49603   }
49604 
49605   return status;
49606 }
49607 
49608 // -------- func lzw.decoder.flush
49609 
49610 WUFFS_BASE__GENERATED_C_CODE
49611 WUFFS_BASE__MAYBE_STATIC wuffs_base__slice_u8
wuffs_lzw__decoder__flush(wuffs_lzw__decoder * self)49612 wuffs_lzw__decoder__flush(
49613     wuffs_lzw__decoder* self) {
49614   if (!self) {
49615     return wuffs_base__make_slice_u8(NULL, 0);
49616   }
49617   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
49618     return wuffs_base__make_slice_u8(NULL, 0);
49619   }
49620 
49621   uint32_t v_ri = 0;
49622   uint32_t v_wi = 0;
49623 
49624   v_ri = self->private_impl.f_output_ri;
49625   v_wi = self->private_impl.f_output_wi;
49626   self->private_impl.f_output_ri = 0u;
49627   self->private_impl.f_output_wi = 0u;
49628   if (v_ri <= v_wi) {
49629     return wuffs_base__make_slice_u8_ij(self->private_data.f_output, v_ri, v_wi);
49630   }
49631   return wuffs_base__make_slice_u8(self->private_data.f_output, 0);
49632 }
49633 
49634 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZW)
49635 
49636 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NETPBM)
49637 
49638 // ---------------- Status Codes Implementations
49639 
49640 const char wuffs_netpbm__error__bad_header[] = "#netpbm: bad header";
49641 const char wuffs_netpbm__error__truncated_input[] = "#netpbm: truncated input";
49642 const char wuffs_netpbm__error__unsupported_netpbm_file[] = "#netpbm: unsupported Netpbm file";
49643 const char wuffs_netpbm__note__internal_note_short_read[] = "@netpbm: internal note: short read";
49644 
49645 // ---------------- Private Consts
49646 
49647 // ---------------- Private Initializer Prototypes
49648 
49649 // ---------------- Private Function Prototypes
49650 
49651 WUFFS_BASE__GENERATED_C_CODE
49652 static wuffs_base__status
49653 wuffs_netpbm__decoder__do_decode_image_config(
49654     wuffs_netpbm__decoder* self,
49655     wuffs_base__image_config* a_dst,
49656     wuffs_base__io_buffer* a_src);
49657 
49658 WUFFS_BASE__GENERATED_C_CODE
49659 static wuffs_base__status
49660 wuffs_netpbm__decoder__do_decode_frame_config(
49661     wuffs_netpbm__decoder* self,
49662     wuffs_base__frame_config* a_dst,
49663     wuffs_base__io_buffer* a_src);
49664 
49665 WUFFS_BASE__GENERATED_C_CODE
49666 static wuffs_base__status
49667 wuffs_netpbm__decoder__do_decode_frame(
49668     wuffs_netpbm__decoder* self,
49669     wuffs_base__pixel_buffer* a_dst,
49670     wuffs_base__io_buffer* a_src,
49671     wuffs_base__pixel_blend a_blend,
49672     wuffs_base__slice_u8 a_workbuf,
49673     wuffs_base__decode_frame_options* a_opts);
49674 
49675 WUFFS_BASE__GENERATED_C_CODE
49676 static wuffs_base__status
49677 wuffs_netpbm__decoder__swizzle(
49678     wuffs_netpbm__decoder* self,
49679     wuffs_base__pixel_buffer* a_dst,
49680     wuffs_base__io_buffer* a_src);
49681 
49682 // ---------------- VTables
49683 
49684 const wuffs_base__image_decoder__func_ptrs
49685 wuffs_netpbm__decoder__func_ptrs_for__wuffs_base__image_decoder = {
49686   (wuffs_base__status(*)(void*,
49687       wuffs_base__pixel_buffer*,
49688       wuffs_base__io_buffer*,
49689       wuffs_base__pixel_blend,
49690       wuffs_base__slice_u8,
49691       wuffs_base__decode_frame_options*))(&wuffs_netpbm__decoder__decode_frame),
49692   (wuffs_base__status(*)(void*,
49693       wuffs_base__frame_config*,
49694       wuffs_base__io_buffer*))(&wuffs_netpbm__decoder__decode_frame_config),
49695   (wuffs_base__status(*)(void*,
49696       wuffs_base__image_config*,
49697       wuffs_base__io_buffer*))(&wuffs_netpbm__decoder__decode_image_config),
49698   (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_netpbm__decoder__frame_dirty_rect),
49699   (uint64_t(*)(const void*,
49700       uint32_t))(&wuffs_netpbm__decoder__get_quirk),
49701   (uint64_t(*)(const void*))(&wuffs_netpbm__decoder__history_retain_length),
49702   (uint32_t(*)(const void*))(&wuffs_netpbm__decoder__num_animation_loops),
49703   (uint64_t(*)(const void*))(&wuffs_netpbm__decoder__num_decoded_frame_configs),
49704   (uint64_t(*)(const void*))(&wuffs_netpbm__decoder__num_decoded_frames),
49705   (wuffs_base__status(*)(void*,
49706       uint64_t,
49707       uint64_t))(&wuffs_netpbm__decoder__restart_frame),
49708   (wuffs_base__status(*)(void*,
49709       uint32_t,
49710       uint64_t))(&wuffs_netpbm__decoder__set_quirk),
49711   (wuffs_base__empty_struct(*)(void*,
49712       uint32_t,
49713       bool))(&wuffs_netpbm__decoder__set_report_metadata),
49714   (wuffs_base__status(*)(void*,
49715       wuffs_base__io_buffer*,
49716       wuffs_base__more_information*,
49717       wuffs_base__io_buffer*))(&wuffs_netpbm__decoder__tell_me_more),
49718   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_netpbm__decoder__workbuf_len),
49719 };
49720 
49721 // ---------------- Initializer Implementations
49722 
49723 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
wuffs_netpbm__decoder__initialize(wuffs_netpbm__decoder * self,size_t sizeof_star_self,uint64_t wuffs_version,uint32_t options)49724 wuffs_netpbm__decoder__initialize(
49725     wuffs_netpbm__decoder* self,
49726     size_t sizeof_star_self,
49727     uint64_t wuffs_version,
49728     uint32_t options){
49729   if (!self) {
49730     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
49731   }
49732   if (sizeof(*self) != sizeof_star_self) {
49733     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
49734   }
49735   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
49736       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
49737     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
49738   }
49739 
49740   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
49741     // The whole point of this if-check is to detect an uninitialized *self.
49742     // We disable the warning on GCC. Clang-5.0 does not have this warning.
49743 #if !defined(__clang__) && defined(__GNUC__)
49744 #pragma GCC diagnostic push
49745 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
49746 #endif
49747     if (self->private_impl.magic != 0) {
49748       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
49749     }
49750 #if !defined(__clang__) && defined(__GNUC__)
49751 #pragma GCC diagnostic pop
49752 #endif
49753   } else {
49754     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
49755       memset(self, 0, sizeof(*self));
49756       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
49757     } else {
49758       memset(&(self->private_impl), 0, sizeof(self->private_impl));
49759     }
49760   }
49761 
49762   self->private_impl.magic = WUFFS_BASE__MAGIC;
49763   self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
49764       wuffs_base__image_decoder__vtable_name;
49765   self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
49766       (const void*)(&wuffs_netpbm__decoder__func_ptrs_for__wuffs_base__image_decoder);
49767   return wuffs_base__make_status(NULL);
49768 }
49769 
49770 wuffs_netpbm__decoder*
wuffs_netpbm__decoder__alloc(void)49771 wuffs_netpbm__decoder__alloc(void) {
49772   wuffs_netpbm__decoder* x =
49773       (wuffs_netpbm__decoder*)(calloc(sizeof(wuffs_netpbm__decoder), 1));
49774   if (!x) {
49775     return NULL;
49776   }
49777   if (wuffs_netpbm__decoder__initialize(
49778       x, sizeof(wuffs_netpbm__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
49779     free(x);
49780     return NULL;
49781   }
49782   return x;
49783 }
49784 
49785 size_t
sizeof__wuffs_netpbm__decoder(void)49786 sizeof__wuffs_netpbm__decoder(void) {
49787   return sizeof(wuffs_netpbm__decoder);
49788 }
49789 
49790 // ---------------- Function Implementations
49791 
49792 // -------- func netpbm.decoder.get_quirk
49793 
49794 WUFFS_BASE__GENERATED_C_CODE
49795 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_netpbm__decoder__get_quirk(const wuffs_netpbm__decoder * self,uint32_t a_key)49796 wuffs_netpbm__decoder__get_quirk(
49797     const wuffs_netpbm__decoder* self,
49798     uint32_t a_key) {
49799   if (!self) {
49800     return 0;
49801   }
49802   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
49803       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
49804     return 0;
49805   }
49806 
49807   return 0u;
49808 }
49809 
49810 // -------- func netpbm.decoder.set_quirk
49811 
49812 WUFFS_BASE__GENERATED_C_CODE
49813 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_netpbm__decoder__set_quirk(wuffs_netpbm__decoder * self,uint32_t a_key,uint64_t a_value)49814 wuffs_netpbm__decoder__set_quirk(
49815     wuffs_netpbm__decoder* self,
49816     uint32_t a_key,
49817     uint64_t a_value) {
49818   if (!self) {
49819     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
49820   }
49821   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
49822     return wuffs_base__make_status(
49823         (self->private_impl.magic == WUFFS_BASE__DISABLED)
49824         ? wuffs_base__error__disabled_by_previous_error
49825         : wuffs_base__error__initialize_not_called);
49826   }
49827 
49828   return wuffs_base__make_status(wuffs_base__error__unsupported_option);
49829 }
49830 
49831 // -------- func netpbm.decoder.decode_image_config
49832 
49833 WUFFS_BASE__GENERATED_C_CODE
49834 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_netpbm__decoder__decode_image_config(wuffs_netpbm__decoder * self,wuffs_base__image_config * a_dst,wuffs_base__io_buffer * a_src)49835 wuffs_netpbm__decoder__decode_image_config(
49836     wuffs_netpbm__decoder* self,
49837     wuffs_base__image_config* a_dst,
49838     wuffs_base__io_buffer* a_src) {
49839   if (!self) {
49840     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
49841   }
49842   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
49843     return wuffs_base__make_status(
49844         (self->private_impl.magic == WUFFS_BASE__DISABLED)
49845         ? wuffs_base__error__disabled_by_previous_error
49846         : wuffs_base__error__initialize_not_called);
49847   }
49848   if (!a_src) {
49849     self->private_impl.magic = WUFFS_BASE__DISABLED;
49850     return wuffs_base__make_status(wuffs_base__error__bad_argument);
49851   }
49852   if ((self->private_impl.active_coroutine != 0) &&
49853       (self->private_impl.active_coroutine != 1)) {
49854     self->private_impl.magic = WUFFS_BASE__DISABLED;
49855     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
49856   }
49857   self->private_impl.active_coroutine = 0;
49858   wuffs_base__status status = wuffs_base__make_status(NULL);
49859 
49860   wuffs_base__status v_status = wuffs_base__make_status(NULL);
49861 
49862   uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
49863   switch (coro_susp_point) {
49864     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
49865 
49866     while (true) {
49867       {
49868         wuffs_base__status t_0 = wuffs_netpbm__decoder__do_decode_image_config(self, a_dst, a_src);
49869         v_status = t_0;
49870       }
49871       if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
49872         status = wuffs_base__make_status(wuffs_netpbm__error__truncated_input);
49873         goto exit;
49874       }
49875       status = v_status;
49876       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
49877     }
49878 
49879     ok:
49880     self->private_impl.p_decode_image_config[0] = 0;
49881     goto exit;
49882   }
49883 
49884   goto suspend;
49885   suspend:
49886   self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
49887   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
49888 
49889   goto exit;
49890   exit:
49891   if (wuffs_base__status__is_error(&status)) {
49892     self->private_impl.magic = WUFFS_BASE__DISABLED;
49893   }
49894   return status;
49895 }
49896 
49897 // -------- func netpbm.decoder.do_decode_image_config
49898 
49899 WUFFS_BASE__GENERATED_C_CODE
49900 static wuffs_base__status
wuffs_netpbm__decoder__do_decode_image_config(wuffs_netpbm__decoder * self,wuffs_base__image_config * a_dst,wuffs_base__io_buffer * a_src)49901 wuffs_netpbm__decoder__do_decode_image_config(
49902     wuffs_netpbm__decoder* self,
49903     wuffs_base__image_config* a_dst,
49904     wuffs_base__io_buffer* a_src) {
49905   wuffs_base__status status = wuffs_base__make_status(NULL);
49906 
49907   uint8_t v_c = 0;
49908   uint32_t v_n = 0;
49909 
49910   const uint8_t* iop_a_src = NULL;
49911   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
49912   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
49913   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
49914   if (a_src && a_src->data.ptr) {
49915     io0_a_src = a_src->data.ptr;
49916     io1_a_src = io0_a_src + a_src->meta.ri;
49917     iop_a_src = io1_a_src;
49918     io2_a_src = io0_a_src + a_src->meta.wi;
49919   }
49920 
49921   uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config[0];
49922   switch (coro_susp_point) {
49923     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
49924 
49925     if (self->private_impl.f_call_sequence != 0u) {
49926       status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
49927       goto exit;
49928     }
49929     {
49930       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
49931       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
49932         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
49933         goto suspend;
49934       }
49935       uint8_t t_0 = *iop_a_src++;
49936       v_c = t_0;
49937     }
49938     if (v_c != 80u) {
49939       status = wuffs_base__make_status(wuffs_netpbm__error__bad_header);
49940       goto exit;
49941     }
49942     {
49943       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
49944       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
49945         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
49946         goto suspend;
49947       }
49948       uint8_t t_1 = *iop_a_src++;
49949       v_c = t_1;
49950     }
49951     if ((v_c < 49u) || (55u < v_c)) {
49952       status = wuffs_base__make_status(wuffs_netpbm__error__bad_header);
49953       goto exit;
49954     } else if (v_c == 53u) {
49955       self->private_impl.f_pixfmt = 536870920u;
49956     } else if (v_c == 54u) {
49957       self->private_impl.f_pixfmt = 2684356744u;
49958     } else {
49959       status = wuffs_base__make_status(wuffs_netpbm__error__unsupported_netpbm_file);
49960       goto exit;
49961     }
49962     {
49963       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
49964       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
49965         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
49966         goto suspend;
49967       }
49968       uint8_t t_2 = *iop_a_src++;
49969       v_c = t_2;
49970     }
49971     if (v_c != 10u) {
49972       status = wuffs_base__make_status(wuffs_netpbm__error__bad_header);
49973       goto exit;
49974     }
49975     while (true) {
49976       {
49977         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
49978         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
49979           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
49980           goto suspend;
49981         }
49982         uint8_t t_3 = *iop_a_src++;
49983         v_c = t_3;
49984       }
49985       if ((v_c == 32u) || (v_c == 9u)) {
49986         continue;
49987       } else if (v_c == 35u) {
49988         while (true) {
49989           {
49990             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
49991             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
49992               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
49993               goto suspend;
49994             }
49995             uint8_t t_4 = *iop_a_src++;
49996             v_c = t_4;
49997           }
49998           if (v_c == 10u) {
49999             break;
50000           }
50001         }
50002         continue;
50003       } else if ((v_c < 48u) || (57u < v_c)) {
50004         status = wuffs_base__make_status(wuffs_netpbm__error__bad_header);
50005         goto exit;
50006       }
50007       self->private_impl.f_width = ((uint32_t)((v_c - 48u)));
50008       break;
50009     }
50010     while (true) {
50011       {
50012         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
50013         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
50014           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
50015           goto suspend;
50016         }
50017         uint8_t t_5 = *iop_a_src++;
50018         v_c = t_5;
50019       }
50020       if ((v_c == 32u) || (v_c == 9u)) {
50021         break;
50022       } else if ((v_c < 48u) || (57u < v_c)) {
50023         status = wuffs_base__make_status(wuffs_netpbm__error__bad_header);
50024         goto exit;
50025       }
50026       v_n = ((10u * self->private_impl.f_width) + ((uint32_t)((v_c - 48u))));
50027       if (v_n > 16777215u) {
50028         status = wuffs_base__make_status(wuffs_netpbm__error__unsupported_netpbm_file);
50029         goto exit;
50030       }
50031       self->private_impl.f_width = v_n;
50032     }
50033     while (true) {
50034       {
50035         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
50036         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
50037           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
50038           goto suspend;
50039         }
50040         uint8_t t_6 = *iop_a_src++;
50041         v_c = t_6;
50042       }
50043       if ((v_c == 32u) || (v_c == 9u)) {
50044         continue;
50045       } else if (v_c == 35u) {
50046         while (true) {
50047           {
50048             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
50049             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
50050               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
50051               goto suspend;
50052             }
50053             uint8_t t_7 = *iop_a_src++;
50054             v_c = t_7;
50055           }
50056           if (v_c == 10u) {
50057             break;
50058           }
50059         }
50060         continue;
50061       } else if ((v_c < 48u) || (57u < v_c)) {
50062         status = wuffs_base__make_status(wuffs_netpbm__error__bad_header);
50063         goto exit;
50064       }
50065       self->private_impl.f_height = ((uint32_t)((v_c - 48u)));
50066       break;
50067     }
50068     while (true) {
50069       {
50070         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
50071         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
50072           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
50073           goto suspend;
50074         }
50075         uint8_t t_8 = *iop_a_src++;
50076         v_c = t_8;
50077       }
50078       if ((v_c == 32u) || (v_c == 9u) || (v_c == 13u)) {
50079         continue;
50080       } else if (v_c == 10u) {
50081         break;
50082       } else if ((v_c < 48u) || (57u < v_c)) {
50083         status = wuffs_base__make_status(wuffs_netpbm__error__bad_header);
50084         goto exit;
50085       }
50086       v_n = ((10u * self->private_impl.f_height) + ((uint32_t)((v_c - 48u))));
50087       if (v_n > 16777215u) {
50088         status = wuffs_base__make_status(wuffs_netpbm__error__unsupported_netpbm_file);
50089         goto exit;
50090       }
50091       self->private_impl.f_height = v_n;
50092     }
50093     while (true) {
50094       {
50095         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
50096         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
50097           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
50098           goto suspend;
50099         }
50100         uint8_t t_9 = *iop_a_src++;
50101         v_c = t_9;
50102       }
50103       if ((v_c == 32u) || (v_c == 9u)) {
50104         continue;
50105       } else if (v_c == 35u) {
50106         while (true) {
50107           {
50108             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
50109             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
50110               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
50111               goto suspend;
50112             }
50113             uint8_t t_10 = *iop_a_src++;
50114             v_c = t_10;
50115           }
50116           if (v_c == 10u) {
50117             break;
50118           }
50119         }
50120         continue;
50121       } else if ((v_c < 48u) || (57u < v_c)) {
50122         status = wuffs_base__make_status(wuffs_netpbm__error__bad_header);
50123         goto exit;
50124       }
50125       self->private_impl.f_max_value = ((uint32_t)((v_c - 48u)));
50126       break;
50127     }
50128     while (true) {
50129       {
50130         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
50131         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
50132           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
50133           goto suspend;
50134         }
50135         uint8_t t_11 = *iop_a_src++;
50136         v_c = t_11;
50137       }
50138       if ((v_c == 32u) || (v_c == 9u) || (v_c == 13u)) {
50139         continue;
50140       } else if (v_c == 10u) {
50141         break;
50142       } else if ((v_c < 48u) || (57u < v_c)) {
50143         status = wuffs_base__make_status(wuffs_netpbm__error__bad_header);
50144         goto exit;
50145       }
50146       v_n = ((10u * self->private_impl.f_max_value) + ((uint32_t)((v_c - 48u))));
50147       if (v_n > 16777215u) {
50148         status = wuffs_base__make_status(wuffs_netpbm__error__unsupported_netpbm_file);
50149         goto exit;
50150       }
50151       self->private_impl.f_max_value = v_n;
50152     }
50153     if (self->private_impl.f_max_value != 255u) {
50154       status = wuffs_base__make_status(wuffs_netpbm__error__unsupported_netpbm_file);
50155       goto exit;
50156     }
50157     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)));
50158     if (a_dst != NULL) {
50159       wuffs_base__image_config__set(
50160           a_dst,
50161           self->private_impl.f_pixfmt,
50162           0u,
50163           self->private_impl.f_width,
50164           self->private_impl.f_height,
50165           self->private_impl.f_frame_config_io_position,
50166           false);
50167     }
50168     self->private_impl.f_call_sequence = 32u;
50169 
50170     goto ok;
50171     ok:
50172     self->private_impl.p_do_decode_image_config[0] = 0;
50173     goto exit;
50174   }
50175 
50176   goto suspend;
50177   suspend:
50178   self->private_impl.p_do_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
50179 
50180   goto exit;
50181   exit:
50182   if (a_src && a_src->data.ptr) {
50183     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
50184   }
50185 
50186   return status;
50187 }
50188 
50189 // -------- func netpbm.decoder.decode_frame_config
50190 
50191 WUFFS_BASE__GENERATED_C_CODE
50192 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_netpbm__decoder__decode_frame_config(wuffs_netpbm__decoder * self,wuffs_base__frame_config * a_dst,wuffs_base__io_buffer * a_src)50193 wuffs_netpbm__decoder__decode_frame_config(
50194     wuffs_netpbm__decoder* self,
50195     wuffs_base__frame_config* a_dst,
50196     wuffs_base__io_buffer* a_src) {
50197   if (!self) {
50198     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
50199   }
50200   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
50201     return wuffs_base__make_status(
50202         (self->private_impl.magic == WUFFS_BASE__DISABLED)
50203         ? wuffs_base__error__disabled_by_previous_error
50204         : wuffs_base__error__initialize_not_called);
50205   }
50206   if (!a_src) {
50207     self->private_impl.magic = WUFFS_BASE__DISABLED;
50208     return wuffs_base__make_status(wuffs_base__error__bad_argument);
50209   }
50210   if ((self->private_impl.active_coroutine != 0) &&
50211       (self->private_impl.active_coroutine != 2)) {
50212     self->private_impl.magic = WUFFS_BASE__DISABLED;
50213     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
50214   }
50215   self->private_impl.active_coroutine = 0;
50216   wuffs_base__status status = wuffs_base__make_status(NULL);
50217 
50218   wuffs_base__status v_status = wuffs_base__make_status(NULL);
50219 
50220   uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
50221   switch (coro_susp_point) {
50222     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
50223 
50224     while (true) {
50225       {
50226         wuffs_base__status t_0 = wuffs_netpbm__decoder__do_decode_frame_config(self, a_dst, a_src);
50227         v_status = t_0;
50228       }
50229       if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
50230         status = wuffs_base__make_status(wuffs_netpbm__error__truncated_input);
50231         goto exit;
50232       }
50233       status = v_status;
50234       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
50235     }
50236 
50237     ok:
50238     self->private_impl.p_decode_frame_config[0] = 0;
50239     goto exit;
50240   }
50241 
50242   goto suspend;
50243   suspend:
50244   self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
50245   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
50246 
50247   goto exit;
50248   exit:
50249   if (wuffs_base__status__is_error(&status)) {
50250     self->private_impl.magic = WUFFS_BASE__DISABLED;
50251   }
50252   return status;
50253 }
50254 
50255 // -------- func netpbm.decoder.do_decode_frame_config
50256 
50257 WUFFS_BASE__GENERATED_C_CODE
50258 static wuffs_base__status
wuffs_netpbm__decoder__do_decode_frame_config(wuffs_netpbm__decoder * self,wuffs_base__frame_config * a_dst,wuffs_base__io_buffer * a_src)50259 wuffs_netpbm__decoder__do_decode_frame_config(
50260     wuffs_netpbm__decoder* self,
50261     wuffs_base__frame_config* a_dst,
50262     wuffs_base__io_buffer* a_src) {
50263   wuffs_base__status status = wuffs_base__make_status(NULL);
50264 
50265   const uint8_t* iop_a_src = NULL;
50266   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
50267   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
50268   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
50269   if (a_src && a_src->data.ptr) {
50270     io0_a_src = a_src->data.ptr;
50271     io1_a_src = io0_a_src + a_src->meta.ri;
50272     iop_a_src = io1_a_src;
50273     io2_a_src = io0_a_src + a_src->meta.wi;
50274   }
50275 
50276   uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config[0];
50277   switch (coro_susp_point) {
50278     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
50279 
50280     if (self->private_impl.f_call_sequence == 32u) {
50281     } else if (self->private_impl.f_call_sequence < 32u) {
50282       if (a_src) {
50283         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
50284       }
50285       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
50286       status = wuffs_netpbm__decoder__do_decode_image_config(self, NULL, a_src);
50287       if (a_src) {
50288         iop_a_src = a_src->data.ptr + a_src->meta.ri;
50289       }
50290       if (status.repr) {
50291         goto suspend;
50292       }
50293     } else if (self->private_impl.f_call_sequence == 40u) {
50294       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)))) {
50295         status = wuffs_base__make_status(wuffs_base__error__bad_restart);
50296         goto exit;
50297       }
50298     } else if (self->private_impl.f_call_sequence == 64u) {
50299       self->private_impl.f_call_sequence = 96u;
50300       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
50301       goto ok;
50302     } else {
50303       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
50304       goto ok;
50305     }
50306     if (a_dst != NULL) {
50307       wuffs_base__frame_config__set(
50308           a_dst,
50309           wuffs_base__utility__make_rect_ie_u32(
50310           0u,
50311           0u,
50312           self->private_impl.f_width,
50313           self->private_impl.f_height),
50314           ((wuffs_base__flicks)(0u)),
50315           0u,
50316           self->private_impl.f_frame_config_io_position,
50317           0u,
50318           false,
50319           false,
50320           0u);
50321     }
50322     self->private_impl.f_call_sequence = 64u;
50323 
50324     ok:
50325     self->private_impl.p_do_decode_frame_config[0] = 0;
50326     goto exit;
50327   }
50328 
50329   goto suspend;
50330   suspend:
50331   self->private_impl.p_do_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
50332 
50333   goto exit;
50334   exit:
50335   if (a_src && a_src->data.ptr) {
50336     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
50337   }
50338 
50339   return status;
50340 }
50341 
50342 // -------- func netpbm.decoder.decode_frame
50343 
50344 WUFFS_BASE__GENERATED_C_CODE
50345 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_netpbm__decoder__decode_frame(wuffs_netpbm__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__pixel_blend a_blend,wuffs_base__slice_u8 a_workbuf,wuffs_base__decode_frame_options * a_opts)50346 wuffs_netpbm__decoder__decode_frame(
50347     wuffs_netpbm__decoder* self,
50348     wuffs_base__pixel_buffer* a_dst,
50349     wuffs_base__io_buffer* a_src,
50350     wuffs_base__pixel_blend a_blend,
50351     wuffs_base__slice_u8 a_workbuf,
50352     wuffs_base__decode_frame_options* a_opts) {
50353   if (!self) {
50354     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
50355   }
50356   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
50357     return wuffs_base__make_status(
50358         (self->private_impl.magic == WUFFS_BASE__DISABLED)
50359         ? wuffs_base__error__disabled_by_previous_error
50360         : wuffs_base__error__initialize_not_called);
50361   }
50362   if (!a_dst || !a_src) {
50363     self->private_impl.magic = WUFFS_BASE__DISABLED;
50364     return wuffs_base__make_status(wuffs_base__error__bad_argument);
50365   }
50366   if ((self->private_impl.active_coroutine != 0) &&
50367       (self->private_impl.active_coroutine != 3)) {
50368     self->private_impl.magic = WUFFS_BASE__DISABLED;
50369     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
50370   }
50371   self->private_impl.active_coroutine = 0;
50372   wuffs_base__status status = wuffs_base__make_status(NULL);
50373 
50374   wuffs_base__status v_status = wuffs_base__make_status(NULL);
50375 
50376   uint32_t coro_susp_point = self->private_impl.p_decode_frame[0];
50377   switch (coro_susp_point) {
50378     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
50379 
50380     while (true) {
50381       {
50382         wuffs_base__status t_0 = wuffs_netpbm__decoder__do_decode_frame(self,
50383             a_dst,
50384             a_src,
50385             a_blend,
50386             a_workbuf,
50387             a_opts);
50388         v_status = t_0;
50389       }
50390       if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
50391         status = wuffs_base__make_status(wuffs_netpbm__error__truncated_input);
50392         goto exit;
50393       }
50394       status = v_status;
50395       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
50396     }
50397 
50398     ok:
50399     self->private_impl.p_decode_frame[0] = 0;
50400     goto exit;
50401   }
50402 
50403   goto suspend;
50404   suspend:
50405   self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
50406   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
50407 
50408   goto exit;
50409   exit:
50410   if (wuffs_base__status__is_error(&status)) {
50411     self->private_impl.magic = WUFFS_BASE__DISABLED;
50412   }
50413   return status;
50414 }
50415 
50416 // -------- func netpbm.decoder.do_decode_frame
50417 
50418 WUFFS_BASE__GENERATED_C_CODE
50419 static wuffs_base__status
wuffs_netpbm__decoder__do_decode_frame(wuffs_netpbm__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__pixel_blend a_blend,wuffs_base__slice_u8 a_workbuf,wuffs_base__decode_frame_options * a_opts)50420 wuffs_netpbm__decoder__do_decode_frame(
50421     wuffs_netpbm__decoder* self,
50422     wuffs_base__pixel_buffer* a_dst,
50423     wuffs_base__io_buffer* a_src,
50424     wuffs_base__pixel_blend a_blend,
50425     wuffs_base__slice_u8 a_workbuf,
50426     wuffs_base__decode_frame_options* a_opts) {
50427   wuffs_base__status status = wuffs_base__make_status(NULL);
50428 
50429   wuffs_base__status v_status = wuffs_base__make_status(NULL);
50430 
50431   uint32_t coro_susp_point = self->private_impl.p_do_decode_frame[0];
50432   switch (coro_susp_point) {
50433     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
50434 
50435     if (self->private_impl.f_call_sequence == 64u) {
50436     } else if (self->private_impl.f_call_sequence < 64u) {
50437       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
50438       status = wuffs_netpbm__decoder__do_decode_frame_config(self, NULL, a_src);
50439       if (status.repr) {
50440         goto suspend;
50441       }
50442     } else {
50443       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
50444       goto ok;
50445     }
50446     self->private_impl.f_dst_x = 0u;
50447     self->private_impl.f_dst_y = 0u;
50448     v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
50449         wuffs_base__pixel_buffer__pixel_format(a_dst),
50450         wuffs_base__pixel_buffer__palette(a_dst),
50451         wuffs_base__utility__make_pixel_format(self->private_impl.f_pixfmt),
50452         wuffs_base__utility__empty_slice_u8(),
50453         a_blend);
50454     if ( ! wuffs_base__status__is_ok(&v_status)) {
50455       status = v_status;
50456       if (wuffs_base__status__is_error(&status)) {
50457         goto exit;
50458       } else if (wuffs_base__status__is_suspension(&status)) {
50459         status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
50460         goto exit;
50461       }
50462       goto ok;
50463     }
50464     while (true) {
50465       v_status = wuffs_netpbm__decoder__swizzle(self, a_dst, a_src);
50466       if (wuffs_base__status__is_ok(&v_status)) {
50467         break;
50468       } else if (v_status.repr != wuffs_netpbm__note__internal_note_short_read) {
50469         status = v_status;
50470         if (wuffs_base__status__is_error(&status)) {
50471           goto exit;
50472         } else if (wuffs_base__status__is_suspension(&status)) {
50473           status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
50474           goto exit;
50475         }
50476         goto ok;
50477       }
50478       status = wuffs_base__make_status(wuffs_base__suspension__short_read);
50479       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
50480     }
50481     self->private_impl.f_call_sequence = 96u;
50482 
50483     ok:
50484     self->private_impl.p_do_decode_frame[0] = 0;
50485     goto exit;
50486   }
50487 
50488   goto suspend;
50489   suspend:
50490   self->private_impl.p_do_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
50491 
50492   goto exit;
50493   exit:
50494   return status;
50495 }
50496 
50497 // -------- func netpbm.decoder.swizzle
50498 
50499 WUFFS_BASE__GENERATED_C_CODE
50500 static wuffs_base__status
wuffs_netpbm__decoder__swizzle(wuffs_netpbm__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src)50501 wuffs_netpbm__decoder__swizzle(
50502     wuffs_netpbm__decoder* self,
50503     wuffs_base__pixel_buffer* a_dst,
50504     wuffs_base__io_buffer* a_src) {
50505   wuffs_base__status status = wuffs_base__make_status(NULL);
50506 
50507   wuffs_base__pixel_format v_dst_pixfmt = {0};
50508   uint32_t v_dst_bits_per_pixel = 0;
50509   uint32_t v_dst_bytes_per_pixel = 0;
50510   uint64_t v_dst_bytes_per_row = 0;
50511   uint32_t v_src_bytes_per_pixel = 0;
50512   wuffs_base__table_u8 v_tab = {0};
50513   wuffs_base__slice_u8 v_dst = {0};
50514   uint64_t v_i = 0;
50515   uint64_t v_j = 0;
50516   uint64_t v_n = 0;
50517 
50518   const uint8_t* iop_a_src = NULL;
50519   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
50520   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
50521   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
50522   if (a_src && a_src->data.ptr) {
50523     io0_a_src = a_src->data.ptr;
50524     io1_a_src = io0_a_src + a_src->meta.ri;
50525     iop_a_src = io1_a_src;
50526     io2_a_src = io0_a_src + a_src->meta.wi;
50527   }
50528 
50529   v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
50530   v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
50531   if ((v_dst_bits_per_pixel & 7u) != 0u) {
50532     status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
50533     goto exit;
50534   }
50535   v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u);
50536   v_dst_bytes_per_row = ((uint64_t)((self->private_impl.f_width * v_dst_bytes_per_pixel)));
50537   v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
50538   while (true) {
50539     if (self->private_impl.f_dst_x == self->private_impl.f_width) {
50540       self->private_impl.f_dst_x = 0u;
50541       self->private_impl.f_dst_y += 1u;
50542       if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
50543         break;
50544       }
50545     }
50546     v_dst = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
50547     if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) {
50548       v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row);
50549     }
50550     v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_dst_bytes_per_pixel)));
50551     if (v_i >= ((uint64_t)(v_dst.len))) {
50552       v_src_bytes_per_pixel = 1u;
50553       if (self->private_impl.f_pixfmt == 2684356744u) {
50554         v_src_bytes_per_pixel = 3u;
50555       }
50556       v_n = (((uint64_t)(io2_a_src - iop_a_src)) / ((uint64_t)(v_src_bytes_per_pixel)));
50557       v_n = wuffs_base__u64__min(v_n, ((uint64_t)(((uint32_t)(self->private_impl.f_width - self->private_impl.f_dst_x)))));
50558       v_j = v_n;
50559       while (v_j >= 8u) {
50560         if (((uint64_t)(io2_a_src - iop_a_src)) >= ((uint64_t)((v_src_bytes_per_pixel * 8u)))) {
50561           iop_a_src += (v_src_bytes_per_pixel * 8u);
50562         }
50563         v_j -= 8u;
50564       }
50565       while (v_j > 0u) {
50566         if (((uint64_t)(io2_a_src - iop_a_src)) >= ((uint64_t)((v_src_bytes_per_pixel * 1u)))) {
50567           iop_a_src += (v_src_bytes_per_pixel * 1u);
50568         }
50569         v_j -= 1u;
50570       }
50571     } else {
50572       v_n = wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(
50573           &self->private_impl.f_swizzler,
50574           wuffs_base__slice_u8__subslice_i(v_dst, v_i),
50575           wuffs_base__pixel_buffer__palette(a_dst),
50576           &iop_a_src,
50577           io2_a_src);
50578     }
50579     if (v_n == 0u) {
50580       status = wuffs_base__make_status(wuffs_netpbm__note__internal_note_short_read);
50581       goto ok;
50582     }
50583     wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n)));
50584   }
50585   status = wuffs_base__make_status(NULL);
50586   goto ok;
50587 
50588   ok:
50589   goto exit;
50590   exit:
50591   if (a_src && a_src->data.ptr) {
50592     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
50593   }
50594 
50595   return status;
50596 }
50597 
50598 // -------- func netpbm.decoder.frame_dirty_rect
50599 
50600 WUFFS_BASE__GENERATED_C_CODE
50601 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
wuffs_netpbm__decoder__frame_dirty_rect(const wuffs_netpbm__decoder * self)50602 wuffs_netpbm__decoder__frame_dirty_rect(
50603     const wuffs_netpbm__decoder* self) {
50604   if (!self) {
50605     return wuffs_base__utility__empty_rect_ie_u32();
50606   }
50607   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
50608       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
50609     return wuffs_base__utility__empty_rect_ie_u32();
50610   }
50611 
50612   return wuffs_base__utility__make_rect_ie_u32(
50613       0u,
50614       0u,
50615       self->private_impl.f_width,
50616       self->private_impl.f_height);
50617 }
50618 
50619 // -------- func netpbm.decoder.num_animation_loops
50620 
50621 WUFFS_BASE__GENERATED_C_CODE
50622 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_netpbm__decoder__num_animation_loops(const wuffs_netpbm__decoder * self)50623 wuffs_netpbm__decoder__num_animation_loops(
50624     const wuffs_netpbm__decoder* self) {
50625   if (!self) {
50626     return 0;
50627   }
50628   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
50629       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
50630     return 0;
50631   }
50632 
50633   return 0u;
50634 }
50635 
50636 // -------- func netpbm.decoder.num_decoded_frame_configs
50637 
50638 WUFFS_BASE__GENERATED_C_CODE
50639 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_netpbm__decoder__num_decoded_frame_configs(const wuffs_netpbm__decoder * self)50640 wuffs_netpbm__decoder__num_decoded_frame_configs(
50641     const wuffs_netpbm__decoder* self) {
50642   if (!self) {
50643     return 0;
50644   }
50645   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
50646       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
50647     return 0;
50648   }
50649 
50650   if (self->private_impl.f_call_sequence > 32u) {
50651     return 1u;
50652   }
50653   return 0u;
50654 }
50655 
50656 // -------- func netpbm.decoder.num_decoded_frames
50657 
50658 WUFFS_BASE__GENERATED_C_CODE
50659 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_netpbm__decoder__num_decoded_frames(const wuffs_netpbm__decoder * self)50660 wuffs_netpbm__decoder__num_decoded_frames(
50661     const wuffs_netpbm__decoder* self) {
50662   if (!self) {
50663     return 0;
50664   }
50665   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
50666       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
50667     return 0;
50668   }
50669 
50670   if (self->private_impl.f_call_sequence > 64u) {
50671     return 1u;
50672   }
50673   return 0u;
50674 }
50675 
50676 // -------- func netpbm.decoder.restart_frame
50677 
50678 WUFFS_BASE__GENERATED_C_CODE
50679 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_netpbm__decoder__restart_frame(wuffs_netpbm__decoder * self,uint64_t a_index,uint64_t a_io_position)50680 wuffs_netpbm__decoder__restart_frame(
50681     wuffs_netpbm__decoder* self,
50682     uint64_t a_index,
50683     uint64_t a_io_position) {
50684   if (!self) {
50685     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
50686   }
50687   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
50688     return wuffs_base__make_status(
50689         (self->private_impl.magic == WUFFS_BASE__DISABLED)
50690         ? wuffs_base__error__disabled_by_previous_error
50691         : wuffs_base__error__initialize_not_called);
50692   }
50693 
50694   if (self->private_impl.f_call_sequence < 32u) {
50695     return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
50696   }
50697   if ((a_index != 0u) || (a_io_position != self->private_impl.f_frame_config_io_position)) {
50698     return wuffs_base__make_status(wuffs_base__error__bad_argument);
50699   }
50700   self->private_impl.f_call_sequence = 40u;
50701   return wuffs_base__make_status(NULL);
50702 }
50703 
50704 // -------- func netpbm.decoder.set_report_metadata
50705 
50706 WUFFS_BASE__GENERATED_C_CODE
50707 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_netpbm__decoder__set_report_metadata(wuffs_netpbm__decoder * self,uint32_t a_fourcc,bool a_report)50708 wuffs_netpbm__decoder__set_report_metadata(
50709     wuffs_netpbm__decoder* self,
50710     uint32_t a_fourcc,
50711     bool a_report) {
50712   return wuffs_base__make_empty_struct();
50713 }
50714 
50715 // -------- func netpbm.decoder.tell_me_more
50716 
50717 WUFFS_BASE__GENERATED_C_CODE
50718 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_netpbm__decoder__tell_me_more(wuffs_netpbm__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__more_information * a_minfo,wuffs_base__io_buffer * a_src)50719 wuffs_netpbm__decoder__tell_me_more(
50720     wuffs_netpbm__decoder* self,
50721     wuffs_base__io_buffer* a_dst,
50722     wuffs_base__more_information* a_minfo,
50723     wuffs_base__io_buffer* a_src) {
50724   if (!self) {
50725     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
50726   }
50727   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
50728     return wuffs_base__make_status(
50729         (self->private_impl.magic == WUFFS_BASE__DISABLED)
50730         ? wuffs_base__error__disabled_by_previous_error
50731         : wuffs_base__error__initialize_not_called);
50732   }
50733   if (!a_dst || !a_src) {
50734     self->private_impl.magic = WUFFS_BASE__DISABLED;
50735     return wuffs_base__make_status(wuffs_base__error__bad_argument);
50736   }
50737   if ((self->private_impl.active_coroutine != 0) &&
50738       (self->private_impl.active_coroutine != 4)) {
50739     self->private_impl.magic = WUFFS_BASE__DISABLED;
50740     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
50741   }
50742   self->private_impl.active_coroutine = 0;
50743   wuffs_base__status status = wuffs_base__make_status(NULL);
50744 
50745   status = wuffs_base__make_status(wuffs_base__error__no_more_information);
50746   goto exit;
50747 
50748   goto ok;
50749   ok:
50750   goto exit;
50751   exit:
50752   if (wuffs_base__status__is_error(&status)) {
50753     self->private_impl.magic = WUFFS_BASE__DISABLED;
50754   }
50755   return status;
50756 }
50757 
50758 // -------- func netpbm.decoder.history_retain_length
50759 
50760 WUFFS_BASE__GENERATED_C_CODE
50761 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_netpbm__decoder__history_retain_length(const wuffs_netpbm__decoder * self)50762 wuffs_netpbm__decoder__history_retain_length(
50763     const wuffs_netpbm__decoder* self) {
50764   if (!self) {
50765     return 0;
50766   }
50767   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
50768       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
50769     return 0;
50770   }
50771 
50772   return 0u;
50773 }
50774 
50775 // -------- func netpbm.decoder.workbuf_len
50776 
50777 WUFFS_BASE__GENERATED_C_CODE
50778 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_netpbm__decoder__workbuf_len(const wuffs_netpbm__decoder * self)50779 wuffs_netpbm__decoder__workbuf_len(
50780     const wuffs_netpbm__decoder* self) {
50781   if (!self) {
50782     return wuffs_base__utility__empty_range_ii_u64();
50783   }
50784   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
50785       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
50786     return wuffs_base__utility__empty_range_ii_u64();
50787   }
50788 
50789   return wuffs_base__utility__make_range_ii_u64(0u, 0u);
50790 }
50791 
50792 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NETPBM)
50793 
50794 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NIE)
50795 
50796 // ---------------- Status Codes Implementations
50797 
50798 const char wuffs_nie__error__bad_header[] = "#nie: bad header";
50799 const char wuffs_nie__error__truncated_input[] = "#nie: truncated input";
50800 const char wuffs_nie__error__unsupported_nie_file[] = "#nie: unsupported NIE file";
50801 const char wuffs_nie__note__internal_note_short_read[] = "@nie: internal note: short read";
50802 
50803 // ---------------- Private Consts
50804 
50805 // ---------------- Private Initializer Prototypes
50806 
50807 // ---------------- Private Function Prototypes
50808 
50809 WUFFS_BASE__GENERATED_C_CODE
50810 static wuffs_base__status
50811 wuffs_nie__decoder__do_decode_image_config(
50812     wuffs_nie__decoder* self,
50813     wuffs_base__image_config* a_dst,
50814     wuffs_base__io_buffer* a_src);
50815 
50816 WUFFS_BASE__GENERATED_C_CODE
50817 static wuffs_base__status
50818 wuffs_nie__decoder__do_decode_frame_config(
50819     wuffs_nie__decoder* self,
50820     wuffs_base__frame_config* a_dst,
50821     wuffs_base__io_buffer* a_src);
50822 
50823 WUFFS_BASE__GENERATED_C_CODE
50824 static wuffs_base__status
50825 wuffs_nie__decoder__do_decode_frame(
50826     wuffs_nie__decoder* self,
50827     wuffs_base__pixel_buffer* a_dst,
50828     wuffs_base__io_buffer* a_src,
50829     wuffs_base__pixel_blend a_blend,
50830     wuffs_base__slice_u8 a_workbuf,
50831     wuffs_base__decode_frame_options* a_opts);
50832 
50833 WUFFS_BASE__GENERATED_C_CODE
50834 static wuffs_base__status
50835 wuffs_nie__decoder__swizzle(
50836     wuffs_nie__decoder* self,
50837     wuffs_base__pixel_buffer* a_dst,
50838     wuffs_base__io_buffer* a_src);
50839 
50840 // ---------------- VTables
50841 
50842 const wuffs_base__image_decoder__func_ptrs
50843 wuffs_nie__decoder__func_ptrs_for__wuffs_base__image_decoder = {
50844   (wuffs_base__status(*)(void*,
50845       wuffs_base__pixel_buffer*,
50846       wuffs_base__io_buffer*,
50847       wuffs_base__pixel_blend,
50848       wuffs_base__slice_u8,
50849       wuffs_base__decode_frame_options*))(&wuffs_nie__decoder__decode_frame),
50850   (wuffs_base__status(*)(void*,
50851       wuffs_base__frame_config*,
50852       wuffs_base__io_buffer*))(&wuffs_nie__decoder__decode_frame_config),
50853   (wuffs_base__status(*)(void*,
50854       wuffs_base__image_config*,
50855       wuffs_base__io_buffer*))(&wuffs_nie__decoder__decode_image_config),
50856   (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_nie__decoder__frame_dirty_rect),
50857   (uint64_t(*)(const void*,
50858       uint32_t))(&wuffs_nie__decoder__get_quirk),
50859   (uint64_t(*)(const void*))(&wuffs_nie__decoder__history_retain_length),
50860   (uint32_t(*)(const void*))(&wuffs_nie__decoder__num_animation_loops),
50861   (uint64_t(*)(const void*))(&wuffs_nie__decoder__num_decoded_frame_configs),
50862   (uint64_t(*)(const void*))(&wuffs_nie__decoder__num_decoded_frames),
50863   (wuffs_base__status(*)(void*,
50864       uint64_t,
50865       uint64_t))(&wuffs_nie__decoder__restart_frame),
50866   (wuffs_base__status(*)(void*,
50867       uint32_t,
50868       uint64_t))(&wuffs_nie__decoder__set_quirk),
50869   (wuffs_base__empty_struct(*)(void*,
50870       uint32_t,
50871       bool))(&wuffs_nie__decoder__set_report_metadata),
50872   (wuffs_base__status(*)(void*,
50873       wuffs_base__io_buffer*,
50874       wuffs_base__more_information*,
50875       wuffs_base__io_buffer*))(&wuffs_nie__decoder__tell_me_more),
50876   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_nie__decoder__workbuf_len),
50877 };
50878 
50879 // ---------------- Initializer Implementations
50880 
50881 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
wuffs_nie__decoder__initialize(wuffs_nie__decoder * self,size_t sizeof_star_self,uint64_t wuffs_version,uint32_t options)50882 wuffs_nie__decoder__initialize(
50883     wuffs_nie__decoder* self,
50884     size_t sizeof_star_self,
50885     uint64_t wuffs_version,
50886     uint32_t options){
50887   if (!self) {
50888     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
50889   }
50890   if (sizeof(*self) != sizeof_star_self) {
50891     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
50892   }
50893   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
50894       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
50895     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
50896   }
50897 
50898   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
50899     // The whole point of this if-check is to detect an uninitialized *self.
50900     // We disable the warning on GCC. Clang-5.0 does not have this warning.
50901 #if !defined(__clang__) && defined(__GNUC__)
50902 #pragma GCC diagnostic push
50903 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
50904 #endif
50905     if (self->private_impl.magic != 0) {
50906       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
50907     }
50908 #if !defined(__clang__) && defined(__GNUC__)
50909 #pragma GCC diagnostic pop
50910 #endif
50911   } else {
50912     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
50913       memset(self, 0, sizeof(*self));
50914       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
50915     } else {
50916       memset(&(self->private_impl), 0, sizeof(self->private_impl));
50917     }
50918   }
50919 
50920   self->private_impl.magic = WUFFS_BASE__MAGIC;
50921   self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
50922       wuffs_base__image_decoder__vtable_name;
50923   self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
50924       (const void*)(&wuffs_nie__decoder__func_ptrs_for__wuffs_base__image_decoder);
50925   return wuffs_base__make_status(NULL);
50926 }
50927 
50928 wuffs_nie__decoder*
wuffs_nie__decoder__alloc(void)50929 wuffs_nie__decoder__alloc(void) {
50930   wuffs_nie__decoder* x =
50931       (wuffs_nie__decoder*)(calloc(sizeof(wuffs_nie__decoder), 1));
50932   if (!x) {
50933     return NULL;
50934   }
50935   if (wuffs_nie__decoder__initialize(
50936       x, sizeof(wuffs_nie__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
50937     free(x);
50938     return NULL;
50939   }
50940   return x;
50941 }
50942 
50943 size_t
sizeof__wuffs_nie__decoder(void)50944 sizeof__wuffs_nie__decoder(void) {
50945   return sizeof(wuffs_nie__decoder);
50946 }
50947 
50948 // ---------------- Function Implementations
50949 
50950 // -------- func nie.decoder.get_quirk
50951 
50952 WUFFS_BASE__GENERATED_C_CODE
50953 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_nie__decoder__get_quirk(const wuffs_nie__decoder * self,uint32_t a_key)50954 wuffs_nie__decoder__get_quirk(
50955     const wuffs_nie__decoder* self,
50956     uint32_t a_key) {
50957   if (!self) {
50958     return 0;
50959   }
50960   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
50961       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
50962     return 0;
50963   }
50964 
50965   return 0u;
50966 }
50967 
50968 // -------- func nie.decoder.set_quirk
50969 
50970 WUFFS_BASE__GENERATED_C_CODE
50971 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_nie__decoder__set_quirk(wuffs_nie__decoder * self,uint32_t a_key,uint64_t a_value)50972 wuffs_nie__decoder__set_quirk(
50973     wuffs_nie__decoder* self,
50974     uint32_t a_key,
50975     uint64_t a_value) {
50976   if (!self) {
50977     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
50978   }
50979   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
50980     return wuffs_base__make_status(
50981         (self->private_impl.magic == WUFFS_BASE__DISABLED)
50982         ? wuffs_base__error__disabled_by_previous_error
50983         : wuffs_base__error__initialize_not_called);
50984   }
50985 
50986   return wuffs_base__make_status(wuffs_base__error__unsupported_option);
50987 }
50988 
50989 // -------- func nie.decoder.decode_image_config
50990 
50991 WUFFS_BASE__GENERATED_C_CODE
50992 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_nie__decoder__decode_image_config(wuffs_nie__decoder * self,wuffs_base__image_config * a_dst,wuffs_base__io_buffer * a_src)50993 wuffs_nie__decoder__decode_image_config(
50994     wuffs_nie__decoder* self,
50995     wuffs_base__image_config* a_dst,
50996     wuffs_base__io_buffer* a_src) {
50997   if (!self) {
50998     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
50999   }
51000   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
51001     return wuffs_base__make_status(
51002         (self->private_impl.magic == WUFFS_BASE__DISABLED)
51003         ? wuffs_base__error__disabled_by_previous_error
51004         : wuffs_base__error__initialize_not_called);
51005   }
51006   if (!a_src) {
51007     self->private_impl.magic = WUFFS_BASE__DISABLED;
51008     return wuffs_base__make_status(wuffs_base__error__bad_argument);
51009   }
51010   if ((self->private_impl.active_coroutine != 0) &&
51011       (self->private_impl.active_coroutine != 1)) {
51012     self->private_impl.magic = WUFFS_BASE__DISABLED;
51013     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
51014   }
51015   self->private_impl.active_coroutine = 0;
51016   wuffs_base__status status = wuffs_base__make_status(NULL);
51017 
51018   wuffs_base__status v_status = wuffs_base__make_status(NULL);
51019 
51020   uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
51021   switch (coro_susp_point) {
51022     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
51023 
51024     while (true) {
51025       {
51026         wuffs_base__status t_0 = wuffs_nie__decoder__do_decode_image_config(self, a_dst, a_src);
51027         v_status = t_0;
51028       }
51029       if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
51030         status = wuffs_base__make_status(wuffs_nie__error__truncated_input);
51031         goto exit;
51032       }
51033       status = v_status;
51034       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
51035     }
51036 
51037     ok:
51038     self->private_impl.p_decode_image_config[0] = 0;
51039     goto exit;
51040   }
51041 
51042   goto suspend;
51043   suspend:
51044   self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
51045   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
51046 
51047   goto exit;
51048   exit:
51049   if (wuffs_base__status__is_error(&status)) {
51050     self->private_impl.magic = WUFFS_BASE__DISABLED;
51051   }
51052   return status;
51053 }
51054 
51055 // -------- func nie.decoder.do_decode_image_config
51056 
51057 WUFFS_BASE__GENERATED_C_CODE
51058 static wuffs_base__status
wuffs_nie__decoder__do_decode_image_config(wuffs_nie__decoder * self,wuffs_base__image_config * a_dst,wuffs_base__io_buffer * a_src)51059 wuffs_nie__decoder__do_decode_image_config(
51060     wuffs_nie__decoder* self,
51061     wuffs_base__image_config* a_dst,
51062     wuffs_base__io_buffer* a_src) {
51063   wuffs_base__status status = wuffs_base__make_status(NULL);
51064 
51065   uint32_t v_a = 0;
51066 
51067   const uint8_t* iop_a_src = NULL;
51068   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
51069   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
51070   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
51071   if (a_src && a_src->data.ptr) {
51072     io0_a_src = a_src->data.ptr;
51073     io1_a_src = io0_a_src + a_src->meta.ri;
51074     iop_a_src = io1_a_src;
51075     io2_a_src = io0_a_src + a_src->meta.wi;
51076   }
51077 
51078   uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config[0];
51079   switch (coro_susp_point) {
51080     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
51081 
51082     if (self->private_impl.f_call_sequence != 0u) {
51083       status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
51084       goto exit;
51085     }
51086     {
51087       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
51088       uint32_t t_0;
51089       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
51090         t_0 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
51091         iop_a_src += 4;
51092       } else {
51093         self->private_data.s_do_decode_image_config[0].scratch = 0;
51094         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
51095         while (true) {
51096           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
51097             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
51098             goto suspend;
51099           }
51100           uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
51101           uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
51102           *scratch <<= 8;
51103           *scratch >>= 8;
51104           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
51105           if (num_bits_0 == 24) {
51106             t_0 = ((uint32_t)(*scratch));
51107             break;
51108           }
51109           num_bits_0 += 8u;
51110           *scratch |= ((uint64_t)(num_bits_0)) << 56;
51111         }
51112       }
51113       v_a = t_0;
51114     }
51115     if (v_a != 1169146734u) {
51116       status = wuffs_base__make_status(wuffs_nie__error__bad_header);
51117       goto exit;
51118     }
51119     {
51120       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
51121       uint32_t t_1;
51122       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
51123         t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
51124         iop_a_src += 4;
51125       } else {
51126         self->private_data.s_do_decode_image_config[0].scratch = 0;
51127         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
51128         while (true) {
51129           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
51130             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
51131             goto suspend;
51132           }
51133           uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
51134           uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
51135           *scratch <<= 8;
51136           *scratch >>= 8;
51137           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
51138           if (num_bits_1 == 24) {
51139             t_1 = ((uint32_t)(*scratch));
51140             break;
51141           }
51142           num_bits_1 += 8u;
51143           *scratch |= ((uint64_t)(num_bits_1)) << 56;
51144         }
51145       }
51146       v_a = t_1;
51147     }
51148     if (v_a == 879649535u) {
51149       self->private_impl.f_pixfmt = 2164295816u;
51150     } else if (v_a == 946758399u) {
51151       self->private_impl.f_pixfmt = 2164308923u;
51152     } else if (v_a == 879780607u) {
51153       status = wuffs_base__make_status(wuffs_nie__error__unsupported_nie_file);
51154       goto exit;
51155     } else if (v_a == 946889471u) {
51156       status = wuffs_base__make_status(wuffs_nie__error__unsupported_nie_file);
51157       goto exit;
51158     } else {
51159       status = wuffs_base__make_status(wuffs_nie__error__bad_header);
51160       goto exit;
51161     }
51162     {
51163       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
51164       uint32_t t_2;
51165       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
51166         t_2 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
51167         iop_a_src += 4;
51168       } else {
51169         self->private_data.s_do_decode_image_config[0].scratch = 0;
51170         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
51171         while (true) {
51172           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
51173             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
51174             goto suspend;
51175           }
51176           uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
51177           uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
51178           *scratch <<= 8;
51179           *scratch >>= 8;
51180           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
51181           if (num_bits_2 == 24) {
51182             t_2 = ((uint32_t)(*scratch));
51183             break;
51184           }
51185           num_bits_2 += 8u;
51186           *scratch |= ((uint64_t)(num_bits_2)) << 56;
51187         }
51188       }
51189       v_a = t_2;
51190     }
51191     if (v_a > 2147483647u) {
51192       status = wuffs_base__make_status(wuffs_nie__error__bad_header);
51193       goto exit;
51194     } else if (v_a > 16777215u) {
51195       status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension);
51196       goto exit;
51197     }
51198     self->private_impl.f_width = v_a;
51199     {
51200       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
51201       uint32_t t_3;
51202       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
51203         t_3 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
51204         iop_a_src += 4;
51205       } else {
51206         self->private_data.s_do_decode_image_config[0].scratch = 0;
51207         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
51208         while (true) {
51209           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
51210             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
51211             goto suspend;
51212           }
51213           uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
51214           uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56));
51215           *scratch <<= 8;
51216           *scratch >>= 8;
51217           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3;
51218           if (num_bits_3 == 24) {
51219             t_3 = ((uint32_t)(*scratch));
51220             break;
51221           }
51222           num_bits_3 += 8u;
51223           *scratch |= ((uint64_t)(num_bits_3)) << 56;
51224         }
51225       }
51226       v_a = t_3;
51227     }
51228     if (v_a > 2147483647u) {
51229       status = wuffs_base__make_status(wuffs_nie__error__bad_header);
51230       goto exit;
51231     } else if (v_a > 16777215u) {
51232       status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension);
51233       goto exit;
51234     }
51235     self->private_impl.f_height = v_a;
51236     if (a_dst != NULL) {
51237       wuffs_base__image_config__set(
51238           a_dst,
51239           self->private_impl.f_pixfmt,
51240           0u,
51241           self->private_impl.f_width,
51242           self->private_impl.f_height,
51243           16u,
51244           false);
51245     }
51246     self->private_impl.f_call_sequence = 32u;
51247 
51248     goto ok;
51249     ok:
51250     self->private_impl.p_do_decode_image_config[0] = 0;
51251     goto exit;
51252   }
51253 
51254   goto suspend;
51255   suspend:
51256   self->private_impl.p_do_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
51257 
51258   goto exit;
51259   exit:
51260   if (a_src && a_src->data.ptr) {
51261     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
51262   }
51263 
51264   return status;
51265 }
51266 
51267 // -------- func nie.decoder.decode_frame_config
51268 
51269 WUFFS_BASE__GENERATED_C_CODE
51270 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_nie__decoder__decode_frame_config(wuffs_nie__decoder * self,wuffs_base__frame_config * a_dst,wuffs_base__io_buffer * a_src)51271 wuffs_nie__decoder__decode_frame_config(
51272     wuffs_nie__decoder* self,
51273     wuffs_base__frame_config* a_dst,
51274     wuffs_base__io_buffer* a_src) {
51275   if (!self) {
51276     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
51277   }
51278   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
51279     return wuffs_base__make_status(
51280         (self->private_impl.magic == WUFFS_BASE__DISABLED)
51281         ? wuffs_base__error__disabled_by_previous_error
51282         : wuffs_base__error__initialize_not_called);
51283   }
51284   if (!a_src) {
51285     self->private_impl.magic = WUFFS_BASE__DISABLED;
51286     return wuffs_base__make_status(wuffs_base__error__bad_argument);
51287   }
51288   if ((self->private_impl.active_coroutine != 0) &&
51289       (self->private_impl.active_coroutine != 2)) {
51290     self->private_impl.magic = WUFFS_BASE__DISABLED;
51291     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
51292   }
51293   self->private_impl.active_coroutine = 0;
51294   wuffs_base__status status = wuffs_base__make_status(NULL);
51295 
51296   wuffs_base__status v_status = wuffs_base__make_status(NULL);
51297 
51298   uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
51299   switch (coro_susp_point) {
51300     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
51301 
51302     while (true) {
51303       {
51304         wuffs_base__status t_0 = wuffs_nie__decoder__do_decode_frame_config(self, a_dst, a_src);
51305         v_status = t_0;
51306       }
51307       if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
51308         status = wuffs_base__make_status(wuffs_nie__error__truncated_input);
51309         goto exit;
51310       }
51311       status = v_status;
51312       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
51313     }
51314 
51315     ok:
51316     self->private_impl.p_decode_frame_config[0] = 0;
51317     goto exit;
51318   }
51319 
51320   goto suspend;
51321   suspend:
51322   self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
51323   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
51324 
51325   goto exit;
51326   exit:
51327   if (wuffs_base__status__is_error(&status)) {
51328     self->private_impl.magic = WUFFS_BASE__DISABLED;
51329   }
51330   return status;
51331 }
51332 
51333 // -------- func nie.decoder.do_decode_frame_config
51334 
51335 WUFFS_BASE__GENERATED_C_CODE
51336 static wuffs_base__status
wuffs_nie__decoder__do_decode_frame_config(wuffs_nie__decoder * self,wuffs_base__frame_config * a_dst,wuffs_base__io_buffer * a_src)51337 wuffs_nie__decoder__do_decode_frame_config(
51338     wuffs_nie__decoder* self,
51339     wuffs_base__frame_config* a_dst,
51340     wuffs_base__io_buffer* a_src) {
51341   wuffs_base__status status = wuffs_base__make_status(NULL);
51342 
51343   const uint8_t* iop_a_src = NULL;
51344   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
51345   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
51346   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
51347   if (a_src && a_src->data.ptr) {
51348     io0_a_src = a_src->data.ptr;
51349     io1_a_src = io0_a_src + a_src->meta.ri;
51350     iop_a_src = io1_a_src;
51351     io2_a_src = io0_a_src + a_src->meta.wi;
51352   }
51353 
51354   uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config[0];
51355   switch (coro_susp_point) {
51356     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
51357 
51358     if (self->private_impl.f_call_sequence == 32u) {
51359     } else if (self->private_impl.f_call_sequence < 32u) {
51360       if (a_src) {
51361         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
51362       }
51363       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
51364       status = wuffs_nie__decoder__do_decode_image_config(self, NULL, a_src);
51365       if (a_src) {
51366         iop_a_src = a_src->data.ptr + a_src->meta.ri;
51367       }
51368       if (status.repr) {
51369         goto suspend;
51370       }
51371     } else if (self->private_impl.f_call_sequence == 40u) {
51372       if (16u != wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)))) {
51373         status = wuffs_base__make_status(wuffs_base__error__bad_restart);
51374         goto exit;
51375       }
51376     } else if (self->private_impl.f_call_sequence == 64u) {
51377       self->private_impl.f_call_sequence = 96u;
51378       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
51379       goto ok;
51380     } else {
51381       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
51382       goto ok;
51383     }
51384     if (a_dst != NULL) {
51385       wuffs_base__frame_config__set(
51386           a_dst,
51387           wuffs_base__utility__make_rect_ie_u32(
51388           0u,
51389           0u,
51390           self->private_impl.f_width,
51391           self->private_impl.f_height),
51392           ((wuffs_base__flicks)(0u)),
51393           0u,
51394           16u,
51395           0u,
51396           false,
51397           false,
51398           0u);
51399     }
51400     self->private_impl.f_call_sequence = 64u;
51401 
51402     ok:
51403     self->private_impl.p_do_decode_frame_config[0] = 0;
51404     goto exit;
51405   }
51406 
51407   goto suspend;
51408   suspend:
51409   self->private_impl.p_do_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
51410 
51411   goto exit;
51412   exit:
51413   if (a_src && a_src->data.ptr) {
51414     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
51415   }
51416 
51417   return status;
51418 }
51419 
51420 // -------- func nie.decoder.decode_frame
51421 
51422 WUFFS_BASE__GENERATED_C_CODE
51423 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_nie__decoder__decode_frame(wuffs_nie__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__pixel_blend a_blend,wuffs_base__slice_u8 a_workbuf,wuffs_base__decode_frame_options * a_opts)51424 wuffs_nie__decoder__decode_frame(
51425     wuffs_nie__decoder* self,
51426     wuffs_base__pixel_buffer* a_dst,
51427     wuffs_base__io_buffer* a_src,
51428     wuffs_base__pixel_blend a_blend,
51429     wuffs_base__slice_u8 a_workbuf,
51430     wuffs_base__decode_frame_options* a_opts) {
51431   if (!self) {
51432     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
51433   }
51434   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
51435     return wuffs_base__make_status(
51436         (self->private_impl.magic == WUFFS_BASE__DISABLED)
51437         ? wuffs_base__error__disabled_by_previous_error
51438         : wuffs_base__error__initialize_not_called);
51439   }
51440   if (!a_dst || !a_src) {
51441     self->private_impl.magic = WUFFS_BASE__DISABLED;
51442     return wuffs_base__make_status(wuffs_base__error__bad_argument);
51443   }
51444   if ((self->private_impl.active_coroutine != 0) &&
51445       (self->private_impl.active_coroutine != 3)) {
51446     self->private_impl.magic = WUFFS_BASE__DISABLED;
51447     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
51448   }
51449   self->private_impl.active_coroutine = 0;
51450   wuffs_base__status status = wuffs_base__make_status(NULL);
51451 
51452   wuffs_base__status v_status = wuffs_base__make_status(NULL);
51453 
51454   uint32_t coro_susp_point = self->private_impl.p_decode_frame[0];
51455   switch (coro_susp_point) {
51456     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
51457 
51458     while (true) {
51459       {
51460         wuffs_base__status t_0 = wuffs_nie__decoder__do_decode_frame(self,
51461             a_dst,
51462             a_src,
51463             a_blend,
51464             a_workbuf,
51465             a_opts);
51466         v_status = t_0;
51467       }
51468       if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
51469         status = wuffs_base__make_status(wuffs_nie__error__truncated_input);
51470         goto exit;
51471       }
51472       status = v_status;
51473       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
51474     }
51475 
51476     ok:
51477     self->private_impl.p_decode_frame[0] = 0;
51478     goto exit;
51479   }
51480 
51481   goto suspend;
51482   suspend:
51483   self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
51484   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
51485 
51486   goto exit;
51487   exit:
51488   if (wuffs_base__status__is_error(&status)) {
51489     self->private_impl.magic = WUFFS_BASE__DISABLED;
51490   }
51491   return status;
51492 }
51493 
51494 // -------- func nie.decoder.do_decode_frame
51495 
51496 WUFFS_BASE__GENERATED_C_CODE
51497 static wuffs_base__status
wuffs_nie__decoder__do_decode_frame(wuffs_nie__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__pixel_blend a_blend,wuffs_base__slice_u8 a_workbuf,wuffs_base__decode_frame_options * a_opts)51498 wuffs_nie__decoder__do_decode_frame(
51499     wuffs_nie__decoder* self,
51500     wuffs_base__pixel_buffer* a_dst,
51501     wuffs_base__io_buffer* a_src,
51502     wuffs_base__pixel_blend a_blend,
51503     wuffs_base__slice_u8 a_workbuf,
51504     wuffs_base__decode_frame_options* a_opts) {
51505   wuffs_base__status status = wuffs_base__make_status(NULL);
51506 
51507   wuffs_base__status v_status = wuffs_base__make_status(NULL);
51508 
51509   uint32_t coro_susp_point = self->private_impl.p_do_decode_frame[0];
51510   switch (coro_susp_point) {
51511     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
51512 
51513     if (self->private_impl.f_call_sequence == 64u) {
51514     } else if (self->private_impl.f_call_sequence < 64u) {
51515       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
51516       status = wuffs_nie__decoder__do_decode_frame_config(self, NULL, a_src);
51517       if (status.repr) {
51518         goto suspend;
51519       }
51520     } else {
51521       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
51522       goto ok;
51523     }
51524     self->private_impl.f_dst_x = 0u;
51525     self->private_impl.f_dst_y = 0u;
51526     v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
51527         wuffs_base__pixel_buffer__pixel_format(a_dst),
51528         wuffs_base__pixel_buffer__palette(a_dst),
51529         wuffs_base__utility__make_pixel_format(self->private_impl.f_pixfmt),
51530         wuffs_base__utility__empty_slice_u8(),
51531         a_blend);
51532     if ( ! wuffs_base__status__is_ok(&v_status)) {
51533       status = v_status;
51534       if (wuffs_base__status__is_error(&status)) {
51535         goto exit;
51536       } else if (wuffs_base__status__is_suspension(&status)) {
51537         status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
51538         goto exit;
51539       }
51540       goto ok;
51541     }
51542     while (true) {
51543       v_status = wuffs_nie__decoder__swizzle(self, a_dst, a_src);
51544       if (wuffs_base__status__is_ok(&v_status)) {
51545         break;
51546       } else if (v_status.repr != wuffs_nie__note__internal_note_short_read) {
51547         status = v_status;
51548         if (wuffs_base__status__is_error(&status)) {
51549           goto exit;
51550         } else if (wuffs_base__status__is_suspension(&status)) {
51551           status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
51552           goto exit;
51553         }
51554         goto ok;
51555       }
51556       status = wuffs_base__make_status(wuffs_base__suspension__short_read);
51557       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
51558     }
51559     self->private_impl.f_call_sequence = 96u;
51560 
51561     ok:
51562     self->private_impl.p_do_decode_frame[0] = 0;
51563     goto exit;
51564   }
51565 
51566   goto suspend;
51567   suspend:
51568   self->private_impl.p_do_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
51569 
51570   goto exit;
51571   exit:
51572   return status;
51573 }
51574 
51575 // -------- func nie.decoder.swizzle
51576 
51577 WUFFS_BASE__GENERATED_C_CODE
51578 static wuffs_base__status
wuffs_nie__decoder__swizzle(wuffs_nie__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src)51579 wuffs_nie__decoder__swizzle(
51580     wuffs_nie__decoder* self,
51581     wuffs_base__pixel_buffer* a_dst,
51582     wuffs_base__io_buffer* a_src) {
51583   wuffs_base__status status = wuffs_base__make_status(NULL);
51584 
51585   wuffs_base__pixel_format v_dst_pixfmt = {0};
51586   uint32_t v_dst_bits_per_pixel = 0;
51587   uint32_t v_dst_bytes_per_pixel = 0;
51588   uint64_t v_dst_bytes_per_row = 0;
51589   uint32_t v_src_bytes_per_pixel = 0;
51590   wuffs_base__table_u8 v_tab = {0};
51591   wuffs_base__slice_u8 v_dst = {0};
51592   uint64_t v_i = 0;
51593   uint64_t v_j = 0;
51594   uint64_t v_n = 0;
51595 
51596   const uint8_t* iop_a_src = NULL;
51597   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
51598   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
51599   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
51600   if (a_src && a_src->data.ptr) {
51601     io0_a_src = a_src->data.ptr;
51602     io1_a_src = io0_a_src + a_src->meta.ri;
51603     iop_a_src = io1_a_src;
51604     io2_a_src = io0_a_src + a_src->meta.wi;
51605   }
51606 
51607   v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
51608   v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
51609   if ((v_dst_bits_per_pixel & 7u) != 0u) {
51610     status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
51611     goto exit;
51612   }
51613   v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u);
51614   v_dst_bytes_per_row = ((uint64_t)((self->private_impl.f_width * v_dst_bytes_per_pixel)));
51615   v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
51616   while (true) {
51617     if (self->private_impl.f_dst_x == self->private_impl.f_width) {
51618       self->private_impl.f_dst_x = 0u;
51619       self->private_impl.f_dst_y += 1u;
51620       if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
51621         break;
51622       }
51623     }
51624     v_dst = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
51625     if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) {
51626       v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row);
51627     }
51628     v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_dst_bytes_per_pixel)));
51629     if (v_i >= ((uint64_t)(v_dst.len))) {
51630       v_src_bytes_per_pixel = 4u;
51631       if (self->private_impl.f_pixfmt == 2164308923u) {
51632         v_src_bytes_per_pixel = 8u;
51633       }
51634       v_n = (((uint64_t)(io2_a_src - iop_a_src)) / ((uint64_t)(v_src_bytes_per_pixel)));
51635       v_n = wuffs_base__u64__min(v_n, ((uint64_t)(((uint32_t)(self->private_impl.f_width - self->private_impl.f_dst_x)))));
51636       v_j = v_n;
51637       while (v_j >= 8u) {
51638         if (((uint64_t)(io2_a_src - iop_a_src)) >= ((uint64_t)((v_src_bytes_per_pixel * 8u)))) {
51639           iop_a_src += (v_src_bytes_per_pixel * 8u);
51640         }
51641         v_j -= 8u;
51642       }
51643       while (v_j > 0u) {
51644         if (((uint64_t)(io2_a_src - iop_a_src)) >= ((uint64_t)((v_src_bytes_per_pixel * 1u)))) {
51645           iop_a_src += (v_src_bytes_per_pixel * 1u);
51646         }
51647         v_j -= 1u;
51648       }
51649     } else {
51650       v_n = wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(
51651           &self->private_impl.f_swizzler,
51652           wuffs_base__slice_u8__subslice_i(v_dst, v_i),
51653           wuffs_base__pixel_buffer__palette(a_dst),
51654           &iop_a_src,
51655           io2_a_src);
51656     }
51657     if (v_n == 0u) {
51658       status = wuffs_base__make_status(wuffs_nie__note__internal_note_short_read);
51659       goto ok;
51660     }
51661     wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n)));
51662   }
51663   status = wuffs_base__make_status(NULL);
51664   goto ok;
51665 
51666   ok:
51667   goto exit;
51668   exit:
51669   if (a_src && a_src->data.ptr) {
51670     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
51671   }
51672 
51673   return status;
51674 }
51675 
51676 // -------- func nie.decoder.frame_dirty_rect
51677 
51678 WUFFS_BASE__GENERATED_C_CODE
51679 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
wuffs_nie__decoder__frame_dirty_rect(const wuffs_nie__decoder * self)51680 wuffs_nie__decoder__frame_dirty_rect(
51681     const wuffs_nie__decoder* self) {
51682   if (!self) {
51683     return wuffs_base__utility__empty_rect_ie_u32();
51684   }
51685   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
51686       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
51687     return wuffs_base__utility__empty_rect_ie_u32();
51688   }
51689 
51690   return wuffs_base__utility__make_rect_ie_u32(
51691       0u,
51692       0u,
51693       self->private_impl.f_width,
51694       self->private_impl.f_height);
51695 }
51696 
51697 // -------- func nie.decoder.num_animation_loops
51698 
51699 WUFFS_BASE__GENERATED_C_CODE
51700 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_nie__decoder__num_animation_loops(const wuffs_nie__decoder * self)51701 wuffs_nie__decoder__num_animation_loops(
51702     const wuffs_nie__decoder* self) {
51703   if (!self) {
51704     return 0;
51705   }
51706   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
51707       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
51708     return 0;
51709   }
51710 
51711   return 0u;
51712 }
51713 
51714 // -------- func nie.decoder.num_decoded_frame_configs
51715 
51716 WUFFS_BASE__GENERATED_C_CODE
51717 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_nie__decoder__num_decoded_frame_configs(const wuffs_nie__decoder * self)51718 wuffs_nie__decoder__num_decoded_frame_configs(
51719     const wuffs_nie__decoder* self) {
51720   if (!self) {
51721     return 0;
51722   }
51723   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
51724       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
51725     return 0;
51726   }
51727 
51728   if (self->private_impl.f_call_sequence > 32u) {
51729     return 1u;
51730   }
51731   return 0u;
51732 }
51733 
51734 // -------- func nie.decoder.num_decoded_frames
51735 
51736 WUFFS_BASE__GENERATED_C_CODE
51737 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_nie__decoder__num_decoded_frames(const wuffs_nie__decoder * self)51738 wuffs_nie__decoder__num_decoded_frames(
51739     const wuffs_nie__decoder* self) {
51740   if (!self) {
51741     return 0;
51742   }
51743   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
51744       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
51745     return 0;
51746   }
51747 
51748   if (self->private_impl.f_call_sequence > 64u) {
51749     return 1u;
51750   }
51751   return 0u;
51752 }
51753 
51754 // -------- func nie.decoder.restart_frame
51755 
51756 WUFFS_BASE__GENERATED_C_CODE
51757 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_nie__decoder__restart_frame(wuffs_nie__decoder * self,uint64_t a_index,uint64_t a_io_position)51758 wuffs_nie__decoder__restart_frame(
51759     wuffs_nie__decoder* self,
51760     uint64_t a_index,
51761     uint64_t a_io_position) {
51762   if (!self) {
51763     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
51764   }
51765   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
51766     return wuffs_base__make_status(
51767         (self->private_impl.magic == WUFFS_BASE__DISABLED)
51768         ? wuffs_base__error__disabled_by_previous_error
51769         : wuffs_base__error__initialize_not_called);
51770   }
51771 
51772   if (self->private_impl.f_call_sequence < 32u) {
51773     return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
51774   }
51775   if ((a_index != 0u) || (a_io_position != 16u)) {
51776     return wuffs_base__make_status(wuffs_base__error__bad_argument);
51777   }
51778   self->private_impl.f_call_sequence = 40u;
51779   return wuffs_base__make_status(NULL);
51780 }
51781 
51782 // -------- func nie.decoder.set_report_metadata
51783 
51784 WUFFS_BASE__GENERATED_C_CODE
51785 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_nie__decoder__set_report_metadata(wuffs_nie__decoder * self,uint32_t a_fourcc,bool a_report)51786 wuffs_nie__decoder__set_report_metadata(
51787     wuffs_nie__decoder* self,
51788     uint32_t a_fourcc,
51789     bool a_report) {
51790   return wuffs_base__make_empty_struct();
51791 }
51792 
51793 // -------- func nie.decoder.tell_me_more
51794 
51795 WUFFS_BASE__GENERATED_C_CODE
51796 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_nie__decoder__tell_me_more(wuffs_nie__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__more_information * a_minfo,wuffs_base__io_buffer * a_src)51797 wuffs_nie__decoder__tell_me_more(
51798     wuffs_nie__decoder* self,
51799     wuffs_base__io_buffer* a_dst,
51800     wuffs_base__more_information* a_minfo,
51801     wuffs_base__io_buffer* a_src) {
51802   if (!self) {
51803     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
51804   }
51805   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
51806     return wuffs_base__make_status(
51807         (self->private_impl.magic == WUFFS_BASE__DISABLED)
51808         ? wuffs_base__error__disabled_by_previous_error
51809         : wuffs_base__error__initialize_not_called);
51810   }
51811   if (!a_dst || !a_src) {
51812     self->private_impl.magic = WUFFS_BASE__DISABLED;
51813     return wuffs_base__make_status(wuffs_base__error__bad_argument);
51814   }
51815   if ((self->private_impl.active_coroutine != 0) &&
51816       (self->private_impl.active_coroutine != 4)) {
51817     self->private_impl.magic = WUFFS_BASE__DISABLED;
51818     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
51819   }
51820   self->private_impl.active_coroutine = 0;
51821   wuffs_base__status status = wuffs_base__make_status(NULL);
51822 
51823   status = wuffs_base__make_status(wuffs_base__error__no_more_information);
51824   goto exit;
51825 
51826   goto ok;
51827   ok:
51828   goto exit;
51829   exit:
51830   if (wuffs_base__status__is_error(&status)) {
51831     self->private_impl.magic = WUFFS_BASE__DISABLED;
51832   }
51833   return status;
51834 }
51835 
51836 // -------- func nie.decoder.history_retain_length
51837 
51838 WUFFS_BASE__GENERATED_C_CODE
51839 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_nie__decoder__history_retain_length(const wuffs_nie__decoder * self)51840 wuffs_nie__decoder__history_retain_length(
51841     const wuffs_nie__decoder* self) {
51842   if (!self) {
51843     return 0;
51844   }
51845   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
51846       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
51847     return 0;
51848   }
51849 
51850   return 0u;
51851 }
51852 
51853 // -------- func nie.decoder.workbuf_len
51854 
51855 WUFFS_BASE__GENERATED_C_CODE
51856 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_nie__decoder__workbuf_len(const wuffs_nie__decoder * self)51857 wuffs_nie__decoder__workbuf_len(
51858     const wuffs_nie__decoder* self) {
51859   if (!self) {
51860     return wuffs_base__utility__empty_range_ii_u64();
51861   }
51862   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
51863       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
51864     return wuffs_base__utility__empty_range_ii_u64();
51865   }
51866 
51867   return wuffs_base__utility__make_range_ii_u64(0u, 0u);
51868 }
51869 
51870 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NIE)
51871 
51872 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ZLIB)
51873 
51874 // ---------------- Status Codes Implementations
51875 
51876 const char wuffs_zlib__note__dictionary_required[] = "@zlib: dictionary required";
51877 const char wuffs_zlib__error__bad_checksum[] = "#zlib: bad checksum";
51878 const char wuffs_zlib__error__bad_compression_method[] = "#zlib: bad compression method";
51879 const char wuffs_zlib__error__bad_compression_window_size[] = "#zlib: bad compression window size";
51880 const char wuffs_zlib__error__bad_parity_check[] = "#zlib: bad parity check";
51881 const char wuffs_zlib__error__incorrect_dictionary[] = "#zlib: incorrect dictionary";
51882 const char wuffs_zlib__error__truncated_input[] = "#zlib: truncated input";
51883 
51884 // ---------------- Private Consts
51885 
51886 #define WUFFS_ZLIB__QUIRKS_BASE 2113790976
51887 
51888 #define WUFFS_ZLIB__QUIRKS_COUNT 1
51889 
51890 // ---------------- Private Initializer Prototypes
51891 
51892 // ---------------- Private Function Prototypes
51893 
51894 WUFFS_BASE__GENERATED_C_CODE
51895 static wuffs_base__status
51896 wuffs_zlib__decoder__do_transform_io(
51897     wuffs_zlib__decoder* self,
51898     wuffs_base__io_buffer* a_dst,
51899     wuffs_base__io_buffer* a_src,
51900     wuffs_base__slice_u8 a_workbuf);
51901 
51902 // ---------------- VTables
51903 
51904 const wuffs_base__io_transformer__func_ptrs
51905 wuffs_zlib__decoder__func_ptrs_for__wuffs_base__io_transformer = {
51906   (uint64_t(*)(const void*,
51907       uint32_t))(&wuffs_zlib__decoder__get_quirk),
51908   (uint64_t(*)(const void*))(&wuffs_zlib__decoder__history_retain_length),
51909   (wuffs_base__status(*)(void*,
51910       uint32_t,
51911       uint64_t))(&wuffs_zlib__decoder__set_quirk),
51912   (wuffs_base__status(*)(void*,
51913       wuffs_base__io_buffer*,
51914       wuffs_base__io_buffer*,
51915       wuffs_base__slice_u8))(&wuffs_zlib__decoder__transform_io),
51916   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_zlib__decoder__workbuf_len),
51917 };
51918 
51919 // ---------------- Initializer Implementations
51920 
51921 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
wuffs_zlib__decoder__initialize(wuffs_zlib__decoder * self,size_t sizeof_star_self,uint64_t wuffs_version,uint32_t options)51922 wuffs_zlib__decoder__initialize(
51923     wuffs_zlib__decoder* self,
51924     size_t sizeof_star_self,
51925     uint64_t wuffs_version,
51926     uint32_t options){
51927   if (!self) {
51928     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
51929   }
51930   if (sizeof(*self) != sizeof_star_self) {
51931     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
51932   }
51933   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
51934       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
51935     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
51936   }
51937 
51938   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
51939     // The whole point of this if-check is to detect an uninitialized *self.
51940     // We disable the warning on GCC. Clang-5.0 does not have this warning.
51941 #if !defined(__clang__) && defined(__GNUC__)
51942 #pragma GCC diagnostic push
51943 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
51944 #endif
51945     if (self->private_impl.magic != 0) {
51946       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
51947     }
51948 #if !defined(__clang__) && defined(__GNUC__)
51949 #pragma GCC diagnostic pop
51950 #endif
51951   } else {
51952     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
51953       memset(self, 0, sizeof(*self));
51954       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
51955     } else {
51956       memset(&(self->private_impl), 0, sizeof(self->private_impl));
51957     }
51958   }
51959 
51960   {
51961     wuffs_base__status z = wuffs_adler32__hasher__initialize(
51962         &self->private_data.f_checksum, sizeof(self->private_data.f_checksum), WUFFS_VERSION, options);
51963     if (z.repr) {
51964       return z;
51965     }
51966   }
51967   {
51968     wuffs_base__status z = wuffs_adler32__hasher__initialize(
51969         &self->private_data.f_dict_id_hasher, sizeof(self->private_data.f_dict_id_hasher), WUFFS_VERSION, options);
51970     if (z.repr) {
51971       return z;
51972     }
51973   }
51974   {
51975     wuffs_base__status z = wuffs_deflate__decoder__initialize(
51976         &self->private_data.f_flate, sizeof(self->private_data.f_flate), WUFFS_VERSION, options);
51977     if (z.repr) {
51978       return z;
51979     }
51980   }
51981   self->private_impl.magic = WUFFS_BASE__MAGIC;
51982   self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name =
51983       wuffs_base__io_transformer__vtable_name;
51984   self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers =
51985       (const void*)(&wuffs_zlib__decoder__func_ptrs_for__wuffs_base__io_transformer);
51986   return wuffs_base__make_status(NULL);
51987 }
51988 
51989 wuffs_zlib__decoder*
wuffs_zlib__decoder__alloc(void)51990 wuffs_zlib__decoder__alloc(void) {
51991   wuffs_zlib__decoder* x =
51992       (wuffs_zlib__decoder*)(calloc(sizeof(wuffs_zlib__decoder), 1));
51993   if (!x) {
51994     return NULL;
51995   }
51996   if (wuffs_zlib__decoder__initialize(
51997       x, sizeof(wuffs_zlib__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
51998     free(x);
51999     return NULL;
52000   }
52001   return x;
52002 }
52003 
52004 size_t
sizeof__wuffs_zlib__decoder(void)52005 sizeof__wuffs_zlib__decoder(void) {
52006   return sizeof(wuffs_zlib__decoder);
52007 }
52008 
52009 // ---------------- Function Implementations
52010 
52011 // -------- func zlib.decoder.dictionary_id
52012 
52013 WUFFS_BASE__GENERATED_C_CODE
52014 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_zlib__decoder__dictionary_id(const wuffs_zlib__decoder * self)52015 wuffs_zlib__decoder__dictionary_id(
52016     const wuffs_zlib__decoder* self) {
52017   if (!self) {
52018     return 0;
52019   }
52020   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
52021       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
52022     return 0;
52023   }
52024 
52025   return self->private_impl.f_dict_id_want;
52026 }
52027 
52028 // -------- func zlib.decoder.add_dictionary
52029 
52030 WUFFS_BASE__GENERATED_C_CODE
52031 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_zlib__decoder__add_dictionary(wuffs_zlib__decoder * self,wuffs_base__slice_u8 a_dict)52032 wuffs_zlib__decoder__add_dictionary(
52033     wuffs_zlib__decoder* self,
52034     wuffs_base__slice_u8 a_dict) {
52035   if (!self) {
52036     return wuffs_base__make_empty_struct();
52037   }
52038   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
52039     return wuffs_base__make_empty_struct();
52040   }
52041 
52042   if (self->private_impl.f_header_complete) {
52043     self->private_impl.f_bad_call_sequence = true;
52044   } else {
52045     self->private_impl.f_dict_id_got = wuffs_adler32__hasher__update_u32(&self->private_data.f_dict_id_hasher, a_dict);
52046     wuffs_deflate__decoder__add_history(&self->private_data.f_flate, a_dict);
52047   }
52048   self->private_impl.f_got_dictionary = true;
52049   return wuffs_base__make_empty_struct();
52050 }
52051 
52052 // -------- func zlib.decoder.get_quirk
52053 
52054 WUFFS_BASE__GENERATED_C_CODE
52055 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_zlib__decoder__get_quirk(const wuffs_zlib__decoder * self,uint32_t a_key)52056 wuffs_zlib__decoder__get_quirk(
52057     const wuffs_zlib__decoder* self,
52058     uint32_t a_key) {
52059   if (!self) {
52060     return 0;
52061   }
52062   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
52063       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
52064     return 0;
52065   }
52066 
52067   uint32_t v_key = 0;
52068 
52069   if ((a_key == 1u) && self->private_impl.f_ignore_checksum) {
52070     return 1u;
52071   } else if (a_key >= 2113790976u) {
52072     v_key = (a_key - 2113790976u);
52073     if (v_key < 1u) {
52074       if (self->private_impl.f_quirks[v_key]) {
52075         return 1u;
52076       }
52077     }
52078   }
52079   return 0u;
52080 }
52081 
52082 // -------- func zlib.decoder.set_quirk
52083 
52084 WUFFS_BASE__GENERATED_C_CODE
52085 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_zlib__decoder__set_quirk(wuffs_zlib__decoder * self,uint32_t a_key,uint64_t a_value)52086 wuffs_zlib__decoder__set_quirk(
52087     wuffs_zlib__decoder* self,
52088     uint32_t a_key,
52089     uint64_t a_value) {
52090   if (!self) {
52091     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
52092   }
52093   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
52094     return wuffs_base__make_status(
52095         (self->private_impl.magic == WUFFS_BASE__DISABLED)
52096         ? wuffs_base__error__disabled_by_previous_error
52097         : wuffs_base__error__initialize_not_called);
52098   }
52099 
52100   if (self->private_impl.f_header_complete) {
52101     self->private_impl.f_bad_call_sequence = true;
52102     return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
52103   } else if (a_key == 1u) {
52104     self->private_impl.f_ignore_checksum = (a_value > 0u);
52105     return wuffs_base__make_status(NULL);
52106   } else if (a_key >= 2113790976u) {
52107     a_key -= 2113790976u;
52108     if (a_key < 1u) {
52109       self->private_impl.f_quirks[a_key] = (a_value > 0u);
52110       return wuffs_base__make_status(NULL);
52111     }
52112   }
52113   return wuffs_base__make_status(wuffs_base__error__unsupported_option);
52114 }
52115 
52116 // -------- func zlib.decoder.history_retain_length
52117 
52118 WUFFS_BASE__GENERATED_C_CODE
52119 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_zlib__decoder__history_retain_length(const wuffs_zlib__decoder * self)52120 wuffs_zlib__decoder__history_retain_length(
52121     const wuffs_zlib__decoder* self) {
52122   if (!self) {
52123     return 0;
52124   }
52125   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
52126       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
52127     return 0;
52128   }
52129 
52130   return 0u;
52131 }
52132 
52133 // -------- func zlib.decoder.workbuf_len
52134 
52135 WUFFS_BASE__GENERATED_C_CODE
52136 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_zlib__decoder__workbuf_len(const wuffs_zlib__decoder * self)52137 wuffs_zlib__decoder__workbuf_len(
52138     const wuffs_zlib__decoder* self) {
52139   if (!self) {
52140     return wuffs_base__utility__empty_range_ii_u64();
52141   }
52142   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
52143       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
52144     return wuffs_base__utility__empty_range_ii_u64();
52145   }
52146 
52147   return wuffs_base__utility__make_range_ii_u64(1u, 1u);
52148 }
52149 
52150 // -------- func zlib.decoder.transform_io
52151 
52152 WUFFS_BASE__GENERATED_C_CODE
52153 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_zlib__decoder__transform_io(wuffs_zlib__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__slice_u8 a_workbuf)52154 wuffs_zlib__decoder__transform_io(
52155     wuffs_zlib__decoder* self,
52156     wuffs_base__io_buffer* a_dst,
52157     wuffs_base__io_buffer* a_src,
52158     wuffs_base__slice_u8 a_workbuf) {
52159   if (!self) {
52160     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
52161   }
52162   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
52163     return wuffs_base__make_status(
52164         (self->private_impl.magic == WUFFS_BASE__DISABLED)
52165         ? wuffs_base__error__disabled_by_previous_error
52166         : wuffs_base__error__initialize_not_called);
52167   }
52168   if (!a_dst || !a_src) {
52169     self->private_impl.magic = WUFFS_BASE__DISABLED;
52170     return wuffs_base__make_status(wuffs_base__error__bad_argument);
52171   }
52172   if ((self->private_impl.active_coroutine != 0) &&
52173       (self->private_impl.active_coroutine != 1)) {
52174     self->private_impl.magic = WUFFS_BASE__DISABLED;
52175     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
52176   }
52177   self->private_impl.active_coroutine = 0;
52178   wuffs_base__status status = wuffs_base__make_status(NULL);
52179 
52180   wuffs_base__status v_status = wuffs_base__make_status(NULL);
52181 
52182   uint32_t coro_susp_point = self->private_impl.p_transform_io[0];
52183   switch (coro_susp_point) {
52184     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
52185 
52186     while (true) {
52187       {
52188         wuffs_base__status t_0 = wuffs_zlib__decoder__do_transform_io(self, a_dst, a_src, a_workbuf);
52189         v_status = t_0;
52190       }
52191       if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
52192         status = wuffs_base__make_status(wuffs_zlib__error__truncated_input);
52193         goto exit;
52194       }
52195       status = v_status;
52196       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
52197     }
52198 
52199     ok:
52200     self->private_impl.p_transform_io[0] = 0;
52201     goto exit;
52202   }
52203 
52204   goto suspend;
52205   suspend:
52206   self->private_impl.p_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
52207   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
52208 
52209   goto exit;
52210   exit:
52211   if (wuffs_base__status__is_error(&status)) {
52212     self->private_impl.magic = WUFFS_BASE__DISABLED;
52213   }
52214   return status;
52215 }
52216 
52217 // -------- func zlib.decoder.do_transform_io
52218 
52219 WUFFS_BASE__GENERATED_C_CODE
52220 static wuffs_base__status
wuffs_zlib__decoder__do_transform_io(wuffs_zlib__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__slice_u8 a_workbuf)52221 wuffs_zlib__decoder__do_transform_io(
52222     wuffs_zlib__decoder* self,
52223     wuffs_base__io_buffer* a_dst,
52224     wuffs_base__io_buffer* a_src,
52225     wuffs_base__slice_u8 a_workbuf) {
52226   wuffs_base__status status = wuffs_base__make_status(NULL);
52227 
52228   uint16_t v_x = 0;
52229   uint32_t v_checksum_got = 0;
52230   wuffs_base__status v_status = wuffs_base__make_status(NULL);
52231   uint32_t v_checksum_want = 0;
52232   uint64_t v_mark = 0;
52233 
52234   uint8_t* iop_a_dst = NULL;
52235   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
52236   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
52237   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
52238   if (a_dst && a_dst->data.ptr) {
52239     io0_a_dst = a_dst->data.ptr;
52240     io1_a_dst = io0_a_dst + a_dst->meta.wi;
52241     iop_a_dst = io1_a_dst;
52242     io2_a_dst = io0_a_dst + a_dst->data.len;
52243     if (a_dst->meta.closed) {
52244       io2_a_dst = iop_a_dst;
52245     }
52246   }
52247   const uint8_t* iop_a_src = NULL;
52248   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
52249   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
52250   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
52251   if (a_src && a_src->data.ptr) {
52252     io0_a_src = a_src->data.ptr;
52253     io1_a_src = io0_a_src + a_src->meta.ri;
52254     iop_a_src = io1_a_src;
52255     io2_a_src = io0_a_src + a_src->meta.wi;
52256   }
52257 
52258   uint32_t coro_susp_point = self->private_impl.p_do_transform_io[0];
52259   if (coro_susp_point) {
52260     v_checksum_got = self->private_data.s_do_transform_io[0].v_checksum_got;
52261   }
52262   switch (coro_susp_point) {
52263     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
52264 
52265     if (self->private_impl.f_bad_call_sequence) {
52266       status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
52267       goto exit;
52268     } else if (self->private_impl.f_quirks[0u]) {
52269     } else if ( ! self->private_impl.f_want_dictionary) {
52270       {
52271         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
52272         uint16_t t_0;
52273         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
52274           t_0 = wuffs_base__peek_u16be__no_bounds_check(iop_a_src);
52275           iop_a_src += 2;
52276         } else {
52277           self->private_data.s_do_transform_io[0].scratch = 0;
52278           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
52279           while (true) {
52280             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
52281               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
52282               goto suspend;
52283             }
52284             uint64_t* scratch = &self->private_data.s_do_transform_io[0].scratch;
52285             uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu));
52286             *scratch >>= 8;
52287             *scratch <<= 8;
52288             *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
52289             if (num_bits_0 == 8) {
52290               t_0 = ((uint16_t)(*scratch >> 48));
52291               break;
52292             }
52293             num_bits_0 += 8u;
52294             *scratch |= ((uint64_t)(num_bits_0));
52295           }
52296         }
52297         v_x = t_0;
52298       }
52299       if (((v_x >> 8u) & 15u) != 8u) {
52300         status = wuffs_base__make_status(wuffs_zlib__error__bad_compression_method);
52301         goto exit;
52302       }
52303       if ((v_x >> 12u) > 7u) {
52304         status = wuffs_base__make_status(wuffs_zlib__error__bad_compression_window_size);
52305         goto exit;
52306       }
52307       if ((v_x % 31u) != 0u) {
52308         status = wuffs_base__make_status(wuffs_zlib__error__bad_parity_check);
52309         goto exit;
52310       }
52311       self->private_impl.f_want_dictionary = ((v_x & 32u) != 0u);
52312       if (self->private_impl.f_want_dictionary) {
52313         self->private_impl.f_dict_id_got = 1u;
52314         {
52315           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
52316           uint32_t t_1;
52317           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
52318             t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
52319             iop_a_src += 4;
52320           } else {
52321             self->private_data.s_do_transform_io[0].scratch = 0;
52322             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
52323             while (true) {
52324               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
52325                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
52326                 goto suspend;
52327               }
52328               uint64_t* scratch = &self->private_data.s_do_transform_io[0].scratch;
52329               uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu));
52330               *scratch >>= 8;
52331               *scratch <<= 8;
52332               *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
52333               if (num_bits_1 == 24) {
52334                 t_1 = ((uint32_t)(*scratch >> 32));
52335                 break;
52336               }
52337               num_bits_1 += 8u;
52338               *scratch |= ((uint64_t)(num_bits_1));
52339             }
52340           }
52341           self->private_impl.f_dict_id_want = t_1;
52342         }
52343         status = wuffs_base__make_status(wuffs_zlib__note__dictionary_required);
52344         goto ok;
52345       } else if (self->private_impl.f_got_dictionary) {
52346         status = wuffs_base__make_status(wuffs_zlib__error__incorrect_dictionary);
52347         goto exit;
52348       }
52349     } else if (self->private_impl.f_dict_id_got != self->private_impl.f_dict_id_want) {
52350       if (self->private_impl.f_got_dictionary) {
52351         status = wuffs_base__make_status(wuffs_zlib__error__incorrect_dictionary);
52352         goto exit;
52353       }
52354       status = wuffs_base__make_status(wuffs_zlib__note__dictionary_required);
52355       goto ok;
52356     }
52357     self->private_impl.f_header_complete = true;
52358     while (true) {
52359       v_mark = ((uint64_t)(iop_a_dst - io0_a_dst));
52360       {
52361         if (a_dst) {
52362           a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
52363         }
52364         if (a_src) {
52365           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
52366         }
52367         wuffs_base__status t_2 = wuffs_deflate__decoder__transform_io(&self->private_data.f_flate, a_dst, a_src, a_workbuf);
52368         v_status = t_2;
52369         if (a_dst) {
52370           iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
52371         }
52372         if (a_src) {
52373           iop_a_src = a_src->data.ptr + a_src->meta.ri;
52374         }
52375       }
52376       if ( ! self->private_impl.f_ignore_checksum &&  ! self->private_impl.f_quirks[0u]) {
52377         v_checksum_got = wuffs_adler32__hasher__update_u32(&self->private_data.f_checksum, wuffs_base__io__since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst));
52378       }
52379       if (wuffs_base__status__is_ok(&v_status)) {
52380         break;
52381       }
52382       status = v_status;
52383       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
52384     }
52385     if ( ! self->private_impl.f_quirks[0u]) {
52386       {
52387         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
52388         uint32_t t_3;
52389         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
52390           t_3 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
52391           iop_a_src += 4;
52392         } else {
52393           self->private_data.s_do_transform_io[0].scratch = 0;
52394           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
52395           while (true) {
52396             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
52397               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
52398               goto suspend;
52399             }
52400             uint64_t* scratch = &self->private_data.s_do_transform_io[0].scratch;
52401             uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFFu));
52402             *scratch >>= 8;
52403             *scratch <<= 8;
52404             *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3);
52405             if (num_bits_3 == 24) {
52406               t_3 = ((uint32_t)(*scratch >> 32));
52407               break;
52408             }
52409             num_bits_3 += 8u;
52410             *scratch |= ((uint64_t)(num_bits_3));
52411           }
52412         }
52413         v_checksum_want = t_3;
52414       }
52415       if ( ! self->private_impl.f_ignore_checksum && (v_checksum_got != v_checksum_want)) {
52416         status = wuffs_base__make_status(wuffs_zlib__error__bad_checksum);
52417         goto exit;
52418       }
52419     }
52420 
52421     ok:
52422     self->private_impl.p_do_transform_io[0] = 0;
52423     goto exit;
52424   }
52425 
52426   goto suspend;
52427   suspend:
52428   self->private_impl.p_do_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
52429   self->private_data.s_do_transform_io[0].v_checksum_got = v_checksum_got;
52430 
52431   goto exit;
52432   exit:
52433   if (a_dst && a_dst->data.ptr) {
52434     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
52435   }
52436   if (a_src && a_src->data.ptr) {
52437     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
52438   }
52439 
52440   return status;
52441 }
52442 
52443 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ZLIB)
52444 
52445 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__PNG)
52446 
52447 // ---------------- Status Codes Implementations
52448 
52449 const char wuffs_png__error__bad_animation_sequence_number[] = "#png: bad animation sequence number";
52450 const char wuffs_png__error__bad_checksum[] = "#png: bad checksum";
52451 const char wuffs_png__error__bad_chunk[] = "#png: bad chunk";
52452 const char wuffs_png__error__bad_filter[] = "#png: bad filter";
52453 const char wuffs_png__error__bad_header[] = "#png: bad header";
52454 const char wuffs_png__error__bad_text_chunk_not_latin_1[] = "#png: bad text chunk (not Latin-1)";
52455 const char wuffs_png__error__missing_palette[] = "#png: missing palette";
52456 const char wuffs_png__error__truncated_input[] = "#png: truncated input";
52457 const char wuffs_png__error__unsupported_cgbi_extension[] = "#png: unsupported CgBI extension";
52458 const char wuffs_png__error__unsupported_png_compression_method[] = "#png: unsupported PNG compression method";
52459 const char wuffs_png__error__unsupported_png_file[] = "#png: unsupported PNG file";
52460 const char wuffs_png__error__internal_error_inconsistent_i_o[] = "#png: internal error: inconsistent I/O";
52461 const char wuffs_png__error__internal_error_inconsistent_chunk_type[] = "#png: internal error: inconsistent chunk type";
52462 const char wuffs_png__error__internal_error_inconsistent_frame_bounds[] = "#png: internal error: inconsistent frame bounds";
52463 const char wuffs_png__error__internal_error_inconsistent_workbuf_length[] = "#png: internal error: inconsistent workbuf length";
52464 const char wuffs_png__error__internal_error_zlib_decoder_did_not_exhaust_its_input[] = "#png: internal error: zlib decoder did not exhaust its input";
52465 
52466 // ---------------- Private Consts
52467 
52468 #define WUFFS_PNG__ANCILLARY_BIT 32
52469 
52470 static const uint8_t
52471 WUFFS_PNG__INTERLACING[8][6] WUFFS_BASE__POTENTIALLY_UNUSED = {
52472   {
52473     0, 0, 0, 0, 0, 0,
52474   }, {
52475     3, 7, 0, 3, 7, 0,
52476   }, {
52477     3, 3, 4, 3, 7, 0,
52478   }, {
52479     2, 3, 0, 3, 3, 4,
52480   }, {
52481     2, 1, 2, 2, 3, 0,
52482   }, {
52483     1, 1, 0, 2, 1, 2,
52484   }, {
52485     1, 0, 1, 1, 1, 0,
52486   }, {
52487     0, 0, 0, 1, 0, 1,
52488   },
52489 };
52490 
52491 static const uint8_t
52492 WUFFS_PNG__LOW_BIT_DEPTH_MULTIPLIERS[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
52493   0, 255, 85, 0, 17, 0, 0, 0,
52494 };
52495 
52496 static const uint8_t
52497 WUFFS_PNG__LOW_BIT_DEPTH_NUM_PACKS[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
52498   0, 8, 4, 0, 2, 0, 0, 0,
52499 };
52500 
52501 static const uint8_t
52502 WUFFS_PNG__NUM_CHANNELS[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
52503   1, 0, 3, 1, 2, 0, 4, 0,
52504 };
52505 
52506 static const uint16_t
52507 WUFFS_PNG__LATIN_1[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
52508   0, 0, 0, 0, 0, 0, 0, 0,
52509   0, 0, 0, 0, 0, 0, 0, 0,
52510   0, 0, 0, 0, 0, 0, 0, 0,
52511   0, 0, 0, 0, 0, 0, 0, 0,
52512   32, 33, 34, 35, 36, 37, 38, 39,
52513   40, 41, 42, 43, 44, 45, 46, 47,
52514   48, 49, 50, 51, 52, 53, 54, 55,
52515   56, 57, 58, 59, 60, 61, 62, 63,
52516   64, 65, 66, 67, 68, 69, 70, 71,
52517   72, 73, 74, 75, 76, 77, 78, 79,
52518   80, 81, 82, 83, 84, 85, 86, 87,
52519   88, 89, 90, 91, 92, 93, 94, 95,
52520   96, 97, 98, 99, 100, 101, 102, 103,
52521   104, 105, 106, 107, 108, 109, 110, 111,
52522   112, 113, 114, 115, 116, 117, 118, 119,
52523   120, 121, 122, 123, 124, 125, 126, 0,
52524   0, 0, 0, 0, 0, 0, 0, 0,
52525   0, 0, 0, 0, 0, 0, 0, 0,
52526   0, 0, 0, 0, 0, 0, 0, 0,
52527   0, 0, 0, 0, 0, 0, 0, 0,
52528   0, 41410, 41666, 41922, 42178, 42434, 42690, 42946,
52529   43202, 43458, 43714, 43970, 44226, 44482, 44738, 44994,
52530   45250, 45506, 45762, 46018, 46274, 46530, 46786, 47042,
52531   47298, 47554, 47810, 48066, 48322, 48578, 48834, 49090,
52532   32963, 33219, 33475, 33731, 33987, 34243, 34499, 34755,
52533   35011, 35267, 35523, 35779, 36035, 36291, 36547, 36803,
52534   37059, 37315, 37571, 37827, 38083, 38339, 38595, 38851,
52535   39107, 39363, 39619, 39875, 40131, 40387, 40643, 40899,
52536   41155, 41411, 41667, 41923, 42179, 42435, 42691, 42947,
52537   43203, 43459, 43715, 43971, 44227, 44483, 44739, 44995,
52538   45251, 45507, 45763, 46019, 46275, 46531, 46787, 47043,
52539   47299, 47555, 47811, 48067, 48323, 48579, 48835, 49091,
52540 };
52541 
52542 // ---------------- Private Initializer Prototypes
52543 
52544 // ---------------- Private Function Prototypes
52545 
52546 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
52547 WUFFS_BASE__GENERATED_C_CODE
52548 static wuffs_base__empty_struct
52549 wuffs_png__decoder__filter_1_distance_4_arm_neon(
52550     wuffs_png__decoder* self,
52551     wuffs_base__slice_u8 a_curr);
52552 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
52553 
52554 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
52555 WUFFS_BASE__GENERATED_C_CODE
52556 static wuffs_base__empty_struct
52557 wuffs_png__decoder__filter_3_distance_4_arm_neon(
52558     wuffs_png__decoder* self,
52559     wuffs_base__slice_u8 a_curr,
52560     wuffs_base__slice_u8 a_prev);
52561 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
52562 
52563 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
52564 WUFFS_BASE__GENERATED_C_CODE
52565 static wuffs_base__empty_struct
52566 wuffs_png__decoder__filter_4_distance_3_arm_neon(
52567     wuffs_png__decoder* self,
52568     wuffs_base__slice_u8 a_curr,
52569     wuffs_base__slice_u8 a_prev);
52570 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
52571 
52572 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
52573 WUFFS_BASE__GENERATED_C_CODE
52574 static wuffs_base__empty_struct
52575 wuffs_png__decoder__filter_4_distance_4_arm_neon(
52576     wuffs_png__decoder* self,
52577     wuffs_base__slice_u8 a_curr,
52578     wuffs_base__slice_u8 a_prev);
52579 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
52580 
52581 WUFFS_BASE__GENERATED_C_CODE
52582 static wuffs_base__empty_struct
52583 wuffs_png__decoder__filter_1(
52584     wuffs_png__decoder* self,
52585     wuffs_base__slice_u8 a_curr);
52586 
52587 WUFFS_BASE__GENERATED_C_CODE
52588 static wuffs_base__empty_struct
52589 wuffs_png__decoder__filter_1__choosy_default(
52590     wuffs_png__decoder* self,
52591     wuffs_base__slice_u8 a_curr);
52592 
52593 WUFFS_BASE__GENERATED_C_CODE
52594 static wuffs_base__empty_struct
52595 wuffs_png__decoder__filter_1_distance_3_fallback(
52596     wuffs_png__decoder* self,
52597     wuffs_base__slice_u8 a_curr);
52598 
52599 WUFFS_BASE__GENERATED_C_CODE
52600 static wuffs_base__empty_struct
52601 wuffs_png__decoder__filter_1_distance_4_fallback(
52602     wuffs_png__decoder* self,
52603     wuffs_base__slice_u8 a_curr);
52604 
52605 WUFFS_BASE__GENERATED_C_CODE
52606 static wuffs_base__empty_struct
52607 wuffs_png__decoder__filter_2(
52608     wuffs_png__decoder* self,
52609     wuffs_base__slice_u8 a_curr,
52610     wuffs_base__slice_u8 a_prev);
52611 
52612 WUFFS_BASE__GENERATED_C_CODE
52613 static wuffs_base__empty_struct
52614 wuffs_png__decoder__filter_3(
52615     wuffs_png__decoder* self,
52616     wuffs_base__slice_u8 a_curr,
52617     wuffs_base__slice_u8 a_prev);
52618 
52619 WUFFS_BASE__GENERATED_C_CODE
52620 static wuffs_base__empty_struct
52621 wuffs_png__decoder__filter_3__choosy_default(
52622     wuffs_png__decoder* self,
52623     wuffs_base__slice_u8 a_curr,
52624     wuffs_base__slice_u8 a_prev);
52625 
52626 WUFFS_BASE__GENERATED_C_CODE
52627 static wuffs_base__empty_struct
52628 wuffs_png__decoder__filter_3_distance_3_fallback(
52629     wuffs_png__decoder* self,
52630     wuffs_base__slice_u8 a_curr,
52631     wuffs_base__slice_u8 a_prev);
52632 
52633 WUFFS_BASE__GENERATED_C_CODE
52634 static wuffs_base__empty_struct
52635 wuffs_png__decoder__filter_3_distance_4_fallback(
52636     wuffs_png__decoder* self,
52637     wuffs_base__slice_u8 a_curr,
52638     wuffs_base__slice_u8 a_prev);
52639 
52640 WUFFS_BASE__GENERATED_C_CODE
52641 static wuffs_base__empty_struct
52642 wuffs_png__decoder__filter_4(
52643     wuffs_png__decoder* self,
52644     wuffs_base__slice_u8 a_curr,
52645     wuffs_base__slice_u8 a_prev);
52646 
52647 WUFFS_BASE__GENERATED_C_CODE
52648 static wuffs_base__empty_struct
52649 wuffs_png__decoder__filter_4__choosy_default(
52650     wuffs_png__decoder* self,
52651     wuffs_base__slice_u8 a_curr,
52652     wuffs_base__slice_u8 a_prev);
52653 
52654 WUFFS_BASE__GENERATED_C_CODE
52655 static wuffs_base__empty_struct
52656 wuffs_png__decoder__filter_4_distance_3_fallback(
52657     wuffs_png__decoder* self,
52658     wuffs_base__slice_u8 a_curr,
52659     wuffs_base__slice_u8 a_prev);
52660 
52661 WUFFS_BASE__GENERATED_C_CODE
52662 static wuffs_base__empty_struct
52663 wuffs_png__decoder__filter_4_distance_4_fallback(
52664     wuffs_png__decoder* self,
52665     wuffs_base__slice_u8 a_curr,
52666     wuffs_base__slice_u8 a_prev);
52667 
52668 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
52669 WUFFS_BASE__GENERATED_C_CODE
52670 static wuffs_base__empty_struct
52671 wuffs_png__decoder__filter_1_distance_4_x86_sse42(
52672     wuffs_png__decoder* self,
52673     wuffs_base__slice_u8 a_curr);
52674 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
52675 
52676 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
52677 WUFFS_BASE__GENERATED_C_CODE
52678 static wuffs_base__empty_struct
52679 wuffs_png__decoder__filter_3_distance_4_x86_sse42(
52680     wuffs_png__decoder* self,
52681     wuffs_base__slice_u8 a_curr,
52682     wuffs_base__slice_u8 a_prev);
52683 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
52684 
52685 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
52686 WUFFS_BASE__GENERATED_C_CODE
52687 static wuffs_base__empty_struct
52688 wuffs_png__decoder__filter_4_distance_3_x86_sse42(
52689     wuffs_png__decoder* self,
52690     wuffs_base__slice_u8 a_curr,
52691     wuffs_base__slice_u8 a_prev);
52692 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
52693 
52694 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
52695 WUFFS_BASE__GENERATED_C_CODE
52696 static wuffs_base__empty_struct
52697 wuffs_png__decoder__filter_4_distance_4_x86_sse42(
52698     wuffs_png__decoder* self,
52699     wuffs_base__slice_u8 a_curr,
52700     wuffs_base__slice_u8 a_prev);
52701 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
52702 
52703 WUFFS_BASE__GENERATED_C_CODE
52704 static wuffs_base__status
52705 wuffs_png__decoder__do_decode_image_config(
52706     wuffs_png__decoder* self,
52707     wuffs_base__image_config* a_dst,
52708     wuffs_base__io_buffer* a_src);
52709 
52710 WUFFS_BASE__GENERATED_C_CODE
52711 static wuffs_base__status
52712 wuffs_png__decoder__decode_ihdr(
52713     wuffs_png__decoder* self,
52714     wuffs_base__io_buffer* a_src);
52715 
52716 WUFFS_BASE__GENERATED_C_CODE
52717 static wuffs_base__empty_struct
52718 wuffs_png__decoder__assign_filter_distance(
52719     wuffs_png__decoder* self);
52720 
52721 WUFFS_BASE__GENERATED_C_CODE
52722 static uint64_t
52723 wuffs_png__decoder__calculate_bytes_per_row(
52724     const wuffs_png__decoder* self,
52725     uint32_t a_width);
52726 
52727 WUFFS_BASE__GENERATED_C_CODE
52728 static wuffs_base__empty_struct
52729 wuffs_png__decoder__choose_filter_implementations(
52730     wuffs_png__decoder* self);
52731 
52732 WUFFS_BASE__GENERATED_C_CODE
52733 static wuffs_base__status
52734 wuffs_png__decoder__decode_other_chunk(
52735     wuffs_png__decoder* self,
52736     wuffs_base__io_buffer* a_src,
52737     bool a_framy);
52738 
52739 WUFFS_BASE__GENERATED_C_CODE
52740 static wuffs_base__status
52741 wuffs_png__decoder__decode_actl(
52742     wuffs_png__decoder* self,
52743     wuffs_base__io_buffer* a_src);
52744 
52745 WUFFS_BASE__GENERATED_C_CODE
52746 static wuffs_base__status
52747 wuffs_png__decoder__decode_chrm(
52748     wuffs_png__decoder* self,
52749     wuffs_base__io_buffer* a_src);
52750 
52751 WUFFS_BASE__GENERATED_C_CODE
52752 static wuffs_base__status
52753 wuffs_png__decoder__decode_exif(
52754     wuffs_png__decoder* self,
52755     wuffs_base__io_buffer* a_src);
52756 
52757 WUFFS_BASE__GENERATED_C_CODE
52758 static wuffs_base__status
52759 wuffs_png__decoder__decode_fctl(
52760     wuffs_png__decoder* self,
52761     wuffs_base__io_buffer* a_src);
52762 
52763 WUFFS_BASE__GENERATED_C_CODE
52764 static wuffs_base__status
52765 wuffs_png__decoder__decode_gama(
52766     wuffs_png__decoder* self,
52767     wuffs_base__io_buffer* a_src);
52768 
52769 WUFFS_BASE__GENERATED_C_CODE
52770 static wuffs_base__status
52771 wuffs_png__decoder__decode_iccp(
52772     wuffs_png__decoder* self,
52773     wuffs_base__io_buffer* a_src);
52774 
52775 WUFFS_BASE__GENERATED_C_CODE
52776 static wuffs_base__status
52777 wuffs_png__decoder__decode_plte(
52778     wuffs_png__decoder* self,
52779     wuffs_base__io_buffer* a_src);
52780 
52781 WUFFS_BASE__GENERATED_C_CODE
52782 static wuffs_base__status
52783 wuffs_png__decoder__decode_srgb(
52784     wuffs_png__decoder* self,
52785     wuffs_base__io_buffer* a_src);
52786 
52787 WUFFS_BASE__GENERATED_C_CODE
52788 static wuffs_base__status
52789 wuffs_png__decoder__decode_trns(
52790     wuffs_png__decoder* self,
52791     wuffs_base__io_buffer* a_src);
52792 
52793 WUFFS_BASE__GENERATED_C_CODE
52794 static wuffs_base__status
52795 wuffs_png__decoder__do_decode_frame_config(
52796     wuffs_png__decoder* self,
52797     wuffs_base__frame_config* a_dst,
52798     wuffs_base__io_buffer* a_src);
52799 
52800 WUFFS_BASE__GENERATED_C_CODE
52801 static wuffs_base__status
52802 wuffs_png__decoder__skip_frame(
52803     wuffs_png__decoder* self,
52804     wuffs_base__io_buffer* a_src);
52805 
52806 WUFFS_BASE__GENERATED_C_CODE
52807 static wuffs_base__status
52808 wuffs_png__decoder__do_decode_frame(
52809     wuffs_png__decoder* self,
52810     wuffs_base__pixel_buffer* a_dst,
52811     wuffs_base__io_buffer* a_src,
52812     wuffs_base__pixel_blend a_blend,
52813     wuffs_base__slice_u8 a_workbuf,
52814     wuffs_base__decode_frame_options* a_opts);
52815 
52816 WUFFS_BASE__GENERATED_C_CODE
52817 static wuffs_base__status
52818 wuffs_png__decoder__decode_pass(
52819     wuffs_png__decoder* self,
52820     wuffs_base__io_buffer* a_src,
52821     wuffs_base__slice_u8 a_workbuf);
52822 
52823 WUFFS_BASE__GENERATED_C_CODE
52824 static wuffs_base__status
52825 wuffs_png__decoder__do_tell_me_more(
52826     wuffs_png__decoder* self,
52827     wuffs_base__io_buffer* a_dst,
52828     wuffs_base__more_information* a_minfo,
52829     wuffs_base__io_buffer* a_src);
52830 
52831 WUFFS_BASE__GENERATED_C_CODE
52832 static wuffs_base__status
52833 wuffs_png__decoder__filter_and_swizzle(
52834     wuffs_png__decoder* self,
52835     wuffs_base__pixel_buffer* a_dst,
52836     wuffs_base__slice_u8 a_workbuf);
52837 
52838 WUFFS_BASE__GENERATED_C_CODE
52839 static wuffs_base__status
52840 wuffs_png__decoder__filter_and_swizzle__choosy_default(
52841     wuffs_png__decoder* self,
52842     wuffs_base__pixel_buffer* a_dst,
52843     wuffs_base__slice_u8 a_workbuf);
52844 
52845 WUFFS_BASE__GENERATED_C_CODE
52846 static wuffs_base__status
52847 wuffs_png__decoder__filter_and_swizzle_tricky(
52848     wuffs_png__decoder* self,
52849     wuffs_base__pixel_buffer* a_dst,
52850     wuffs_base__slice_u8 a_workbuf);
52851 
52852 // ---------------- VTables
52853 
52854 const wuffs_base__image_decoder__func_ptrs
52855 wuffs_png__decoder__func_ptrs_for__wuffs_base__image_decoder = {
52856   (wuffs_base__status(*)(void*,
52857       wuffs_base__pixel_buffer*,
52858       wuffs_base__io_buffer*,
52859       wuffs_base__pixel_blend,
52860       wuffs_base__slice_u8,
52861       wuffs_base__decode_frame_options*))(&wuffs_png__decoder__decode_frame),
52862   (wuffs_base__status(*)(void*,
52863       wuffs_base__frame_config*,
52864       wuffs_base__io_buffer*))(&wuffs_png__decoder__decode_frame_config),
52865   (wuffs_base__status(*)(void*,
52866       wuffs_base__image_config*,
52867       wuffs_base__io_buffer*))(&wuffs_png__decoder__decode_image_config),
52868   (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_png__decoder__frame_dirty_rect),
52869   (uint64_t(*)(const void*,
52870       uint32_t))(&wuffs_png__decoder__get_quirk),
52871   (uint64_t(*)(const void*))(&wuffs_png__decoder__history_retain_length),
52872   (uint32_t(*)(const void*))(&wuffs_png__decoder__num_animation_loops),
52873   (uint64_t(*)(const void*))(&wuffs_png__decoder__num_decoded_frame_configs),
52874   (uint64_t(*)(const void*))(&wuffs_png__decoder__num_decoded_frames),
52875   (wuffs_base__status(*)(void*,
52876       uint64_t,
52877       uint64_t))(&wuffs_png__decoder__restart_frame),
52878   (wuffs_base__status(*)(void*,
52879       uint32_t,
52880       uint64_t))(&wuffs_png__decoder__set_quirk),
52881   (wuffs_base__empty_struct(*)(void*,
52882       uint32_t,
52883       bool))(&wuffs_png__decoder__set_report_metadata),
52884   (wuffs_base__status(*)(void*,
52885       wuffs_base__io_buffer*,
52886       wuffs_base__more_information*,
52887       wuffs_base__io_buffer*))(&wuffs_png__decoder__tell_me_more),
52888   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_png__decoder__workbuf_len),
52889 };
52890 
52891 // ---------------- Initializer Implementations
52892 
52893 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
wuffs_png__decoder__initialize(wuffs_png__decoder * self,size_t sizeof_star_self,uint64_t wuffs_version,uint32_t options)52894 wuffs_png__decoder__initialize(
52895     wuffs_png__decoder* self,
52896     size_t sizeof_star_self,
52897     uint64_t wuffs_version,
52898     uint32_t options){
52899   if (!self) {
52900     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
52901   }
52902   if (sizeof(*self) != sizeof_star_self) {
52903     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
52904   }
52905   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
52906       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
52907     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
52908   }
52909 
52910   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
52911     // The whole point of this if-check is to detect an uninitialized *self.
52912     // We disable the warning on GCC. Clang-5.0 does not have this warning.
52913 #if !defined(__clang__) && defined(__GNUC__)
52914 #pragma GCC diagnostic push
52915 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
52916 #endif
52917     if (self->private_impl.magic != 0) {
52918       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
52919     }
52920 #if !defined(__clang__) && defined(__GNUC__)
52921 #pragma GCC diagnostic pop
52922 #endif
52923   } else {
52924     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
52925       memset(self, 0, sizeof(*self));
52926       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
52927     } else {
52928       memset(&(self->private_impl), 0, sizeof(self->private_impl));
52929     }
52930   }
52931 
52932   self->private_impl.choosy_filter_1 = &wuffs_png__decoder__filter_1__choosy_default;
52933   self->private_impl.choosy_filter_3 = &wuffs_png__decoder__filter_3__choosy_default;
52934   self->private_impl.choosy_filter_4 = &wuffs_png__decoder__filter_4__choosy_default;
52935   self->private_impl.choosy_filter_and_swizzle = &wuffs_png__decoder__filter_and_swizzle__choosy_default;
52936 
52937   {
52938     wuffs_base__status z = wuffs_crc32__ieee_hasher__initialize(
52939         &self->private_data.f_crc32, sizeof(self->private_data.f_crc32), WUFFS_VERSION, options);
52940     if (z.repr) {
52941       return z;
52942     }
52943   }
52944   {
52945     wuffs_base__status z = wuffs_zlib__decoder__initialize(
52946         &self->private_data.f_zlib, sizeof(self->private_data.f_zlib), WUFFS_VERSION, options);
52947     if (z.repr) {
52948       return z;
52949     }
52950   }
52951   self->private_impl.magic = WUFFS_BASE__MAGIC;
52952   self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
52953       wuffs_base__image_decoder__vtable_name;
52954   self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
52955       (const void*)(&wuffs_png__decoder__func_ptrs_for__wuffs_base__image_decoder);
52956   return wuffs_base__make_status(NULL);
52957 }
52958 
52959 wuffs_png__decoder*
wuffs_png__decoder__alloc(void)52960 wuffs_png__decoder__alloc(void) {
52961   wuffs_png__decoder* x =
52962       (wuffs_png__decoder*)(calloc(sizeof(wuffs_png__decoder), 1));
52963   if (!x) {
52964     return NULL;
52965   }
52966   if (wuffs_png__decoder__initialize(
52967       x, sizeof(wuffs_png__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
52968     free(x);
52969     return NULL;
52970   }
52971   return x;
52972 }
52973 
52974 size_t
sizeof__wuffs_png__decoder(void)52975 sizeof__wuffs_png__decoder(void) {
52976   return sizeof(wuffs_png__decoder);
52977 }
52978 
52979 // ---------------- Function Implementations
52980 
52981 // ‼ WUFFS MULTI-FILE SECTION +arm_neon
52982 // -------- func png.decoder.filter_1_distance_4_arm_neon
52983 
52984 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
52985 WUFFS_BASE__GENERATED_C_CODE
52986 static wuffs_base__empty_struct
wuffs_png__decoder__filter_1_distance_4_arm_neon(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr)52987 wuffs_png__decoder__filter_1_distance_4_arm_neon(
52988     wuffs_png__decoder* self,
52989     wuffs_base__slice_u8 a_curr) {
52990   wuffs_base__slice_u8 v_curr = {0};
52991   uint8x8_t v_fa = {0};
52992   uint8x8_t v_fx = {0};
52993 
52994   {
52995     wuffs_base__slice_u8 i_slice_curr = a_curr;
52996     v_curr.ptr = i_slice_curr.ptr;
52997     v_curr.len = 4;
52998     uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
52999     while (v_curr.ptr < i_end0_curr) {
53000       v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
53001       v_fx = vadd_u8(v_fx, v_fa);
53002       wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
53003       v_fa = v_fx;
53004       v_curr.ptr += 4;
53005       v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
53006       v_fx = vadd_u8(v_fx, v_fa);
53007       wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
53008       v_fa = v_fx;
53009       v_curr.ptr += 4;
53010     }
53011     v_curr.len = 4;
53012     uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
53013     while (v_curr.ptr < i_end1_curr) {
53014       v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
53015       v_fx = vadd_u8(v_fx, v_fa);
53016       wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
53017       v_fa = v_fx;
53018       v_curr.ptr += 4;
53019     }
53020     v_curr.len = 0;
53021   }
53022   return wuffs_base__make_empty_struct();
53023 }
53024 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
53025 // ‼ WUFFS MULTI-FILE SECTION -arm_neon
53026 
53027 // ‼ WUFFS MULTI-FILE SECTION +arm_neon
53028 // -------- func png.decoder.filter_3_distance_4_arm_neon
53029 
53030 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
53031 WUFFS_BASE__GENERATED_C_CODE
53032 static wuffs_base__empty_struct
wuffs_png__decoder__filter_3_distance_4_arm_neon(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr,wuffs_base__slice_u8 a_prev)53033 wuffs_png__decoder__filter_3_distance_4_arm_neon(
53034     wuffs_png__decoder* self,
53035     wuffs_base__slice_u8 a_curr,
53036     wuffs_base__slice_u8 a_prev) {
53037   wuffs_base__slice_u8 v_curr = {0};
53038   wuffs_base__slice_u8 v_prev = {0};
53039   uint8x8_t v_fa = {0};
53040   uint8x8_t v_fb = {0};
53041   uint8x8_t v_fx = {0};
53042 
53043   if (((uint64_t)(a_prev.len)) == 0u) {
53044     {
53045       wuffs_base__slice_u8 i_slice_curr = a_curr;
53046       v_curr.ptr = i_slice_curr.ptr;
53047       v_curr.len = 4;
53048       uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
53049       while (v_curr.ptr < i_end0_curr) {
53050         v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
53051         v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb));
53052         wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
53053         v_fa = v_fx;
53054         v_curr.ptr += 4;
53055         v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
53056         v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb));
53057         wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
53058         v_fa = v_fx;
53059         v_curr.ptr += 4;
53060       }
53061       v_curr.len = 4;
53062       uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
53063       while (v_curr.ptr < i_end1_curr) {
53064         v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
53065         v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb));
53066         wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
53067         v_fa = v_fx;
53068         v_curr.ptr += 4;
53069       }
53070       v_curr.len = 0;
53071     }
53072   } else {
53073     {
53074       wuffs_base__slice_u8 i_slice_curr = a_curr;
53075       v_curr.ptr = i_slice_curr.ptr;
53076       wuffs_base__slice_u8 i_slice_prev = a_prev;
53077       v_prev.ptr = i_slice_prev.ptr;
53078       i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
53079       v_curr.len = 4;
53080       v_prev.len = 4;
53081       uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
53082       while (v_curr.ptr < i_end0_curr) {
53083         v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
53084         v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
53085         v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb));
53086         wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
53087         v_fa = v_fx;
53088         v_curr.ptr += 4;
53089         v_prev.ptr += 4;
53090         v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
53091         v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
53092         v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb));
53093         wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
53094         v_fa = v_fx;
53095         v_curr.ptr += 4;
53096         v_prev.ptr += 4;
53097       }
53098       v_curr.len = 4;
53099       v_prev.len = 4;
53100       uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
53101       while (v_curr.ptr < i_end1_curr) {
53102         v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
53103         v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
53104         v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb));
53105         wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
53106         v_fa = v_fx;
53107         v_curr.ptr += 4;
53108         v_prev.ptr += 4;
53109       }
53110       v_curr.len = 0;
53111       v_prev.len = 0;
53112     }
53113   }
53114   return wuffs_base__make_empty_struct();
53115 }
53116 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
53117 // ‼ WUFFS MULTI-FILE SECTION -arm_neon
53118 
53119 // ‼ WUFFS MULTI-FILE SECTION +arm_neon
53120 // -------- func png.decoder.filter_4_distance_3_arm_neon
53121 
53122 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
53123 WUFFS_BASE__GENERATED_C_CODE
53124 static wuffs_base__empty_struct
wuffs_png__decoder__filter_4_distance_3_arm_neon(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr,wuffs_base__slice_u8 a_prev)53125 wuffs_png__decoder__filter_4_distance_3_arm_neon(
53126     wuffs_png__decoder* self,
53127     wuffs_base__slice_u8 a_curr,
53128     wuffs_base__slice_u8 a_prev) {
53129   wuffs_base__slice_u8 v_curr = {0};
53130   wuffs_base__slice_u8 v_prev = {0};
53131   uint8x8_t v_fa = {0};
53132   uint8x8_t v_fb = {0};
53133   uint8x8_t v_fc = {0};
53134   uint8x8_t v_fx = {0};
53135   uint16x8_t v_fafb = {0};
53136   uint16x8_t v_fcfc = {0};
53137   uint16x8_t v_pa = {0};
53138   uint16x8_t v_pb = {0};
53139   uint16x8_t v_pc = {0};
53140   uint16x8_t v_cmpab = {0};
53141   uint16x8_t v_cmpac = {0};
53142   uint8x8_t v_picka = {0};
53143   uint8x8_t v_pickb = {0};
53144 
53145   {
53146     wuffs_base__slice_u8 i_slice_curr = a_curr;
53147     v_curr.ptr = i_slice_curr.ptr;
53148     wuffs_base__slice_u8 i_slice_prev = a_prev;
53149     v_prev.ptr = i_slice_prev.ptr;
53150     i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
53151     v_curr.len = 4;
53152     v_prev.len = 4;
53153     uint8_t* i_end0_curr = v_curr.ptr + wuffs_base__iterate_total_advance((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)), 7, 6);
53154     while (v_curr.ptr < i_end0_curr) {
53155       v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
53156       v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
53157       v_fafb = vaddl_u8(v_fa, v_fb);
53158       v_fcfc = vaddl_u8(v_fc, v_fc);
53159       v_pa = vabdl_u8(v_fb, v_fc);
53160       v_pb = vabdl_u8(v_fa, v_fc);
53161       v_pc = vabdq_u16(v_fafb, v_fcfc);
53162       v_cmpab = vcleq_u16(v_pa, v_pb);
53163       v_cmpac = vcleq_u16(v_pa, v_pc);
53164       v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
53165       v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
53166       v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
53167       wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
53168       v_fc = v_fb;
53169       v_fa = v_fx;
53170       v_curr.ptr += 3;
53171       v_prev.ptr += 3;
53172       v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
53173       v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
53174       v_fafb = vaddl_u8(v_fa, v_fb);
53175       v_fcfc = vaddl_u8(v_fc, v_fc);
53176       v_pa = vabdl_u8(v_fb, v_fc);
53177       v_pb = vabdl_u8(v_fa, v_fc);
53178       v_pc = vabdq_u16(v_fafb, v_fcfc);
53179       v_cmpab = vcleq_u16(v_pa, v_pb);
53180       v_cmpac = vcleq_u16(v_pa, v_pc);
53181       v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
53182       v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
53183       v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
53184       wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
53185       v_fc = v_fb;
53186       v_fa = v_fx;
53187       v_curr.ptr += 3;
53188       v_prev.ptr += 3;
53189     }
53190     v_curr.len = 4;
53191     v_prev.len = 4;
53192     uint8_t* i_end1_curr = v_curr.ptr + wuffs_base__iterate_total_advance((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)), 4, 3);
53193     while (v_curr.ptr < i_end1_curr) {
53194       v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
53195       v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
53196       v_fafb = vaddl_u8(v_fa, v_fb);
53197       v_fcfc = vaddl_u8(v_fc, v_fc);
53198       v_pa = vabdl_u8(v_fb, v_fc);
53199       v_pb = vabdl_u8(v_fa, v_fc);
53200       v_pc = vabdq_u16(v_fafb, v_fcfc);
53201       v_cmpab = vcleq_u16(v_pa, v_pb);
53202       v_cmpac = vcleq_u16(v_pa, v_pc);
53203       v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
53204       v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
53205       v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
53206       wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
53207       v_fc = v_fb;
53208       v_fa = v_fx;
53209       v_curr.ptr += 3;
53210       v_prev.ptr += 3;
53211     }
53212     v_curr.len = 3;
53213     v_prev.len = 3;
53214     uint8_t* i_end2_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3);
53215     while (v_curr.ptr < i_end2_curr) {
53216       v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u24le__no_bounds_check(v_prev.ptr)));
53217       v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u24le__no_bounds_check(v_curr.ptr)));
53218       v_fafb = vaddl_u8(v_fa, v_fb);
53219       v_fcfc = vaddl_u8(v_fc, v_fc);
53220       v_pa = vabdl_u8(v_fb, v_fc);
53221       v_pb = vabdl_u8(v_fa, v_fc);
53222       v_pc = vabdq_u16(v_fafb, v_fcfc);
53223       v_cmpab = vcleq_u16(v_pa, v_pb);
53224       v_cmpac = vcleq_u16(v_pa, v_pc);
53225       v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
53226       v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
53227       v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
53228       wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
53229       v_curr.ptr += 3;
53230       v_prev.ptr += 3;
53231     }
53232     v_curr.len = 0;
53233     v_prev.len = 0;
53234   }
53235   return wuffs_base__make_empty_struct();
53236 }
53237 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
53238 // ‼ WUFFS MULTI-FILE SECTION -arm_neon
53239 
53240 // ‼ WUFFS MULTI-FILE SECTION +arm_neon
53241 // -------- func png.decoder.filter_4_distance_4_arm_neon
53242 
53243 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
53244 WUFFS_BASE__GENERATED_C_CODE
53245 static wuffs_base__empty_struct
wuffs_png__decoder__filter_4_distance_4_arm_neon(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr,wuffs_base__slice_u8 a_prev)53246 wuffs_png__decoder__filter_4_distance_4_arm_neon(
53247     wuffs_png__decoder* self,
53248     wuffs_base__slice_u8 a_curr,
53249     wuffs_base__slice_u8 a_prev) {
53250   wuffs_base__slice_u8 v_curr = {0};
53251   wuffs_base__slice_u8 v_prev = {0};
53252   uint8x8_t v_fa = {0};
53253   uint8x8_t v_fb = {0};
53254   uint8x8_t v_fc = {0};
53255   uint8x8_t v_fx = {0};
53256   uint16x8_t v_fafb = {0};
53257   uint16x8_t v_fcfc = {0};
53258   uint16x8_t v_pa = {0};
53259   uint16x8_t v_pb = {0};
53260   uint16x8_t v_pc = {0};
53261   uint16x8_t v_cmpab = {0};
53262   uint16x8_t v_cmpac = {0};
53263   uint8x8_t v_picka = {0};
53264   uint8x8_t v_pickb = {0};
53265 
53266   {
53267     wuffs_base__slice_u8 i_slice_curr = a_curr;
53268     v_curr.ptr = i_slice_curr.ptr;
53269     wuffs_base__slice_u8 i_slice_prev = a_prev;
53270     v_prev.ptr = i_slice_prev.ptr;
53271     i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
53272     v_curr.len = 4;
53273     v_prev.len = 4;
53274     uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
53275     while (v_curr.ptr < i_end0_curr) {
53276       v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
53277       v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
53278       v_fafb = vaddl_u8(v_fa, v_fb);
53279       v_fcfc = vaddl_u8(v_fc, v_fc);
53280       v_pa = vabdl_u8(v_fb, v_fc);
53281       v_pb = vabdl_u8(v_fa, v_fc);
53282       v_pc = vabdq_u16(v_fafb, v_fcfc);
53283       v_cmpab = vcleq_u16(v_pa, v_pb);
53284       v_cmpac = vcleq_u16(v_pa, v_pc);
53285       v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
53286       v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
53287       v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
53288       wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
53289       v_fc = v_fb;
53290       v_fa = v_fx;
53291       v_curr.ptr += 4;
53292       v_prev.ptr += 4;
53293       v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
53294       v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
53295       v_fafb = vaddl_u8(v_fa, v_fb);
53296       v_fcfc = vaddl_u8(v_fc, v_fc);
53297       v_pa = vabdl_u8(v_fb, v_fc);
53298       v_pb = vabdl_u8(v_fa, v_fc);
53299       v_pc = vabdq_u16(v_fafb, v_fcfc);
53300       v_cmpab = vcleq_u16(v_pa, v_pb);
53301       v_cmpac = vcleq_u16(v_pa, v_pc);
53302       v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
53303       v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
53304       v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
53305       wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
53306       v_fc = v_fb;
53307       v_fa = v_fx;
53308       v_curr.ptr += 4;
53309       v_prev.ptr += 4;
53310     }
53311     v_curr.len = 4;
53312     v_prev.len = 4;
53313     uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
53314     while (v_curr.ptr < i_end1_curr) {
53315       v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
53316       v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
53317       v_fafb = vaddl_u8(v_fa, v_fb);
53318       v_fcfc = vaddl_u8(v_fc, v_fc);
53319       v_pa = vabdl_u8(v_fb, v_fc);
53320       v_pb = vabdl_u8(v_fa, v_fc);
53321       v_pc = vabdq_u16(v_fafb, v_fcfc);
53322       v_cmpab = vcleq_u16(v_pa, v_pb);
53323       v_cmpac = vcleq_u16(v_pa, v_pc);
53324       v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
53325       v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
53326       v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
53327       wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
53328       v_fc = v_fb;
53329       v_fa = v_fx;
53330       v_curr.ptr += 4;
53331       v_prev.ptr += 4;
53332     }
53333     v_curr.len = 0;
53334     v_prev.len = 0;
53335   }
53336   return wuffs_base__make_empty_struct();
53337 }
53338 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
53339 // ‼ WUFFS MULTI-FILE SECTION -arm_neon
53340 
53341 // -------- func png.decoder.filter_1
53342 
53343 WUFFS_BASE__GENERATED_C_CODE
53344 static wuffs_base__empty_struct
wuffs_png__decoder__filter_1(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr)53345 wuffs_png__decoder__filter_1(
53346     wuffs_png__decoder* self,
53347     wuffs_base__slice_u8 a_curr) {
53348   return (*self->private_impl.choosy_filter_1)(self, a_curr);
53349 }
53350 
53351 WUFFS_BASE__GENERATED_C_CODE
53352 static wuffs_base__empty_struct
wuffs_png__decoder__filter_1__choosy_default(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr)53353 wuffs_png__decoder__filter_1__choosy_default(
53354     wuffs_png__decoder* self,
53355     wuffs_base__slice_u8 a_curr) {
53356   uint64_t v_filter_distance = 0;
53357   uint8_t v_fa = 0;
53358   uint64_t v_i_start = 0;
53359   uint64_t v_i = 0;
53360 
53361   v_filter_distance = ((uint64_t)(self->private_impl.f_filter_distance));
53362   v_i_start = 0u;
53363   while (v_i_start < v_filter_distance) {
53364     v_fa = 0u;
53365     v_i = v_i_start;
53366     while (v_i < ((uint64_t)(a_curr.len))) {
53367       a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + v_fa));
53368       v_fa = a_curr.ptr[v_i];
53369       v_i += v_filter_distance;
53370     }
53371     v_i_start += 1u;
53372   }
53373   return wuffs_base__make_empty_struct();
53374 }
53375 
53376 // -------- func png.decoder.filter_1_distance_3_fallback
53377 
53378 WUFFS_BASE__GENERATED_C_CODE
53379 static wuffs_base__empty_struct
wuffs_png__decoder__filter_1_distance_3_fallback(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr)53380 wuffs_png__decoder__filter_1_distance_3_fallback(
53381     wuffs_png__decoder* self,
53382     wuffs_base__slice_u8 a_curr) {
53383   wuffs_base__slice_u8 v_curr = {0};
53384   uint8_t v_fa0 = 0;
53385   uint8_t v_fa1 = 0;
53386   uint8_t v_fa2 = 0;
53387 
53388   {
53389     wuffs_base__slice_u8 i_slice_curr = a_curr;
53390     v_curr.ptr = i_slice_curr.ptr;
53391     v_curr.len = 3;
53392     uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 6) * 6);
53393     while (v_curr.ptr < i_end0_curr) {
53394       v_fa0 = ((uint8_t)(v_fa0 + v_curr.ptr[0u]));
53395       v_curr.ptr[0u] = v_fa0;
53396       v_fa1 = ((uint8_t)(v_fa1 + v_curr.ptr[1u]));
53397       v_curr.ptr[1u] = v_fa1;
53398       v_fa2 = ((uint8_t)(v_fa2 + v_curr.ptr[2u]));
53399       v_curr.ptr[2u] = v_fa2;
53400       v_curr.ptr += 3;
53401       v_fa0 = ((uint8_t)(v_fa0 + v_curr.ptr[0u]));
53402       v_curr.ptr[0u] = v_fa0;
53403       v_fa1 = ((uint8_t)(v_fa1 + v_curr.ptr[1u]));
53404       v_curr.ptr[1u] = v_fa1;
53405       v_fa2 = ((uint8_t)(v_fa2 + v_curr.ptr[2u]));
53406       v_curr.ptr[2u] = v_fa2;
53407       v_curr.ptr += 3;
53408     }
53409     v_curr.len = 3;
53410     uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3);
53411     while (v_curr.ptr < i_end1_curr) {
53412       v_fa0 = ((uint8_t)(v_fa0 + v_curr.ptr[0u]));
53413       v_curr.ptr[0u] = v_fa0;
53414       v_fa1 = ((uint8_t)(v_fa1 + v_curr.ptr[1u]));
53415       v_curr.ptr[1u] = v_fa1;
53416       v_fa2 = ((uint8_t)(v_fa2 + v_curr.ptr[2u]));
53417       v_curr.ptr[2u] = v_fa2;
53418       v_curr.ptr += 3;
53419     }
53420     v_curr.len = 0;
53421   }
53422   return wuffs_base__make_empty_struct();
53423 }
53424 
53425 // -------- func png.decoder.filter_1_distance_4_fallback
53426 
53427 WUFFS_BASE__GENERATED_C_CODE
53428 static wuffs_base__empty_struct
wuffs_png__decoder__filter_1_distance_4_fallback(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr)53429 wuffs_png__decoder__filter_1_distance_4_fallback(
53430     wuffs_png__decoder* self,
53431     wuffs_base__slice_u8 a_curr) {
53432   wuffs_base__slice_u8 v_curr = {0};
53433   uint8_t v_fa0 = 0;
53434   uint8_t v_fa1 = 0;
53435   uint8_t v_fa2 = 0;
53436   uint8_t v_fa3 = 0;
53437 
53438   {
53439     wuffs_base__slice_u8 i_slice_curr = a_curr;
53440     v_curr.ptr = i_slice_curr.ptr;
53441     v_curr.len = 4;
53442     uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
53443     while (v_curr.ptr < i_end0_curr) {
53444       v_fa0 = ((uint8_t)(v_fa0 + v_curr.ptr[0u]));
53445       v_curr.ptr[0u] = v_fa0;
53446       v_fa1 = ((uint8_t)(v_fa1 + v_curr.ptr[1u]));
53447       v_curr.ptr[1u] = v_fa1;
53448       v_fa2 = ((uint8_t)(v_fa2 + v_curr.ptr[2u]));
53449       v_curr.ptr[2u] = v_fa2;
53450       v_fa3 = ((uint8_t)(v_fa3 + v_curr.ptr[3u]));
53451       v_curr.ptr[3u] = v_fa3;
53452       v_curr.ptr += 4;
53453     }
53454     v_curr.len = 0;
53455   }
53456   return wuffs_base__make_empty_struct();
53457 }
53458 
53459 // -------- func png.decoder.filter_2
53460 
53461 WUFFS_BASE__GENERATED_C_CODE
53462 static wuffs_base__empty_struct
wuffs_png__decoder__filter_2(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr,wuffs_base__slice_u8 a_prev)53463 wuffs_png__decoder__filter_2(
53464     wuffs_png__decoder* self,
53465     wuffs_base__slice_u8 a_curr,
53466     wuffs_base__slice_u8 a_prev) {
53467   uint64_t v_n = 0;
53468   uint64_t v_i = 0;
53469 
53470   v_n = wuffs_base__u64__min(((uint64_t)(a_curr.len)), ((uint64_t)(a_prev.len)));
53471   v_i = 0u;
53472   while (v_i < v_n) {
53473     a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + a_prev.ptr[v_i]));
53474     v_i += 1u;
53475   }
53476   return wuffs_base__make_empty_struct();
53477 }
53478 
53479 // -------- func png.decoder.filter_3
53480 
53481 WUFFS_BASE__GENERATED_C_CODE
53482 static wuffs_base__empty_struct
wuffs_png__decoder__filter_3(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr,wuffs_base__slice_u8 a_prev)53483 wuffs_png__decoder__filter_3(
53484     wuffs_png__decoder* self,
53485     wuffs_base__slice_u8 a_curr,
53486     wuffs_base__slice_u8 a_prev) {
53487   return (*self->private_impl.choosy_filter_3)(self, a_curr, a_prev);
53488 }
53489 
53490 WUFFS_BASE__GENERATED_C_CODE
53491 static wuffs_base__empty_struct
wuffs_png__decoder__filter_3__choosy_default(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr,wuffs_base__slice_u8 a_prev)53492 wuffs_png__decoder__filter_3__choosy_default(
53493     wuffs_png__decoder* self,
53494     wuffs_base__slice_u8 a_curr,
53495     wuffs_base__slice_u8 a_prev) {
53496   uint64_t v_filter_distance = 0;
53497   uint64_t v_n = 0;
53498   uint64_t v_i = 0;
53499 
53500   v_filter_distance = ((uint64_t)(self->private_impl.f_filter_distance));
53501   if (((uint64_t)(a_prev.len)) == 0u) {
53502     v_i = v_filter_distance;
53503     while (v_i < ((uint64_t)(a_curr.len))) {
53504       a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + (a_curr.ptr[(v_i - v_filter_distance)] / 2u)));
53505       v_i += 1u;
53506     }
53507   } else {
53508     v_n = wuffs_base__u64__min(((uint64_t)(a_curr.len)), ((uint64_t)(a_prev.len)));
53509     v_i = 0u;
53510     while ((v_i < v_n) && (v_i < v_filter_distance)) {
53511       a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + (a_prev.ptr[v_i] / 2u)));
53512       v_i += 1u;
53513     }
53514     v_i = v_filter_distance;
53515     while (v_i < v_n) {
53516       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)))));
53517       v_i += 1u;
53518     }
53519   }
53520   return wuffs_base__make_empty_struct();
53521 }
53522 
53523 // -------- func png.decoder.filter_3_distance_3_fallback
53524 
53525 WUFFS_BASE__GENERATED_C_CODE
53526 static wuffs_base__empty_struct
wuffs_png__decoder__filter_3_distance_3_fallback(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr,wuffs_base__slice_u8 a_prev)53527 wuffs_png__decoder__filter_3_distance_3_fallback(
53528     wuffs_png__decoder* self,
53529     wuffs_base__slice_u8 a_curr,
53530     wuffs_base__slice_u8 a_prev) {
53531   wuffs_base__slice_u8 v_curr = {0};
53532   wuffs_base__slice_u8 v_prev = {0};
53533   uint8_t v_fa0 = 0;
53534   uint8_t v_fa1 = 0;
53535   uint8_t v_fa2 = 0;
53536 
53537   if (((uint64_t)(a_prev.len)) == 0u) {
53538     {
53539       wuffs_base__slice_u8 i_slice_curr = a_curr;
53540       v_curr.ptr = i_slice_curr.ptr;
53541       v_curr.len = 3;
53542       uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 6) * 6);
53543       while (v_curr.ptr < i_end0_curr) {
53544         v_fa0 = ((uint8_t)((v_fa0 / 2u) + v_curr.ptr[0u]));
53545         v_curr.ptr[0u] = v_fa0;
53546         v_fa1 = ((uint8_t)((v_fa1 / 2u) + v_curr.ptr[1u]));
53547         v_curr.ptr[1u] = v_fa1;
53548         v_fa2 = ((uint8_t)((v_fa2 / 2u) + v_curr.ptr[2u]));
53549         v_curr.ptr[2u] = v_fa2;
53550         v_curr.ptr += 3;
53551         v_fa0 = ((uint8_t)((v_fa0 / 2u) + v_curr.ptr[0u]));
53552         v_curr.ptr[0u] = v_fa0;
53553         v_fa1 = ((uint8_t)((v_fa1 / 2u) + v_curr.ptr[1u]));
53554         v_curr.ptr[1u] = v_fa1;
53555         v_fa2 = ((uint8_t)((v_fa2 / 2u) + v_curr.ptr[2u]));
53556         v_curr.ptr[2u] = v_fa2;
53557         v_curr.ptr += 3;
53558       }
53559       v_curr.len = 3;
53560       uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3);
53561       while (v_curr.ptr < i_end1_curr) {
53562         v_fa0 = ((uint8_t)((v_fa0 / 2u) + v_curr.ptr[0u]));
53563         v_curr.ptr[0u] = v_fa0;
53564         v_fa1 = ((uint8_t)((v_fa1 / 2u) + v_curr.ptr[1u]));
53565         v_curr.ptr[1u] = v_fa1;
53566         v_fa2 = ((uint8_t)((v_fa2 / 2u) + v_curr.ptr[2u]));
53567         v_curr.ptr[2u] = v_fa2;
53568         v_curr.ptr += 3;
53569       }
53570       v_curr.len = 0;
53571     }
53572   } else {
53573     {
53574       wuffs_base__slice_u8 i_slice_curr = a_curr;
53575       v_curr.ptr = i_slice_curr.ptr;
53576       wuffs_base__slice_u8 i_slice_prev = a_prev;
53577       v_prev.ptr = i_slice_prev.ptr;
53578       i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
53579       v_curr.len = 3;
53580       v_prev.len = 3;
53581       uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 6) * 6);
53582       while (v_curr.ptr < i_end0_curr) {
53583         v_fa0 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa0)) + ((uint32_t)(v_prev.ptr[0u]))) / 2u))) + v_curr.ptr[0u]));
53584         v_curr.ptr[0u] = v_fa0;
53585         v_fa1 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa1)) + ((uint32_t)(v_prev.ptr[1u]))) / 2u))) + v_curr.ptr[1u]));
53586         v_curr.ptr[1u] = v_fa1;
53587         v_fa2 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa2)) + ((uint32_t)(v_prev.ptr[2u]))) / 2u))) + v_curr.ptr[2u]));
53588         v_curr.ptr[2u] = v_fa2;
53589         v_curr.ptr += 3;
53590         v_prev.ptr += 3;
53591         v_fa0 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa0)) + ((uint32_t)(v_prev.ptr[0u]))) / 2u))) + v_curr.ptr[0u]));
53592         v_curr.ptr[0u] = v_fa0;
53593         v_fa1 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa1)) + ((uint32_t)(v_prev.ptr[1u]))) / 2u))) + v_curr.ptr[1u]));
53594         v_curr.ptr[1u] = v_fa1;
53595         v_fa2 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa2)) + ((uint32_t)(v_prev.ptr[2u]))) / 2u))) + v_curr.ptr[2u]));
53596         v_curr.ptr[2u] = v_fa2;
53597         v_curr.ptr += 3;
53598         v_prev.ptr += 3;
53599       }
53600       v_curr.len = 3;
53601       v_prev.len = 3;
53602       uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3);
53603       while (v_curr.ptr < i_end1_curr) {
53604         v_fa0 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa0)) + ((uint32_t)(v_prev.ptr[0u]))) / 2u))) + v_curr.ptr[0u]));
53605         v_curr.ptr[0u] = v_fa0;
53606         v_fa1 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa1)) + ((uint32_t)(v_prev.ptr[1u]))) / 2u))) + v_curr.ptr[1u]));
53607         v_curr.ptr[1u] = v_fa1;
53608         v_fa2 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa2)) + ((uint32_t)(v_prev.ptr[2u]))) / 2u))) + v_curr.ptr[2u]));
53609         v_curr.ptr[2u] = v_fa2;
53610         v_curr.ptr += 3;
53611         v_prev.ptr += 3;
53612       }
53613       v_curr.len = 0;
53614       v_prev.len = 0;
53615     }
53616   }
53617   return wuffs_base__make_empty_struct();
53618 }
53619 
53620 // -------- func png.decoder.filter_3_distance_4_fallback
53621 
53622 WUFFS_BASE__GENERATED_C_CODE
53623 static wuffs_base__empty_struct
wuffs_png__decoder__filter_3_distance_4_fallback(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr,wuffs_base__slice_u8 a_prev)53624 wuffs_png__decoder__filter_3_distance_4_fallback(
53625     wuffs_png__decoder* self,
53626     wuffs_base__slice_u8 a_curr,
53627     wuffs_base__slice_u8 a_prev) {
53628   wuffs_base__slice_u8 v_curr = {0};
53629   wuffs_base__slice_u8 v_prev = {0};
53630   uint8_t v_fa0 = 0;
53631   uint8_t v_fa1 = 0;
53632   uint8_t v_fa2 = 0;
53633   uint8_t v_fa3 = 0;
53634 
53635   if (((uint64_t)(a_prev.len)) == 0u) {
53636     {
53637       wuffs_base__slice_u8 i_slice_curr = a_curr;
53638       v_curr.ptr = i_slice_curr.ptr;
53639       v_curr.len = 4;
53640       uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
53641       while (v_curr.ptr < i_end0_curr) {
53642         v_fa0 = ((uint8_t)((v_fa0 / 2u) + v_curr.ptr[0u]));
53643         v_curr.ptr[0u] = v_fa0;
53644         v_fa1 = ((uint8_t)((v_fa1 / 2u) + v_curr.ptr[1u]));
53645         v_curr.ptr[1u] = v_fa1;
53646         v_fa2 = ((uint8_t)((v_fa2 / 2u) + v_curr.ptr[2u]));
53647         v_curr.ptr[2u] = v_fa2;
53648         v_fa3 = ((uint8_t)((v_fa3 / 2u) + v_curr.ptr[3u]));
53649         v_curr.ptr[3u] = v_fa3;
53650         v_curr.ptr += 4;
53651       }
53652       v_curr.len = 0;
53653     }
53654   } else {
53655     {
53656       wuffs_base__slice_u8 i_slice_curr = a_curr;
53657       v_curr.ptr = i_slice_curr.ptr;
53658       wuffs_base__slice_u8 i_slice_prev = a_prev;
53659       v_prev.ptr = i_slice_prev.ptr;
53660       i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
53661       v_curr.len = 4;
53662       v_prev.len = 4;
53663       uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
53664       while (v_curr.ptr < i_end0_curr) {
53665         v_fa0 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa0)) + ((uint32_t)(v_prev.ptr[0u]))) / 2u))) + v_curr.ptr[0u]));
53666         v_curr.ptr[0u] = v_fa0;
53667         v_fa1 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa1)) + ((uint32_t)(v_prev.ptr[1u]))) / 2u))) + v_curr.ptr[1u]));
53668         v_curr.ptr[1u] = v_fa1;
53669         v_fa2 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa2)) + ((uint32_t)(v_prev.ptr[2u]))) / 2u))) + v_curr.ptr[2u]));
53670         v_curr.ptr[2u] = v_fa2;
53671         v_fa3 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa3)) + ((uint32_t)(v_prev.ptr[3u]))) / 2u))) + v_curr.ptr[3u]));
53672         v_curr.ptr[3u] = v_fa3;
53673         v_curr.ptr += 4;
53674         v_prev.ptr += 4;
53675       }
53676       v_curr.len = 0;
53677       v_prev.len = 0;
53678     }
53679   }
53680   return wuffs_base__make_empty_struct();
53681 }
53682 
53683 // -------- func png.decoder.filter_4
53684 
53685 WUFFS_BASE__GENERATED_C_CODE
53686 static wuffs_base__empty_struct
wuffs_png__decoder__filter_4(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr,wuffs_base__slice_u8 a_prev)53687 wuffs_png__decoder__filter_4(
53688     wuffs_png__decoder* self,
53689     wuffs_base__slice_u8 a_curr,
53690     wuffs_base__slice_u8 a_prev) {
53691   return (*self->private_impl.choosy_filter_4)(self, a_curr, a_prev);
53692 }
53693 
53694 WUFFS_BASE__GENERATED_C_CODE
53695 static wuffs_base__empty_struct
wuffs_png__decoder__filter_4__choosy_default(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr,wuffs_base__slice_u8 a_prev)53696 wuffs_png__decoder__filter_4__choosy_default(
53697     wuffs_png__decoder* self,
53698     wuffs_base__slice_u8 a_curr,
53699     wuffs_base__slice_u8 a_prev) {
53700   uint64_t v_filter_distance = 0;
53701   uint64_t v_n = 0;
53702   uint64_t v_i = 0;
53703   uint32_t v_fa = 0;
53704   uint32_t v_fb = 0;
53705   uint32_t v_fc = 0;
53706   uint32_t v_pp = 0;
53707   uint32_t v_pa = 0;
53708   uint32_t v_pb = 0;
53709   uint32_t v_pc = 0;
53710 
53711   v_filter_distance = ((uint64_t)(self->private_impl.f_filter_distance));
53712   v_n = wuffs_base__u64__min(((uint64_t)(a_curr.len)), ((uint64_t)(a_prev.len)));
53713   v_i = 0u;
53714   while ((v_i < v_n) && (v_i < v_filter_distance)) {
53715     a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + a_prev.ptr[v_i]));
53716     v_i += 1u;
53717   }
53718   v_i = v_filter_distance;
53719   while (v_i < v_n) {
53720     v_fa = ((uint32_t)(a_curr.ptr[(v_i - v_filter_distance)]));
53721     v_fb = ((uint32_t)(a_prev.ptr[v_i]));
53722     v_fc = ((uint32_t)(a_prev.ptr[(v_i - v_filter_distance)]));
53723     v_pp = ((uint32_t)(((uint32_t)(v_fa + v_fb)) - v_fc));
53724     v_pa = ((uint32_t)(v_pp - v_fa));
53725     if (v_pa >= 2147483648u) {
53726       v_pa = ((uint32_t)(0u - v_pa));
53727     }
53728     v_pb = ((uint32_t)(v_pp - v_fb));
53729     if (v_pb >= 2147483648u) {
53730       v_pb = ((uint32_t)(0u - v_pb));
53731     }
53732     v_pc = ((uint32_t)(v_pp - v_fc));
53733     if (v_pc >= 2147483648u) {
53734       v_pc = ((uint32_t)(0u - v_pc));
53735     }
53736     if ((v_pa <= v_pb) && (v_pa <= v_pc)) {
53737     } else if (v_pb <= v_pc) {
53738       v_fa = v_fb;
53739     } else {
53740       v_fa = v_fc;
53741     }
53742     a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + ((uint8_t)(v_fa))));
53743     v_i += 1u;
53744   }
53745   return wuffs_base__make_empty_struct();
53746 }
53747 
53748 // -------- func png.decoder.filter_4_distance_3_fallback
53749 
53750 WUFFS_BASE__GENERATED_C_CODE
53751 static wuffs_base__empty_struct
wuffs_png__decoder__filter_4_distance_3_fallback(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr,wuffs_base__slice_u8 a_prev)53752 wuffs_png__decoder__filter_4_distance_3_fallback(
53753     wuffs_png__decoder* self,
53754     wuffs_base__slice_u8 a_curr,
53755     wuffs_base__slice_u8 a_prev) {
53756   wuffs_base__slice_u8 v_curr = {0};
53757   wuffs_base__slice_u8 v_prev = {0};
53758   uint32_t v_fa0 = 0;
53759   uint32_t v_fa1 = 0;
53760   uint32_t v_fa2 = 0;
53761   uint32_t v_fb0 = 0;
53762   uint32_t v_fb1 = 0;
53763   uint32_t v_fb2 = 0;
53764   uint32_t v_fc0 = 0;
53765   uint32_t v_fc1 = 0;
53766   uint32_t v_fc2 = 0;
53767   uint32_t v_pp0 = 0;
53768   uint32_t v_pp1 = 0;
53769   uint32_t v_pp2 = 0;
53770   uint32_t v_pa0 = 0;
53771   uint32_t v_pa1 = 0;
53772   uint32_t v_pa2 = 0;
53773   uint32_t v_pb0 = 0;
53774   uint32_t v_pb1 = 0;
53775   uint32_t v_pb2 = 0;
53776   uint32_t v_pc0 = 0;
53777   uint32_t v_pc1 = 0;
53778   uint32_t v_pc2 = 0;
53779 
53780   {
53781     wuffs_base__slice_u8 i_slice_curr = a_curr;
53782     v_curr.ptr = i_slice_curr.ptr;
53783     wuffs_base__slice_u8 i_slice_prev = a_prev;
53784     v_prev.ptr = i_slice_prev.ptr;
53785     i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
53786     v_curr.len = 3;
53787     v_prev.len = 3;
53788     uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3);
53789     while (v_curr.ptr < i_end0_curr) {
53790       v_fb0 = ((uint32_t)(v_prev.ptr[0u]));
53791       v_pp0 = ((uint32_t)(((uint32_t)(v_fa0 + v_fb0)) - v_fc0));
53792       v_pa0 = ((uint32_t)(v_pp0 - v_fa0));
53793       if (v_pa0 >= 2147483648u) {
53794         v_pa0 = ((uint32_t)(0u - v_pa0));
53795       }
53796       v_pb0 = ((uint32_t)(v_pp0 - v_fb0));
53797       if (v_pb0 >= 2147483648u) {
53798         v_pb0 = ((uint32_t)(0u - v_pb0));
53799       }
53800       v_pc0 = ((uint32_t)(v_pp0 - v_fc0));
53801       if (v_pc0 >= 2147483648u) {
53802         v_pc0 = ((uint32_t)(0u - v_pc0));
53803       }
53804       if ((v_pa0 <= v_pb0) && (v_pa0 <= v_pc0)) {
53805       } else if (v_pb0 <= v_pc0) {
53806         v_fa0 = v_fb0;
53807       } else {
53808         v_fa0 = v_fc0;
53809       }
53810       v_curr.ptr[0u] = ((uint8_t)(v_curr.ptr[0u] + ((uint8_t)(v_fa0))));
53811       v_fa0 = ((uint32_t)(v_curr.ptr[0u]));
53812       v_fc0 = v_fb0;
53813       v_fb1 = ((uint32_t)(v_prev.ptr[1u]));
53814       v_pp1 = ((uint32_t)(((uint32_t)(v_fa1 + v_fb1)) - v_fc1));
53815       v_pa1 = ((uint32_t)(v_pp1 - v_fa1));
53816       if (v_pa1 >= 2147483648u) {
53817         v_pa1 = ((uint32_t)(0u - v_pa1));
53818       }
53819       v_pb1 = ((uint32_t)(v_pp1 - v_fb1));
53820       if (v_pb1 >= 2147483648u) {
53821         v_pb1 = ((uint32_t)(0u - v_pb1));
53822       }
53823       v_pc1 = ((uint32_t)(v_pp1 - v_fc1));
53824       if (v_pc1 >= 2147483648u) {
53825         v_pc1 = ((uint32_t)(0u - v_pc1));
53826       }
53827       if ((v_pa1 <= v_pb1) && (v_pa1 <= v_pc1)) {
53828       } else if (v_pb1 <= v_pc1) {
53829         v_fa1 = v_fb1;
53830       } else {
53831         v_fa1 = v_fc1;
53832       }
53833       v_curr.ptr[1u] = ((uint8_t)(v_curr.ptr[1u] + ((uint8_t)(v_fa1))));
53834       v_fa1 = ((uint32_t)(v_curr.ptr[1u]));
53835       v_fc1 = v_fb1;
53836       v_fb2 = ((uint32_t)(v_prev.ptr[2u]));
53837       v_pp2 = ((uint32_t)(((uint32_t)(v_fa2 + v_fb2)) - v_fc2));
53838       v_pa2 = ((uint32_t)(v_pp2 - v_fa2));
53839       if (v_pa2 >= 2147483648u) {
53840         v_pa2 = ((uint32_t)(0u - v_pa2));
53841       }
53842       v_pb2 = ((uint32_t)(v_pp2 - v_fb2));
53843       if (v_pb2 >= 2147483648u) {
53844         v_pb2 = ((uint32_t)(0u - v_pb2));
53845       }
53846       v_pc2 = ((uint32_t)(v_pp2 - v_fc2));
53847       if (v_pc2 >= 2147483648u) {
53848         v_pc2 = ((uint32_t)(0u - v_pc2));
53849       }
53850       if ((v_pa2 <= v_pb2) && (v_pa2 <= v_pc2)) {
53851       } else if (v_pb2 <= v_pc2) {
53852         v_fa2 = v_fb2;
53853       } else {
53854         v_fa2 = v_fc2;
53855       }
53856       v_curr.ptr[2u] = ((uint8_t)(v_curr.ptr[2u] + ((uint8_t)(v_fa2))));
53857       v_fa2 = ((uint32_t)(v_curr.ptr[2u]));
53858       v_fc2 = v_fb2;
53859       v_curr.ptr += 3;
53860       v_prev.ptr += 3;
53861     }
53862     v_curr.len = 0;
53863     v_prev.len = 0;
53864   }
53865   return wuffs_base__make_empty_struct();
53866 }
53867 
53868 // -------- func png.decoder.filter_4_distance_4_fallback
53869 
53870 WUFFS_BASE__GENERATED_C_CODE
53871 static wuffs_base__empty_struct
wuffs_png__decoder__filter_4_distance_4_fallback(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr,wuffs_base__slice_u8 a_prev)53872 wuffs_png__decoder__filter_4_distance_4_fallback(
53873     wuffs_png__decoder* self,
53874     wuffs_base__slice_u8 a_curr,
53875     wuffs_base__slice_u8 a_prev) {
53876   wuffs_base__slice_u8 v_curr = {0};
53877   wuffs_base__slice_u8 v_prev = {0};
53878   uint32_t v_fa0 = 0;
53879   uint32_t v_fa1 = 0;
53880   uint32_t v_fa2 = 0;
53881   uint32_t v_fa3 = 0;
53882   uint32_t v_fb0 = 0;
53883   uint32_t v_fb1 = 0;
53884   uint32_t v_fb2 = 0;
53885   uint32_t v_fb3 = 0;
53886   uint32_t v_fc0 = 0;
53887   uint32_t v_fc1 = 0;
53888   uint32_t v_fc2 = 0;
53889   uint32_t v_fc3 = 0;
53890   uint32_t v_pp0 = 0;
53891   uint32_t v_pp1 = 0;
53892   uint32_t v_pp2 = 0;
53893   uint32_t v_pp3 = 0;
53894   uint32_t v_pa0 = 0;
53895   uint32_t v_pa1 = 0;
53896   uint32_t v_pa2 = 0;
53897   uint32_t v_pa3 = 0;
53898   uint32_t v_pb0 = 0;
53899   uint32_t v_pb1 = 0;
53900   uint32_t v_pb2 = 0;
53901   uint32_t v_pb3 = 0;
53902   uint32_t v_pc0 = 0;
53903   uint32_t v_pc1 = 0;
53904   uint32_t v_pc2 = 0;
53905   uint32_t v_pc3 = 0;
53906 
53907   {
53908     wuffs_base__slice_u8 i_slice_curr = a_curr;
53909     v_curr.ptr = i_slice_curr.ptr;
53910     wuffs_base__slice_u8 i_slice_prev = a_prev;
53911     v_prev.ptr = i_slice_prev.ptr;
53912     i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
53913     v_curr.len = 4;
53914     v_prev.len = 4;
53915     uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
53916     while (v_curr.ptr < i_end0_curr) {
53917       v_fb0 = ((uint32_t)(v_prev.ptr[0u]));
53918       v_pp0 = ((uint32_t)(((uint32_t)(v_fa0 + v_fb0)) - v_fc0));
53919       v_pa0 = ((uint32_t)(v_pp0 - v_fa0));
53920       if (v_pa0 >= 2147483648u) {
53921         v_pa0 = ((uint32_t)(0u - v_pa0));
53922       }
53923       v_pb0 = ((uint32_t)(v_pp0 - v_fb0));
53924       if (v_pb0 >= 2147483648u) {
53925         v_pb0 = ((uint32_t)(0u - v_pb0));
53926       }
53927       v_pc0 = ((uint32_t)(v_pp0 - v_fc0));
53928       if (v_pc0 >= 2147483648u) {
53929         v_pc0 = ((uint32_t)(0u - v_pc0));
53930       }
53931       if ((v_pa0 <= v_pb0) && (v_pa0 <= v_pc0)) {
53932       } else if (v_pb0 <= v_pc0) {
53933         v_fa0 = v_fb0;
53934       } else {
53935         v_fa0 = v_fc0;
53936       }
53937       v_curr.ptr[0u] = ((uint8_t)(v_curr.ptr[0u] + ((uint8_t)(v_fa0))));
53938       v_fa0 = ((uint32_t)(v_curr.ptr[0u]));
53939       v_fc0 = v_fb0;
53940       v_fb1 = ((uint32_t)(v_prev.ptr[1u]));
53941       v_pp1 = ((uint32_t)(((uint32_t)(v_fa1 + v_fb1)) - v_fc1));
53942       v_pa1 = ((uint32_t)(v_pp1 - v_fa1));
53943       if (v_pa1 >= 2147483648u) {
53944         v_pa1 = ((uint32_t)(0u - v_pa1));
53945       }
53946       v_pb1 = ((uint32_t)(v_pp1 - v_fb1));
53947       if (v_pb1 >= 2147483648u) {
53948         v_pb1 = ((uint32_t)(0u - v_pb1));
53949       }
53950       v_pc1 = ((uint32_t)(v_pp1 - v_fc1));
53951       if (v_pc1 >= 2147483648u) {
53952         v_pc1 = ((uint32_t)(0u - v_pc1));
53953       }
53954       if ((v_pa1 <= v_pb1) && (v_pa1 <= v_pc1)) {
53955       } else if (v_pb1 <= v_pc1) {
53956         v_fa1 = v_fb1;
53957       } else {
53958         v_fa1 = v_fc1;
53959       }
53960       v_curr.ptr[1u] = ((uint8_t)(v_curr.ptr[1u] + ((uint8_t)(v_fa1))));
53961       v_fa1 = ((uint32_t)(v_curr.ptr[1u]));
53962       v_fc1 = v_fb1;
53963       v_fb2 = ((uint32_t)(v_prev.ptr[2u]));
53964       v_pp2 = ((uint32_t)(((uint32_t)(v_fa2 + v_fb2)) - v_fc2));
53965       v_pa2 = ((uint32_t)(v_pp2 - v_fa2));
53966       if (v_pa2 >= 2147483648u) {
53967         v_pa2 = ((uint32_t)(0u - v_pa2));
53968       }
53969       v_pb2 = ((uint32_t)(v_pp2 - v_fb2));
53970       if (v_pb2 >= 2147483648u) {
53971         v_pb2 = ((uint32_t)(0u - v_pb2));
53972       }
53973       v_pc2 = ((uint32_t)(v_pp2 - v_fc2));
53974       if (v_pc2 >= 2147483648u) {
53975         v_pc2 = ((uint32_t)(0u - v_pc2));
53976       }
53977       if ((v_pa2 <= v_pb2) && (v_pa2 <= v_pc2)) {
53978       } else if (v_pb2 <= v_pc2) {
53979         v_fa2 = v_fb2;
53980       } else {
53981         v_fa2 = v_fc2;
53982       }
53983       v_curr.ptr[2u] = ((uint8_t)(v_curr.ptr[2u] + ((uint8_t)(v_fa2))));
53984       v_fa2 = ((uint32_t)(v_curr.ptr[2u]));
53985       v_fc2 = v_fb2;
53986       v_fb3 = ((uint32_t)(v_prev.ptr[3u]));
53987       v_pp3 = ((uint32_t)(((uint32_t)(v_fa3 + v_fb3)) - v_fc3));
53988       v_pa3 = ((uint32_t)(v_pp3 - v_fa3));
53989       if (v_pa3 >= 2147483648u) {
53990         v_pa3 = ((uint32_t)(0u - v_pa3));
53991       }
53992       v_pb3 = ((uint32_t)(v_pp3 - v_fb3));
53993       if (v_pb3 >= 2147483648u) {
53994         v_pb3 = ((uint32_t)(0u - v_pb3));
53995       }
53996       v_pc3 = ((uint32_t)(v_pp3 - v_fc3));
53997       if (v_pc3 >= 2147483648u) {
53998         v_pc3 = ((uint32_t)(0u - v_pc3));
53999       }
54000       if ((v_pa3 <= v_pb3) && (v_pa3 <= v_pc3)) {
54001       } else if (v_pb3 <= v_pc3) {
54002         v_fa3 = v_fb3;
54003       } else {
54004         v_fa3 = v_fc3;
54005       }
54006       v_curr.ptr[3u] = ((uint8_t)(v_curr.ptr[3u] + ((uint8_t)(v_fa3))));
54007       v_fa3 = ((uint32_t)(v_curr.ptr[3u]));
54008       v_fc3 = v_fb3;
54009       v_curr.ptr += 4;
54010       v_prev.ptr += 4;
54011     }
54012     v_curr.len = 0;
54013     v_prev.len = 0;
54014   }
54015   return wuffs_base__make_empty_struct();
54016 }
54017 
54018 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
54019 // -------- func png.decoder.filter_1_distance_4_x86_sse42
54020 
54021 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
54022 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
54023 WUFFS_BASE__GENERATED_C_CODE
54024 static wuffs_base__empty_struct
wuffs_png__decoder__filter_1_distance_4_x86_sse42(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr)54025 wuffs_png__decoder__filter_1_distance_4_x86_sse42(
54026     wuffs_png__decoder* self,
54027     wuffs_base__slice_u8 a_curr) {
54028   wuffs_base__slice_u8 v_curr = {0};
54029   __m128i v_x128 = {0};
54030   __m128i v_a128 = {0};
54031 
54032   {
54033     wuffs_base__slice_u8 i_slice_curr = a_curr;
54034     v_curr.ptr = i_slice_curr.ptr;
54035     v_curr.len = 4;
54036     uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
54037     while (v_curr.ptr < i_end0_curr) {
54038       v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
54039       v_x128 = _mm_add_epi8(v_x128, v_a128);
54040       v_a128 = v_x128;
54041       wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
54042       v_curr.ptr += 4;
54043       v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
54044       v_x128 = _mm_add_epi8(v_x128, v_a128);
54045       v_a128 = v_x128;
54046       wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
54047       v_curr.ptr += 4;
54048     }
54049     v_curr.len = 4;
54050     uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
54051     while (v_curr.ptr < i_end1_curr) {
54052       v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
54053       v_x128 = _mm_add_epi8(v_x128, v_a128);
54054       v_a128 = v_x128;
54055       wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
54056       v_curr.ptr += 4;
54057     }
54058     v_curr.len = 0;
54059   }
54060   return wuffs_base__make_empty_struct();
54061 }
54062 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
54063 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
54064 
54065 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
54066 // -------- func png.decoder.filter_3_distance_4_x86_sse42
54067 
54068 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
54069 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
54070 WUFFS_BASE__GENERATED_C_CODE
54071 static wuffs_base__empty_struct
wuffs_png__decoder__filter_3_distance_4_x86_sse42(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr,wuffs_base__slice_u8 a_prev)54072 wuffs_png__decoder__filter_3_distance_4_x86_sse42(
54073     wuffs_png__decoder* self,
54074     wuffs_base__slice_u8 a_curr,
54075     wuffs_base__slice_u8 a_prev) {
54076   wuffs_base__slice_u8 v_curr = {0};
54077   wuffs_base__slice_u8 v_prev = {0};
54078   __m128i v_x128 = {0};
54079   __m128i v_a128 = {0};
54080   __m128i v_b128 = {0};
54081   __m128i v_p128 = {0};
54082   __m128i v_k128 = {0};
54083 
54084   if (((uint64_t)(a_prev.len)) == 0u) {
54085     v_k128 = _mm_set1_epi8((int8_t)(254u));
54086     {
54087       wuffs_base__slice_u8 i_slice_curr = a_curr;
54088       v_curr.ptr = i_slice_curr.ptr;
54089       v_curr.len = 4;
54090       uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
54091       while (v_curr.ptr < i_end0_curr) {
54092         v_p128 = _mm_avg_epu8(_mm_and_si128(v_a128, v_k128), v_b128);
54093         v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
54094         v_x128 = _mm_add_epi8(v_x128, v_p128);
54095         v_a128 = v_x128;
54096         wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
54097         v_curr.ptr += 4;
54098         v_p128 = _mm_avg_epu8(_mm_and_si128(v_a128, v_k128), v_b128);
54099         v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
54100         v_x128 = _mm_add_epi8(v_x128, v_p128);
54101         v_a128 = v_x128;
54102         wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
54103         v_curr.ptr += 4;
54104       }
54105       v_curr.len = 4;
54106       uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
54107       while (v_curr.ptr < i_end1_curr) {
54108         v_p128 = _mm_avg_epu8(_mm_and_si128(v_a128, v_k128), v_b128);
54109         v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
54110         v_x128 = _mm_add_epi8(v_x128, v_p128);
54111         v_a128 = v_x128;
54112         wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
54113         v_curr.ptr += 4;
54114       }
54115       v_curr.len = 0;
54116     }
54117   } else {
54118     v_k128 = _mm_set1_epi8((int8_t)(1u));
54119     {
54120       wuffs_base__slice_u8 i_slice_curr = a_curr;
54121       v_curr.ptr = i_slice_curr.ptr;
54122       wuffs_base__slice_u8 i_slice_prev = a_prev;
54123       v_prev.ptr = i_slice_prev.ptr;
54124       i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
54125       v_curr.len = 4;
54126       v_prev.len = 4;
54127       uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
54128       while (v_curr.ptr < i_end0_curr) {
54129         v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
54130         v_p128 = _mm_avg_epu8(v_a128, v_b128);
54131         v_p128 = _mm_sub_epi8(v_p128, _mm_and_si128(v_k128, _mm_xor_si128(v_a128, v_b128)));
54132         v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
54133         v_x128 = _mm_add_epi8(v_x128, v_p128);
54134         v_a128 = v_x128;
54135         wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
54136         v_curr.ptr += 4;
54137         v_prev.ptr += 4;
54138         v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
54139         v_p128 = _mm_avg_epu8(v_a128, v_b128);
54140         v_p128 = _mm_sub_epi8(v_p128, _mm_and_si128(v_k128, _mm_xor_si128(v_a128, v_b128)));
54141         v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
54142         v_x128 = _mm_add_epi8(v_x128, v_p128);
54143         v_a128 = v_x128;
54144         wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
54145         v_curr.ptr += 4;
54146         v_prev.ptr += 4;
54147       }
54148       v_curr.len = 4;
54149       v_prev.len = 4;
54150       uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
54151       while (v_curr.ptr < i_end1_curr) {
54152         v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
54153         v_p128 = _mm_avg_epu8(v_a128, v_b128);
54154         v_p128 = _mm_sub_epi8(v_p128, _mm_and_si128(v_k128, _mm_xor_si128(v_a128, v_b128)));
54155         v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
54156         v_x128 = _mm_add_epi8(v_x128, v_p128);
54157         v_a128 = v_x128;
54158         wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
54159         v_curr.ptr += 4;
54160         v_prev.ptr += 4;
54161       }
54162       v_curr.len = 0;
54163       v_prev.len = 0;
54164     }
54165   }
54166   return wuffs_base__make_empty_struct();
54167 }
54168 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
54169 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
54170 
54171 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
54172 // -------- func png.decoder.filter_4_distance_3_x86_sse42
54173 
54174 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
54175 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
54176 WUFFS_BASE__GENERATED_C_CODE
54177 static wuffs_base__empty_struct
wuffs_png__decoder__filter_4_distance_3_x86_sse42(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr,wuffs_base__slice_u8 a_prev)54178 wuffs_png__decoder__filter_4_distance_3_x86_sse42(
54179     wuffs_png__decoder* self,
54180     wuffs_base__slice_u8 a_curr,
54181     wuffs_base__slice_u8 a_prev) {
54182   wuffs_base__slice_u8 v_curr = {0};
54183   wuffs_base__slice_u8 v_prev = {0};
54184   __m128i v_x128 = {0};
54185   __m128i v_a128 = {0};
54186   __m128i v_b128 = {0};
54187   __m128i v_c128 = {0};
54188   __m128i v_p128 = {0};
54189   __m128i v_pa128 = {0};
54190   __m128i v_pb128 = {0};
54191   __m128i v_pc128 = {0};
54192   __m128i v_smallest128 = {0};
54193   __m128i v_z128 = {0};
54194 
54195   {
54196     wuffs_base__slice_u8 i_slice_curr = a_curr;
54197     v_curr.ptr = i_slice_curr.ptr;
54198     wuffs_base__slice_u8 i_slice_prev = a_prev;
54199     v_prev.ptr = i_slice_prev.ptr;
54200     i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
54201     v_curr.len = 4;
54202     v_prev.len = 4;
54203     uint8_t* i_end0_curr = v_curr.ptr + wuffs_base__iterate_total_advance((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)), 7, 6);
54204     while (v_curr.ptr < i_end0_curr) {
54205       v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
54206       v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
54207       v_pa128 = _mm_sub_epi16(v_b128, v_c128);
54208       v_pb128 = _mm_sub_epi16(v_a128, v_c128);
54209       v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
54210       v_pa128 = _mm_abs_epi16(v_pa128);
54211       v_pb128 = _mm_abs_epi16(v_pb128);
54212       v_pc128 = _mm_abs_epi16(v_pc128);
54213       v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
54214       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));
54215       v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
54216       v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
54217       v_x128 = _mm_add_epi8(v_x128, v_p128);
54218       v_a128 = v_x128;
54219       v_c128 = v_b128;
54220       v_x128 = _mm_packus_epi16(v_x128, v_x128);
54221       wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
54222       v_curr.ptr += 3;
54223       v_prev.ptr += 3;
54224       v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
54225       v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
54226       v_pa128 = _mm_sub_epi16(v_b128, v_c128);
54227       v_pb128 = _mm_sub_epi16(v_a128, v_c128);
54228       v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
54229       v_pa128 = _mm_abs_epi16(v_pa128);
54230       v_pb128 = _mm_abs_epi16(v_pb128);
54231       v_pc128 = _mm_abs_epi16(v_pc128);
54232       v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
54233       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));
54234       v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
54235       v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
54236       v_x128 = _mm_add_epi8(v_x128, v_p128);
54237       v_a128 = v_x128;
54238       v_c128 = v_b128;
54239       v_x128 = _mm_packus_epi16(v_x128, v_x128);
54240       wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
54241       v_curr.ptr += 3;
54242       v_prev.ptr += 3;
54243     }
54244     v_curr.len = 4;
54245     v_prev.len = 4;
54246     uint8_t* i_end1_curr = v_curr.ptr + wuffs_base__iterate_total_advance((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)), 4, 3);
54247     while (v_curr.ptr < i_end1_curr) {
54248       v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
54249       v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
54250       v_pa128 = _mm_sub_epi16(v_b128, v_c128);
54251       v_pb128 = _mm_sub_epi16(v_a128, v_c128);
54252       v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
54253       v_pa128 = _mm_abs_epi16(v_pa128);
54254       v_pb128 = _mm_abs_epi16(v_pb128);
54255       v_pc128 = _mm_abs_epi16(v_pc128);
54256       v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
54257       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));
54258       v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
54259       v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
54260       v_x128 = _mm_add_epi8(v_x128, v_p128);
54261       v_a128 = v_x128;
54262       v_c128 = v_b128;
54263       v_x128 = _mm_packus_epi16(v_x128, v_x128);
54264       wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
54265       v_curr.ptr += 3;
54266       v_prev.ptr += 3;
54267     }
54268     v_curr.len = 3;
54269     v_prev.len = 3;
54270     uint8_t* i_end2_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3);
54271     while (v_curr.ptr < i_end2_curr) {
54272       v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u24le__no_bounds_check(v_prev.ptr)));
54273       v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
54274       v_pa128 = _mm_sub_epi16(v_b128, v_c128);
54275       v_pb128 = _mm_sub_epi16(v_a128, v_c128);
54276       v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
54277       v_pa128 = _mm_abs_epi16(v_pa128);
54278       v_pb128 = _mm_abs_epi16(v_pb128);
54279       v_pc128 = _mm_abs_epi16(v_pc128);
54280       v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
54281       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));
54282       v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u24le__no_bounds_check(v_curr.ptr)));
54283       v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
54284       v_x128 = _mm_add_epi8(v_x128, v_p128);
54285       v_x128 = _mm_packus_epi16(v_x128, v_x128);
54286       wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
54287       v_curr.ptr += 3;
54288       v_prev.ptr += 3;
54289     }
54290     v_curr.len = 0;
54291     v_prev.len = 0;
54292   }
54293   return wuffs_base__make_empty_struct();
54294 }
54295 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
54296 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
54297 
54298 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
54299 // -------- func png.decoder.filter_4_distance_4_x86_sse42
54300 
54301 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
54302 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
54303 WUFFS_BASE__GENERATED_C_CODE
54304 static wuffs_base__empty_struct
wuffs_png__decoder__filter_4_distance_4_x86_sse42(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr,wuffs_base__slice_u8 a_prev)54305 wuffs_png__decoder__filter_4_distance_4_x86_sse42(
54306     wuffs_png__decoder* self,
54307     wuffs_base__slice_u8 a_curr,
54308     wuffs_base__slice_u8 a_prev) {
54309   wuffs_base__slice_u8 v_curr = {0};
54310   wuffs_base__slice_u8 v_prev = {0};
54311   __m128i v_x128 = {0};
54312   __m128i v_a128 = {0};
54313   __m128i v_b128 = {0};
54314   __m128i v_c128 = {0};
54315   __m128i v_p128 = {0};
54316   __m128i v_pa128 = {0};
54317   __m128i v_pb128 = {0};
54318   __m128i v_pc128 = {0};
54319   __m128i v_smallest128 = {0};
54320   __m128i v_z128 = {0};
54321 
54322   {
54323     wuffs_base__slice_u8 i_slice_curr = a_curr;
54324     v_curr.ptr = i_slice_curr.ptr;
54325     wuffs_base__slice_u8 i_slice_prev = a_prev;
54326     v_prev.ptr = i_slice_prev.ptr;
54327     i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
54328     v_curr.len = 4;
54329     v_prev.len = 4;
54330     uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
54331     while (v_curr.ptr < i_end0_curr) {
54332       v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
54333       v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
54334       v_pa128 = _mm_sub_epi16(v_b128, v_c128);
54335       v_pb128 = _mm_sub_epi16(v_a128, v_c128);
54336       v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
54337       v_pa128 = _mm_abs_epi16(v_pa128);
54338       v_pb128 = _mm_abs_epi16(v_pb128);
54339       v_pc128 = _mm_abs_epi16(v_pc128);
54340       v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
54341       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));
54342       v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
54343       v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
54344       v_x128 = _mm_add_epi8(v_x128, v_p128);
54345       v_a128 = v_x128;
54346       v_c128 = v_b128;
54347       v_x128 = _mm_packus_epi16(v_x128, v_x128);
54348       wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
54349       v_curr.ptr += 4;
54350       v_prev.ptr += 4;
54351       v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
54352       v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
54353       v_pa128 = _mm_sub_epi16(v_b128, v_c128);
54354       v_pb128 = _mm_sub_epi16(v_a128, v_c128);
54355       v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
54356       v_pa128 = _mm_abs_epi16(v_pa128);
54357       v_pb128 = _mm_abs_epi16(v_pb128);
54358       v_pc128 = _mm_abs_epi16(v_pc128);
54359       v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
54360       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));
54361       v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
54362       v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
54363       v_x128 = _mm_add_epi8(v_x128, v_p128);
54364       v_a128 = v_x128;
54365       v_c128 = v_b128;
54366       v_x128 = _mm_packus_epi16(v_x128, v_x128);
54367       wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
54368       v_curr.ptr += 4;
54369       v_prev.ptr += 4;
54370     }
54371     v_curr.len = 4;
54372     v_prev.len = 4;
54373     uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
54374     while (v_curr.ptr < i_end1_curr) {
54375       v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
54376       v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
54377       v_pa128 = _mm_sub_epi16(v_b128, v_c128);
54378       v_pb128 = _mm_sub_epi16(v_a128, v_c128);
54379       v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
54380       v_pa128 = _mm_abs_epi16(v_pa128);
54381       v_pb128 = _mm_abs_epi16(v_pb128);
54382       v_pc128 = _mm_abs_epi16(v_pc128);
54383       v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
54384       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));
54385       v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
54386       v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
54387       v_x128 = _mm_add_epi8(v_x128, v_p128);
54388       v_a128 = v_x128;
54389       v_c128 = v_b128;
54390       v_x128 = _mm_packus_epi16(v_x128, v_x128);
54391       wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
54392       v_curr.ptr += 4;
54393       v_prev.ptr += 4;
54394     }
54395     v_curr.len = 0;
54396     v_prev.len = 0;
54397   }
54398   return wuffs_base__make_empty_struct();
54399 }
54400 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
54401 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
54402 
54403 // -------- func png.decoder.get_quirk
54404 
54405 WUFFS_BASE__GENERATED_C_CODE
54406 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_png__decoder__get_quirk(const wuffs_png__decoder * self,uint32_t a_key)54407 wuffs_png__decoder__get_quirk(
54408     const wuffs_png__decoder* self,
54409     uint32_t a_key) {
54410   if (!self) {
54411     return 0;
54412   }
54413   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
54414       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
54415     return 0;
54416   }
54417 
54418   if ((a_key == 1u) && self->private_impl.f_ignore_checksum) {
54419     return 1u;
54420   }
54421   return 0u;
54422 }
54423 
54424 // -------- func png.decoder.set_quirk
54425 
54426 WUFFS_BASE__GENERATED_C_CODE
54427 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_png__decoder__set_quirk(wuffs_png__decoder * self,uint32_t a_key,uint64_t a_value)54428 wuffs_png__decoder__set_quirk(
54429     wuffs_png__decoder* self,
54430     uint32_t a_key,
54431     uint64_t a_value) {
54432   if (!self) {
54433     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
54434   }
54435   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
54436     return wuffs_base__make_status(
54437         (self->private_impl.magic == WUFFS_BASE__DISABLED)
54438         ? wuffs_base__error__disabled_by_previous_error
54439         : wuffs_base__error__initialize_not_called);
54440   }
54441 
54442   if (a_key == 1u) {
54443     self->private_impl.f_ignore_checksum = (a_value > 0u);
54444     wuffs_zlib__decoder__set_quirk(&self->private_data.f_zlib, a_key, a_value);
54445     return wuffs_base__make_status(NULL);
54446   }
54447   return wuffs_base__make_status(wuffs_base__error__unsupported_option);
54448 }
54449 
54450 // -------- func png.decoder.decode_image_config
54451 
54452 WUFFS_BASE__GENERATED_C_CODE
54453 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_png__decoder__decode_image_config(wuffs_png__decoder * self,wuffs_base__image_config * a_dst,wuffs_base__io_buffer * a_src)54454 wuffs_png__decoder__decode_image_config(
54455     wuffs_png__decoder* self,
54456     wuffs_base__image_config* a_dst,
54457     wuffs_base__io_buffer* a_src) {
54458   if (!self) {
54459     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
54460   }
54461   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
54462     return wuffs_base__make_status(
54463         (self->private_impl.magic == WUFFS_BASE__DISABLED)
54464         ? wuffs_base__error__disabled_by_previous_error
54465         : wuffs_base__error__initialize_not_called);
54466   }
54467   if (!a_src) {
54468     self->private_impl.magic = WUFFS_BASE__DISABLED;
54469     return wuffs_base__make_status(wuffs_base__error__bad_argument);
54470   }
54471   if ((self->private_impl.active_coroutine != 0) &&
54472       (self->private_impl.active_coroutine != 1)) {
54473     self->private_impl.magic = WUFFS_BASE__DISABLED;
54474     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
54475   }
54476   self->private_impl.active_coroutine = 0;
54477   wuffs_base__status status = wuffs_base__make_status(NULL);
54478 
54479   wuffs_base__status v_status = wuffs_base__make_status(NULL);
54480 
54481   uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
54482   switch (coro_susp_point) {
54483     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
54484 
54485     while (true) {
54486       {
54487         wuffs_base__status t_0 = wuffs_png__decoder__do_decode_image_config(self, a_dst, a_src);
54488         v_status = t_0;
54489       }
54490       if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
54491         status = wuffs_base__make_status(wuffs_png__error__truncated_input);
54492         goto exit;
54493       }
54494       status = v_status;
54495       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
54496     }
54497 
54498     ok:
54499     self->private_impl.p_decode_image_config[0] = 0;
54500     goto exit;
54501   }
54502 
54503   goto suspend;
54504   suspend:
54505   self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
54506   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
54507 
54508   goto exit;
54509   exit:
54510   if (wuffs_base__status__is_error(&status)) {
54511     self->private_impl.magic = WUFFS_BASE__DISABLED;
54512   }
54513   return status;
54514 }
54515 
54516 // -------- func png.decoder.do_decode_image_config
54517 
54518 WUFFS_BASE__GENERATED_C_CODE
54519 static wuffs_base__status
wuffs_png__decoder__do_decode_image_config(wuffs_png__decoder * self,wuffs_base__image_config * a_dst,wuffs_base__io_buffer * a_src)54520 wuffs_png__decoder__do_decode_image_config(
54521     wuffs_png__decoder* self,
54522     wuffs_base__image_config* a_dst,
54523     wuffs_base__io_buffer* a_src) {
54524   wuffs_base__status status = wuffs_base__make_status(NULL);
54525 
54526   uint64_t v_magic = 0;
54527   uint64_t v_mark = 0;
54528   uint32_t v_checksum_have = 0;
54529   uint32_t v_checksum_want = 0;
54530   wuffs_base__status v_status = wuffs_base__make_status(NULL);
54531 
54532   const uint8_t* iop_a_src = NULL;
54533   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
54534   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
54535   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
54536   if (a_src && a_src->data.ptr) {
54537     io0_a_src = a_src->data.ptr;
54538     io1_a_src = io0_a_src + a_src->meta.ri;
54539     iop_a_src = io1_a_src;
54540     io2_a_src = io0_a_src + a_src->meta.wi;
54541   }
54542 
54543   uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config[0];
54544   if (coro_susp_point) {
54545     v_checksum_have = self->private_data.s_do_decode_image_config[0].v_checksum_have;
54546   }
54547   switch (coro_susp_point) {
54548     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
54549 
54550     if (self->private_impl.f_call_sequence != 0u) {
54551       status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
54552       goto exit;
54553     } else if ( ! self->private_impl.f_seen_ihdr) {
54554       {
54555         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
54556         uint64_t t_0;
54557         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 8)) {
54558           t_0 = wuffs_base__peek_u64le__no_bounds_check(iop_a_src);
54559           iop_a_src += 8;
54560         } else {
54561           self->private_data.s_do_decode_image_config[0].scratch = 0;
54562           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
54563           while (true) {
54564             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
54565               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
54566               goto suspend;
54567             }
54568             uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
54569             uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
54570             *scratch <<= 8;
54571             *scratch >>= 8;
54572             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
54573             if (num_bits_0 == 56) {
54574               t_0 = ((uint64_t)(*scratch));
54575               break;
54576             }
54577             num_bits_0 += 8u;
54578             *scratch |= ((uint64_t)(num_bits_0)) << 56;
54579           }
54580         }
54581         v_magic = t_0;
54582       }
54583       if (v_magic != 727905341920923785u) {
54584         status = wuffs_base__make_status(wuffs_png__error__bad_header);
54585         goto exit;
54586       }
54587       {
54588         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
54589         uint64_t t_1;
54590         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 8)) {
54591           t_1 = wuffs_base__peek_u64le__no_bounds_check(iop_a_src);
54592           iop_a_src += 8;
54593         } else {
54594           self->private_data.s_do_decode_image_config[0].scratch = 0;
54595           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
54596           while (true) {
54597             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
54598               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
54599               goto suspend;
54600             }
54601             uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
54602             uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
54603             *scratch <<= 8;
54604             *scratch >>= 8;
54605             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
54606             if (num_bits_1 == 56) {
54607               t_1 = ((uint64_t)(*scratch));
54608               break;
54609             }
54610             num_bits_1 += 8u;
54611             *scratch |= ((uint64_t)(num_bits_1)) << 56;
54612           }
54613         }
54614         v_magic = t_1;
54615       }
54616       if (v_magic != 5927942488114331648u) {
54617         if (v_magic == 5278895250759221248u) {
54618           status = wuffs_base__make_status(wuffs_png__error__unsupported_cgbi_extension);
54619           goto exit;
54620         }
54621         status = wuffs_base__make_status(wuffs_png__error__bad_header);
54622         goto exit;
54623       }
54624       self->private_impl.f_chunk_type_array[0u] = 73u;
54625       self->private_impl.f_chunk_type_array[1u] = 72u;
54626       self->private_impl.f_chunk_type_array[2u] = 68u;
54627       self->private_impl.f_chunk_type_array[3u] = 82u;
54628       wuffs_base__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32,
54629           sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
54630       wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__make_slice_u8(self->private_impl.f_chunk_type_array, 4));
54631       while (true) {
54632         v_mark = ((uint64_t)(iop_a_src - io0_a_src));
54633         {
54634           if (a_src) {
54635             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
54636           }
54637           wuffs_base__status t_2 = wuffs_png__decoder__decode_ihdr(self, a_src);
54638           v_status = t_2;
54639           if (a_src) {
54640             iop_a_src = a_src->data.ptr + a_src->meta.ri;
54641           }
54642         }
54643         if ( ! self->private_impl.f_ignore_checksum) {
54644           v_checksum_have = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__io__since(v_mark, ((uint64_t)(iop_a_src - io0_a_src)), io0_a_src));
54645         }
54646         if (wuffs_base__status__is_ok(&v_status)) {
54647           break;
54648         }
54649         status = v_status;
54650         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
54651       }
54652       {
54653         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
54654         uint32_t t_3;
54655         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
54656           t_3 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
54657           iop_a_src += 4;
54658         } else {
54659           self->private_data.s_do_decode_image_config[0].scratch = 0;
54660           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
54661           while (true) {
54662             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
54663               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
54664               goto suspend;
54665             }
54666             uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
54667             uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFFu));
54668             *scratch >>= 8;
54669             *scratch <<= 8;
54670             *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3);
54671             if (num_bits_3 == 24) {
54672               t_3 = ((uint32_t)(*scratch >> 32));
54673               break;
54674             }
54675             num_bits_3 += 8u;
54676             *scratch |= ((uint64_t)(num_bits_3));
54677           }
54678         }
54679         v_checksum_want = t_3;
54680       }
54681       if ( ! self->private_impl.f_ignore_checksum && (v_checksum_have != v_checksum_want)) {
54682         status = wuffs_base__make_status(wuffs_png__error__bad_checksum);
54683         goto exit;
54684       }
54685       self->private_impl.f_seen_ihdr = true;
54686     } else if (self->private_impl.f_metadata_fourcc != 0u) {
54687       self->private_impl.f_call_sequence = 16u;
54688       status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
54689       goto ok;
54690     }
54691     while (true) {
54692       if (((uint64_t)(io2_a_src - iop_a_src)) < 8u) {
54693         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
54694         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8);
54695         continue;
54696       }
54697       self->private_impl.f_chunk_length = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
54698       self->private_impl.f_chunk_type = ((uint32_t)((wuffs_base__peek_u64le__no_bounds_check(iop_a_src) >> 32u)));
54699       if (self->private_impl.f_chunk_type == 1413563465u) {
54700         if ( ! self->private_impl.f_seen_actl || self->private_impl.f_seen_fctl) {
54701           break;
54702         }
54703         self->private_impl.f_seen_idat = true;
54704       } else if (self->private_impl.f_chunk_type == 1413571686u) {
54705         if (self->private_impl.f_seen_idat && self->private_impl.f_seen_fctl) {
54706           break;
54707         }
54708         status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
54709         goto exit;
54710       }
54711       iop_a_src += 8u;
54712       if ( ! self->private_impl.f_ignore_checksum && ((self->private_impl.f_chunk_type & 32u) == 0u)) {
54713         self->private_impl.f_chunk_type_array[0u] = ((uint8_t)((self->private_impl.f_chunk_type >> 0u)));
54714         self->private_impl.f_chunk_type_array[1u] = ((uint8_t)((self->private_impl.f_chunk_type >> 8u)));
54715         self->private_impl.f_chunk_type_array[2u] = ((uint8_t)((self->private_impl.f_chunk_type >> 16u)));
54716         self->private_impl.f_chunk_type_array[3u] = ((uint8_t)((self->private_impl.f_chunk_type >> 24u)));
54717         wuffs_base__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32,
54718             sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
54719         wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__make_slice_u8(self->private_impl.f_chunk_type_array, 4));
54720       }
54721       while (true) {
54722         v_mark = ((uint64_t)(iop_a_src - io0_a_src));
54723         {
54724           if (a_src) {
54725             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
54726           }
54727           wuffs_base__status t_4 = wuffs_png__decoder__decode_other_chunk(self, a_src, false);
54728           v_status = t_4;
54729           if (a_src) {
54730             iop_a_src = a_src->data.ptr + a_src->meta.ri;
54731           }
54732         }
54733         if ( ! self->private_impl.f_ignore_checksum && ((self->private_impl.f_chunk_type & 32u) == 0u)) {
54734           v_checksum_have = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__io__since(v_mark, ((uint64_t)(iop_a_src - io0_a_src)), io0_a_src));
54735         }
54736         if (wuffs_base__status__is_ok(&v_status)) {
54737           break;
54738         }
54739         status = v_status;
54740         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9);
54741       }
54742       if (self->private_impl.f_metadata_fourcc != 0u) {
54743         self->private_impl.f_call_sequence = 16u;
54744         status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
54745         goto ok;
54746       }
54747       {
54748         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
54749         uint32_t t_5;
54750         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
54751           t_5 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
54752           iop_a_src += 4;
54753         } else {
54754           self->private_data.s_do_decode_image_config[0].scratch = 0;
54755           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
54756           while (true) {
54757             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
54758               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
54759               goto suspend;
54760             }
54761             uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
54762             uint32_t num_bits_5 = ((uint32_t)(*scratch & 0xFFu));
54763             *scratch >>= 8;
54764             *scratch <<= 8;
54765             *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_5);
54766             if (num_bits_5 == 24) {
54767               t_5 = ((uint32_t)(*scratch >> 32));
54768               break;
54769             }
54770             num_bits_5 += 8u;
54771             *scratch |= ((uint64_t)(num_bits_5));
54772           }
54773         }
54774         v_checksum_want = t_5;
54775       }
54776       if ( ! self->private_impl.f_ignore_checksum && ((self->private_impl.f_chunk_type & 32u) == 0u) && (v_checksum_have != v_checksum_want)) {
54777         status = wuffs_base__make_status(wuffs_png__error__bad_checksum);
54778         goto exit;
54779       }
54780     }
54781     if ((self->private_impl.f_color_type == 3u) &&  ! self->private_impl.f_seen_plte) {
54782       status = wuffs_base__make_status(wuffs_png__error__missing_palette);
54783       goto exit;
54784     }
54785     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)));
54786     self->private_impl.f_first_config_io_position = self->private_impl.f_frame_config_io_position;
54787     if (a_dst != NULL) {
54788       wuffs_base__image_config__set(
54789           a_dst,
54790           self->private_impl.f_dst_pixfmt,
54791           0u,
54792           self->private_impl.f_width,
54793           self->private_impl.f_height,
54794           self->private_impl.f_first_config_io_position,
54795           ((self->private_impl.f_color_type <= 3u) &&  ! self->private_impl.f_seen_trns));
54796     }
54797     if ( ! self->private_impl.f_seen_actl) {
54798       self->private_impl.f_num_animation_frames_value = 1u;
54799       self->private_impl.f_first_rect_x0 = 0u;
54800       self->private_impl.f_first_rect_y0 = 0u;
54801       self->private_impl.f_first_rect_x1 = self->private_impl.f_width;
54802       self->private_impl.f_first_rect_y1 = self->private_impl.f_height;
54803       self->private_impl.f_first_duration = 0u;
54804       self->private_impl.f_first_disposal = 0u;
54805       self->private_impl.f_first_overwrite_instead_of_blend = false;
54806     }
54807     self->private_impl.f_call_sequence = 32u;
54808 
54809     ok:
54810     self->private_impl.p_do_decode_image_config[0] = 0;
54811     goto exit;
54812   }
54813 
54814   goto suspend;
54815   suspend:
54816   self->private_impl.p_do_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
54817   self->private_data.s_do_decode_image_config[0].v_checksum_have = v_checksum_have;
54818 
54819   goto exit;
54820   exit:
54821   if (a_src && a_src->data.ptr) {
54822     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
54823   }
54824 
54825   return status;
54826 }
54827 
54828 // -------- func png.decoder.decode_ihdr
54829 
54830 WUFFS_BASE__GENERATED_C_CODE
54831 static wuffs_base__status
wuffs_png__decoder__decode_ihdr(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)54832 wuffs_png__decoder__decode_ihdr(
54833     wuffs_png__decoder* self,
54834     wuffs_base__io_buffer* a_src) {
54835   wuffs_base__status status = wuffs_base__make_status(NULL);
54836 
54837   uint32_t v_a32 = 0;
54838   uint8_t v_a8 = 0;
54839 
54840   const uint8_t* iop_a_src = NULL;
54841   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
54842   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
54843   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
54844   if (a_src && a_src->data.ptr) {
54845     io0_a_src = a_src->data.ptr;
54846     io1_a_src = io0_a_src + a_src->meta.ri;
54847     iop_a_src = io1_a_src;
54848     io2_a_src = io0_a_src + a_src->meta.wi;
54849   }
54850 
54851   uint32_t coro_susp_point = self->private_impl.p_decode_ihdr[0];
54852   switch (coro_susp_point) {
54853     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
54854 
54855     {
54856       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
54857       uint32_t t_0;
54858       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
54859         t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
54860         iop_a_src += 4;
54861       } else {
54862         self->private_data.s_decode_ihdr[0].scratch = 0;
54863         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
54864         while (true) {
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;
54868           }
54869           uint64_t* scratch = &self->private_data.s_decode_ihdr[0].scratch;
54870           uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu));
54871           *scratch >>= 8;
54872           *scratch <<= 8;
54873           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
54874           if (num_bits_0 == 24) {
54875             t_0 = ((uint32_t)(*scratch >> 32));
54876             break;
54877           }
54878           num_bits_0 += 8u;
54879           *scratch |= ((uint64_t)(num_bits_0));
54880         }
54881       }
54882       v_a32 = t_0;
54883     }
54884     if ((v_a32 == 0u) || (v_a32 > 2147483647u)) {
54885       status = wuffs_base__make_status(wuffs_png__error__bad_header);
54886       goto exit;
54887     } else if (v_a32 > 16777215u) {
54888       status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension);
54889       goto exit;
54890     }
54891     self->private_impl.f_width = v_a32;
54892     {
54893       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
54894       uint32_t t_1;
54895       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
54896         t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
54897         iop_a_src += 4;
54898       } else {
54899         self->private_data.s_decode_ihdr[0].scratch = 0;
54900         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
54901         while (true) {
54902           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
54903             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
54904             goto suspend;
54905           }
54906           uint64_t* scratch = &self->private_data.s_decode_ihdr[0].scratch;
54907           uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu));
54908           *scratch >>= 8;
54909           *scratch <<= 8;
54910           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
54911           if (num_bits_1 == 24) {
54912             t_1 = ((uint32_t)(*scratch >> 32));
54913             break;
54914           }
54915           num_bits_1 += 8u;
54916           *scratch |= ((uint64_t)(num_bits_1));
54917         }
54918       }
54919       v_a32 = t_1;
54920     }
54921     if ((v_a32 == 0u) || (v_a32 > 2147483647u)) {
54922       status = wuffs_base__make_status(wuffs_png__error__bad_header);
54923       goto exit;
54924     } else if (v_a32 > 16777215u) {
54925       status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension);
54926       goto exit;
54927     }
54928     self->private_impl.f_height = v_a32;
54929     {
54930       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
54931       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
54932         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
54933         goto suspend;
54934       }
54935       uint8_t t_2 = *iop_a_src++;
54936       v_a8 = t_2;
54937     }
54938     if (v_a8 > 16u) {
54939       status = wuffs_base__make_status(wuffs_png__error__bad_header);
54940       goto exit;
54941     }
54942     self->private_impl.f_depth = v_a8;
54943     {
54944       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
54945       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
54946         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
54947         goto suspend;
54948       }
54949       uint8_t t_3 = *iop_a_src++;
54950       v_a8 = t_3;
54951     }
54952     if ((v_a8 == 1u) || (v_a8 == 5u) || (v_a8 > 6u)) {
54953       status = wuffs_base__make_status(wuffs_png__error__bad_header);
54954       goto exit;
54955     }
54956     self->private_impl.f_color_type = v_a8;
54957     {
54958       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
54959       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
54960         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
54961         goto suspend;
54962       }
54963       uint8_t t_4 = *iop_a_src++;
54964       v_a8 = t_4;
54965     }
54966     if (v_a8 != 0u) {
54967       status = wuffs_base__make_status(wuffs_png__error__unsupported_png_compression_method);
54968       goto exit;
54969     }
54970     {
54971       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
54972       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
54973         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
54974         goto suspend;
54975       }
54976       uint8_t t_5 = *iop_a_src++;
54977       v_a8 = t_5;
54978     }
54979     if (v_a8 != 0u) {
54980       status = wuffs_base__make_status(wuffs_png__error__bad_header);
54981       goto exit;
54982     }
54983     {
54984       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
54985       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
54986         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
54987         goto suspend;
54988       }
54989       uint8_t t_6 = *iop_a_src++;
54990       v_a8 = t_6;
54991     }
54992     if (v_a8 == 0u) {
54993       self->private_impl.f_interlace_pass = 0u;
54994     } else if (v_a8 == 1u) {
54995       self->private_impl.f_interlace_pass = 1u;
54996       self->private_impl.choosy_filter_and_swizzle = (
54997           &wuffs_png__decoder__filter_and_swizzle_tricky);
54998     } else {
54999       status = wuffs_base__make_status(wuffs_png__error__bad_header);
55000       goto exit;
55001     }
55002     self->private_impl.f_filter_distance = 0u;
55003     wuffs_png__decoder__assign_filter_distance(self);
55004     if (self->private_impl.f_filter_distance == 0u) {
55005       status = wuffs_base__make_status(wuffs_png__error__bad_header);
55006       goto exit;
55007     }
55008     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)));
55009     wuffs_png__decoder__choose_filter_implementations(self);
55010 
55011     goto ok;
55012     ok:
55013     self->private_impl.p_decode_ihdr[0] = 0;
55014     goto exit;
55015   }
55016 
55017   goto suspend;
55018   suspend:
55019   self->private_impl.p_decode_ihdr[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
55020 
55021   goto exit;
55022   exit:
55023   if (a_src && a_src->data.ptr) {
55024     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
55025   }
55026 
55027   return status;
55028 }
55029 
55030 // -------- func png.decoder.assign_filter_distance
55031 
55032 WUFFS_BASE__GENERATED_C_CODE
55033 static wuffs_base__empty_struct
wuffs_png__decoder__assign_filter_distance(wuffs_png__decoder * self)55034 wuffs_png__decoder__assign_filter_distance(
55035     wuffs_png__decoder* self) {
55036   if (self->private_impl.f_depth < 8u) {
55037     if ((self->private_impl.f_depth != 1u) && (self->private_impl.f_depth != 2u) && (self->private_impl.f_depth != 4u)) {
55038       return wuffs_base__make_empty_struct();
55039     } else if (self->private_impl.f_color_type == 0u) {
55040       self->private_impl.f_dst_pixfmt = 536870920u;
55041       self->private_impl.f_src_pixfmt = 536870920u;
55042     } else if (self->private_impl.f_color_type == 3u) {
55043       self->private_impl.f_dst_pixfmt = 2198077448u;
55044       self->private_impl.f_src_pixfmt = 2198077448u;
55045     } else {
55046       return wuffs_base__make_empty_struct();
55047     }
55048     self->private_impl.f_filter_distance = 1u;
55049     self->private_impl.choosy_filter_and_swizzle = (
55050         &wuffs_png__decoder__filter_and_swizzle_tricky);
55051   } else if (self->private_impl.f_color_type == 0u) {
55052     if (self->private_impl.f_depth == 8u) {
55053       self->private_impl.f_dst_pixfmt = 536870920u;
55054       self->private_impl.f_src_pixfmt = 536870920u;
55055       self->private_impl.f_filter_distance = 1u;
55056     } else if (self->private_impl.f_depth == 16u) {
55057       if (self->private_impl.f_interlace_pass == 0u) {
55058         self->private_impl.f_dst_pixfmt = 536870923u;
55059         self->private_impl.f_src_pixfmt = 537919499u;
55060       } else {
55061         self->private_impl.f_dst_pixfmt = 2164308923u;
55062         self->private_impl.f_src_pixfmt = 2164308923u;
55063       }
55064       self->private_impl.f_filter_distance = 2u;
55065     }
55066   } else if (self->private_impl.f_color_type == 2u) {
55067     if (self->private_impl.f_depth == 8u) {
55068       self->private_impl.f_dst_pixfmt = 2147485832u;
55069       self->private_impl.f_src_pixfmt = 2684356744u;
55070       self->private_impl.f_filter_distance = 3u;
55071     } else if (self->private_impl.f_depth == 16u) {
55072       self->private_impl.f_dst_pixfmt = 2164308923u;
55073       self->private_impl.f_src_pixfmt = 2164308923u;
55074       self->private_impl.f_filter_distance = 6u;
55075       self->private_impl.choosy_filter_and_swizzle = (
55076           &wuffs_png__decoder__filter_and_swizzle_tricky);
55077     }
55078   } else if (self->private_impl.f_color_type == 3u) {
55079     if (self->private_impl.f_depth == 8u) {
55080       self->private_impl.f_dst_pixfmt = 2198077448u;
55081       self->private_impl.f_src_pixfmt = 2198077448u;
55082       self->private_impl.f_filter_distance = 1u;
55083     }
55084   } else if (self->private_impl.f_color_type == 4u) {
55085     if (self->private_impl.f_depth == 8u) {
55086       self->private_impl.f_dst_pixfmt = 2164295816u;
55087       self->private_impl.f_src_pixfmt = 2164295816u;
55088       self->private_impl.f_filter_distance = 2u;
55089       self->private_impl.choosy_filter_and_swizzle = (
55090           &wuffs_png__decoder__filter_and_swizzle_tricky);
55091     } else if (self->private_impl.f_depth == 16u) {
55092       self->private_impl.f_dst_pixfmt = 2164308923u;
55093       self->private_impl.f_src_pixfmt = 2164308923u;
55094       self->private_impl.f_filter_distance = 4u;
55095       self->private_impl.choosy_filter_and_swizzle = (
55096           &wuffs_png__decoder__filter_and_swizzle_tricky);
55097     }
55098   } else if (self->private_impl.f_color_type == 6u) {
55099     if (self->private_impl.f_depth == 8u) {
55100       self->private_impl.f_dst_pixfmt = 2164295816u;
55101       self->private_impl.f_src_pixfmt = 2701166728u;
55102       self->private_impl.f_filter_distance = 4u;
55103     } else if (self->private_impl.f_depth == 16u) {
55104       self->private_impl.f_dst_pixfmt = 2164308923u;
55105       self->private_impl.f_src_pixfmt = 2164308923u;
55106       self->private_impl.f_filter_distance = 8u;
55107       self->private_impl.choosy_filter_and_swizzle = (
55108           &wuffs_png__decoder__filter_and_swizzle_tricky);
55109     }
55110   }
55111   return wuffs_base__make_empty_struct();
55112 }
55113 
55114 // -------- func png.decoder.calculate_bytes_per_row
55115 
55116 WUFFS_BASE__GENERATED_C_CODE
55117 static uint64_t
wuffs_png__decoder__calculate_bytes_per_row(const wuffs_png__decoder * self,uint32_t a_width)55118 wuffs_png__decoder__calculate_bytes_per_row(
55119     const wuffs_png__decoder* self,
55120     uint32_t a_width) {
55121   uint64_t v_bytes_per_channel = 0;
55122 
55123   if (self->private_impl.f_depth == 1u) {
55124     return ((uint64_t)(((a_width + 7u) / 8u)));
55125   } else if (self->private_impl.f_depth == 2u) {
55126     return ((uint64_t)(((a_width + 3u) / 4u)));
55127   } else if (self->private_impl.f_depth == 4u) {
55128     return ((uint64_t)(((a_width + 1u) / 2u)));
55129   }
55130   v_bytes_per_channel = ((uint64_t)((self->private_impl.f_depth >> 3u)));
55131   return (((uint64_t)(a_width)) * v_bytes_per_channel * ((uint64_t)(WUFFS_PNG__NUM_CHANNELS[self->private_impl.f_color_type])));
55132 }
55133 
55134 // -------- func png.decoder.choose_filter_implementations
55135 
55136 WUFFS_BASE__GENERATED_C_CODE
55137 static wuffs_base__empty_struct
wuffs_png__decoder__choose_filter_implementations(wuffs_png__decoder * self)55138 wuffs_png__decoder__choose_filter_implementations(
55139     wuffs_png__decoder* self) {
55140   if (self->private_impl.f_filter_distance == 3u) {
55141     self->private_impl.choosy_filter_1 = (
55142         &wuffs_png__decoder__filter_1_distance_3_fallback);
55143     self->private_impl.choosy_filter_3 = (
55144         &wuffs_png__decoder__filter_3_distance_3_fallback);
55145     self->private_impl.choosy_filter_4 = (
55146 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
55147         wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_png__decoder__filter_4_distance_3_arm_neon :
55148 #endif
55149 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
55150         wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_png__decoder__filter_4_distance_3_x86_sse42 :
55151 #endif
55152         &wuffs_png__decoder__filter_4_distance_3_fallback);
55153   } else if (self->private_impl.f_filter_distance == 4u) {
55154     self->private_impl.choosy_filter_1 = (
55155 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
55156         wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_png__decoder__filter_1_distance_4_arm_neon :
55157 #endif
55158 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
55159         wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_png__decoder__filter_1_distance_4_x86_sse42 :
55160 #endif
55161         &wuffs_png__decoder__filter_1_distance_4_fallback);
55162     self->private_impl.choosy_filter_3 = (
55163 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
55164         wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_png__decoder__filter_3_distance_4_arm_neon :
55165 #endif
55166 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
55167         wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_png__decoder__filter_3_distance_4_x86_sse42 :
55168 #endif
55169         &wuffs_png__decoder__filter_3_distance_4_fallback);
55170     self->private_impl.choosy_filter_4 = (
55171 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
55172         wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_png__decoder__filter_4_distance_4_arm_neon :
55173 #endif
55174 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
55175         wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_png__decoder__filter_4_distance_4_x86_sse42 :
55176 #endif
55177         &wuffs_png__decoder__filter_4_distance_4_fallback);
55178   }
55179   return wuffs_base__make_empty_struct();
55180 }
55181 
55182 // -------- func png.decoder.decode_other_chunk
55183 
55184 WUFFS_BASE__GENERATED_C_CODE
55185 static wuffs_base__status
wuffs_png__decoder__decode_other_chunk(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src,bool a_framy)55186 wuffs_png__decoder__decode_other_chunk(
55187     wuffs_png__decoder* self,
55188     wuffs_base__io_buffer* a_src,
55189     bool a_framy) {
55190   wuffs_base__status status = wuffs_base__make_status(NULL);
55191 
55192   const uint8_t* iop_a_src = NULL;
55193   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
55194   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
55195   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
55196   if (a_src && a_src->data.ptr) {
55197     io0_a_src = a_src->data.ptr;
55198     io1_a_src = io0_a_src + a_src->meta.ri;
55199     iop_a_src = io1_a_src;
55200     io2_a_src = io0_a_src + a_src->meta.wi;
55201   }
55202 
55203   uint32_t coro_susp_point = self->private_impl.p_decode_other_chunk[0];
55204   switch (coro_susp_point) {
55205     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
55206 
55207     if ((self->private_impl.f_chunk_type == 1163152464u) &&  ! a_framy) {
55208       if (self->private_impl.f_seen_plte) {
55209         status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
55210         goto exit;
55211       } else if (self->private_impl.f_color_type == 3u) {
55212         if (a_src) {
55213           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
55214         }
55215         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
55216         status = wuffs_png__decoder__decode_plte(self, a_src);
55217         if (a_src) {
55218           iop_a_src = a_src->data.ptr + a_src->meta.ri;
55219         }
55220         if (status.repr) {
55221           goto suspend;
55222         }
55223       } else if ((self->private_impl.f_color_type == 2u) || (self->private_impl.f_color_type == 6u)) {
55224       } else {
55225         status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
55226         goto exit;
55227       }
55228       self->private_impl.f_seen_plte = true;
55229     } else if ((self->private_impl.f_chunk_type & 32u) == 0u) {
55230       if (self->private_impl.f_chunk_type != 1413563465u) {
55231         status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
55232         goto exit;
55233       }
55234     }
55235     if (self->private_impl.f_chunk_type == 1716082789u) {
55236       if (self->private_impl.f_report_metadata_exif) {
55237         if (self->private_impl.f_seen_exif) {
55238           status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
55239           goto exit;
55240         }
55241         if (a_src) {
55242           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
55243         }
55244         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
55245         status = wuffs_png__decoder__decode_exif(self, a_src);
55246         if (a_src) {
55247           iop_a_src = a_src->data.ptr + a_src->meta.ri;
55248         }
55249         if (status.repr) {
55250           goto suspend;
55251         }
55252         self->private_impl.f_seen_exif = true;
55253       }
55254     } else if ((self->private_impl.f_chunk_type == 1951945833u) || (self->private_impl.f_chunk_type == 1951942004u) || (self->private_impl.f_chunk_type == 1951945850u)) {
55255       if (self->private_impl.f_report_metadata_kvp) {
55256         self->private_impl.f_metadata_flavor = 4u;
55257         self->private_impl.f_metadata_fourcc = 1263947851u;
55258         self->private_impl.f_metadata_x = 0u;
55259         self->private_impl.f_metadata_y = 0u;
55260         self->private_impl.f_metadata_z = 0u;
55261       }
55262     } else if ( ! a_framy) {
55263       if (self->private_impl.f_chunk_type == 1280598881u) {
55264         if (self->private_impl.f_seen_actl) {
55265           status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
55266           goto exit;
55267         }
55268         if (a_src) {
55269           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
55270         }
55271         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
55272         status = wuffs_png__decoder__decode_actl(self, a_src);
55273         if (a_src) {
55274           iop_a_src = a_src->data.ptr + a_src->meta.ri;
55275         }
55276         if (status.repr) {
55277           goto suspend;
55278         }
55279         self->private_impl.f_seen_actl = true;
55280       } else if (self->private_impl.f_chunk_type == 1297238115u) {
55281         if (self->private_impl.f_report_metadata_chrm) {
55282           if (self->private_impl.f_seen_chrm) {
55283             status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
55284             goto exit;
55285           }
55286           if (a_src) {
55287             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
55288           }
55289           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
55290           status = wuffs_png__decoder__decode_chrm(self, a_src);
55291           if (a_src) {
55292             iop_a_src = a_src->data.ptr + a_src->meta.ri;
55293           }
55294           if (status.repr) {
55295             goto suspend;
55296           }
55297           self->private_impl.f_seen_chrm = true;
55298         }
55299       } else if (self->private_impl.f_chunk_type == 1280598886u) {
55300         if (self->private_impl.f_seen_fctl) {
55301           status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
55302           goto exit;
55303         }
55304         if (a_src) {
55305           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
55306         }
55307         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
55308         status = wuffs_png__decoder__decode_fctl(self, a_src);
55309         if (a_src) {
55310           iop_a_src = a_src->data.ptr + a_src->meta.ri;
55311         }
55312         if (status.repr) {
55313           goto suspend;
55314         }
55315         self->private_impl.f_seen_fctl = true;
55316       } else if (self->private_impl.f_chunk_type == 1095582055u) {
55317         if (self->private_impl.f_report_metadata_gama) {
55318           if (self->private_impl.f_seen_gama) {
55319             status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
55320             goto exit;
55321           }
55322           if (a_src) {
55323             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
55324           }
55325           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
55326           status = wuffs_png__decoder__decode_gama(self, a_src);
55327           if (a_src) {
55328             iop_a_src = a_src->data.ptr + a_src->meta.ri;
55329           }
55330           if (status.repr) {
55331             goto suspend;
55332           }
55333           self->private_impl.f_seen_gama = true;
55334         }
55335       } else if (self->private_impl.f_chunk_type == 1346585449u) {
55336         if (self->private_impl.f_report_metadata_iccp) {
55337           if (self->private_impl.f_seen_iccp) {
55338             status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
55339             goto exit;
55340           }
55341           if (a_src) {
55342             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
55343           }
55344           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
55345           status = wuffs_png__decoder__decode_iccp(self, a_src);
55346           if (a_src) {
55347             iop_a_src = a_src->data.ptr + a_src->meta.ri;
55348           }
55349           if (status.repr) {
55350             goto suspend;
55351           }
55352           self->private_impl.f_seen_iccp = true;
55353         }
55354       } else if (self->private_impl.f_chunk_type == 1111970419u) {
55355         if (self->private_impl.f_report_metadata_srgb) {
55356           if (self->private_impl.f_seen_srgb) {
55357             status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
55358             goto exit;
55359           }
55360           if (a_src) {
55361             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
55362           }
55363           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
55364           status = wuffs_png__decoder__decode_srgb(self, a_src);
55365           if (a_src) {
55366             iop_a_src = a_src->data.ptr + a_src->meta.ri;
55367           }
55368           if (status.repr) {
55369             goto suspend;
55370           }
55371           self->private_impl.f_seen_srgb = true;
55372         }
55373       } else if (self->private_impl.f_chunk_type == 1397641844u) {
55374         if (self->private_impl.f_seen_trns || (self->private_impl.f_color_type > 3u) || ((self->private_impl.f_color_type == 3u) &&  ! self->private_impl.f_seen_plte)) {
55375           status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
55376           goto exit;
55377         }
55378         if (a_src) {
55379           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
55380         }
55381         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
55382         status = wuffs_png__decoder__decode_trns(self, a_src);
55383         if (a_src) {
55384           iop_a_src = a_src->data.ptr + a_src->meta.ri;
55385         }
55386         if (status.repr) {
55387           goto suspend;
55388         }
55389         self->private_impl.f_seen_trns = true;
55390       }
55391     }
55392     if (self->private_impl.f_metadata_fourcc == 0u) {
55393       self->private_data.s_decode_other_chunk[0].scratch = self->private_impl.f_chunk_length;
55394       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
55395       if (self->private_data.s_decode_other_chunk[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
55396         self->private_data.s_decode_other_chunk[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
55397         iop_a_src = io2_a_src;
55398         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
55399         goto suspend;
55400       }
55401       iop_a_src += self->private_data.s_decode_other_chunk[0].scratch;
55402     }
55403 
55404     goto ok;
55405     ok:
55406     self->private_impl.p_decode_other_chunk[0] = 0;
55407     goto exit;
55408   }
55409 
55410   goto suspend;
55411   suspend:
55412   self->private_impl.p_decode_other_chunk[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
55413 
55414   goto exit;
55415   exit:
55416   if (a_src && a_src->data.ptr) {
55417     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
55418   }
55419 
55420   return status;
55421 }
55422 
55423 // -------- func png.decoder.decode_actl
55424 
55425 WUFFS_BASE__GENERATED_C_CODE
55426 static wuffs_base__status
wuffs_png__decoder__decode_actl(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)55427 wuffs_png__decoder__decode_actl(
55428     wuffs_png__decoder* self,
55429     wuffs_base__io_buffer* a_src) {
55430   wuffs_base__status status = wuffs_base__make_status(NULL);
55431 
55432   const uint8_t* iop_a_src = NULL;
55433   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
55434   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
55435   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
55436   if (a_src && a_src->data.ptr) {
55437     io0_a_src = a_src->data.ptr;
55438     io1_a_src = io0_a_src + a_src->meta.ri;
55439     iop_a_src = io1_a_src;
55440     io2_a_src = io0_a_src + a_src->meta.wi;
55441   }
55442 
55443   uint32_t coro_susp_point = self->private_impl.p_decode_actl[0];
55444   switch (coro_susp_point) {
55445     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
55446 
55447     if (self->private_impl.f_chunk_length != 8u) {
55448       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
55449       goto exit;
55450     } else if (self->private_impl.f_interlace_pass > 0u) {
55451       status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file);
55452       goto exit;
55453     }
55454     self->private_impl.f_chunk_length = 0u;
55455     {
55456       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
55457       uint32_t t_0;
55458       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
55459         t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
55460         iop_a_src += 4;
55461       } else {
55462         self->private_data.s_decode_actl[0].scratch = 0;
55463         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
55464         while (true) {
55465           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
55466             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
55467             goto suspend;
55468           }
55469           uint64_t* scratch = &self->private_data.s_decode_actl[0].scratch;
55470           uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu));
55471           *scratch >>= 8;
55472           *scratch <<= 8;
55473           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
55474           if (num_bits_0 == 24) {
55475             t_0 = ((uint32_t)(*scratch >> 32));
55476             break;
55477           }
55478           num_bits_0 += 8u;
55479           *scratch |= ((uint64_t)(num_bits_0));
55480         }
55481       }
55482       self->private_impl.f_num_animation_frames_value = t_0;
55483     }
55484     if (self->private_impl.f_num_animation_frames_value == 0u) {
55485       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
55486       goto exit;
55487     }
55488     {
55489       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
55490       uint32_t t_1;
55491       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
55492         t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
55493         iop_a_src += 4;
55494       } else {
55495         self->private_data.s_decode_actl[0].scratch = 0;
55496         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
55497         while (true) {
55498           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
55499             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
55500             goto suspend;
55501           }
55502           uint64_t* scratch = &self->private_data.s_decode_actl[0].scratch;
55503           uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu));
55504           *scratch >>= 8;
55505           *scratch <<= 8;
55506           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
55507           if (num_bits_1 == 24) {
55508             t_1 = ((uint32_t)(*scratch >> 32));
55509             break;
55510           }
55511           num_bits_1 += 8u;
55512           *scratch |= ((uint64_t)(num_bits_1));
55513         }
55514       }
55515       self->private_impl.f_num_animation_loops_value = t_1;
55516     }
55517 
55518     goto ok;
55519     ok:
55520     self->private_impl.p_decode_actl[0] = 0;
55521     goto exit;
55522   }
55523 
55524   goto suspend;
55525   suspend:
55526   self->private_impl.p_decode_actl[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
55527 
55528   goto exit;
55529   exit:
55530   if (a_src && a_src->data.ptr) {
55531     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
55532   }
55533 
55534   return status;
55535 }
55536 
55537 // -------- func png.decoder.decode_chrm
55538 
55539 WUFFS_BASE__GENERATED_C_CODE
55540 static wuffs_base__status
wuffs_png__decoder__decode_chrm(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)55541 wuffs_png__decoder__decode_chrm(
55542     wuffs_png__decoder* self,
55543     wuffs_base__io_buffer* a_src) {
55544   wuffs_base__status status = wuffs_base__make_status(NULL);
55545 
55546   uint64_t v_u = 0;
55547 
55548   const uint8_t* iop_a_src = NULL;
55549   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
55550   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
55551   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
55552   if (a_src && a_src->data.ptr) {
55553     io0_a_src = a_src->data.ptr;
55554     io1_a_src = io0_a_src + a_src->meta.ri;
55555     iop_a_src = io1_a_src;
55556     io2_a_src = io0_a_src + a_src->meta.wi;
55557   }
55558 
55559   uint32_t coro_susp_point = self->private_impl.p_decode_chrm[0];
55560   switch (coro_susp_point) {
55561     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
55562 
55563     if (self->private_impl.f_chunk_length != 32u) {
55564       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
55565       goto exit;
55566     }
55567     self->private_impl.f_chunk_length = 0u;
55568     self->private_impl.f_metadata_flavor = 5u;
55569     self->private_impl.f_metadata_fourcc = 1128813133u;
55570     self->private_impl.f_metadata_x = 0u;
55571     self->private_impl.f_metadata_y = 0u;
55572     self->private_impl.f_metadata_z = 0u;
55573     {
55574       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
55575       uint64_t t_0;
55576       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
55577         t_0 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
55578         iop_a_src += 4;
55579       } else {
55580         self->private_data.s_decode_chrm[0].scratch = 0;
55581         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
55582         while (true) {
55583           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
55584             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
55585             goto suspend;
55586           }
55587           uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
55588           uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu));
55589           *scratch >>= 8;
55590           *scratch <<= 8;
55591           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
55592           if (num_bits_0 == 24) {
55593             t_0 = ((uint64_t)(*scratch >> 32));
55594             break;
55595           }
55596           num_bits_0 += 8u;
55597           *scratch |= ((uint64_t)(num_bits_0));
55598         }
55599       }
55600       v_u = t_0;
55601     }
55602     self->private_impl.f_metadata_x |= ((16777215u & v_u) << 0u);
55603     {
55604       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
55605       uint64_t t_1;
55606       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
55607         t_1 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
55608         iop_a_src += 4;
55609       } else {
55610         self->private_data.s_decode_chrm[0].scratch = 0;
55611         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
55612         while (true) {
55613           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
55614             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
55615             goto suspend;
55616           }
55617           uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
55618           uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu));
55619           *scratch >>= 8;
55620           *scratch <<= 8;
55621           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
55622           if (num_bits_1 == 24) {
55623             t_1 = ((uint64_t)(*scratch >> 32));
55624             break;
55625           }
55626           num_bits_1 += 8u;
55627           *scratch |= ((uint64_t)(num_bits_1));
55628         }
55629       }
55630       v_u = t_1;
55631     }
55632     self->private_impl.f_metadata_x |= ((16777215u & v_u) << 24u);
55633     {
55634       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
55635       uint64_t t_2;
55636       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
55637         t_2 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
55638         iop_a_src += 4;
55639       } else {
55640         self->private_data.s_decode_chrm[0].scratch = 0;
55641         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
55642         while (true) {
55643           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
55644             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
55645             goto suspend;
55646           }
55647           uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
55648           uint32_t num_bits_2 = ((uint32_t)(*scratch & 0xFFu));
55649           *scratch >>= 8;
55650           *scratch <<= 8;
55651           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_2);
55652           if (num_bits_2 == 24) {
55653             t_2 = ((uint64_t)(*scratch >> 32));
55654             break;
55655           }
55656           num_bits_2 += 8u;
55657           *scratch |= ((uint64_t)(num_bits_2));
55658         }
55659       }
55660       v_u = t_2;
55661     }
55662     self->private_impl.f_metadata_x |= ((uint64_t)((16777215u & v_u) << 48u));
55663     self->private_impl.f_metadata_y |= ((16777215u & v_u) >> 16u);
55664     {
55665       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
55666       uint64_t t_3;
55667       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
55668         t_3 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
55669         iop_a_src += 4;
55670       } else {
55671         self->private_data.s_decode_chrm[0].scratch = 0;
55672         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
55673         while (true) {
55674           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
55675             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
55676             goto suspend;
55677           }
55678           uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
55679           uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFFu));
55680           *scratch >>= 8;
55681           *scratch <<= 8;
55682           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3);
55683           if (num_bits_3 == 24) {
55684             t_3 = ((uint64_t)(*scratch >> 32));
55685             break;
55686           }
55687           num_bits_3 += 8u;
55688           *scratch |= ((uint64_t)(num_bits_3));
55689         }
55690       }
55691       v_u = t_3;
55692     }
55693     self->private_impl.f_metadata_y |= ((16777215u & v_u) << 8u);
55694     {
55695       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
55696       uint64_t t_4;
55697       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
55698         t_4 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
55699         iop_a_src += 4;
55700       } else {
55701         self->private_data.s_decode_chrm[0].scratch = 0;
55702         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
55703         while (true) {
55704           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
55705             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
55706             goto suspend;
55707           }
55708           uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
55709           uint32_t num_bits_4 = ((uint32_t)(*scratch & 0xFFu));
55710           *scratch >>= 8;
55711           *scratch <<= 8;
55712           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_4);
55713           if (num_bits_4 == 24) {
55714             t_4 = ((uint64_t)(*scratch >> 32));
55715             break;
55716           }
55717           num_bits_4 += 8u;
55718           *scratch |= ((uint64_t)(num_bits_4));
55719         }
55720       }
55721       v_u = t_4;
55722     }
55723     self->private_impl.f_metadata_y |= ((16777215u & v_u) << 32u);
55724     {
55725       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
55726       uint64_t t_5;
55727       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
55728         t_5 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
55729         iop_a_src += 4;
55730       } else {
55731         self->private_data.s_decode_chrm[0].scratch = 0;
55732         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
55733         while (true) {
55734           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
55735             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
55736             goto suspend;
55737           }
55738           uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
55739           uint32_t num_bits_5 = ((uint32_t)(*scratch & 0xFFu));
55740           *scratch >>= 8;
55741           *scratch <<= 8;
55742           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_5);
55743           if (num_bits_5 == 24) {
55744             t_5 = ((uint64_t)(*scratch >> 32));
55745             break;
55746           }
55747           num_bits_5 += 8u;
55748           *scratch |= ((uint64_t)(num_bits_5));
55749         }
55750       }
55751       v_u = t_5;
55752     }
55753     self->private_impl.f_metadata_y |= ((uint64_t)((16777215u & v_u) << 56u));
55754     self->private_impl.f_metadata_z |= ((16777215u & v_u) >> 8u);
55755     {
55756       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
55757       uint64_t t_6;
55758       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
55759         t_6 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
55760         iop_a_src += 4;
55761       } else {
55762         self->private_data.s_decode_chrm[0].scratch = 0;
55763         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
55764         while (true) {
55765           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
55766             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
55767             goto suspend;
55768           }
55769           uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
55770           uint32_t num_bits_6 = ((uint32_t)(*scratch & 0xFFu));
55771           *scratch >>= 8;
55772           *scratch <<= 8;
55773           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_6);
55774           if (num_bits_6 == 24) {
55775             t_6 = ((uint64_t)(*scratch >> 32));
55776             break;
55777           }
55778           num_bits_6 += 8u;
55779           *scratch |= ((uint64_t)(num_bits_6));
55780         }
55781       }
55782       v_u = t_6;
55783     }
55784     self->private_impl.f_metadata_z |= ((16777215u & v_u) << 16u);
55785     {
55786       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
55787       uint64_t t_7;
55788       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
55789         t_7 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
55790         iop_a_src += 4;
55791       } else {
55792         self->private_data.s_decode_chrm[0].scratch = 0;
55793         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
55794         while (true) {
55795           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
55796             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
55797             goto suspend;
55798           }
55799           uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
55800           uint32_t num_bits_7 = ((uint32_t)(*scratch & 0xFFu));
55801           *scratch >>= 8;
55802           *scratch <<= 8;
55803           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_7);
55804           if (num_bits_7 == 24) {
55805             t_7 = ((uint64_t)(*scratch >> 32));
55806             break;
55807           }
55808           num_bits_7 += 8u;
55809           *scratch |= ((uint64_t)(num_bits_7));
55810         }
55811       }
55812       v_u = t_7;
55813     }
55814     self->private_impl.f_metadata_z |= ((16777215u & v_u) << 40u);
55815 
55816     goto ok;
55817     ok:
55818     self->private_impl.p_decode_chrm[0] = 0;
55819     goto exit;
55820   }
55821 
55822   goto suspend;
55823   suspend:
55824   self->private_impl.p_decode_chrm[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
55825 
55826   goto exit;
55827   exit:
55828   if (a_src && a_src->data.ptr) {
55829     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
55830   }
55831 
55832   return status;
55833 }
55834 
55835 // -------- func png.decoder.decode_exif
55836 
55837 WUFFS_BASE__GENERATED_C_CODE
55838 static wuffs_base__status
wuffs_png__decoder__decode_exif(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)55839 wuffs_png__decoder__decode_exif(
55840     wuffs_png__decoder* self,
55841     wuffs_base__io_buffer* a_src) {
55842   wuffs_base__status status = wuffs_base__make_status(NULL);
55843 
55844   const uint8_t* iop_a_src = NULL;
55845   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
55846   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
55847   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
55848   if (a_src && a_src->data.ptr) {
55849     io0_a_src = a_src->data.ptr;
55850     io1_a_src = io0_a_src + a_src->meta.ri;
55851     iop_a_src = io1_a_src;
55852     io2_a_src = io0_a_src + a_src->meta.wi;
55853   }
55854 
55855   if (self->private_impl.f_chunk_length < 4u) {
55856     status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
55857     goto exit;
55858   }
55859   self->private_impl.f_metadata_flavor = 3u;
55860   self->private_impl.f_metadata_fourcc = 1163413830u;
55861   self->private_impl.f_metadata_x = 0u;
55862   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)));
55863   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)));
55864   self->private_impl.f_chunk_length = 0u;
55865 
55866   goto ok;
55867   ok:
55868   goto exit;
55869   exit:
55870   if (a_src && a_src->data.ptr) {
55871     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
55872   }
55873 
55874   return status;
55875 }
55876 
55877 // -------- func png.decoder.decode_fctl
55878 
55879 WUFFS_BASE__GENERATED_C_CODE
55880 static wuffs_base__status
wuffs_png__decoder__decode_fctl(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)55881 wuffs_png__decoder__decode_fctl(
55882     wuffs_png__decoder* self,
55883     wuffs_base__io_buffer* a_src) {
55884   wuffs_base__status status = wuffs_base__make_status(NULL);
55885 
55886   uint32_t v_x0 = 0;
55887   uint32_t v_y0 = 0;
55888   uint32_t v_x1 = 0;
55889   uint32_t v_y1 = 0;
55890 
55891   const uint8_t* iop_a_src = NULL;
55892   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
55893   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
55894   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
55895   if (a_src && a_src->data.ptr) {
55896     io0_a_src = a_src->data.ptr;
55897     io1_a_src = io0_a_src + a_src->meta.ri;
55898     iop_a_src = io1_a_src;
55899     io2_a_src = io0_a_src + a_src->meta.wi;
55900   }
55901 
55902   uint32_t coro_susp_point = self->private_impl.p_decode_fctl[0];
55903   if (coro_susp_point) {
55904     v_x0 = self->private_data.s_decode_fctl[0].v_x0;
55905     v_x1 = self->private_data.s_decode_fctl[0].v_x1;
55906     v_y1 = self->private_data.s_decode_fctl[0].v_y1;
55907   }
55908   switch (coro_susp_point) {
55909     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
55910 
55911     if (self->private_impl.f_chunk_length != 26u) {
55912       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
55913       goto exit;
55914     }
55915     self->private_impl.f_chunk_length = 0u;
55916     {
55917       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
55918       uint32_t t_0;
55919       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
55920         t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
55921         iop_a_src += 4;
55922       } else {
55923         self->private_data.s_decode_fctl[0].scratch = 0;
55924         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
55925         while (true) {
55926           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
55927             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
55928             goto suspend;
55929           }
55930           uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch;
55931           uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu));
55932           *scratch >>= 8;
55933           *scratch <<= 8;
55934           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
55935           if (num_bits_0 == 24) {
55936             t_0 = ((uint32_t)(*scratch >> 32));
55937             break;
55938           }
55939           num_bits_0 += 8u;
55940           *scratch |= ((uint64_t)(num_bits_0));
55941         }
55942       }
55943       v_x0 = t_0;
55944     }
55945     if (v_x0 != self->private_impl.f_next_animation_seq_num) {
55946       status = wuffs_base__make_status(wuffs_png__error__bad_animation_sequence_number);
55947       goto exit;
55948     } else if (self->private_impl.f_next_animation_seq_num >= 4294967295u) {
55949       status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file);
55950       goto exit;
55951     }
55952     self->private_impl.f_next_animation_seq_num += 1u;
55953     {
55954       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
55955       uint32_t t_1;
55956       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
55957         t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
55958         iop_a_src += 4;
55959       } else {
55960         self->private_data.s_decode_fctl[0].scratch = 0;
55961         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
55962         while (true) {
55963           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
55964             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
55965             goto suspend;
55966           }
55967           uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch;
55968           uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu));
55969           *scratch >>= 8;
55970           *scratch <<= 8;
55971           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
55972           if (num_bits_1 == 24) {
55973             t_1 = ((uint32_t)(*scratch >> 32));
55974             break;
55975           }
55976           num_bits_1 += 8u;
55977           *scratch |= ((uint64_t)(num_bits_1));
55978         }
55979       }
55980       v_x1 = t_1;
55981     }
55982     {
55983       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
55984       uint32_t t_2;
55985       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
55986         t_2 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
55987         iop_a_src += 4;
55988       } else {
55989         self->private_data.s_decode_fctl[0].scratch = 0;
55990         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
55991         while (true) {
55992           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
55993             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
55994             goto suspend;
55995           }
55996           uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch;
55997           uint32_t num_bits_2 = ((uint32_t)(*scratch & 0xFFu));
55998           *scratch >>= 8;
55999           *scratch <<= 8;
56000           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_2);
56001           if (num_bits_2 == 24) {
56002             t_2 = ((uint32_t)(*scratch >> 32));
56003             break;
56004           }
56005           num_bits_2 += 8u;
56006           *scratch |= ((uint64_t)(num_bits_2));
56007         }
56008       }
56009       v_y1 = t_2;
56010     }
56011     {
56012       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
56013       uint32_t t_3;
56014       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
56015         t_3 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
56016         iop_a_src += 4;
56017       } else {
56018         self->private_data.s_decode_fctl[0].scratch = 0;
56019         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
56020         while (true) {
56021           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
56022             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
56023             goto suspend;
56024           }
56025           uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch;
56026           uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFFu));
56027           *scratch >>= 8;
56028           *scratch <<= 8;
56029           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3);
56030           if (num_bits_3 == 24) {
56031             t_3 = ((uint32_t)(*scratch >> 32));
56032             break;
56033           }
56034           num_bits_3 += 8u;
56035           *scratch |= ((uint64_t)(num_bits_3));
56036         }
56037       }
56038       v_x0 = t_3;
56039     }
56040     {
56041       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
56042       uint32_t t_4;
56043       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
56044         t_4 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
56045         iop_a_src += 4;
56046       } else {
56047         self->private_data.s_decode_fctl[0].scratch = 0;
56048         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
56049         while (true) {
56050           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
56051             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
56052             goto suspend;
56053           }
56054           uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch;
56055           uint32_t num_bits_4 = ((uint32_t)(*scratch & 0xFFu));
56056           *scratch >>= 8;
56057           *scratch <<= 8;
56058           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_4);
56059           if (num_bits_4 == 24) {
56060             t_4 = ((uint32_t)(*scratch >> 32));
56061             break;
56062           }
56063           num_bits_4 += 8u;
56064           *scratch |= ((uint64_t)(num_bits_4));
56065         }
56066       }
56067       v_y0 = t_4;
56068     }
56069     v_x1 += v_x0;
56070     v_y1 += v_y0;
56071     if ((v_x0 >= v_x1) ||
56072         (v_x0 > self->private_impl.f_width) ||
56073         (v_x1 > self->private_impl.f_width) ||
56074         (v_y0 >= v_y1) ||
56075         (v_y0 > self->private_impl.f_height) ||
56076         (v_y1 > self->private_impl.f_height)) {
56077       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
56078       goto exit;
56079     }
56080     self->private_impl.f_frame_rect_x0 = v_x0;
56081     self->private_impl.f_frame_rect_y0 = v_y0;
56082     self->private_impl.f_frame_rect_x1 = v_x1;
56083     self->private_impl.f_frame_rect_y1 = v_y1;
56084     {
56085       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
56086       uint32_t t_5;
56087       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
56088         t_5 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
56089         iop_a_src += 2;
56090       } else {
56091         self->private_data.s_decode_fctl[0].scratch = 0;
56092         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
56093         while (true) {
56094           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
56095             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
56096             goto suspend;
56097           }
56098           uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch;
56099           uint32_t num_bits_5 = ((uint32_t)(*scratch & 0xFFu));
56100           *scratch >>= 8;
56101           *scratch <<= 8;
56102           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_5);
56103           if (num_bits_5 == 8) {
56104             t_5 = ((uint32_t)(*scratch >> 48));
56105             break;
56106           }
56107           num_bits_5 += 8u;
56108           *scratch |= ((uint64_t)(num_bits_5));
56109         }
56110       }
56111       v_x0 = t_5;
56112     }
56113     {
56114       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
56115       uint32_t t_6;
56116       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
56117         t_6 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
56118         iop_a_src += 2;
56119       } else {
56120         self->private_data.s_decode_fctl[0].scratch = 0;
56121         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
56122         while (true) {
56123           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
56124             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
56125             goto suspend;
56126           }
56127           uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch;
56128           uint32_t num_bits_6 = ((uint32_t)(*scratch & 0xFFu));
56129           *scratch >>= 8;
56130           *scratch <<= 8;
56131           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_6);
56132           if (num_bits_6 == 8) {
56133             t_6 = ((uint32_t)(*scratch >> 48));
56134             break;
56135           }
56136           num_bits_6 += 8u;
56137           *scratch |= ((uint64_t)(num_bits_6));
56138         }
56139       }
56140       v_x1 = t_6;
56141     }
56142     if (v_x1 <= 0u) {
56143       self->private_impl.f_frame_duration = (((uint64_t)(v_x0)) * 7056000u);
56144     } else {
56145       self->private_impl.f_frame_duration = ((((uint64_t)(v_x0)) * 705600000u) / ((uint64_t)(v_x1)));
56146     }
56147     {
56148       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
56149       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
56150         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
56151         goto suspend;
56152       }
56153       uint32_t t_7 = *iop_a_src++;
56154       v_x0 = t_7;
56155     }
56156     if (v_x0 == 0u) {
56157       self->private_impl.f_frame_disposal = 0u;
56158     } else if (v_x0 == 1u) {
56159       self->private_impl.f_frame_disposal = 1u;
56160     } else if (v_x0 == 2u) {
56161       self->private_impl.f_frame_disposal = 2u;
56162     } else {
56163       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
56164       goto exit;
56165     }
56166     {
56167       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
56168       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
56169         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
56170         goto suspend;
56171       }
56172       uint32_t t_8 = *iop_a_src++;
56173       v_x0 = t_8;
56174     }
56175     if (v_x0 == 0u) {
56176       self->private_impl.f_frame_overwrite_instead_of_blend = true;
56177     } else if (v_x0 == 1u) {
56178       self->private_impl.f_frame_overwrite_instead_of_blend = false;
56179     } else {
56180       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
56181       goto exit;
56182     }
56183     if (self->private_impl.f_num_decoded_frame_configs_value == 0u) {
56184       self->private_impl.f_first_rect_x0 = self->private_impl.f_frame_rect_x0;
56185       self->private_impl.f_first_rect_y0 = self->private_impl.f_frame_rect_y0;
56186       self->private_impl.f_first_rect_x1 = self->private_impl.f_frame_rect_x1;
56187       self->private_impl.f_first_rect_y1 = self->private_impl.f_frame_rect_y1;
56188       self->private_impl.f_first_duration = self->private_impl.f_frame_duration;
56189       self->private_impl.f_first_disposal = self->private_impl.f_frame_disposal;
56190       self->private_impl.f_first_overwrite_instead_of_blend = self->private_impl.f_frame_overwrite_instead_of_blend;
56191     }
56192 
56193     goto ok;
56194     ok:
56195     self->private_impl.p_decode_fctl[0] = 0;
56196     goto exit;
56197   }
56198 
56199   goto suspend;
56200   suspend:
56201   self->private_impl.p_decode_fctl[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
56202   self->private_data.s_decode_fctl[0].v_x0 = v_x0;
56203   self->private_data.s_decode_fctl[0].v_x1 = v_x1;
56204   self->private_data.s_decode_fctl[0].v_y1 = v_y1;
56205 
56206   goto exit;
56207   exit:
56208   if (a_src && a_src->data.ptr) {
56209     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
56210   }
56211 
56212   return status;
56213 }
56214 
56215 // -------- func png.decoder.decode_gama
56216 
56217 WUFFS_BASE__GENERATED_C_CODE
56218 static wuffs_base__status
wuffs_png__decoder__decode_gama(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)56219 wuffs_png__decoder__decode_gama(
56220     wuffs_png__decoder* self,
56221     wuffs_base__io_buffer* a_src) {
56222   wuffs_base__status status = wuffs_base__make_status(NULL);
56223 
56224   const uint8_t* iop_a_src = NULL;
56225   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
56226   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
56227   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
56228   if (a_src && a_src->data.ptr) {
56229     io0_a_src = a_src->data.ptr;
56230     io1_a_src = io0_a_src + a_src->meta.ri;
56231     iop_a_src = io1_a_src;
56232     io2_a_src = io0_a_src + a_src->meta.wi;
56233   }
56234 
56235   uint32_t coro_susp_point = self->private_impl.p_decode_gama[0];
56236   switch (coro_susp_point) {
56237     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
56238 
56239     if (self->private_impl.f_chunk_length != 4u) {
56240       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
56241       goto exit;
56242     }
56243     self->private_impl.f_chunk_length = 0u;
56244     self->private_impl.f_metadata_flavor = 5u;
56245     self->private_impl.f_metadata_fourcc = 1195461953u;
56246     {
56247       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
56248       uint64_t t_0;
56249       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
56250         t_0 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
56251         iop_a_src += 4;
56252       } else {
56253         self->private_data.s_decode_gama[0].scratch = 0;
56254         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
56255         while (true) {
56256           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
56257             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
56258             goto suspend;
56259           }
56260           uint64_t* scratch = &self->private_data.s_decode_gama[0].scratch;
56261           uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu));
56262           *scratch >>= 8;
56263           *scratch <<= 8;
56264           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
56265           if (num_bits_0 == 24) {
56266             t_0 = ((uint64_t)(*scratch >> 32));
56267             break;
56268           }
56269           num_bits_0 += 8u;
56270           *scratch |= ((uint64_t)(num_bits_0));
56271         }
56272       }
56273       self->private_impl.f_metadata_x = t_0;
56274     }
56275     self->private_impl.f_metadata_y = 0u;
56276     self->private_impl.f_metadata_z = 0u;
56277 
56278     goto ok;
56279     ok:
56280     self->private_impl.p_decode_gama[0] = 0;
56281     goto exit;
56282   }
56283 
56284   goto suspend;
56285   suspend:
56286   self->private_impl.p_decode_gama[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
56287 
56288   goto exit;
56289   exit:
56290   if (a_src && a_src->data.ptr) {
56291     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
56292   }
56293 
56294   return status;
56295 }
56296 
56297 // -------- func png.decoder.decode_iccp
56298 
56299 WUFFS_BASE__GENERATED_C_CODE
56300 static wuffs_base__status
wuffs_png__decoder__decode_iccp(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)56301 wuffs_png__decoder__decode_iccp(
56302     wuffs_png__decoder* self,
56303     wuffs_base__io_buffer* a_src) {
56304   wuffs_base__status status = wuffs_base__make_status(NULL);
56305 
56306   uint8_t v_c = 0;
56307 
56308   const uint8_t* iop_a_src = NULL;
56309   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
56310   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
56311   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
56312   if (a_src && a_src->data.ptr) {
56313     io0_a_src = a_src->data.ptr;
56314     io1_a_src = io0_a_src + a_src->meta.ri;
56315     iop_a_src = io1_a_src;
56316     io2_a_src = io0_a_src + a_src->meta.wi;
56317   }
56318 
56319   uint32_t coro_susp_point = self->private_impl.p_decode_iccp[0];
56320   switch (coro_susp_point) {
56321     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
56322 
56323     while (true) {
56324       if (self->private_impl.f_chunk_length <= 0u) {
56325         status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
56326         goto exit;
56327       }
56328       self->private_impl.f_chunk_length -= 1u;
56329       {
56330         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
56331         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
56332           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
56333           goto suspend;
56334         }
56335         uint8_t t_0 = *iop_a_src++;
56336         v_c = t_0;
56337       }
56338       if (v_c == 0u) {
56339         break;
56340       }
56341     }
56342     if (self->private_impl.f_chunk_length <= 0u) {
56343       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
56344       goto exit;
56345     }
56346     self->private_impl.f_chunk_length -= 1u;
56347     {
56348       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
56349       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
56350         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
56351         goto suspend;
56352       }
56353       uint8_t t_1 = *iop_a_src++;
56354       v_c = t_1;
56355     }
56356     if (v_c != 0u) {
56357       status = wuffs_base__make_status(wuffs_png__error__unsupported_png_compression_method);
56358       goto exit;
56359     }
56360     self->private_impl.f_metadata_is_zlib_compressed = true;
56361     self->private_impl.f_metadata_flavor = 4u;
56362     self->private_impl.f_metadata_fourcc = 1229144912u;
56363     self->private_impl.f_metadata_x = 0u;
56364     self->private_impl.f_metadata_y = 0u;
56365     self->private_impl.f_metadata_z = 0u;
56366 
56367     goto ok;
56368     ok:
56369     self->private_impl.p_decode_iccp[0] = 0;
56370     goto exit;
56371   }
56372 
56373   goto suspend;
56374   suspend:
56375   self->private_impl.p_decode_iccp[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
56376 
56377   goto exit;
56378   exit:
56379   if (a_src && a_src->data.ptr) {
56380     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
56381   }
56382 
56383   return status;
56384 }
56385 
56386 // -------- func png.decoder.decode_plte
56387 
56388 WUFFS_BASE__GENERATED_C_CODE
56389 static wuffs_base__status
wuffs_png__decoder__decode_plte(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)56390 wuffs_png__decoder__decode_plte(
56391     wuffs_png__decoder* self,
56392     wuffs_base__io_buffer* a_src) {
56393   wuffs_base__status status = wuffs_base__make_status(NULL);
56394 
56395   uint32_t v_num_entries = 0;
56396   uint32_t v_i = 0;
56397   uint32_t v_argb = 0;
56398 
56399   const uint8_t* iop_a_src = NULL;
56400   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
56401   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
56402   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
56403   if (a_src && a_src->data.ptr) {
56404     io0_a_src = a_src->data.ptr;
56405     io1_a_src = io0_a_src + a_src->meta.ri;
56406     iop_a_src = io1_a_src;
56407     io2_a_src = io0_a_src + a_src->meta.wi;
56408   }
56409 
56410   uint32_t coro_susp_point = self->private_impl.p_decode_plte[0];
56411   if (coro_susp_point) {
56412     v_num_entries = self->private_data.s_decode_plte[0].v_num_entries;
56413     v_i = self->private_data.s_decode_plte[0].v_i;
56414   }
56415   switch (coro_susp_point) {
56416     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
56417 
56418     if ((self->private_impl.f_chunk_length > 768u) || ((self->private_impl.f_chunk_length % 3u) != 0u)) {
56419       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
56420       goto exit;
56421     }
56422     v_num_entries = (((uint32_t)(self->private_impl.f_chunk_length)) / 3u);
56423     self->private_impl.f_chunk_length = 0u;
56424     while (v_i < v_num_entries) {
56425       {
56426         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
56427         uint32_t t_0;
56428         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) {
56429           t_0 = ((uint32_t)(wuffs_base__peek_u24be__no_bounds_check(iop_a_src)));
56430           iop_a_src += 3;
56431         } else {
56432           self->private_data.s_decode_plte[0].scratch = 0;
56433           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
56434           while (true) {
56435             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
56436               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
56437               goto suspend;
56438             }
56439             uint64_t* scratch = &self->private_data.s_decode_plte[0].scratch;
56440             uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu));
56441             *scratch >>= 8;
56442             *scratch <<= 8;
56443             *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
56444             if (num_bits_0 == 16) {
56445               t_0 = ((uint32_t)(*scratch >> 40));
56446               break;
56447             }
56448             num_bits_0 += 8u;
56449             *scratch |= ((uint64_t)(num_bits_0));
56450           }
56451         }
56452         v_argb = t_0;
56453       }
56454       v_argb |= 4278190080u;
56455       self->private_data.f_src_palette[((4u * v_i) + 0u)] = ((uint8_t)((v_argb >> 0u)));
56456       self->private_data.f_src_palette[((4u * v_i) + 1u)] = ((uint8_t)((v_argb >> 8u)));
56457       self->private_data.f_src_palette[((4u * v_i) + 2u)] = ((uint8_t)((v_argb >> 16u)));
56458       self->private_data.f_src_palette[((4u * v_i) + 3u)] = ((uint8_t)((v_argb >> 24u)));
56459       v_i += 1u;
56460     }
56461     while (v_i < 256u) {
56462       self->private_data.f_src_palette[((4u * v_i) + 0u)] = 0u;
56463       self->private_data.f_src_palette[((4u * v_i) + 1u)] = 0u;
56464       self->private_data.f_src_palette[((4u * v_i) + 2u)] = 0u;
56465       self->private_data.f_src_palette[((4u * v_i) + 3u)] = 255u;
56466       v_i += 1u;
56467     }
56468 
56469     goto ok;
56470     ok:
56471     self->private_impl.p_decode_plte[0] = 0;
56472     goto exit;
56473   }
56474 
56475   goto suspend;
56476   suspend:
56477   self->private_impl.p_decode_plte[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
56478   self->private_data.s_decode_plte[0].v_num_entries = v_num_entries;
56479   self->private_data.s_decode_plte[0].v_i = v_i;
56480 
56481   goto exit;
56482   exit:
56483   if (a_src && a_src->data.ptr) {
56484     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
56485   }
56486 
56487   return status;
56488 }
56489 
56490 // -------- func png.decoder.decode_srgb
56491 
56492 WUFFS_BASE__GENERATED_C_CODE
56493 static wuffs_base__status
wuffs_png__decoder__decode_srgb(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)56494 wuffs_png__decoder__decode_srgb(
56495     wuffs_png__decoder* self,
56496     wuffs_base__io_buffer* a_src) {
56497   wuffs_base__status status = wuffs_base__make_status(NULL);
56498 
56499   const uint8_t* iop_a_src = NULL;
56500   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
56501   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
56502   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
56503   if (a_src && a_src->data.ptr) {
56504     io0_a_src = a_src->data.ptr;
56505     io1_a_src = io0_a_src + a_src->meta.ri;
56506     iop_a_src = io1_a_src;
56507     io2_a_src = io0_a_src + a_src->meta.wi;
56508   }
56509 
56510   uint32_t coro_susp_point = self->private_impl.p_decode_srgb[0];
56511   switch (coro_susp_point) {
56512     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
56513 
56514     if (self->private_impl.f_chunk_length != 1u) {
56515       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
56516       goto exit;
56517     }
56518     self->private_impl.f_chunk_length = 0u;
56519     self->private_impl.f_metadata_flavor = 5u;
56520     self->private_impl.f_metadata_fourcc = 1397901122u;
56521     {
56522       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
56523       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
56524         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
56525         goto suspend;
56526       }
56527       uint64_t t_0 = *iop_a_src++;
56528       self->private_impl.f_metadata_x = t_0;
56529     }
56530     self->private_impl.f_metadata_y = 0u;
56531     self->private_impl.f_metadata_z = 0u;
56532 
56533     goto ok;
56534     ok:
56535     self->private_impl.p_decode_srgb[0] = 0;
56536     goto exit;
56537   }
56538 
56539   goto suspend;
56540   suspend:
56541   self->private_impl.p_decode_srgb[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
56542 
56543   goto exit;
56544   exit:
56545   if (a_src && a_src->data.ptr) {
56546     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
56547   }
56548 
56549   return status;
56550 }
56551 
56552 // -------- func png.decoder.decode_trns
56553 
56554 WUFFS_BASE__GENERATED_C_CODE
56555 static wuffs_base__status
wuffs_png__decoder__decode_trns(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)56556 wuffs_png__decoder__decode_trns(
56557     wuffs_png__decoder* self,
56558     wuffs_base__io_buffer* a_src) {
56559   wuffs_base__status status = wuffs_base__make_status(NULL);
56560 
56561   uint32_t v_i = 0;
56562   uint32_t v_n = 0;
56563   uint64_t v_u = 0;
56564 
56565   const uint8_t* iop_a_src = NULL;
56566   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
56567   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
56568   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
56569   if (a_src && a_src->data.ptr) {
56570     io0_a_src = a_src->data.ptr;
56571     io1_a_src = io0_a_src + a_src->meta.ri;
56572     iop_a_src = io1_a_src;
56573     io2_a_src = io0_a_src + a_src->meta.wi;
56574   }
56575 
56576   uint32_t coro_susp_point = self->private_impl.p_decode_trns[0];
56577   if (coro_susp_point) {
56578     v_i = self->private_data.s_decode_trns[0].v_i;
56579     v_n = self->private_data.s_decode_trns[0].v_n;
56580   }
56581   switch (coro_susp_point) {
56582     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
56583 
56584     if (self->private_impl.f_color_type == 0u) {
56585       self->private_impl.choosy_filter_and_swizzle = (
56586           &wuffs_png__decoder__filter_and_swizzle_tricky);
56587       if (self->private_impl.f_depth <= 8u) {
56588         self->private_impl.f_dst_pixfmt = 2164295816u;
56589         self->private_impl.f_src_pixfmt = 2164295816u;
56590       } else {
56591         self->private_impl.f_dst_pixfmt = 2164308923u;
56592         self->private_impl.f_src_pixfmt = 2164308923u;
56593       }
56594       if (self->private_impl.f_chunk_length != 2u) {
56595         status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
56596         goto exit;
56597       }
56598       self->private_impl.f_chunk_length = 0u;
56599       {
56600         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
56601         uint64_t t_0;
56602         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
56603           t_0 = ((uint64_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
56604           iop_a_src += 2;
56605         } else {
56606           self->private_data.s_decode_trns[0].scratch = 0;
56607           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
56608           while (true) {
56609             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
56610               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
56611               goto suspend;
56612             }
56613             uint64_t* scratch = &self->private_data.s_decode_trns[0].scratch;
56614             uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu));
56615             *scratch >>= 8;
56616             *scratch <<= 8;
56617             *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
56618             if (num_bits_0 == 8) {
56619               t_0 = ((uint64_t)(*scratch >> 48));
56620               break;
56621             }
56622             num_bits_0 += 8u;
56623             *scratch |= ((uint64_t)(num_bits_0));
56624           }
56625         }
56626         v_u = t_0;
56627       }
56628       if (self->private_impl.f_depth <= 1u) {
56629         self->private_impl.f_remap_transparency = (((v_u & 1u) * 16777215u) | 4278190080u);
56630       } else if (self->private_impl.f_depth <= 2u) {
56631         self->private_impl.f_remap_transparency = (((v_u & 3u) * 5592405u) | 4278190080u);
56632       } else if (self->private_impl.f_depth <= 4u) {
56633         self->private_impl.f_remap_transparency = (((v_u & 15u) * 1118481u) | 4278190080u);
56634       } else if (self->private_impl.f_depth <= 8u) {
56635         self->private_impl.f_remap_transparency = (((v_u & 255u) * 65793u) | 4278190080u);
56636       } else {
56637         self->private_impl.f_remap_transparency = ((v_u * 4295032833u) | 18446462598732840960u);
56638       }
56639     } else if (self->private_impl.f_color_type == 2u) {
56640       self->private_impl.choosy_filter_and_swizzle = (
56641           &wuffs_png__decoder__filter_and_swizzle_tricky);
56642       if (self->private_impl.f_depth <= 8u) {
56643         self->private_impl.f_dst_pixfmt = 2164295816u;
56644         self->private_impl.f_src_pixfmt = 2164295816u;
56645       } else {
56646         self->private_impl.f_dst_pixfmt = 2164308923u;
56647         self->private_impl.f_src_pixfmt = 2164308923u;
56648       }
56649       if (self->private_impl.f_chunk_length != 6u) {
56650         status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
56651         goto exit;
56652       }
56653       self->private_impl.f_chunk_length = 0u;
56654       {
56655         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
56656         uint64_t t_1;
56657         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 6)) {
56658           t_1 = ((uint64_t)(wuffs_base__peek_u48be__no_bounds_check(iop_a_src)));
56659           iop_a_src += 6;
56660         } else {
56661           self->private_data.s_decode_trns[0].scratch = 0;
56662           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
56663           while (true) {
56664             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
56665               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
56666               goto suspend;
56667             }
56668             uint64_t* scratch = &self->private_data.s_decode_trns[0].scratch;
56669             uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu));
56670             *scratch >>= 8;
56671             *scratch <<= 8;
56672             *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
56673             if (num_bits_1 == 40) {
56674               t_1 = ((uint64_t)(*scratch >> 16));
56675               break;
56676             }
56677             num_bits_1 += 8u;
56678             *scratch |= ((uint64_t)(num_bits_1));
56679           }
56680         }
56681         v_u = t_1;
56682       }
56683       if (self->private_impl.f_depth <= 8u) {
56684         self->private_impl.f_remap_transparency = ((255u & (v_u >> 0u)) |
56685             (65280u & (v_u >> 8u)) |
56686             (16711680u & (v_u >> 16u)) |
56687             4278190080u);
56688       } else {
56689         self->private_impl.f_remap_transparency = (v_u | 18446462598732840960u);
56690       }
56691     } else if (self->private_impl.f_color_type == 3u) {
56692       self->private_impl.f_dst_pixfmt = 2164523016u;
56693       self->private_impl.f_src_pixfmt = 2164523016u;
56694       if (self->private_impl.f_chunk_length > 256u) {
56695         status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
56696         goto exit;
56697       }
56698       v_n = ((uint32_t)(self->private_impl.f_chunk_length));
56699       self->private_impl.f_chunk_length = 0u;
56700       while (v_i < v_n) {
56701         {
56702           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
56703           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
56704             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
56705             goto suspend;
56706           }
56707           uint8_t t_2 = *iop_a_src++;
56708           self->private_data.f_src_palette[((4u * v_i) + 3u)] = t_2;
56709         }
56710         v_i += 1u;
56711       }
56712     } else {
56713       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
56714       goto exit;
56715     }
56716 
56717     goto ok;
56718     ok:
56719     self->private_impl.p_decode_trns[0] = 0;
56720     goto exit;
56721   }
56722 
56723   goto suspend;
56724   suspend:
56725   self->private_impl.p_decode_trns[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
56726   self->private_data.s_decode_trns[0].v_i = v_i;
56727   self->private_data.s_decode_trns[0].v_n = v_n;
56728 
56729   goto exit;
56730   exit:
56731   if (a_src && a_src->data.ptr) {
56732     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
56733   }
56734 
56735   return status;
56736 }
56737 
56738 // -------- func png.decoder.decode_frame_config
56739 
56740 WUFFS_BASE__GENERATED_C_CODE
56741 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_png__decoder__decode_frame_config(wuffs_png__decoder * self,wuffs_base__frame_config * a_dst,wuffs_base__io_buffer * a_src)56742 wuffs_png__decoder__decode_frame_config(
56743     wuffs_png__decoder* self,
56744     wuffs_base__frame_config* a_dst,
56745     wuffs_base__io_buffer* a_src) {
56746   if (!self) {
56747     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
56748   }
56749   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
56750     return wuffs_base__make_status(
56751         (self->private_impl.magic == WUFFS_BASE__DISABLED)
56752         ? wuffs_base__error__disabled_by_previous_error
56753         : wuffs_base__error__initialize_not_called);
56754   }
56755   if (!a_src) {
56756     self->private_impl.magic = WUFFS_BASE__DISABLED;
56757     return wuffs_base__make_status(wuffs_base__error__bad_argument);
56758   }
56759   if ((self->private_impl.active_coroutine != 0) &&
56760       (self->private_impl.active_coroutine != 2)) {
56761     self->private_impl.magic = WUFFS_BASE__DISABLED;
56762     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
56763   }
56764   self->private_impl.active_coroutine = 0;
56765   wuffs_base__status status = wuffs_base__make_status(NULL);
56766 
56767   wuffs_base__status v_status = wuffs_base__make_status(NULL);
56768 
56769   uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
56770   switch (coro_susp_point) {
56771     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
56772 
56773     while (true) {
56774       {
56775         wuffs_base__status t_0 = wuffs_png__decoder__do_decode_frame_config(self, a_dst, a_src);
56776         v_status = t_0;
56777       }
56778       if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
56779         status = wuffs_base__make_status(wuffs_png__error__truncated_input);
56780         goto exit;
56781       }
56782       status = v_status;
56783       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
56784     }
56785 
56786     ok:
56787     self->private_impl.p_decode_frame_config[0] = 0;
56788     goto exit;
56789   }
56790 
56791   goto suspend;
56792   suspend:
56793   self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
56794   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
56795 
56796   goto exit;
56797   exit:
56798   if (wuffs_base__status__is_error(&status)) {
56799     self->private_impl.magic = WUFFS_BASE__DISABLED;
56800   }
56801   return status;
56802 }
56803 
56804 // -------- func png.decoder.do_decode_frame_config
56805 
56806 WUFFS_BASE__GENERATED_C_CODE
56807 static wuffs_base__status
wuffs_png__decoder__do_decode_frame_config(wuffs_png__decoder * self,wuffs_base__frame_config * a_dst,wuffs_base__io_buffer * a_src)56808 wuffs_png__decoder__do_decode_frame_config(
56809     wuffs_png__decoder* self,
56810     wuffs_base__frame_config* a_dst,
56811     wuffs_base__io_buffer* a_src) {
56812   wuffs_base__status status = wuffs_base__make_status(NULL);
56813 
56814   uint32_t v_checksum_have = 0;
56815 
56816   const uint8_t* iop_a_src = NULL;
56817   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
56818   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
56819   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
56820   if (a_src && a_src->data.ptr) {
56821     io0_a_src = a_src->data.ptr;
56822     io1_a_src = io0_a_src + a_src->meta.ri;
56823     iop_a_src = io1_a_src;
56824     io2_a_src = io0_a_src + a_src->meta.wi;
56825   }
56826 
56827   uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config[0];
56828   switch (coro_susp_point) {
56829     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
56830 
56831     if ((self->private_impl.f_call_sequence & 16u) != 0u) {
56832       status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
56833       goto exit;
56834     } else if (self->private_impl.f_call_sequence == 32u) {
56835     } else if (self->private_impl.f_call_sequence < 32u) {
56836       if (a_src) {
56837         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
56838       }
56839       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
56840       status = wuffs_png__decoder__do_decode_image_config(self, NULL, a_src);
56841       if (a_src) {
56842         iop_a_src = a_src->data.ptr + a_src->meta.ri;
56843       }
56844       if (status.repr) {
56845         goto suspend;
56846       }
56847     } else if (self->private_impl.f_call_sequence == 40u) {
56848       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)))) {
56849         status = wuffs_base__make_status(wuffs_base__error__bad_restart);
56850         goto exit;
56851       }
56852     } else if (self->private_impl.f_call_sequence == 64u) {
56853       if (a_src) {
56854         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
56855       }
56856       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
56857       status = wuffs_png__decoder__skip_frame(self, a_src);
56858       if (a_src) {
56859         iop_a_src = a_src->data.ptr + a_src->meta.ri;
56860       }
56861       if (status.repr) {
56862         goto suspend;
56863       }
56864     } else {
56865       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
56866       goto ok;
56867     }
56868     if (self->private_impl.f_metadata_fourcc != 0u) {
56869       self->private_impl.f_call_sequence = 48u;
56870       status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
56871       goto ok;
56872     }
56873     if (self->private_impl.f_num_decoded_frame_configs_value == 0u) {
56874       self->private_impl.f_frame_rect_x0 = self->private_impl.f_first_rect_x0;
56875       self->private_impl.f_frame_rect_y0 = self->private_impl.f_first_rect_y0;
56876       self->private_impl.f_frame_rect_x1 = self->private_impl.f_first_rect_x1;
56877       self->private_impl.f_frame_rect_y1 = self->private_impl.f_first_rect_y1;
56878       self->private_impl.f_frame_config_io_position = self->private_impl.f_first_config_io_position;
56879       self->private_impl.f_frame_duration = self->private_impl.f_first_duration;
56880       self->private_impl.f_frame_disposal = self->private_impl.f_first_disposal;
56881       self->private_impl.f_frame_overwrite_instead_of_blend = self->private_impl.f_first_overwrite_instead_of_blend;
56882     } else {
56883       while (true) {
56884         {
56885           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
56886           uint32_t t_0;
56887           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
56888             t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
56889             iop_a_src += 4;
56890           } else {
56891             self->private_data.s_do_decode_frame_config[0].scratch = 0;
56892             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
56893             while (true) {
56894               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
56895                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
56896                 goto suspend;
56897               }
56898               uint64_t* scratch = &self->private_data.s_do_decode_frame_config[0].scratch;
56899               uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu));
56900               *scratch >>= 8;
56901               *scratch <<= 8;
56902               *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
56903               if (num_bits_0 == 24) {
56904                 t_0 = ((uint32_t)(*scratch >> 32));
56905                 break;
56906               }
56907               num_bits_0 += 8u;
56908               *scratch |= ((uint64_t)(num_bits_0));
56909             }
56910           }
56911           self->private_impl.f_chunk_length = t_0;
56912         }
56913         {
56914           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
56915           uint32_t t_1;
56916           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
56917             t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
56918             iop_a_src += 4;
56919           } else {
56920             self->private_data.s_do_decode_frame_config[0].scratch = 0;
56921             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
56922             while (true) {
56923               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
56924                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
56925                 goto suspend;
56926               }
56927               uint64_t* scratch = &self->private_data.s_do_decode_frame_config[0].scratch;
56928               uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
56929               *scratch <<= 8;
56930               *scratch >>= 8;
56931               *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
56932               if (num_bits_1 == 24) {
56933                 t_1 = ((uint32_t)(*scratch));
56934                 break;
56935               }
56936               num_bits_1 += 8u;
56937               *scratch |= ((uint64_t)(num_bits_1)) << 56;
56938             }
56939           }
56940           self->private_impl.f_chunk_type = t_1;
56941         }
56942         if (self->private_impl.f_chunk_type == 1145980233u) {
56943           if (self->private_impl.f_chunk_length != 0u) {
56944             status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
56945             goto exit;
56946           }
56947           {
56948             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
56949             uint32_t t_2;
56950             if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
56951               t_2 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
56952               iop_a_src += 4;
56953             } else {
56954               self->private_data.s_do_decode_frame_config[0].scratch = 0;
56955               WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
56956               while (true) {
56957                 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
56958                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
56959                   goto suspend;
56960                 }
56961                 uint64_t* scratch = &self->private_data.s_do_decode_frame_config[0].scratch;
56962                 uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
56963                 *scratch <<= 8;
56964                 *scratch >>= 8;
56965                 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
56966                 if (num_bits_2 == 24) {
56967                   t_2 = ((uint32_t)(*scratch));
56968                   break;
56969                 }
56970                 num_bits_2 += 8u;
56971                 *scratch |= ((uint64_t)(num_bits_2)) << 56;
56972               }
56973             }
56974             v_checksum_have = t_2;
56975           }
56976           if ( ! self->private_impl.f_ignore_checksum && (v_checksum_have != 2187346606u)) {
56977             status = wuffs_base__make_status(wuffs_png__error__bad_checksum);
56978             goto exit;
56979           }
56980           self->private_impl.f_call_sequence = 96u;
56981           status = wuffs_base__make_status(wuffs_base__note__end_of_data);
56982           goto ok;
56983         } else if (self->private_impl.f_chunk_type == 1413571686u) {
56984           status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
56985           goto exit;
56986         } else if (self->private_impl.f_chunk_type == 1280598886u) {
56987           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));
56988           if (a_src) {
56989             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
56990           }
56991           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
56992           status = wuffs_png__decoder__decode_fctl(self, a_src);
56993           if (a_src) {
56994             iop_a_src = a_src->data.ptr + a_src->meta.ri;
56995           }
56996           if (status.repr) {
56997             goto suspend;
56998           }
56999           self->private_data.s_do_decode_frame_config[0].scratch = 4u;
57000           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
57001           if (self->private_data.s_do_decode_frame_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
57002             self->private_data.s_do_decode_frame_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
57003             iop_a_src = io2_a_src;
57004             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
57005             goto suspend;
57006           }
57007           iop_a_src += self->private_data.s_do_decode_frame_config[0].scratch;
57008           break;
57009         }
57010         if (a_src) {
57011           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
57012         }
57013         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
57014         status = wuffs_png__decoder__decode_other_chunk(self, a_src, true);
57015         if (a_src) {
57016           iop_a_src = a_src->data.ptr + a_src->meta.ri;
57017         }
57018         if (status.repr) {
57019           goto suspend;
57020         }
57021         if (self->private_impl.f_metadata_fourcc != 0u) {
57022           self->private_impl.f_call_sequence = 48u;
57023           status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
57024           goto ok;
57025         }
57026         self->private_data.s_do_decode_frame_config[0].scratch = 4u;
57027         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
57028         if (self->private_data.s_do_decode_frame_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
57029           self->private_data.s_do_decode_frame_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
57030           iop_a_src = io2_a_src;
57031           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
57032           goto suspend;
57033         }
57034         iop_a_src += self->private_data.s_do_decode_frame_config[0].scratch;
57035         self->private_impl.f_chunk_length = 0u;
57036       }
57037     }
57038     if (a_dst != NULL) {
57039       wuffs_base__frame_config__set(
57040           a_dst,
57041           wuffs_base__utility__make_rect_ie_u32(
57042           self->private_impl.f_frame_rect_x0,
57043           self->private_impl.f_frame_rect_y0,
57044           self->private_impl.f_frame_rect_x1,
57045           self->private_impl.f_frame_rect_y1),
57046           ((wuffs_base__flicks)(self->private_impl.f_frame_duration)),
57047           ((uint64_t)(self->private_impl.f_num_decoded_frame_configs_value)),
57048           self->private_impl.f_frame_config_io_position,
57049           self->private_impl.f_frame_disposal,
57050           ((self->private_impl.f_color_type <= 3u) &&  ! self->private_impl.f_seen_trns),
57051           self->private_impl.f_frame_overwrite_instead_of_blend,
57052           0u);
57053     }
57054     wuffs_base__u32__sat_add_indirect(&self->private_impl.f_num_decoded_frame_configs_value, 1u);
57055     self->private_impl.f_call_sequence = 64u;
57056 
57057     ok:
57058     self->private_impl.p_do_decode_frame_config[0] = 0;
57059     goto exit;
57060   }
57061 
57062   goto suspend;
57063   suspend:
57064   self->private_impl.p_do_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
57065 
57066   goto exit;
57067   exit:
57068   if (a_src && a_src->data.ptr) {
57069     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
57070   }
57071 
57072   return status;
57073 }
57074 
57075 // -------- func png.decoder.skip_frame
57076 
57077 WUFFS_BASE__GENERATED_C_CODE
57078 static wuffs_base__status
wuffs_png__decoder__skip_frame(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)57079 wuffs_png__decoder__skip_frame(
57080     wuffs_png__decoder* self,
57081     wuffs_base__io_buffer* a_src) {
57082   wuffs_base__status status = wuffs_base__make_status(NULL);
57083 
57084   uint32_t v_seq_num = 0;
57085 
57086   const uint8_t* iop_a_src = NULL;
57087   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
57088   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
57089   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
57090   if (a_src && a_src->data.ptr) {
57091     io0_a_src = a_src->data.ptr;
57092     io1_a_src = io0_a_src + a_src->meta.ri;
57093     iop_a_src = io1_a_src;
57094     io2_a_src = io0_a_src + a_src->meta.wi;
57095   }
57096 
57097   uint32_t coro_susp_point = self->private_impl.p_skip_frame[0];
57098   switch (coro_susp_point) {
57099     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
57100 
57101     self->private_impl.f_chunk_type_array[0u] = 0u;
57102     self->private_impl.f_chunk_type_array[1u] = 0u;
57103     self->private_impl.f_chunk_type_array[2u] = 0u;
57104     self->private_impl.f_chunk_type_array[3u] = 0u;
57105     while (true) {
57106       if (((uint64_t)(io2_a_src - iop_a_src)) < 8u) {
57107         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
57108         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
57109         continue;
57110       }
57111       self->private_impl.f_chunk_length = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
57112       self->private_impl.f_chunk_type = ((uint32_t)((wuffs_base__peek_u64le__no_bounds_check(iop_a_src) >> 32u)));
57113       if (self->private_impl.f_chunk_type == 1413563465u) {
57114         if (self->private_impl.f_chunk_type_array[0u] == 102u) {
57115           status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
57116           goto exit;
57117         }
57118         self->private_impl.f_chunk_type_array[0u] = 73u;
57119         self->private_impl.f_chunk_type_array[1u] = 68u;
57120         self->private_impl.f_chunk_type_array[2u] = 65u;
57121         self->private_impl.f_chunk_type_array[3u] = 84u;
57122       } else if (self->private_impl.f_chunk_type == 1413571686u) {
57123         if (self->private_impl.f_chunk_type_array[0u] == 73u) {
57124           status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
57125           goto exit;
57126         }
57127         self->private_impl.f_chunk_type_array[0u] = 102u;
57128         self->private_impl.f_chunk_type_array[1u] = 100u;
57129         self->private_impl.f_chunk_type_array[2u] = 65u;
57130         self->private_impl.f_chunk_type_array[3u] = 84u;
57131         if (self->private_impl.f_chunk_length < 4u) {
57132           status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
57133           goto exit;
57134         }
57135         self->private_impl.f_chunk_length -= 4u;
57136         iop_a_src += 8u;
57137         {
57138           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
57139           uint32_t t_0;
57140           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
57141             t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
57142             iop_a_src += 4;
57143           } else {
57144             self->private_data.s_skip_frame[0].scratch = 0;
57145             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
57146             while (true) {
57147               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
57148                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
57149                 goto suspend;
57150               }
57151               uint64_t* scratch = &self->private_data.s_skip_frame[0].scratch;
57152               uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu));
57153               *scratch >>= 8;
57154               *scratch <<= 8;
57155               *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
57156               if (num_bits_0 == 24) {
57157                 t_0 = ((uint32_t)(*scratch >> 32));
57158                 break;
57159               }
57160               num_bits_0 += 8u;
57161               *scratch |= ((uint64_t)(num_bits_0));
57162             }
57163           }
57164           v_seq_num = t_0;
57165         }
57166         if (v_seq_num != self->private_impl.f_next_animation_seq_num) {
57167           status = wuffs_base__make_status(wuffs_png__error__bad_animation_sequence_number);
57168           goto exit;
57169         } else if (self->private_impl.f_next_animation_seq_num >= 4294967295u) {
57170           status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file);
57171           goto exit;
57172         }
57173         self->private_impl.f_next_animation_seq_num += 1u;
57174         self->private_data.s_skip_frame[0].scratch = (((uint64_t)(self->private_impl.f_chunk_length)) + 4u);
57175         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
57176         if (self->private_data.s_skip_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
57177           self->private_data.s_skip_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
57178           iop_a_src = io2_a_src;
57179           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
57180           goto suspend;
57181         }
57182         iop_a_src += self->private_data.s_skip_frame[0].scratch;
57183         self->private_impl.f_chunk_length = 0u;
57184         continue;
57185       } else if (self->private_impl.f_chunk_type_array[0u] != 0u) {
57186         break;
57187       } else if (self->private_impl.f_chunk_type == 1280598886u) {
57188         status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
57189         goto exit;
57190       }
57191       self->private_data.s_skip_frame[0].scratch = (((uint64_t)(self->private_impl.f_chunk_length)) + 12u);
57192       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
57193       if (self->private_data.s_skip_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
57194         self->private_data.s_skip_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
57195         iop_a_src = io2_a_src;
57196         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
57197         goto suspend;
57198       }
57199       iop_a_src += self->private_data.s_skip_frame[0].scratch;
57200       self->private_impl.f_chunk_length = 0u;
57201     }
57202     wuffs_base__u32__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1u);
57203     self->private_impl.f_call_sequence = 32u;
57204 
57205     ok:
57206     self->private_impl.p_skip_frame[0] = 0;
57207     goto exit;
57208   }
57209 
57210   goto suspend;
57211   suspend:
57212   self->private_impl.p_skip_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
57213 
57214   goto exit;
57215   exit:
57216   if (a_src && a_src->data.ptr) {
57217     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
57218   }
57219 
57220   return status;
57221 }
57222 
57223 // -------- func png.decoder.decode_frame
57224 
57225 WUFFS_BASE__GENERATED_C_CODE
57226 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_png__decoder__decode_frame(wuffs_png__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__pixel_blend a_blend,wuffs_base__slice_u8 a_workbuf,wuffs_base__decode_frame_options * a_opts)57227 wuffs_png__decoder__decode_frame(
57228     wuffs_png__decoder* self,
57229     wuffs_base__pixel_buffer* a_dst,
57230     wuffs_base__io_buffer* a_src,
57231     wuffs_base__pixel_blend a_blend,
57232     wuffs_base__slice_u8 a_workbuf,
57233     wuffs_base__decode_frame_options* a_opts) {
57234   if (!self) {
57235     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
57236   }
57237   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
57238     return wuffs_base__make_status(
57239         (self->private_impl.magic == WUFFS_BASE__DISABLED)
57240         ? wuffs_base__error__disabled_by_previous_error
57241         : wuffs_base__error__initialize_not_called);
57242   }
57243   if (!a_dst || !a_src) {
57244     self->private_impl.magic = WUFFS_BASE__DISABLED;
57245     return wuffs_base__make_status(wuffs_base__error__bad_argument);
57246   }
57247   if ((self->private_impl.active_coroutine != 0) &&
57248       (self->private_impl.active_coroutine != 3)) {
57249     self->private_impl.magic = WUFFS_BASE__DISABLED;
57250     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
57251   }
57252   self->private_impl.active_coroutine = 0;
57253   wuffs_base__status status = wuffs_base__make_status(NULL);
57254 
57255   wuffs_base__status v_status = wuffs_base__make_status(NULL);
57256 
57257   uint32_t coro_susp_point = self->private_impl.p_decode_frame[0];
57258   switch (coro_susp_point) {
57259     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
57260 
57261     while (true) {
57262       {
57263         wuffs_base__status t_0 = wuffs_png__decoder__do_decode_frame(self,
57264             a_dst,
57265             a_src,
57266             a_blend,
57267             a_workbuf,
57268             a_opts);
57269         v_status = t_0;
57270       }
57271       if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
57272         status = wuffs_base__make_status(wuffs_png__error__truncated_input);
57273         goto exit;
57274       }
57275       status = v_status;
57276       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
57277     }
57278 
57279     ok:
57280     self->private_impl.p_decode_frame[0] = 0;
57281     goto exit;
57282   }
57283 
57284   goto suspend;
57285   suspend:
57286   self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
57287   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
57288 
57289   goto exit;
57290   exit:
57291   if (wuffs_base__status__is_error(&status)) {
57292     self->private_impl.magic = WUFFS_BASE__DISABLED;
57293   }
57294   return status;
57295 }
57296 
57297 // -------- func png.decoder.do_decode_frame
57298 
57299 WUFFS_BASE__GENERATED_C_CODE
57300 static wuffs_base__status
wuffs_png__decoder__do_decode_frame(wuffs_png__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__pixel_blend a_blend,wuffs_base__slice_u8 a_workbuf,wuffs_base__decode_frame_options * a_opts)57301 wuffs_png__decoder__do_decode_frame(
57302     wuffs_png__decoder* self,
57303     wuffs_base__pixel_buffer* a_dst,
57304     wuffs_base__io_buffer* a_src,
57305     wuffs_base__pixel_blend a_blend,
57306     wuffs_base__slice_u8 a_workbuf,
57307     wuffs_base__decode_frame_options* a_opts) {
57308   wuffs_base__status status = wuffs_base__make_status(NULL);
57309 
57310   uint32_t v_seq_num = 0;
57311   wuffs_base__status v_status = wuffs_base__make_status(NULL);
57312   uint32_t v_pass_width = 0;
57313   uint32_t v_pass_height = 0;
57314 
57315   const uint8_t* iop_a_src = NULL;
57316   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
57317   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
57318   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
57319   if (a_src && a_src->data.ptr) {
57320     io0_a_src = a_src->data.ptr;
57321     io1_a_src = io0_a_src + a_src->meta.ri;
57322     iop_a_src = io1_a_src;
57323     io2_a_src = io0_a_src + a_src->meta.wi;
57324   }
57325 
57326   uint32_t coro_susp_point = self->private_impl.p_do_decode_frame[0];
57327   switch (coro_susp_point) {
57328     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
57329 
57330     if ((self->private_impl.f_call_sequence & 16u) != 0u) {
57331       status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
57332       goto exit;
57333     } else if (self->private_impl.f_call_sequence >= 96u) {
57334       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
57335       goto ok;
57336     } else if (self->private_impl.f_call_sequence != 64u) {
57337       if (a_src) {
57338         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
57339       }
57340       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
57341       status = wuffs_png__decoder__do_decode_frame_config(self, NULL, a_src);
57342       if (a_src) {
57343         iop_a_src = a_src->data.ptr + a_src->meta.ri;
57344       }
57345       if (status.repr) {
57346         goto suspend;
57347       }
57348     }
57349     while (true) {
57350       if (((uint64_t)(io2_a_src - iop_a_src)) < 8u) {
57351         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
57352         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
57353         continue;
57354       }
57355       self->private_impl.f_chunk_length = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
57356       self->private_impl.f_chunk_type = ((uint32_t)((wuffs_base__peek_u64le__no_bounds_check(iop_a_src) >> 32u)));
57357       if (self->private_impl.f_chunk_type == 1413563465u) {
57358         self->private_impl.f_chunk_type_array[0u] = 73u;
57359         self->private_impl.f_chunk_type_array[1u] = 68u;
57360         self->private_impl.f_chunk_type_array[2u] = 65u;
57361         self->private_impl.f_chunk_type_array[3u] = 84u;
57362         iop_a_src += 8u;
57363         if ( ! self->private_impl.f_ignore_checksum) {
57364           wuffs_base__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32,
57365               sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
57366           wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__make_slice_u8(self->private_impl.f_chunk_type_array, 4));
57367         }
57368         break;
57369       } else if (self->private_impl.f_chunk_type == 1413571686u) {
57370         self->private_impl.f_chunk_type_array[0u] = 102u;
57371         self->private_impl.f_chunk_type_array[1u] = 100u;
57372         self->private_impl.f_chunk_type_array[2u] = 65u;
57373         self->private_impl.f_chunk_type_array[3u] = 84u;
57374         if (self->private_impl.f_chunk_length < 4u) {
57375           status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
57376           goto exit;
57377         }
57378         self->private_impl.f_chunk_length -= 4u;
57379         iop_a_src += 8u;
57380         {
57381           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
57382           uint32_t t_0;
57383           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
57384             t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
57385             iop_a_src += 4;
57386           } else {
57387             self->private_data.s_do_decode_frame[0].scratch = 0;
57388             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
57389             while (true) {
57390               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
57391                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
57392                 goto suspend;
57393               }
57394               uint64_t* scratch = &self->private_data.s_do_decode_frame[0].scratch;
57395               uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu));
57396               *scratch >>= 8;
57397               *scratch <<= 8;
57398               *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
57399               if (num_bits_0 == 24) {
57400                 t_0 = ((uint32_t)(*scratch >> 32));
57401                 break;
57402               }
57403               num_bits_0 += 8u;
57404               *scratch |= ((uint64_t)(num_bits_0));
57405             }
57406           }
57407           v_seq_num = t_0;
57408         }
57409         if (v_seq_num != self->private_impl.f_next_animation_seq_num) {
57410           status = wuffs_base__make_status(wuffs_png__error__bad_animation_sequence_number);
57411           goto exit;
57412         } else if (self->private_impl.f_next_animation_seq_num >= 4294967295u) {
57413           status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file);
57414           goto exit;
57415         }
57416         self->private_impl.f_next_animation_seq_num += 1u;
57417         break;
57418       } else if (self->private_impl.f_chunk_type == 1280598886u) {
57419         status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
57420         goto exit;
57421       }
57422       self->private_data.s_do_decode_frame[0].scratch = (((uint64_t)(self->private_impl.f_chunk_length)) + 12u);
57423       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
57424       if (self->private_data.s_do_decode_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
57425         self->private_data.s_do_decode_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
57426         iop_a_src = io2_a_src;
57427         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
57428         goto suspend;
57429       }
57430       iop_a_src += self->private_data.s_do_decode_frame[0].scratch;
57431       self->private_impl.f_chunk_length = 0u;
57432     }
57433     if (self->private_impl.f_zlib_is_dirty) {
57434       wuffs_base__ignore_status(wuffs_zlib__decoder__initialize(&self->private_data.f_zlib,
57435           sizeof (wuffs_zlib__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
57436       if (self->private_impl.f_ignore_checksum) {
57437         wuffs_zlib__decoder__set_quirk(&self->private_data.f_zlib, 1u, 1u);
57438       }
57439     }
57440     self->private_impl.f_zlib_is_dirty = true;
57441     v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
57442         wuffs_base__pixel_buffer__pixel_format(a_dst),
57443         wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)),
57444         wuffs_base__utility__make_pixel_format(self->private_impl.f_src_pixfmt),
57445         wuffs_base__make_slice_u8(self->private_data.f_src_palette, 1024),
57446         a_blend);
57447     if ( ! wuffs_base__status__is_ok(&v_status)) {
57448       status = v_status;
57449       if (wuffs_base__status__is_error(&status)) {
57450         goto exit;
57451       } else if (wuffs_base__status__is_suspension(&status)) {
57452         status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
57453         goto exit;
57454       }
57455       goto ok;
57456     }
57457     self->private_impl.f_workbuf_hist_pos_base = 0u;
57458     while (true) {
57459       if (self->private_impl.f_chunk_type_array[0u] == 73u) {
57460         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]));
57461         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]));
57462       } else {
57463         v_pass_width = (16777215u & ((uint32_t)(self->private_impl.f_frame_rect_x1 - self->private_impl.f_frame_rect_x0)));
57464         v_pass_height = (16777215u & ((uint32_t)(self->private_impl.f_frame_rect_y1 - self->private_impl.f_frame_rect_y0)));
57465       }
57466       if ((v_pass_width > 0u) && (v_pass_height > 0u)) {
57467         self->private_impl.f_pass_bytes_per_row = wuffs_png__decoder__calculate_bytes_per_row(self, v_pass_width);
57468         self->private_impl.f_pass_workbuf_length = (((uint64_t)(v_pass_height)) * (1u + self->private_impl.f_pass_bytes_per_row));
57469         while (true) {
57470           {
57471             if (a_src) {
57472               a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
57473             }
57474             wuffs_base__status t_1 = wuffs_png__decoder__decode_pass(self, a_src, a_workbuf);
57475             v_status = t_1;
57476             if (a_src) {
57477               iop_a_src = a_src->data.ptr + a_src->meta.ri;
57478             }
57479           }
57480           if (wuffs_base__status__is_ok(&v_status)) {
57481             break;
57482           } else if (wuffs_base__status__is_error(&v_status) || ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed))) {
57483             if (self->private_impl.f_workbuf_wi <= ((uint64_t)(a_workbuf.len))) {
57484               wuffs_png__decoder__filter_and_swizzle(self, a_dst, wuffs_base__slice_u8__subslice_j(a_workbuf, self->private_impl.f_workbuf_wi));
57485             }
57486             if (v_status.repr == wuffs_base__suspension__short_read) {
57487               status = wuffs_base__make_status(wuffs_png__error__truncated_input);
57488               goto exit;
57489             }
57490           }
57491           status = v_status;
57492           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
57493         }
57494         v_status = wuffs_png__decoder__filter_and_swizzle(self, a_dst, a_workbuf);
57495         if ( ! wuffs_base__status__is_ok(&v_status)) {
57496           status = v_status;
57497           if (wuffs_base__status__is_error(&status)) {
57498             goto exit;
57499           } else if (wuffs_base__status__is_suspension(&status)) {
57500             status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
57501             goto exit;
57502           }
57503           goto ok;
57504         }
57505         self->private_impl.f_workbuf_hist_pos_base += self->private_impl.f_pass_workbuf_length;
57506       }
57507       if ((self->private_impl.f_interlace_pass == 0u) || (self->private_impl.f_interlace_pass >= 7u)) {
57508         break;
57509       }
57510 #if defined(__GNUC__)
57511 #pragma GCC diagnostic push
57512 #pragma GCC diagnostic ignored "-Wconversion"
57513 #endif
57514       self->private_impl.f_interlace_pass += 1u;
57515 #if defined(__GNUC__)
57516 #pragma GCC diagnostic pop
57517 #endif
57518     }
57519     wuffs_base__u32__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1u);
57520     self->private_impl.f_call_sequence = 32u;
57521 
57522     ok:
57523     self->private_impl.p_do_decode_frame[0] = 0;
57524     goto exit;
57525   }
57526 
57527   goto suspend;
57528   suspend:
57529   self->private_impl.p_do_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
57530 
57531   goto exit;
57532   exit:
57533   if (a_src && a_src->data.ptr) {
57534     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
57535   }
57536 
57537   return status;
57538 }
57539 
57540 // -------- func png.decoder.decode_pass
57541 
57542 WUFFS_BASE__GENERATED_C_CODE
57543 static wuffs_base__status
wuffs_png__decoder__decode_pass(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src,wuffs_base__slice_u8 a_workbuf)57544 wuffs_png__decoder__decode_pass(
57545     wuffs_png__decoder* self,
57546     wuffs_base__io_buffer* a_src,
57547     wuffs_base__slice_u8 a_workbuf) {
57548   wuffs_base__status status = wuffs_base__make_status(NULL);
57549 
57550   wuffs_base__io_buffer u_w = wuffs_base__empty_io_buffer();
57551   wuffs_base__io_buffer* v_w = &u_w;
57552   uint8_t* iop_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
57553   uint8_t* io0_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
57554   uint8_t* io1_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
57555   uint8_t* io2_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
57556   uint64_t v_w_mark = 0;
57557   uint64_t v_r_mark = 0;
57558   wuffs_base__status v_zlib_status = wuffs_base__make_status(NULL);
57559   uint32_t v_checksum_have = 0;
57560   uint32_t v_checksum_want = 0;
57561   uint32_t v_seq_num = 0;
57562 
57563   const uint8_t* iop_a_src = NULL;
57564   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
57565   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
57566   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
57567   if (a_src && a_src->data.ptr) {
57568     io0_a_src = a_src->data.ptr;
57569     io1_a_src = io0_a_src + a_src->meta.ri;
57570     iop_a_src = io1_a_src;
57571     io2_a_src = io0_a_src + a_src->meta.wi;
57572   }
57573 
57574   uint32_t coro_susp_point = self->private_impl.p_decode_pass[0];
57575   switch (coro_susp_point) {
57576     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
57577 
57578     self->private_impl.f_workbuf_wi = 0u;
57579     while (true) {
57580       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)))) {
57581         status = wuffs_base__make_status(wuffs_base__error__bad_workbuf_length);
57582         goto exit;
57583       }
57584       {
57585         wuffs_base__io_buffer* o_0_v_w = v_w;
57586         uint8_t *o_0_iop_v_w = iop_v_w;
57587         uint8_t *o_0_io0_v_w = io0_v_w;
57588         uint8_t *o_0_io1_v_w = io1_v_w;
57589         uint8_t *o_0_io2_v_w = io2_v_w;
57590         v_w = wuffs_base__io_writer__set(
57591             &u_w,
57592             &iop_v_w,
57593             &io0_v_w,
57594             &io1_v_w,
57595             &io2_v_w,
57596             wuffs_base__slice_u8__subslice_ij(a_workbuf,
57597             self->private_impl.f_workbuf_wi,
57598             self->private_impl.f_pass_workbuf_length),
57599             ((uint64_t)(self->private_impl.f_workbuf_hist_pos_base + self->private_impl.f_workbuf_wi)));
57600         {
57601           const bool o_1_closed_a_src = a_src->meta.closed;
57602           const uint8_t *o_1_io2_a_src = io2_a_src;
57603           wuffs_base__io_reader__limit(&io2_a_src, iop_a_src,
57604               ((uint64_t)(self->private_impl.f_chunk_length)));
57605           if (a_src) {
57606             size_t n = ((size_t)(io2_a_src - a_src->data.ptr));
57607             a_src->meta.closed = a_src->meta.closed && (a_src->meta.wi <= n);
57608             a_src->meta.wi = n;
57609           }
57610           v_w_mark = ((uint64_t)(iop_v_w - io0_v_w));
57611           v_r_mark = ((uint64_t)(iop_a_src - io0_a_src));
57612           {
57613             u_w.meta.wi = ((size_t)(iop_v_w - u_w.data.ptr));
57614             if (a_src) {
57615               a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
57616             }
57617             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());
57618             v_zlib_status = t_0;
57619             iop_v_w = u_w.data.ptr + u_w.meta.wi;
57620             if (a_src) {
57621               iop_a_src = a_src->data.ptr + a_src->meta.ri;
57622             }
57623           }
57624           if ( ! self->private_impl.f_ignore_checksum) {
57625             wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__io__since(v_r_mark, ((uint64_t)(iop_a_src - io0_a_src)), io0_a_src));
57626           }
57627           wuffs_base__u32__sat_sub_indirect(&self->private_impl.f_chunk_length, ((uint32_t)(wuffs_base__io__count_since(v_r_mark, ((uint64_t)(iop_a_src - io0_a_src))))));
57628           wuffs_base__u64__sat_add_indirect(&self->private_impl.f_workbuf_wi, wuffs_base__io__count_since(v_w_mark, ((uint64_t)(iop_v_w - io0_v_w))));
57629           io2_a_src = o_1_io2_a_src;
57630           if (a_src) {
57631             a_src->meta.closed = o_1_closed_a_src;
57632             a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
57633           }
57634         }
57635         v_w = o_0_v_w;
57636         iop_v_w = o_0_iop_v_w;
57637         io0_v_w = o_0_io0_v_w;
57638         io1_v_w = o_0_io1_v_w;
57639         io2_v_w = o_0_io2_v_w;
57640       }
57641       if (wuffs_base__status__is_ok(&v_zlib_status)) {
57642         if (self->private_impl.f_chunk_length > 0u) {
57643           status = wuffs_base__make_status(wuffs_base__error__too_much_data);
57644           goto exit;
57645         }
57646         {
57647           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
57648           uint32_t t_1;
57649           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
57650             t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
57651             iop_a_src += 4;
57652           } else {
57653             self->private_data.s_decode_pass[0].scratch = 0;
57654             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
57655             while (true) {
57656               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
57657                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
57658                 goto suspend;
57659               }
57660               uint64_t* scratch = &self->private_data.s_decode_pass[0].scratch;
57661               uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu));
57662               *scratch >>= 8;
57663               *scratch <<= 8;
57664               *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
57665               if (num_bits_1 == 24) {
57666                 t_1 = ((uint32_t)(*scratch >> 32));
57667                 break;
57668               }
57669               num_bits_1 += 8u;
57670               *scratch |= ((uint64_t)(num_bits_1));
57671             }
57672           }
57673           v_checksum_want = t_1;
57674         }
57675         if ( ! self->private_impl.f_ignore_checksum && (self->private_impl.f_chunk_type_array[0u] == 73u)) {
57676           v_checksum_have = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__utility__empty_slice_u8());
57677           if (v_checksum_have != v_checksum_want) {
57678             status = wuffs_base__make_status(wuffs_png__error__bad_checksum);
57679             goto exit;
57680           }
57681         }
57682         break;
57683       } else if (v_zlib_status.repr == wuffs_base__suspension__short_write) {
57684         if ((1u <= self->private_impl.f_interlace_pass) && (self->private_impl.f_interlace_pass <= 6u)) {
57685           break;
57686         }
57687         status = wuffs_base__make_status(wuffs_base__error__too_much_data);
57688         goto exit;
57689       } else if (v_zlib_status.repr != wuffs_base__suspension__short_read) {
57690         status = v_zlib_status;
57691         if (wuffs_base__status__is_error(&status)) {
57692           goto exit;
57693         } else if (wuffs_base__status__is_suspension(&status)) {
57694           status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
57695           goto exit;
57696         }
57697         goto ok;
57698       } else if (self->private_impl.f_chunk_length == 0u) {
57699         {
57700           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
57701           uint32_t t_2;
57702           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
57703             t_2 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
57704             iop_a_src += 4;
57705           } else {
57706             self->private_data.s_decode_pass[0].scratch = 0;
57707             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
57708             while (true) {
57709               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
57710                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
57711                 goto suspend;
57712               }
57713               uint64_t* scratch = &self->private_data.s_decode_pass[0].scratch;
57714               uint32_t num_bits_2 = ((uint32_t)(*scratch & 0xFFu));
57715               *scratch >>= 8;
57716               *scratch <<= 8;
57717               *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_2);
57718               if (num_bits_2 == 24) {
57719                 t_2 = ((uint32_t)(*scratch >> 32));
57720                 break;
57721               }
57722               num_bits_2 += 8u;
57723               *scratch |= ((uint64_t)(num_bits_2));
57724             }
57725           }
57726           v_checksum_want = t_2;
57727         }
57728         if ( ! self->private_impl.f_ignore_checksum && (self->private_impl.f_chunk_type_array[0u] == 73u)) {
57729           v_checksum_have = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__utility__empty_slice_u8());
57730           if (v_checksum_have != v_checksum_want) {
57731             status = wuffs_base__make_status(wuffs_png__error__bad_checksum);
57732             goto exit;
57733           }
57734         }
57735         {
57736           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
57737           uint32_t t_3;
57738           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
57739             t_3 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
57740             iop_a_src += 4;
57741           } else {
57742             self->private_data.s_decode_pass[0].scratch = 0;
57743             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
57744             while (true) {
57745               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
57746                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
57747                 goto suspend;
57748               }
57749               uint64_t* scratch = &self->private_data.s_decode_pass[0].scratch;
57750               uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFFu));
57751               *scratch >>= 8;
57752               *scratch <<= 8;
57753               *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3);
57754               if (num_bits_3 == 24) {
57755                 t_3 = ((uint32_t)(*scratch >> 32));
57756                 break;
57757               }
57758               num_bits_3 += 8u;
57759               *scratch |= ((uint64_t)(num_bits_3));
57760             }
57761           }
57762           self->private_impl.f_chunk_length = t_3;
57763         }
57764         {
57765           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
57766           uint32_t t_4;
57767           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
57768             t_4 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
57769             iop_a_src += 4;
57770           } else {
57771             self->private_data.s_decode_pass[0].scratch = 0;
57772             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
57773             while (true) {
57774               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
57775                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
57776                 goto suspend;
57777               }
57778               uint64_t* scratch = &self->private_data.s_decode_pass[0].scratch;
57779               uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
57780               *scratch <<= 8;
57781               *scratch >>= 8;
57782               *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
57783               if (num_bits_4 == 24) {
57784                 t_4 = ((uint32_t)(*scratch));
57785                 break;
57786               }
57787               num_bits_4 += 8u;
57788               *scratch |= ((uint64_t)(num_bits_4)) << 56;
57789             }
57790           }
57791           self->private_impl.f_chunk_type = t_4;
57792         }
57793         if (self->private_impl.f_chunk_type_array[0u] == 73u) {
57794           if (self->private_impl.f_chunk_type != 1413563465u) {
57795             status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
57796             goto exit;
57797           }
57798           if ( ! self->private_impl.f_ignore_checksum) {
57799             wuffs_base__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32,
57800                 sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
57801             wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__make_slice_u8(self->private_impl.f_chunk_type_array, 4));
57802           }
57803         } else {
57804           if ((self->private_impl.f_chunk_type != 1413571686u) || (self->private_impl.f_chunk_length < 4u)) {
57805             status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
57806             goto exit;
57807           }
57808           self->private_impl.f_chunk_length -= 4u;
57809           {
57810             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
57811             uint32_t t_5;
57812             if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
57813               t_5 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
57814               iop_a_src += 4;
57815             } else {
57816               self->private_data.s_decode_pass[0].scratch = 0;
57817               WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
57818               while (true) {
57819                 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
57820                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
57821                   goto suspend;
57822                 }
57823                 uint64_t* scratch = &self->private_data.s_decode_pass[0].scratch;
57824                 uint32_t num_bits_5 = ((uint32_t)(*scratch & 0xFFu));
57825                 *scratch >>= 8;
57826                 *scratch <<= 8;
57827                 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_5);
57828                 if (num_bits_5 == 24) {
57829                   t_5 = ((uint32_t)(*scratch >> 32));
57830                   break;
57831                 }
57832                 num_bits_5 += 8u;
57833                 *scratch |= ((uint64_t)(num_bits_5));
57834               }
57835             }
57836             v_seq_num = t_5;
57837           }
57838           if (v_seq_num != self->private_impl.f_next_animation_seq_num) {
57839             status = wuffs_base__make_status(wuffs_png__error__bad_animation_sequence_number);
57840             goto exit;
57841           } else if (self->private_impl.f_next_animation_seq_num >= 4294967295u) {
57842             status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file);
57843             goto exit;
57844           }
57845           self->private_impl.f_next_animation_seq_num += 1u;
57846         }
57847         continue;
57848       } else if (((uint64_t)(io2_a_src - iop_a_src)) > 0u) {
57849         status = wuffs_base__make_status(wuffs_png__error__internal_error_zlib_decoder_did_not_exhaust_its_input);
57850         goto exit;
57851       }
57852       status = wuffs_base__make_status(wuffs_base__suspension__short_read);
57853       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(11);
57854     }
57855     if (self->private_impl.f_workbuf_wi != self->private_impl.f_pass_workbuf_length) {
57856       status = wuffs_base__make_status(wuffs_base__error__not_enough_data);
57857       goto exit;
57858     } else if (0u < ((uint64_t)(a_workbuf.len))) {
57859       if (a_workbuf.ptr[0u] == 4u) {
57860         a_workbuf.ptr[0u] = 1u;
57861       }
57862     }
57863 
57864     ok:
57865     self->private_impl.p_decode_pass[0] = 0;
57866     goto exit;
57867   }
57868 
57869   goto suspend;
57870   suspend:
57871   self->private_impl.p_decode_pass[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
57872 
57873   goto exit;
57874   exit:
57875   if (a_src && a_src->data.ptr) {
57876     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
57877   }
57878 
57879   return status;
57880 }
57881 
57882 // -------- func png.decoder.frame_dirty_rect
57883 
57884 WUFFS_BASE__GENERATED_C_CODE
57885 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
wuffs_png__decoder__frame_dirty_rect(const wuffs_png__decoder * self)57886 wuffs_png__decoder__frame_dirty_rect(
57887     const wuffs_png__decoder* self) {
57888   if (!self) {
57889     return wuffs_base__utility__empty_rect_ie_u32();
57890   }
57891   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
57892       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
57893     return wuffs_base__utility__empty_rect_ie_u32();
57894   }
57895 
57896   return wuffs_base__utility__make_rect_ie_u32(
57897       self->private_impl.f_frame_rect_x0,
57898       self->private_impl.f_frame_rect_y0,
57899       self->private_impl.f_frame_rect_x1,
57900       self->private_impl.f_frame_rect_y1);
57901 }
57902 
57903 // -------- func png.decoder.num_animation_loops
57904 
57905 WUFFS_BASE__GENERATED_C_CODE
57906 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_png__decoder__num_animation_loops(const wuffs_png__decoder * self)57907 wuffs_png__decoder__num_animation_loops(
57908     const wuffs_png__decoder* self) {
57909   if (!self) {
57910     return 0;
57911   }
57912   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
57913       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
57914     return 0;
57915   }
57916 
57917   return self->private_impl.f_num_animation_loops_value;
57918 }
57919 
57920 // -------- func png.decoder.num_decoded_frame_configs
57921 
57922 WUFFS_BASE__GENERATED_C_CODE
57923 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_png__decoder__num_decoded_frame_configs(const wuffs_png__decoder * self)57924 wuffs_png__decoder__num_decoded_frame_configs(
57925     const wuffs_png__decoder* self) {
57926   if (!self) {
57927     return 0;
57928   }
57929   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
57930       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
57931     return 0;
57932   }
57933 
57934   return ((uint64_t)(self->private_impl.f_num_decoded_frame_configs_value));
57935 }
57936 
57937 // -------- func png.decoder.num_decoded_frames
57938 
57939 WUFFS_BASE__GENERATED_C_CODE
57940 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_png__decoder__num_decoded_frames(const wuffs_png__decoder * self)57941 wuffs_png__decoder__num_decoded_frames(
57942     const wuffs_png__decoder* self) {
57943   if (!self) {
57944     return 0;
57945   }
57946   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
57947       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
57948     return 0;
57949   }
57950 
57951   return ((uint64_t)(self->private_impl.f_num_decoded_frames_value));
57952 }
57953 
57954 // -------- func png.decoder.restart_frame
57955 
57956 WUFFS_BASE__GENERATED_C_CODE
57957 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_png__decoder__restart_frame(wuffs_png__decoder * self,uint64_t a_index,uint64_t a_io_position)57958 wuffs_png__decoder__restart_frame(
57959     wuffs_png__decoder* self,
57960     uint64_t a_index,
57961     uint64_t a_io_position) {
57962   if (!self) {
57963     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
57964   }
57965   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
57966     return wuffs_base__make_status(
57967         (self->private_impl.magic == WUFFS_BASE__DISABLED)
57968         ? wuffs_base__error__disabled_by_previous_error
57969         : wuffs_base__error__initialize_not_called);
57970   }
57971 
57972   if (self->private_impl.f_call_sequence < 32u) {
57973     return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
57974   } 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))) {
57975     return wuffs_base__make_status(wuffs_base__error__bad_argument);
57976   }
57977   self->private_impl.f_call_sequence = 40u;
57978   if (self->private_impl.f_interlace_pass >= 1u) {
57979     self->private_impl.f_interlace_pass = 1u;
57980   }
57981   self->private_impl.f_frame_config_io_position = a_io_position;
57982   self->private_impl.f_num_decoded_frame_configs_value = ((uint32_t)(a_index));
57983   self->private_impl.f_num_decoded_frames_value = self->private_impl.f_num_decoded_frame_configs_value;
57984   return wuffs_base__make_status(NULL);
57985 }
57986 
57987 // -------- func png.decoder.set_report_metadata
57988 
57989 WUFFS_BASE__GENERATED_C_CODE
57990 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_png__decoder__set_report_metadata(wuffs_png__decoder * self,uint32_t a_fourcc,bool a_report)57991 wuffs_png__decoder__set_report_metadata(
57992     wuffs_png__decoder* self,
57993     uint32_t a_fourcc,
57994     bool a_report) {
57995   if (!self) {
57996     return wuffs_base__make_empty_struct();
57997   }
57998   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
57999     return wuffs_base__make_empty_struct();
58000   }
58001 
58002   if (a_fourcc == 1128813133u) {
58003     self->private_impl.f_report_metadata_chrm = a_report;
58004   } else if (a_fourcc == 1163413830u) {
58005     self->private_impl.f_report_metadata_exif = a_report;
58006   } else if (a_fourcc == 1195461953u) {
58007     self->private_impl.f_report_metadata_gama = a_report;
58008   } else if (a_fourcc == 1229144912u) {
58009     self->private_impl.f_report_metadata_iccp = a_report;
58010   } else if (a_fourcc == 1263947808u) {
58011     self->private_impl.f_report_metadata_kvp = a_report;
58012   } else if (a_fourcc == 1397901122u) {
58013     self->private_impl.f_report_metadata_srgb = a_report;
58014   }
58015   return wuffs_base__make_empty_struct();
58016 }
58017 
58018 // -------- func png.decoder.tell_me_more
58019 
58020 WUFFS_BASE__GENERATED_C_CODE
58021 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_png__decoder__tell_me_more(wuffs_png__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__more_information * a_minfo,wuffs_base__io_buffer * a_src)58022 wuffs_png__decoder__tell_me_more(
58023     wuffs_png__decoder* self,
58024     wuffs_base__io_buffer* a_dst,
58025     wuffs_base__more_information* a_minfo,
58026     wuffs_base__io_buffer* a_src) {
58027   if (!self) {
58028     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
58029   }
58030   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
58031     return wuffs_base__make_status(
58032         (self->private_impl.magic == WUFFS_BASE__DISABLED)
58033         ? wuffs_base__error__disabled_by_previous_error
58034         : wuffs_base__error__initialize_not_called);
58035   }
58036   if (!a_dst || !a_src) {
58037     self->private_impl.magic = WUFFS_BASE__DISABLED;
58038     return wuffs_base__make_status(wuffs_base__error__bad_argument);
58039   }
58040   if ((self->private_impl.active_coroutine != 0) &&
58041       (self->private_impl.active_coroutine != 4)) {
58042     self->private_impl.magic = WUFFS_BASE__DISABLED;
58043     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
58044   }
58045   self->private_impl.active_coroutine = 0;
58046   wuffs_base__status status = wuffs_base__make_status(NULL);
58047 
58048   wuffs_base__status v_status = wuffs_base__make_status(NULL);
58049 
58050   uint32_t coro_susp_point = self->private_impl.p_tell_me_more[0];
58051   switch (coro_susp_point) {
58052     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
58053 
58054     while (true) {
58055       {
58056         wuffs_base__status t_0 = wuffs_png__decoder__do_tell_me_more(self, a_dst, a_minfo, a_src);
58057         v_status = t_0;
58058       }
58059       if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
58060         status = wuffs_base__make_status(wuffs_png__error__truncated_input);
58061         goto exit;
58062       }
58063       status = v_status;
58064       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
58065     }
58066 
58067     ok:
58068     self->private_impl.p_tell_me_more[0] = 0;
58069     goto exit;
58070   }
58071 
58072   goto suspend;
58073   suspend:
58074   self->private_impl.p_tell_me_more[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
58075   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 4 : 0;
58076 
58077   goto exit;
58078   exit:
58079   if (wuffs_base__status__is_error(&status)) {
58080     self->private_impl.magic = WUFFS_BASE__DISABLED;
58081   }
58082   return status;
58083 }
58084 
58085 // -------- func png.decoder.do_tell_me_more
58086 
58087 WUFFS_BASE__GENERATED_C_CODE
58088 static wuffs_base__status
wuffs_png__decoder__do_tell_me_more(wuffs_png__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__more_information * a_minfo,wuffs_base__io_buffer * a_src)58089 wuffs_png__decoder__do_tell_me_more(
58090     wuffs_png__decoder* self,
58091     wuffs_base__io_buffer* a_dst,
58092     wuffs_base__more_information* a_minfo,
58093     wuffs_base__io_buffer* a_src) {
58094   wuffs_base__status status = wuffs_base__make_status(NULL);
58095 
58096   uint8_t v_c = 0;
58097   uint16_t v_c2 = 0;
58098   wuffs_base__io_buffer u_w = wuffs_base__empty_io_buffer();
58099   wuffs_base__io_buffer* v_w = &u_w;
58100   uint8_t* iop_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
58101   uint8_t* io0_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
58102   uint8_t* io1_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
58103   uint8_t* io2_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
58104   uint64_t v_num_written = 0;
58105   uint64_t v_w_mark = 0;
58106   uint64_t v_r_mark = 0;
58107   wuffs_base__status v_zlib_status = wuffs_base__make_status(NULL);
58108 
58109   uint8_t* iop_a_dst = NULL;
58110   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
58111   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
58112   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
58113   if (a_dst && a_dst->data.ptr) {
58114     io0_a_dst = a_dst->data.ptr;
58115     io1_a_dst = io0_a_dst + a_dst->meta.wi;
58116     iop_a_dst = io1_a_dst;
58117     io2_a_dst = io0_a_dst + a_dst->data.len;
58118     if (a_dst->meta.closed) {
58119       io2_a_dst = iop_a_dst;
58120     }
58121   }
58122   const uint8_t* iop_a_src = NULL;
58123   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
58124   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
58125   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
58126   if (a_src && a_src->data.ptr) {
58127     io0_a_src = a_src->data.ptr;
58128     io1_a_src = io0_a_src + a_src->meta.ri;
58129     iop_a_src = io1_a_src;
58130     io2_a_src = io0_a_src + a_src->meta.wi;
58131   }
58132 
58133   uint32_t coro_susp_point = self->private_impl.p_do_tell_me_more[0];
58134   if (coro_susp_point) {
58135     v_zlib_status = self->private_data.s_do_tell_me_more[0].v_zlib_status;
58136   }
58137   switch (coro_susp_point) {
58138     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
58139 
58140     if ((self->private_impl.f_call_sequence & 16u) == 0u) {
58141       status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
58142       goto exit;
58143     }
58144     if (self->private_impl.f_metadata_fourcc == 0u) {
58145       status = wuffs_base__make_status(wuffs_base__error__no_more_information);
58146       goto exit;
58147     }
58148     do {
58149       if (self->private_impl.f_metadata_flavor == 3u) {
58150         while (true) {
58151           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) {
58152             status = wuffs_base__make_status(wuffs_base__error__bad_i_o_position);
58153             goto exit;
58154           } else if (a_minfo != NULL) {
58155             wuffs_base__more_information__set(a_minfo,
58156                 self->private_impl.f_metadata_flavor,
58157                 self->private_impl.f_metadata_fourcc,
58158                 self->private_impl.f_metadata_x,
58159                 self->private_impl.f_metadata_y,
58160                 self->private_impl.f_metadata_z);
58161           }
58162           if (self->private_impl.f_metadata_y >= self->private_impl.f_metadata_z) {
58163             goto label__goto_done__break;
58164           }
58165           self->private_impl.f_metadata_y = self->private_impl.f_metadata_z;
58166           status = wuffs_base__make_status(wuffs_base__suspension__even_more_information);
58167           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
58168         }
58169       }
58170       if (self->private_impl.f_metadata_is_zlib_compressed) {
58171         if (self->private_impl.f_zlib_is_dirty) {
58172           wuffs_base__ignore_status(wuffs_zlib__decoder__initialize(&self->private_data.f_zlib,
58173               sizeof (wuffs_zlib__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
58174           if (self->private_impl.f_ignore_checksum) {
58175             wuffs_zlib__decoder__set_quirk(&self->private_data.f_zlib, 1u, 1u);
58176           }
58177         }
58178         self->private_impl.f_zlib_is_dirty = true;
58179         self->private_impl.f_ztxt_hist_pos = 0u;
58180       }
58181       label__loop__continue:;
58182       while (true) {
58183         if (a_minfo != NULL) {
58184           wuffs_base__more_information__set(a_minfo,
58185               self->private_impl.f_metadata_flavor,
58186               self->private_impl.f_metadata_fourcc,
58187               self->private_impl.f_metadata_x,
58188               self->private_impl.f_metadata_y,
58189               self->private_impl.f_metadata_z);
58190         }
58191         if (self->private_impl.f_metadata_flavor != 4u) {
58192           break;
58193         }
58194         if (self->private_impl.f_metadata_is_zlib_compressed) {
58195           if (self->private_impl.f_chunk_type == 1346585449u) {
58196             {
58197               const bool o_0_closed_a_src = a_src->meta.closed;
58198               const uint8_t *o_0_io2_a_src = io2_a_src;
58199               wuffs_base__io_reader__limit(&io2_a_src, iop_a_src,
58200                   ((uint64_t)(self->private_impl.f_chunk_length)));
58201               if (a_src) {
58202                 size_t n = ((size_t)(io2_a_src - a_src->data.ptr));
58203                 a_src->meta.closed = a_src->meta.closed && (a_src->meta.wi <= n);
58204                 a_src->meta.wi = n;
58205               }
58206               v_r_mark = ((uint64_t)(iop_a_src - io0_a_src));
58207               {
58208                 if (a_dst) {
58209                   a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
58210                 }
58211                 if (a_src) {
58212                   a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
58213                 }
58214                 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());
58215                 v_zlib_status = t_0;
58216                 if (a_dst) {
58217                   iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
58218                 }
58219                 if (a_src) {
58220                   iop_a_src = a_src->data.ptr + a_src->meta.ri;
58221                 }
58222               }
58223               wuffs_base__u32__sat_sub_indirect(&self->private_impl.f_chunk_length, ((uint32_t)(wuffs_base__io__count_since(v_r_mark, ((uint64_t)(iop_a_src - io0_a_src))))));
58224               io2_a_src = o_0_io2_a_src;
58225               if (a_src) {
58226                 a_src->meta.closed = o_0_closed_a_src;
58227                 a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
58228               }
58229             }
58230             if (wuffs_base__status__is_ok(&v_zlib_status)) {
58231               self->private_impl.f_metadata_is_zlib_compressed = false;
58232               break;
58233             } else if ( ! wuffs_base__status__is_suspension(&v_zlib_status)) {
58234               status = v_zlib_status;
58235               if (wuffs_base__status__is_error(&status)) {
58236                 goto exit;
58237               } else if (wuffs_base__status__is_suspension(&status)) {
58238                 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
58239                 goto exit;
58240               }
58241               goto ok;
58242             }
58243             status = v_zlib_status;
58244             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
58245           } else if (self->private_impl.f_chunk_type == 1951945833u) {
58246             {
58247               const bool o_1_closed_a_src = a_src->meta.closed;
58248               const uint8_t *o_1_io2_a_src = io2_a_src;
58249               wuffs_base__io_reader__limit(&io2_a_src, iop_a_src,
58250                   ((uint64_t)(self->private_impl.f_chunk_length)));
58251               if (a_src) {
58252                 size_t n = ((size_t)(io2_a_src - a_src->data.ptr));
58253                 a_src->meta.closed = a_src->meta.closed && (a_src->meta.wi <= n);
58254                 a_src->meta.wi = n;
58255               }
58256               v_r_mark = ((uint64_t)(iop_a_src - io0_a_src));
58257               {
58258                 if (a_dst) {
58259                   a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
58260                 }
58261                 if (a_src) {
58262                   a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
58263                 }
58264                 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());
58265                 v_zlib_status = t_1;
58266                 if (a_dst) {
58267                   iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
58268                 }
58269                 if (a_src) {
58270                   iop_a_src = a_src->data.ptr + a_src->meta.ri;
58271                 }
58272               }
58273               wuffs_base__u32__sat_sub_indirect(&self->private_impl.f_chunk_length, ((uint32_t)(wuffs_base__io__count_since(v_r_mark, ((uint64_t)(iop_a_src - io0_a_src))))));
58274               io2_a_src = o_1_io2_a_src;
58275               if (a_src) {
58276                 a_src->meta.closed = o_1_closed_a_src;
58277                 a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
58278               }
58279             }
58280             if (wuffs_base__status__is_ok(&v_zlib_status)) {
58281               self->private_impl.f_metadata_is_zlib_compressed = false;
58282               break;
58283             } else if ( ! wuffs_base__status__is_suspension(&v_zlib_status)) {
58284               status = v_zlib_status;
58285               if (wuffs_base__status__is_error(&status)) {
58286                 goto exit;
58287               } else if (wuffs_base__status__is_suspension(&status)) {
58288                 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
58289                 goto exit;
58290               }
58291               goto ok;
58292             }
58293             status = v_zlib_status;
58294             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
58295           } else if (self->private_impl.f_chunk_type == 1951945850u) {
58296             if (self->private_impl.f_ztxt_ri == self->private_impl.f_ztxt_wi) {
58297               {
58298                 wuffs_base__io_buffer* o_2_v_w = v_w;
58299                 uint8_t *o_2_iop_v_w = iop_v_w;
58300                 uint8_t *o_2_io0_v_w = io0_v_w;
58301                 uint8_t *o_2_io1_v_w = io1_v_w;
58302                 uint8_t *o_2_io2_v_w = io2_v_w;
58303                 v_w = wuffs_base__io_writer__set(
58304                     &u_w,
58305                     &iop_v_w,
58306                     &io0_v_w,
58307                     &io1_v_w,
58308                     &io2_v_w,
58309                     wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024),
58310                     self->private_impl.f_ztxt_hist_pos);
58311                 {
58312                   const bool o_3_closed_a_src = a_src->meta.closed;
58313                   const uint8_t *o_3_io2_a_src = io2_a_src;
58314                   wuffs_base__io_reader__limit(&io2_a_src, iop_a_src,
58315                       ((uint64_t)(self->private_impl.f_chunk_length)));
58316                   if (a_src) {
58317                     size_t n = ((size_t)(io2_a_src - a_src->data.ptr));
58318                     a_src->meta.closed = a_src->meta.closed && (a_src->meta.wi <= n);
58319                     a_src->meta.wi = n;
58320                   }
58321                   v_w_mark = ((uint64_t)(iop_v_w - io0_v_w));
58322                   v_r_mark = ((uint64_t)(iop_a_src - io0_a_src));
58323                   {
58324                     u_w.meta.wi = ((size_t)(iop_v_w - u_w.data.ptr));
58325                     if (a_src) {
58326                       a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
58327                     }
58328                     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());
58329                     v_zlib_status = t_2;
58330                     iop_v_w = u_w.data.ptr + u_w.meta.wi;
58331                     if (a_src) {
58332                       iop_a_src = a_src->data.ptr + a_src->meta.ri;
58333                     }
58334                   }
58335                   wuffs_base__u32__sat_sub_indirect(&self->private_impl.f_chunk_length, ((uint32_t)(wuffs_base__io__count_since(v_r_mark, ((uint64_t)(iop_a_src - io0_a_src))))));
58336                   v_num_written = wuffs_base__io__count_since(v_w_mark, ((uint64_t)(iop_v_w - io0_v_w)));
58337                   io2_a_src = o_3_io2_a_src;
58338                   if (a_src) {
58339                     a_src->meta.closed = o_3_closed_a_src;
58340                     a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
58341                   }
58342                 }
58343                 v_w = o_2_v_w;
58344                 iop_v_w = o_2_iop_v_w;
58345                 io0_v_w = o_2_io0_v_w;
58346                 io1_v_w = o_2_io1_v_w;
58347                 io2_v_w = o_2_io2_v_w;
58348               }
58349               if (v_num_written > 1024u) {
58350                 status = wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_i_o);
58351                 goto exit;
58352               }
58353               self->private_impl.f_ztxt_ri = 0u;
58354               self->private_impl.f_ztxt_wi = ((uint32_t)(v_num_written));
58355               wuffs_base__u64__sat_add_indirect(&self->private_impl.f_ztxt_hist_pos, v_num_written);
58356             }
58357             while (self->private_impl.f_ztxt_ri < self->private_impl.f_ztxt_wi) {
58358               v_c2 = WUFFS_PNG__LATIN_1[self->private_data.f_dst_palette[self->private_impl.f_ztxt_ri]];
58359               if (v_c2 == 0u) {
58360                 status = wuffs_base__make_status(wuffs_png__error__bad_text_chunk_not_latin_1);
58361                 goto exit;
58362               } else if (v_c2 <= 127u) {
58363                 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
58364                   status = wuffs_base__make_status(wuffs_base__suspension__short_write);
58365                   WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
58366                   goto label__loop__continue;
58367                 }
58368                 self->private_impl.f_ztxt_ri += 1u;
58369                 (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)(v_c2))), iop_a_dst += 1);
58370               } else {
58371                 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 1u) {
58372                   status = wuffs_base__make_status(wuffs_base__suspension__short_write);
58373                   WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
58374                   goto label__loop__continue;
58375                 }
58376                 self->private_impl.f_ztxt_ri += 1u;
58377                 (wuffs_base__poke_u16le__no_bounds_check(iop_a_dst, v_c2), iop_a_dst += 2);
58378               }
58379             }
58380             if (wuffs_base__status__is_ok(&v_zlib_status)) {
58381               self->private_impl.f_metadata_is_zlib_compressed = false;
58382               break;
58383             } else if ( ! wuffs_base__status__is_suspension(&v_zlib_status)) {
58384               status = v_zlib_status;
58385               if (wuffs_base__status__is_error(&status)) {
58386                 goto exit;
58387               } else if (wuffs_base__status__is_suspension(&status)) {
58388                 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
58389                 goto exit;
58390               }
58391               goto ok;
58392             } else if (v_zlib_status.repr != wuffs_base__suspension__short_write) {
58393               status = v_zlib_status;
58394               WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
58395             }
58396           } else {
58397             status = wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_chunk_type);
58398             goto exit;
58399           }
58400         } else if ((self->private_impl.f_chunk_type == 1951945833u) && (self->private_impl.f_metadata_fourcc == 1263947862u)) {
58401           while (true) {
58402             if (self->private_impl.f_chunk_length <= 0u) {
58403               goto label__loop__break;
58404             } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
58405               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
58406               WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7);
58407               goto label__loop__continue;
58408             } else if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
58409               status = wuffs_base__make_status(wuffs_base__suspension__short_write);
58410               WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8);
58411               goto label__loop__continue;
58412             }
58413             self->private_impl.f_chunk_length -= 1u;
58414             v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
58415             iop_a_src += 1u;
58416             (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, v_c), iop_a_dst += 1);
58417           }
58418         } else {
58419           while (true) {
58420             if (self->private_impl.f_chunk_length <= 0u) {
58421               if (self->private_impl.f_metadata_fourcc == 1263947851u) {
58422                 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
58423                 goto exit;
58424               }
58425               goto label__loop__break;
58426             } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
58427               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
58428               WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9);
58429               goto label__loop__continue;
58430             }
58431             v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
58432             if (v_c == 0u) {
58433               self->private_impl.f_chunk_length -= 1u;
58434               iop_a_src += 1u;
58435               goto label__loop__break;
58436             }
58437             v_c2 = WUFFS_PNG__LATIN_1[v_c];
58438             if (v_c2 == 0u) {
58439               status = wuffs_base__make_status(wuffs_png__error__bad_text_chunk_not_latin_1);
58440               goto exit;
58441             } else if (v_c2 <= 127u) {
58442               if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
58443                 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
58444                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10);
58445                 goto label__loop__continue;
58446               }
58447               self->private_impl.f_chunk_length -= 1u;
58448               iop_a_src += 1u;
58449               (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)(v_c2))), iop_a_dst += 1);
58450             } else {
58451               if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 1u) {
58452                 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
58453                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(11);
58454                 goto label__loop__continue;
58455               }
58456               self->private_impl.f_chunk_length -= 1u;
58457               iop_a_src += 1u;
58458               (wuffs_base__poke_u16le__no_bounds_check(iop_a_dst, v_c2), iop_a_dst += 2);
58459             }
58460           }
58461         }
58462       }
58463       label__loop__break:;
58464       if (self->private_impl.f_metadata_fourcc == 1263947851u) {
58465         self->private_impl.f_metadata_fourcc = 1263947862u;
58466         if (self->private_impl.f_chunk_type == 1951945833u) {
58467           if (self->private_impl.f_chunk_length <= 1u) {
58468             status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
58469             goto exit;
58470           }
58471           self->private_impl.f_chunk_length -= 2u;
58472           {
58473             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
58474             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
58475               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
58476               goto suspend;
58477             }
58478             uint8_t t_3 = *iop_a_src++;
58479             v_c = t_3;
58480           }
58481           if (v_c == 0u) {
58482             self->private_impl.f_metadata_is_zlib_compressed = false;
58483           } else if (v_c == 1u) {
58484             self->private_impl.f_metadata_is_zlib_compressed = true;
58485           } else {
58486             status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
58487             goto exit;
58488           }
58489           {
58490             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
58491             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
58492               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
58493               goto suspend;
58494             }
58495             uint8_t t_4 = *iop_a_src++;
58496             v_c = t_4;
58497           }
58498           if ((v_c != 0u) && self->private_impl.f_metadata_is_zlib_compressed) {
58499             status = wuffs_base__make_status(wuffs_png__error__unsupported_png_compression_method);
58500             goto exit;
58501           }
58502           self->private_impl.f_metadata_fourcc -= 2u;
58503           while (self->private_impl.f_metadata_fourcc != 1263947862u) {
58504             self->private_impl.f_metadata_fourcc += 1u;
58505             while (true) {
58506               if (self->private_impl.f_chunk_length <= 0u) {
58507                 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
58508                 goto exit;
58509               }
58510               self->private_impl.f_chunk_length -= 1u;
58511               {
58512                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
58513                 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
58514                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
58515                   goto suspend;
58516                 }
58517                 uint8_t t_5 = *iop_a_src++;
58518                 v_c = t_5;
58519               }
58520               if (v_c == 0u) {
58521                 break;
58522               }
58523             }
58524           }
58525         } else if (self->private_impl.f_chunk_type == 1951945850u) {
58526           if (self->private_impl.f_chunk_length <= 0u) {
58527             status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
58528             goto exit;
58529           }
58530           self->private_impl.f_chunk_length -= 1u;
58531           {
58532             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
58533             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
58534               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
58535               goto suspend;
58536             }
58537             uint8_t t_6 = *iop_a_src++;
58538             v_c = t_6;
58539           }
58540           if (v_c != 0u) {
58541             status = wuffs_base__make_status(wuffs_png__error__unsupported_png_compression_method);
58542             goto exit;
58543           }
58544           self->private_impl.f_metadata_is_zlib_compressed = true;
58545         }
58546         self->private_impl.f_call_sequence &= 239u;
58547         status = wuffs_base__make_status(NULL);
58548         goto ok;
58549       }
58550     } while (0);
58551     label__goto_done__break:;
58552     if (self->private_impl.f_chunk_length != 0u) {
58553       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
58554       goto exit;
58555     }
58556     self->private_data.s_do_tell_me_more[0].scratch = 4u;
58557     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
58558     if (self->private_data.s_do_tell_me_more[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
58559       self->private_data.s_do_tell_me_more[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
58560       iop_a_src = io2_a_src;
58561       status = wuffs_base__make_status(wuffs_base__suspension__short_read);
58562       goto suspend;
58563     }
58564     iop_a_src += self->private_data.s_do_tell_me_more[0].scratch;
58565     self->private_impl.f_metadata_flavor = 0u;
58566     self->private_impl.f_metadata_fourcc = 0u;
58567     self->private_impl.f_metadata_x = 0u;
58568     self->private_impl.f_metadata_y = 0u;
58569     self->private_impl.f_metadata_z = 0u;
58570     self->private_impl.f_call_sequence &= 239u;
58571     status = wuffs_base__make_status(NULL);
58572     goto ok;
58573 
58574     ok:
58575     self->private_impl.p_do_tell_me_more[0] = 0;
58576     goto exit;
58577   }
58578 
58579   goto suspend;
58580   suspend:
58581   self->private_impl.p_do_tell_me_more[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
58582   self->private_data.s_do_tell_me_more[0].v_zlib_status = v_zlib_status;
58583 
58584   goto exit;
58585   exit:
58586   if (a_dst && a_dst->data.ptr) {
58587     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
58588   }
58589   if (a_src && a_src->data.ptr) {
58590     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
58591   }
58592 
58593   return status;
58594 }
58595 
58596 // -------- func png.decoder.history_retain_length
58597 
58598 WUFFS_BASE__GENERATED_C_CODE
58599 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_png__decoder__history_retain_length(const wuffs_png__decoder * self)58600 wuffs_png__decoder__history_retain_length(
58601     const wuffs_png__decoder* self) {
58602   if (!self) {
58603     return 0;
58604   }
58605   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
58606       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
58607     return 0;
58608   }
58609 
58610   return 0u;
58611 }
58612 
58613 // -------- func png.decoder.workbuf_len
58614 
58615 WUFFS_BASE__GENERATED_C_CODE
58616 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_png__decoder__workbuf_len(const wuffs_png__decoder * self)58617 wuffs_png__decoder__workbuf_len(
58618     const wuffs_png__decoder* self) {
58619   if (!self) {
58620     return wuffs_base__utility__empty_range_ii_u64();
58621   }
58622   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
58623       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
58624     return wuffs_base__utility__empty_range_ii_u64();
58625   }
58626 
58627   return wuffs_base__utility__make_range_ii_u64(self->private_impl.f_overall_workbuf_length, self->private_impl.f_overall_workbuf_length);
58628 }
58629 
58630 // -------- func png.decoder.filter_and_swizzle
58631 
58632 WUFFS_BASE__GENERATED_C_CODE
58633 static wuffs_base__status
wuffs_png__decoder__filter_and_swizzle(wuffs_png__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__slice_u8 a_workbuf)58634 wuffs_png__decoder__filter_and_swizzle(
58635     wuffs_png__decoder* self,
58636     wuffs_base__pixel_buffer* a_dst,
58637     wuffs_base__slice_u8 a_workbuf) {
58638   return (*self->private_impl.choosy_filter_and_swizzle)(self, a_dst, a_workbuf);
58639 }
58640 
58641 WUFFS_BASE__GENERATED_C_CODE
58642 static wuffs_base__status
wuffs_png__decoder__filter_and_swizzle__choosy_default(wuffs_png__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__slice_u8 a_workbuf)58643 wuffs_png__decoder__filter_and_swizzle__choosy_default(
58644     wuffs_png__decoder* self,
58645     wuffs_base__pixel_buffer* a_dst,
58646     wuffs_base__slice_u8 a_workbuf) {
58647   wuffs_base__pixel_format v_dst_pixfmt = {0};
58648   uint32_t v_dst_bits_per_pixel = 0;
58649   uint64_t v_dst_bytes_per_pixel = 0;
58650   uint64_t v_dst_bytes_per_row0 = 0;
58651   uint64_t v_dst_bytes_per_row1 = 0;
58652   wuffs_base__slice_u8 v_dst_palette = {0};
58653   wuffs_base__table_u8 v_tab = {0};
58654   uint32_t v_y = 0;
58655   wuffs_base__slice_u8 v_dst = {0};
58656   uint8_t v_filter = 0;
58657   wuffs_base__slice_u8 v_curr_row = {0};
58658   wuffs_base__slice_u8 v_prev_row = {0};
58659 
58660   v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
58661   v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
58662   if ((v_dst_bits_per_pixel & 7u) != 0u) {
58663     return wuffs_base__make_status(wuffs_base__error__unsupported_option);
58664   }
58665   v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8u)));
58666   v_dst_bytes_per_row0 = (((uint64_t)(self->private_impl.f_frame_rect_x0)) * v_dst_bytes_per_pixel);
58667   v_dst_bytes_per_row1 = (((uint64_t)(self->private_impl.f_frame_rect_x1)) * v_dst_bytes_per_pixel);
58668   v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024));
58669   v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
58670   if (v_dst_bytes_per_row1 < ((uint64_t)(v_tab.width))) {
58671     v_tab = wuffs_base__table_u8__subtable_ij(v_tab,
58672         0u,
58673         0u,
58674         v_dst_bytes_per_row1,
58675         ((uint64_t)(v_tab.height)));
58676   }
58677   if (v_dst_bytes_per_row0 < ((uint64_t)(v_tab.width))) {
58678     v_tab = wuffs_base__table_u8__subtable_ij(v_tab,
58679         v_dst_bytes_per_row0,
58680         0u,
58681         ((uint64_t)(v_tab.width)),
58682         ((uint64_t)(v_tab.height)));
58683   } else {
58684     v_tab = wuffs_base__table_u8__subtable_ij(v_tab,
58685         0u,
58686         0u,
58687         0u,
58688         0u);
58689   }
58690   v_y = self->private_impl.f_frame_rect_y0;
58691   while (v_y < self->private_impl.f_frame_rect_y1) {
58692     v_dst = wuffs_base__table_u8__row_u32(v_tab, v_y);
58693     if (1u > ((uint64_t)(a_workbuf.len))) {
58694       return wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_workbuf_length);
58695     }
58696     v_filter = a_workbuf.ptr[0u];
58697     a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, 1u);
58698     if (self->private_impl.f_pass_bytes_per_row > ((uint64_t)(a_workbuf.len))) {
58699       return wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_workbuf_length);
58700     }
58701     v_curr_row = wuffs_base__slice_u8__subslice_j(a_workbuf, self->private_impl.f_pass_bytes_per_row);
58702     a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, self->private_impl.f_pass_bytes_per_row);
58703     if (v_filter == 0u) {
58704     } else if (v_filter == 1u) {
58705       wuffs_png__decoder__filter_1(self, v_curr_row);
58706     } else if (v_filter == 2u) {
58707       wuffs_png__decoder__filter_2(self, v_curr_row, v_prev_row);
58708     } else if (v_filter == 3u) {
58709       wuffs_png__decoder__filter_3(self, v_curr_row, v_prev_row);
58710     } else if (v_filter == 4u) {
58711       wuffs_png__decoder__filter_4(self, v_curr_row, v_prev_row);
58712     } else {
58713       return wuffs_base__make_status(wuffs_png__error__bad_filter);
58714     }
58715     wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, v_curr_row);
58716     v_prev_row = v_curr_row;
58717     v_y += 1u;
58718   }
58719   return wuffs_base__make_status(NULL);
58720 }
58721 
58722 // -------- func png.decoder.filter_and_swizzle_tricky
58723 
58724 WUFFS_BASE__GENERATED_C_CODE
58725 static wuffs_base__status
wuffs_png__decoder__filter_and_swizzle_tricky(wuffs_png__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__slice_u8 a_workbuf)58726 wuffs_png__decoder__filter_and_swizzle_tricky(
58727     wuffs_png__decoder* self,
58728     wuffs_base__pixel_buffer* a_dst,
58729     wuffs_base__slice_u8 a_workbuf) {
58730   wuffs_base__pixel_format v_dst_pixfmt = {0};
58731   uint32_t v_dst_bits_per_pixel = 0;
58732   uint64_t v_dst_bytes_per_pixel = 0;
58733   uint64_t v_dst_bytes_per_row1 = 0;
58734   wuffs_base__slice_u8 v_dst_palette = {0};
58735   wuffs_base__table_u8 v_tab = {0};
58736   uint64_t v_src_bytes_per_pixel = 0;
58737   uint32_t v_x = 0;
58738   uint32_t v_y = 0;
58739   uint64_t v_i = 0;
58740   wuffs_base__slice_u8 v_dst = {0};
58741   uint8_t v_filter = 0;
58742   wuffs_base__slice_u8 v_s = {0};
58743   wuffs_base__slice_u8 v_curr_row = {0};
58744   wuffs_base__slice_u8 v_prev_row = {0};
58745   uint8_t v_bits_unpacked[8] = {0};
58746   uint8_t v_bits_packed = 0;
58747   uint8_t v_packs_remaining = 0;
58748   uint8_t v_multiplier = 0;
58749   uint8_t v_shift = 0;
58750 
58751   v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
58752   v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
58753   if ((v_dst_bits_per_pixel & 7u) != 0u) {
58754     return wuffs_base__make_status(wuffs_base__error__unsupported_option);
58755   }
58756   v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8u)));
58757   v_dst_bytes_per_row1 = (((uint64_t)(self->private_impl.f_frame_rect_x1)) * v_dst_bytes_per_pixel);
58758   v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024));
58759   v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
58760   v_src_bytes_per_pixel = 1u;
58761   if (self->private_impl.f_depth >= 8u) {
58762     v_src_bytes_per_pixel = (((uint64_t)(WUFFS_PNG__NUM_CHANNELS[self->private_impl.f_color_type])) * ((uint64_t)((self->private_impl.f_depth >> 3u))));
58763   }
58764   if (self->private_impl.f_chunk_type_array[0u] == 73u) {
58765     v_y = ((uint32_t)(WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][5u]));
58766   } else {
58767     v_y = self->private_impl.f_frame_rect_y0;
58768   }
58769   while (v_y < self->private_impl.f_frame_rect_y1) {
58770     v_dst = wuffs_base__table_u8__row_u32(v_tab, v_y);
58771     if (v_dst_bytes_per_row1 < ((uint64_t)(v_dst.len))) {
58772       v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row1);
58773     }
58774     if (1u > ((uint64_t)(a_workbuf.len))) {
58775       return wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_workbuf_length);
58776     }
58777     v_filter = a_workbuf.ptr[0u];
58778     a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, 1u);
58779     if (self->private_impl.f_pass_bytes_per_row > ((uint64_t)(a_workbuf.len))) {
58780       return wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_workbuf_length);
58781     }
58782     v_curr_row = wuffs_base__slice_u8__subslice_j(a_workbuf, self->private_impl.f_pass_bytes_per_row);
58783     a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, self->private_impl.f_pass_bytes_per_row);
58784     if (v_filter == 0u) {
58785     } else if (v_filter == 1u) {
58786       wuffs_png__decoder__filter_1(self, v_curr_row);
58787     } else if (v_filter == 2u) {
58788       wuffs_png__decoder__filter_2(self, v_curr_row, v_prev_row);
58789     } else if (v_filter == 3u) {
58790       wuffs_png__decoder__filter_3(self, v_curr_row, v_prev_row);
58791     } else if (v_filter == 4u) {
58792       wuffs_png__decoder__filter_4(self, v_curr_row, v_prev_row);
58793     } else {
58794       return wuffs_base__make_status(wuffs_png__error__bad_filter);
58795     }
58796     v_s = v_curr_row;
58797     if (self->private_impl.f_chunk_type_array[0u] == 73u) {
58798       v_x = ((uint32_t)(WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][2u]));
58799     } else {
58800       v_x = self->private_impl.f_frame_rect_x0;
58801     }
58802     if (self->private_impl.f_depth == 8u) {
58803       while (v_x < self->private_impl.f_frame_rect_x1) {
58804         v_i = (((uint64_t)(v_x)) * v_dst_bytes_per_pixel);
58805         if (v_i <= ((uint64_t)(v_dst.len))) {
58806           if (self->private_impl.f_color_type == 4u) {
58807             if (2u <= ((uint64_t)(v_s.len))) {
58808               v_bits_unpacked[0u] = v_s.ptr[0u];
58809               v_bits_unpacked[1u] = v_s.ptr[0u];
58810               v_bits_unpacked[2u] = v_s.ptr[0u];
58811               v_bits_unpacked[3u] = v_s.ptr[1u];
58812               v_s = wuffs_base__slice_u8__subslice_i(v_s, 2u);
58813               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));
58814             }
58815           } else if (((uint32_t)(self->private_impl.f_remap_transparency)) != 0u) {
58816             if (self->private_impl.f_color_type == 0u) {
58817               if (1u <= ((uint64_t)(v_s.len))) {
58818                 v_bits_unpacked[0u] = v_s.ptr[0u];
58819                 v_bits_unpacked[1u] = v_s.ptr[0u];
58820                 v_bits_unpacked[2u] = v_s.ptr[0u];
58821                 v_bits_unpacked[3u] = 255u;
58822                 v_s = wuffs_base__slice_u8__subslice_i(v_s, 1u);
58823                 if (((uint32_t)(self->private_impl.f_remap_transparency)) == ((((uint32_t)(v_bits_unpacked[0u])) << 0u) |
58824                     (((uint32_t)(v_bits_unpacked[1u])) << 8u) |
58825                     (((uint32_t)(v_bits_unpacked[2u])) << 16u) |
58826                     (((uint32_t)(v_bits_unpacked[3u])) << 24u))) {
58827                   v_bits_unpacked[0u] = 0u;
58828                   v_bits_unpacked[1u] = 0u;
58829                   v_bits_unpacked[2u] = 0u;
58830                   v_bits_unpacked[3u] = 0u;
58831                 }
58832                 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));
58833               }
58834             } else {
58835               if (3u <= ((uint64_t)(v_s.len))) {
58836                 v_bits_unpacked[0u] = v_s.ptr[2u];
58837                 v_bits_unpacked[1u] = v_s.ptr[1u];
58838                 v_bits_unpacked[2u] = v_s.ptr[0u];
58839                 v_bits_unpacked[3u] = 255u;
58840                 v_s = wuffs_base__slice_u8__subslice_i(v_s, 3u);
58841                 if (((uint32_t)(self->private_impl.f_remap_transparency)) == ((((uint32_t)(v_bits_unpacked[0u])) << 0u) |
58842                     (((uint32_t)(v_bits_unpacked[1u])) << 8u) |
58843                     (((uint32_t)(v_bits_unpacked[2u])) << 16u) |
58844                     (((uint32_t)(v_bits_unpacked[3u])) << 24u))) {
58845                   v_bits_unpacked[0u] = 0u;
58846                   v_bits_unpacked[1u] = 0u;
58847                   v_bits_unpacked[2u] = 0u;
58848                   v_bits_unpacked[3u] = 0u;
58849                 }
58850                 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));
58851               }
58852             }
58853           } else if (v_src_bytes_per_pixel <= ((uint64_t)(v_s.len))) {
58854             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));
58855             v_s = wuffs_base__slice_u8__subslice_i(v_s, v_src_bytes_per_pixel);
58856           }
58857         }
58858         v_x += (((uint32_t)(1u)) << WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][0u]);
58859       }
58860     } else if (self->private_impl.f_depth < 8u) {
58861       v_multiplier = 1u;
58862       if (self->private_impl.f_color_type == 0u) {
58863         v_multiplier = WUFFS_PNG__LOW_BIT_DEPTH_MULTIPLIERS[self->private_impl.f_depth];
58864       }
58865       v_shift = ((8u - self->private_impl.f_depth) & 7u);
58866       v_packs_remaining = 0u;
58867       while (v_x < self->private_impl.f_frame_rect_x1) {
58868         v_i = (((uint64_t)(v_x)) * v_dst_bytes_per_pixel);
58869         if (v_i <= ((uint64_t)(v_dst.len))) {
58870           if ((v_packs_remaining == 0u) && (1u <= ((uint64_t)(v_s.len)))) {
58871             v_packs_remaining = WUFFS_PNG__LOW_BIT_DEPTH_NUM_PACKS[self->private_impl.f_depth];
58872             v_bits_packed = v_s.ptr[0u];
58873             v_s = wuffs_base__slice_u8__subslice_i(v_s, 1u);
58874           }
58875           v_bits_unpacked[0u] = ((uint8_t)((v_bits_packed >> v_shift) * v_multiplier));
58876           v_bits_packed = ((uint8_t)(v_bits_packed << self->private_impl.f_depth));
58877           v_packs_remaining = ((uint8_t)(v_packs_remaining - 1u));
58878           if (((uint32_t)(self->private_impl.f_remap_transparency)) != 0u) {
58879             v_bits_unpacked[1u] = v_bits_unpacked[0u];
58880             v_bits_unpacked[2u] = v_bits_unpacked[0u];
58881             v_bits_unpacked[3u] = 255u;
58882             if (((uint32_t)(self->private_impl.f_remap_transparency)) == ((((uint32_t)(v_bits_unpacked[0u])) << 0u) |
58883                 (((uint32_t)(v_bits_unpacked[1u])) << 8u) |
58884                 (((uint32_t)(v_bits_unpacked[2u])) << 16u) |
58885                 (((uint32_t)(v_bits_unpacked[3u])) << 24u))) {
58886               v_bits_unpacked[0u] = 0u;
58887               v_bits_unpacked[1u] = 0u;
58888               v_bits_unpacked[2u] = 0u;
58889               v_bits_unpacked[3u] = 0u;
58890             }
58891             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));
58892           } else {
58893             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));
58894           }
58895         }
58896         v_x += (((uint32_t)(1u)) << WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][0u]);
58897       }
58898     } else {
58899       while (v_x < self->private_impl.f_frame_rect_x1) {
58900         v_i = (((uint64_t)(v_x)) * v_dst_bytes_per_pixel);
58901         if (v_i <= ((uint64_t)(v_dst.len))) {
58902           if (self->private_impl.f_color_type == 0u) {
58903             if (2u <= ((uint64_t)(v_s.len))) {
58904               v_bits_unpacked[0u] = v_s.ptr[1u];
58905               v_bits_unpacked[1u] = v_s.ptr[0u];
58906               v_bits_unpacked[2u] = v_s.ptr[1u];
58907               v_bits_unpacked[3u] = v_s.ptr[0u];
58908               v_bits_unpacked[4u] = v_s.ptr[1u];
58909               v_bits_unpacked[5u] = v_s.ptr[0u];
58910               v_bits_unpacked[6u] = 255u;
58911               v_bits_unpacked[7u] = 255u;
58912               v_s = wuffs_base__slice_u8__subslice_i(v_s, 2u);
58913               if (self->private_impl.f_remap_transparency == ((((uint64_t)(v_bits_unpacked[0u])) << 0u) |
58914                   (((uint64_t)(v_bits_unpacked[1u])) << 8u) |
58915                   (((uint64_t)(v_bits_unpacked[2u])) << 16u) |
58916                   (((uint64_t)(v_bits_unpacked[3u])) << 24u) |
58917                   (((uint64_t)(v_bits_unpacked[4u])) << 32u) |
58918                   (((uint64_t)(v_bits_unpacked[5u])) << 40u) |
58919                   (((uint64_t)(v_bits_unpacked[6u])) << 48u) |
58920                   (((uint64_t)(v_bits_unpacked[7u])) << 56u))) {
58921                 v_bits_unpacked[0u] = 0u;
58922                 v_bits_unpacked[1u] = 0u;
58923                 v_bits_unpacked[2u] = 0u;
58924                 v_bits_unpacked[3u] = 0u;
58925                 v_bits_unpacked[4u] = 0u;
58926                 v_bits_unpacked[5u] = 0u;
58927                 v_bits_unpacked[6u] = 0u;
58928                 v_bits_unpacked[7u] = 0u;
58929               }
58930             }
58931           } else if (self->private_impl.f_color_type == 2u) {
58932             if (6u <= ((uint64_t)(v_s.len))) {
58933               v_bits_unpacked[0u] = v_s.ptr[5u];
58934               v_bits_unpacked[1u] = v_s.ptr[4u];
58935               v_bits_unpacked[2u] = v_s.ptr[3u];
58936               v_bits_unpacked[3u] = v_s.ptr[2u];
58937               v_bits_unpacked[4u] = v_s.ptr[1u];
58938               v_bits_unpacked[5u] = v_s.ptr[0u];
58939               v_bits_unpacked[6u] = 255u;
58940               v_bits_unpacked[7u] = 255u;
58941               v_s = wuffs_base__slice_u8__subslice_i(v_s, 6u);
58942               if (self->private_impl.f_remap_transparency == ((((uint64_t)(v_bits_unpacked[0u])) << 0u) |
58943                   (((uint64_t)(v_bits_unpacked[1u])) << 8u) |
58944                   (((uint64_t)(v_bits_unpacked[2u])) << 16u) |
58945                   (((uint64_t)(v_bits_unpacked[3u])) << 24u) |
58946                   (((uint64_t)(v_bits_unpacked[4u])) << 32u) |
58947                   (((uint64_t)(v_bits_unpacked[5u])) << 40u) |
58948                   (((uint64_t)(v_bits_unpacked[6u])) << 48u) |
58949                   (((uint64_t)(v_bits_unpacked[7u])) << 56u))) {
58950                 v_bits_unpacked[0u] = 0u;
58951                 v_bits_unpacked[1u] = 0u;
58952                 v_bits_unpacked[2u] = 0u;
58953                 v_bits_unpacked[3u] = 0u;
58954                 v_bits_unpacked[4u] = 0u;
58955                 v_bits_unpacked[5u] = 0u;
58956                 v_bits_unpacked[6u] = 0u;
58957                 v_bits_unpacked[7u] = 0u;
58958               }
58959             }
58960           } else if (self->private_impl.f_color_type == 4u) {
58961             if (4u <= ((uint64_t)(v_s.len))) {
58962               v_bits_unpacked[0u] = v_s.ptr[1u];
58963               v_bits_unpacked[1u] = v_s.ptr[0u];
58964               v_bits_unpacked[2u] = v_s.ptr[1u];
58965               v_bits_unpacked[3u] = v_s.ptr[0u];
58966               v_bits_unpacked[4u] = v_s.ptr[1u];
58967               v_bits_unpacked[5u] = v_s.ptr[0u];
58968               v_bits_unpacked[6u] = v_s.ptr[3u];
58969               v_bits_unpacked[7u] = v_s.ptr[2u];
58970               v_s = wuffs_base__slice_u8__subslice_i(v_s, 4u);
58971             }
58972           } else {
58973             if (8u <= ((uint64_t)(v_s.len))) {
58974               v_bits_unpacked[0u] = v_s.ptr[5u];
58975               v_bits_unpacked[1u] = v_s.ptr[4u];
58976               v_bits_unpacked[2u] = v_s.ptr[3u];
58977               v_bits_unpacked[3u] = v_s.ptr[2u];
58978               v_bits_unpacked[4u] = v_s.ptr[1u];
58979               v_bits_unpacked[5u] = v_s.ptr[0u];
58980               v_bits_unpacked[6u] = v_s.ptr[7u];
58981               v_bits_unpacked[7u] = v_s.ptr[6u];
58982               v_s = wuffs_base__slice_u8__subslice_i(v_s, 8u);
58983             }
58984           }
58985           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));
58986         }
58987         v_x += (((uint32_t)(1u)) << WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][0u]);
58988       }
58989     }
58990     v_prev_row = v_curr_row;
58991     v_y += (((uint32_t)(1u)) << WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][3u]);
58992   }
58993   return wuffs_base__make_status(NULL);
58994 }
58995 
58996 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__PNG)
58997 
58998 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__TGA)
58999 
59000 // ---------------- Status Codes Implementations
59001 
59002 const char wuffs_tga__error__bad_header[] = "#tga: bad header";
59003 const char wuffs_tga__error__bad_run_length_encoding[] = "#tga: bad run length encoding";
59004 const char wuffs_tga__error__truncated_input[] = "#tga: truncated input";
59005 const char wuffs_tga__error__unsupported_tga_file[] = "#tga: unsupported TGA file";
59006 
59007 // ---------------- Private Consts
59008 
59009 // ---------------- Private Initializer Prototypes
59010 
59011 // ---------------- Private Function Prototypes
59012 
59013 WUFFS_BASE__GENERATED_C_CODE
59014 static wuffs_base__status
59015 wuffs_tga__decoder__do_decode_image_config(
59016     wuffs_tga__decoder* self,
59017     wuffs_base__image_config* a_dst,
59018     wuffs_base__io_buffer* a_src);
59019 
59020 WUFFS_BASE__GENERATED_C_CODE
59021 static wuffs_base__status
59022 wuffs_tga__decoder__do_decode_frame_config(
59023     wuffs_tga__decoder* self,
59024     wuffs_base__frame_config* a_dst,
59025     wuffs_base__io_buffer* a_src);
59026 
59027 WUFFS_BASE__GENERATED_C_CODE
59028 static wuffs_base__status
59029 wuffs_tga__decoder__do_decode_frame(
59030     wuffs_tga__decoder* self,
59031     wuffs_base__pixel_buffer* a_dst,
59032     wuffs_base__io_buffer* a_src,
59033     wuffs_base__pixel_blend a_blend,
59034     wuffs_base__slice_u8 a_workbuf,
59035     wuffs_base__decode_frame_options* a_opts);
59036 
59037 // ---------------- VTables
59038 
59039 const wuffs_base__image_decoder__func_ptrs
59040 wuffs_tga__decoder__func_ptrs_for__wuffs_base__image_decoder = {
59041   (wuffs_base__status(*)(void*,
59042       wuffs_base__pixel_buffer*,
59043       wuffs_base__io_buffer*,
59044       wuffs_base__pixel_blend,
59045       wuffs_base__slice_u8,
59046       wuffs_base__decode_frame_options*))(&wuffs_tga__decoder__decode_frame),
59047   (wuffs_base__status(*)(void*,
59048       wuffs_base__frame_config*,
59049       wuffs_base__io_buffer*))(&wuffs_tga__decoder__decode_frame_config),
59050   (wuffs_base__status(*)(void*,
59051       wuffs_base__image_config*,
59052       wuffs_base__io_buffer*))(&wuffs_tga__decoder__decode_image_config),
59053   (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_tga__decoder__frame_dirty_rect),
59054   (uint64_t(*)(const void*,
59055       uint32_t))(&wuffs_tga__decoder__get_quirk),
59056   (uint64_t(*)(const void*))(&wuffs_tga__decoder__history_retain_length),
59057   (uint32_t(*)(const void*))(&wuffs_tga__decoder__num_animation_loops),
59058   (uint64_t(*)(const void*))(&wuffs_tga__decoder__num_decoded_frame_configs),
59059   (uint64_t(*)(const void*))(&wuffs_tga__decoder__num_decoded_frames),
59060   (wuffs_base__status(*)(void*,
59061       uint64_t,
59062       uint64_t))(&wuffs_tga__decoder__restart_frame),
59063   (wuffs_base__status(*)(void*,
59064       uint32_t,
59065       uint64_t))(&wuffs_tga__decoder__set_quirk),
59066   (wuffs_base__empty_struct(*)(void*,
59067       uint32_t,
59068       bool))(&wuffs_tga__decoder__set_report_metadata),
59069   (wuffs_base__status(*)(void*,
59070       wuffs_base__io_buffer*,
59071       wuffs_base__more_information*,
59072       wuffs_base__io_buffer*))(&wuffs_tga__decoder__tell_me_more),
59073   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_tga__decoder__workbuf_len),
59074 };
59075 
59076 // ---------------- Initializer Implementations
59077 
59078 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
wuffs_tga__decoder__initialize(wuffs_tga__decoder * self,size_t sizeof_star_self,uint64_t wuffs_version,uint32_t options)59079 wuffs_tga__decoder__initialize(
59080     wuffs_tga__decoder* self,
59081     size_t sizeof_star_self,
59082     uint64_t wuffs_version,
59083     uint32_t options){
59084   if (!self) {
59085     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
59086   }
59087   if (sizeof(*self) != sizeof_star_self) {
59088     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
59089   }
59090   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
59091       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
59092     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
59093   }
59094 
59095   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
59096     // The whole point of this if-check is to detect an uninitialized *self.
59097     // We disable the warning on GCC. Clang-5.0 does not have this warning.
59098 #if !defined(__clang__) && defined(__GNUC__)
59099 #pragma GCC diagnostic push
59100 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
59101 #endif
59102     if (self->private_impl.magic != 0) {
59103       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
59104     }
59105 #if !defined(__clang__) && defined(__GNUC__)
59106 #pragma GCC diagnostic pop
59107 #endif
59108   } else {
59109     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
59110       memset(self, 0, sizeof(*self));
59111       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
59112     } else {
59113       memset(&(self->private_impl), 0, sizeof(self->private_impl));
59114     }
59115   }
59116 
59117   self->private_impl.magic = WUFFS_BASE__MAGIC;
59118   self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
59119       wuffs_base__image_decoder__vtable_name;
59120   self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
59121       (const void*)(&wuffs_tga__decoder__func_ptrs_for__wuffs_base__image_decoder);
59122   return wuffs_base__make_status(NULL);
59123 }
59124 
59125 wuffs_tga__decoder*
wuffs_tga__decoder__alloc(void)59126 wuffs_tga__decoder__alloc(void) {
59127   wuffs_tga__decoder* x =
59128       (wuffs_tga__decoder*)(calloc(sizeof(wuffs_tga__decoder), 1));
59129   if (!x) {
59130     return NULL;
59131   }
59132   if (wuffs_tga__decoder__initialize(
59133       x, sizeof(wuffs_tga__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
59134     free(x);
59135     return NULL;
59136   }
59137   return x;
59138 }
59139 
59140 size_t
sizeof__wuffs_tga__decoder(void)59141 sizeof__wuffs_tga__decoder(void) {
59142   return sizeof(wuffs_tga__decoder);
59143 }
59144 
59145 // ---------------- Function Implementations
59146 
59147 // -------- func tga.decoder.get_quirk
59148 
59149 WUFFS_BASE__GENERATED_C_CODE
59150 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_tga__decoder__get_quirk(const wuffs_tga__decoder * self,uint32_t a_key)59151 wuffs_tga__decoder__get_quirk(
59152     const wuffs_tga__decoder* self,
59153     uint32_t a_key) {
59154   if (!self) {
59155     return 0;
59156   }
59157   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
59158       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
59159     return 0;
59160   }
59161 
59162   return 0u;
59163 }
59164 
59165 // -------- func tga.decoder.set_quirk
59166 
59167 WUFFS_BASE__GENERATED_C_CODE
59168 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_tga__decoder__set_quirk(wuffs_tga__decoder * self,uint32_t a_key,uint64_t a_value)59169 wuffs_tga__decoder__set_quirk(
59170     wuffs_tga__decoder* self,
59171     uint32_t a_key,
59172     uint64_t a_value) {
59173   if (!self) {
59174     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
59175   }
59176   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
59177     return wuffs_base__make_status(
59178         (self->private_impl.magic == WUFFS_BASE__DISABLED)
59179         ? wuffs_base__error__disabled_by_previous_error
59180         : wuffs_base__error__initialize_not_called);
59181   }
59182 
59183   return wuffs_base__make_status(wuffs_base__error__unsupported_option);
59184 }
59185 
59186 // -------- func tga.decoder.decode_image_config
59187 
59188 WUFFS_BASE__GENERATED_C_CODE
59189 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_tga__decoder__decode_image_config(wuffs_tga__decoder * self,wuffs_base__image_config * a_dst,wuffs_base__io_buffer * a_src)59190 wuffs_tga__decoder__decode_image_config(
59191     wuffs_tga__decoder* self,
59192     wuffs_base__image_config* a_dst,
59193     wuffs_base__io_buffer* a_src) {
59194   if (!self) {
59195     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
59196   }
59197   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
59198     return wuffs_base__make_status(
59199         (self->private_impl.magic == WUFFS_BASE__DISABLED)
59200         ? wuffs_base__error__disabled_by_previous_error
59201         : wuffs_base__error__initialize_not_called);
59202   }
59203   if (!a_src) {
59204     self->private_impl.magic = WUFFS_BASE__DISABLED;
59205     return wuffs_base__make_status(wuffs_base__error__bad_argument);
59206   }
59207   if ((self->private_impl.active_coroutine != 0) &&
59208       (self->private_impl.active_coroutine != 1)) {
59209     self->private_impl.magic = WUFFS_BASE__DISABLED;
59210     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
59211   }
59212   self->private_impl.active_coroutine = 0;
59213   wuffs_base__status status = wuffs_base__make_status(NULL);
59214 
59215   wuffs_base__status v_status = wuffs_base__make_status(NULL);
59216 
59217   uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
59218   switch (coro_susp_point) {
59219     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
59220 
59221     while (true) {
59222       {
59223         wuffs_base__status t_0 = wuffs_tga__decoder__do_decode_image_config(self, a_dst, a_src);
59224         v_status = t_0;
59225       }
59226       if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
59227         status = wuffs_base__make_status(wuffs_tga__error__truncated_input);
59228         goto exit;
59229       }
59230       status = v_status;
59231       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
59232     }
59233 
59234     ok:
59235     self->private_impl.p_decode_image_config[0] = 0;
59236     goto exit;
59237   }
59238 
59239   goto suspend;
59240   suspend:
59241   self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
59242   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
59243 
59244   goto exit;
59245   exit:
59246   if (wuffs_base__status__is_error(&status)) {
59247     self->private_impl.magic = WUFFS_BASE__DISABLED;
59248   }
59249   return status;
59250 }
59251 
59252 // -------- func tga.decoder.do_decode_image_config
59253 
59254 WUFFS_BASE__GENERATED_C_CODE
59255 static wuffs_base__status
wuffs_tga__decoder__do_decode_image_config(wuffs_tga__decoder * self,wuffs_base__image_config * a_dst,wuffs_base__io_buffer * a_src)59256 wuffs_tga__decoder__do_decode_image_config(
59257     wuffs_tga__decoder* self,
59258     wuffs_base__image_config* a_dst,
59259     wuffs_base__io_buffer* a_src) {
59260   wuffs_base__status status = wuffs_base__make_status(NULL);
59261 
59262   uint32_t v_c = 0;
59263   uint32_t v_c5 = 0;
59264   uint32_t v_i = 0;
59265 
59266   const uint8_t* iop_a_src = NULL;
59267   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
59268   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
59269   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
59270   if (a_src && a_src->data.ptr) {
59271     io0_a_src = a_src->data.ptr;
59272     io1_a_src = io0_a_src + a_src->meta.ri;
59273     iop_a_src = io1_a_src;
59274     io2_a_src = io0_a_src + a_src->meta.wi;
59275   }
59276 
59277   uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config[0];
59278   if (coro_susp_point) {
59279     v_i = self->private_data.s_do_decode_image_config[0].v_i;
59280   }
59281   switch (coro_susp_point) {
59282     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
59283 
59284     if (self->private_impl.f_call_sequence != 0u) {
59285       status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
59286       goto exit;
59287     }
59288     {
59289       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
59290       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
59291         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
59292         goto suspend;
59293       }
59294       uint8_t t_0 = *iop_a_src++;
59295       self->private_impl.f_header_id_length = t_0;
59296     }
59297     {
59298       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
59299       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
59300         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
59301         goto suspend;
59302       }
59303       uint8_t t_1 = *iop_a_src++;
59304       self->private_impl.f_header_color_map_type = t_1;
59305     }
59306     if (self->private_impl.f_header_color_map_type > 1u) {
59307       status = wuffs_base__make_status(wuffs_tga__error__bad_header);
59308       goto exit;
59309     }
59310     {
59311       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
59312       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
59313         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
59314         goto suspend;
59315       }
59316       uint8_t t_2 = *iop_a_src++;
59317       self->private_impl.f_header_image_type = t_2;
59318     }
59319     if ((self->private_impl.f_header_image_type == 1u) ||
59320         (self->private_impl.f_header_image_type == 2u) ||
59321         (self->private_impl.f_header_image_type == 3u) ||
59322         (self->private_impl.f_header_image_type == 9u) ||
59323         (self->private_impl.f_header_image_type == 10u) ||
59324         (self->private_impl.f_header_image_type == 11u)) {
59325     } else {
59326       status = wuffs_base__make_status(wuffs_tga__error__bad_header);
59327       goto exit;
59328     }
59329     {
59330       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
59331       uint16_t t_3;
59332       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
59333         t_3 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src);
59334         iop_a_src += 2;
59335       } else {
59336         self->private_data.s_do_decode_image_config[0].scratch = 0;
59337         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
59338         while (true) {
59339           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
59340             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
59341             goto suspend;
59342           }
59343           uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
59344           uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56));
59345           *scratch <<= 8;
59346           *scratch >>= 8;
59347           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3;
59348           if (num_bits_3 == 8) {
59349             t_3 = ((uint16_t)(*scratch));
59350             break;
59351           }
59352           num_bits_3 += 8u;
59353           *scratch |= ((uint64_t)(num_bits_3)) << 56;
59354         }
59355       }
59356       self->private_impl.f_header_color_map_first_entry_index = t_3;
59357     }
59358     {
59359       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
59360       uint16_t t_4;
59361       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
59362         t_4 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src);
59363         iop_a_src += 2;
59364       } else {
59365         self->private_data.s_do_decode_image_config[0].scratch = 0;
59366         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
59367         while (true) {
59368           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
59369             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
59370             goto suspend;
59371           }
59372           uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
59373           uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
59374           *scratch <<= 8;
59375           *scratch >>= 8;
59376           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
59377           if (num_bits_4 == 8) {
59378             t_4 = ((uint16_t)(*scratch));
59379             break;
59380           }
59381           num_bits_4 += 8u;
59382           *scratch |= ((uint64_t)(num_bits_4)) << 56;
59383         }
59384       }
59385       self->private_impl.f_header_color_map_length = t_4;
59386     }
59387     {
59388       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
59389       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
59390         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
59391         goto suspend;
59392       }
59393       uint8_t t_5 = *iop_a_src++;
59394       self->private_impl.f_header_color_map_entry_size = t_5;
59395     }
59396     if (self->private_impl.f_header_color_map_type != 0u) {
59397       if ((self->private_impl.f_header_color_map_first_entry_index != 0u) || (self->private_impl.f_header_color_map_length > 256u)) {
59398         status = wuffs_base__make_status(wuffs_tga__error__unsupported_tga_file);
59399         goto exit;
59400       } else if ((self->private_impl.f_header_color_map_entry_size != 15u) &&
59401           (self->private_impl.f_header_color_map_entry_size != 16u) &&
59402           (self->private_impl.f_header_color_map_entry_size != 24u) &&
59403           (self->private_impl.f_header_color_map_entry_size != 32u)) {
59404         status = wuffs_base__make_status(wuffs_tga__error__bad_header);
59405         goto exit;
59406       }
59407     } else {
59408       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)) {
59409         status = wuffs_base__make_status(wuffs_tga__error__bad_header);
59410         goto exit;
59411       }
59412     }
59413     self->private_data.s_do_decode_image_config[0].scratch = 4u;
59414     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
59415     if (self->private_data.s_do_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
59416       self->private_data.s_do_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
59417       iop_a_src = io2_a_src;
59418       status = wuffs_base__make_status(wuffs_base__suspension__short_read);
59419       goto suspend;
59420     }
59421     iop_a_src += self->private_data.s_do_decode_image_config[0].scratch;
59422     {
59423       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
59424       uint32_t t_6;
59425       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
59426         t_6 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
59427         iop_a_src += 2;
59428       } else {
59429         self->private_data.s_do_decode_image_config[0].scratch = 0;
59430         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
59431         while (true) {
59432           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
59433             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
59434             goto suspend;
59435           }
59436           uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
59437           uint32_t num_bits_6 = ((uint32_t)(*scratch >> 56));
59438           *scratch <<= 8;
59439           *scratch >>= 8;
59440           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_6;
59441           if (num_bits_6 == 8) {
59442             t_6 = ((uint32_t)(*scratch));
59443             break;
59444           }
59445           num_bits_6 += 8u;
59446           *scratch |= ((uint64_t)(num_bits_6)) << 56;
59447         }
59448       }
59449       self->private_impl.f_width = t_6;
59450     }
59451     {
59452       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
59453       uint32_t t_7;
59454       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
59455         t_7 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
59456         iop_a_src += 2;
59457       } else {
59458         self->private_data.s_do_decode_image_config[0].scratch = 0;
59459         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
59460         while (true) {
59461           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
59462             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
59463             goto suspend;
59464           }
59465           uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
59466           uint32_t num_bits_7 = ((uint32_t)(*scratch >> 56));
59467           *scratch <<= 8;
59468           *scratch >>= 8;
59469           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_7;
59470           if (num_bits_7 == 8) {
59471             t_7 = ((uint32_t)(*scratch));
59472             break;
59473           }
59474           num_bits_7 += 8u;
59475           *scratch |= ((uint64_t)(num_bits_7)) << 56;
59476         }
59477       }
59478       self->private_impl.f_height = t_7;
59479     }
59480     {
59481       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
59482       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
59483         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
59484         goto suspend;
59485       }
59486       uint8_t t_8 = *iop_a_src++;
59487       self->private_impl.f_header_pixel_depth = t_8;
59488     }
59489     if ((self->private_impl.f_header_pixel_depth != 1u) &&
59490         (self->private_impl.f_header_pixel_depth != 8u) &&
59491         (self->private_impl.f_header_pixel_depth != 15u) &&
59492         (self->private_impl.f_header_pixel_depth != 16u) &&
59493         (self->private_impl.f_header_pixel_depth != 24u) &&
59494         (self->private_impl.f_header_pixel_depth != 32u)) {
59495       status = wuffs_base__make_status(wuffs_tga__error__bad_header);
59496       goto exit;
59497     }
59498     if ((self->private_impl.f_header_image_type | 8u) == 9u) {
59499       self->private_impl.f_scratch_bytes_per_pixel = 1u;
59500       self->private_impl.f_src_bytes_per_pixel = 1u;
59501       self->private_impl.f_src_pixfmt = 2164523016u;
59502       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));
59503     } else if ((self->private_impl.f_header_image_type | 8u) == 10u) {
59504       if ((self->private_impl.f_header_pixel_depth == 15u) || (self->private_impl.f_header_pixel_depth == 16u)) {
59505         self->private_impl.f_scratch_bytes_per_pixel = 4u;
59506         self->private_impl.f_src_bytes_per_pixel = 0u;
59507         self->private_impl.f_src_pixfmt = 2164295816u;
59508       } else if (self->private_impl.f_header_pixel_depth == 24u) {
59509         self->private_impl.f_scratch_bytes_per_pixel = 3u;
59510         self->private_impl.f_src_bytes_per_pixel = 3u;
59511         self->private_impl.f_src_pixfmt = 2147485832u;
59512         self->private_impl.f_opaque = true;
59513       } else if (self->private_impl.f_header_pixel_depth == 32u) {
59514         self->private_impl.f_scratch_bytes_per_pixel = 4u;
59515         self->private_impl.f_src_bytes_per_pixel = 4u;
59516         self->private_impl.f_src_pixfmt = 2164295816u;
59517       } else {
59518         status = wuffs_base__make_status(wuffs_tga__error__unsupported_tga_file);
59519         goto exit;
59520       }
59521     } else {
59522       if (self->private_impl.f_header_pixel_depth == 8u) {
59523         self->private_impl.f_scratch_bytes_per_pixel = 1u;
59524         self->private_impl.f_src_bytes_per_pixel = 1u;
59525         self->private_impl.f_src_pixfmt = 536870920u;
59526         self->private_impl.f_opaque = true;
59527       } else {
59528         status = wuffs_base__make_status(wuffs_tga__error__unsupported_tga_file);
59529         goto exit;
59530       }
59531     }
59532     {
59533       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
59534       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
59535         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
59536         goto suspend;
59537       }
59538       uint8_t t_9 = *iop_a_src++;
59539       self->private_impl.f_header_image_descriptor = t_9;
59540     }
59541     if ((self->private_impl.f_header_image_descriptor & 16u) != 0u) {
59542       status = wuffs_base__make_status(wuffs_tga__error__unsupported_tga_file);
59543       goto exit;
59544     }
59545     self->private_data.s_do_decode_image_config[0].scratch = ((uint32_t)(self->private_impl.f_header_id_length));
59546     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
59547     if (self->private_data.s_do_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
59548       self->private_data.s_do_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
59549       iop_a_src = io2_a_src;
59550       status = wuffs_base__make_status(wuffs_base__suspension__short_read);
59551       goto suspend;
59552     }
59553     iop_a_src += self->private_data.s_do_decode_image_config[0].scratch;
59554     if (self->private_impl.f_header_color_map_type != 0u) {
59555       while (v_i < ((uint32_t)(self->private_impl.f_header_color_map_length))) {
59556         if (self->private_impl.f_header_color_map_entry_size == 24u) {
59557           {
59558             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(17);
59559             uint32_t t_10;
59560             if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) {
59561               t_10 = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src)));
59562               iop_a_src += 3;
59563             } else {
59564               self->private_data.s_do_decode_image_config[0].scratch = 0;
59565               WUFFS_BASE__COROUTINE_SUSPENSION_POINT(18);
59566               while (true) {
59567                 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
59568                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
59569                   goto suspend;
59570                 }
59571                 uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
59572                 uint32_t num_bits_10 = ((uint32_t)(*scratch >> 56));
59573                 *scratch <<= 8;
59574                 *scratch >>= 8;
59575                 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_10;
59576                 if (num_bits_10 == 16) {
59577                   t_10 = ((uint32_t)(*scratch));
59578                   break;
59579                 }
59580                 num_bits_10 += 8u;
59581                 *scratch |= ((uint64_t)(num_bits_10)) << 56;
59582               }
59583             }
59584             v_c = t_10;
59585           }
59586           self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 0u)] = ((uint8_t)((v_c >> 0u)));
59587           self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 1u)] = ((uint8_t)((v_c >> 8u)));
59588           self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 2u)] = ((uint8_t)((v_c >> 16u)));
59589           self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 3u)] = 255u;
59590         } else if (self->private_impl.f_header_color_map_entry_size == 32u) {
59591           {
59592             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(19);
59593             uint32_t t_11;
59594             if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
59595               t_11 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
59596               iop_a_src += 4;
59597             } else {
59598               self->private_data.s_do_decode_image_config[0].scratch = 0;
59599               WUFFS_BASE__COROUTINE_SUSPENSION_POINT(20);
59600               while (true) {
59601                 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
59602                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
59603                   goto suspend;
59604                 }
59605                 uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
59606                 uint32_t num_bits_11 = ((uint32_t)(*scratch >> 56));
59607                 *scratch <<= 8;
59608                 *scratch >>= 8;
59609                 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_11;
59610                 if (num_bits_11 == 24) {
59611                   t_11 = ((uint32_t)(*scratch));
59612                   break;
59613                 }
59614                 num_bits_11 += 8u;
59615                 *scratch |= ((uint64_t)(num_bits_11)) << 56;
59616               }
59617             }
59618             v_c = t_11;
59619           }
59620           self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 0u)] = ((uint8_t)((v_c >> 0u)));
59621           self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 1u)] = ((uint8_t)((v_c >> 8u)));
59622           self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 2u)] = ((uint8_t)((v_c >> 16u)));
59623           self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 3u)] = ((uint8_t)((v_c >> 24u)));
59624         } else {
59625           {
59626             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(21);
59627             uint32_t t_12;
59628             if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
59629               t_12 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
59630               iop_a_src += 2;
59631             } else {
59632               self->private_data.s_do_decode_image_config[0].scratch = 0;
59633               WUFFS_BASE__COROUTINE_SUSPENSION_POINT(22);
59634               while (true) {
59635                 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
59636                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
59637                   goto suspend;
59638                 }
59639                 uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
59640                 uint32_t num_bits_12 = ((uint32_t)(*scratch >> 56));
59641                 *scratch <<= 8;
59642                 *scratch >>= 8;
59643                 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_12;
59644                 if (num_bits_12 == 8) {
59645                   t_12 = ((uint32_t)(*scratch));
59646                   break;
59647                 }
59648                 num_bits_12 += 8u;
59649                 *scratch |= ((uint64_t)(num_bits_12)) << 56;
59650               }
59651             }
59652             v_c = t_12;
59653           }
59654           v_c5 = (31u & (v_c >> 0u));
59655           self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 0u)] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u))));
59656           v_c5 = (31u & (v_c >> 5u));
59657           self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 1u)] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u))));
59658           v_c5 = (31u & (v_c >> 10u));
59659           self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 2u)] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u))));
59660           self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 3u)] = 255u;
59661         }
59662         v_i += 1u;
59663       }
59664       while (v_i < 256u) {
59665         self->private_data.f_src_palette[((v_i * 4u) + 0u)] = 0u;
59666         self->private_data.f_src_palette[((v_i * 4u) + 1u)] = 0u;
59667         self->private_data.f_src_palette[((v_i * 4u) + 2u)] = 0u;
59668         self->private_data.f_src_palette[((v_i * 4u) + 3u)] = 255u;
59669         v_i += 1u;
59670       }
59671     }
59672     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)));
59673     if (a_dst != NULL) {
59674       wuffs_base__image_config__set(
59675           a_dst,
59676           self->private_impl.f_src_pixfmt,
59677           0u,
59678           self->private_impl.f_width,
59679           self->private_impl.f_height,
59680           self->private_impl.f_frame_config_io_position,
59681           self->private_impl.f_opaque);
59682     }
59683     self->private_impl.f_call_sequence = 32u;
59684 
59685     goto ok;
59686     ok:
59687     self->private_impl.p_do_decode_image_config[0] = 0;
59688     goto exit;
59689   }
59690 
59691   goto suspend;
59692   suspend:
59693   self->private_impl.p_do_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
59694   self->private_data.s_do_decode_image_config[0].v_i = v_i;
59695 
59696   goto exit;
59697   exit:
59698   if (a_src && a_src->data.ptr) {
59699     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
59700   }
59701 
59702   return status;
59703 }
59704 
59705 // -------- func tga.decoder.decode_frame_config
59706 
59707 WUFFS_BASE__GENERATED_C_CODE
59708 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_tga__decoder__decode_frame_config(wuffs_tga__decoder * self,wuffs_base__frame_config * a_dst,wuffs_base__io_buffer * a_src)59709 wuffs_tga__decoder__decode_frame_config(
59710     wuffs_tga__decoder* self,
59711     wuffs_base__frame_config* a_dst,
59712     wuffs_base__io_buffer* a_src) {
59713   if (!self) {
59714     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
59715   }
59716   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
59717     return wuffs_base__make_status(
59718         (self->private_impl.magic == WUFFS_BASE__DISABLED)
59719         ? wuffs_base__error__disabled_by_previous_error
59720         : wuffs_base__error__initialize_not_called);
59721   }
59722   if (!a_src) {
59723     self->private_impl.magic = WUFFS_BASE__DISABLED;
59724     return wuffs_base__make_status(wuffs_base__error__bad_argument);
59725   }
59726   if ((self->private_impl.active_coroutine != 0) &&
59727       (self->private_impl.active_coroutine != 2)) {
59728     self->private_impl.magic = WUFFS_BASE__DISABLED;
59729     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
59730   }
59731   self->private_impl.active_coroutine = 0;
59732   wuffs_base__status status = wuffs_base__make_status(NULL);
59733 
59734   wuffs_base__status v_status = wuffs_base__make_status(NULL);
59735 
59736   uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
59737   switch (coro_susp_point) {
59738     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
59739 
59740     while (true) {
59741       {
59742         wuffs_base__status t_0 = wuffs_tga__decoder__do_decode_frame_config(self, a_dst, a_src);
59743         v_status = t_0;
59744       }
59745       if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
59746         status = wuffs_base__make_status(wuffs_tga__error__truncated_input);
59747         goto exit;
59748       }
59749       status = v_status;
59750       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
59751     }
59752 
59753     ok:
59754     self->private_impl.p_decode_frame_config[0] = 0;
59755     goto exit;
59756   }
59757 
59758   goto suspend;
59759   suspend:
59760   self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
59761   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
59762 
59763   goto exit;
59764   exit:
59765   if (wuffs_base__status__is_error(&status)) {
59766     self->private_impl.magic = WUFFS_BASE__DISABLED;
59767   }
59768   return status;
59769 }
59770 
59771 // -------- func tga.decoder.do_decode_frame_config
59772 
59773 WUFFS_BASE__GENERATED_C_CODE
59774 static wuffs_base__status
wuffs_tga__decoder__do_decode_frame_config(wuffs_tga__decoder * self,wuffs_base__frame_config * a_dst,wuffs_base__io_buffer * a_src)59775 wuffs_tga__decoder__do_decode_frame_config(
59776     wuffs_tga__decoder* self,
59777     wuffs_base__frame_config* a_dst,
59778     wuffs_base__io_buffer* a_src) {
59779   wuffs_base__status status = wuffs_base__make_status(NULL);
59780 
59781   const uint8_t* iop_a_src = NULL;
59782   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
59783   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
59784   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
59785   if (a_src && a_src->data.ptr) {
59786     io0_a_src = a_src->data.ptr;
59787     io1_a_src = io0_a_src + a_src->meta.ri;
59788     iop_a_src = io1_a_src;
59789     io2_a_src = io0_a_src + a_src->meta.wi;
59790   }
59791 
59792   uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config[0];
59793   switch (coro_susp_point) {
59794     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
59795 
59796     if (self->private_impl.f_call_sequence == 32u) {
59797     } else if (self->private_impl.f_call_sequence < 32u) {
59798       if (a_src) {
59799         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
59800       }
59801       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
59802       status = wuffs_tga__decoder__do_decode_image_config(self, NULL, a_src);
59803       if (a_src) {
59804         iop_a_src = a_src->data.ptr + a_src->meta.ri;
59805       }
59806       if (status.repr) {
59807         goto suspend;
59808       }
59809     } else if (self->private_impl.f_call_sequence == 40u) {
59810       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)))) {
59811         status = wuffs_base__make_status(wuffs_base__error__bad_restart);
59812         goto exit;
59813       }
59814     } else if (self->private_impl.f_call_sequence == 64u) {
59815       self->private_impl.f_call_sequence = 96u;
59816       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
59817       goto ok;
59818     } else {
59819       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
59820       goto ok;
59821     }
59822     if (a_dst != NULL) {
59823       wuffs_base__frame_config__set(
59824           a_dst,
59825           wuffs_base__utility__make_rect_ie_u32(
59826           0u,
59827           0u,
59828           self->private_impl.f_width,
59829           self->private_impl.f_height),
59830           ((wuffs_base__flicks)(0u)),
59831           0u,
59832           self->private_impl.f_frame_config_io_position,
59833           0u,
59834           self->private_impl.f_opaque,
59835           false,
59836           4278190080u);
59837     }
59838     self->private_impl.f_call_sequence = 64u;
59839 
59840     ok:
59841     self->private_impl.p_do_decode_frame_config[0] = 0;
59842     goto exit;
59843   }
59844 
59845   goto suspend;
59846   suspend:
59847   self->private_impl.p_do_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
59848 
59849   goto exit;
59850   exit:
59851   if (a_src && a_src->data.ptr) {
59852     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
59853   }
59854 
59855   return status;
59856 }
59857 
59858 // -------- func tga.decoder.decode_frame
59859 
59860 WUFFS_BASE__GENERATED_C_CODE
59861 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_tga__decoder__decode_frame(wuffs_tga__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__pixel_blend a_blend,wuffs_base__slice_u8 a_workbuf,wuffs_base__decode_frame_options * a_opts)59862 wuffs_tga__decoder__decode_frame(
59863     wuffs_tga__decoder* self,
59864     wuffs_base__pixel_buffer* a_dst,
59865     wuffs_base__io_buffer* a_src,
59866     wuffs_base__pixel_blend a_blend,
59867     wuffs_base__slice_u8 a_workbuf,
59868     wuffs_base__decode_frame_options* a_opts) {
59869   if (!self) {
59870     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
59871   }
59872   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
59873     return wuffs_base__make_status(
59874         (self->private_impl.magic == WUFFS_BASE__DISABLED)
59875         ? wuffs_base__error__disabled_by_previous_error
59876         : wuffs_base__error__initialize_not_called);
59877   }
59878   if (!a_dst || !a_src) {
59879     self->private_impl.magic = WUFFS_BASE__DISABLED;
59880     return wuffs_base__make_status(wuffs_base__error__bad_argument);
59881   }
59882   if ((self->private_impl.active_coroutine != 0) &&
59883       (self->private_impl.active_coroutine != 3)) {
59884     self->private_impl.magic = WUFFS_BASE__DISABLED;
59885     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
59886   }
59887   self->private_impl.active_coroutine = 0;
59888   wuffs_base__status status = wuffs_base__make_status(NULL);
59889 
59890   wuffs_base__status v_status = wuffs_base__make_status(NULL);
59891 
59892   uint32_t coro_susp_point = self->private_impl.p_decode_frame[0];
59893   switch (coro_susp_point) {
59894     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
59895 
59896     while (true) {
59897       {
59898         wuffs_base__status t_0 = wuffs_tga__decoder__do_decode_frame(self,
59899             a_dst,
59900             a_src,
59901             a_blend,
59902             a_workbuf,
59903             a_opts);
59904         v_status = t_0;
59905       }
59906       if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
59907         status = wuffs_base__make_status(wuffs_tga__error__truncated_input);
59908         goto exit;
59909       }
59910       status = v_status;
59911       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
59912     }
59913 
59914     ok:
59915     self->private_impl.p_decode_frame[0] = 0;
59916     goto exit;
59917   }
59918 
59919   goto suspend;
59920   suspend:
59921   self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
59922   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
59923 
59924   goto exit;
59925   exit:
59926   if (wuffs_base__status__is_error(&status)) {
59927     self->private_impl.magic = WUFFS_BASE__DISABLED;
59928   }
59929   return status;
59930 }
59931 
59932 // -------- func tga.decoder.do_decode_frame
59933 
59934 WUFFS_BASE__GENERATED_C_CODE
59935 static wuffs_base__status
wuffs_tga__decoder__do_decode_frame(wuffs_tga__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__pixel_blend a_blend,wuffs_base__slice_u8 a_workbuf,wuffs_base__decode_frame_options * a_opts)59936 wuffs_tga__decoder__do_decode_frame(
59937     wuffs_tga__decoder* self,
59938     wuffs_base__pixel_buffer* a_dst,
59939     wuffs_base__io_buffer* a_src,
59940     wuffs_base__pixel_blend a_blend,
59941     wuffs_base__slice_u8 a_workbuf,
59942     wuffs_base__decode_frame_options* a_opts) {
59943   wuffs_base__status status = wuffs_base__make_status(NULL);
59944 
59945   wuffs_base__status v_status = wuffs_base__make_status(NULL);
59946   wuffs_base__pixel_format v_dst_pixfmt = {0};
59947   uint32_t v_dst_bits_per_pixel = 0;
59948   uint64_t v_dst_bytes_per_pixel = 0;
59949   uint32_t v_dst_x = 0;
59950   uint32_t v_dst_y = 0;
59951   wuffs_base__table_u8 v_tab = {0};
59952   wuffs_base__slice_u8 v_dst_palette = {0};
59953   wuffs_base__slice_u8 v_dst = {0};
59954   uint64_t v_dst_start = 0;
59955   wuffs_base__slice_u8 v_src_palette = {0};
59956   uint64_t v_mark = 0;
59957   uint64_t v_num_pixels64 = 0;
59958   uint32_t v_num_pixels32 = 0;
59959   uint32_t v_lit_length = 0;
59960   uint32_t v_run_length = 0;
59961   uint64_t v_num_dst_bytes = 0;
59962   uint32_t v_num_src_bytes = 0;
59963   uint32_t v_c = 0;
59964   uint32_t v_c5 = 0;
59965 
59966   const uint8_t* iop_a_src = NULL;
59967   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
59968   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
59969   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
59970   if (a_src && a_src->data.ptr) {
59971     io0_a_src = a_src->data.ptr;
59972     io1_a_src = io0_a_src + a_src->meta.ri;
59973     iop_a_src = io1_a_src;
59974     io2_a_src = io0_a_src + a_src->meta.wi;
59975   }
59976 
59977   uint32_t coro_susp_point = self->private_impl.p_do_decode_frame[0];
59978   if (coro_susp_point) {
59979     v_dst_bytes_per_pixel = self->private_data.s_do_decode_frame[0].v_dst_bytes_per_pixel;
59980     v_dst_x = self->private_data.s_do_decode_frame[0].v_dst_x;
59981     v_dst_y = self->private_data.s_do_decode_frame[0].v_dst_y;
59982     v_mark = self->private_data.s_do_decode_frame[0].v_mark;
59983     v_num_pixels32 = self->private_data.s_do_decode_frame[0].v_num_pixels32;
59984     v_lit_length = self->private_data.s_do_decode_frame[0].v_lit_length;
59985     v_run_length = self->private_data.s_do_decode_frame[0].v_run_length;
59986     v_num_dst_bytes = self->private_data.s_do_decode_frame[0].v_num_dst_bytes;
59987   }
59988   switch (coro_susp_point) {
59989     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
59990 
59991     if (self->private_impl.f_call_sequence == 64u) {
59992     } else if (self->private_impl.f_call_sequence < 64u) {
59993       if (a_src) {
59994         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
59995       }
59996       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
59997       status = wuffs_tga__decoder__do_decode_frame_config(self, NULL, a_src);
59998       if (a_src) {
59999         iop_a_src = a_src->data.ptr + a_src->meta.ri;
60000       }
60001       if (status.repr) {
60002         goto suspend;
60003       }
60004     } else {
60005       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
60006       goto ok;
60007     }
60008     if (self->private_impl.f_header_color_map_type != 0u) {
60009       v_src_palette = wuffs_base__make_slice_u8(self->private_data.f_src_palette, 1024);
60010     }
60011     v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
60012         wuffs_base__pixel_buffer__pixel_format(a_dst),
60013         wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)),
60014         wuffs_base__utility__make_pixel_format(self->private_impl.f_src_pixfmt),
60015         v_src_palette,
60016         a_blend);
60017     if ( ! wuffs_base__status__is_ok(&v_status)) {
60018       status = v_status;
60019       if (wuffs_base__status__is_error(&status)) {
60020         goto exit;
60021       } else if (wuffs_base__status__is_suspension(&status)) {
60022         status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
60023         goto exit;
60024       }
60025       goto ok;
60026     }
60027     v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
60028     v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
60029     if ((v_dst_bits_per_pixel & 7u) != 0u) {
60030       status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
60031       goto exit;
60032     }
60033     v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8u)));
60034     if ((self->private_impl.f_header_image_descriptor & 32u) == 0u) {
60035       v_dst_y = ((uint32_t)(self->private_impl.f_height - 1u));
60036     }
60037     if ((self->private_impl.f_header_image_type & 8u) == 0u) {
60038       v_lit_length = self->private_impl.f_width;
60039     }
60040     label__resume__continue:;
60041     while (true) {
60042       v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
60043       v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024));
60044       while (v_dst_y < self->private_impl.f_height) {
60045         v_dst = wuffs_base__table_u8__row_u32(v_tab, v_dst_y);
60046         v_dst_start = (((uint64_t)(v_dst_x)) * v_dst_bytes_per_pixel);
60047         if (v_dst_start <= ((uint64_t)(v_dst.len))) {
60048           v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_start);
60049         } else {
60050           v_dst = wuffs_base__utility__empty_slice_u8();
60051         }
60052         while (v_dst_x < self->private_impl.f_width) {
60053           if (self->private_impl.f_src_bytes_per_pixel > 0u) {
60054             if (v_lit_length > 0u) {
60055               v_mark = ((uint64_t)(iop_a_src - io0_a_src));
60056               v_num_pixels64 = (((uint64_t)(io2_a_src - iop_a_src)) / ((uint64_t)(self->private_impl.f_src_bytes_per_pixel)));
60057               v_num_pixels32 = ((uint32_t)(wuffs_base__u64__min(v_num_pixels64, ((uint64_t)(v_lit_length)))));
60058               v_num_dst_bytes = (((uint64_t)(v_num_pixels32)) * v_dst_bytes_per_pixel);
60059               v_num_src_bytes = (v_num_pixels32 * self->private_impl.f_src_bytes_per_pixel);
60060               self->private_data.s_do_decode_frame[0].scratch = v_num_src_bytes;
60061               WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
60062               if (self->private_data.s_do_decode_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
60063                 self->private_data.s_do_decode_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
60064                 iop_a_src = io2_a_src;
60065                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
60066                 goto suspend;
60067               }
60068               iop_a_src += self->private_data.s_do_decode_frame[0].scratch;
60069               wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, wuffs_base__io__since(v_mark, ((uint64_t)(iop_a_src - io0_a_src)), io0_a_src));
60070               if (v_num_dst_bytes <= ((uint64_t)(v_dst.len))) {
60071                 v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_num_dst_bytes);
60072               } else {
60073                 v_dst = wuffs_base__utility__empty_slice_u8();
60074               }
60075               v_dst_x += v_num_pixels32;
60076               v_lit_length = (((uint32_t)(v_lit_length - v_num_pixels32)) & 65535u);
60077               if (v_lit_length > 0u) {
60078                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
60079                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
60080                 goto label__resume__continue;
60081               }
60082             } else if (v_run_length > 0u) {
60083               v_run_length -= 1u;
60084               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));
60085               if (v_dst_bytes_per_pixel <= ((uint64_t)(v_dst.len))) {
60086                 v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_bytes_per_pixel);
60087               }
60088               v_dst_x += 1u;
60089             } else {
60090               if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
60091                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
60092                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
60093                 goto label__resume__continue;
60094               }
60095               if (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) < 128u) {
60096                 v_lit_length = (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) + 1u);
60097                 iop_a_src += 1u;
60098                 if ((v_lit_length + v_dst_x) > self->private_impl.f_width) {
60099                   status = wuffs_base__make_status(wuffs_tga__error__bad_run_length_encoding);
60100                   goto exit;
60101                 }
60102               } else {
60103                 if (self->private_impl.f_src_bytes_per_pixel == 1u) {
60104                   if (((uint64_t)(io2_a_src - iop_a_src)) < 2u) {
60105                     status = wuffs_base__make_status(wuffs_base__suspension__short_read);
60106                     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
60107                     goto label__resume__continue;
60108                   }
60109                   v_run_length = ((((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) & 127u) + 1u);
60110                   iop_a_src += 1u;
60111                   self->private_data.f_scratch[0u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
60112                   iop_a_src += 1u;
60113                 } else if (self->private_impl.f_src_bytes_per_pixel == 3u) {
60114                   if (((uint64_t)(io2_a_src - iop_a_src)) < 4u) {
60115                     status = wuffs_base__make_status(wuffs_base__suspension__short_read);
60116                     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
60117                     goto label__resume__continue;
60118                   }
60119                   v_run_length = ((((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) & 127u) + 1u);
60120                   iop_a_src += 1u;
60121                   self->private_data.f_scratch[0u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
60122                   iop_a_src += 1u;
60123                   self->private_data.f_scratch[1u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
60124                   iop_a_src += 1u;
60125                   self->private_data.f_scratch[2u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
60126                   iop_a_src += 1u;
60127                 } else {
60128                   if (((uint64_t)(io2_a_src - iop_a_src)) < 5u) {
60129                     status = wuffs_base__make_status(wuffs_base__suspension__short_read);
60130                     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7);
60131                     goto label__resume__continue;
60132                   }
60133                   v_run_length = ((((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) & 127u) + 1u);
60134                   iop_a_src += 1u;
60135                   self->private_data.f_scratch[0u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
60136                   iop_a_src += 1u;
60137                   self->private_data.f_scratch[1u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
60138                   iop_a_src += 1u;
60139                   self->private_data.f_scratch[2u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
60140                   iop_a_src += 1u;
60141                   self->private_data.f_scratch[3u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
60142                   iop_a_src += 1u;
60143                 }
60144                 if ((v_run_length + v_dst_x) > self->private_impl.f_width) {
60145                   status = wuffs_base__make_status(wuffs_tga__error__bad_run_length_encoding);
60146                   goto exit;
60147                 }
60148               }
60149             }
60150           } else {
60151             if (v_lit_length > 0u) {
60152               if (((uint64_t)(io2_a_src - iop_a_src)) < 2u) {
60153                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
60154                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8);
60155                 goto label__resume__continue;
60156               }
60157               v_c = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
60158               iop_a_src += 2u;
60159               v_c5 = (31u & (v_c >> 0u));
60160               self->private_data.f_scratch[0u] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u))));
60161               v_c5 = (31u & (v_c >> 5u));
60162               self->private_data.f_scratch[1u] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u))));
60163               v_c5 = (31u & (v_c >> 10u));
60164               self->private_data.f_scratch[2u] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u))));
60165               self->private_data.f_scratch[3u] = 255u;
60166               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));
60167               if (v_dst_bytes_per_pixel <= ((uint64_t)(v_dst.len))) {
60168                 v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_bytes_per_pixel);
60169               }
60170               v_dst_x += 1u;
60171               v_lit_length -= 1u;
60172             } else if (v_run_length > 0u) {
60173               v_run_length -= 1u;
60174               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));
60175               if (v_dst_bytes_per_pixel <= ((uint64_t)(v_dst.len))) {
60176                 v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_bytes_per_pixel);
60177               }
60178               v_dst_x += 1u;
60179             } else {
60180               if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
60181                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
60182                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9);
60183                 goto label__resume__continue;
60184               }
60185               if (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) < 128u) {
60186                 v_lit_length = (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) + 1u);
60187                 iop_a_src += 1u;
60188                 if ((v_lit_length + v_dst_x) > self->private_impl.f_width) {
60189                   status = wuffs_base__make_status(wuffs_tga__error__bad_run_length_encoding);
60190                   goto exit;
60191                 }
60192               } else {
60193                 if (((uint64_t)(io2_a_src - iop_a_src)) < 3u) {
60194                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
60195                   WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10);
60196                   goto label__resume__continue;
60197                 }
60198                 v_run_length = ((((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) & 127u) + 1u);
60199                 iop_a_src += 1u;
60200                 v_c = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
60201                 iop_a_src += 2u;
60202                 v_c5 = (31u & (v_c >> 0u));
60203                 self->private_data.f_scratch[0u] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u))));
60204                 v_c5 = (31u & (v_c >> 5u));
60205                 self->private_data.f_scratch[1u] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u))));
60206                 v_c5 = (31u & (v_c >> 10u));
60207                 self->private_data.f_scratch[2u] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u))));
60208                 self->private_data.f_scratch[3u] = 255u;
60209                 if ((v_run_length + v_dst_x) > self->private_impl.f_width) {
60210                   status = wuffs_base__make_status(wuffs_tga__error__bad_run_length_encoding);
60211                   goto exit;
60212                 }
60213               }
60214             }
60215           }
60216         }
60217         v_dst_x = 0u;
60218         if ((self->private_impl.f_header_image_descriptor & 32u) == 0u) {
60219           v_dst_y -= 1u;
60220         } else {
60221           v_dst_y += 1u;
60222         }
60223         if ((self->private_impl.f_header_image_type & 8u) == 0u) {
60224           v_lit_length = self->private_impl.f_width;
60225         }
60226       }
60227       break;
60228     }
60229     self->private_impl.f_call_sequence = 96u;
60230 
60231     ok:
60232     self->private_impl.p_do_decode_frame[0] = 0;
60233     goto exit;
60234   }
60235 
60236   goto suspend;
60237   suspend:
60238   self->private_impl.p_do_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
60239   self->private_data.s_do_decode_frame[0].v_dst_bytes_per_pixel = v_dst_bytes_per_pixel;
60240   self->private_data.s_do_decode_frame[0].v_dst_x = v_dst_x;
60241   self->private_data.s_do_decode_frame[0].v_dst_y = v_dst_y;
60242   self->private_data.s_do_decode_frame[0].v_mark = v_mark;
60243   self->private_data.s_do_decode_frame[0].v_num_pixels32 = v_num_pixels32;
60244   self->private_data.s_do_decode_frame[0].v_lit_length = v_lit_length;
60245   self->private_data.s_do_decode_frame[0].v_run_length = v_run_length;
60246   self->private_data.s_do_decode_frame[0].v_num_dst_bytes = v_num_dst_bytes;
60247 
60248   goto exit;
60249   exit:
60250   if (a_src && a_src->data.ptr) {
60251     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
60252   }
60253 
60254   return status;
60255 }
60256 
60257 // -------- func tga.decoder.frame_dirty_rect
60258 
60259 WUFFS_BASE__GENERATED_C_CODE
60260 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
wuffs_tga__decoder__frame_dirty_rect(const wuffs_tga__decoder * self)60261 wuffs_tga__decoder__frame_dirty_rect(
60262     const wuffs_tga__decoder* self) {
60263   if (!self) {
60264     return wuffs_base__utility__empty_rect_ie_u32();
60265   }
60266   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
60267       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
60268     return wuffs_base__utility__empty_rect_ie_u32();
60269   }
60270 
60271   return wuffs_base__utility__make_rect_ie_u32(
60272       0u,
60273       0u,
60274       self->private_impl.f_width,
60275       self->private_impl.f_height);
60276 }
60277 
60278 // -------- func tga.decoder.num_animation_loops
60279 
60280 WUFFS_BASE__GENERATED_C_CODE
60281 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_tga__decoder__num_animation_loops(const wuffs_tga__decoder * self)60282 wuffs_tga__decoder__num_animation_loops(
60283     const wuffs_tga__decoder* self) {
60284   if (!self) {
60285     return 0;
60286   }
60287   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
60288       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
60289     return 0;
60290   }
60291 
60292   return 0u;
60293 }
60294 
60295 // -------- func tga.decoder.num_decoded_frame_configs
60296 
60297 WUFFS_BASE__GENERATED_C_CODE
60298 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_tga__decoder__num_decoded_frame_configs(const wuffs_tga__decoder * self)60299 wuffs_tga__decoder__num_decoded_frame_configs(
60300     const wuffs_tga__decoder* self) {
60301   if (!self) {
60302     return 0;
60303   }
60304   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
60305       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
60306     return 0;
60307   }
60308 
60309   if (self->private_impl.f_call_sequence > 32u) {
60310     return 1u;
60311   }
60312   return 0u;
60313 }
60314 
60315 // -------- func tga.decoder.num_decoded_frames
60316 
60317 WUFFS_BASE__GENERATED_C_CODE
60318 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_tga__decoder__num_decoded_frames(const wuffs_tga__decoder * self)60319 wuffs_tga__decoder__num_decoded_frames(
60320     const wuffs_tga__decoder* self) {
60321   if (!self) {
60322     return 0;
60323   }
60324   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
60325       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
60326     return 0;
60327   }
60328 
60329   if (self->private_impl.f_call_sequence > 64u) {
60330     return 1u;
60331   }
60332   return 0u;
60333 }
60334 
60335 // -------- func tga.decoder.restart_frame
60336 
60337 WUFFS_BASE__GENERATED_C_CODE
60338 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_tga__decoder__restart_frame(wuffs_tga__decoder * self,uint64_t a_index,uint64_t a_io_position)60339 wuffs_tga__decoder__restart_frame(
60340     wuffs_tga__decoder* self,
60341     uint64_t a_index,
60342     uint64_t a_io_position) {
60343   if (!self) {
60344     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
60345   }
60346   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
60347     return wuffs_base__make_status(
60348         (self->private_impl.magic == WUFFS_BASE__DISABLED)
60349         ? wuffs_base__error__disabled_by_previous_error
60350         : wuffs_base__error__initialize_not_called);
60351   }
60352 
60353   if (self->private_impl.f_call_sequence < 32u) {
60354     return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
60355   }
60356   if (a_index != 0u) {
60357     return wuffs_base__make_status(wuffs_base__error__bad_argument);
60358   }
60359   self->private_impl.f_call_sequence = 40u;
60360   self->private_impl.f_frame_config_io_position = a_io_position;
60361   return wuffs_base__make_status(NULL);
60362 }
60363 
60364 // -------- func tga.decoder.set_report_metadata
60365 
60366 WUFFS_BASE__GENERATED_C_CODE
60367 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_tga__decoder__set_report_metadata(wuffs_tga__decoder * self,uint32_t a_fourcc,bool a_report)60368 wuffs_tga__decoder__set_report_metadata(
60369     wuffs_tga__decoder* self,
60370     uint32_t a_fourcc,
60371     bool a_report) {
60372   return wuffs_base__make_empty_struct();
60373 }
60374 
60375 // -------- func tga.decoder.tell_me_more
60376 
60377 WUFFS_BASE__GENERATED_C_CODE
60378 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_tga__decoder__tell_me_more(wuffs_tga__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__more_information * a_minfo,wuffs_base__io_buffer * a_src)60379 wuffs_tga__decoder__tell_me_more(
60380     wuffs_tga__decoder* self,
60381     wuffs_base__io_buffer* a_dst,
60382     wuffs_base__more_information* a_minfo,
60383     wuffs_base__io_buffer* a_src) {
60384   if (!self) {
60385     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
60386   }
60387   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
60388     return wuffs_base__make_status(
60389         (self->private_impl.magic == WUFFS_BASE__DISABLED)
60390         ? wuffs_base__error__disabled_by_previous_error
60391         : wuffs_base__error__initialize_not_called);
60392   }
60393   if (!a_dst || !a_src) {
60394     self->private_impl.magic = WUFFS_BASE__DISABLED;
60395     return wuffs_base__make_status(wuffs_base__error__bad_argument);
60396   }
60397   if ((self->private_impl.active_coroutine != 0) &&
60398       (self->private_impl.active_coroutine != 4)) {
60399     self->private_impl.magic = WUFFS_BASE__DISABLED;
60400     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
60401   }
60402   self->private_impl.active_coroutine = 0;
60403   wuffs_base__status status = wuffs_base__make_status(NULL);
60404 
60405   status = wuffs_base__make_status(wuffs_base__error__no_more_information);
60406   goto exit;
60407 
60408   goto ok;
60409   ok:
60410   goto exit;
60411   exit:
60412   if (wuffs_base__status__is_error(&status)) {
60413     self->private_impl.magic = WUFFS_BASE__DISABLED;
60414   }
60415   return status;
60416 }
60417 
60418 // -------- func tga.decoder.history_retain_length
60419 
60420 WUFFS_BASE__GENERATED_C_CODE
60421 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_tga__decoder__history_retain_length(const wuffs_tga__decoder * self)60422 wuffs_tga__decoder__history_retain_length(
60423     const wuffs_tga__decoder* self) {
60424   if (!self) {
60425     return 0;
60426   }
60427   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
60428       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
60429     return 0;
60430   }
60431 
60432   return 0u;
60433 }
60434 
60435 // -------- func tga.decoder.workbuf_len
60436 
60437 WUFFS_BASE__GENERATED_C_CODE
60438 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_tga__decoder__workbuf_len(const wuffs_tga__decoder * self)60439 wuffs_tga__decoder__workbuf_len(
60440     const wuffs_tga__decoder* self) {
60441   if (!self) {
60442     return wuffs_base__utility__empty_range_ii_u64();
60443   }
60444   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
60445       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
60446     return wuffs_base__utility__empty_range_ii_u64();
60447   }
60448 
60449   return wuffs_base__utility__make_range_ii_u64(0u, 0u);
60450 }
60451 
60452 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__TGA)
60453 
60454 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP)
60455 
60456 // ---------------- Status Codes Implementations
60457 
60458 const char wuffs_wbmp__error__bad_header[] = "#wbmp: bad header";
60459 const char wuffs_wbmp__error__truncated_input[] = "#wbmp: truncated input";
60460 
60461 // ---------------- Private Consts
60462 
60463 // ---------------- Private Initializer Prototypes
60464 
60465 // ---------------- Private Function Prototypes
60466 
60467 WUFFS_BASE__GENERATED_C_CODE
60468 static wuffs_base__status
60469 wuffs_wbmp__decoder__do_decode_image_config(
60470     wuffs_wbmp__decoder* self,
60471     wuffs_base__image_config* a_dst,
60472     wuffs_base__io_buffer* a_src);
60473 
60474 WUFFS_BASE__GENERATED_C_CODE
60475 static wuffs_base__status
60476 wuffs_wbmp__decoder__do_decode_frame_config(
60477     wuffs_wbmp__decoder* self,
60478     wuffs_base__frame_config* a_dst,
60479     wuffs_base__io_buffer* a_src);
60480 
60481 WUFFS_BASE__GENERATED_C_CODE
60482 static wuffs_base__status
60483 wuffs_wbmp__decoder__do_decode_frame(
60484     wuffs_wbmp__decoder* self,
60485     wuffs_base__pixel_buffer* a_dst,
60486     wuffs_base__io_buffer* a_src,
60487     wuffs_base__pixel_blend a_blend,
60488     wuffs_base__slice_u8 a_workbuf,
60489     wuffs_base__decode_frame_options* a_opts);
60490 
60491 // ---------------- VTables
60492 
60493 const wuffs_base__image_decoder__func_ptrs
60494 wuffs_wbmp__decoder__func_ptrs_for__wuffs_base__image_decoder = {
60495   (wuffs_base__status(*)(void*,
60496       wuffs_base__pixel_buffer*,
60497       wuffs_base__io_buffer*,
60498       wuffs_base__pixel_blend,
60499       wuffs_base__slice_u8,
60500       wuffs_base__decode_frame_options*))(&wuffs_wbmp__decoder__decode_frame),
60501   (wuffs_base__status(*)(void*,
60502       wuffs_base__frame_config*,
60503       wuffs_base__io_buffer*))(&wuffs_wbmp__decoder__decode_frame_config),
60504   (wuffs_base__status(*)(void*,
60505       wuffs_base__image_config*,
60506       wuffs_base__io_buffer*))(&wuffs_wbmp__decoder__decode_image_config),
60507   (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_wbmp__decoder__frame_dirty_rect),
60508   (uint64_t(*)(const void*,
60509       uint32_t))(&wuffs_wbmp__decoder__get_quirk),
60510   (uint64_t(*)(const void*))(&wuffs_wbmp__decoder__history_retain_length),
60511   (uint32_t(*)(const void*))(&wuffs_wbmp__decoder__num_animation_loops),
60512   (uint64_t(*)(const void*))(&wuffs_wbmp__decoder__num_decoded_frame_configs),
60513   (uint64_t(*)(const void*))(&wuffs_wbmp__decoder__num_decoded_frames),
60514   (wuffs_base__status(*)(void*,
60515       uint64_t,
60516       uint64_t))(&wuffs_wbmp__decoder__restart_frame),
60517   (wuffs_base__status(*)(void*,
60518       uint32_t,
60519       uint64_t))(&wuffs_wbmp__decoder__set_quirk),
60520   (wuffs_base__empty_struct(*)(void*,
60521       uint32_t,
60522       bool))(&wuffs_wbmp__decoder__set_report_metadata),
60523   (wuffs_base__status(*)(void*,
60524       wuffs_base__io_buffer*,
60525       wuffs_base__more_information*,
60526       wuffs_base__io_buffer*))(&wuffs_wbmp__decoder__tell_me_more),
60527   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_wbmp__decoder__workbuf_len),
60528 };
60529 
60530 // ---------------- Initializer Implementations
60531 
60532 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
wuffs_wbmp__decoder__initialize(wuffs_wbmp__decoder * self,size_t sizeof_star_self,uint64_t wuffs_version,uint32_t options)60533 wuffs_wbmp__decoder__initialize(
60534     wuffs_wbmp__decoder* self,
60535     size_t sizeof_star_self,
60536     uint64_t wuffs_version,
60537     uint32_t options){
60538   if (!self) {
60539     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
60540   }
60541   if (sizeof(*self) != sizeof_star_self) {
60542     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
60543   }
60544   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
60545       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
60546     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
60547   }
60548 
60549   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
60550     // The whole point of this if-check is to detect an uninitialized *self.
60551     // We disable the warning on GCC. Clang-5.0 does not have this warning.
60552 #if !defined(__clang__) && defined(__GNUC__)
60553 #pragma GCC diagnostic push
60554 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
60555 #endif
60556     if (self->private_impl.magic != 0) {
60557       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
60558     }
60559 #if !defined(__clang__) && defined(__GNUC__)
60560 #pragma GCC diagnostic pop
60561 #endif
60562   } else {
60563     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
60564       memset(self, 0, sizeof(*self));
60565       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
60566     } else {
60567       memset(&(self->private_impl), 0, sizeof(self->private_impl));
60568     }
60569   }
60570 
60571   self->private_impl.magic = WUFFS_BASE__MAGIC;
60572   self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
60573       wuffs_base__image_decoder__vtable_name;
60574   self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
60575       (const void*)(&wuffs_wbmp__decoder__func_ptrs_for__wuffs_base__image_decoder);
60576   return wuffs_base__make_status(NULL);
60577 }
60578 
60579 wuffs_wbmp__decoder*
wuffs_wbmp__decoder__alloc(void)60580 wuffs_wbmp__decoder__alloc(void) {
60581   wuffs_wbmp__decoder* x =
60582       (wuffs_wbmp__decoder*)(calloc(sizeof(wuffs_wbmp__decoder), 1));
60583   if (!x) {
60584     return NULL;
60585   }
60586   if (wuffs_wbmp__decoder__initialize(
60587       x, sizeof(wuffs_wbmp__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
60588     free(x);
60589     return NULL;
60590   }
60591   return x;
60592 }
60593 
60594 size_t
sizeof__wuffs_wbmp__decoder(void)60595 sizeof__wuffs_wbmp__decoder(void) {
60596   return sizeof(wuffs_wbmp__decoder);
60597 }
60598 
60599 // ---------------- Function Implementations
60600 
60601 // -------- func wbmp.decoder.get_quirk
60602 
60603 WUFFS_BASE__GENERATED_C_CODE
60604 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_wbmp__decoder__get_quirk(const wuffs_wbmp__decoder * self,uint32_t a_key)60605 wuffs_wbmp__decoder__get_quirk(
60606     const wuffs_wbmp__decoder* self,
60607     uint32_t a_key) {
60608   if (!self) {
60609     return 0;
60610   }
60611   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
60612       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
60613     return 0;
60614   }
60615 
60616   return 0u;
60617 }
60618 
60619 // -------- func wbmp.decoder.set_quirk
60620 
60621 WUFFS_BASE__GENERATED_C_CODE
60622 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_wbmp__decoder__set_quirk(wuffs_wbmp__decoder * self,uint32_t a_key,uint64_t a_value)60623 wuffs_wbmp__decoder__set_quirk(
60624     wuffs_wbmp__decoder* self,
60625     uint32_t a_key,
60626     uint64_t a_value) {
60627   if (!self) {
60628     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
60629   }
60630   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
60631     return wuffs_base__make_status(
60632         (self->private_impl.magic == WUFFS_BASE__DISABLED)
60633         ? wuffs_base__error__disabled_by_previous_error
60634         : wuffs_base__error__initialize_not_called);
60635   }
60636 
60637   return wuffs_base__make_status(wuffs_base__error__unsupported_option);
60638 }
60639 
60640 // -------- func wbmp.decoder.decode_image_config
60641 
60642 WUFFS_BASE__GENERATED_C_CODE
60643 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_wbmp__decoder__decode_image_config(wuffs_wbmp__decoder * self,wuffs_base__image_config * a_dst,wuffs_base__io_buffer * a_src)60644 wuffs_wbmp__decoder__decode_image_config(
60645     wuffs_wbmp__decoder* self,
60646     wuffs_base__image_config* a_dst,
60647     wuffs_base__io_buffer* a_src) {
60648   if (!self) {
60649     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
60650   }
60651   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
60652     return wuffs_base__make_status(
60653         (self->private_impl.magic == WUFFS_BASE__DISABLED)
60654         ? wuffs_base__error__disabled_by_previous_error
60655         : wuffs_base__error__initialize_not_called);
60656   }
60657   if (!a_src) {
60658     self->private_impl.magic = WUFFS_BASE__DISABLED;
60659     return wuffs_base__make_status(wuffs_base__error__bad_argument);
60660   }
60661   if ((self->private_impl.active_coroutine != 0) &&
60662       (self->private_impl.active_coroutine != 1)) {
60663     self->private_impl.magic = WUFFS_BASE__DISABLED;
60664     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
60665   }
60666   self->private_impl.active_coroutine = 0;
60667   wuffs_base__status status = wuffs_base__make_status(NULL);
60668 
60669   wuffs_base__status v_status = wuffs_base__make_status(NULL);
60670 
60671   uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
60672   switch (coro_susp_point) {
60673     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
60674 
60675     while (true) {
60676       {
60677         wuffs_base__status t_0 = wuffs_wbmp__decoder__do_decode_image_config(self, a_dst, a_src);
60678         v_status = t_0;
60679       }
60680       if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
60681         status = wuffs_base__make_status(wuffs_wbmp__error__truncated_input);
60682         goto exit;
60683       }
60684       status = v_status;
60685       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
60686     }
60687 
60688     ok:
60689     self->private_impl.p_decode_image_config[0] = 0;
60690     goto exit;
60691   }
60692 
60693   goto suspend;
60694   suspend:
60695   self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
60696   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
60697 
60698   goto exit;
60699   exit:
60700   if (wuffs_base__status__is_error(&status)) {
60701     self->private_impl.magic = WUFFS_BASE__DISABLED;
60702   }
60703   return status;
60704 }
60705 
60706 // -------- func wbmp.decoder.do_decode_image_config
60707 
60708 WUFFS_BASE__GENERATED_C_CODE
60709 static wuffs_base__status
wuffs_wbmp__decoder__do_decode_image_config(wuffs_wbmp__decoder * self,wuffs_base__image_config * a_dst,wuffs_base__io_buffer * a_src)60710 wuffs_wbmp__decoder__do_decode_image_config(
60711     wuffs_wbmp__decoder* self,
60712     wuffs_base__image_config* a_dst,
60713     wuffs_base__io_buffer* a_src) {
60714   wuffs_base__status status = wuffs_base__make_status(NULL);
60715 
60716   uint8_t v_c = 0;
60717   uint32_t v_i = 0;
60718   uint32_t v_p = 0;
60719 
60720   const uint8_t* iop_a_src = NULL;
60721   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
60722   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
60723   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
60724   if (a_src && a_src->data.ptr) {
60725     io0_a_src = a_src->data.ptr;
60726     io1_a_src = io0_a_src + a_src->meta.ri;
60727     iop_a_src = io1_a_src;
60728     io2_a_src = io0_a_src + a_src->meta.wi;
60729   }
60730 
60731   uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config[0];
60732   if (coro_susp_point) {
60733     v_i = self->private_data.s_do_decode_image_config[0].v_i;
60734     v_p = self->private_data.s_do_decode_image_config[0].v_p;
60735   }
60736   switch (coro_susp_point) {
60737     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
60738 
60739     if (self->private_impl.f_call_sequence != 0u) {
60740       status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
60741       goto exit;
60742     }
60743     v_i = 0u;
60744     while (v_i < 2u) {
60745       {
60746         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
60747         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
60748           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
60749           goto suspend;
60750         }
60751         uint8_t t_0 = *iop_a_src++;
60752         v_c = t_0;
60753       }
60754       if (v_c != 0u) {
60755         status = wuffs_base__make_status(wuffs_wbmp__error__bad_header);
60756         goto exit;
60757       }
60758       v_i += 1u;
60759     }
60760     v_i = 0u;
60761     while (v_i < 2u) {
60762       v_p = 0u;
60763       while (true) {
60764         {
60765           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
60766           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
60767             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
60768             goto suspend;
60769           }
60770           uint8_t t_1 = *iop_a_src++;
60771           v_c = t_1;
60772         }
60773         v_p |= ((uint32_t)((v_c & 127u)));
60774         if ((v_c >> 7u) == 0u) {
60775           break;
60776         } else if (v_p > 131071u) {
60777           status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension);
60778           goto exit;
60779         }
60780         v_p <<= 7u;
60781       }
60782       if (v_i == 0u) {
60783         self->private_impl.f_width = v_p;
60784       } else {
60785         self->private_impl.f_height = v_p;
60786       }
60787       v_i += 1u;
60788     }
60789     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)));
60790     if (a_dst != NULL) {
60791       wuffs_base__image_config__set(
60792           a_dst,
60793           2198077448u,
60794           0u,
60795           self->private_impl.f_width,
60796           self->private_impl.f_height,
60797           self->private_impl.f_frame_config_io_position,
60798           true);
60799     }
60800     self->private_impl.f_call_sequence = 32u;
60801 
60802     goto ok;
60803     ok:
60804     self->private_impl.p_do_decode_image_config[0] = 0;
60805     goto exit;
60806   }
60807 
60808   goto suspend;
60809   suspend:
60810   self->private_impl.p_do_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
60811   self->private_data.s_do_decode_image_config[0].v_i = v_i;
60812   self->private_data.s_do_decode_image_config[0].v_p = v_p;
60813 
60814   goto exit;
60815   exit:
60816   if (a_src && a_src->data.ptr) {
60817     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
60818   }
60819 
60820   return status;
60821 }
60822 
60823 // -------- func wbmp.decoder.decode_frame_config
60824 
60825 WUFFS_BASE__GENERATED_C_CODE
60826 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_wbmp__decoder__decode_frame_config(wuffs_wbmp__decoder * self,wuffs_base__frame_config * a_dst,wuffs_base__io_buffer * a_src)60827 wuffs_wbmp__decoder__decode_frame_config(
60828     wuffs_wbmp__decoder* self,
60829     wuffs_base__frame_config* a_dst,
60830     wuffs_base__io_buffer* a_src) {
60831   if (!self) {
60832     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
60833   }
60834   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
60835     return wuffs_base__make_status(
60836         (self->private_impl.magic == WUFFS_BASE__DISABLED)
60837         ? wuffs_base__error__disabled_by_previous_error
60838         : wuffs_base__error__initialize_not_called);
60839   }
60840   if (!a_src) {
60841     self->private_impl.magic = WUFFS_BASE__DISABLED;
60842     return wuffs_base__make_status(wuffs_base__error__bad_argument);
60843   }
60844   if ((self->private_impl.active_coroutine != 0) &&
60845       (self->private_impl.active_coroutine != 2)) {
60846     self->private_impl.magic = WUFFS_BASE__DISABLED;
60847     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
60848   }
60849   self->private_impl.active_coroutine = 0;
60850   wuffs_base__status status = wuffs_base__make_status(NULL);
60851 
60852   wuffs_base__status v_status = wuffs_base__make_status(NULL);
60853 
60854   uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
60855   switch (coro_susp_point) {
60856     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
60857 
60858     while (true) {
60859       {
60860         wuffs_base__status t_0 = wuffs_wbmp__decoder__do_decode_frame_config(self, a_dst, a_src);
60861         v_status = t_0;
60862       }
60863       if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
60864         status = wuffs_base__make_status(wuffs_wbmp__error__truncated_input);
60865         goto exit;
60866       }
60867       status = v_status;
60868       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
60869     }
60870 
60871     ok:
60872     self->private_impl.p_decode_frame_config[0] = 0;
60873     goto exit;
60874   }
60875 
60876   goto suspend;
60877   suspend:
60878   self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
60879   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
60880 
60881   goto exit;
60882   exit:
60883   if (wuffs_base__status__is_error(&status)) {
60884     self->private_impl.magic = WUFFS_BASE__DISABLED;
60885   }
60886   return status;
60887 }
60888 
60889 // -------- func wbmp.decoder.do_decode_frame_config
60890 
60891 WUFFS_BASE__GENERATED_C_CODE
60892 static wuffs_base__status
wuffs_wbmp__decoder__do_decode_frame_config(wuffs_wbmp__decoder * self,wuffs_base__frame_config * a_dst,wuffs_base__io_buffer * a_src)60893 wuffs_wbmp__decoder__do_decode_frame_config(
60894     wuffs_wbmp__decoder* self,
60895     wuffs_base__frame_config* a_dst,
60896     wuffs_base__io_buffer* a_src) {
60897   wuffs_base__status status = wuffs_base__make_status(NULL);
60898 
60899   const uint8_t* iop_a_src = NULL;
60900   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
60901   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
60902   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
60903   if (a_src && a_src->data.ptr) {
60904     io0_a_src = a_src->data.ptr;
60905     io1_a_src = io0_a_src + a_src->meta.ri;
60906     iop_a_src = io1_a_src;
60907     io2_a_src = io0_a_src + a_src->meta.wi;
60908   }
60909 
60910   uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config[0];
60911   switch (coro_susp_point) {
60912     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
60913 
60914     if (self->private_impl.f_call_sequence == 32u) {
60915     } else if (self->private_impl.f_call_sequence < 32u) {
60916       if (a_src) {
60917         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
60918       }
60919       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
60920       status = wuffs_wbmp__decoder__do_decode_image_config(self, NULL, a_src);
60921       if (a_src) {
60922         iop_a_src = a_src->data.ptr + a_src->meta.ri;
60923       }
60924       if (status.repr) {
60925         goto suspend;
60926       }
60927     } else if (self->private_impl.f_call_sequence == 40u) {
60928       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)))) {
60929         status = wuffs_base__make_status(wuffs_base__error__bad_restart);
60930         goto exit;
60931       }
60932     } else if (self->private_impl.f_call_sequence == 64u) {
60933       self->private_impl.f_call_sequence = 96u;
60934       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
60935       goto ok;
60936     } else {
60937       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
60938       goto ok;
60939     }
60940     if (a_dst != NULL) {
60941       wuffs_base__frame_config__set(
60942           a_dst,
60943           wuffs_base__utility__make_rect_ie_u32(
60944           0u,
60945           0u,
60946           self->private_impl.f_width,
60947           self->private_impl.f_height),
60948           ((wuffs_base__flicks)(0u)),
60949           0u,
60950           self->private_impl.f_frame_config_io_position,
60951           0u,
60952           true,
60953           false,
60954           4278190080u);
60955     }
60956     self->private_impl.f_call_sequence = 64u;
60957 
60958     ok:
60959     self->private_impl.p_do_decode_frame_config[0] = 0;
60960     goto exit;
60961   }
60962 
60963   goto suspend;
60964   suspend:
60965   self->private_impl.p_do_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
60966 
60967   goto exit;
60968   exit:
60969   if (a_src && a_src->data.ptr) {
60970     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
60971   }
60972 
60973   return status;
60974 }
60975 
60976 // -------- func wbmp.decoder.decode_frame
60977 
60978 WUFFS_BASE__GENERATED_C_CODE
60979 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_wbmp__decoder__decode_frame(wuffs_wbmp__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__pixel_blend a_blend,wuffs_base__slice_u8 a_workbuf,wuffs_base__decode_frame_options * a_opts)60980 wuffs_wbmp__decoder__decode_frame(
60981     wuffs_wbmp__decoder* self,
60982     wuffs_base__pixel_buffer* a_dst,
60983     wuffs_base__io_buffer* a_src,
60984     wuffs_base__pixel_blend a_blend,
60985     wuffs_base__slice_u8 a_workbuf,
60986     wuffs_base__decode_frame_options* a_opts) {
60987   if (!self) {
60988     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
60989   }
60990   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
60991     return wuffs_base__make_status(
60992         (self->private_impl.magic == WUFFS_BASE__DISABLED)
60993         ? wuffs_base__error__disabled_by_previous_error
60994         : wuffs_base__error__initialize_not_called);
60995   }
60996   if (!a_dst || !a_src) {
60997     self->private_impl.magic = WUFFS_BASE__DISABLED;
60998     return wuffs_base__make_status(wuffs_base__error__bad_argument);
60999   }
61000   if ((self->private_impl.active_coroutine != 0) &&
61001       (self->private_impl.active_coroutine != 3)) {
61002     self->private_impl.magic = WUFFS_BASE__DISABLED;
61003     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
61004   }
61005   self->private_impl.active_coroutine = 0;
61006   wuffs_base__status status = wuffs_base__make_status(NULL);
61007 
61008   wuffs_base__status v_status = wuffs_base__make_status(NULL);
61009 
61010   uint32_t coro_susp_point = self->private_impl.p_decode_frame[0];
61011   switch (coro_susp_point) {
61012     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
61013 
61014     while (true) {
61015       {
61016         wuffs_base__status t_0 = wuffs_wbmp__decoder__do_decode_frame(self,
61017             a_dst,
61018             a_src,
61019             a_blend,
61020             a_workbuf,
61021             a_opts);
61022         v_status = t_0;
61023       }
61024       if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
61025         status = wuffs_base__make_status(wuffs_wbmp__error__truncated_input);
61026         goto exit;
61027       }
61028       status = v_status;
61029       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
61030     }
61031 
61032     ok:
61033     self->private_impl.p_decode_frame[0] = 0;
61034     goto exit;
61035   }
61036 
61037   goto suspend;
61038   suspend:
61039   self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
61040   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
61041 
61042   goto exit;
61043   exit:
61044   if (wuffs_base__status__is_error(&status)) {
61045     self->private_impl.magic = WUFFS_BASE__DISABLED;
61046   }
61047   return status;
61048 }
61049 
61050 // -------- func wbmp.decoder.do_decode_frame
61051 
61052 WUFFS_BASE__GENERATED_C_CODE
61053 static wuffs_base__status
wuffs_wbmp__decoder__do_decode_frame(wuffs_wbmp__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__pixel_blend a_blend,wuffs_base__slice_u8 a_workbuf,wuffs_base__decode_frame_options * a_opts)61054 wuffs_wbmp__decoder__do_decode_frame(
61055     wuffs_wbmp__decoder* self,
61056     wuffs_base__pixel_buffer* a_dst,
61057     wuffs_base__io_buffer* a_src,
61058     wuffs_base__pixel_blend a_blend,
61059     wuffs_base__slice_u8 a_workbuf,
61060     wuffs_base__decode_frame_options* a_opts) {
61061   wuffs_base__status status = wuffs_base__make_status(NULL);
61062 
61063   wuffs_base__status v_status = wuffs_base__make_status(NULL);
61064   wuffs_base__pixel_format v_dst_pixfmt = {0};
61065   uint32_t v_dst_bits_per_pixel = 0;
61066   uint64_t v_dst_bytes_per_pixel = 0;
61067   uint64_t v_dst_x_in_bytes = 0;
61068   uint32_t v_dst_x = 0;
61069   uint32_t v_dst_y = 0;
61070   wuffs_base__table_u8 v_tab = {0};
61071   wuffs_base__slice_u8 v_dst = {0};
61072   uint8_t v_src[1] = {0};
61073   uint8_t v_c = 0;
61074 
61075   const uint8_t* iop_a_src = NULL;
61076   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
61077   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
61078   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
61079   if (a_src && a_src->data.ptr) {
61080     io0_a_src = a_src->data.ptr;
61081     io1_a_src = io0_a_src + a_src->meta.ri;
61082     iop_a_src = io1_a_src;
61083     io2_a_src = io0_a_src + a_src->meta.wi;
61084   }
61085 
61086   uint32_t coro_susp_point = self->private_impl.p_do_decode_frame[0];
61087   if (coro_susp_point) {
61088     v_dst_bytes_per_pixel = self->private_data.s_do_decode_frame[0].v_dst_bytes_per_pixel;
61089     v_dst_x = self->private_data.s_do_decode_frame[0].v_dst_x;
61090     v_dst_y = self->private_data.s_do_decode_frame[0].v_dst_y;
61091     memcpy(v_src, self->private_data.s_do_decode_frame[0].v_src, sizeof(v_src));
61092     v_c = self->private_data.s_do_decode_frame[0].v_c;
61093   }
61094   switch (coro_susp_point) {
61095     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
61096 
61097     if (self->private_impl.f_call_sequence == 64u) {
61098     } else if (self->private_impl.f_call_sequence < 64u) {
61099       if (a_src) {
61100         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
61101       }
61102       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
61103       status = wuffs_wbmp__decoder__do_decode_frame_config(self, NULL, a_src);
61104       if (a_src) {
61105         iop_a_src = a_src->data.ptr + a_src->meta.ri;
61106       }
61107       if (status.repr) {
61108         goto suspend;
61109       }
61110     } else {
61111       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
61112       goto ok;
61113     }
61114     v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
61115         wuffs_base__pixel_buffer__pixel_format(a_dst),
61116         wuffs_base__pixel_buffer__palette(a_dst),
61117         wuffs_base__utility__make_pixel_format(536870920u),
61118         wuffs_base__utility__empty_slice_u8(),
61119         a_blend);
61120     if ( ! wuffs_base__status__is_ok(&v_status)) {
61121       status = v_status;
61122       if (wuffs_base__status__is_error(&status)) {
61123         goto exit;
61124       } else if (wuffs_base__status__is_suspension(&status)) {
61125         status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
61126         goto exit;
61127       }
61128       goto ok;
61129     }
61130     v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
61131     v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
61132     if ((v_dst_bits_per_pixel & 7u) != 0u) {
61133       status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
61134       goto exit;
61135     }
61136     v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8u)));
61137     if (self->private_impl.f_width > 0u) {
61138       v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
61139       while (v_dst_y < self->private_impl.f_height) {
61140         v_dst = wuffs_base__table_u8__row_u32(v_tab, v_dst_y);
61141         v_dst_x = 0u;
61142         while (v_dst_x < self->private_impl.f_width) {
61143           if ((v_dst_x & 7u) == 0u) {
61144             while (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
61145               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
61146               WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
61147               v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
61148               v_dst = wuffs_base__table_u8__row_u32(v_tab, v_dst_y);
61149               v_dst_x_in_bytes = (((uint64_t)(v_dst_x)) * v_dst_bytes_per_pixel);
61150               if (v_dst_x_in_bytes <= ((uint64_t)(v_dst.len))) {
61151                 v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_x_in_bytes);
61152               }
61153             }
61154             v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
61155             iop_a_src += 1u;
61156           }
61157           if ((v_c & 128u) == 0u) {
61158             v_src[0u] = 0u;
61159           } else {
61160             v_src[0u] = 255u;
61161           }
61162           v_c = ((uint8_t)((((uint32_t)(v_c)) << 1u)));
61163           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));
61164           if (v_dst_bytes_per_pixel <= ((uint64_t)(v_dst.len))) {
61165             v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_bytes_per_pixel);
61166           }
61167           v_dst_x += 1u;
61168         }
61169         v_dst_y += 1u;
61170       }
61171     }
61172     self->private_impl.f_call_sequence = 96u;
61173 
61174     ok:
61175     self->private_impl.p_do_decode_frame[0] = 0;
61176     goto exit;
61177   }
61178 
61179   goto suspend;
61180   suspend:
61181   self->private_impl.p_do_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
61182   self->private_data.s_do_decode_frame[0].v_dst_bytes_per_pixel = v_dst_bytes_per_pixel;
61183   self->private_data.s_do_decode_frame[0].v_dst_x = v_dst_x;
61184   self->private_data.s_do_decode_frame[0].v_dst_y = v_dst_y;
61185   memcpy(self->private_data.s_do_decode_frame[0].v_src, v_src, sizeof(v_src));
61186   self->private_data.s_do_decode_frame[0].v_c = v_c;
61187 
61188   goto exit;
61189   exit:
61190   if (a_src && a_src->data.ptr) {
61191     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
61192   }
61193 
61194   return status;
61195 }
61196 
61197 // -------- func wbmp.decoder.frame_dirty_rect
61198 
61199 WUFFS_BASE__GENERATED_C_CODE
61200 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
wuffs_wbmp__decoder__frame_dirty_rect(const wuffs_wbmp__decoder * self)61201 wuffs_wbmp__decoder__frame_dirty_rect(
61202     const wuffs_wbmp__decoder* self) {
61203   if (!self) {
61204     return wuffs_base__utility__empty_rect_ie_u32();
61205   }
61206   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
61207       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
61208     return wuffs_base__utility__empty_rect_ie_u32();
61209   }
61210 
61211   return wuffs_base__utility__make_rect_ie_u32(
61212       0u,
61213       0u,
61214       self->private_impl.f_width,
61215       self->private_impl.f_height);
61216 }
61217 
61218 // -------- func wbmp.decoder.num_animation_loops
61219 
61220 WUFFS_BASE__GENERATED_C_CODE
61221 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_wbmp__decoder__num_animation_loops(const wuffs_wbmp__decoder * self)61222 wuffs_wbmp__decoder__num_animation_loops(
61223     const wuffs_wbmp__decoder* self) {
61224   if (!self) {
61225     return 0;
61226   }
61227   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
61228       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
61229     return 0;
61230   }
61231 
61232   return 0u;
61233 }
61234 
61235 // -------- func wbmp.decoder.num_decoded_frame_configs
61236 
61237 WUFFS_BASE__GENERATED_C_CODE
61238 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_wbmp__decoder__num_decoded_frame_configs(const wuffs_wbmp__decoder * self)61239 wuffs_wbmp__decoder__num_decoded_frame_configs(
61240     const wuffs_wbmp__decoder* self) {
61241   if (!self) {
61242     return 0;
61243   }
61244   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
61245       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
61246     return 0;
61247   }
61248 
61249   if (self->private_impl.f_call_sequence > 32u) {
61250     return 1u;
61251   }
61252   return 0u;
61253 }
61254 
61255 // -------- func wbmp.decoder.num_decoded_frames
61256 
61257 WUFFS_BASE__GENERATED_C_CODE
61258 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_wbmp__decoder__num_decoded_frames(const wuffs_wbmp__decoder * self)61259 wuffs_wbmp__decoder__num_decoded_frames(
61260     const wuffs_wbmp__decoder* self) {
61261   if (!self) {
61262     return 0;
61263   }
61264   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
61265       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
61266     return 0;
61267   }
61268 
61269   if (self->private_impl.f_call_sequence > 64u) {
61270     return 1u;
61271   }
61272   return 0u;
61273 }
61274 
61275 // -------- func wbmp.decoder.restart_frame
61276 
61277 WUFFS_BASE__GENERATED_C_CODE
61278 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_wbmp__decoder__restart_frame(wuffs_wbmp__decoder * self,uint64_t a_index,uint64_t a_io_position)61279 wuffs_wbmp__decoder__restart_frame(
61280     wuffs_wbmp__decoder* self,
61281     uint64_t a_index,
61282     uint64_t a_io_position) {
61283   if (!self) {
61284     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
61285   }
61286   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
61287     return wuffs_base__make_status(
61288         (self->private_impl.magic == WUFFS_BASE__DISABLED)
61289         ? wuffs_base__error__disabled_by_previous_error
61290         : wuffs_base__error__initialize_not_called);
61291   }
61292 
61293   if (self->private_impl.f_call_sequence < 32u) {
61294     return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
61295   }
61296   if (a_index != 0u) {
61297     return wuffs_base__make_status(wuffs_base__error__bad_argument);
61298   }
61299   self->private_impl.f_call_sequence = 40u;
61300   self->private_impl.f_frame_config_io_position = a_io_position;
61301   return wuffs_base__make_status(NULL);
61302 }
61303 
61304 // -------- func wbmp.decoder.set_report_metadata
61305 
61306 WUFFS_BASE__GENERATED_C_CODE
61307 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_wbmp__decoder__set_report_metadata(wuffs_wbmp__decoder * self,uint32_t a_fourcc,bool a_report)61308 wuffs_wbmp__decoder__set_report_metadata(
61309     wuffs_wbmp__decoder* self,
61310     uint32_t a_fourcc,
61311     bool a_report) {
61312   return wuffs_base__make_empty_struct();
61313 }
61314 
61315 // -------- func wbmp.decoder.tell_me_more
61316 
61317 WUFFS_BASE__GENERATED_C_CODE
61318 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_wbmp__decoder__tell_me_more(wuffs_wbmp__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__more_information * a_minfo,wuffs_base__io_buffer * a_src)61319 wuffs_wbmp__decoder__tell_me_more(
61320     wuffs_wbmp__decoder* self,
61321     wuffs_base__io_buffer* a_dst,
61322     wuffs_base__more_information* a_minfo,
61323     wuffs_base__io_buffer* a_src) {
61324   if (!self) {
61325     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
61326   }
61327   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
61328     return wuffs_base__make_status(
61329         (self->private_impl.magic == WUFFS_BASE__DISABLED)
61330         ? wuffs_base__error__disabled_by_previous_error
61331         : wuffs_base__error__initialize_not_called);
61332   }
61333   if (!a_dst || !a_src) {
61334     self->private_impl.magic = WUFFS_BASE__DISABLED;
61335     return wuffs_base__make_status(wuffs_base__error__bad_argument);
61336   }
61337   if ((self->private_impl.active_coroutine != 0) &&
61338       (self->private_impl.active_coroutine != 4)) {
61339     self->private_impl.magic = WUFFS_BASE__DISABLED;
61340     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
61341   }
61342   self->private_impl.active_coroutine = 0;
61343   wuffs_base__status status = wuffs_base__make_status(NULL);
61344 
61345   status = wuffs_base__make_status(wuffs_base__error__no_more_information);
61346   goto exit;
61347 
61348   goto ok;
61349   ok:
61350   goto exit;
61351   exit:
61352   if (wuffs_base__status__is_error(&status)) {
61353     self->private_impl.magic = WUFFS_BASE__DISABLED;
61354   }
61355   return status;
61356 }
61357 
61358 // -------- func wbmp.decoder.history_retain_length
61359 
61360 WUFFS_BASE__GENERATED_C_CODE
61361 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_wbmp__decoder__history_retain_length(const wuffs_wbmp__decoder * self)61362 wuffs_wbmp__decoder__history_retain_length(
61363     const wuffs_wbmp__decoder* self) {
61364   if (!self) {
61365     return 0;
61366   }
61367   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
61368       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
61369     return 0;
61370   }
61371 
61372   return 0u;
61373 }
61374 
61375 // -------- func wbmp.decoder.workbuf_len
61376 
61377 WUFFS_BASE__GENERATED_C_CODE
61378 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_wbmp__decoder__workbuf_len(const wuffs_wbmp__decoder * self)61379 wuffs_wbmp__decoder__workbuf_len(
61380     const wuffs_wbmp__decoder* self) {
61381   if (!self) {
61382     return wuffs_base__utility__empty_range_ii_u64();
61383   }
61384   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
61385       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
61386     return wuffs_base__utility__empty_range_ii_u64();
61387   }
61388 
61389   return wuffs_base__utility__make_range_ii_u64(0u, 0u);
61390 }
61391 
61392 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP)
61393 
61394 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH32)
61395 
61396 // ---------------- Status Codes Implementations
61397 
61398 // ---------------- Private Consts
61399 
61400 #define WUFFS_XXHASH32__XXH_PRIME32_1 2654435761
61401 
61402 #define WUFFS_XXHASH32__XXH_PRIME32_2 2246822519
61403 
61404 #define WUFFS_XXHASH32__XXH_PRIME32_3 3266489917
61405 
61406 #define WUFFS_XXHASH32__XXH_PRIME32_4 668265263
61407 
61408 #define WUFFS_XXHASH32__XXH_PRIME32_5 374761393
61409 
61410 #define WUFFS_XXHASH32__INITIAL_V0 606290984
61411 
61412 #define WUFFS_XXHASH32__INITIAL_V1 2246822519
61413 
61414 #define WUFFS_XXHASH32__INITIAL_V2 0
61415 
61416 #define WUFFS_XXHASH32__INITIAL_V3 1640531535
61417 
61418 // ---------------- Private Initializer Prototypes
61419 
61420 // ---------------- Private Function Prototypes
61421 
61422 WUFFS_BASE__GENERATED_C_CODE
61423 static wuffs_base__empty_struct
61424 wuffs_xxhash32__hasher__up(
61425     wuffs_xxhash32__hasher* self,
61426     wuffs_base__slice_u8 a_x);
61427 
61428 // ---------------- VTables
61429 
61430 const wuffs_base__hasher_u32__func_ptrs
61431 wuffs_xxhash32__hasher__func_ptrs_for__wuffs_base__hasher_u32 = {
61432   (uint32_t(*)(const void*))(&wuffs_xxhash32__hasher__checksum_u32),
61433   (uint64_t(*)(const void*,
61434       uint32_t))(&wuffs_xxhash32__hasher__get_quirk),
61435   (wuffs_base__status(*)(void*,
61436       uint32_t,
61437       uint64_t))(&wuffs_xxhash32__hasher__set_quirk),
61438   (wuffs_base__empty_struct(*)(void*,
61439       wuffs_base__slice_u8))(&wuffs_xxhash32__hasher__update),
61440   (uint32_t(*)(void*,
61441       wuffs_base__slice_u8))(&wuffs_xxhash32__hasher__update_u32),
61442 };
61443 
61444 // ---------------- Initializer Implementations
61445 
61446 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
wuffs_xxhash32__hasher__initialize(wuffs_xxhash32__hasher * self,size_t sizeof_star_self,uint64_t wuffs_version,uint32_t options)61447 wuffs_xxhash32__hasher__initialize(
61448     wuffs_xxhash32__hasher* self,
61449     size_t sizeof_star_self,
61450     uint64_t wuffs_version,
61451     uint32_t options){
61452   if (!self) {
61453     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
61454   }
61455   if (sizeof(*self) != sizeof_star_self) {
61456     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
61457   }
61458   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
61459       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
61460     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
61461   }
61462 
61463   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
61464     // The whole point of this if-check is to detect an uninitialized *self.
61465     // We disable the warning on GCC. Clang-5.0 does not have this warning.
61466 #if !defined(__clang__) && defined(__GNUC__)
61467 #pragma GCC diagnostic push
61468 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
61469 #endif
61470     if (self->private_impl.magic != 0) {
61471       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
61472     }
61473 #if !defined(__clang__) && defined(__GNUC__)
61474 #pragma GCC diagnostic pop
61475 #endif
61476   } else {
61477     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
61478       memset(self, 0, sizeof(*self));
61479       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
61480     } else {
61481       memset(&(self->private_impl), 0, sizeof(self->private_impl));
61482     }
61483   }
61484 
61485   self->private_impl.magic = WUFFS_BASE__MAGIC;
61486   self->private_impl.vtable_for__wuffs_base__hasher_u32.vtable_name =
61487       wuffs_base__hasher_u32__vtable_name;
61488   self->private_impl.vtable_for__wuffs_base__hasher_u32.function_pointers =
61489       (const void*)(&wuffs_xxhash32__hasher__func_ptrs_for__wuffs_base__hasher_u32);
61490   return wuffs_base__make_status(NULL);
61491 }
61492 
61493 wuffs_xxhash32__hasher*
wuffs_xxhash32__hasher__alloc(void)61494 wuffs_xxhash32__hasher__alloc(void) {
61495   wuffs_xxhash32__hasher* x =
61496       (wuffs_xxhash32__hasher*)(calloc(sizeof(wuffs_xxhash32__hasher), 1));
61497   if (!x) {
61498     return NULL;
61499   }
61500   if (wuffs_xxhash32__hasher__initialize(
61501       x, sizeof(wuffs_xxhash32__hasher), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
61502     free(x);
61503     return NULL;
61504   }
61505   return x;
61506 }
61507 
61508 size_t
sizeof__wuffs_xxhash32__hasher(void)61509 sizeof__wuffs_xxhash32__hasher(void) {
61510   return sizeof(wuffs_xxhash32__hasher);
61511 }
61512 
61513 // ---------------- Function Implementations
61514 
61515 // -------- func xxhash32.hasher.get_quirk
61516 
61517 WUFFS_BASE__GENERATED_C_CODE
61518 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_xxhash32__hasher__get_quirk(const wuffs_xxhash32__hasher * self,uint32_t a_key)61519 wuffs_xxhash32__hasher__get_quirk(
61520     const wuffs_xxhash32__hasher* self,
61521     uint32_t a_key) {
61522   if (!self) {
61523     return 0;
61524   }
61525   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
61526       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
61527     return 0;
61528   }
61529 
61530   return 0u;
61531 }
61532 
61533 // -------- func xxhash32.hasher.set_quirk
61534 
61535 WUFFS_BASE__GENERATED_C_CODE
61536 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_xxhash32__hasher__set_quirk(wuffs_xxhash32__hasher * self,uint32_t a_key,uint64_t a_value)61537 wuffs_xxhash32__hasher__set_quirk(
61538     wuffs_xxhash32__hasher* self,
61539     uint32_t a_key,
61540     uint64_t a_value) {
61541   if (!self) {
61542     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
61543   }
61544   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
61545     return wuffs_base__make_status(
61546         (self->private_impl.magic == WUFFS_BASE__DISABLED)
61547         ? wuffs_base__error__disabled_by_previous_error
61548         : wuffs_base__error__initialize_not_called);
61549   }
61550 
61551   return wuffs_base__make_status(wuffs_base__error__unsupported_option);
61552 }
61553 
61554 // -------- func xxhash32.hasher.update
61555 
61556 WUFFS_BASE__GENERATED_C_CODE
61557 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_xxhash32__hasher__update(wuffs_xxhash32__hasher * self,wuffs_base__slice_u8 a_x)61558 wuffs_xxhash32__hasher__update(
61559     wuffs_xxhash32__hasher* self,
61560     wuffs_base__slice_u8 a_x) {
61561   if (!self) {
61562     return wuffs_base__make_empty_struct();
61563   }
61564   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
61565     return wuffs_base__make_empty_struct();
61566   }
61567 
61568   wuffs_base__slice_u8 v_remaining = {0};
61569 
61570   if ((self->private_impl.f_length_modulo_u32 == 0u) &&  ! self->private_impl.f_length_overflows_u32) {
61571     self->private_impl.f_v0 = 606290984u;
61572     self->private_impl.f_v1 = 2246822519u;
61573     self->private_impl.f_v2 = 0u;
61574     self->private_impl.f_v3 = 1640531535u;
61575   }
61576   while (((uint64_t)(a_x.len)) > 0u) {
61577     v_remaining = wuffs_base__slice_u8__subslice_j(a_x, 0u);
61578     if (((uint64_t)(a_x.len)) > 16777216u) {
61579       v_remaining = wuffs_base__slice_u8__subslice_i(a_x, 16777216u);
61580       a_x = wuffs_base__slice_u8__subslice_j(a_x, 16777216u);
61581     }
61582     wuffs_xxhash32__hasher__up(self, a_x);
61583     a_x = v_remaining;
61584   }
61585   return wuffs_base__make_empty_struct();
61586 }
61587 
61588 // -------- func xxhash32.hasher.update_u32
61589 
61590 WUFFS_BASE__GENERATED_C_CODE
61591 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_xxhash32__hasher__update_u32(wuffs_xxhash32__hasher * self,wuffs_base__slice_u8 a_x)61592 wuffs_xxhash32__hasher__update_u32(
61593     wuffs_xxhash32__hasher* self,
61594     wuffs_base__slice_u8 a_x) {
61595   if (!self) {
61596     return 0;
61597   }
61598   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
61599     return 0;
61600   }
61601 
61602   wuffs_xxhash32__hasher__update(self, a_x);
61603   return wuffs_xxhash32__hasher__checksum_u32(self);
61604 }
61605 
61606 // -------- func xxhash32.hasher.up
61607 
61608 WUFFS_BASE__GENERATED_C_CODE
61609 static wuffs_base__empty_struct
wuffs_xxhash32__hasher__up(wuffs_xxhash32__hasher * self,wuffs_base__slice_u8 a_x)61610 wuffs_xxhash32__hasher__up(
61611     wuffs_xxhash32__hasher* self,
61612     wuffs_base__slice_u8 a_x) {
61613   uint32_t v_new_lmu = 0;
61614   uint32_t v_buf_u32 = 0;
61615   uint32_t v_buf_len = 0;
61616   uint32_t v_v0 = 0;
61617   uint32_t v_v1 = 0;
61618   uint32_t v_v2 = 0;
61619   uint32_t v_v3 = 0;
61620   wuffs_base__slice_u8 v_p = {0};
61621 
61622   v_new_lmu = ((uint32_t)(self->private_impl.f_length_modulo_u32 + ((uint32_t)(((uint64_t)(a_x.len))))));
61623   self->private_impl.f_length_overflows_u32 = ((v_new_lmu < self->private_impl.f_length_modulo_u32) || self->private_impl.f_length_overflows_u32);
61624   self->private_impl.f_length_modulo_u32 = v_new_lmu;
61625   while (true) {
61626     if (self->private_impl.f_buf_len >= 16u) {
61627       v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[0u])) |
61628           (((uint32_t)(self->private_impl.f_buf_data[1u])) << 8u) |
61629           (((uint32_t)(self->private_impl.f_buf_data[2u])) << 16u) |
61630           (((uint32_t)(self->private_impl.f_buf_data[3u])) << 24u));
61631       v_v0 = ((uint32_t)(self->private_impl.f_v0 + ((uint32_t)(v_buf_u32 * 2246822519u))));
61632       v_v0 = (((uint32_t)(v_v0 << 13u)) | (v_v0 >> 19u));
61633       self->private_impl.f_v0 = ((uint32_t)(v_v0 * 2654435761u));
61634       v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[4u])) |
61635           (((uint32_t)(self->private_impl.f_buf_data[5u])) << 8u) |
61636           (((uint32_t)(self->private_impl.f_buf_data[6u])) << 16u) |
61637           (((uint32_t)(self->private_impl.f_buf_data[7u])) << 24u));
61638       v_v1 = ((uint32_t)(self->private_impl.f_v1 + ((uint32_t)(v_buf_u32 * 2246822519u))));
61639       v_v1 = (((uint32_t)(v_v1 << 13u)) | (v_v1 >> 19u));
61640       self->private_impl.f_v1 = ((uint32_t)(v_v1 * 2654435761u));
61641       v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[8u])) |
61642           (((uint32_t)(self->private_impl.f_buf_data[9u])) << 8u) |
61643           (((uint32_t)(self->private_impl.f_buf_data[10u])) << 16u) |
61644           (((uint32_t)(self->private_impl.f_buf_data[11u])) << 24u));
61645       v_v2 = ((uint32_t)(self->private_impl.f_v2 + ((uint32_t)(v_buf_u32 * 2246822519u))));
61646       v_v2 = (((uint32_t)(v_v2 << 13u)) | (v_v2 >> 19u));
61647       self->private_impl.f_v2 = ((uint32_t)(v_v2 * 2654435761u));
61648       v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[12u])) |
61649           (((uint32_t)(self->private_impl.f_buf_data[13u])) << 8u) |
61650           (((uint32_t)(self->private_impl.f_buf_data[14u])) << 16u) |
61651           (((uint32_t)(self->private_impl.f_buf_data[15u])) << 24u));
61652       v_v3 = ((uint32_t)(self->private_impl.f_v3 + ((uint32_t)(v_buf_u32 * 2246822519u))));
61653       v_v3 = (((uint32_t)(v_v3 << 13u)) | (v_v3 >> 19u));
61654       self->private_impl.f_v3 = ((uint32_t)(v_v3 * 2654435761u));
61655       self->private_impl.f_buf_len = 0u;
61656       break;
61657     }
61658     if (((uint64_t)(a_x.len)) <= 0u) {
61659       return wuffs_base__make_empty_struct();
61660     }
61661     self->private_impl.f_buf_data[self->private_impl.f_buf_len] = a_x.ptr[0u];
61662 #if defined(__GNUC__)
61663 #pragma GCC diagnostic push
61664 #pragma GCC diagnostic ignored "-Wconversion"
61665 #endif
61666     self->private_impl.f_buf_len += 1u;
61667 #if defined(__GNUC__)
61668 #pragma GCC diagnostic pop
61669 #endif
61670     a_x = wuffs_base__slice_u8__subslice_i(a_x, 1u);
61671   }
61672   v_buf_len = ((uint32_t)((self->private_impl.f_buf_len & 15u)));
61673   v_v0 = self->private_impl.f_v0;
61674   v_v1 = self->private_impl.f_v1;
61675   v_v2 = self->private_impl.f_v2;
61676   v_v3 = self->private_impl.f_v3;
61677   {
61678     wuffs_base__slice_u8 i_slice_p = a_x;
61679     v_p.ptr = i_slice_p.ptr;
61680     v_p.len = 16;
61681     uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 16) * 16);
61682     while (v_p.ptr < i_end0_p) {
61683       v_buf_u32 = (((uint32_t)(v_p.ptr[0u])) |
61684           (((uint32_t)(v_p.ptr[1u])) << 8u) |
61685           (((uint32_t)(v_p.ptr[2u])) << 16u) |
61686           (((uint32_t)(v_p.ptr[3u])) << 24u));
61687       v_v0 = ((uint32_t)(v_v0 + ((uint32_t)(v_buf_u32 * 2246822519u))));
61688       v_v0 = (((uint32_t)(v_v0 << 13u)) | (v_v0 >> 19u));
61689       v_v0 = ((uint32_t)(v_v0 * 2654435761u));
61690       v_buf_u32 = (((uint32_t)(v_p.ptr[4u])) |
61691           (((uint32_t)(v_p.ptr[5u])) << 8u) |
61692           (((uint32_t)(v_p.ptr[6u])) << 16u) |
61693           (((uint32_t)(v_p.ptr[7u])) << 24u));
61694       v_v1 = ((uint32_t)(v_v1 + ((uint32_t)(v_buf_u32 * 2246822519u))));
61695       v_v1 = (((uint32_t)(v_v1 << 13u)) | (v_v1 >> 19u));
61696       v_v1 = ((uint32_t)(v_v1 * 2654435761u));
61697       v_buf_u32 = (((uint32_t)(v_p.ptr[8u])) |
61698           (((uint32_t)(v_p.ptr[9u])) << 8u) |
61699           (((uint32_t)(v_p.ptr[10u])) << 16u) |
61700           (((uint32_t)(v_p.ptr[11u])) << 24u));
61701       v_v2 = ((uint32_t)(v_v2 + ((uint32_t)(v_buf_u32 * 2246822519u))));
61702       v_v2 = (((uint32_t)(v_v2 << 13u)) | (v_v2 >> 19u));
61703       v_v2 = ((uint32_t)(v_v2 * 2654435761u));
61704       v_buf_u32 = (((uint32_t)(v_p.ptr[12u])) |
61705           (((uint32_t)(v_p.ptr[13u])) << 8u) |
61706           (((uint32_t)(v_p.ptr[14u])) << 16u) |
61707           (((uint32_t)(v_p.ptr[15u])) << 24u));
61708       v_v3 = ((uint32_t)(v_v3 + ((uint32_t)(v_buf_u32 * 2246822519u))));
61709       v_v3 = (((uint32_t)(v_v3 << 13u)) | (v_v3 >> 19u));
61710       v_v3 = ((uint32_t)(v_v3 * 2654435761u));
61711       v_p.ptr += 16;
61712     }
61713     v_p.len = 1;
61714     uint8_t* i_end1_p = i_slice_p.ptr + i_slice_p.len;
61715     while (v_p.ptr < i_end1_p) {
61716       self->private_impl.f_buf_data[v_buf_len] = v_p.ptr[0u];
61717       v_buf_len = ((v_buf_len + 1u) & 15u);
61718       v_p.ptr += 1;
61719     }
61720     v_p.len = 0;
61721   }
61722   self->private_impl.f_buf_len = ((uint8_t)(v_buf_len));
61723   self->private_impl.f_v0 = v_v0;
61724   self->private_impl.f_v1 = v_v1;
61725   self->private_impl.f_v2 = v_v2;
61726   self->private_impl.f_v3 = v_v3;
61727   return wuffs_base__make_empty_struct();
61728 }
61729 
61730 // -------- func xxhash32.hasher.checksum_u32
61731 
61732 WUFFS_BASE__GENERATED_C_CODE
61733 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_xxhash32__hasher__checksum_u32(const wuffs_xxhash32__hasher * self)61734 wuffs_xxhash32__hasher__checksum_u32(
61735     const wuffs_xxhash32__hasher* self) {
61736   if (!self) {
61737     return 0;
61738   }
61739   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
61740       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
61741     return 0;
61742   }
61743 
61744   uint32_t v_ret = 0;
61745   uint32_t v_i = 0;
61746   uint32_t v_n = 0;
61747   uint32_t v_buf_u32 = 0;
61748 
61749   if ((self->private_impl.f_length_modulo_u32 >= 16u) || self->private_impl.f_length_overflows_u32) {
61750     v_ret += (((uint32_t)(self->private_impl.f_v0 << 1u)) | (self->private_impl.f_v0 >> 31u));
61751     v_ret += (((uint32_t)(self->private_impl.f_v1 << 7u)) | (self->private_impl.f_v1 >> 25u));
61752     v_ret += (((uint32_t)(self->private_impl.f_v2 << 12u)) | (self->private_impl.f_v2 >> 20u));
61753     v_ret += (((uint32_t)(self->private_impl.f_v3 << 18u)) | (self->private_impl.f_v3 >> 14u));
61754     v_ret += self->private_impl.f_length_modulo_u32;
61755   } else {
61756     v_ret += 374761393u;
61757     v_ret += self->private_impl.f_length_modulo_u32;
61758   }
61759   v_n = 16u;
61760   v_n = wuffs_base__u32__min(v_n, ((uint32_t)(self->private_impl.f_buf_len)));
61761   if (4u <= v_n) {
61762     v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[0u])) |
61763         (((uint32_t)(self->private_impl.f_buf_data[1u])) << 8u) |
61764         (((uint32_t)(self->private_impl.f_buf_data[2u])) << 16u) |
61765         (((uint32_t)(self->private_impl.f_buf_data[3u])) << 24u));
61766     v_ret += ((uint32_t)(v_buf_u32 * 3266489917u));
61767     v_ret = (((uint32_t)(v_ret << 17u)) | (v_ret >> 15u));
61768     v_ret *= 668265263u;
61769     v_i = 4u;
61770   }
61771   if (8u <= v_n) {
61772     v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[4u])) |
61773         (((uint32_t)(self->private_impl.f_buf_data[5u])) << 8u) |
61774         (((uint32_t)(self->private_impl.f_buf_data[6u])) << 16u) |
61775         (((uint32_t)(self->private_impl.f_buf_data[7u])) << 24u));
61776     v_ret += ((uint32_t)(v_buf_u32 * 3266489917u));
61777     v_ret = (((uint32_t)(v_ret << 17u)) | (v_ret >> 15u));
61778     v_ret *= 668265263u;
61779     v_i = 8u;
61780   }
61781   if (12u <= v_n) {
61782     v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[8u])) |
61783         (((uint32_t)(self->private_impl.f_buf_data[9u])) << 8u) |
61784         (((uint32_t)(self->private_impl.f_buf_data[10u])) << 16u) |
61785         (((uint32_t)(self->private_impl.f_buf_data[11u])) << 24u));
61786     v_ret += ((uint32_t)(v_buf_u32 * 3266489917u));
61787     v_ret = (((uint32_t)(v_ret << 17u)) | (v_ret >> 15u));
61788     v_ret *= 668265263u;
61789     v_i = 12u;
61790   }
61791   while (v_i < v_n) {
61792     v_ret += ((uint32_t)(((uint32_t)(self->private_impl.f_buf_data[v_i])) * 374761393u));
61793     v_ret = (((uint32_t)(v_ret << 11u)) | (v_ret >> 21u));
61794     v_ret *= 2654435761u;
61795     v_i += 1u;
61796   }
61797   v_ret ^= (v_ret >> 15u);
61798   v_ret *= 2246822519u;
61799   v_ret ^= (v_ret >> 13u);
61800   v_ret *= 3266489917u;
61801   v_ret ^= (v_ret >> 16u);
61802   return v_ret;
61803 }
61804 
61805 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH32)
61806 
61807 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH64)
61808 
61809 // ---------------- Status Codes Implementations
61810 
61811 // ---------------- Private Consts
61812 
61813 #define WUFFS_XXHASH64__XXH_PRIME64_1 11400714785074694791
61814 
61815 #define WUFFS_XXHASH64__XXH_PRIME64_2 14029467366897019727
61816 
61817 #define WUFFS_XXHASH64__XXH_PRIME64_3 1609587929392839161
61818 
61819 #define WUFFS_XXHASH64__XXH_PRIME64_4 9650029242287828579
61820 
61821 #define WUFFS_XXHASH64__XXH_PRIME64_5 2870177450012600261
61822 
61823 #define WUFFS_XXHASH64__INITIAL_V0 6983438078262162902
61824 
61825 #define WUFFS_XXHASH64__INITIAL_V1 14029467366897019727
61826 
61827 #define WUFFS_XXHASH64__INITIAL_V2 0
61828 
61829 #define WUFFS_XXHASH64__INITIAL_V3 7046029288634856825
61830 
61831 // ---------------- Private Initializer Prototypes
61832 
61833 // ---------------- Private Function Prototypes
61834 
61835 WUFFS_BASE__GENERATED_C_CODE
61836 static wuffs_base__empty_struct
61837 wuffs_xxhash64__hasher__up(
61838     wuffs_xxhash64__hasher* self,
61839     wuffs_base__slice_u8 a_x);
61840 
61841 // ---------------- VTables
61842 
61843 const wuffs_base__hasher_u64__func_ptrs
61844 wuffs_xxhash64__hasher__func_ptrs_for__wuffs_base__hasher_u64 = {
61845   (uint64_t(*)(const void*))(&wuffs_xxhash64__hasher__checksum_u64),
61846   (uint64_t(*)(const void*,
61847       uint32_t))(&wuffs_xxhash64__hasher__get_quirk),
61848   (wuffs_base__status(*)(void*,
61849       uint32_t,
61850       uint64_t))(&wuffs_xxhash64__hasher__set_quirk),
61851   (wuffs_base__empty_struct(*)(void*,
61852       wuffs_base__slice_u8))(&wuffs_xxhash64__hasher__update),
61853   (uint64_t(*)(void*,
61854       wuffs_base__slice_u8))(&wuffs_xxhash64__hasher__update_u64),
61855 };
61856 
61857 // ---------------- Initializer Implementations
61858 
61859 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
wuffs_xxhash64__hasher__initialize(wuffs_xxhash64__hasher * self,size_t sizeof_star_self,uint64_t wuffs_version,uint32_t options)61860 wuffs_xxhash64__hasher__initialize(
61861     wuffs_xxhash64__hasher* self,
61862     size_t sizeof_star_self,
61863     uint64_t wuffs_version,
61864     uint32_t options){
61865   if (!self) {
61866     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
61867   }
61868   if (sizeof(*self) != sizeof_star_self) {
61869     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
61870   }
61871   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
61872       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
61873     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
61874   }
61875 
61876   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
61877     // The whole point of this if-check is to detect an uninitialized *self.
61878     // We disable the warning on GCC. Clang-5.0 does not have this warning.
61879 #if !defined(__clang__) && defined(__GNUC__)
61880 #pragma GCC diagnostic push
61881 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
61882 #endif
61883     if (self->private_impl.magic != 0) {
61884       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
61885     }
61886 #if !defined(__clang__) && defined(__GNUC__)
61887 #pragma GCC diagnostic pop
61888 #endif
61889   } else {
61890     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
61891       memset(self, 0, sizeof(*self));
61892       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
61893     } else {
61894       memset(&(self->private_impl), 0, sizeof(self->private_impl));
61895     }
61896   }
61897 
61898   self->private_impl.magic = WUFFS_BASE__MAGIC;
61899   self->private_impl.vtable_for__wuffs_base__hasher_u64.vtable_name =
61900       wuffs_base__hasher_u64__vtable_name;
61901   self->private_impl.vtable_for__wuffs_base__hasher_u64.function_pointers =
61902       (const void*)(&wuffs_xxhash64__hasher__func_ptrs_for__wuffs_base__hasher_u64);
61903   return wuffs_base__make_status(NULL);
61904 }
61905 
61906 wuffs_xxhash64__hasher*
wuffs_xxhash64__hasher__alloc(void)61907 wuffs_xxhash64__hasher__alloc(void) {
61908   wuffs_xxhash64__hasher* x =
61909       (wuffs_xxhash64__hasher*)(calloc(sizeof(wuffs_xxhash64__hasher), 1));
61910   if (!x) {
61911     return NULL;
61912   }
61913   if (wuffs_xxhash64__hasher__initialize(
61914       x, sizeof(wuffs_xxhash64__hasher), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
61915     free(x);
61916     return NULL;
61917   }
61918   return x;
61919 }
61920 
61921 size_t
sizeof__wuffs_xxhash64__hasher(void)61922 sizeof__wuffs_xxhash64__hasher(void) {
61923   return sizeof(wuffs_xxhash64__hasher);
61924 }
61925 
61926 // ---------------- Function Implementations
61927 
61928 // -------- func xxhash64.hasher.get_quirk
61929 
61930 WUFFS_BASE__GENERATED_C_CODE
61931 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_xxhash64__hasher__get_quirk(const wuffs_xxhash64__hasher * self,uint32_t a_key)61932 wuffs_xxhash64__hasher__get_quirk(
61933     const wuffs_xxhash64__hasher* self,
61934     uint32_t a_key) {
61935   if (!self) {
61936     return 0;
61937   }
61938   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
61939       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
61940     return 0;
61941   }
61942 
61943   return 0u;
61944 }
61945 
61946 // -------- func xxhash64.hasher.set_quirk
61947 
61948 WUFFS_BASE__GENERATED_C_CODE
61949 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_xxhash64__hasher__set_quirk(wuffs_xxhash64__hasher * self,uint32_t a_key,uint64_t a_value)61950 wuffs_xxhash64__hasher__set_quirk(
61951     wuffs_xxhash64__hasher* self,
61952     uint32_t a_key,
61953     uint64_t a_value) {
61954   if (!self) {
61955     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
61956   }
61957   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
61958     return wuffs_base__make_status(
61959         (self->private_impl.magic == WUFFS_BASE__DISABLED)
61960         ? wuffs_base__error__disabled_by_previous_error
61961         : wuffs_base__error__initialize_not_called);
61962   }
61963 
61964   return wuffs_base__make_status(wuffs_base__error__unsupported_option);
61965 }
61966 
61967 // -------- func xxhash64.hasher.update
61968 
61969 WUFFS_BASE__GENERATED_C_CODE
61970 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_xxhash64__hasher__update(wuffs_xxhash64__hasher * self,wuffs_base__slice_u8 a_x)61971 wuffs_xxhash64__hasher__update(
61972     wuffs_xxhash64__hasher* self,
61973     wuffs_base__slice_u8 a_x) {
61974   if (!self) {
61975     return wuffs_base__make_empty_struct();
61976   }
61977   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
61978     return wuffs_base__make_empty_struct();
61979   }
61980 
61981   if ((self->private_impl.f_length_modulo_u64 == 0u) &&  ! self->private_impl.f_length_overflows_u64) {
61982     self->private_impl.f_v0 = 6983438078262162902u;
61983     self->private_impl.f_v1 = 14029467366897019727u;
61984     self->private_impl.f_v2 = 0u;
61985     self->private_impl.f_v3 = 7046029288634856825u;
61986   }
61987   wuffs_xxhash64__hasher__up(self, a_x);
61988   return wuffs_base__make_empty_struct();
61989 }
61990 
61991 // -------- func xxhash64.hasher.update_u64
61992 
61993 WUFFS_BASE__GENERATED_C_CODE
61994 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_xxhash64__hasher__update_u64(wuffs_xxhash64__hasher * self,wuffs_base__slice_u8 a_x)61995 wuffs_xxhash64__hasher__update_u64(
61996     wuffs_xxhash64__hasher* self,
61997     wuffs_base__slice_u8 a_x) {
61998   if (!self) {
61999     return 0;
62000   }
62001   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
62002     return 0;
62003   }
62004 
62005   wuffs_xxhash64__hasher__update(self, a_x);
62006   return wuffs_xxhash64__hasher__checksum_u64(self);
62007 }
62008 
62009 // -------- func xxhash64.hasher.up
62010 
62011 WUFFS_BASE__GENERATED_C_CODE
62012 static wuffs_base__empty_struct
wuffs_xxhash64__hasher__up(wuffs_xxhash64__hasher * self,wuffs_base__slice_u8 a_x)62013 wuffs_xxhash64__hasher__up(
62014     wuffs_xxhash64__hasher* self,
62015     wuffs_base__slice_u8 a_x) {
62016   uint64_t v_new_lmu = 0;
62017   uint64_t v_buf_u64 = 0;
62018   uint32_t v_buf_len = 0;
62019   uint64_t v_v0 = 0;
62020   uint64_t v_v1 = 0;
62021   uint64_t v_v2 = 0;
62022   uint64_t v_v3 = 0;
62023   wuffs_base__slice_u8 v_p = {0};
62024 
62025   v_new_lmu = ((uint64_t)(self->private_impl.f_length_modulo_u64 + ((uint64_t)(a_x.len))));
62026   self->private_impl.f_length_overflows_u64 = ((v_new_lmu < self->private_impl.f_length_modulo_u64) || self->private_impl.f_length_overflows_u64);
62027   self->private_impl.f_length_modulo_u64 = v_new_lmu;
62028   while (true) {
62029     if (self->private_impl.f_buf_len >= 32u) {
62030       v_buf_u64 = (((uint64_t)(self->private_impl.f_buf_data[0u])) |
62031           (((uint64_t)(self->private_impl.f_buf_data[1u])) << 8u) |
62032           (((uint64_t)(self->private_impl.f_buf_data[2u])) << 16u) |
62033           (((uint64_t)(self->private_impl.f_buf_data[3u])) << 24u) |
62034           (((uint64_t)(self->private_impl.f_buf_data[4u])) << 32u) |
62035           (((uint64_t)(self->private_impl.f_buf_data[5u])) << 40u) |
62036           (((uint64_t)(self->private_impl.f_buf_data[6u])) << 48u) |
62037           (((uint64_t)(self->private_impl.f_buf_data[7u])) << 56u));
62038       v_v0 = ((uint64_t)(self->private_impl.f_v0 + ((uint64_t)(v_buf_u64 * 14029467366897019727u))));
62039       v_v0 = (((uint64_t)(v_v0 << 31u)) | (v_v0 >> 33u));
62040       self->private_impl.f_v0 = ((uint64_t)(v_v0 * 11400714785074694791u));
62041       v_buf_u64 = (((uint64_t)(self->private_impl.f_buf_data[8u])) |
62042           (((uint64_t)(self->private_impl.f_buf_data[9u])) << 8u) |
62043           (((uint64_t)(self->private_impl.f_buf_data[10u])) << 16u) |
62044           (((uint64_t)(self->private_impl.f_buf_data[11u])) << 24u) |
62045           (((uint64_t)(self->private_impl.f_buf_data[12u])) << 32u) |
62046           (((uint64_t)(self->private_impl.f_buf_data[13u])) << 40u) |
62047           (((uint64_t)(self->private_impl.f_buf_data[14u])) << 48u) |
62048           (((uint64_t)(self->private_impl.f_buf_data[15u])) << 56u));
62049       v_v1 = ((uint64_t)(self->private_impl.f_v1 + ((uint64_t)(v_buf_u64 * 14029467366897019727u))));
62050       v_v1 = (((uint64_t)(v_v1 << 31u)) | (v_v1 >> 33u));
62051       self->private_impl.f_v1 = ((uint64_t)(v_v1 * 11400714785074694791u));
62052       v_buf_u64 = (((uint64_t)(self->private_impl.f_buf_data[16u])) |
62053           (((uint64_t)(self->private_impl.f_buf_data[17u])) << 8u) |
62054           (((uint64_t)(self->private_impl.f_buf_data[18u])) << 16u) |
62055           (((uint64_t)(self->private_impl.f_buf_data[19u])) << 24u) |
62056           (((uint64_t)(self->private_impl.f_buf_data[20u])) << 32u) |
62057           (((uint64_t)(self->private_impl.f_buf_data[21u])) << 40u) |
62058           (((uint64_t)(self->private_impl.f_buf_data[22u])) << 48u) |
62059           (((uint64_t)(self->private_impl.f_buf_data[23u])) << 56u));
62060       v_v2 = ((uint64_t)(self->private_impl.f_v2 + ((uint64_t)(v_buf_u64 * 14029467366897019727u))));
62061       v_v2 = (((uint64_t)(v_v2 << 31u)) | (v_v2 >> 33u));
62062       self->private_impl.f_v2 = ((uint64_t)(v_v2 * 11400714785074694791u));
62063       v_buf_u64 = (((uint64_t)(self->private_impl.f_buf_data[24u])) |
62064           (((uint64_t)(self->private_impl.f_buf_data[25u])) << 8u) |
62065           (((uint64_t)(self->private_impl.f_buf_data[26u])) << 16u) |
62066           (((uint64_t)(self->private_impl.f_buf_data[27u])) << 24u) |
62067           (((uint64_t)(self->private_impl.f_buf_data[28u])) << 32u) |
62068           (((uint64_t)(self->private_impl.f_buf_data[29u])) << 40u) |
62069           (((uint64_t)(self->private_impl.f_buf_data[30u])) << 48u) |
62070           (((uint64_t)(self->private_impl.f_buf_data[31u])) << 56u));
62071       v_v3 = ((uint64_t)(self->private_impl.f_v3 + ((uint64_t)(v_buf_u64 * 14029467366897019727u))));
62072       v_v3 = (((uint64_t)(v_v3 << 31u)) | (v_v3 >> 33u));
62073       self->private_impl.f_v3 = ((uint64_t)(v_v3 * 11400714785074694791u));
62074       self->private_impl.f_buf_len = 0u;
62075       break;
62076     }
62077     if (((uint64_t)(a_x.len)) <= 0u) {
62078       return wuffs_base__make_empty_struct();
62079     }
62080     self->private_impl.f_buf_data[self->private_impl.f_buf_len] = a_x.ptr[0u];
62081     self->private_impl.f_buf_len += 1u;
62082     a_x = wuffs_base__slice_u8__subslice_i(a_x, 1u);
62083   }
62084   v_buf_len = (self->private_impl.f_buf_len & 31u);
62085   v_v0 = self->private_impl.f_v0;
62086   v_v1 = self->private_impl.f_v1;
62087   v_v2 = self->private_impl.f_v2;
62088   v_v3 = self->private_impl.f_v3;
62089   {
62090     wuffs_base__slice_u8 i_slice_p = a_x;
62091     v_p.ptr = i_slice_p.ptr;
62092     v_p.len = 32;
62093     uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 32) * 32);
62094     while (v_p.ptr < i_end0_p) {
62095       v_buf_u64 = (((uint64_t)(v_p.ptr[0u])) |
62096           (((uint64_t)(v_p.ptr[1u])) << 8u) |
62097           (((uint64_t)(v_p.ptr[2u])) << 16u) |
62098           (((uint64_t)(v_p.ptr[3u])) << 24u) |
62099           (((uint64_t)(v_p.ptr[4u])) << 32u) |
62100           (((uint64_t)(v_p.ptr[5u])) << 40u) |
62101           (((uint64_t)(v_p.ptr[6u])) << 48u) |
62102           (((uint64_t)(v_p.ptr[7u])) << 56u));
62103       v_v0 = ((uint64_t)(v_v0 + ((uint64_t)(v_buf_u64 * 14029467366897019727u))));
62104       v_v0 = (((uint64_t)(v_v0 << 31u)) | (v_v0 >> 33u));
62105       v_v0 = ((uint64_t)(v_v0 * 11400714785074694791u));
62106       v_buf_u64 = (((uint64_t)(v_p.ptr[8u])) |
62107           (((uint64_t)(v_p.ptr[9u])) << 8u) |
62108           (((uint64_t)(v_p.ptr[10u])) << 16u) |
62109           (((uint64_t)(v_p.ptr[11u])) << 24u) |
62110           (((uint64_t)(v_p.ptr[12u])) << 32u) |
62111           (((uint64_t)(v_p.ptr[13u])) << 40u) |
62112           (((uint64_t)(v_p.ptr[14u])) << 48u) |
62113           (((uint64_t)(v_p.ptr[15u])) << 56u));
62114       v_v1 = ((uint64_t)(v_v1 + ((uint64_t)(v_buf_u64 * 14029467366897019727u))));
62115       v_v1 = (((uint64_t)(v_v1 << 31u)) | (v_v1 >> 33u));
62116       v_v1 = ((uint64_t)(v_v1 * 11400714785074694791u));
62117       v_buf_u64 = (((uint64_t)(v_p.ptr[16u])) |
62118           (((uint64_t)(v_p.ptr[17u])) << 8u) |
62119           (((uint64_t)(v_p.ptr[18u])) << 16u) |
62120           (((uint64_t)(v_p.ptr[19u])) << 24u) |
62121           (((uint64_t)(v_p.ptr[20u])) << 32u) |
62122           (((uint64_t)(v_p.ptr[21u])) << 40u) |
62123           (((uint64_t)(v_p.ptr[22u])) << 48u) |
62124           (((uint64_t)(v_p.ptr[23u])) << 56u));
62125       v_v2 = ((uint64_t)(v_v2 + ((uint64_t)(v_buf_u64 * 14029467366897019727u))));
62126       v_v2 = (((uint64_t)(v_v2 << 31u)) | (v_v2 >> 33u));
62127       v_v2 = ((uint64_t)(v_v2 * 11400714785074694791u));
62128       v_buf_u64 = (((uint64_t)(v_p.ptr[24u])) |
62129           (((uint64_t)(v_p.ptr[25u])) << 8u) |
62130           (((uint64_t)(v_p.ptr[26u])) << 16u) |
62131           (((uint64_t)(v_p.ptr[27u])) << 24u) |
62132           (((uint64_t)(v_p.ptr[28u])) << 32u) |
62133           (((uint64_t)(v_p.ptr[29u])) << 40u) |
62134           (((uint64_t)(v_p.ptr[30u])) << 48u) |
62135           (((uint64_t)(v_p.ptr[31u])) << 56u));
62136       v_v3 = ((uint64_t)(v_v3 + ((uint64_t)(v_buf_u64 * 14029467366897019727u))));
62137       v_v3 = (((uint64_t)(v_v3 << 31u)) | (v_v3 >> 33u));
62138       v_v3 = ((uint64_t)(v_v3 * 11400714785074694791u));
62139       v_p.ptr += 32;
62140     }
62141     v_p.len = 1;
62142     uint8_t* i_end1_p = i_slice_p.ptr + i_slice_p.len;
62143     while (v_p.ptr < i_end1_p) {
62144       self->private_impl.f_buf_data[v_buf_len] = v_p.ptr[0u];
62145       v_buf_len = ((v_buf_len + 1u) & 31u);
62146       v_p.ptr += 1;
62147     }
62148     v_p.len = 0;
62149   }
62150   self->private_impl.f_buf_len = v_buf_len;
62151   self->private_impl.f_v0 = v_v0;
62152   self->private_impl.f_v1 = v_v1;
62153   self->private_impl.f_v2 = v_v2;
62154   self->private_impl.f_v3 = v_v3;
62155   return wuffs_base__make_empty_struct();
62156 }
62157 
62158 // -------- func xxhash64.hasher.checksum_u64
62159 
62160 WUFFS_BASE__GENERATED_C_CODE
62161 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_xxhash64__hasher__checksum_u64(const wuffs_xxhash64__hasher * self)62162 wuffs_xxhash64__hasher__checksum_u64(
62163     const wuffs_xxhash64__hasher* self) {
62164   if (!self) {
62165     return 0;
62166   }
62167   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
62168       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
62169     return 0;
62170   }
62171 
62172   uint64_t v_ret = 0;
62173   uint64_t v_v0 = 0;
62174   uint64_t v_v1 = 0;
62175   uint64_t v_v2 = 0;
62176   uint64_t v_v3 = 0;
62177   uint32_t v_i = 0;
62178   uint32_t v_i8 = 0;
62179   uint32_t v_n = 0;
62180   uint32_t v_buf_u32 = 0;
62181   uint64_t v_buf_u64 = 0;
62182 
62183   if ((self->private_impl.f_length_modulo_u64 >= 32u) || self->private_impl.f_length_overflows_u64) {
62184     v_ret += (((uint64_t)(self->private_impl.f_v0 << 1u)) | (self->private_impl.f_v0 >> 63u));
62185     v_ret += (((uint64_t)(self->private_impl.f_v1 << 7u)) | (self->private_impl.f_v1 >> 57u));
62186     v_ret += (((uint64_t)(self->private_impl.f_v2 << 12u)) | (self->private_impl.f_v2 >> 52u));
62187     v_ret += (((uint64_t)(self->private_impl.f_v3 << 18u)) | (self->private_impl.f_v3 >> 46u));
62188     v_v0 = ((uint64_t)(self->private_impl.f_v0 * 14029467366897019727u));
62189     v_v0 = (((uint64_t)(v_v0 << 31u)) | (v_v0 >> 33u));
62190     v_v0 *= 11400714785074694791u;
62191     v_v1 = ((uint64_t)(self->private_impl.f_v1 * 14029467366897019727u));
62192     v_v1 = (((uint64_t)(v_v1 << 31u)) | (v_v1 >> 33u));
62193     v_v1 *= 11400714785074694791u;
62194     v_v2 = ((uint64_t)(self->private_impl.f_v2 * 14029467366897019727u));
62195     v_v2 = (((uint64_t)(v_v2 << 31u)) | (v_v2 >> 33u));
62196     v_v2 *= 11400714785074694791u;
62197     v_v3 = ((uint64_t)(self->private_impl.f_v3 * 14029467366897019727u));
62198     v_v3 = (((uint64_t)(v_v3 << 31u)) | (v_v3 >> 33u));
62199     v_v3 *= 11400714785074694791u;
62200     v_ret = ((uint64_t)(((uint64_t)((v_ret ^ v_v0) * 11400714785074694791u)) + 9650029242287828579u));
62201     v_ret = ((uint64_t)(((uint64_t)((v_ret ^ v_v1) * 11400714785074694791u)) + 9650029242287828579u));
62202     v_ret = ((uint64_t)(((uint64_t)((v_ret ^ v_v2) * 11400714785074694791u)) + 9650029242287828579u));
62203     v_ret = ((uint64_t)(((uint64_t)((v_ret ^ v_v3) * 11400714785074694791u)) + 9650029242287828579u));
62204     v_ret += self->private_impl.f_length_modulo_u64;
62205   } else {
62206     v_ret += 2870177450012600261u;
62207     v_ret += self->private_impl.f_length_modulo_u64;
62208   }
62209   v_n = 32u;
62210   v_n = wuffs_base__u32__min(v_n, self->private_impl.f_buf_len);
62211   if (8u <= v_n) {
62212     v_buf_u64 = (((uint64_t)(self->private_impl.f_buf_data[0u])) |
62213         (((uint64_t)(self->private_impl.f_buf_data[1u])) << 8u) |
62214         (((uint64_t)(self->private_impl.f_buf_data[2u])) << 16u) |
62215         (((uint64_t)(self->private_impl.f_buf_data[3u])) << 24u) |
62216         (((uint64_t)(self->private_impl.f_buf_data[4u])) << 32u) |
62217         (((uint64_t)(self->private_impl.f_buf_data[5u])) << 40u) |
62218         (((uint64_t)(self->private_impl.f_buf_data[6u])) << 48u) |
62219         (((uint64_t)(self->private_impl.f_buf_data[7u])) << 56u));
62220     v_buf_u64 *= 14029467366897019727u;
62221     v_buf_u64 = (((uint64_t)(v_buf_u64 << 31u)) | (v_buf_u64 >> 33u));
62222     v_buf_u64 *= 11400714785074694791u;
62223     v_ret ^= v_buf_u64;
62224     v_ret = (((uint64_t)(v_ret << 27u)) | (v_ret >> 37u));
62225     v_ret *= 11400714785074694791u;
62226     v_ret += 9650029242287828579u;
62227     v_i = 8u;
62228   }
62229   if (16u <= v_n) {
62230     v_buf_u64 = (((uint64_t)(self->private_impl.f_buf_data[8u])) |
62231         (((uint64_t)(self->private_impl.f_buf_data[9u])) << 8u) |
62232         (((uint64_t)(self->private_impl.f_buf_data[10u])) << 16u) |
62233         (((uint64_t)(self->private_impl.f_buf_data[11u])) << 24u) |
62234         (((uint64_t)(self->private_impl.f_buf_data[12u])) << 32u) |
62235         (((uint64_t)(self->private_impl.f_buf_data[13u])) << 40u) |
62236         (((uint64_t)(self->private_impl.f_buf_data[14u])) << 48u) |
62237         (((uint64_t)(self->private_impl.f_buf_data[15u])) << 56u));
62238     v_buf_u64 *= 14029467366897019727u;
62239     v_buf_u64 = (((uint64_t)(v_buf_u64 << 31u)) | (v_buf_u64 >> 33u));
62240     v_buf_u64 *= 11400714785074694791u;
62241     v_ret ^= v_buf_u64;
62242     v_ret = (((uint64_t)(v_ret << 27u)) | (v_ret >> 37u));
62243     v_ret *= 11400714785074694791u;
62244     v_ret += 9650029242287828579u;
62245     v_i = 16u;
62246   }
62247   if (24u <= v_n) {
62248     v_buf_u64 = (((uint64_t)(self->private_impl.f_buf_data[16u])) |
62249         (((uint64_t)(self->private_impl.f_buf_data[17u])) << 8u) |
62250         (((uint64_t)(self->private_impl.f_buf_data[18u])) << 16u) |
62251         (((uint64_t)(self->private_impl.f_buf_data[19u])) << 24u) |
62252         (((uint64_t)(self->private_impl.f_buf_data[20u])) << 32u) |
62253         (((uint64_t)(self->private_impl.f_buf_data[21u])) << 40u) |
62254         (((uint64_t)(self->private_impl.f_buf_data[22u])) << 48u) |
62255         (((uint64_t)(self->private_impl.f_buf_data[23u])) << 56u));
62256     v_buf_u64 *= 14029467366897019727u;
62257     v_buf_u64 = (((uint64_t)(v_buf_u64 << 31u)) | (v_buf_u64 >> 33u));
62258     v_buf_u64 *= 11400714785074694791u;
62259     v_ret ^= v_buf_u64;
62260     v_ret = (((uint64_t)(v_ret << 27u)) | (v_ret >> 37u));
62261     v_ret *= 11400714785074694791u;
62262     v_ret += 9650029242287828579u;
62263     v_i = 24u;
62264   }
62265   if ((v_n & 4u) != 0u) {
62266     v_i8 = (v_i & 24u);
62267     v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[(v_i8 + 0u)])) |
62268         (((uint32_t)(self->private_impl.f_buf_data[(v_i8 + 1u)])) << 8u) |
62269         (((uint32_t)(self->private_impl.f_buf_data[(v_i8 + 2u)])) << 16u) |
62270         (((uint32_t)(self->private_impl.f_buf_data[(v_i8 + 3u)])) << 24u));
62271     v_ret ^= ((uint64_t)(((uint64_t)(v_buf_u32)) * 11400714785074694791u));
62272     v_ret = (((uint64_t)(v_ret << 23u)) | (v_ret >> 41u));
62273     v_ret *= 14029467366897019727u;
62274     v_ret += 1609587929392839161u;
62275     v_i = (v_i8 + 4u);
62276   }
62277   while (v_i < v_n) {
62278     v_ret ^= ((uint64_t)(((uint64_t)(self->private_impl.f_buf_data[v_i])) * 2870177450012600261u));
62279     v_ret = (((uint64_t)(v_ret << 11u)) | (v_ret >> 53u));
62280     v_ret *= 11400714785074694791u;
62281     v_i += 1u;
62282   }
62283   v_ret ^= (v_ret >> 33u);
62284   v_ret *= 14029467366897019727u;
62285   v_ret ^= (v_ret >> 29u);
62286   v_ret *= 1609587929392839161u;
62287   v_ret ^= (v_ret >> 32u);
62288   return ((uint64_t)(v_ret));
62289 }
62290 
62291 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH64)
62292 
62293 #if defined(__cplusplus) && defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
62294 
62295 // ---------------- Auxiliary - Base
62296 
62297 // Auxiliary code is discussed at
62298 // https://github.com/google/wuffs/blob/main/doc/note/auxiliary-code.md
62299 
62300 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__AUX__BASE)
62301 
62302 namespace wuffs_aux {
62303 
62304 namespace sync_io {
62305 
62306 // --------
62307 
DynIOBuffer(uint64_t max_incl)62308 DynIOBuffer::DynIOBuffer(uint64_t max_incl)
62309     : m_buf(wuffs_base__empty_io_buffer()), m_max_incl(max_incl) {}
62310 
~DynIOBuffer()62311 DynIOBuffer::~DynIOBuffer() {
62312   if (m_buf.data.ptr) {
62313     free(m_buf.data.ptr);
62314   }
62315 }
62316 
62317 void  //
drop()62318 DynIOBuffer::drop() {
62319   if (m_buf.data.ptr) {
62320     free(m_buf.data.ptr);
62321   }
62322   m_buf = wuffs_base__empty_io_buffer();
62323 }
62324 
62325 DynIOBuffer::GrowResult  //
grow(uint64_t min_incl)62326 DynIOBuffer::grow(uint64_t min_incl) {
62327   uint64_t n = round_up(min_incl, m_max_incl);
62328   if (n == 0) {
62329     return ((min_incl == 0) && (m_max_incl == 0))
62330                ? DynIOBuffer::GrowResult::OK
62331                : DynIOBuffer::GrowResult::FailedMaxInclExceeded;
62332   } else if (n > m_buf.data.len) {
62333     uint8_t* ptr = static_cast<uint8_t*>(realloc(m_buf.data.ptr, n));
62334     if (!ptr) {
62335       return DynIOBuffer::GrowResult::FailedOutOfMemory;
62336     }
62337     m_buf.data.ptr = ptr;
62338     m_buf.data.len = n;
62339   }
62340   return DynIOBuffer::GrowResult::OK;
62341 }
62342 
62343 // round_up rounds min_incl up, returning the smallest value x satisfying
62344 // (min_incl <= x) and (x <= max_incl) and some other constraints. It returns 0
62345 // if there is no such x.
62346 //
62347 // When max_incl <= 4096, the other constraints are:
62348 //  - (x == max_incl)
62349 //
62350 // When max_incl >  4096, the other constraints are:
62351 //  - (x == max_incl) or (x is a power of 2)
62352 //  - (x >= 4096)
62353 uint64_t  //
round_up(uint64_t min_incl,uint64_t max_incl)62354 DynIOBuffer::round_up(uint64_t min_incl, uint64_t max_incl) {
62355   if (min_incl > max_incl) {
62356     return 0;
62357   }
62358   uint64_t n = 4096;
62359   if (n >= max_incl) {
62360     return max_incl;
62361   }
62362   while (n < min_incl) {
62363     if (n >= (max_incl / 2)) {
62364       return max_incl;
62365     }
62366     n *= 2;
62367   }
62368   return n;
62369 }
62370 
62371 // --------
62372 
~Input()62373 Input::~Input() {}
62374 
62375 IOBuffer*  //
BringsItsOwnIOBuffer()62376 Input::BringsItsOwnIOBuffer() {
62377   return nullptr;
62378 }
62379 
62380 // --------
62381 
FileInput(FILE * f)62382 FileInput::FileInput(FILE* f) : m_f(f) {}
62383 
62384 std::string  //
CopyIn(IOBuffer * dst,uint64_t history_retain_length)62385 FileInput::CopyIn(IOBuffer* dst, uint64_t history_retain_length) {
62386   if (!m_f) {
62387     return "wuffs_aux::sync_io::FileInput: nullptr file";
62388   } else if (!dst) {
62389     return "wuffs_aux::sync_io::FileInput: nullptr IOBuffer";
62390   } else if (dst->meta.closed) {
62391     return "wuffs_aux::sync_io::FileInput: end of file";
62392   } else {
62393     dst->compact_retaining(history_retain_length);
62394     size_t n = fread(dst->writer_pointer(), 1, dst->writer_length(), m_f);
62395     dst->meta.wi += n;
62396     dst->meta.closed = feof(m_f);
62397     if (ferror(m_f)) {
62398       return "wuffs_aux::sync_io::FileInput: error reading file";
62399     }
62400   }
62401   return "";
62402 }
62403 
62404 // --------
62405 
MemoryInput(const char * ptr,size_t len)62406 MemoryInput::MemoryInput(const char* ptr, size_t len)
62407     : m_io(wuffs_base__ptr_u8__reader(
62408           static_cast<uint8_t*>(static_cast<void*>(const_cast<char*>(ptr))),
62409           len,
62410           true)) {}
62411 
MemoryInput(const uint8_t * ptr,size_t len)62412 MemoryInput::MemoryInput(const uint8_t* ptr, size_t len)
62413     : m_io(wuffs_base__ptr_u8__reader(const_cast<uint8_t*>(ptr), len, true)) {}
62414 
62415 IOBuffer*  //
BringsItsOwnIOBuffer()62416 MemoryInput::BringsItsOwnIOBuffer() {
62417   return &m_io;
62418 }
62419 
62420 std::string  //
CopyIn(IOBuffer * dst,uint64_t history_retain_length)62421 MemoryInput::CopyIn(IOBuffer* dst, uint64_t history_retain_length) {
62422   if (!dst) {
62423     return "wuffs_aux::sync_io::MemoryInput: nullptr IOBuffer";
62424   } else if (dst->meta.closed) {
62425     return "wuffs_aux::sync_io::MemoryInput: end of file";
62426   } else if (wuffs_base__slice_u8__overlaps(dst->data, m_io.data)) {
62427     // Treat m_io's data as immutable, so don't compact dst or otherwise write
62428     // to it.
62429     return "wuffs_aux::sync_io::MemoryInput: overlapping buffers";
62430   } else {
62431     dst->compact_retaining(history_retain_length);
62432     size_t nd = dst->writer_length();
62433     size_t ns = m_io.reader_length();
62434     size_t n = (nd < ns) ? nd : ns;
62435     memcpy(dst->writer_pointer(), m_io.reader_pointer(), n);
62436     m_io.meta.ri += n;
62437     dst->meta.wi += n;
62438     dst->meta.closed = m_io.reader_length() == 0;
62439   }
62440   return "";
62441 }
62442 
62443 // --------
62444 
62445 }  // namespace sync_io
62446 
62447 namespace private_impl {
62448 
62449 struct ErrorMessages {
62450   const char* max_incl_metadata_length_exceeded;
62451   const char* out_of_memory;
62452   const char* unexpected_end_of_file;
62453   const char* unsupported_metadata;
62454   const char* unsupported_negative_advance;
62455 
62456   // If adding new "const char*" typed fields to this struct, either add them
62457   // after existing fields or, if re-ordering fields, make sure that you update
62458   // all of the "const private_impl::ErrorMessages FooBarErrorMessages" values
62459   // in all of the sibling *.cc files.
62460 
resolveErrorMessages62461   static inline const char* resolve(const char* s) {
62462     return s ? s : "wuffs_aux::private_impl: unknown error";
62463   };
62464 };
62465 
62466 std::string  //
AdvanceIOBufferTo(const ErrorMessages & error_messages,sync_io::Input & input,IOBuffer & io_buf,uint64_t absolute_position)62467 AdvanceIOBufferTo(const ErrorMessages& error_messages,
62468                   sync_io::Input& input,
62469                   IOBuffer& io_buf,
62470                   uint64_t absolute_position) {
62471   if (absolute_position < io_buf.reader_position()) {
62472     return error_messages.resolve(error_messages.unsupported_negative_advance);
62473   }
62474   while (true) {
62475     uint64_t relative_position = absolute_position - io_buf.reader_position();
62476     if (relative_position <= io_buf.reader_length()) {
62477       io_buf.meta.ri += (size_t)relative_position;
62478       break;
62479     } else if (io_buf.meta.closed) {
62480       return error_messages.resolve(error_messages.unexpected_end_of_file);
62481     }
62482     io_buf.meta.ri = io_buf.meta.wi;
62483     if (!input.BringsItsOwnIOBuffer()) {
62484       io_buf.compact();
62485     }
62486     std::string error_message = input.CopyIn(&io_buf, 0);
62487     if (!error_message.empty()) {
62488       return error_message;
62489     }
62490   }
62491   return "";
62492 }
62493 
62494 std::string  //
HandleMetadata(const ErrorMessages & error_messages,sync_io::Input & input,wuffs_base__io_buffer & io_buf,sync_io::DynIOBuffer & raw,wuffs_base__status (* tell_me_more_func)(void *,wuffs_base__io_buffer *,wuffs_base__more_information *,wuffs_base__io_buffer *),void * tell_me_more_receiver,std::string (* handle_metadata_func)(void *,const wuffs_base__more_information *,wuffs_base__slice_u8),void * handle_metadata_receiver)62495 HandleMetadata(
62496     const ErrorMessages& error_messages,
62497     sync_io::Input& input,
62498     wuffs_base__io_buffer& io_buf,
62499     sync_io::DynIOBuffer& raw,
62500     wuffs_base__status (*tell_me_more_func)(void*,
62501                                             wuffs_base__io_buffer*,
62502                                             wuffs_base__more_information*,
62503                                             wuffs_base__io_buffer*),
62504     void* tell_me_more_receiver,
62505     std::string (*handle_metadata_func)(void*,
62506                                         const wuffs_base__more_information*,
62507                                         wuffs_base__slice_u8),
62508     void* handle_metadata_receiver) {
62509   wuffs_base__more_information minfo = wuffs_base__empty_more_information();
62510   // Reset raw but keep its backing array (the raw.m_buf.data slice).
62511   raw.m_buf.meta = wuffs_base__empty_io_buffer_meta();
62512 
62513   while (true) {
62514     minfo = wuffs_base__empty_more_information();
62515     wuffs_base__status status = (*tell_me_more_func)(
62516         tell_me_more_receiver, &raw.m_buf, &minfo, &io_buf);
62517     switch (minfo.flavor) {
62518       case 0:
62519       case WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_RAW_TRANSFORM:
62520       case WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_PARSED:
62521         break;
62522 
62523       case WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_RAW_PASSTHROUGH: {
62524         wuffs_base__range_ie_u64 r = minfo.metadata_raw_passthrough__range();
62525         if (r.is_empty()) {
62526           break;
62527         }
62528         uint64_t num_to_copy = r.length();
62529         if (num_to_copy > (raw.m_max_incl - raw.m_buf.meta.wi)) {
62530           return error_messages.resolve(
62531               error_messages.max_incl_metadata_length_exceeded);
62532         } else if (num_to_copy > (raw.m_buf.data.len - raw.m_buf.meta.wi)) {
62533           switch (raw.grow(num_to_copy + raw.m_buf.meta.wi)) {
62534             case sync_io::DynIOBuffer::GrowResult::OK:
62535               break;
62536             case sync_io::DynIOBuffer::GrowResult::FailedMaxInclExceeded:
62537               return error_messages.resolve(
62538                   error_messages.max_incl_metadata_length_exceeded);
62539             case sync_io::DynIOBuffer::GrowResult::FailedOutOfMemory:
62540               return error_messages.resolve(error_messages.out_of_memory);
62541           }
62542         }
62543 
62544         if (io_buf.reader_position() > r.min_incl) {
62545           return error_messages.resolve(error_messages.unsupported_metadata);
62546         } else {
62547           std::string error_message =
62548               AdvanceIOBufferTo(error_messages, input, io_buf, r.min_incl);
62549           if (!error_message.empty()) {
62550             return error_message;
62551           }
62552         }
62553 
62554         while (true) {
62555           uint64_t n =
62556               wuffs_base__u64__min(num_to_copy, io_buf.reader_length());
62557           memcpy(raw.m_buf.writer_pointer(), io_buf.reader_pointer(), n);
62558           raw.m_buf.meta.wi += n;
62559           io_buf.meta.ri += n;
62560           num_to_copy -= n;
62561           if (num_to_copy == 0) {
62562             break;
62563           } else if (io_buf.meta.closed) {
62564             return error_messages.resolve(
62565                 error_messages.unexpected_end_of_file);
62566           } else if (!input.BringsItsOwnIOBuffer()) {
62567             io_buf.compact();
62568           }
62569           std::string error_message = input.CopyIn(&io_buf, 0);
62570           if (!error_message.empty()) {
62571             return error_message;
62572           }
62573         }
62574         break;
62575       }
62576 
62577       default:
62578         return error_messages.resolve(error_messages.unsupported_metadata);
62579     }
62580 
62581     if (status.repr == nullptr) {
62582       break;
62583     } else if (status.repr != wuffs_base__suspension__even_more_information) {
62584       if (status.repr != wuffs_base__suspension__short_write) {
62585         return status.message();
62586       }
62587       switch (raw.grow(wuffs_base__u64__sat_add(raw.m_buf.data.len, 1))) {
62588         case sync_io::DynIOBuffer::GrowResult::OK:
62589           break;
62590         case sync_io::DynIOBuffer::GrowResult::FailedMaxInclExceeded:
62591           return error_messages.resolve(
62592               error_messages.max_incl_metadata_length_exceeded);
62593         case sync_io::DynIOBuffer::GrowResult::FailedOutOfMemory:
62594           return error_messages.resolve(error_messages.out_of_memory);
62595       }
62596     }
62597   }
62598 
62599   return (*handle_metadata_func)(handle_metadata_receiver, &minfo,
62600                                  raw.m_buf.reader_slice());
62601 }
62602 
62603 }  // namespace private_impl
62604 
62605 }  // namespace wuffs_aux
62606 
62607 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
62608         // defined(WUFFS_CONFIG__MODULE__AUX__BASE)
62609 
62610 // ---------------- Auxiliary - CBOR
62611 
62612 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__AUX__CBOR)
62613 
62614 #include <utility>
62615 
62616 namespace wuffs_aux {
62617 
DecodeCborResult(std::string && error_message0,uint64_t cursor_position0)62618 DecodeCborResult::DecodeCborResult(std::string&& error_message0,
62619                                    uint64_t cursor_position0)
62620     : error_message(std::move(error_message0)),
62621       cursor_position(cursor_position0) {}
62622 
~DecodeCborCallbacks()62623 DecodeCborCallbacks::~DecodeCborCallbacks() {}
62624 
62625 void  //
Done(DecodeCborResult & result,sync_io::Input & input,IOBuffer & buffer)62626 DecodeCborCallbacks::Done(DecodeCborResult& result,
62627                           sync_io::Input& input,
62628                           IOBuffer& buffer) {}
62629 
DecodeCborArgQuirks(wuffs_base__slice_u32 repr0)62630 DecodeCborArgQuirks::DecodeCborArgQuirks(wuffs_base__slice_u32 repr0)
62631     : repr(repr0) {}
62632 
DecodeCborArgQuirks(uint32_t * ptr0,size_t len0)62633 DecodeCborArgQuirks::DecodeCborArgQuirks(uint32_t* ptr0, size_t len0)
62634     : repr(wuffs_base__make_slice_u32(ptr0, len0)) {}
62635 
62636 DecodeCborArgQuirks  //
DefaultValue()62637 DecodeCborArgQuirks::DefaultValue() {
62638   return DecodeCborArgQuirks(wuffs_base__empty_slice_u32());
62639 }
62640 
62641 DecodeCborResult  //
DecodeCbor(DecodeCborCallbacks & callbacks,sync_io::Input & input,DecodeCborArgQuirks quirks)62642 DecodeCbor(DecodeCborCallbacks& callbacks,
62643            sync_io::Input& input,
62644            DecodeCborArgQuirks quirks) {
62645   // Prepare the wuffs_base__io_buffer and the resultant error_message.
62646   wuffs_base__io_buffer* io_buf = input.BringsItsOwnIOBuffer();
62647   wuffs_base__io_buffer fallback_io_buf = wuffs_base__empty_io_buffer();
62648   std::unique_ptr<uint8_t[]> fallback_io_array(nullptr);
62649   if (!io_buf) {
62650     fallback_io_array = std::unique_ptr<uint8_t[]>(new uint8_t[4096]);
62651     fallback_io_buf = wuffs_base__ptr_u8__writer(fallback_io_array.get(), 4096);
62652     io_buf = &fallback_io_buf;
62653   }
62654   // cursor_index is discussed at
62655   // https://nigeltao.github.io/blog/2020/jsonptr.html#the-cursor-index
62656   size_t cursor_index = 0;
62657   std::string ret_error_message;
62658   std::string io_error_message;
62659 
62660   do {
62661     // Prepare the low-level CBOR decoder.
62662     wuffs_cbor__decoder::unique_ptr dec = wuffs_cbor__decoder::alloc();
62663     if (!dec) {
62664       ret_error_message = "wuffs_aux::DecodeCbor: out of memory";
62665       goto done;
62666     }
62667     for (size_t i = 0; i < quirks.repr.len; i++) {
62668       dec->set_quirk(quirks.repr.ptr[i], 1);
62669     }
62670 
62671     // Prepare the wuffs_base__tok_buffer. 256 tokens is 2KiB.
62672     wuffs_base__token tok_array[256];
62673     wuffs_base__token_buffer tok_buf =
62674         wuffs_base__slice_token__writer(wuffs_base__make_slice_token(
62675             &tok_array[0], (sizeof(tok_array) / sizeof(tok_array[0]))));
62676     wuffs_base__status tok_status = wuffs_base__make_status(nullptr);
62677 
62678     // Prepare other state.
62679     int32_t depth = 0;
62680     std::string str;
62681     int64_t extension_category = 0;
62682     uint64_t extension_detail = 0;
62683 
62684     // Valid token's VBCs range in 0 ..= 15. Values over that are for tokens
62685     // from outside of the base package, such as the CBOR package.
62686     constexpr int64_t EXT_CAT__CBOR_TAG = 16;
62687 
62688     // Loop, doing these two things:
62689     //  1. Get the next token.
62690     //  2. Process that token.
62691     while (true) {
62692       // 1. Get the next token.
62693 
62694       while (tok_buf.meta.ri >= tok_buf.meta.wi) {
62695         if (tok_status.repr == nullptr) {
62696           // No-op.
62697         } else if (tok_status.repr == wuffs_base__suspension__short_write) {
62698           tok_buf.compact();
62699         } else if (tok_status.repr == wuffs_base__suspension__short_read) {
62700           // Read from input to io_buf.
62701           if (!io_error_message.empty()) {
62702             ret_error_message = std::move(io_error_message);
62703             goto done;
62704           } else if (cursor_index != io_buf->meta.ri) {
62705             ret_error_message =
62706                 "wuffs_aux::DecodeCbor: internal error: bad cursor_index";
62707             goto done;
62708           } else if (io_buf->meta.closed) {
62709             ret_error_message =
62710                 "wuffs_aux::DecodeCbor: internal error: io_buf is closed";
62711             goto done;
62712           }
62713           io_buf->compact_retaining(dec->history_retain_length());
62714           if (io_buf->meta.wi >= io_buf->data.len) {
62715             ret_error_message =
62716                 "wuffs_aux::DecodeCbor: internal error: io_buf is full";
62717             goto done;
62718           }
62719           cursor_index = io_buf->meta.ri;
62720           io_error_message = input.CopyIn(io_buf, dec->history_retain_length());
62721         } else {
62722           ret_error_message = tok_status.message();
62723           goto done;
62724         }
62725 
62726         if (WUFFS_CBOR__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE != 0) {
62727           ret_error_message =
62728               "wuffs_aux::DecodeCbor: internal error: bad WORKBUF_LEN";
62729           goto done;
62730         }
62731         wuffs_base__slice_u8 work_buf = wuffs_base__empty_slice_u8();
62732         tok_status = dec->decode_tokens(&tok_buf, io_buf, work_buf);
62733         if ((tok_buf.meta.ri > tok_buf.meta.wi) ||
62734             (tok_buf.meta.wi > tok_buf.data.len) ||
62735             (io_buf->meta.ri > io_buf->meta.wi) ||
62736             (io_buf->meta.wi > io_buf->data.len)) {
62737           ret_error_message =
62738               "wuffs_aux::DecodeCbor: internal error: bad buffer indexes";
62739           goto done;
62740         }
62741       }
62742 
62743       wuffs_base__token token = tok_buf.data.ptr[tok_buf.meta.ri++];
62744       uint64_t token_len = token.length();
62745       if ((io_buf->meta.ri < cursor_index) ||
62746           ((io_buf->meta.ri - cursor_index) < token_len)) {
62747         ret_error_message =
62748             "wuffs_aux::DecodeCbor: internal error: bad token indexes";
62749         goto done;
62750       }
62751       uint8_t* token_ptr = io_buf->data.ptr + cursor_index;
62752       cursor_index += static_cast<size_t>(token_len);
62753 
62754       // 2. Process that token.
62755 
62756       uint64_t vbd = token.value_base_detail();
62757 
62758       if (extension_category != 0) {
62759         int64_t ext = token.value_extension();
62760         if ((ext >= 0) && !token.continued()) {
62761           extension_detail = (extension_detail
62762                               << WUFFS_BASE__TOKEN__VALUE_EXTENSION__NUM_BITS) |
62763                              static_cast<uint64_t>(ext);
62764           switch (extension_category) {
62765             case WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_SIGNED:
62766               extension_category = 0;
62767               ret_error_message =
62768                   callbacks.AppendI64(static_cast<int64_t>(extension_detail));
62769               goto parsed_a_value;
62770             case WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_UNSIGNED:
62771               extension_category = 0;
62772               ret_error_message = callbacks.AppendU64(extension_detail);
62773               goto parsed_a_value;
62774             case EXT_CAT__CBOR_TAG:
62775               extension_category = 0;
62776               ret_error_message = callbacks.AppendCborTag(extension_detail);
62777               if (!ret_error_message.empty()) {
62778                 goto done;
62779               }
62780               continue;
62781           }
62782         }
62783         ret_error_message =
62784             "wuffs_aux::DecodeCbor: internal error: bad extended token";
62785         goto done;
62786       }
62787 
62788       switch (token.value_base_category()) {
62789         case WUFFS_BASE__TOKEN__VBC__FILLER:
62790           continue;
62791 
62792         case WUFFS_BASE__TOKEN__VBC__STRUCTURE: {
62793           if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {
62794             ret_error_message = callbacks.Push(static_cast<uint32_t>(vbd));
62795             if (!ret_error_message.empty()) {
62796               goto done;
62797             }
62798             depth++;
62799             if (depth > WUFFS_CBOR__DECODER_DEPTH_MAX_INCL) {
62800               ret_error_message =
62801                   "wuffs_aux::DecodeCbor: internal error: bad depth";
62802               goto done;
62803             }
62804             continue;
62805           }
62806           ret_error_message = callbacks.Pop(static_cast<uint32_t>(vbd));
62807           depth--;
62808           if (depth < 0) {
62809             ret_error_message =
62810                 "wuffs_aux::DecodeCbor: internal error: bad depth";
62811             goto done;
62812           }
62813           goto parsed_a_value;
62814         }
62815 
62816         case WUFFS_BASE__TOKEN__VBC__STRING: {
62817           if (vbd & WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_0_DST_1_SRC_DROP) {
62818             // No-op.
62819           } else if (vbd &
62820                      WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_1_SRC_COPY) {
62821             const char* ptr =  // Convert from (uint8_t*).
62822                 static_cast<const char*>(static_cast<void*>(token_ptr));
62823             str.append(ptr, static_cast<size_t>(token_len));
62824           } else {
62825             goto fail;
62826           }
62827           if (token.continued()) {
62828             continue;
62829           }
62830           ret_error_message =
62831               (vbd & WUFFS_BASE__TOKEN__VBD__STRING__CHAIN_MUST_BE_UTF_8)
62832                   ? callbacks.AppendTextString(std::move(str))
62833                   : callbacks.AppendByteString(std::move(str));
62834           str.clear();
62835           goto parsed_a_value;
62836         }
62837 
62838         case WUFFS_BASE__TOKEN__VBC__UNICODE_CODE_POINT: {
62839           uint8_t u[WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL];
62840           size_t n = wuffs_base__utf_8__encode(
62841               wuffs_base__make_slice_u8(
62842                   &u[0], WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL),
62843               static_cast<uint32_t>(vbd));
62844           const char* ptr =  // Convert from (uint8_t*).
62845               static_cast<const char*>(static_cast<void*>(&u[0]));
62846           str.append(ptr, n);
62847           if (token.continued()) {
62848             continue;
62849           }
62850           goto fail;
62851         }
62852 
62853         case WUFFS_BASE__TOKEN__VBC__LITERAL: {
62854           if (vbd & WUFFS_BASE__TOKEN__VBD__LITERAL__NULL) {
62855             ret_error_message = callbacks.AppendNull();
62856           } else if (vbd & WUFFS_BASE__TOKEN__VBD__LITERAL__UNDEFINED) {
62857             ret_error_message = callbacks.AppendUndefined();
62858           } else {
62859             ret_error_message = callbacks.AppendBool(
62860                 vbd & WUFFS_BASE__TOKEN__VBD__LITERAL__TRUE);
62861           }
62862           goto parsed_a_value;
62863         }
62864 
62865         case WUFFS_BASE__TOKEN__VBC__NUMBER: {
62866           const uint64_t cfp_fbbe_fifb =
62867               WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_FLOATING_POINT |
62868               WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_BINARY_BIG_ENDIAN |
62869               WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_IGNORE_FIRST_BYTE;
62870           if ((vbd & cfp_fbbe_fifb) == cfp_fbbe_fifb) {
62871             double f;
62872             switch (token_len) {
62873               case 3:
62874                 f = wuffs_base__ieee_754_bit_representation__from_u16_to_f64(
62875                     wuffs_base__peek_u16be__no_bounds_check(token_ptr + 1));
62876                 break;
62877               case 5:
62878                 f = wuffs_base__ieee_754_bit_representation__from_u32_to_f64(
62879                     wuffs_base__peek_u32be__no_bounds_check(token_ptr + 1));
62880                 break;
62881               case 9:
62882                 f = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
62883                     wuffs_base__peek_u64be__no_bounds_check(token_ptr + 1));
62884                 break;
62885               default:
62886                 goto fail;
62887             }
62888             ret_error_message = callbacks.AppendF64(f);
62889             goto parsed_a_value;
62890           }
62891           goto fail;
62892         }
62893 
62894         case WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_SIGNED: {
62895           if (token.continued()) {
62896             extension_category = WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_SIGNED;
62897             extension_detail =
62898                 static_cast<uint64_t>(token.value_base_detail__sign_extended());
62899             continue;
62900           }
62901           ret_error_message =
62902               callbacks.AppendI64(token.value_base_detail__sign_extended());
62903           goto parsed_a_value;
62904         }
62905 
62906         case WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_UNSIGNED: {
62907           if (token.continued()) {
62908             extension_category =
62909                 WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_UNSIGNED;
62910             extension_detail = vbd;
62911             continue;
62912           }
62913           ret_error_message = callbacks.AppendU64(vbd);
62914           goto parsed_a_value;
62915         }
62916       }
62917 
62918       if (token.value_major() == WUFFS_CBOR__TOKEN_VALUE_MAJOR) {
62919         uint64_t value_minor = token.value_minor();
62920         if (value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__MINUS_1_MINUS_X) {
62921           if (token_len == 9) {
62922             ret_error_message = callbacks.AppendMinus1MinusX(
62923                 wuffs_base__peek_u64be__no_bounds_check(token_ptr + 1));
62924             goto parsed_a_value;
62925           }
62926         } else if (value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__SIMPLE_VALUE) {
62927           ret_error_message =
62928               callbacks.AppendCborSimpleValue(static_cast<uint8_t>(
62929                   value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__DETAIL_MASK));
62930           goto parsed_a_value;
62931         } else if (value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__TAG) {
62932           if (token.continued()) {
62933             extension_category = EXT_CAT__CBOR_TAG;
62934             extension_detail =
62935                 value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__DETAIL_MASK;
62936             continue;
62937           }
62938           ret_error_message = callbacks.AppendCborTag(
62939               value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__DETAIL_MASK);
62940           if (!ret_error_message.empty()) {
62941             goto done;
62942           }
62943           continue;
62944         }
62945       }
62946 
62947     fail:
62948       ret_error_message =
62949           "wuffs_aux::DecodeCbor: internal error: unexpected token";
62950       goto done;
62951 
62952     parsed_a_value:
62953       if (!ret_error_message.empty() || (depth == 0)) {
62954         goto done;
62955       }
62956     }
62957   } while (false);
62958 
62959 done:
62960   DecodeCborResult result(
62961       std::move(ret_error_message),
62962       wuffs_base__u64__sat_add(io_buf->meta.pos, cursor_index));
62963   callbacks.Done(result, input, *io_buf);
62964   return result;
62965 }
62966 
62967 }  // namespace wuffs_aux
62968 
62969 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
62970         // defined(WUFFS_CONFIG__MODULE__AUX__CBOR)
62971 
62972 // ---------------- Auxiliary - Image
62973 
62974 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__AUX__IMAGE)
62975 
62976 #include <utility>
62977 
62978 namespace wuffs_aux {
62979 
DecodeImageResult(MemOwner && pixbuf_mem_owner0,wuffs_base__pixel_buffer pixbuf0,std::string && error_message0)62980 DecodeImageResult::DecodeImageResult(MemOwner&& pixbuf_mem_owner0,
62981                                      wuffs_base__pixel_buffer pixbuf0,
62982                                      std::string&& error_message0)
62983     : pixbuf_mem_owner(std::move(pixbuf_mem_owner0)),
62984       pixbuf(pixbuf0),
62985       error_message(std::move(error_message0)) {}
62986 
DecodeImageResult(std::string && error_message0)62987 DecodeImageResult::DecodeImageResult(std::string&& error_message0)
62988     : pixbuf_mem_owner(nullptr, &free),
62989       pixbuf(wuffs_base__null_pixel_buffer()),
62990       error_message(std::move(error_message0)) {}
62991 
~DecodeImageCallbacks()62992 DecodeImageCallbacks::~DecodeImageCallbacks() {}
62993 
AllocPixbufResult(MemOwner && mem_owner0,wuffs_base__pixel_buffer pixbuf0)62994 DecodeImageCallbacks::AllocPixbufResult::AllocPixbufResult(
62995     MemOwner&& mem_owner0,
62996     wuffs_base__pixel_buffer pixbuf0)
62997     : mem_owner(std::move(mem_owner0)), pixbuf(pixbuf0), error_message("") {}
62998 
AllocPixbufResult(std::string && error_message0)62999 DecodeImageCallbacks::AllocPixbufResult::AllocPixbufResult(
63000     std::string&& error_message0)
63001     : mem_owner(nullptr, &free),
63002       pixbuf(wuffs_base__null_pixel_buffer()),
63003       error_message(std::move(error_message0)) {}
63004 
AllocWorkbufResult(MemOwner && mem_owner0,wuffs_base__slice_u8 workbuf0)63005 DecodeImageCallbacks::AllocWorkbufResult::AllocWorkbufResult(
63006     MemOwner&& mem_owner0,
63007     wuffs_base__slice_u8 workbuf0)
63008     : mem_owner(std::move(mem_owner0)), workbuf(workbuf0), error_message("") {}
63009 
AllocWorkbufResult(std::string && error_message0)63010 DecodeImageCallbacks::AllocWorkbufResult::AllocWorkbufResult(
63011     std::string&& error_message0)
63012     : mem_owner(nullptr, &free),
63013       workbuf(wuffs_base__empty_slice_u8()),
63014       error_message(std::move(error_message0)) {}
63015 
63016 wuffs_base__image_decoder::unique_ptr  //
SelectDecoder(uint32_t fourcc,wuffs_base__slice_u8 prefix_data,bool prefix_closed)63017 DecodeImageCallbacks::SelectDecoder(uint32_t fourcc,
63018                                     wuffs_base__slice_u8 prefix_data,
63019                                     bool prefix_closed) {
63020   switch (fourcc) {
63021 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BMP)
63022     case WUFFS_BASE__FOURCC__BMP:
63023       return wuffs_bmp__decoder::alloc_as__wuffs_base__image_decoder();
63024 #endif
63025 
63026 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GIF)
63027     case WUFFS_BASE__FOURCC__GIF:
63028       return wuffs_gif__decoder::alloc_as__wuffs_base__image_decoder();
63029 #endif
63030 
63031 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JPEG)
63032     case WUFFS_BASE__FOURCC__JPEG:
63033       return wuffs_jpeg__decoder::alloc_as__wuffs_base__image_decoder();
63034 #endif
63035 
63036 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NIE)
63037     case WUFFS_BASE__FOURCC__NIE:
63038       return wuffs_nie__decoder::alloc_as__wuffs_base__image_decoder();
63039 #endif
63040 
63041 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NETPBM)
63042     case WUFFS_BASE__FOURCC__NPBM:
63043       return wuffs_netpbm__decoder::alloc_as__wuffs_base__image_decoder();
63044 #endif
63045 
63046 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__PNG)
63047     case WUFFS_BASE__FOURCC__PNG: {
63048       auto dec = wuffs_png__decoder::alloc_as__wuffs_base__image_decoder();
63049       // Favor faster decodes over rejecting invalid checksums.
63050       dec->set_quirk(WUFFS_BASE__QUIRK_IGNORE_CHECKSUM, 1);
63051       return dec;
63052     }
63053 #endif
63054 
63055 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__TGA)
63056     case WUFFS_BASE__FOURCC__TGA:
63057       return wuffs_tga__decoder::alloc_as__wuffs_base__image_decoder();
63058 #endif
63059 
63060 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP)
63061     case WUFFS_BASE__FOURCC__WBMP:
63062       return wuffs_wbmp__decoder::alloc_as__wuffs_base__image_decoder();
63063 #endif
63064   }
63065 
63066   return wuffs_base__image_decoder::unique_ptr(nullptr);
63067 }
63068 
63069 std::string  //
HandleMetadata(const wuffs_base__more_information & minfo,wuffs_base__slice_u8 raw)63070 DecodeImageCallbacks::HandleMetadata(const wuffs_base__more_information& minfo,
63071                                      wuffs_base__slice_u8 raw) {
63072   return "";
63073 }
63074 
63075 wuffs_base__pixel_format  //
SelectPixfmt(const wuffs_base__image_config & image_config)63076 DecodeImageCallbacks::SelectPixfmt(
63077     const wuffs_base__image_config& image_config) {
63078   return wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL);
63079 }
63080 
63081 DecodeImageCallbacks::AllocPixbufResult  //
AllocPixbuf(const wuffs_base__image_config & image_config,bool allow_uninitialized_memory)63082 DecodeImageCallbacks::AllocPixbuf(const wuffs_base__image_config& image_config,
63083                                   bool allow_uninitialized_memory) {
63084   uint32_t w = image_config.pixcfg.width();
63085   uint32_t h = image_config.pixcfg.height();
63086   if ((w == 0) || (h == 0)) {
63087     return AllocPixbufResult("");
63088   }
63089   uint64_t len = image_config.pixcfg.pixbuf_len();
63090   if ((len == 0) || (SIZE_MAX < len)) {
63091     return AllocPixbufResult(DecodeImage_UnsupportedPixelConfiguration);
63092   }
63093   void* ptr =
63094       allow_uninitialized_memory ? malloc((size_t)len) : calloc((size_t)len, 1);
63095   if (!ptr) {
63096     return AllocPixbufResult(DecodeImage_OutOfMemory);
63097   }
63098   wuffs_base__pixel_buffer pixbuf;
63099   wuffs_base__status status = pixbuf.set_from_slice(
63100       &image_config.pixcfg,
63101       wuffs_base__make_slice_u8((uint8_t*)ptr, (size_t)len));
63102   if (!status.is_ok()) {
63103     free(ptr);
63104     return AllocPixbufResult(status.message());
63105   }
63106   return AllocPixbufResult(MemOwner(ptr, &free), pixbuf);
63107 }
63108 
63109 DecodeImageCallbacks::AllocWorkbufResult  //
AllocWorkbuf(wuffs_base__range_ii_u64 len_range,bool allow_uninitialized_memory)63110 DecodeImageCallbacks::AllocWorkbuf(wuffs_base__range_ii_u64 len_range,
63111                                    bool allow_uninitialized_memory) {
63112   uint64_t len = len_range.max_incl;
63113   if (len == 0) {
63114     return AllocWorkbufResult("");
63115   } else if (SIZE_MAX < len) {
63116     return AllocWorkbufResult(DecodeImage_OutOfMemory);
63117   }
63118   void* ptr =
63119       allow_uninitialized_memory ? malloc((size_t)len) : calloc((size_t)len, 1);
63120   if (!ptr) {
63121     return AllocWorkbufResult(DecodeImage_OutOfMemory);
63122   }
63123   return AllocWorkbufResult(
63124       MemOwner(ptr, &free),
63125       wuffs_base__make_slice_u8((uint8_t*)ptr, (size_t)len));
63126 }
63127 
63128 void  //
Done(DecodeImageResult & result,sync_io::Input & input,IOBuffer & buffer,wuffs_base__image_decoder::unique_ptr image_decoder)63129 DecodeImageCallbacks::Done(
63130     DecodeImageResult& result,
63131     sync_io::Input& input,
63132     IOBuffer& buffer,
63133     wuffs_base__image_decoder::unique_ptr image_decoder) {}
63134 
63135 const char DecodeImage_BufferIsTooShort[] =  //
63136     "wuffs_aux::DecodeImage: buffer is too short";
63137 const char DecodeImage_MaxInclDimensionExceeded[] =  //
63138     "wuffs_aux::DecodeImage: max_incl_dimension exceeded";
63139 const char DecodeImage_MaxInclMetadataLengthExceeded[] =  //
63140     "wuffs_aux::DecodeImage: max_incl_metadata_length exceeded";
63141 const char DecodeImage_OutOfMemory[] =  //
63142     "wuffs_aux::DecodeImage: out of memory";
63143 const char DecodeImage_UnexpectedEndOfFile[] =  //
63144     "wuffs_aux::DecodeImage: unexpected end of file";
63145 const char DecodeImage_UnsupportedImageFormat[] =  //
63146     "wuffs_aux::DecodeImage: unsupported image format";
63147 const char DecodeImage_UnsupportedMetadata[] =  //
63148     "wuffs_aux::DecodeImage: unsupported metadata";
63149 const char DecodeImage_UnsupportedPixelBlend[] =  //
63150     "wuffs_aux::DecodeImage: unsupported pixel blend";
63151 const char DecodeImage_UnsupportedPixelConfiguration[] =  //
63152     "wuffs_aux::DecodeImage: unsupported pixel configuration";
63153 const char DecodeImage_UnsupportedPixelFormat[] =  //
63154     "wuffs_aux::DecodeImage: unsupported pixel format";
63155 
DecodeImageArgQuirks(wuffs_base__slice_u32 repr0)63156 DecodeImageArgQuirks::DecodeImageArgQuirks(wuffs_base__slice_u32 repr0)
63157     : repr(repr0) {}
63158 
DecodeImageArgQuirks(uint32_t * ptr0,size_t len0)63159 DecodeImageArgQuirks::DecodeImageArgQuirks(uint32_t* ptr0, size_t len0)
63160     : repr(wuffs_base__make_slice_u32(ptr0, len0)) {}
63161 
63162 DecodeImageArgQuirks  //
DefaultValue()63163 DecodeImageArgQuirks::DefaultValue() {
63164   return DecodeImageArgQuirks(wuffs_base__empty_slice_u32());
63165 }
63166 
DecodeImageArgFlags(uint64_t repr0)63167 DecodeImageArgFlags::DecodeImageArgFlags(uint64_t repr0) : repr(repr0) {}
63168 
63169 DecodeImageArgFlags  //
DefaultValue()63170 DecodeImageArgFlags::DefaultValue() {
63171   return DecodeImageArgFlags(0);
63172 }
63173 
DecodeImageArgPixelBlend(wuffs_base__pixel_blend repr0)63174 DecodeImageArgPixelBlend::DecodeImageArgPixelBlend(
63175     wuffs_base__pixel_blend repr0)
63176     : repr(repr0) {}
63177 
63178 DecodeImageArgPixelBlend  //
DefaultValue()63179 DecodeImageArgPixelBlend::DefaultValue() {
63180   return DecodeImageArgPixelBlend(WUFFS_BASE__PIXEL_BLEND__SRC);
63181 }
63182 
DecodeImageArgBackgroundColor(wuffs_base__color_u32_argb_premul repr0)63183 DecodeImageArgBackgroundColor::DecodeImageArgBackgroundColor(
63184     wuffs_base__color_u32_argb_premul repr0)
63185     : repr(repr0) {}
63186 
63187 DecodeImageArgBackgroundColor  //
DefaultValue()63188 DecodeImageArgBackgroundColor::DefaultValue() {
63189   return DecodeImageArgBackgroundColor(1);
63190 }
63191 
DecodeImageArgMaxInclDimension(uint32_t repr0)63192 DecodeImageArgMaxInclDimension::DecodeImageArgMaxInclDimension(uint32_t repr0)
63193     : repr(repr0) {}
63194 
63195 DecodeImageArgMaxInclDimension  //
DefaultValue()63196 DecodeImageArgMaxInclDimension::DefaultValue() {
63197   return DecodeImageArgMaxInclDimension(1048575);
63198 }
63199 
DecodeImageArgMaxInclMetadataLength(uint64_t repr0)63200 DecodeImageArgMaxInclMetadataLength::DecodeImageArgMaxInclMetadataLength(
63201     uint64_t repr0)
63202     : repr(repr0) {}
63203 
63204 DecodeImageArgMaxInclMetadataLength  //
DefaultValue()63205 DecodeImageArgMaxInclMetadataLength::DefaultValue() {
63206   return DecodeImageArgMaxInclMetadataLength(16777215);
63207 }
63208 
63209 // --------
63210 
63211 namespace {
63212 
63213 const private_impl::ErrorMessages DecodeImageErrorMessages = {
63214     DecodeImage_MaxInclMetadataLengthExceeded,  //
63215     DecodeImage_OutOfMemory,                    //
63216     DecodeImage_UnexpectedEndOfFile,            //
63217     DecodeImage_UnsupportedMetadata,            //
63218     DecodeImage_UnsupportedImageFormat,         //
63219 };
63220 
63221 std::string  //
DecodeImageAdvanceIOBufferTo(sync_io::Input & input,wuffs_base__io_buffer & io_buf,uint64_t absolute_position)63222 DecodeImageAdvanceIOBufferTo(sync_io::Input& input,
63223                              wuffs_base__io_buffer& io_buf,
63224                              uint64_t absolute_position) {
63225   return private_impl::AdvanceIOBufferTo(DecodeImageErrorMessages, input,
63226                                          io_buf, absolute_position);
63227 }
63228 
63229 wuffs_base__status  //
DIHM0(void * self,wuffs_base__io_buffer * a_dst,wuffs_base__more_information * a_minfo,wuffs_base__io_buffer * a_src)63230 DIHM0(void* self,
63231       wuffs_base__io_buffer* a_dst,
63232       wuffs_base__more_information* a_minfo,
63233       wuffs_base__io_buffer* a_src) {
63234   return wuffs_base__image_decoder__tell_me_more(
63235       static_cast<wuffs_base__image_decoder*>(self), a_dst, a_minfo, a_src);
63236 }
63237 
63238 std::string  //
DIHM1(void * self,const wuffs_base__more_information * minfo,wuffs_base__slice_u8 raw)63239 DIHM1(void* self,
63240       const wuffs_base__more_information* minfo,
63241       wuffs_base__slice_u8 raw) {
63242   return static_cast<DecodeImageCallbacks*>(self)->HandleMetadata(*minfo, raw);
63243 }
63244 
63245 std::string  //
DecodeImageHandleMetadata(wuffs_base__image_decoder::unique_ptr & image_decoder,DecodeImageCallbacks & callbacks,sync_io::Input & input,wuffs_base__io_buffer & io_buf,sync_io::DynIOBuffer & raw_metadata_buf)63246 DecodeImageHandleMetadata(wuffs_base__image_decoder::unique_ptr& image_decoder,
63247                           DecodeImageCallbacks& callbacks,
63248                           sync_io::Input& input,
63249                           wuffs_base__io_buffer& io_buf,
63250                           sync_io::DynIOBuffer& raw_metadata_buf) {
63251   return private_impl::HandleMetadata(DecodeImageErrorMessages, input, io_buf,
63252                                       raw_metadata_buf, DIHM0,
63253                                       static_cast<void*>(image_decoder.get()),
63254                                       DIHM1, static_cast<void*>(&callbacks));
63255 }
63256 
63257 DecodeImageResult  //
DecodeImage0(wuffs_base__image_decoder::unique_ptr & image_decoder,DecodeImageCallbacks & callbacks,sync_io::Input & input,wuffs_base__io_buffer & io_buf,wuffs_base__slice_u32 quirks,uint64_t flags,wuffs_base__pixel_blend pixel_blend,wuffs_base__color_u32_argb_premul background_color,uint32_t max_incl_dimension,uint64_t max_incl_metadata_length)63258 DecodeImage0(wuffs_base__image_decoder::unique_ptr& image_decoder,
63259              DecodeImageCallbacks& callbacks,
63260              sync_io::Input& input,
63261              wuffs_base__io_buffer& io_buf,
63262              wuffs_base__slice_u32 quirks,
63263              uint64_t flags,
63264              wuffs_base__pixel_blend pixel_blend,
63265              wuffs_base__color_u32_argb_premul background_color,
63266              uint32_t max_incl_dimension,
63267              uint64_t max_incl_metadata_length) {
63268   // Check args.
63269   switch (pixel_blend) {
63270     case WUFFS_BASE__PIXEL_BLEND__SRC:
63271     case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
63272       break;
63273     default:
63274       return DecodeImageResult(DecodeImage_UnsupportedPixelBlend);
63275   }
63276 
63277   wuffs_base__image_config image_config = wuffs_base__null_image_config();
63278   sync_io::DynIOBuffer raw_metadata_buf(max_incl_metadata_length);
63279   uint64_t start_pos = io_buf.reader_position();
63280   bool interested_in_metadata_after_the_frame = false;
63281   bool redirected = false;
63282   int32_t fourcc = 0;
63283 redirect:
63284   do {
63285     // Determine the image format.
63286     if (!redirected) {
63287       while (true) {
63288         fourcc = wuffs_base__magic_number_guess_fourcc(io_buf.reader_slice(),
63289                                                        io_buf.meta.closed);
63290         if (fourcc > 0) {
63291           break;
63292         } else if ((fourcc == 0) && (io_buf.reader_length() >= 64)) {
63293           // Having (fourcc == 0) means that Wuffs' built in MIME sniffer
63294           // didn't recognize the image format. Nonetheless, custom callbacks
63295           // may still be able to do their own MIME sniffing, for exotic image
63296           // types. We try to give them at least 64 bytes of prefix data when
63297           // one-shot-calling callbacks.SelectDecoder. There is no mechanism
63298           // for the callbacks to request a longer prefix.
63299           break;
63300         } else if (io_buf.meta.closed || (io_buf.writer_length() == 0)) {
63301           fourcc = 0;
63302           break;
63303         }
63304         std::string error_message = input.CopyIn(&io_buf, 0);
63305         if (!error_message.empty()) {
63306           return DecodeImageResult(std::move(error_message));
63307         }
63308       }
63309     } else {
63310       wuffs_base__io_buffer empty = wuffs_base__empty_io_buffer();
63311       wuffs_base__more_information minfo = wuffs_base__empty_more_information();
63312       wuffs_base__status tmm_status =
63313           image_decoder->tell_me_more(&empty, &minfo, &io_buf);
63314       if (tmm_status.repr != nullptr) {
63315         return DecodeImageResult(tmm_status.message());
63316       }
63317       if (minfo.flavor != WUFFS_BASE__MORE_INFORMATION__FLAVOR__IO_REDIRECT) {
63318         return DecodeImageResult(DecodeImage_UnsupportedImageFormat);
63319       }
63320       uint64_t pos = minfo.io_redirect__range().min_incl;
63321       if (pos <= start_pos) {
63322         // Redirects must go forward.
63323         return DecodeImageResult(DecodeImage_UnsupportedImageFormat);
63324       }
63325       std::string error_message =
63326           DecodeImageAdvanceIOBufferTo(input, io_buf, pos);
63327       if (!error_message.empty()) {
63328         return DecodeImageResult(std::move(error_message));
63329       }
63330       fourcc = (int32_t)(minfo.io_redirect__fourcc());
63331       if (fourcc == 0) {
63332         return DecodeImageResult(DecodeImage_UnsupportedImageFormat);
63333       }
63334       image_decoder.reset();
63335     }
63336 
63337     // Select the image decoder.
63338     image_decoder = callbacks.SelectDecoder(
63339         (uint32_t)fourcc, io_buf.reader_slice(), io_buf.meta.closed);
63340     if (!image_decoder) {
63341       return DecodeImageResult(DecodeImage_UnsupportedImageFormat);
63342     }
63343 
63344     // Apply quirks.
63345     for (size_t i = 0; i < quirks.len; i++) {
63346       image_decoder->set_quirk(quirks.ptr[i], 1);
63347     }
63348 
63349     // Apply flags.
63350     if (flags != 0) {
63351       if (flags & DecodeImageArgFlags::REPORT_METADATA_CHRM) {
63352         image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__CHRM, true);
63353       }
63354       if (flags & DecodeImageArgFlags::REPORT_METADATA_EXIF) {
63355         interested_in_metadata_after_the_frame = true;
63356         image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__EXIF, true);
63357       }
63358       if (flags & DecodeImageArgFlags::REPORT_METADATA_GAMA) {
63359         image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__GAMA, true);
63360       }
63361       if (flags & DecodeImageArgFlags::REPORT_METADATA_ICCP) {
63362         image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__ICCP, true);
63363       }
63364       if (flags & DecodeImageArgFlags::REPORT_METADATA_KVP) {
63365         interested_in_metadata_after_the_frame = true;
63366         image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__KVP, true);
63367       }
63368       if (flags & DecodeImageArgFlags::REPORT_METADATA_SRGB) {
63369         image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__SRGB, true);
63370       }
63371       if (flags & DecodeImageArgFlags::REPORT_METADATA_XMP) {
63372         interested_in_metadata_after_the_frame = true;
63373         image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__XMP, true);
63374       }
63375     }
63376 
63377     // Decode the image config.
63378     while (true) {
63379       wuffs_base__status id_dic_status =
63380           image_decoder->decode_image_config(&image_config, &io_buf);
63381       if (id_dic_status.repr == nullptr) {
63382         break;
63383       } else if (id_dic_status.repr == wuffs_base__note__i_o_redirect) {
63384         if (redirected) {
63385           return DecodeImageResult(DecodeImage_UnsupportedImageFormat);
63386         }
63387         redirected = true;
63388         goto redirect;
63389       } else if (id_dic_status.repr == wuffs_base__note__metadata_reported) {
63390         std::string error_message = DecodeImageHandleMetadata(
63391             image_decoder, callbacks, input, io_buf, raw_metadata_buf);
63392         if (!error_message.empty()) {
63393           return DecodeImageResult(std::move(error_message));
63394         }
63395       } else if (id_dic_status.repr != wuffs_base__suspension__short_read) {
63396         return DecodeImageResult(id_dic_status.message());
63397       } else if (io_buf.meta.closed) {
63398         return DecodeImageResult(DecodeImage_UnexpectedEndOfFile);
63399       } else {
63400         std::string error_message =
63401             input.CopyIn(&io_buf, image_decoder->history_retain_length());
63402         if (!error_message.empty()) {
63403           return DecodeImageResult(std::move(error_message));
63404         }
63405       }
63406     }
63407   } while (false);
63408   if (!interested_in_metadata_after_the_frame) {
63409     raw_metadata_buf.drop();
63410   }
63411 
63412   // Select the pixel format.
63413   uint32_t w = image_config.pixcfg.width();
63414   uint32_t h = image_config.pixcfg.height();
63415   if ((w > max_incl_dimension) || (h > max_incl_dimension)) {
63416     return DecodeImageResult(DecodeImage_MaxInclDimensionExceeded);
63417   }
63418   wuffs_base__pixel_format pixel_format = callbacks.SelectPixfmt(image_config);
63419   if (pixel_format.repr != image_config.pixcfg.pixel_format().repr) {
63420     switch (pixel_format.repr) {
63421       case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
63422       case WUFFS_BASE__PIXEL_FORMAT__BGR:
63423       case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
63424       case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
63425       case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
63426       case WUFFS_BASE__PIXEL_FORMAT__RGB:
63427       case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
63428       case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
63429         break;
63430       default:
63431         return DecodeImageResult(DecodeImage_UnsupportedPixelFormat);
63432     }
63433     image_config.pixcfg.set(pixel_format.repr,
63434                             WUFFS_BASE__PIXEL_SUBSAMPLING__NONE, w, h);
63435   }
63436 
63437   // Allocate the pixel buffer.
63438   bool valid_background_color =
63439       wuffs_base__color_u32_argb_premul__is_valid(background_color);
63440   DecodeImageCallbacks::AllocPixbufResult alloc_pixbuf_result =
63441       callbacks.AllocPixbuf(image_config, valid_background_color);
63442   if (!alloc_pixbuf_result.error_message.empty()) {
63443     return DecodeImageResult(std::move(alloc_pixbuf_result.error_message));
63444   }
63445   wuffs_base__pixel_buffer pixel_buffer = alloc_pixbuf_result.pixbuf;
63446   if (valid_background_color) {
63447     wuffs_base__status pb_scufr_status = pixel_buffer.set_color_u32_fill_rect(
63448         pixel_buffer.pixcfg.bounds(), background_color);
63449     if (pb_scufr_status.repr != nullptr) {
63450       return DecodeImageResult(pb_scufr_status.message());
63451     }
63452   }
63453 
63454   // Allocate the work buffer. Wuffs' decoders conventionally assume that this
63455   // can be uninitialized memory.
63456   wuffs_base__range_ii_u64 workbuf_len = image_decoder->workbuf_len();
63457   DecodeImageCallbacks::AllocWorkbufResult alloc_workbuf_result =
63458       callbacks.AllocWorkbuf(workbuf_len, true);
63459   if (!alloc_workbuf_result.error_message.empty()) {
63460     return DecodeImageResult(std::move(alloc_workbuf_result.error_message));
63461   } else if (alloc_workbuf_result.workbuf.len < workbuf_len.min_incl) {
63462     return DecodeImageResult(DecodeImage_BufferIsTooShort);
63463   }
63464 
63465   // Decode the frame config.
63466   wuffs_base__frame_config frame_config = wuffs_base__null_frame_config();
63467   while (true) {
63468     wuffs_base__status id_dfc_status =
63469         image_decoder->decode_frame_config(&frame_config, &io_buf);
63470     if (id_dfc_status.repr == nullptr) {
63471       break;
63472     } else if (id_dfc_status.repr == wuffs_base__note__metadata_reported) {
63473       std::string error_message = DecodeImageHandleMetadata(
63474           image_decoder, callbacks, input, io_buf, raw_metadata_buf);
63475       if (!error_message.empty()) {
63476         return DecodeImageResult(std::move(error_message));
63477       }
63478     } else if (id_dfc_status.repr != wuffs_base__suspension__short_read) {
63479       return DecodeImageResult(id_dfc_status.message());
63480     } else if (io_buf.meta.closed) {
63481       return DecodeImageResult(DecodeImage_UnexpectedEndOfFile);
63482     } else {
63483       std::string error_message =
63484           input.CopyIn(&io_buf, image_decoder->history_retain_length());
63485       if (!error_message.empty()) {
63486         return DecodeImageResult(std::move(error_message));
63487       }
63488     }
63489   }
63490 
63491   // Decode the frame (the pixels).
63492   //
63493   // From here on, always returns the pixel_buffer. If we get this far, we can
63494   // still display a partial image, even if we encounter an error.
63495   std::string message("");
63496   if ((pixel_blend == WUFFS_BASE__PIXEL_BLEND__SRC_OVER) &&
63497       frame_config.overwrite_instead_of_blend()) {
63498     pixel_blend = WUFFS_BASE__PIXEL_BLEND__SRC;
63499   }
63500   while (true) {
63501     wuffs_base__status id_df_status =
63502         image_decoder->decode_frame(&pixel_buffer, &io_buf, pixel_blend,
63503                                     alloc_workbuf_result.workbuf, nullptr);
63504     if (id_df_status.repr == nullptr) {
63505       break;
63506     } else if (id_df_status.repr != wuffs_base__suspension__short_read) {
63507       message = id_df_status.message();
63508       break;
63509     } else if (io_buf.meta.closed) {
63510       message = DecodeImage_UnexpectedEndOfFile;
63511       break;
63512     } else {
63513       std::string error_message =
63514           input.CopyIn(&io_buf, image_decoder->history_retain_length());
63515       if (!error_message.empty()) {
63516         message = std::move(error_message);
63517         break;
63518       }
63519     }
63520   }
63521 
63522   // Decode any metadata after the frame.
63523   if (interested_in_metadata_after_the_frame) {
63524     while (true) {
63525       wuffs_base__status id_dfc_status =
63526           image_decoder->decode_frame_config(NULL, &io_buf);
63527       if (id_dfc_status.repr == wuffs_base__note__end_of_data) {
63528         break;
63529       } else if (id_dfc_status.repr == nullptr) {
63530         continue;
63531       } else if (id_dfc_status.repr == wuffs_base__note__metadata_reported) {
63532         std::string error_message = DecodeImageHandleMetadata(
63533             image_decoder, callbacks, input, io_buf, raw_metadata_buf);
63534         if (!error_message.empty()) {
63535           return DecodeImageResult(std::move(error_message));
63536         }
63537       } else if (id_dfc_status.repr != wuffs_base__suspension__short_read) {
63538         return DecodeImageResult(id_dfc_status.message());
63539       } else if (io_buf.meta.closed) {
63540         return DecodeImageResult(DecodeImage_UnexpectedEndOfFile);
63541       } else {
63542         std::string error_message =
63543             input.CopyIn(&io_buf, image_decoder->history_retain_length());
63544         if (!error_message.empty()) {
63545           return DecodeImageResult(std::move(error_message));
63546         }
63547       }
63548     }
63549   }
63550 
63551   return DecodeImageResult(std::move(alloc_pixbuf_result.mem_owner),
63552                            pixel_buffer, std::move(message));
63553 }
63554 
63555 }  // namespace
63556 
63557 DecodeImageResult  //
DecodeImage(DecodeImageCallbacks & callbacks,sync_io::Input & input,DecodeImageArgQuirks quirks,DecodeImageArgFlags flags,DecodeImageArgPixelBlend pixel_blend,DecodeImageArgBackgroundColor background_color,DecodeImageArgMaxInclDimension max_incl_dimension,DecodeImageArgMaxInclMetadataLength max_incl_metadata_length)63558 DecodeImage(DecodeImageCallbacks& callbacks,
63559             sync_io::Input& input,
63560             DecodeImageArgQuirks quirks,
63561             DecodeImageArgFlags flags,
63562             DecodeImageArgPixelBlend pixel_blend,
63563             DecodeImageArgBackgroundColor background_color,
63564             DecodeImageArgMaxInclDimension max_incl_dimension,
63565             DecodeImageArgMaxInclMetadataLength max_incl_metadata_length) {
63566   wuffs_base__io_buffer* io_buf = input.BringsItsOwnIOBuffer();
63567   wuffs_base__io_buffer fallback_io_buf = wuffs_base__empty_io_buffer();
63568   std::unique_ptr<uint8_t[]> fallback_io_array(nullptr);
63569   if (!io_buf) {
63570     fallback_io_array = std::unique_ptr<uint8_t[]>(new uint8_t[32768]);
63571     fallback_io_buf =
63572         wuffs_base__ptr_u8__writer(fallback_io_array.get(), 32768);
63573     io_buf = &fallback_io_buf;
63574   }
63575 
63576   wuffs_base__image_decoder::unique_ptr image_decoder(nullptr);
63577   DecodeImageResult result =
63578       DecodeImage0(image_decoder, callbacks, input, *io_buf, quirks.repr,
63579                    flags.repr, pixel_blend.repr, background_color.repr,
63580                    max_incl_dimension.repr, max_incl_metadata_length.repr);
63581   callbacks.Done(result, input, *io_buf, std::move(image_decoder));
63582   return result;
63583 }
63584 
63585 }  // namespace wuffs_aux
63586 
63587 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
63588         // defined(WUFFS_CONFIG__MODULE__AUX__IMAGE)
63589 
63590 // ---------------- Auxiliary - JSON
63591 
63592 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__AUX__JSON)
63593 
63594 #include <utility>
63595 
63596 namespace wuffs_aux {
63597 
DecodeJsonResult(std::string && error_message0,uint64_t cursor_position0)63598 DecodeJsonResult::DecodeJsonResult(std::string&& error_message0,
63599                                    uint64_t cursor_position0)
63600     : error_message(std::move(error_message0)),
63601       cursor_position(cursor_position0) {}
63602 
~DecodeJsonCallbacks()63603 DecodeJsonCallbacks::~DecodeJsonCallbacks() {}
63604 
63605 void  //
Done(DecodeJsonResult & result,sync_io::Input & input,IOBuffer & buffer)63606 DecodeJsonCallbacks::Done(DecodeJsonResult& result,
63607                           sync_io::Input& input,
63608                           IOBuffer& buffer) {}
63609 
63610 const char DecodeJson_BadJsonPointer[] =  //
63611     "wuffs_aux::DecodeJson: bad JSON Pointer";
63612 const char DecodeJson_NoMatch[] =  //
63613     "wuffs_aux::DecodeJson: no match";
63614 
DecodeJsonArgQuirks(wuffs_base__slice_u32 repr0)63615 DecodeJsonArgQuirks::DecodeJsonArgQuirks(wuffs_base__slice_u32 repr0)
63616     : repr(repr0) {}
63617 
DecodeJsonArgQuirks(uint32_t * ptr0,size_t len0)63618 DecodeJsonArgQuirks::DecodeJsonArgQuirks(uint32_t* ptr0, size_t len0)
63619     : repr(wuffs_base__make_slice_u32(ptr0, len0)) {}
63620 
63621 DecodeJsonArgQuirks  //
DefaultValue()63622 DecodeJsonArgQuirks::DefaultValue() {
63623   return DecodeJsonArgQuirks(wuffs_base__empty_slice_u32());
63624 }
63625 
DecodeJsonArgJsonPointer(std::string repr0)63626 DecodeJsonArgJsonPointer::DecodeJsonArgJsonPointer(std::string repr0)
63627     : repr(repr0) {}
63628 
63629 DecodeJsonArgJsonPointer  //
DefaultValue()63630 DecodeJsonArgJsonPointer::DefaultValue() {
63631   return DecodeJsonArgJsonPointer(std::string());
63632 }
63633 
63634 // --------
63635 
63636 #define WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN                           \
63637   while (tok_buf.meta.ri >= tok_buf.meta.wi) {                               \
63638     if (tok_status.repr == nullptr) {                                        \
63639       goto done;                                                             \
63640     } else if (tok_status.repr == wuffs_base__suspension__short_write) {     \
63641       tok_buf.compact();                                                     \
63642     } else if (tok_status.repr == wuffs_base__suspension__short_read) {      \
63643       if (!io_error_message.empty()) {                                       \
63644         ret_error_message = std::move(io_error_message);                     \
63645         goto done;                                                           \
63646       } else if (cursor_index != io_buf->meta.ri) {                          \
63647         ret_error_message =                                                  \
63648             "wuffs_aux::DecodeJson: internal error: bad cursor_index";       \
63649         goto done;                                                           \
63650       } else if (io_buf->meta.closed) {                                      \
63651         ret_error_message =                                                  \
63652             "wuffs_aux::DecodeJson: internal error: io_buf is closed";       \
63653         goto done;                                                           \
63654       }                                                                      \
63655       io_buf->compact_retaining(dec->history_retain_length());               \
63656       if (io_buf->meta.wi >= io_buf->data.len) {                             \
63657         ret_error_message =                                                  \
63658             "wuffs_aux::DecodeJson: internal error: io_buf is full";         \
63659         goto done;                                                           \
63660       }                                                                      \
63661       cursor_index = io_buf->meta.ri;                                        \
63662       io_error_message = input.CopyIn(io_buf, dec->history_retain_length()); \
63663     } else {                                                                 \
63664       ret_error_message = tok_status.message();                              \
63665       goto done;                                                             \
63666     }                                                                        \
63667     tok_status =                                                             \
63668         dec->decode_tokens(&tok_buf, io_buf, wuffs_base__empty_slice_u8());  \
63669     if ((tok_buf.meta.ri > tok_buf.meta.wi) ||                               \
63670         (tok_buf.meta.wi > tok_buf.data.len) ||                              \
63671         (io_buf->meta.ri > io_buf->meta.wi) ||                               \
63672         (io_buf->meta.wi > io_buf->data.len)) {                              \
63673       ret_error_message =                                                    \
63674           "wuffs_aux::DecodeJson: internal error: bad buffer indexes";       \
63675       goto done;                                                             \
63676     }                                                                        \
63677   }                                                                          \
63678   wuffs_base__token token = tok_buf.data.ptr[tok_buf.meta.ri++];             \
63679   uint64_t token_len = token.length();                                       \
63680   if ((io_buf->meta.ri < cursor_index) ||                                    \
63681       ((io_buf->meta.ri - cursor_index) < token_len)) {                      \
63682     ret_error_message =                                                      \
63683         "wuffs_aux::DecodeJson: internal error: bad token indexes";          \
63684     goto done;                                                               \
63685   }                                                                          \
63686   uint8_t* token_ptr = io_buf->data.ptr + cursor_index;                      \
63687   (void)(token_ptr);                                                         \
63688   cursor_index += static_cast<size_t>(token_len)
63689 
63690 // --------
63691 
63692 namespace {
63693 
63694 // DecodeJson_SplitJsonPointer returns ("bar", 8) for ("/foo/bar/b~1z/qux", 5,
63695 // etc). It returns a 0 size_t when s has invalid JSON Pointer syntax or i is
63696 // out of bounds.
63697 //
63698 // The string returned is unescaped. If calling it again, this time with i=8,
63699 // the "b~1z" substring would be returned as "b/z".
63700 std::pair<std::string, size_t>  //
DecodeJson_SplitJsonPointer(std::string & s,size_t i,bool allow_tilde_n_tilde_r_tilde_t)63701 DecodeJson_SplitJsonPointer(std::string& s,
63702                             size_t i,
63703                             bool allow_tilde_n_tilde_r_tilde_t) {
63704   std::string fragment;
63705   if (i > s.size()) {
63706     return std::make_pair(std::string(), 0);
63707   }
63708   while (i < s.size()) {
63709     char c = s[i];
63710     if (c == '/') {
63711       break;
63712     } else if (c != '~') {
63713       fragment.push_back(c);
63714       i++;
63715       continue;
63716     }
63717     i++;
63718     if (i >= s.size()) {
63719       return std::make_pair(std::string(), 0);
63720     }
63721     c = s[i];
63722     if (c == '0') {
63723       fragment.push_back('~');
63724       i++;
63725       continue;
63726     } else if (c == '1') {
63727       fragment.push_back('/');
63728       i++;
63729       continue;
63730     } else if (allow_tilde_n_tilde_r_tilde_t) {
63731       if (c == 'n') {
63732         fragment.push_back('\n');
63733         i++;
63734         continue;
63735       } else if (c == 'r') {
63736         fragment.push_back('\r');
63737         i++;
63738         continue;
63739       } else if (c == 't') {
63740         fragment.push_back('\t');
63741         i++;
63742         continue;
63743       }
63744     }
63745     return std::make_pair(std::string(), 0);
63746   }
63747   return std::make_pair(std::move(fragment), i);
63748 }
63749 
63750 // --------
63751 
63752 std::string  //
DecodeJson_WalkJsonPointerFragment(wuffs_base__token_buffer & tok_buf,wuffs_base__status & tok_status,wuffs_json__decoder::unique_ptr & dec,wuffs_base__io_buffer * io_buf,std::string & io_error_message,size_t & cursor_index,sync_io::Input & input,std::string & json_pointer_fragment)63753 DecodeJson_WalkJsonPointerFragment(wuffs_base__token_buffer& tok_buf,
63754                                    wuffs_base__status& tok_status,
63755                                    wuffs_json__decoder::unique_ptr& dec,
63756                                    wuffs_base__io_buffer* io_buf,
63757                                    std::string& io_error_message,
63758                                    size_t& cursor_index,
63759                                    sync_io::Input& input,
63760                                    std::string& json_pointer_fragment) {
63761   std::string ret_error_message;
63762   while (true) {
63763     WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;
63764 
63765     int64_t vbc = token.value_base_category();
63766     uint64_t vbd = token.value_base_detail();
63767     if (vbc == WUFFS_BASE__TOKEN__VBC__FILLER) {
63768       continue;
63769     } else if ((vbc != WUFFS_BASE__TOKEN__VBC__STRUCTURE) ||
63770                !(vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH)) {
63771       return DecodeJson_NoMatch;
63772     } else if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_LIST) {
63773       goto do_list;
63774     }
63775     goto do_dict;
63776   }
63777 
63778 do_dict:
63779   // Alternate between these two things:
63780   //  1. Decode the next dict key (a string). If it matches the fragment, we're
63781   //    done (success). If we've reached the dict's end (VBD__STRUCTURE__POP)
63782   //    so that there was no next dict key, we're done (failure).
63783   //  2. Otherwise, skip the next dict value.
63784   while (true) {
63785     for (std::string str; true;) {
63786       WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;
63787 
63788       int64_t vbc = token.value_base_category();
63789       uint64_t vbd = token.value_base_detail();
63790       switch (vbc) {
63791         case WUFFS_BASE__TOKEN__VBC__FILLER:
63792           continue;
63793 
63794         case WUFFS_BASE__TOKEN__VBC__STRUCTURE:
63795           if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {
63796             goto fail;
63797           }
63798           return DecodeJson_NoMatch;
63799 
63800         case WUFFS_BASE__TOKEN__VBC__STRING: {
63801           if (vbd & WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_0_DST_1_SRC_DROP) {
63802             // No-op.
63803           } else if (vbd &
63804                      WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_1_SRC_COPY) {
63805             const char* ptr =  // Convert from (uint8_t*).
63806                 static_cast<const char*>(static_cast<void*>(token_ptr));
63807             str.append(ptr, static_cast<size_t>(token_len));
63808           } else {
63809             goto fail;
63810           }
63811           break;
63812         }
63813 
63814         case WUFFS_BASE__TOKEN__VBC__UNICODE_CODE_POINT: {
63815           uint8_t u[WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL];
63816           size_t n = wuffs_base__utf_8__encode(
63817               wuffs_base__make_slice_u8(
63818                   &u[0], WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL),
63819               static_cast<uint32_t>(vbd));
63820           const char* ptr =  // Convert from (uint8_t*).
63821               static_cast<const char*>(static_cast<void*>(&u[0]));
63822           str.append(ptr, n);
63823           break;
63824         }
63825 
63826         default:
63827           goto fail;
63828       }
63829 
63830       if (token.continued()) {
63831         continue;
63832       }
63833       if (str == json_pointer_fragment) {
63834         return "";
63835       }
63836       goto skip_the_next_dict_value;
63837     }
63838 
63839   skip_the_next_dict_value:
63840     for (uint32_t skip_depth = 0; true;) {
63841       WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;
63842 
63843       int64_t vbc = token.value_base_category();
63844       uint64_t vbd = token.value_base_detail();
63845       if (token.continued() || (vbc == WUFFS_BASE__TOKEN__VBC__FILLER)) {
63846         continue;
63847       } else if (vbc == WUFFS_BASE__TOKEN__VBC__STRUCTURE) {
63848         if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {
63849           skip_depth++;
63850           continue;
63851         }
63852         skip_depth--;
63853       }
63854 
63855       if (skip_depth == 0) {
63856         break;
63857       }
63858     }  // skip_the_next_dict_value
63859   }    // do_dict
63860 
63861 do_list:
63862   do {
63863     wuffs_base__result_u64 result_u64 = wuffs_base__parse_number_u64(
63864         wuffs_base__make_slice_u8(
63865             static_cast<uint8_t*>(static_cast<void*>(
63866                 const_cast<char*>(json_pointer_fragment.data()))),
63867             json_pointer_fragment.size()),
63868         WUFFS_BASE__PARSE_NUMBER_XXX__DEFAULT_OPTIONS);
63869     if (!result_u64.status.is_ok()) {
63870       return DecodeJson_NoMatch;
63871     }
63872     uint64_t remaining = result_u64.value;
63873     if (remaining == 0) {
63874       goto check_that_a_value_follows;
63875     }
63876     for (uint32_t skip_depth = 0; true;) {
63877       WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;
63878 
63879       int64_t vbc = token.value_base_category();
63880       uint64_t vbd = token.value_base_detail();
63881       if (token.continued() || (vbc == WUFFS_BASE__TOKEN__VBC__FILLER)) {
63882         continue;
63883       } else if (vbc == WUFFS_BASE__TOKEN__VBC__STRUCTURE) {
63884         if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {
63885           skip_depth++;
63886           continue;
63887         }
63888         if (skip_depth == 0) {
63889           return DecodeJson_NoMatch;
63890         }
63891         skip_depth--;
63892       }
63893 
63894       if (skip_depth > 0) {
63895         continue;
63896       }
63897       remaining--;
63898       if (remaining == 0) {
63899         goto check_that_a_value_follows;
63900       }
63901     }
63902   } while (false);  // do_list
63903 
63904 check_that_a_value_follows:
63905   while (true) {
63906     WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;
63907 
63908     int64_t vbc = token.value_base_category();
63909     uint64_t vbd = token.value_base_detail();
63910     if (vbc == WUFFS_BASE__TOKEN__VBC__FILLER) {
63911       continue;
63912     }
63913 
63914     // Undo the last part of WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN, so
63915     // that we're only peeking at the next token.
63916     tok_buf.meta.ri--;
63917     cursor_index -= static_cast<size_t>(token_len);
63918 
63919     if ((vbc == WUFFS_BASE__TOKEN__VBC__STRUCTURE) &&
63920         (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__POP)) {
63921       return DecodeJson_NoMatch;
63922     }
63923     return "";
63924   }  // check_that_a_value_follows
63925 
63926 fail:
63927   return "wuffs_aux::DecodeJson: internal error: unexpected token";
63928 done:
63929   return ret_error_message;
63930 }
63931 
63932 }  // namespace
63933 
63934 // --------
63935 
63936 DecodeJsonResult  //
DecodeJson(DecodeJsonCallbacks & callbacks,sync_io::Input & input,DecodeJsonArgQuirks quirks,DecodeJsonArgJsonPointer json_pointer)63937 DecodeJson(DecodeJsonCallbacks& callbacks,
63938            sync_io::Input& input,
63939            DecodeJsonArgQuirks quirks,
63940            DecodeJsonArgJsonPointer json_pointer) {
63941   // Prepare the wuffs_base__io_buffer and the resultant error_message.
63942   wuffs_base__io_buffer* io_buf = input.BringsItsOwnIOBuffer();
63943   wuffs_base__io_buffer fallback_io_buf = wuffs_base__empty_io_buffer();
63944   std::unique_ptr<uint8_t[]> fallback_io_array(nullptr);
63945   if (!io_buf) {
63946     fallback_io_array = std::unique_ptr<uint8_t[]>(new uint8_t[4096]);
63947     fallback_io_buf = wuffs_base__ptr_u8__writer(fallback_io_array.get(), 4096);
63948     io_buf = &fallback_io_buf;
63949   }
63950   // cursor_index is discussed at
63951   // https://nigeltao.github.io/blog/2020/jsonptr.html#the-cursor-index
63952   size_t cursor_index = 0;
63953   std::string ret_error_message;
63954   std::string io_error_message;
63955 
63956   do {
63957     // Prepare the low-level JSON decoder.
63958     wuffs_json__decoder::unique_ptr dec = wuffs_json__decoder::alloc();
63959     if (!dec) {
63960       ret_error_message = "wuffs_aux::DecodeJson: out of memory";
63961       goto done;
63962     } else if (WUFFS_JSON__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE != 0) {
63963       ret_error_message =
63964           "wuffs_aux::DecodeJson: internal error: bad WORKBUF_LEN";
63965       goto done;
63966     }
63967     bool allow_tilde_n_tilde_r_tilde_t = false;
63968     for (size_t i = 0; i < quirks.repr.len; i++) {
63969       dec->set_quirk(quirks.repr.ptr[i], 1);
63970       if (quirks.repr.ptr[i] ==
63971           WUFFS_JSON__QUIRK_JSON_POINTER_ALLOW_TILDE_N_TILDE_R_TILDE_T) {
63972         allow_tilde_n_tilde_r_tilde_t = true;
63973       }
63974     }
63975 
63976     // Prepare the wuffs_base__tok_buffer. 256 tokens is 2KiB.
63977     wuffs_base__token tok_array[256];
63978     wuffs_base__token_buffer tok_buf =
63979         wuffs_base__slice_token__writer(wuffs_base__make_slice_token(
63980             &tok_array[0], (sizeof(tok_array) / sizeof(tok_array[0]))));
63981     wuffs_base__status tok_status =
63982         dec->decode_tokens(&tok_buf, io_buf, wuffs_base__empty_slice_u8());
63983 
63984     // Prepare other state.
63985     int32_t depth = 0;
63986     std::string str;
63987 
63988     // Walk the (optional) JSON Pointer.
63989     for (size_t i = 0; i < json_pointer.repr.size();) {
63990       if (json_pointer.repr[i] != '/') {
63991         ret_error_message = DecodeJson_BadJsonPointer;
63992         goto done;
63993       }
63994       std::pair<std::string, size_t> split = DecodeJson_SplitJsonPointer(
63995           json_pointer.repr, i + 1, allow_tilde_n_tilde_r_tilde_t);
63996       i = split.second;
63997       if (i == 0) {
63998         ret_error_message = DecodeJson_BadJsonPointer;
63999         goto done;
64000       }
64001       ret_error_message = DecodeJson_WalkJsonPointerFragment(
64002           tok_buf, tok_status, dec, io_buf, io_error_message, cursor_index,
64003           input, split.first);
64004       if (!ret_error_message.empty()) {
64005         goto done;
64006       }
64007     }
64008 
64009     // Loop, doing these two things:
64010     //  1. Get the next token.
64011     //  2. Process that token.
64012     while (true) {
64013       WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;
64014 
64015       int64_t vbc = token.value_base_category();
64016       uint64_t vbd = token.value_base_detail();
64017       switch (vbc) {
64018         case WUFFS_BASE__TOKEN__VBC__FILLER:
64019           continue;
64020 
64021         case WUFFS_BASE__TOKEN__VBC__STRUCTURE: {
64022           if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {
64023             ret_error_message = callbacks.Push(static_cast<uint32_t>(vbd));
64024             if (!ret_error_message.empty()) {
64025               goto done;
64026             }
64027             depth++;
64028             if (depth > WUFFS_JSON__DECODER_DEPTH_MAX_INCL) {
64029               ret_error_message =
64030                   "wuffs_aux::DecodeJson: internal error: bad depth";
64031               goto done;
64032             }
64033             continue;
64034           }
64035           ret_error_message = callbacks.Pop(static_cast<uint32_t>(vbd));
64036           depth--;
64037           if (depth < 0) {
64038             ret_error_message =
64039                 "wuffs_aux::DecodeJson: internal error: bad depth";
64040             goto done;
64041           }
64042           goto parsed_a_value;
64043         }
64044 
64045         case WUFFS_BASE__TOKEN__VBC__STRING: {
64046           if (vbd & WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_0_DST_1_SRC_DROP) {
64047             // No-op.
64048           } else if (vbd &
64049                      WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_1_SRC_COPY) {
64050             const char* ptr =  // Convert from (uint8_t*).
64051                 static_cast<const char*>(static_cast<void*>(token_ptr));
64052             str.append(ptr, static_cast<size_t>(token_len));
64053           } else {
64054             goto fail;
64055           }
64056           if (token.continued()) {
64057             continue;
64058           }
64059           ret_error_message = callbacks.AppendTextString(std::move(str));
64060           str.clear();
64061           goto parsed_a_value;
64062         }
64063 
64064         case WUFFS_BASE__TOKEN__VBC__UNICODE_CODE_POINT: {
64065           uint8_t u[WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL];
64066           size_t n = wuffs_base__utf_8__encode(
64067               wuffs_base__make_slice_u8(
64068                   &u[0], WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL),
64069               static_cast<uint32_t>(vbd));
64070           const char* ptr =  // Convert from (uint8_t*).
64071               static_cast<const char*>(static_cast<void*>(&u[0]));
64072           str.append(ptr, n);
64073           if (token.continued()) {
64074             continue;
64075           }
64076           goto fail;
64077         }
64078 
64079         case WUFFS_BASE__TOKEN__VBC__LITERAL: {
64080           ret_error_message =
64081               (vbd & WUFFS_BASE__TOKEN__VBD__LITERAL__NULL)
64082                   ? callbacks.AppendNull()
64083                   : callbacks.AppendBool(vbd &
64084                                          WUFFS_BASE__TOKEN__VBD__LITERAL__TRUE);
64085           goto parsed_a_value;
64086         }
64087 
64088         case WUFFS_BASE__TOKEN__VBC__NUMBER: {
64089           if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_TEXT) {
64090             if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_SIGNED) {
64091               wuffs_base__result_i64 r = wuffs_base__parse_number_i64(
64092                   wuffs_base__make_slice_u8(token_ptr,
64093                                             static_cast<size_t>(token_len)),
64094                   WUFFS_BASE__PARSE_NUMBER_XXX__DEFAULT_OPTIONS);
64095               if (r.status.is_ok()) {
64096                 ret_error_message = callbacks.AppendI64(r.value);
64097                 goto parsed_a_value;
64098               }
64099             }
64100             if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_FLOATING_POINT) {
64101               wuffs_base__result_f64 r = wuffs_base__parse_number_f64(
64102                   wuffs_base__make_slice_u8(token_ptr,
64103                                             static_cast<size_t>(token_len)),
64104                   WUFFS_BASE__PARSE_NUMBER_XXX__DEFAULT_OPTIONS);
64105               if (r.status.is_ok()) {
64106                 ret_error_message = callbacks.AppendF64(r.value);
64107                 goto parsed_a_value;
64108               }
64109             }
64110           } else if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_NEG_INF) {
64111             ret_error_message = callbacks.AppendF64(
64112                 wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
64113                     0xFFF0000000000000ul));
64114             goto parsed_a_value;
64115           } else if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_POS_INF) {
64116             ret_error_message = callbacks.AppendF64(
64117                 wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
64118                     0x7FF0000000000000ul));
64119             goto parsed_a_value;
64120           } else if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_NEG_NAN) {
64121             ret_error_message = callbacks.AppendF64(
64122                 wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
64123                     0xFFFFFFFFFFFFFFFFul));
64124             goto parsed_a_value;
64125           } else if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_POS_NAN) {
64126             ret_error_message = callbacks.AppendF64(
64127                 wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
64128                     0x7FFFFFFFFFFFFFFFul));
64129             goto parsed_a_value;
64130           }
64131           goto fail;
64132         }
64133       }
64134 
64135     fail:
64136       ret_error_message =
64137           "wuffs_aux::DecodeJson: internal error: unexpected token";
64138       goto done;
64139 
64140     parsed_a_value:
64141       // If an error was encountered, we are done. Otherwise, (depth == 0)
64142       // after parsing a value is equivalent to having decoded the entire JSON
64143       // value (for an empty json_pointer query) or having decoded the
64144       // pointed-to JSON value (for a non-empty json_pointer query). In the
64145       // latter case, we are also done.
64146       //
64147       // However, if quirks like WUFFS_JSON__QUIRK_ALLOW_TRAILING_FILLER or
64148       // WUFFS_JSON__QUIRK_EXPECT_TRAILING_NEW_LINE_OR_EOF are passed, decoding
64149       // the entire JSON value should also consume any trailing filler, in case
64150       // the DecodeJson caller wants to subsequently check that the input is
64151       // completely exhausted (and otherwise raise "valid JSON followed by
64152       // further (unexpected) data"). We aren't done yet. Instead, keep the
64153       // loop running until WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN's
64154       // decode_tokens returns an ok status.
64155       if (!ret_error_message.empty() ||
64156           ((depth == 0) && !json_pointer.repr.empty())) {
64157         goto done;
64158       }
64159     }
64160   } while (false);
64161 
64162 done:
64163   DecodeJsonResult result(
64164       std::move(ret_error_message),
64165       wuffs_base__u64__sat_add(io_buf->meta.pos, cursor_index));
64166   callbacks.Done(result, input, *io_buf);
64167   return result;
64168 }
64169 
64170 #undef WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN
64171 
64172 }  // namespace wuffs_aux
64173 
64174 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
64175         // defined(WUFFS_CONFIG__MODULE__AUX__JSON)
64176 
64177 #endif  // defined(__cplusplus) && defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
64178 
64179 #endif  // WUFFS_IMPLEMENTATION
64180 
64181 #if defined(__GNUC__)
64182 #pragma GCC diagnostic pop
64183 #elif defined(__clang__)
64184 #pragma clang diagnostic pop
64185 #endif
64186 
64187 #endif  // WUFFS_INCLUDE_GUARD
64188