xref: /aosp_15_r20/external/wuffs-mirror-release-c/release/c/wuffs-v0.3.c (revision 30889fd3ad667d11ca7a90e9af352e217875dd23)
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 (the "License");
41 // you may not use this file except in compliance with the License.
42 // You may obtain a copy of the License at
43 //
44 //    https://www.apache.org/licenses/LICENSE-2.0
45 //
46 // Unless required by applicable law or agreed to in writing, software
47 // distributed under the License is distributed on an "AS IS" BASIS,
48 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
49 // See the License for the specific language governing permissions and
50 // limitations under the License.
51 
52 #include <stdbool.h>
53 #include <stdint.h>
54 #include <stdlib.h>
55 #include <string.h>
56 
57 #ifdef __cplusplus
58 #if (__cplusplus >= 201103L) || defined(_MSC_VER)
59 #include <memory>
60 #define WUFFS_BASE__HAVE_EQ_DELETE
61 #define WUFFS_BASE__HAVE_UNIQUE_PTR
62 // The "defined(__clang__)" isn't redundant. While vanilla clang defines
63 // __GNUC__, clang-cl (which mimics MSVC's cl.exe) does not.
64 #elif defined(__GNUC__) || defined(__clang__)
65 #warning "Wuffs' C++ code expects -std=c++11 or later"
66 #endif
67 
68 extern "C" {
69 #endif
70 
71 // ---------------- Version
72 
73 // WUFFS_VERSION is the major.minor.patch version, as per https://semver.org/,
74 // as a uint64_t. The major number is the high 32 bits. The minor number is the
75 // middle 16 bits. The patch number is the low 16 bits. The pre-release label
76 // and build metadata are part of the string representation (such as
77 // "1.2.3-beta+456.20181231") but not the uint64_t representation.
78 //
79 // WUFFS_VERSION_PRE_RELEASE_LABEL (such as "", "beta" or "rc.1") being
80 // non-empty denotes a developer preview, not a release version, and has no
81 // backwards or forwards compatibility guarantees.
82 //
83 // WUFFS_VERSION_BUILD_METADATA_XXX, if non-zero, are the number of commits and
84 // the last commit date in the repository used to build this library. Within
85 // each major.minor branch, the commit count should increase monotonically.
86 //
87 // WUFFS_VERSION was overridden by "wuffs gen -version" based on revision
88 // 161e4730d8b446a72d6152b8343da8543e7518bf committed on 2021-11-18.
89 #define WUFFS_VERSION 0x000030000
90 #define WUFFS_VERSION_MAJOR 0
91 #define WUFFS_VERSION_MINOR 3
92 #define WUFFS_VERSION_PATCH 0
93 #define WUFFS_VERSION_PRE_RELEASE_LABEL "beta.11"
94 #define WUFFS_VERSION_BUILD_METADATA_COMMIT_COUNT 3198
95 #define WUFFS_VERSION_BUILD_METADATA_COMMIT_DATE 20211118
96 #define WUFFS_VERSION_STRING "0.3.0-beta.11+3198.20211118"
97 
98 // ---------------- Configuration
99 
100 // Define WUFFS_CONFIG__AVOID_CPU_ARCH to avoid any code tied to a specific CPU
101 // architecture, such as SSE SIMD for the x86 CPU family.
102 #if defined(WUFFS_CONFIG__AVOID_CPU_ARCH)  // (#if-chain ref AVOID_CPU_ARCH_0)
103 // No-op.
104 #else  // (#if-chain ref AVOID_CPU_ARCH_0)
105 
106 // The "defined(__clang__)" isn't redundant. While vanilla clang defines
107 // __GNUC__, clang-cl (which mimics MSVC's cl.exe) does not.
108 #if defined(__GNUC__) || defined(__clang__)
109 #define WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET(arg) __attribute__((target(arg)))
110 #else
111 #define WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET(arg)
112 #endif  // defined(__GNUC__) || defined(__clang__)
113 
114 #if defined(__GNUC__)  // (#if-chain ref AVOID_CPU_ARCH_1)
115 
116 // To simplify Wuffs code, "cpu_arch >= arm_xxx" requires xxx but also
117 // unaligned little-endian load/stores.
118 #if defined(__ARM_FEATURE_UNALIGNED) && !defined(__native_client__) && \
119     defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
120 // Not all gcc versions define __ARM_ACLE, even if they support crc32
121 // intrinsics. Look for __ARM_FEATURE_CRC32 instead.
122 #if defined(__ARM_FEATURE_CRC32)
123 #include <arm_acle.h>
124 #define WUFFS_BASE__CPU_ARCH__ARM_CRC32
125 #endif  // defined(__ARM_FEATURE_CRC32)
126 #if defined(__ARM_NEON)
127 #include <arm_neon.h>
128 #define WUFFS_BASE__CPU_ARCH__ARM_NEON
129 #endif  // defined(__ARM_NEON)
130 #endif  // defined(__ARM_FEATURE_UNALIGNED) etc
131 
132 // Similarly, "cpu_arch >= x86_sse42" requires SSE4.2 but also PCLMUL and
133 // POPCNT. This is checked at runtime via cpuid, not at compile time.
134 //
135 // Likewise, "cpu_arch >= x86_avx2" also requires PCLMUL, POPCNT and SSE4.2.
136 #if defined(__i386__) || defined(__x86_64__)
137 #if !defined(__native_client__)
138 #include <cpuid.h>
139 #include <x86intrin.h>
140 // X86_FAMILY means X86 (32-bit) or X86_64 (64-bit, obviously).
141 #define WUFFS_BASE__CPU_ARCH__X86_FAMILY
142 #endif  // !defined(__native_client__)
143 #endif  // defined(__i386__) || defined(__x86_64__)
144 
145 #elif defined(_MSC_VER)  // (#if-chain ref AVOID_CPU_ARCH_1)
146 
147 #if defined(_M_IX86) || defined(_M_X64)
148 #if defined(__AVX__) || defined(__clang__)
149 
150 // We need <intrin.h> for the __cpuid function.
151 #include <intrin.h>
152 // That's not enough for X64 SIMD, with clang-cl, if we want to use
153 // "__attribute__((target(arg)))" without e.g. "/arch:AVX".
154 //
155 // Some web pages suggest that <immintrin.h> is all you need, as it pulls in
156 // the earlier SIMD families like SSE4.2, but that doesn't seem to work in
157 // practice, possibly for the same reason that just <intrin.h> doesn't work.
158 #include <immintrin.h>  // AVX, AVX2, FMA, POPCNT
159 #include <nmmintrin.h>  // SSE4.2
160 #include <wmmintrin.h>  // AES, PCLMUL
161 // X86_FAMILY means X86 (32-bit) or X86_64 (64-bit, obviously).
162 #define WUFFS_BASE__CPU_ARCH__X86_FAMILY
163 
164 #else  // defined(__AVX__) || defined(__clang__)
165 
166 // clang-cl (which defines both __clang__ and _MSC_VER) supports
167 // "__attribute__((target(arg)))".
168 //
169 // For MSVC's cl.exe (unlike clang or gcc), SIMD capability is a compile-time
170 // property of the source file (e.g. a /arch:AVX or -mavx compiler flag), not
171 // of individual functions (that can be conditionally selected at runtime).
172 #pragma message("Wuffs with MSVC+IX86/X64 needs /arch:AVX for best performance")
173 
174 #endif  // defined(__AVX__) || defined(__clang__)
175 #endif  // defined(_M_IX86) || defined(_M_X64)
176 
177 #endif  // (#if-chain ref AVOID_CPU_ARCH_1)
178 #endif  // (#if-chain ref AVOID_CPU_ARCH_0)
179 
180 // --------
181 
182 // Define WUFFS_CONFIG__STATIC_FUNCTIONS (combined with WUFFS_IMPLEMENTATION)
183 // to make all of Wuffs' functions have static storage.
184 //
185 // This can help the compiler ignore or discard unused code, which can produce
186 // faster compiles and smaller binaries. Other motivations are discussed in the
187 // "ALLOW STATIC IMPLEMENTATION" section of
188 // https://raw.githubusercontent.com/nothings/stb/master/docs/stb_howto.txt
189 #if defined(WUFFS_CONFIG__STATIC_FUNCTIONS)
190 #define WUFFS_BASE__MAYBE_STATIC static
191 #else
192 #define WUFFS_BASE__MAYBE_STATIC
193 #endif  // defined(WUFFS_CONFIG__STATIC_FUNCTIONS)
194 
195 // ---------------- CPU Architecture
196 
197 static inline bool  //
wuffs_base__cpu_arch__have_arm_crc32()198 wuffs_base__cpu_arch__have_arm_crc32() {
199 #if defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32)
200   return true;
201 #else
202   return false;
203 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32)
204 }
205 
206 static inline bool  //
wuffs_base__cpu_arch__have_arm_neon()207 wuffs_base__cpu_arch__have_arm_neon() {
208 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
209   return true;
210 #else
211   return false;
212 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
213 }
214 
215 static inline bool  //
wuffs_base__cpu_arch__have_x86_avx2()216 wuffs_base__cpu_arch__have_x86_avx2() {
217 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
218   // GCC defines these macros but MSVC does not.
219   //  - bit_AVX2 = (1 <<  5)
220   const unsigned int avx2_ebx7 = 0x00000020;
221   // GCC defines these macros but MSVC does not.
222   //  - bit_PCLMUL = (1 <<  1)
223   //  - bit_POPCNT = (1 << 23)
224   //  - bit_SSE4_2 = (1 << 20)
225   const unsigned int avx2_ecx1 = 0x00900002;
226 
227   // clang defines __GNUC__ and clang-cl defines _MSC_VER (but not __GNUC__).
228 #if defined(__GNUC__)
229   unsigned int eax7 = 0;
230   unsigned int ebx7 = 0;
231   unsigned int ecx7 = 0;
232   unsigned int edx7 = 0;
233   if (__get_cpuid_count(7, 0, &eax7, &ebx7, &ecx7, &edx7) &&
234       ((ebx7 & avx2_ebx7) == avx2_ebx7)) {
235     unsigned int eax1 = 0;
236     unsigned int ebx1 = 0;
237     unsigned int ecx1 = 0;
238     unsigned int edx1 = 0;
239     if (__get_cpuid(1, &eax1, &ebx1, &ecx1, &edx1) &&
240         ((ecx1 & avx2_ecx1) == avx2_ecx1)) {
241       return true;
242     }
243   }
244 #elif defined(_MSC_VER)  // defined(__GNUC__)
245   int x7[4];
246   __cpuidex(x7, 7, 0);
247   if ((((unsigned int)(x7[1])) & avx2_ebx7) == avx2_ebx7) {
248     int x1[4];
249     __cpuid(x1, 1);
250     if ((((unsigned int)(x1[2])) & avx2_ecx1) == avx2_ecx1) {
251       return true;
252     }
253   }
254 #else
255 #error "WUFFS_BASE__CPU_ARCH__ETC combined with an unsupported compiler"
256 #endif  // defined(__GNUC__); defined(_MSC_VER)
257 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
258   return false;
259 }
260 
261 static inline bool  //
wuffs_base__cpu_arch__have_x86_bmi2()262 wuffs_base__cpu_arch__have_x86_bmi2() {
263 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
264   // GCC defines these macros but MSVC does not.
265   //  - bit_BMI2 = (1 <<  8)
266   const unsigned int bmi2_ebx7 = 0x00000100;
267 
268   // clang defines __GNUC__ and clang-cl defines _MSC_VER (but not __GNUC__).
269 #if defined(__GNUC__)
270   unsigned int eax7 = 0;
271   unsigned int ebx7 = 0;
272   unsigned int ecx7 = 0;
273   unsigned int edx7 = 0;
274   if (__get_cpuid_count(7, 0, &eax7, &ebx7, &ecx7, &edx7) &&
275       ((ebx7 & bmi2_ebx7) == bmi2_ebx7)) {
276     return true;
277   }
278 #elif defined(_MSC_VER)  // defined(__GNUC__)
279   int x7[4];
280   __cpuidex(x7, 7, 0);
281   if ((((unsigned int)(x7[1])) & bmi2_ebx7) == bmi2_ebx7) {
282     return true;
283   }
284 #else
285 #error "WUFFS_BASE__CPU_ARCH__ETC combined with an unsupported compiler"
286 #endif  // defined(__GNUC__); defined(_MSC_VER)
287 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
288   return false;
289 }
290 
291 static inline bool  //
wuffs_base__cpu_arch__have_x86_sse42()292 wuffs_base__cpu_arch__have_x86_sse42() {
293 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
294   // GCC defines these macros but MSVC does not.
295   //  - bit_PCLMUL = (1 <<  1)
296   //  - bit_POPCNT = (1 << 23)
297   //  - bit_SSE4_2 = (1 << 20)
298   const unsigned int sse42_ecx1 = 0x00900002;
299 
300   // clang defines __GNUC__ and clang-cl defines _MSC_VER (but not __GNUC__).
301 #if defined(__GNUC__)
302   unsigned int eax1 = 0;
303   unsigned int ebx1 = 0;
304   unsigned int ecx1 = 0;
305   unsigned int edx1 = 0;
306   if (__get_cpuid(1, &eax1, &ebx1, &ecx1, &edx1) &&
307       ((ecx1 & sse42_ecx1) == sse42_ecx1)) {
308     return true;
309   }
310 #elif defined(_MSC_VER)  // defined(__GNUC__)
311   int x1[4];
312   __cpuid(x1, 1);
313   if ((((unsigned int)(x1[2])) & sse42_ecx1) == sse42_ecx1) {
314     return true;
315   }
316 #else
317 #error "WUFFS_BASE__CPU_ARCH__ETC combined with an unsupported compiler"
318 #endif  // defined(__GNUC__); defined(_MSC_VER)
319 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
320   return false;
321 }
322 
323 // ---------------- Fundamentals
324 
325 // Wuffs assumes that:
326 //  - converting a uint32_t to a size_t will never overflow.
327 //  - converting a size_t to a uint64_t will never overflow.
328 #if defined(__WORDSIZE)
329 #if (__WORDSIZE != 32) && (__WORDSIZE != 64)
330 #error "Wuffs requires a word size of either 32 or 64 bits"
331 #endif
332 #endif
333 
334 // The "defined(__clang__)" isn't redundant. While vanilla clang defines
335 // __GNUC__, clang-cl (which mimics MSVC's cl.exe) does not.
336 #if defined(__GNUC__) || defined(__clang__)
337 #define WUFFS_BASE__POTENTIALLY_UNUSED __attribute__((unused))
338 #define WUFFS_BASE__WARN_UNUSED_RESULT __attribute__((warn_unused_result))
339 #else
340 #define WUFFS_BASE__POTENTIALLY_UNUSED
341 #define WUFFS_BASE__WARN_UNUSED_RESULT
342 #endif
343 
344 // --------
345 
346 // Options (bitwise or'ed together) for wuffs_foo__bar__initialize functions.
347 
348 #define WUFFS_INITIALIZE__DEFAULT_OPTIONS ((uint32_t)0x00000000)
349 
350 // WUFFS_INITIALIZE__ALREADY_ZEROED means that the "self" receiver struct value
351 // has already been set to all zeroes.
352 #define WUFFS_INITIALIZE__ALREADY_ZEROED ((uint32_t)0x00000001)
353 
354 // WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED means that, absent
355 // WUFFS_INITIALIZE__ALREADY_ZEROED, only some of the "self" receiver struct
356 // value will be set to all zeroes. Internal buffers, which tend to be a large
357 // proportion of the struct's size, will be left uninitialized. Internal means
358 // that the buffer is contained by the receiver struct, as opposed to being
359 // passed as a separately allocated "work buffer".
360 //
361 // For more detail, see:
362 // https://github.com/google/wuffs/blob/main/doc/note/initialization.md
363 #define WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED \
364   ((uint32_t)0x00000002)
365 
366 // --------
367 
368 // wuffs_base__empty_struct is used when a Wuffs function returns an empty
369 // struct. In C, if a function f returns void, you can't say "x = f()", but in
370 // Wuffs, if a function g returns empty, you can say "y = g()".
371 typedef struct wuffs_base__empty_struct__struct {
372   // private_impl is a placeholder field. It isn't explicitly used, except that
373   // without it, the sizeof a struct with no fields can differ across C/C++
374   // compilers, and it is undefined behavior in C99. For example, gcc says that
375   // the sizeof an empty struct is 0, and g++ says that it is 1. This leads to
376   // ABI incompatibility if a Wuffs .c file is processed by one compiler and
377   // its .h file with another compiler.
378   //
379   // Instead, we explicitly insert an otherwise unused field, so that the
380   // sizeof this struct is always 1.
381   uint8_t private_impl;
382 } wuffs_base__empty_struct;
383 
384 static inline wuffs_base__empty_struct  //
wuffs_base__make_empty_struct()385 wuffs_base__make_empty_struct() {
386   wuffs_base__empty_struct ret;
387   ret.private_impl = 0;
388   return ret;
389 }
390 
391 // wuffs_base__utility is a placeholder receiver type. It enables what Java
392 // calls static methods, as opposed to regular methods.
393 typedef struct wuffs_base__utility__struct {
394   // private_impl is a placeholder field. It isn't explicitly used, except that
395   // without it, the sizeof a struct with no fields can differ across C/C++
396   // compilers, and it is undefined behavior in C99. For example, gcc says that
397   // the sizeof an empty struct is 0, and g++ says that it is 1. This leads to
398   // ABI incompatibility if a Wuffs .c file is processed by one compiler and
399   // its .h file with another compiler.
400   //
401   // Instead, we explicitly insert an otherwise unused field, so that the
402   // sizeof this struct is always 1.
403   uint8_t private_impl;
404 } wuffs_base__utility;
405 
406 typedef struct wuffs_base__vtable__struct {
407   const char* vtable_name;
408   const void* function_pointers;
409 } wuffs_base__vtable;
410 
411 // --------
412 
413 // See https://github.com/google/wuffs/blob/main/doc/note/statuses.md
414 typedef struct wuffs_base__status__struct {
415   const char* repr;
416 
417 #ifdef __cplusplus
418   inline bool is_complete() const;
419   inline bool is_error() const;
420   inline bool is_note() const;
421   inline bool is_ok() const;
422   inline bool is_suspension() const;
423   inline const char* message() const;
424 #endif  // __cplusplus
425 
426 } wuffs_base__status;
427 
428 extern const char wuffs_base__note__i_o_redirect[];
429 extern const char wuffs_base__note__end_of_data[];
430 extern const char wuffs_base__note__metadata_reported[];
431 extern const char wuffs_base__suspension__even_more_information[];
432 extern const char wuffs_base__suspension__mispositioned_read[];
433 extern const char wuffs_base__suspension__mispositioned_write[];
434 extern const char wuffs_base__suspension__short_read[];
435 extern const char wuffs_base__suspension__short_write[];
436 extern const char wuffs_base__error__bad_i_o_position[];
437 extern const char wuffs_base__error__bad_argument_length_too_short[];
438 extern const char wuffs_base__error__bad_argument[];
439 extern const char wuffs_base__error__bad_call_sequence[];
440 extern const char wuffs_base__error__bad_data[];
441 extern const char wuffs_base__error__bad_receiver[];
442 extern const char wuffs_base__error__bad_restart[];
443 extern const char wuffs_base__error__bad_sizeof_receiver[];
444 extern const char wuffs_base__error__bad_vtable[];
445 extern const char wuffs_base__error__bad_workbuf_length[];
446 extern const char wuffs_base__error__bad_wuffs_version[];
447 extern const char wuffs_base__error__cannot_return_a_suspension[];
448 extern const char wuffs_base__error__disabled_by_previous_error[];
449 extern const char wuffs_base__error__initialize_falsely_claimed_already_zeroed[];
450 extern const char wuffs_base__error__initialize_not_called[];
451 extern const char wuffs_base__error__interleaved_coroutine_calls[];
452 extern const char wuffs_base__error__no_more_information[];
453 extern const char wuffs_base__error__not_enough_data[];
454 extern const char wuffs_base__error__out_of_bounds[];
455 extern const char wuffs_base__error__unsupported_method[];
456 extern const char wuffs_base__error__unsupported_option[];
457 extern const char wuffs_base__error__unsupported_pixel_swizzler_option[];
458 extern const char wuffs_base__error__too_much_data[];
459 
460 static inline wuffs_base__status  //
wuffs_base__make_status(const char * repr)461 wuffs_base__make_status(const char* repr) {
462   wuffs_base__status z;
463   z.repr = repr;
464   return z;
465 }
466 
467 static inline bool  //
wuffs_base__status__is_complete(const wuffs_base__status * z)468 wuffs_base__status__is_complete(const wuffs_base__status* z) {
469   return (z->repr == NULL) || ((*z->repr != '$') && (*z->repr != '#'));
470 }
471 
472 static inline bool  //
wuffs_base__status__is_error(const wuffs_base__status * z)473 wuffs_base__status__is_error(const wuffs_base__status* z) {
474   return z->repr && (*z->repr == '#');
475 }
476 
477 static inline bool  //
wuffs_base__status__is_note(const wuffs_base__status * z)478 wuffs_base__status__is_note(const wuffs_base__status* z) {
479   return z->repr && (*z->repr != '$') && (*z->repr != '#');
480 }
481 
482 static inline bool  //
wuffs_base__status__is_ok(const wuffs_base__status * z)483 wuffs_base__status__is_ok(const wuffs_base__status* z) {
484   return z->repr == NULL;
485 }
486 
487 static inline bool  //
wuffs_base__status__is_suspension(const wuffs_base__status * z)488 wuffs_base__status__is_suspension(const wuffs_base__status* z) {
489   return z->repr && (*z->repr == '$');
490 }
491 
492 // wuffs_base__status__message strips the leading '$', '#' or '@'.
493 static inline const char*  //
wuffs_base__status__message(const wuffs_base__status * z)494 wuffs_base__status__message(const wuffs_base__status* z) {
495   if (z->repr) {
496     if ((*z->repr == '$') || (*z->repr == '#') || (*z->repr == '@')) {
497       return z->repr + 1;
498     }
499   }
500   return z->repr;
501 }
502 
503 #ifdef __cplusplus
504 
505 inline bool  //
is_complete()506 wuffs_base__status::is_complete() const {
507   return wuffs_base__status__is_complete(this);
508 }
509 
510 inline bool  //
is_error()511 wuffs_base__status::is_error() const {
512   return wuffs_base__status__is_error(this);
513 }
514 
515 inline bool  //
is_note()516 wuffs_base__status::is_note() const {
517   return wuffs_base__status__is_note(this);
518 }
519 
520 inline bool  //
is_ok()521 wuffs_base__status::is_ok() const {
522   return wuffs_base__status__is_ok(this);
523 }
524 
525 inline bool  //
is_suspension()526 wuffs_base__status::is_suspension() const {
527   return wuffs_base__status__is_suspension(this);
528 }
529 
530 inline const char*  //
message()531 wuffs_base__status::message() const {
532   return wuffs_base__status__message(this);
533 }
534 
535 #endif  // __cplusplus
536 
537 // --------
538 
539 // WUFFS_BASE__RESULT is a result type: either a status (an error) or a value.
540 //
541 // A result with all fields NULL or zero is as valid as a zero-valued T.
542 #define WUFFS_BASE__RESULT(T)  \
543   struct {                     \
544     wuffs_base__status status; \
545     T value;                   \
546   }
547 
548 typedef WUFFS_BASE__RESULT(double) wuffs_base__result_f64;
549 typedef WUFFS_BASE__RESULT(int64_t) wuffs_base__result_i64;
550 typedef WUFFS_BASE__RESULT(uint64_t) wuffs_base__result_u64;
551 
552 // --------
553 
554 // wuffs_base__transform__output is the result of transforming from a src slice
555 // to a dst slice.
556 typedef struct wuffs_base__transform__output__struct {
557   wuffs_base__status status;
558   size_t num_dst;
559   size_t num_src;
560 } wuffs_base__transform__output;
561 
562 // --------
563 
564 // FourCC constants. Four Character Codes are literally four ASCII characters
565 // (sometimes padded with ' ' spaces) that pack neatly into a signed or
566 // unsigned 32-bit integer. ASCII letters are conventionally upper case.
567 //
568 // They are often used to identify video codecs (e.g. "H265") and pixel formats
569 // (e.g. "YV12"). Wuffs uses them for that but also generally for naming
570 // various things: compression formats (e.g. "BZ2 "), image metadata (e.g.
571 // "EXIF"), file formats (e.g. "HTML"), etc.
572 //
573 // Wuffs' u32 values are big-endian ("JPEG" is 0x4A504547 not 0x4745504A) to
574 // preserve ordering: "JPEG" < "MP3 " and 0x4A504547 < 0x4D503320.
575 
576 // Background Color.
577 #define WUFFS_BASE__FOURCC__BGCL 0x4247434C
578 
579 // Bitmap.
580 #define WUFFS_BASE__FOURCC__BMP 0x424D5020
581 
582 // Brotli.
583 #define WUFFS_BASE__FOURCC__BRTL 0x4252544C
584 
585 // Bzip2.
586 #define WUFFS_BASE__FOURCC__BZ2 0x425A3220
587 
588 // Concise Binary Object Representation.
589 #define WUFFS_BASE__FOURCC__CBOR 0x43424F52
590 
591 // Primary Chromaticities and White Point.
592 #define WUFFS_BASE__FOURCC__CHRM 0x4348524D
593 
594 // Cascading Style Sheets.
595 #define WUFFS_BASE__FOURCC__CSS 0x43535320
596 
597 // Encapsulated PostScript.
598 #define WUFFS_BASE__FOURCC__EPS 0x45505320
599 
600 // Exchangeable Image File Format.
601 #define WUFFS_BASE__FOURCC__EXIF 0x45584946
602 
603 // Free Lossless Audio Codec.
604 #define WUFFS_BASE__FOURCC__FLAC 0x464C4143
605 
606 // Gamma Correction.
607 #define WUFFS_BASE__FOURCC__GAMA 0x47414D41
608 
609 // Graphics Interchange Format.
610 #define WUFFS_BASE__FOURCC__GIF 0x47494620
611 
612 // GNU Zip.
613 #define WUFFS_BASE__FOURCC__GZ 0x475A2020
614 
615 // High Efficiency Image File.
616 #define WUFFS_BASE__FOURCC__HEIF 0x48454946
617 
618 // Hypertext Markup Language.
619 #define WUFFS_BASE__FOURCC__HTML 0x48544D4C
620 
621 // International Color Consortium Profile.
622 #define WUFFS_BASE__FOURCC__ICCP 0x49434350
623 
624 // Icon.
625 #define WUFFS_BASE__FOURCC__ICO 0x49434F20
626 
627 // Icon Vector Graphics.
628 #define WUFFS_BASE__FOURCC__ICVG 0x49435647
629 
630 // Initialization.
631 #define WUFFS_BASE__FOURCC__INI 0x494E4920
632 
633 // Joint Photographic Experts Group.
634 #define WUFFS_BASE__FOURCC__JPEG 0x4A504547
635 
636 // JavaScript.
637 #define WUFFS_BASE__FOURCC__JS 0x4A532020
638 
639 // JavaScript Object Notation.
640 #define WUFFS_BASE__FOURCC__JSON 0x4A534F4E
641 
642 // JSON With Commas and Comments.
643 #define WUFFS_BASE__FOURCC__JWCC 0x4A574343
644 
645 // Key-Value Pair.
646 #define WUFFS_BASE__FOURCC__KVP 0x4B565020
647 
648 // Key-Value Pair (Key).
649 #define WUFFS_BASE__FOURCC__KVPK 0x4B56504B
650 
651 // Key-Value Pair (Value).
652 #define WUFFS_BASE__FOURCC__KVPV 0x4B565056
653 
654 // Lempel–Ziv 4.
655 #define WUFFS_BASE__FOURCC__LZ4 0x4C5A3420
656 
657 // Markdown.
658 #define WUFFS_BASE__FOURCC__MD 0x4D442020
659 
660 // Modification Time.
661 #define WUFFS_BASE__FOURCC__MTIM 0x4D54494D
662 
663 // MPEG-1 Audio Layer III.
664 #define WUFFS_BASE__FOURCC__MP3 0x4D503320
665 
666 // Naive Image.
667 #define WUFFS_BASE__FOURCC__NIE 0x4E494520
668 
669 // Offset (2-Dimensional).
670 #define WUFFS_BASE__FOURCC__OFS2 0x4F465332
671 
672 // Open Type Format.
673 #define WUFFS_BASE__FOURCC__OTF 0x4F544620
674 
675 // Portable Document Format.
676 #define WUFFS_BASE__FOURCC__PDF 0x50444620
677 
678 // Physical Dimensions.
679 #define WUFFS_BASE__FOURCC__PHYD 0x50485944
680 
681 // Portable Network Graphics.
682 #define WUFFS_BASE__FOURCC__PNG 0x504E4720
683 
684 // Portable Anymap.
685 #define WUFFS_BASE__FOURCC__PNM 0x504E4D20
686 
687 // PostScript.
688 #define WUFFS_BASE__FOURCC__PS 0x50532020
689 
690 // Random Access Compression.
691 #define WUFFS_BASE__FOURCC__RAC 0x52414320
692 
693 // Raw.
694 #define WUFFS_BASE__FOURCC__RAW 0x52415720
695 
696 // Resource Interchange File Format.
697 #define WUFFS_BASE__FOURCC__RIFF 0x52494646
698 
699 // Riegeli Records.
700 #define WUFFS_BASE__FOURCC__RIGL 0x5249474C
701 
702 // Snappy.
703 #define WUFFS_BASE__FOURCC__SNPY 0x534E5059
704 
705 // Standard Red Green Blue (Rendering Intent).
706 #define WUFFS_BASE__FOURCC__SRGB 0x53524742
707 
708 // Scalable Vector Graphics.
709 #define WUFFS_BASE__FOURCC__SVG 0x53564720
710 
711 // Tape Archive.
712 #define WUFFS_BASE__FOURCC__TAR 0x54415220
713 
714 // Text.
715 #define WUFFS_BASE__FOURCC__TEXT 0x54455854
716 
717 // Tagged Image File Format.
718 #define WUFFS_BASE__FOURCC__TIFF 0x54494646
719 
720 // Tom's Obvious Minimal Language.
721 #define WUFFS_BASE__FOURCC__TOML 0x544F4D4C
722 
723 // Waveform.
724 #define WUFFS_BASE__FOURCC__WAVE 0x57415645
725 
726 // Wireless Bitmap.
727 #define WUFFS_BASE__FOURCC__WBMP 0x57424D50
728 
729 // Web Open Font Format.
730 #define WUFFS_BASE__FOURCC__WOFF 0x574F4646
731 
732 // Web Picture (VP8).
733 #define WUFFS_BASE__FOURCC__WP8 0x57503820
734 
735 // Web Picture (VP8 Lossless).
736 #define WUFFS_BASE__FOURCC__WP8L 0x5750384C
737 
738 // Extensible Markup Language.
739 #define WUFFS_BASE__FOURCC__XML 0x584D4C20
740 
741 // Extensible Metadata Platform.
742 #define WUFFS_BASE__FOURCC__XMP 0x584D5020
743 
744 // Xz.
745 #define WUFFS_BASE__FOURCC__XZ 0x585A2020
746 
747 // Zip.
748 #define WUFFS_BASE__FOURCC__ZIP 0x5A495020
749 
750 // Zlib.
751 #define WUFFS_BASE__FOURCC__ZLIB 0x5A4C4942
752 
753 // Zstandard.
754 #define WUFFS_BASE__FOURCC__ZSTD 0x5A535444
755 
756 // --------
757 
758 // Quirks.
759 
760 #define WUFFS_BASE__QUIRK_IGNORE_CHECKSUM 1
761 
762 // --------
763 
764 // Flicks are a unit of time. One flick (frame-tick) is 1 / 705_600_000 of a
765 // second. See https://github.com/OculusVR/Flicks
766 typedef int64_t wuffs_base__flicks;
767 
768 #define WUFFS_BASE__FLICKS_PER_SECOND ((uint64_t)705600000)
769 #define WUFFS_BASE__FLICKS_PER_MILLISECOND ((uint64_t)705600)
770 
771 // ---------------- Numeric Types
772 
773 // The helpers below are functions, instead of macros, because their arguments
774 // can be an expression that we shouldn't evaluate more than once.
775 //
776 // They are static, so that linking multiple wuffs .o files won't complain about
777 // duplicate function definitions.
778 //
779 // They are explicitly marked inline, even if modern compilers don't use the
780 // inline attribute to guide optimizations such as inlining, to avoid the
781 // -Wunused-function warning, and we like to compile with -Wall -Werror.
782 
783 static inline int8_t  //
wuffs_base__i8__min(int8_t x,int8_t y)784 wuffs_base__i8__min(int8_t x, int8_t y) {
785   return x < y ? x : y;
786 }
787 
788 static inline int8_t  //
wuffs_base__i8__max(int8_t x,int8_t y)789 wuffs_base__i8__max(int8_t x, int8_t y) {
790   return x > y ? x : y;
791 }
792 
793 static inline int16_t  //
wuffs_base__i16__min(int16_t x,int16_t y)794 wuffs_base__i16__min(int16_t x, int16_t y) {
795   return x < y ? x : y;
796 }
797 
798 static inline int16_t  //
wuffs_base__i16__max(int16_t x,int16_t y)799 wuffs_base__i16__max(int16_t x, int16_t y) {
800   return x > y ? x : y;
801 }
802 
803 static inline int32_t  //
wuffs_base__i32__min(int32_t x,int32_t y)804 wuffs_base__i32__min(int32_t x, int32_t y) {
805   return x < y ? x : y;
806 }
807 
808 static inline int32_t  //
wuffs_base__i32__max(int32_t x,int32_t y)809 wuffs_base__i32__max(int32_t x, int32_t y) {
810   return x > y ? x : y;
811 }
812 
813 static inline int64_t  //
wuffs_base__i64__min(int64_t x,int64_t y)814 wuffs_base__i64__min(int64_t x, int64_t y) {
815   return x < y ? x : y;
816 }
817 
818 static inline int64_t  //
wuffs_base__i64__max(int64_t x,int64_t y)819 wuffs_base__i64__max(int64_t x, int64_t y) {
820   return x > y ? x : y;
821 }
822 
823 static inline uint8_t  //
wuffs_base__u8__min(uint8_t x,uint8_t y)824 wuffs_base__u8__min(uint8_t x, uint8_t y) {
825   return x < y ? x : y;
826 }
827 
828 static inline uint8_t  //
wuffs_base__u8__max(uint8_t x,uint8_t y)829 wuffs_base__u8__max(uint8_t x, uint8_t y) {
830   return x > y ? x : y;
831 }
832 
833 static inline uint16_t  //
wuffs_base__u16__min(uint16_t x,uint16_t y)834 wuffs_base__u16__min(uint16_t x, uint16_t y) {
835   return x < y ? x : y;
836 }
837 
838 static inline uint16_t  //
wuffs_base__u16__max(uint16_t x,uint16_t y)839 wuffs_base__u16__max(uint16_t x, uint16_t y) {
840   return x > y ? x : y;
841 }
842 
843 static inline uint32_t  //
wuffs_base__u32__min(uint32_t x,uint32_t y)844 wuffs_base__u32__min(uint32_t x, uint32_t y) {
845   return x < y ? x : y;
846 }
847 
848 static inline uint32_t  //
wuffs_base__u32__max(uint32_t x,uint32_t y)849 wuffs_base__u32__max(uint32_t x, uint32_t y) {
850   return x > y ? x : y;
851 }
852 
853 static inline uint64_t  //
wuffs_base__u64__min(uint64_t x,uint64_t y)854 wuffs_base__u64__min(uint64_t x, uint64_t y) {
855   return x < y ? x : y;
856 }
857 
858 static inline uint64_t  //
wuffs_base__u64__max(uint64_t x,uint64_t y)859 wuffs_base__u64__max(uint64_t x, uint64_t y) {
860   return x > y ? x : y;
861 }
862 
863 // --------
864 
865 static inline uint8_t  //
wuffs_base__u8__rotate_left(uint8_t x,uint32_t n)866 wuffs_base__u8__rotate_left(uint8_t x, uint32_t n) {
867   n &= 7;
868   return ((uint8_t)(x << n)) | ((uint8_t)(x >> (8 - n)));
869 }
870 
871 static inline uint8_t  //
wuffs_base__u8__rotate_right(uint8_t x,uint32_t n)872 wuffs_base__u8__rotate_right(uint8_t x, uint32_t n) {
873   n &= 7;
874   return ((uint8_t)(x >> n)) | ((uint8_t)(x << (8 - n)));
875 }
876 
877 static inline uint16_t  //
wuffs_base__u16__rotate_left(uint16_t x,uint32_t n)878 wuffs_base__u16__rotate_left(uint16_t x, uint32_t n) {
879   n &= 15;
880   return ((uint16_t)(x << n)) | ((uint16_t)(x >> (16 - n)));
881 }
882 
883 static inline uint16_t  //
wuffs_base__u16__rotate_right(uint16_t x,uint32_t n)884 wuffs_base__u16__rotate_right(uint16_t x, uint32_t n) {
885   n &= 15;
886   return ((uint16_t)(x >> n)) | ((uint16_t)(x << (16 - n)));
887 }
888 
889 static inline uint32_t  //
wuffs_base__u32__rotate_left(uint32_t x,uint32_t n)890 wuffs_base__u32__rotate_left(uint32_t x, uint32_t n) {
891   n &= 31;
892   return ((uint32_t)(x << n)) | ((uint32_t)(x >> (32 - n)));
893 }
894 
895 static inline uint32_t  //
wuffs_base__u32__rotate_right(uint32_t x,uint32_t n)896 wuffs_base__u32__rotate_right(uint32_t x, uint32_t n) {
897   n &= 31;
898   return ((uint32_t)(x >> n)) | ((uint32_t)(x << (32 - n)));
899 }
900 
901 static inline uint64_t  //
wuffs_base__u64__rotate_left(uint64_t x,uint32_t n)902 wuffs_base__u64__rotate_left(uint64_t x, uint32_t n) {
903   n &= 63;
904   return ((uint64_t)(x << n)) | ((uint64_t)(x >> (64 - n)));
905 }
906 
907 static inline uint64_t  //
wuffs_base__u64__rotate_right(uint64_t x,uint32_t n)908 wuffs_base__u64__rotate_right(uint64_t x, uint32_t n) {
909   n &= 63;
910   return ((uint64_t)(x >> n)) | ((uint64_t)(x << (64 - n)));
911 }
912 
913 // --------
914 
915 // Saturating arithmetic (sat_add, sat_sub) branchless bit-twiddling algorithms
916 // are per https://locklessinc.com/articles/sat_arithmetic/
917 //
918 // It is important that the underlying types are unsigned integers, as signed
919 // integer arithmetic overflow is undefined behavior in C.
920 
921 static inline uint8_t  //
wuffs_base__u8__sat_add(uint8_t x,uint8_t y)922 wuffs_base__u8__sat_add(uint8_t x, uint8_t y) {
923   uint8_t res = (uint8_t)(x + y);
924   res |= (uint8_t)(-(res < x));
925   return res;
926 }
927 
928 static inline uint8_t  //
wuffs_base__u8__sat_sub(uint8_t x,uint8_t y)929 wuffs_base__u8__sat_sub(uint8_t x, uint8_t y) {
930   uint8_t res = (uint8_t)(x - y);
931   res &= (uint8_t)(-(res <= x));
932   return res;
933 }
934 
935 static inline uint16_t  //
wuffs_base__u16__sat_add(uint16_t x,uint16_t y)936 wuffs_base__u16__sat_add(uint16_t x, uint16_t y) {
937   uint16_t res = (uint16_t)(x + y);
938   res |= (uint16_t)(-(res < x));
939   return res;
940 }
941 
942 static inline uint16_t  //
wuffs_base__u16__sat_sub(uint16_t x,uint16_t y)943 wuffs_base__u16__sat_sub(uint16_t x, uint16_t y) {
944   uint16_t res = (uint16_t)(x - y);
945   res &= (uint16_t)(-(res <= x));
946   return res;
947 }
948 
949 static inline uint32_t  //
wuffs_base__u32__sat_add(uint32_t x,uint32_t y)950 wuffs_base__u32__sat_add(uint32_t x, uint32_t y) {
951   uint32_t res = (uint32_t)(x + y);
952   res |= (uint32_t)(-(res < x));
953   return res;
954 }
955 
956 static inline uint32_t  //
wuffs_base__u32__sat_sub(uint32_t x,uint32_t y)957 wuffs_base__u32__sat_sub(uint32_t x, uint32_t y) {
958   uint32_t res = (uint32_t)(x - y);
959   res &= (uint32_t)(-(res <= x));
960   return res;
961 }
962 
963 static inline uint64_t  //
wuffs_base__u64__sat_add(uint64_t x,uint64_t y)964 wuffs_base__u64__sat_add(uint64_t x, uint64_t y) {
965   uint64_t res = (uint64_t)(x + y);
966   res |= (uint64_t)(-(res < x));
967   return res;
968 }
969 
970 static inline uint64_t  //
wuffs_base__u64__sat_sub(uint64_t x,uint64_t y)971 wuffs_base__u64__sat_sub(uint64_t x, uint64_t y) {
972   uint64_t res = (uint64_t)(x - y);
973   res &= (uint64_t)(-(res <= x));
974   return res;
975 }
976 
977 // --------
978 
979 typedef struct wuffs_base__multiply_u64__output__struct {
980   uint64_t lo;
981   uint64_t hi;
982 } wuffs_base__multiply_u64__output;
983 
984 // wuffs_base__multiply_u64 returns x*y as a 128-bit value.
985 //
986 // The maximum inclusive output hi_lo is 0xFFFFFFFFFFFFFFFE_0000000000000001.
987 static inline wuffs_base__multiply_u64__output  //
wuffs_base__multiply_u64(uint64_t x,uint64_t y)988 wuffs_base__multiply_u64(uint64_t x, uint64_t y) {
989 #if defined(__SIZEOF_INT128__)
990   __uint128_t z = ((__uint128_t)x) * ((__uint128_t)y);
991   wuffs_base__multiply_u64__output o;
992   o.lo = ((uint64_t)(z));
993   o.hi = ((uint64_t)(z >> 64));
994   return o;
995 #else
996   // TODO: consider using the _mul128 intrinsic if defined(_MSC_VER).
997   uint64_t x0 = x & 0xFFFFFFFF;
998   uint64_t x1 = x >> 32;
999   uint64_t y0 = y & 0xFFFFFFFF;
1000   uint64_t y1 = y >> 32;
1001   uint64_t w0 = x0 * y0;
1002   uint64_t t = (x1 * y0) + (w0 >> 32);
1003   uint64_t w1 = t & 0xFFFFFFFF;
1004   uint64_t w2 = t >> 32;
1005   w1 += x0 * y1;
1006   wuffs_base__multiply_u64__output o;
1007   o.lo = x * y;
1008   o.hi = (x1 * y1) + w2 + (w1 >> 32);
1009   return o;
1010 #endif
1011 }
1012 
1013 // --------
1014 
1015 // The "defined(__clang__)" isn't redundant. While vanilla clang defines
1016 // __GNUC__, clang-cl (which mimics MSVC's cl.exe) does not.
1017 #if (defined(__GNUC__) || defined(__clang__)) && (__SIZEOF_LONG__ == 8)
1018 
1019 static inline uint32_t  //
wuffs_base__count_leading_zeroes_u64(uint64_t u)1020 wuffs_base__count_leading_zeroes_u64(uint64_t u) {
1021   return u ? ((uint32_t)(__builtin_clzl(u))) : 64u;
1022 }
1023 
1024 #else
1025 // TODO: consider using the _BitScanReverse intrinsic if defined(_MSC_VER).
1026 
1027 static inline uint32_t  //
wuffs_base__count_leading_zeroes_u64(uint64_t u)1028 wuffs_base__count_leading_zeroes_u64(uint64_t u) {
1029   if (u == 0) {
1030     return 64;
1031   }
1032 
1033   uint32_t n = 0;
1034   if ((u >> 32) == 0) {
1035     n |= 32;
1036     u <<= 32;
1037   }
1038   if ((u >> 48) == 0) {
1039     n |= 16;
1040     u <<= 16;
1041   }
1042   if ((u >> 56) == 0) {
1043     n |= 8;
1044     u <<= 8;
1045   }
1046   if ((u >> 60) == 0) {
1047     n |= 4;
1048     u <<= 4;
1049   }
1050   if ((u >> 62) == 0) {
1051     n |= 2;
1052     u <<= 2;
1053   }
1054   if ((u >> 63) == 0) {
1055     n |= 1;
1056     u <<= 1;
1057   }
1058   return n;
1059 }
1060 
1061 #endif  // (defined(__GNUC__) || defined(__clang__)) && (__SIZEOF_LONG__ == 8)
1062 
1063 // --------
1064 
1065 #define wuffs_base__peek_u8be__no_bounds_check \
1066   wuffs_base__peek_u8__no_bounds_check
1067 #define wuffs_base__peek_u8le__no_bounds_check \
1068   wuffs_base__peek_u8__no_bounds_check
1069 
1070 static inline uint8_t  //
wuffs_base__peek_u8__no_bounds_check(const uint8_t * p)1071 wuffs_base__peek_u8__no_bounds_check(const uint8_t* p) {
1072   return p[0];
1073 }
1074 
1075 static inline uint16_t  //
wuffs_base__peek_u16be__no_bounds_check(const uint8_t * p)1076 wuffs_base__peek_u16be__no_bounds_check(const uint8_t* p) {
1077   return (uint16_t)(((uint16_t)(p[0]) << 8) | ((uint16_t)(p[1]) << 0));
1078 }
1079 
1080 static inline uint16_t  //
wuffs_base__peek_u16le__no_bounds_check(const uint8_t * p)1081 wuffs_base__peek_u16le__no_bounds_check(const uint8_t* p) {
1082   return (uint16_t)(((uint16_t)(p[0]) << 0) | ((uint16_t)(p[1]) << 8));
1083 }
1084 
1085 static inline uint32_t  //
wuffs_base__peek_u24be__no_bounds_check(const uint8_t * p)1086 wuffs_base__peek_u24be__no_bounds_check(const uint8_t* p) {
1087   return ((uint32_t)(p[0]) << 16) | ((uint32_t)(p[1]) << 8) |
1088          ((uint32_t)(p[2]) << 0);
1089 }
1090 
1091 static inline uint32_t  //
wuffs_base__peek_u24le__no_bounds_check(const uint8_t * p)1092 wuffs_base__peek_u24le__no_bounds_check(const uint8_t* p) {
1093   return ((uint32_t)(p[0]) << 0) | ((uint32_t)(p[1]) << 8) |
1094          ((uint32_t)(p[2]) << 16);
1095 }
1096 
1097 static inline uint32_t  //
wuffs_base__peek_u32be__no_bounds_check(const uint8_t * p)1098 wuffs_base__peek_u32be__no_bounds_check(const uint8_t* p) {
1099   return ((uint32_t)(p[0]) << 24) | ((uint32_t)(p[1]) << 16) |
1100          ((uint32_t)(p[2]) << 8) | ((uint32_t)(p[3]) << 0);
1101 }
1102 
1103 static inline uint32_t  //
wuffs_base__peek_u32le__no_bounds_check(const uint8_t * p)1104 wuffs_base__peek_u32le__no_bounds_check(const uint8_t* p) {
1105   return ((uint32_t)(p[0]) << 0) | ((uint32_t)(p[1]) << 8) |
1106          ((uint32_t)(p[2]) << 16) | ((uint32_t)(p[3]) << 24);
1107 }
1108 
1109 static inline uint64_t  //
wuffs_base__peek_u40be__no_bounds_check(const uint8_t * p)1110 wuffs_base__peek_u40be__no_bounds_check(const uint8_t* p) {
1111   return ((uint64_t)(p[0]) << 32) | ((uint64_t)(p[1]) << 24) |
1112          ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 8) |
1113          ((uint64_t)(p[4]) << 0);
1114 }
1115 
1116 static inline uint64_t  //
wuffs_base__peek_u40le__no_bounds_check(const uint8_t * p)1117 wuffs_base__peek_u40le__no_bounds_check(const uint8_t* p) {
1118   return ((uint64_t)(p[0]) << 0) | ((uint64_t)(p[1]) << 8) |
1119          ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
1120          ((uint64_t)(p[4]) << 32);
1121 }
1122 
1123 static inline uint64_t  //
wuffs_base__peek_u48be__no_bounds_check(const uint8_t * p)1124 wuffs_base__peek_u48be__no_bounds_check(const uint8_t* p) {
1125   return ((uint64_t)(p[0]) << 40) | ((uint64_t)(p[1]) << 32) |
1126          ((uint64_t)(p[2]) << 24) | ((uint64_t)(p[3]) << 16) |
1127          ((uint64_t)(p[4]) << 8) | ((uint64_t)(p[5]) << 0);
1128 }
1129 
1130 static inline uint64_t  //
wuffs_base__peek_u48le__no_bounds_check(const uint8_t * p)1131 wuffs_base__peek_u48le__no_bounds_check(const uint8_t* p) {
1132   return ((uint64_t)(p[0]) << 0) | ((uint64_t)(p[1]) << 8) |
1133          ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
1134          ((uint64_t)(p[4]) << 32) | ((uint64_t)(p[5]) << 40);
1135 }
1136 
1137 static inline uint64_t  //
wuffs_base__peek_u56be__no_bounds_check(const uint8_t * p)1138 wuffs_base__peek_u56be__no_bounds_check(const uint8_t* p) {
1139   return ((uint64_t)(p[0]) << 48) | ((uint64_t)(p[1]) << 40) |
1140          ((uint64_t)(p[2]) << 32) | ((uint64_t)(p[3]) << 24) |
1141          ((uint64_t)(p[4]) << 16) | ((uint64_t)(p[5]) << 8) |
1142          ((uint64_t)(p[6]) << 0);
1143 }
1144 
1145 static inline uint64_t  //
wuffs_base__peek_u56le__no_bounds_check(const uint8_t * p)1146 wuffs_base__peek_u56le__no_bounds_check(const uint8_t* p) {
1147   return ((uint64_t)(p[0]) << 0) | ((uint64_t)(p[1]) << 8) |
1148          ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
1149          ((uint64_t)(p[4]) << 32) | ((uint64_t)(p[5]) << 40) |
1150          ((uint64_t)(p[6]) << 48);
1151 }
1152 
1153 static inline uint64_t  //
wuffs_base__peek_u64be__no_bounds_check(const uint8_t * p)1154 wuffs_base__peek_u64be__no_bounds_check(const uint8_t* p) {
1155   return ((uint64_t)(p[0]) << 56) | ((uint64_t)(p[1]) << 48) |
1156          ((uint64_t)(p[2]) << 40) | ((uint64_t)(p[3]) << 32) |
1157          ((uint64_t)(p[4]) << 24) | ((uint64_t)(p[5]) << 16) |
1158          ((uint64_t)(p[6]) << 8) | ((uint64_t)(p[7]) << 0);
1159 }
1160 
1161 static inline uint64_t  //
wuffs_base__peek_u64le__no_bounds_check(const uint8_t * p)1162 wuffs_base__peek_u64le__no_bounds_check(const uint8_t* p) {
1163   return ((uint64_t)(p[0]) << 0) | ((uint64_t)(p[1]) << 8) |
1164          ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
1165          ((uint64_t)(p[4]) << 32) | ((uint64_t)(p[5]) << 40) |
1166          ((uint64_t)(p[6]) << 48) | ((uint64_t)(p[7]) << 56);
1167 }
1168 
1169 // --------
1170 
1171 #define wuffs_base__poke_u8be__no_bounds_check \
1172   wuffs_base__poke_u8__no_bounds_check
1173 #define wuffs_base__poke_u8le__no_bounds_check \
1174   wuffs_base__poke_u8__no_bounds_check
1175 
1176 static inline void  //
wuffs_base__poke_u8__no_bounds_check(uint8_t * p,uint8_t x)1177 wuffs_base__poke_u8__no_bounds_check(uint8_t* p, uint8_t x) {
1178   p[0] = x;
1179 }
1180 
1181 static inline void  //
wuffs_base__poke_u16be__no_bounds_check(uint8_t * p,uint16_t x)1182 wuffs_base__poke_u16be__no_bounds_check(uint8_t* p, uint16_t x) {
1183   p[0] = (uint8_t)(x >> 8);
1184   p[1] = (uint8_t)(x >> 0);
1185 }
1186 
1187 static inline void  //
wuffs_base__poke_u16le__no_bounds_check(uint8_t * p,uint16_t x)1188 wuffs_base__poke_u16le__no_bounds_check(uint8_t* p, uint16_t x) {
1189 #if defined(__GNUC__) && !defined(__clang__) && defined(__x86_64__)
1190   // This seems to perform better on gcc 10 (but not clang 9). Clang also
1191   // defines "__GNUC__".
1192   memcpy(p, &x, 2);
1193 #else
1194   p[0] = (uint8_t)(x >> 0);
1195   p[1] = (uint8_t)(x >> 8);
1196 #endif
1197 }
1198 
1199 static inline void  //
wuffs_base__poke_u24be__no_bounds_check(uint8_t * p,uint32_t x)1200 wuffs_base__poke_u24be__no_bounds_check(uint8_t* p, uint32_t x) {
1201   p[0] = (uint8_t)(x >> 16);
1202   p[1] = (uint8_t)(x >> 8);
1203   p[2] = (uint8_t)(x >> 0);
1204 }
1205 
1206 static inline void  //
wuffs_base__poke_u24le__no_bounds_check(uint8_t * p,uint32_t x)1207 wuffs_base__poke_u24le__no_bounds_check(uint8_t* p, uint32_t x) {
1208   p[0] = (uint8_t)(x >> 0);
1209   p[1] = (uint8_t)(x >> 8);
1210   p[2] = (uint8_t)(x >> 16);
1211 }
1212 
1213 static inline void  //
wuffs_base__poke_u32be__no_bounds_check(uint8_t * p,uint32_t x)1214 wuffs_base__poke_u32be__no_bounds_check(uint8_t* p, uint32_t x) {
1215   p[0] = (uint8_t)(x >> 24);
1216   p[1] = (uint8_t)(x >> 16);
1217   p[2] = (uint8_t)(x >> 8);
1218   p[3] = (uint8_t)(x >> 0);
1219 }
1220 
1221 static inline void  //
wuffs_base__poke_u32le__no_bounds_check(uint8_t * p,uint32_t x)1222 wuffs_base__poke_u32le__no_bounds_check(uint8_t* p, uint32_t x) {
1223 #if defined(__GNUC__) && !defined(__clang__) && defined(__x86_64__)
1224   // This seems to perform better on gcc 10 (but not clang 9). Clang also
1225   // defines "__GNUC__".
1226   memcpy(p, &x, 4);
1227 #else
1228   p[0] = (uint8_t)(x >> 0);
1229   p[1] = (uint8_t)(x >> 8);
1230   p[2] = (uint8_t)(x >> 16);
1231   p[3] = (uint8_t)(x >> 24);
1232 #endif
1233 }
1234 
1235 static inline void  //
wuffs_base__poke_u40be__no_bounds_check(uint8_t * p,uint64_t x)1236 wuffs_base__poke_u40be__no_bounds_check(uint8_t* p, uint64_t x) {
1237   p[0] = (uint8_t)(x >> 32);
1238   p[1] = (uint8_t)(x >> 24);
1239   p[2] = (uint8_t)(x >> 16);
1240   p[3] = (uint8_t)(x >> 8);
1241   p[4] = (uint8_t)(x >> 0);
1242 }
1243 
1244 static inline void  //
wuffs_base__poke_u40le__no_bounds_check(uint8_t * p,uint64_t x)1245 wuffs_base__poke_u40le__no_bounds_check(uint8_t* p, uint64_t x) {
1246   p[0] = (uint8_t)(x >> 0);
1247   p[1] = (uint8_t)(x >> 8);
1248   p[2] = (uint8_t)(x >> 16);
1249   p[3] = (uint8_t)(x >> 24);
1250   p[4] = (uint8_t)(x >> 32);
1251 }
1252 
1253 static inline void  //
wuffs_base__poke_u48be__no_bounds_check(uint8_t * p,uint64_t x)1254 wuffs_base__poke_u48be__no_bounds_check(uint8_t* p, uint64_t x) {
1255   p[0] = (uint8_t)(x >> 40);
1256   p[1] = (uint8_t)(x >> 32);
1257   p[2] = (uint8_t)(x >> 24);
1258   p[3] = (uint8_t)(x >> 16);
1259   p[4] = (uint8_t)(x >> 8);
1260   p[5] = (uint8_t)(x >> 0);
1261 }
1262 
1263 static inline void  //
wuffs_base__poke_u48le__no_bounds_check(uint8_t * p,uint64_t x)1264 wuffs_base__poke_u48le__no_bounds_check(uint8_t* p, uint64_t x) {
1265   p[0] = (uint8_t)(x >> 0);
1266   p[1] = (uint8_t)(x >> 8);
1267   p[2] = (uint8_t)(x >> 16);
1268   p[3] = (uint8_t)(x >> 24);
1269   p[4] = (uint8_t)(x >> 32);
1270   p[5] = (uint8_t)(x >> 40);
1271 }
1272 
1273 static inline void  //
wuffs_base__poke_u56be__no_bounds_check(uint8_t * p,uint64_t x)1274 wuffs_base__poke_u56be__no_bounds_check(uint8_t* p, uint64_t x) {
1275   p[0] = (uint8_t)(x >> 48);
1276   p[1] = (uint8_t)(x >> 40);
1277   p[2] = (uint8_t)(x >> 32);
1278   p[3] = (uint8_t)(x >> 24);
1279   p[4] = (uint8_t)(x >> 16);
1280   p[5] = (uint8_t)(x >> 8);
1281   p[6] = (uint8_t)(x >> 0);
1282 }
1283 
1284 static inline void  //
wuffs_base__poke_u56le__no_bounds_check(uint8_t * p,uint64_t x)1285 wuffs_base__poke_u56le__no_bounds_check(uint8_t* p, uint64_t x) {
1286   p[0] = (uint8_t)(x >> 0);
1287   p[1] = (uint8_t)(x >> 8);
1288   p[2] = (uint8_t)(x >> 16);
1289   p[3] = (uint8_t)(x >> 24);
1290   p[4] = (uint8_t)(x >> 32);
1291   p[5] = (uint8_t)(x >> 40);
1292   p[6] = (uint8_t)(x >> 48);
1293 }
1294 
1295 static inline void  //
wuffs_base__poke_u64be__no_bounds_check(uint8_t * p,uint64_t x)1296 wuffs_base__poke_u64be__no_bounds_check(uint8_t* p, uint64_t x) {
1297   p[0] = (uint8_t)(x >> 56);
1298   p[1] = (uint8_t)(x >> 48);
1299   p[2] = (uint8_t)(x >> 40);
1300   p[3] = (uint8_t)(x >> 32);
1301   p[4] = (uint8_t)(x >> 24);
1302   p[5] = (uint8_t)(x >> 16);
1303   p[6] = (uint8_t)(x >> 8);
1304   p[7] = (uint8_t)(x >> 0);
1305 }
1306 
1307 static inline void  //
wuffs_base__poke_u64le__no_bounds_check(uint8_t * p,uint64_t x)1308 wuffs_base__poke_u64le__no_bounds_check(uint8_t* p, uint64_t x) {
1309 #if defined(__GNUC__) && !defined(__clang__) && defined(__x86_64__)
1310   // This seems to perform better on gcc 10 (but not clang 9). Clang also
1311   // defines "__GNUC__".
1312   memcpy(p, &x, 8);
1313 #else
1314   p[0] = (uint8_t)(x >> 0);
1315   p[1] = (uint8_t)(x >> 8);
1316   p[2] = (uint8_t)(x >> 16);
1317   p[3] = (uint8_t)(x >> 24);
1318   p[4] = (uint8_t)(x >> 32);
1319   p[5] = (uint8_t)(x >> 40);
1320   p[6] = (uint8_t)(x >> 48);
1321   p[7] = (uint8_t)(x >> 56);
1322 #endif
1323 }
1324 
1325 // --------
1326 
1327 // Load and Store functions are deprecated. Use Peek and Poke instead.
1328 
1329 #define wuffs_base__load_u8__no_bounds_check \
1330   wuffs_base__peek_u8__no_bounds_check
1331 #define wuffs_base__load_u16be__no_bounds_check \
1332   wuffs_base__peek_u16be__no_bounds_check
1333 #define wuffs_base__load_u16le__no_bounds_check \
1334   wuffs_base__peek_u16le__no_bounds_check
1335 #define wuffs_base__load_u24be__no_bounds_check \
1336   wuffs_base__peek_u24be__no_bounds_check
1337 #define wuffs_base__load_u24le__no_bounds_check \
1338   wuffs_base__peek_u24le__no_bounds_check
1339 #define wuffs_base__load_u32be__no_bounds_check \
1340   wuffs_base__peek_u32be__no_bounds_check
1341 #define wuffs_base__load_u32le__no_bounds_check \
1342   wuffs_base__peek_u32le__no_bounds_check
1343 #define wuffs_base__load_u40be__no_bounds_check \
1344   wuffs_base__peek_u40be__no_bounds_check
1345 #define wuffs_base__load_u40le__no_bounds_check \
1346   wuffs_base__peek_u40le__no_bounds_check
1347 #define wuffs_base__load_u48be__no_bounds_check \
1348   wuffs_base__peek_u48be__no_bounds_check
1349 #define wuffs_base__load_u48le__no_bounds_check \
1350   wuffs_base__peek_u48le__no_bounds_check
1351 #define wuffs_base__load_u56be__no_bounds_check \
1352   wuffs_base__peek_u56be__no_bounds_check
1353 #define wuffs_base__load_u56le__no_bounds_check \
1354   wuffs_base__peek_u56le__no_bounds_check
1355 #define wuffs_base__load_u64be__no_bounds_check \
1356   wuffs_base__peek_u64be__no_bounds_check
1357 #define wuffs_base__load_u64le__no_bounds_check \
1358   wuffs_base__peek_u64le__no_bounds_check
1359 
1360 #define wuffs_base__store_u8__no_bounds_check \
1361   wuffs_base__poke_u8__no_bounds_check
1362 #define wuffs_base__store_u16be__no_bounds_check \
1363   wuffs_base__poke_u16be__no_bounds_check
1364 #define wuffs_base__store_u16le__no_bounds_check \
1365   wuffs_base__poke_u16le__no_bounds_check
1366 #define wuffs_base__store_u24be__no_bounds_check \
1367   wuffs_base__poke_u24be__no_bounds_check
1368 #define wuffs_base__store_u24le__no_bounds_check \
1369   wuffs_base__poke_u24le__no_bounds_check
1370 #define wuffs_base__store_u32be__no_bounds_check \
1371   wuffs_base__poke_u32be__no_bounds_check
1372 #define wuffs_base__store_u32le__no_bounds_check \
1373   wuffs_base__poke_u32le__no_bounds_check
1374 #define wuffs_base__store_u40be__no_bounds_check \
1375   wuffs_base__poke_u40be__no_bounds_check
1376 #define wuffs_base__store_u40le__no_bounds_check \
1377   wuffs_base__poke_u40le__no_bounds_check
1378 #define wuffs_base__store_u48be__no_bounds_check \
1379   wuffs_base__poke_u48be__no_bounds_check
1380 #define wuffs_base__store_u48le__no_bounds_check \
1381   wuffs_base__poke_u48le__no_bounds_check
1382 #define wuffs_base__store_u56be__no_bounds_check \
1383   wuffs_base__poke_u56be__no_bounds_check
1384 #define wuffs_base__store_u56le__no_bounds_check \
1385   wuffs_base__poke_u56le__no_bounds_check
1386 #define wuffs_base__store_u64be__no_bounds_check \
1387   wuffs_base__poke_u64be__no_bounds_check
1388 #define wuffs_base__store_u64le__no_bounds_check \
1389   wuffs_base__poke_u64le__no_bounds_check
1390 
1391 // ---------------- Slices and Tables
1392 
1393 // WUFFS_BASE__SLICE is a 1-dimensional buffer.
1394 //
1395 // len measures a number of elements, not necessarily a size in bytes.
1396 //
1397 // A value with all fields NULL or zero is a valid, empty slice.
1398 #define WUFFS_BASE__SLICE(T) \
1399   struct {                   \
1400     T* ptr;                  \
1401     size_t len;              \
1402   }
1403 
1404 // WUFFS_BASE__TABLE is a 2-dimensional buffer.
1405 //
1406 // width, height and stride measure a number of elements, not necessarily a
1407 // size in bytes.
1408 //
1409 // A value with all fields NULL or zero is a valid, empty table.
1410 #define WUFFS_BASE__TABLE(T) \
1411   struct {                   \
1412     T* ptr;                  \
1413     size_t width;            \
1414     size_t height;           \
1415     size_t stride;           \
1416   }
1417 
1418 typedef WUFFS_BASE__SLICE(uint8_t) wuffs_base__slice_u8;
1419 typedef WUFFS_BASE__SLICE(uint16_t) wuffs_base__slice_u16;
1420 typedef WUFFS_BASE__SLICE(uint32_t) wuffs_base__slice_u32;
1421 typedef WUFFS_BASE__SLICE(uint64_t) wuffs_base__slice_u64;
1422 
1423 typedef WUFFS_BASE__TABLE(uint8_t) wuffs_base__table_u8;
1424 typedef WUFFS_BASE__TABLE(uint16_t) wuffs_base__table_u16;
1425 typedef WUFFS_BASE__TABLE(uint32_t) wuffs_base__table_u32;
1426 typedef WUFFS_BASE__TABLE(uint64_t) wuffs_base__table_u64;
1427 
1428 static inline wuffs_base__slice_u8  //
wuffs_base__make_slice_u8(uint8_t * ptr,size_t len)1429 wuffs_base__make_slice_u8(uint8_t* ptr, size_t len) {
1430   wuffs_base__slice_u8 ret;
1431   ret.ptr = ptr;
1432   ret.len = len;
1433   return ret;
1434 }
1435 
1436 static inline wuffs_base__slice_u16  //
wuffs_base__make_slice_u16(uint16_t * ptr,size_t len)1437 wuffs_base__make_slice_u16(uint16_t* ptr, size_t len) {
1438   wuffs_base__slice_u16 ret;
1439   ret.ptr = ptr;
1440   ret.len = len;
1441   return ret;
1442 }
1443 
1444 static inline wuffs_base__slice_u32  //
wuffs_base__make_slice_u32(uint32_t * ptr,size_t len)1445 wuffs_base__make_slice_u32(uint32_t* ptr, size_t len) {
1446   wuffs_base__slice_u32 ret;
1447   ret.ptr = ptr;
1448   ret.len = len;
1449   return ret;
1450 }
1451 
1452 static inline wuffs_base__slice_u64  //
wuffs_base__make_slice_u64(uint64_t * ptr,size_t len)1453 wuffs_base__make_slice_u64(uint64_t* ptr, size_t len) {
1454   wuffs_base__slice_u64 ret;
1455   ret.ptr = ptr;
1456   ret.len = len;
1457   return ret;
1458 }
1459 
1460 static inline wuffs_base__slice_u8  //
wuffs_base__empty_slice_u8()1461 wuffs_base__empty_slice_u8() {
1462   wuffs_base__slice_u8 ret;
1463   ret.ptr = NULL;
1464   ret.len = 0;
1465   return ret;
1466 }
1467 
1468 static inline wuffs_base__slice_u16  //
wuffs_base__empty_slice_u16()1469 wuffs_base__empty_slice_u16() {
1470   wuffs_base__slice_u16 ret;
1471   ret.ptr = NULL;
1472   ret.len = 0;
1473   return ret;
1474 }
1475 
1476 static inline wuffs_base__slice_u32  //
wuffs_base__empty_slice_u32()1477 wuffs_base__empty_slice_u32() {
1478   wuffs_base__slice_u32 ret;
1479   ret.ptr = NULL;
1480   ret.len = 0;
1481   return ret;
1482 }
1483 
1484 static inline wuffs_base__slice_u64  //
wuffs_base__empty_slice_u64()1485 wuffs_base__empty_slice_u64() {
1486   wuffs_base__slice_u64 ret;
1487   ret.ptr = NULL;
1488   ret.len = 0;
1489   return ret;
1490 }
1491 
1492 static inline wuffs_base__table_u8  //
wuffs_base__make_table_u8(uint8_t * ptr,size_t width,size_t height,size_t stride)1493 wuffs_base__make_table_u8(uint8_t* ptr,
1494                           size_t width,
1495                           size_t height,
1496                           size_t stride) {
1497   wuffs_base__table_u8 ret;
1498   ret.ptr = ptr;
1499   ret.width = width;
1500   ret.height = height;
1501   ret.stride = stride;
1502   return ret;
1503 }
1504 
1505 static inline wuffs_base__table_u16  //
wuffs_base__make_table_u16(uint16_t * ptr,size_t width,size_t height,size_t stride)1506 wuffs_base__make_table_u16(uint16_t* ptr,
1507                            size_t width,
1508                            size_t height,
1509                            size_t stride) {
1510   wuffs_base__table_u16 ret;
1511   ret.ptr = ptr;
1512   ret.width = width;
1513   ret.height = height;
1514   ret.stride = stride;
1515   return ret;
1516 }
1517 
1518 static inline wuffs_base__table_u32  //
wuffs_base__make_table_u32(uint32_t * ptr,size_t width,size_t height,size_t stride)1519 wuffs_base__make_table_u32(uint32_t* ptr,
1520                            size_t width,
1521                            size_t height,
1522                            size_t stride) {
1523   wuffs_base__table_u32 ret;
1524   ret.ptr = ptr;
1525   ret.width = width;
1526   ret.height = height;
1527   ret.stride = stride;
1528   return ret;
1529 }
1530 
1531 static inline wuffs_base__table_u64  //
wuffs_base__make_table_u64(uint64_t * ptr,size_t width,size_t height,size_t stride)1532 wuffs_base__make_table_u64(uint64_t* ptr,
1533                            size_t width,
1534                            size_t height,
1535                            size_t stride) {
1536   wuffs_base__table_u64 ret;
1537   ret.ptr = ptr;
1538   ret.width = width;
1539   ret.height = height;
1540   ret.stride = stride;
1541   return ret;
1542 }
1543 
1544 static inline wuffs_base__table_u8  //
wuffs_base__empty_table_u8()1545 wuffs_base__empty_table_u8() {
1546   wuffs_base__table_u8 ret;
1547   ret.ptr = NULL;
1548   ret.width = 0;
1549   ret.height = 0;
1550   ret.stride = 0;
1551   return ret;
1552 }
1553 
1554 static inline wuffs_base__table_u16  //
wuffs_base__empty_table_u16()1555 wuffs_base__empty_table_u16() {
1556   wuffs_base__table_u16 ret;
1557   ret.ptr = NULL;
1558   ret.width = 0;
1559   ret.height = 0;
1560   ret.stride = 0;
1561   return ret;
1562 }
1563 
1564 static inline wuffs_base__table_u32  //
wuffs_base__empty_table_u32()1565 wuffs_base__empty_table_u32() {
1566   wuffs_base__table_u32 ret;
1567   ret.ptr = NULL;
1568   ret.width = 0;
1569   ret.height = 0;
1570   ret.stride = 0;
1571   return ret;
1572 }
1573 
1574 static inline wuffs_base__table_u64  //
wuffs_base__empty_table_u64()1575 wuffs_base__empty_table_u64() {
1576   wuffs_base__table_u64 ret;
1577   ret.ptr = NULL;
1578   ret.width = 0;
1579   ret.height = 0;
1580   ret.stride = 0;
1581   return ret;
1582 }
1583 
1584 static inline bool  //
wuffs_base__slice_u8__overlaps(wuffs_base__slice_u8 s,wuffs_base__slice_u8 t)1585 wuffs_base__slice_u8__overlaps(wuffs_base__slice_u8 s, wuffs_base__slice_u8 t) {
1586   return ((s.ptr <= t.ptr) && (t.ptr < (s.ptr + s.len))) ||
1587          ((t.ptr <= s.ptr) && (s.ptr < (t.ptr + t.len)));
1588 }
1589 
1590 // wuffs_base__slice_u8__subslice_i returns s[i:].
1591 //
1592 // It returns an empty slice if i is out of bounds.
1593 static inline wuffs_base__slice_u8  //
wuffs_base__slice_u8__subslice_i(wuffs_base__slice_u8 s,uint64_t i)1594 wuffs_base__slice_u8__subslice_i(wuffs_base__slice_u8 s, uint64_t i) {
1595   if ((i <= SIZE_MAX) && (i <= s.len)) {
1596     return wuffs_base__make_slice_u8(s.ptr + i, ((size_t)(s.len - i)));
1597   }
1598   return wuffs_base__make_slice_u8(NULL, 0);
1599 }
1600 
1601 // wuffs_base__slice_u8__subslice_j returns s[:j].
1602 //
1603 // It returns an empty slice if j is out of bounds.
1604 static inline wuffs_base__slice_u8  //
wuffs_base__slice_u8__subslice_j(wuffs_base__slice_u8 s,uint64_t j)1605 wuffs_base__slice_u8__subslice_j(wuffs_base__slice_u8 s, uint64_t j) {
1606   if ((j <= SIZE_MAX) && (j <= s.len)) {
1607     return wuffs_base__make_slice_u8(s.ptr, ((size_t)j));
1608   }
1609   return wuffs_base__make_slice_u8(NULL, 0);
1610 }
1611 
1612 // wuffs_base__slice_u8__subslice_ij returns s[i:j].
1613 //
1614 // It returns an empty slice if i or j is out of bounds.
1615 static inline wuffs_base__slice_u8  //
wuffs_base__slice_u8__subslice_ij(wuffs_base__slice_u8 s,uint64_t i,uint64_t j)1616 wuffs_base__slice_u8__subslice_ij(wuffs_base__slice_u8 s,
1617                                   uint64_t i,
1618                                   uint64_t j) {
1619   if ((i <= j) && (j <= SIZE_MAX) && (j <= s.len)) {
1620     return wuffs_base__make_slice_u8(s.ptr + i, ((size_t)(j - i)));
1621   }
1622   return wuffs_base__make_slice_u8(NULL, 0);
1623 }
1624 
1625 // wuffs_base__table_u8__subtable_ij returns t[ix:jx, iy:jy].
1626 //
1627 // It returns an empty table if i or j is out of bounds.
1628 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)1629 wuffs_base__table_u8__subtable_ij(wuffs_base__table_u8 t,
1630                                   uint64_t ix,
1631                                   uint64_t iy,
1632                                   uint64_t jx,
1633                                   uint64_t jy) {
1634   if ((ix <= jx) && (jx <= SIZE_MAX) && (jx <= t.width) &&  //
1635       (iy <= jy) && (jy <= SIZE_MAX) && (jy <= t.height)) {
1636     return wuffs_base__make_table_u8(t.ptr + ix + (iy * t.stride),  //
1637                                      ((size_t)(jx - ix)),           //
1638                                      ((size_t)(jy - iy)),           //
1639                                      t.stride);                     //
1640   }
1641   return wuffs_base__make_table_u8(NULL, 0, 0, 0);
1642 }
1643 
1644 // wuffs_base__table__flattened_length returns the number of elements covered
1645 // by the 1-dimensional span that backs a 2-dimensional table. This counts the
1646 // elements inside the table and, when width != stride, the elements outside
1647 // the table but between its rows.
1648 //
1649 // For example, consider a width 10, height 4, stride 10 table. Mark its first
1650 // and last (inclusive) elements with 'a' and 'z'. This function returns 40.
1651 //
1652 //    a123456789
1653 //    0123456789
1654 //    0123456789
1655 //    012345678z
1656 //
1657 // Now consider the sub-table of that from (2, 1) inclusive to (8, 4) exclusive.
1658 //
1659 //    a123456789
1660 //    01iiiiiioo
1661 //    ooiiiiiioo
1662 //    ooiiiiii8z
1663 //
1664 // This function (called with width 6, height 3, stride 10) returns 26: 18 'i'
1665 // inside elements plus 8 'o' outside elements. Note that 26 is less than a
1666 // naive (height * stride = 30) computation. Indeed, advancing 29 elements from
1667 // the first 'i' would venture past 'z', out of bounds of the original table.
1668 //
1669 // It does not check for overflow, but if the arguments come from a table that
1670 // exists in memory and each element occupies a positive number of bytes then
1671 // the result should be bounded by the amount of allocatable memory (which
1672 // shouldn't overflow SIZE_MAX).
1673 static inline size_t  //
wuffs_base__table__flattened_length(size_t width,size_t height,size_t stride)1674 wuffs_base__table__flattened_length(size_t width,
1675                                     size_t height,
1676                                     size_t stride) {
1677   if (height == 0) {
1678     return 0;
1679   }
1680   return ((height - 1) * stride) + width;
1681 }
1682 
1683 // ---------------- Magic Numbers
1684 
1685 // wuffs_base__magic_number_guess_fourcc guesses the file format of some data,
1686 // given its opening bytes. It returns a positive FourCC value on success.
1687 //
1688 // It returns zero if nothing matches its hard-coded list of 'magic numbers'.
1689 //
1690 // It returns a negative value if a longer prefix is required for a conclusive
1691 // result. For example, seeing a single 'B' byte is not enough to discriminate
1692 // the BMP and BPG image file formats.
1693 //
1694 // It does not do a full validity check. Like any guess made from a short
1695 // prefix of the data, it may return false positives. Data that starts with 99
1696 // bytes of valid JPEG followed by corruption or truncation is an invalid JPEG
1697 // image overall, but this function will still return WUFFS_BASE__FOURCC__JPEG.
1698 //
1699 // Another source of false positives is that some 'magic numbers' are valid
1700 // ASCII data. A file starting with "GIF87a and GIF89a are the two versions of
1701 // GIF" will match GIF's 'magic number' even if it's plain text, not an image.
1702 //
1703 // For modular builds that divide the base module into sub-modules, using this
1704 // function requires the WUFFS_CONFIG__MODULE__BASE__MAGIC sub-module, not just
1705 // WUFFS_CONFIG__MODULE__BASE__CORE.
1706 WUFFS_BASE__MAYBE_STATIC int32_t  //
1707 wuffs_base__magic_number_guess_fourcc(wuffs_base__slice_u8 prefix);
1708 
1709 // ---------------- Ranges and Rects
1710 
1711 // See https://github.com/google/wuffs/blob/main/doc/note/ranges-and-rects.md
1712 
1713 typedef struct wuffs_base__range_ii_u32__struct {
1714   uint32_t min_incl;
1715   uint32_t max_incl;
1716 
1717 #ifdef __cplusplus
1718   inline bool is_empty() const;
1719   inline bool equals(wuffs_base__range_ii_u32__struct s) const;
1720   inline wuffs_base__range_ii_u32__struct intersect(
1721       wuffs_base__range_ii_u32__struct s) const;
1722   inline wuffs_base__range_ii_u32__struct unite(
1723       wuffs_base__range_ii_u32__struct s) const;
1724   inline bool contains(uint32_t x) const;
1725   inline bool contains_range(wuffs_base__range_ii_u32__struct s) const;
1726 #endif  // __cplusplus
1727 
1728 } wuffs_base__range_ii_u32;
1729 
1730 static inline wuffs_base__range_ii_u32  //
wuffs_base__empty_range_ii_u32()1731 wuffs_base__empty_range_ii_u32() {
1732   wuffs_base__range_ii_u32 ret;
1733   ret.min_incl = 0;
1734   ret.max_incl = 0;
1735   return ret;
1736 }
1737 
1738 static inline wuffs_base__range_ii_u32  //
wuffs_base__make_range_ii_u32(uint32_t min_incl,uint32_t max_incl)1739 wuffs_base__make_range_ii_u32(uint32_t min_incl, uint32_t max_incl) {
1740   wuffs_base__range_ii_u32 ret;
1741   ret.min_incl = min_incl;
1742   ret.max_incl = max_incl;
1743   return ret;
1744 }
1745 
1746 static inline bool  //
wuffs_base__range_ii_u32__is_empty(const wuffs_base__range_ii_u32 * r)1747 wuffs_base__range_ii_u32__is_empty(const wuffs_base__range_ii_u32* r) {
1748   return r->min_incl > r->max_incl;
1749 }
1750 
1751 static inline bool  //
wuffs_base__range_ii_u32__equals(const wuffs_base__range_ii_u32 * r,wuffs_base__range_ii_u32 s)1752 wuffs_base__range_ii_u32__equals(const wuffs_base__range_ii_u32* r,
1753                                  wuffs_base__range_ii_u32 s) {
1754   return (r->min_incl == s.min_incl && r->max_incl == s.max_incl) ||
1755          (wuffs_base__range_ii_u32__is_empty(r) &&
1756           wuffs_base__range_ii_u32__is_empty(&s));
1757 }
1758 
1759 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)1760 wuffs_base__range_ii_u32__intersect(const wuffs_base__range_ii_u32* r,
1761                                     wuffs_base__range_ii_u32 s) {
1762   wuffs_base__range_ii_u32 t;
1763   t.min_incl = wuffs_base__u32__max(r->min_incl, s.min_incl);
1764   t.max_incl = wuffs_base__u32__min(r->max_incl, s.max_incl);
1765   return t;
1766 }
1767 
1768 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)1769 wuffs_base__range_ii_u32__unite(const wuffs_base__range_ii_u32* r,
1770                                 wuffs_base__range_ii_u32 s) {
1771   if (wuffs_base__range_ii_u32__is_empty(r)) {
1772     return s;
1773   }
1774   if (wuffs_base__range_ii_u32__is_empty(&s)) {
1775     return *r;
1776   }
1777   wuffs_base__range_ii_u32 t;
1778   t.min_incl = wuffs_base__u32__min(r->min_incl, s.min_incl);
1779   t.max_incl = wuffs_base__u32__max(r->max_incl, s.max_incl);
1780   return t;
1781 }
1782 
1783 static inline bool  //
wuffs_base__range_ii_u32__contains(const wuffs_base__range_ii_u32 * r,uint32_t x)1784 wuffs_base__range_ii_u32__contains(const wuffs_base__range_ii_u32* r,
1785                                    uint32_t x) {
1786   return (r->min_incl <= x) && (x <= r->max_incl);
1787 }
1788 
1789 static inline bool  //
wuffs_base__range_ii_u32__contains_range(const wuffs_base__range_ii_u32 * r,wuffs_base__range_ii_u32 s)1790 wuffs_base__range_ii_u32__contains_range(const wuffs_base__range_ii_u32* r,
1791                                          wuffs_base__range_ii_u32 s) {
1792   return wuffs_base__range_ii_u32__equals(
1793       &s, wuffs_base__range_ii_u32__intersect(r, s));
1794 }
1795 
1796 #ifdef __cplusplus
1797 
1798 inline bool  //
is_empty()1799 wuffs_base__range_ii_u32::is_empty() const {
1800   return wuffs_base__range_ii_u32__is_empty(this);
1801 }
1802 
1803 inline bool  //
equals(wuffs_base__range_ii_u32 s)1804 wuffs_base__range_ii_u32::equals(wuffs_base__range_ii_u32 s) const {
1805   return wuffs_base__range_ii_u32__equals(this, s);
1806 }
1807 
1808 inline wuffs_base__range_ii_u32  //
intersect(wuffs_base__range_ii_u32 s)1809 wuffs_base__range_ii_u32::intersect(wuffs_base__range_ii_u32 s) const {
1810   return wuffs_base__range_ii_u32__intersect(this, s);
1811 }
1812 
1813 inline wuffs_base__range_ii_u32  //
unite(wuffs_base__range_ii_u32 s)1814 wuffs_base__range_ii_u32::unite(wuffs_base__range_ii_u32 s) const {
1815   return wuffs_base__range_ii_u32__unite(this, s);
1816 }
1817 
1818 inline bool  //
contains(uint32_t x)1819 wuffs_base__range_ii_u32::contains(uint32_t x) const {
1820   return wuffs_base__range_ii_u32__contains(this, x);
1821 }
1822 
1823 inline bool  //
contains_range(wuffs_base__range_ii_u32 s)1824 wuffs_base__range_ii_u32::contains_range(wuffs_base__range_ii_u32 s) const {
1825   return wuffs_base__range_ii_u32__contains_range(this, s);
1826 }
1827 
1828 #endif  // __cplusplus
1829 
1830 // --------
1831 
1832 typedef struct wuffs_base__range_ie_u32__struct {
1833   uint32_t min_incl;
1834   uint32_t max_excl;
1835 
1836 #ifdef __cplusplus
1837   inline bool is_empty() const;
1838   inline bool equals(wuffs_base__range_ie_u32__struct s) const;
1839   inline wuffs_base__range_ie_u32__struct intersect(
1840       wuffs_base__range_ie_u32__struct s) const;
1841   inline wuffs_base__range_ie_u32__struct unite(
1842       wuffs_base__range_ie_u32__struct s) const;
1843   inline bool contains(uint32_t x) const;
1844   inline bool contains_range(wuffs_base__range_ie_u32__struct s) const;
1845   inline uint32_t length() const;
1846 #endif  // __cplusplus
1847 
1848 } wuffs_base__range_ie_u32;
1849 
1850 static inline wuffs_base__range_ie_u32  //
wuffs_base__empty_range_ie_u32()1851 wuffs_base__empty_range_ie_u32() {
1852   wuffs_base__range_ie_u32 ret;
1853   ret.min_incl = 0;
1854   ret.max_excl = 0;
1855   return ret;
1856 }
1857 
1858 static inline wuffs_base__range_ie_u32  //
wuffs_base__make_range_ie_u32(uint32_t min_incl,uint32_t max_excl)1859 wuffs_base__make_range_ie_u32(uint32_t min_incl, uint32_t max_excl) {
1860   wuffs_base__range_ie_u32 ret;
1861   ret.min_incl = min_incl;
1862   ret.max_excl = max_excl;
1863   return ret;
1864 }
1865 
1866 static inline bool  //
wuffs_base__range_ie_u32__is_empty(const wuffs_base__range_ie_u32 * r)1867 wuffs_base__range_ie_u32__is_empty(const wuffs_base__range_ie_u32* r) {
1868   return r->min_incl >= r->max_excl;
1869 }
1870 
1871 static inline bool  //
wuffs_base__range_ie_u32__equals(const wuffs_base__range_ie_u32 * r,wuffs_base__range_ie_u32 s)1872 wuffs_base__range_ie_u32__equals(const wuffs_base__range_ie_u32* r,
1873                                  wuffs_base__range_ie_u32 s) {
1874   return (r->min_incl == s.min_incl && r->max_excl == s.max_excl) ||
1875          (wuffs_base__range_ie_u32__is_empty(r) &&
1876           wuffs_base__range_ie_u32__is_empty(&s));
1877 }
1878 
1879 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)1880 wuffs_base__range_ie_u32__intersect(const wuffs_base__range_ie_u32* r,
1881                                     wuffs_base__range_ie_u32 s) {
1882   wuffs_base__range_ie_u32 t;
1883   t.min_incl = wuffs_base__u32__max(r->min_incl, s.min_incl);
1884   t.max_excl = wuffs_base__u32__min(r->max_excl, s.max_excl);
1885   return t;
1886 }
1887 
1888 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)1889 wuffs_base__range_ie_u32__unite(const wuffs_base__range_ie_u32* r,
1890                                 wuffs_base__range_ie_u32 s) {
1891   if (wuffs_base__range_ie_u32__is_empty(r)) {
1892     return s;
1893   }
1894   if (wuffs_base__range_ie_u32__is_empty(&s)) {
1895     return *r;
1896   }
1897   wuffs_base__range_ie_u32 t;
1898   t.min_incl = wuffs_base__u32__min(r->min_incl, s.min_incl);
1899   t.max_excl = wuffs_base__u32__max(r->max_excl, s.max_excl);
1900   return t;
1901 }
1902 
1903 static inline bool  //
wuffs_base__range_ie_u32__contains(const wuffs_base__range_ie_u32 * r,uint32_t x)1904 wuffs_base__range_ie_u32__contains(const wuffs_base__range_ie_u32* r,
1905                                    uint32_t x) {
1906   return (r->min_incl <= x) && (x < r->max_excl);
1907 }
1908 
1909 static inline bool  //
wuffs_base__range_ie_u32__contains_range(const wuffs_base__range_ie_u32 * r,wuffs_base__range_ie_u32 s)1910 wuffs_base__range_ie_u32__contains_range(const wuffs_base__range_ie_u32* r,
1911                                          wuffs_base__range_ie_u32 s) {
1912   return wuffs_base__range_ie_u32__equals(
1913       &s, wuffs_base__range_ie_u32__intersect(r, s));
1914 }
1915 
1916 static inline uint32_t  //
wuffs_base__range_ie_u32__length(const wuffs_base__range_ie_u32 * r)1917 wuffs_base__range_ie_u32__length(const wuffs_base__range_ie_u32* r) {
1918   return wuffs_base__u32__sat_sub(r->max_excl, r->min_incl);
1919 }
1920 
1921 #ifdef __cplusplus
1922 
1923 inline bool  //
is_empty()1924 wuffs_base__range_ie_u32::is_empty() const {
1925   return wuffs_base__range_ie_u32__is_empty(this);
1926 }
1927 
1928 inline bool  //
equals(wuffs_base__range_ie_u32 s)1929 wuffs_base__range_ie_u32::equals(wuffs_base__range_ie_u32 s) const {
1930   return wuffs_base__range_ie_u32__equals(this, s);
1931 }
1932 
1933 inline wuffs_base__range_ie_u32  //
intersect(wuffs_base__range_ie_u32 s)1934 wuffs_base__range_ie_u32::intersect(wuffs_base__range_ie_u32 s) const {
1935   return wuffs_base__range_ie_u32__intersect(this, s);
1936 }
1937 
1938 inline wuffs_base__range_ie_u32  //
unite(wuffs_base__range_ie_u32 s)1939 wuffs_base__range_ie_u32::unite(wuffs_base__range_ie_u32 s) const {
1940   return wuffs_base__range_ie_u32__unite(this, s);
1941 }
1942 
1943 inline bool  //
contains(uint32_t x)1944 wuffs_base__range_ie_u32::contains(uint32_t x) const {
1945   return wuffs_base__range_ie_u32__contains(this, x);
1946 }
1947 
1948 inline bool  //
contains_range(wuffs_base__range_ie_u32 s)1949 wuffs_base__range_ie_u32::contains_range(wuffs_base__range_ie_u32 s) const {
1950   return wuffs_base__range_ie_u32__contains_range(this, s);
1951 }
1952 
1953 inline uint32_t  //
length()1954 wuffs_base__range_ie_u32::length() const {
1955   return wuffs_base__range_ie_u32__length(this);
1956 }
1957 
1958 #endif  // __cplusplus
1959 
1960 // --------
1961 
1962 typedef struct wuffs_base__range_ii_u64__struct {
1963   uint64_t min_incl;
1964   uint64_t max_incl;
1965 
1966 #ifdef __cplusplus
1967   inline bool is_empty() const;
1968   inline bool equals(wuffs_base__range_ii_u64__struct s) const;
1969   inline wuffs_base__range_ii_u64__struct intersect(
1970       wuffs_base__range_ii_u64__struct s) const;
1971   inline wuffs_base__range_ii_u64__struct unite(
1972       wuffs_base__range_ii_u64__struct s) const;
1973   inline bool contains(uint64_t x) const;
1974   inline bool contains_range(wuffs_base__range_ii_u64__struct s) const;
1975 #endif  // __cplusplus
1976 
1977 } wuffs_base__range_ii_u64;
1978 
1979 static inline wuffs_base__range_ii_u64  //
wuffs_base__empty_range_ii_u64()1980 wuffs_base__empty_range_ii_u64() {
1981   wuffs_base__range_ii_u64 ret;
1982   ret.min_incl = 0;
1983   ret.max_incl = 0;
1984   return ret;
1985 }
1986 
1987 static inline wuffs_base__range_ii_u64  //
wuffs_base__make_range_ii_u64(uint64_t min_incl,uint64_t max_incl)1988 wuffs_base__make_range_ii_u64(uint64_t min_incl, uint64_t max_incl) {
1989   wuffs_base__range_ii_u64 ret;
1990   ret.min_incl = min_incl;
1991   ret.max_incl = max_incl;
1992   return ret;
1993 }
1994 
1995 static inline bool  //
wuffs_base__range_ii_u64__is_empty(const wuffs_base__range_ii_u64 * r)1996 wuffs_base__range_ii_u64__is_empty(const wuffs_base__range_ii_u64* r) {
1997   return r->min_incl > r->max_incl;
1998 }
1999 
2000 static inline bool  //
wuffs_base__range_ii_u64__equals(const wuffs_base__range_ii_u64 * r,wuffs_base__range_ii_u64 s)2001 wuffs_base__range_ii_u64__equals(const wuffs_base__range_ii_u64* r,
2002                                  wuffs_base__range_ii_u64 s) {
2003   return (r->min_incl == s.min_incl && r->max_incl == s.max_incl) ||
2004          (wuffs_base__range_ii_u64__is_empty(r) &&
2005           wuffs_base__range_ii_u64__is_empty(&s));
2006 }
2007 
2008 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)2009 wuffs_base__range_ii_u64__intersect(const wuffs_base__range_ii_u64* r,
2010                                     wuffs_base__range_ii_u64 s) {
2011   wuffs_base__range_ii_u64 t;
2012   t.min_incl = wuffs_base__u64__max(r->min_incl, s.min_incl);
2013   t.max_incl = wuffs_base__u64__min(r->max_incl, s.max_incl);
2014   return t;
2015 }
2016 
2017 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)2018 wuffs_base__range_ii_u64__unite(const wuffs_base__range_ii_u64* r,
2019                                 wuffs_base__range_ii_u64 s) {
2020   if (wuffs_base__range_ii_u64__is_empty(r)) {
2021     return s;
2022   }
2023   if (wuffs_base__range_ii_u64__is_empty(&s)) {
2024     return *r;
2025   }
2026   wuffs_base__range_ii_u64 t;
2027   t.min_incl = wuffs_base__u64__min(r->min_incl, s.min_incl);
2028   t.max_incl = wuffs_base__u64__max(r->max_incl, s.max_incl);
2029   return t;
2030 }
2031 
2032 static inline bool  //
wuffs_base__range_ii_u64__contains(const wuffs_base__range_ii_u64 * r,uint64_t x)2033 wuffs_base__range_ii_u64__contains(const wuffs_base__range_ii_u64* r,
2034                                    uint64_t x) {
2035   return (r->min_incl <= x) && (x <= r->max_incl);
2036 }
2037 
2038 static inline bool  //
wuffs_base__range_ii_u64__contains_range(const wuffs_base__range_ii_u64 * r,wuffs_base__range_ii_u64 s)2039 wuffs_base__range_ii_u64__contains_range(const wuffs_base__range_ii_u64* r,
2040                                          wuffs_base__range_ii_u64 s) {
2041   return wuffs_base__range_ii_u64__equals(
2042       &s, wuffs_base__range_ii_u64__intersect(r, s));
2043 }
2044 
2045 #ifdef __cplusplus
2046 
2047 inline bool  //
is_empty()2048 wuffs_base__range_ii_u64::is_empty() const {
2049   return wuffs_base__range_ii_u64__is_empty(this);
2050 }
2051 
2052 inline bool  //
equals(wuffs_base__range_ii_u64 s)2053 wuffs_base__range_ii_u64::equals(wuffs_base__range_ii_u64 s) const {
2054   return wuffs_base__range_ii_u64__equals(this, s);
2055 }
2056 
2057 inline wuffs_base__range_ii_u64  //
intersect(wuffs_base__range_ii_u64 s)2058 wuffs_base__range_ii_u64::intersect(wuffs_base__range_ii_u64 s) const {
2059   return wuffs_base__range_ii_u64__intersect(this, s);
2060 }
2061 
2062 inline wuffs_base__range_ii_u64  //
unite(wuffs_base__range_ii_u64 s)2063 wuffs_base__range_ii_u64::unite(wuffs_base__range_ii_u64 s) const {
2064   return wuffs_base__range_ii_u64__unite(this, s);
2065 }
2066 
2067 inline bool  //
contains(uint64_t x)2068 wuffs_base__range_ii_u64::contains(uint64_t x) const {
2069   return wuffs_base__range_ii_u64__contains(this, x);
2070 }
2071 
2072 inline bool  //
contains_range(wuffs_base__range_ii_u64 s)2073 wuffs_base__range_ii_u64::contains_range(wuffs_base__range_ii_u64 s) const {
2074   return wuffs_base__range_ii_u64__contains_range(this, s);
2075 }
2076 
2077 #endif  // __cplusplus
2078 
2079 // --------
2080 
2081 typedef struct wuffs_base__range_ie_u64__struct {
2082   uint64_t min_incl;
2083   uint64_t max_excl;
2084 
2085 #ifdef __cplusplus
2086   inline bool is_empty() const;
2087   inline bool equals(wuffs_base__range_ie_u64__struct s) const;
2088   inline wuffs_base__range_ie_u64__struct intersect(
2089       wuffs_base__range_ie_u64__struct s) const;
2090   inline wuffs_base__range_ie_u64__struct unite(
2091       wuffs_base__range_ie_u64__struct s) const;
2092   inline bool contains(uint64_t x) const;
2093   inline bool contains_range(wuffs_base__range_ie_u64__struct s) const;
2094   inline uint64_t length() const;
2095 #endif  // __cplusplus
2096 
2097 } wuffs_base__range_ie_u64;
2098 
2099 static inline wuffs_base__range_ie_u64  //
wuffs_base__empty_range_ie_u64()2100 wuffs_base__empty_range_ie_u64() {
2101   wuffs_base__range_ie_u64 ret;
2102   ret.min_incl = 0;
2103   ret.max_excl = 0;
2104   return ret;
2105 }
2106 
2107 static inline wuffs_base__range_ie_u64  //
wuffs_base__make_range_ie_u64(uint64_t min_incl,uint64_t max_excl)2108 wuffs_base__make_range_ie_u64(uint64_t min_incl, uint64_t max_excl) {
2109   wuffs_base__range_ie_u64 ret;
2110   ret.min_incl = min_incl;
2111   ret.max_excl = max_excl;
2112   return ret;
2113 }
2114 
2115 static inline bool  //
wuffs_base__range_ie_u64__is_empty(const wuffs_base__range_ie_u64 * r)2116 wuffs_base__range_ie_u64__is_empty(const wuffs_base__range_ie_u64* r) {
2117   return r->min_incl >= r->max_excl;
2118 }
2119 
2120 static inline bool  //
wuffs_base__range_ie_u64__equals(const wuffs_base__range_ie_u64 * r,wuffs_base__range_ie_u64 s)2121 wuffs_base__range_ie_u64__equals(const wuffs_base__range_ie_u64* r,
2122                                  wuffs_base__range_ie_u64 s) {
2123   return (r->min_incl == s.min_incl && r->max_excl == s.max_excl) ||
2124          (wuffs_base__range_ie_u64__is_empty(r) &&
2125           wuffs_base__range_ie_u64__is_empty(&s));
2126 }
2127 
2128 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)2129 wuffs_base__range_ie_u64__intersect(const wuffs_base__range_ie_u64* r,
2130                                     wuffs_base__range_ie_u64 s) {
2131   wuffs_base__range_ie_u64 t;
2132   t.min_incl = wuffs_base__u64__max(r->min_incl, s.min_incl);
2133   t.max_excl = wuffs_base__u64__min(r->max_excl, s.max_excl);
2134   return t;
2135 }
2136 
2137 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)2138 wuffs_base__range_ie_u64__unite(const wuffs_base__range_ie_u64* r,
2139                                 wuffs_base__range_ie_u64 s) {
2140   if (wuffs_base__range_ie_u64__is_empty(r)) {
2141     return s;
2142   }
2143   if (wuffs_base__range_ie_u64__is_empty(&s)) {
2144     return *r;
2145   }
2146   wuffs_base__range_ie_u64 t;
2147   t.min_incl = wuffs_base__u64__min(r->min_incl, s.min_incl);
2148   t.max_excl = wuffs_base__u64__max(r->max_excl, s.max_excl);
2149   return t;
2150 }
2151 
2152 static inline bool  //
wuffs_base__range_ie_u64__contains(const wuffs_base__range_ie_u64 * r,uint64_t x)2153 wuffs_base__range_ie_u64__contains(const wuffs_base__range_ie_u64* r,
2154                                    uint64_t x) {
2155   return (r->min_incl <= x) && (x < r->max_excl);
2156 }
2157 
2158 static inline bool  //
wuffs_base__range_ie_u64__contains_range(const wuffs_base__range_ie_u64 * r,wuffs_base__range_ie_u64 s)2159 wuffs_base__range_ie_u64__contains_range(const wuffs_base__range_ie_u64* r,
2160                                          wuffs_base__range_ie_u64 s) {
2161   return wuffs_base__range_ie_u64__equals(
2162       &s, wuffs_base__range_ie_u64__intersect(r, s));
2163 }
2164 
2165 static inline uint64_t  //
wuffs_base__range_ie_u64__length(const wuffs_base__range_ie_u64 * r)2166 wuffs_base__range_ie_u64__length(const wuffs_base__range_ie_u64* r) {
2167   return wuffs_base__u64__sat_sub(r->max_excl, r->min_incl);
2168 }
2169 
2170 #ifdef __cplusplus
2171 
2172 inline bool  //
is_empty()2173 wuffs_base__range_ie_u64::is_empty() const {
2174   return wuffs_base__range_ie_u64__is_empty(this);
2175 }
2176 
2177 inline bool  //
equals(wuffs_base__range_ie_u64 s)2178 wuffs_base__range_ie_u64::equals(wuffs_base__range_ie_u64 s) const {
2179   return wuffs_base__range_ie_u64__equals(this, s);
2180 }
2181 
2182 inline wuffs_base__range_ie_u64  //
intersect(wuffs_base__range_ie_u64 s)2183 wuffs_base__range_ie_u64::intersect(wuffs_base__range_ie_u64 s) const {
2184   return wuffs_base__range_ie_u64__intersect(this, s);
2185 }
2186 
2187 inline wuffs_base__range_ie_u64  //
unite(wuffs_base__range_ie_u64 s)2188 wuffs_base__range_ie_u64::unite(wuffs_base__range_ie_u64 s) const {
2189   return wuffs_base__range_ie_u64__unite(this, s);
2190 }
2191 
2192 inline bool  //
contains(uint64_t x)2193 wuffs_base__range_ie_u64::contains(uint64_t x) const {
2194   return wuffs_base__range_ie_u64__contains(this, x);
2195 }
2196 
2197 inline bool  //
contains_range(wuffs_base__range_ie_u64 s)2198 wuffs_base__range_ie_u64::contains_range(wuffs_base__range_ie_u64 s) const {
2199   return wuffs_base__range_ie_u64__contains_range(this, s);
2200 }
2201 
2202 inline uint64_t  //
length()2203 wuffs_base__range_ie_u64::length() const {
2204   return wuffs_base__range_ie_u64__length(this);
2205 }
2206 
2207 #endif  // __cplusplus
2208 
2209 // --------
2210 
2211 typedef struct wuffs_base__rect_ii_u32__struct {
2212   uint32_t min_incl_x;
2213   uint32_t min_incl_y;
2214   uint32_t max_incl_x;
2215   uint32_t max_incl_y;
2216 
2217 #ifdef __cplusplus
2218   inline bool is_empty() const;
2219   inline bool equals(wuffs_base__rect_ii_u32__struct s) const;
2220   inline wuffs_base__rect_ii_u32__struct intersect(
2221       wuffs_base__rect_ii_u32__struct s) const;
2222   inline wuffs_base__rect_ii_u32__struct unite(
2223       wuffs_base__rect_ii_u32__struct s) const;
2224   inline bool contains(uint32_t x, uint32_t y) const;
2225   inline bool contains_rect(wuffs_base__rect_ii_u32__struct s) const;
2226 #endif  // __cplusplus
2227 
2228 } wuffs_base__rect_ii_u32;
2229 
2230 static inline wuffs_base__rect_ii_u32  //
wuffs_base__empty_rect_ii_u32()2231 wuffs_base__empty_rect_ii_u32() {
2232   wuffs_base__rect_ii_u32 ret;
2233   ret.min_incl_x = 0;
2234   ret.min_incl_y = 0;
2235   ret.max_incl_x = 0;
2236   ret.max_incl_y = 0;
2237   return ret;
2238 }
2239 
2240 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)2241 wuffs_base__make_rect_ii_u32(uint32_t min_incl_x,
2242                              uint32_t min_incl_y,
2243                              uint32_t max_incl_x,
2244                              uint32_t max_incl_y) {
2245   wuffs_base__rect_ii_u32 ret;
2246   ret.min_incl_x = min_incl_x;
2247   ret.min_incl_y = min_incl_y;
2248   ret.max_incl_x = max_incl_x;
2249   ret.max_incl_y = max_incl_y;
2250   return ret;
2251 }
2252 
2253 static inline bool  //
wuffs_base__rect_ii_u32__is_empty(const wuffs_base__rect_ii_u32 * r)2254 wuffs_base__rect_ii_u32__is_empty(const wuffs_base__rect_ii_u32* r) {
2255   return (r->min_incl_x > r->max_incl_x) || (r->min_incl_y > r->max_incl_y);
2256 }
2257 
2258 static inline bool  //
wuffs_base__rect_ii_u32__equals(const wuffs_base__rect_ii_u32 * r,wuffs_base__rect_ii_u32 s)2259 wuffs_base__rect_ii_u32__equals(const wuffs_base__rect_ii_u32* r,
2260                                 wuffs_base__rect_ii_u32 s) {
2261   return (r->min_incl_x == s.min_incl_x && r->min_incl_y == s.min_incl_y &&
2262           r->max_incl_x == s.max_incl_x && r->max_incl_y == s.max_incl_y) ||
2263          (wuffs_base__rect_ii_u32__is_empty(r) &&
2264           wuffs_base__rect_ii_u32__is_empty(&s));
2265 }
2266 
2267 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)2268 wuffs_base__rect_ii_u32__intersect(const wuffs_base__rect_ii_u32* r,
2269                                    wuffs_base__rect_ii_u32 s) {
2270   wuffs_base__rect_ii_u32 t;
2271   t.min_incl_x = wuffs_base__u32__max(r->min_incl_x, s.min_incl_x);
2272   t.min_incl_y = wuffs_base__u32__max(r->min_incl_y, s.min_incl_y);
2273   t.max_incl_x = wuffs_base__u32__min(r->max_incl_x, s.max_incl_x);
2274   t.max_incl_y = wuffs_base__u32__min(r->max_incl_y, s.max_incl_y);
2275   return t;
2276 }
2277 
2278 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)2279 wuffs_base__rect_ii_u32__unite(const wuffs_base__rect_ii_u32* r,
2280                                wuffs_base__rect_ii_u32 s) {
2281   if (wuffs_base__rect_ii_u32__is_empty(r)) {
2282     return s;
2283   }
2284   if (wuffs_base__rect_ii_u32__is_empty(&s)) {
2285     return *r;
2286   }
2287   wuffs_base__rect_ii_u32 t;
2288   t.min_incl_x = wuffs_base__u32__min(r->min_incl_x, s.min_incl_x);
2289   t.min_incl_y = wuffs_base__u32__min(r->min_incl_y, s.min_incl_y);
2290   t.max_incl_x = wuffs_base__u32__max(r->max_incl_x, s.max_incl_x);
2291   t.max_incl_y = wuffs_base__u32__max(r->max_incl_y, s.max_incl_y);
2292   return t;
2293 }
2294 
2295 static inline bool  //
wuffs_base__rect_ii_u32__contains(const wuffs_base__rect_ii_u32 * r,uint32_t x,uint32_t y)2296 wuffs_base__rect_ii_u32__contains(const wuffs_base__rect_ii_u32* r,
2297                                   uint32_t x,
2298                                   uint32_t y) {
2299   return (r->min_incl_x <= x) && (x <= r->max_incl_x) && (r->min_incl_y <= y) &&
2300          (y <= r->max_incl_y);
2301 }
2302 
2303 static inline bool  //
wuffs_base__rect_ii_u32__contains_rect(const wuffs_base__rect_ii_u32 * r,wuffs_base__rect_ii_u32 s)2304 wuffs_base__rect_ii_u32__contains_rect(const wuffs_base__rect_ii_u32* r,
2305                                        wuffs_base__rect_ii_u32 s) {
2306   return wuffs_base__rect_ii_u32__equals(
2307       &s, wuffs_base__rect_ii_u32__intersect(r, s));
2308 }
2309 
2310 #ifdef __cplusplus
2311 
2312 inline bool  //
is_empty()2313 wuffs_base__rect_ii_u32::is_empty() const {
2314   return wuffs_base__rect_ii_u32__is_empty(this);
2315 }
2316 
2317 inline bool  //
equals(wuffs_base__rect_ii_u32 s)2318 wuffs_base__rect_ii_u32::equals(wuffs_base__rect_ii_u32 s) const {
2319   return wuffs_base__rect_ii_u32__equals(this, s);
2320 }
2321 
2322 inline wuffs_base__rect_ii_u32  //
intersect(wuffs_base__rect_ii_u32 s)2323 wuffs_base__rect_ii_u32::intersect(wuffs_base__rect_ii_u32 s) const {
2324   return wuffs_base__rect_ii_u32__intersect(this, s);
2325 }
2326 
2327 inline wuffs_base__rect_ii_u32  //
unite(wuffs_base__rect_ii_u32 s)2328 wuffs_base__rect_ii_u32::unite(wuffs_base__rect_ii_u32 s) const {
2329   return wuffs_base__rect_ii_u32__unite(this, s);
2330 }
2331 
2332 inline bool  //
contains(uint32_t x,uint32_t y)2333 wuffs_base__rect_ii_u32::contains(uint32_t x, uint32_t y) const {
2334   return wuffs_base__rect_ii_u32__contains(this, x, y);
2335 }
2336 
2337 inline bool  //
contains_rect(wuffs_base__rect_ii_u32 s)2338 wuffs_base__rect_ii_u32::contains_rect(wuffs_base__rect_ii_u32 s) const {
2339   return wuffs_base__rect_ii_u32__contains_rect(this, s);
2340 }
2341 
2342 #endif  // __cplusplus
2343 
2344 // --------
2345 
2346 typedef struct wuffs_base__rect_ie_u32__struct {
2347   uint32_t min_incl_x;
2348   uint32_t min_incl_y;
2349   uint32_t max_excl_x;
2350   uint32_t max_excl_y;
2351 
2352 #ifdef __cplusplus
2353   inline bool is_empty() const;
2354   inline bool equals(wuffs_base__rect_ie_u32__struct s) const;
2355   inline wuffs_base__rect_ie_u32__struct intersect(
2356       wuffs_base__rect_ie_u32__struct s) const;
2357   inline wuffs_base__rect_ie_u32__struct unite(
2358       wuffs_base__rect_ie_u32__struct s) const;
2359   inline bool contains(uint32_t x, uint32_t y) const;
2360   inline bool contains_rect(wuffs_base__rect_ie_u32__struct s) const;
2361   inline uint32_t width() const;
2362   inline uint32_t height() const;
2363 #endif  // __cplusplus
2364 
2365 } wuffs_base__rect_ie_u32;
2366 
2367 static inline wuffs_base__rect_ie_u32  //
wuffs_base__empty_rect_ie_u32()2368 wuffs_base__empty_rect_ie_u32() {
2369   wuffs_base__rect_ie_u32 ret;
2370   ret.min_incl_x = 0;
2371   ret.min_incl_y = 0;
2372   ret.max_excl_x = 0;
2373   ret.max_excl_y = 0;
2374   return ret;
2375 }
2376 
2377 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)2378 wuffs_base__make_rect_ie_u32(uint32_t min_incl_x,
2379                              uint32_t min_incl_y,
2380                              uint32_t max_excl_x,
2381                              uint32_t max_excl_y) {
2382   wuffs_base__rect_ie_u32 ret;
2383   ret.min_incl_x = min_incl_x;
2384   ret.min_incl_y = min_incl_y;
2385   ret.max_excl_x = max_excl_x;
2386   ret.max_excl_y = max_excl_y;
2387   return ret;
2388 }
2389 
2390 static inline bool  //
wuffs_base__rect_ie_u32__is_empty(const wuffs_base__rect_ie_u32 * r)2391 wuffs_base__rect_ie_u32__is_empty(const wuffs_base__rect_ie_u32* r) {
2392   return (r->min_incl_x >= r->max_excl_x) || (r->min_incl_y >= r->max_excl_y);
2393 }
2394 
2395 static inline bool  //
wuffs_base__rect_ie_u32__equals(const wuffs_base__rect_ie_u32 * r,wuffs_base__rect_ie_u32 s)2396 wuffs_base__rect_ie_u32__equals(const wuffs_base__rect_ie_u32* r,
2397                                 wuffs_base__rect_ie_u32 s) {
2398   return (r->min_incl_x == s.min_incl_x && r->min_incl_y == s.min_incl_y &&
2399           r->max_excl_x == s.max_excl_x && r->max_excl_y == s.max_excl_y) ||
2400          (wuffs_base__rect_ie_u32__is_empty(r) &&
2401           wuffs_base__rect_ie_u32__is_empty(&s));
2402 }
2403 
2404 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)2405 wuffs_base__rect_ie_u32__intersect(const wuffs_base__rect_ie_u32* r,
2406                                    wuffs_base__rect_ie_u32 s) {
2407   wuffs_base__rect_ie_u32 t;
2408   t.min_incl_x = wuffs_base__u32__max(r->min_incl_x, s.min_incl_x);
2409   t.min_incl_y = wuffs_base__u32__max(r->min_incl_y, s.min_incl_y);
2410   t.max_excl_x = wuffs_base__u32__min(r->max_excl_x, s.max_excl_x);
2411   t.max_excl_y = wuffs_base__u32__min(r->max_excl_y, s.max_excl_y);
2412   return t;
2413 }
2414 
2415 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)2416 wuffs_base__rect_ie_u32__unite(const wuffs_base__rect_ie_u32* r,
2417                                wuffs_base__rect_ie_u32 s) {
2418   if (wuffs_base__rect_ie_u32__is_empty(r)) {
2419     return s;
2420   }
2421   if (wuffs_base__rect_ie_u32__is_empty(&s)) {
2422     return *r;
2423   }
2424   wuffs_base__rect_ie_u32 t;
2425   t.min_incl_x = wuffs_base__u32__min(r->min_incl_x, s.min_incl_x);
2426   t.min_incl_y = wuffs_base__u32__min(r->min_incl_y, s.min_incl_y);
2427   t.max_excl_x = wuffs_base__u32__max(r->max_excl_x, s.max_excl_x);
2428   t.max_excl_y = wuffs_base__u32__max(r->max_excl_y, s.max_excl_y);
2429   return t;
2430 }
2431 
2432 static inline bool  //
wuffs_base__rect_ie_u32__contains(const wuffs_base__rect_ie_u32 * r,uint32_t x,uint32_t y)2433 wuffs_base__rect_ie_u32__contains(const wuffs_base__rect_ie_u32* r,
2434                                   uint32_t x,
2435                                   uint32_t y) {
2436   return (r->min_incl_x <= x) && (x < r->max_excl_x) && (r->min_incl_y <= y) &&
2437          (y < r->max_excl_y);
2438 }
2439 
2440 static inline bool  //
wuffs_base__rect_ie_u32__contains_rect(const wuffs_base__rect_ie_u32 * r,wuffs_base__rect_ie_u32 s)2441 wuffs_base__rect_ie_u32__contains_rect(const wuffs_base__rect_ie_u32* r,
2442                                        wuffs_base__rect_ie_u32 s) {
2443   return wuffs_base__rect_ie_u32__equals(
2444       &s, wuffs_base__rect_ie_u32__intersect(r, s));
2445 }
2446 
2447 static inline uint32_t  //
wuffs_base__rect_ie_u32__width(const wuffs_base__rect_ie_u32 * r)2448 wuffs_base__rect_ie_u32__width(const wuffs_base__rect_ie_u32* r) {
2449   return wuffs_base__u32__sat_sub(r->max_excl_x, r->min_incl_x);
2450 }
2451 
2452 static inline uint32_t  //
wuffs_base__rect_ie_u32__height(const wuffs_base__rect_ie_u32 * r)2453 wuffs_base__rect_ie_u32__height(const wuffs_base__rect_ie_u32* r) {
2454   return wuffs_base__u32__sat_sub(r->max_excl_y, r->min_incl_y);
2455 }
2456 
2457 #ifdef __cplusplus
2458 
2459 inline bool  //
is_empty()2460 wuffs_base__rect_ie_u32::is_empty() const {
2461   return wuffs_base__rect_ie_u32__is_empty(this);
2462 }
2463 
2464 inline bool  //
equals(wuffs_base__rect_ie_u32 s)2465 wuffs_base__rect_ie_u32::equals(wuffs_base__rect_ie_u32 s) const {
2466   return wuffs_base__rect_ie_u32__equals(this, s);
2467 }
2468 
2469 inline wuffs_base__rect_ie_u32  //
intersect(wuffs_base__rect_ie_u32 s)2470 wuffs_base__rect_ie_u32::intersect(wuffs_base__rect_ie_u32 s) const {
2471   return wuffs_base__rect_ie_u32__intersect(this, s);
2472 }
2473 
2474 inline wuffs_base__rect_ie_u32  //
unite(wuffs_base__rect_ie_u32 s)2475 wuffs_base__rect_ie_u32::unite(wuffs_base__rect_ie_u32 s) const {
2476   return wuffs_base__rect_ie_u32__unite(this, s);
2477 }
2478 
2479 inline bool  //
contains(uint32_t x,uint32_t y)2480 wuffs_base__rect_ie_u32::contains(uint32_t x, uint32_t y) const {
2481   return wuffs_base__rect_ie_u32__contains(this, x, y);
2482 }
2483 
2484 inline bool  //
contains_rect(wuffs_base__rect_ie_u32 s)2485 wuffs_base__rect_ie_u32::contains_rect(wuffs_base__rect_ie_u32 s) const {
2486   return wuffs_base__rect_ie_u32__contains_rect(this, s);
2487 }
2488 
2489 inline uint32_t  //
width()2490 wuffs_base__rect_ie_u32::width() const {
2491   return wuffs_base__rect_ie_u32__width(this);
2492 }
2493 
2494 inline uint32_t  //
height()2495 wuffs_base__rect_ie_u32::height() const {
2496   return wuffs_base__rect_ie_u32__height(this);
2497 }
2498 
2499 #endif  // __cplusplus
2500 
2501 // ---------------- More Information
2502 
2503 // wuffs_base__more_information holds additional fields, typically when a Wuffs
2504 // method returns a [note status](/doc/note/statuses.md).
2505 //
2506 // The flavor field follows the base38 namespace
2507 // convention](/doc/note/base38-and-fourcc.md). The other fields' semantics
2508 // depends on the flavor.
2509 typedef struct wuffs_base__more_information__struct {
2510   uint32_t flavor;
2511   uint32_t w;
2512   uint64_t x;
2513   uint64_t y;
2514   uint64_t z;
2515 
2516 #ifdef __cplusplus
2517   inline void set(uint32_t flavor_arg,
2518                   uint32_t w_arg,
2519                   uint64_t x_arg,
2520                   uint64_t y_arg,
2521                   uint64_t z_arg);
2522   inline uint32_t io_redirect__fourcc() const;
2523   inline wuffs_base__range_ie_u64 io_redirect__range() const;
2524   inline uint64_t io_seek__position() const;
2525   inline uint32_t metadata__fourcc() const;
2526   // Deprecated: use metadata_raw_passthrough__range.
2527   inline wuffs_base__range_ie_u64 metadata__range() const;
2528   inline wuffs_base__range_ie_u64 metadata_raw_passthrough__range() const;
2529   inline int32_t metadata_parsed__chrm(uint32_t component) const;
2530   inline uint32_t metadata_parsed__gama() const;
2531   inline uint32_t metadata_parsed__srgb() const;
2532 #endif  // __cplusplus
2533 
2534 } wuffs_base__more_information;
2535 
2536 #define WUFFS_BASE__MORE_INFORMATION__FLAVOR__IO_REDIRECT 1
2537 #define WUFFS_BASE__MORE_INFORMATION__FLAVOR__IO_SEEK 2
2538 // Deprecated: use
2539 // WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_RAW_PASSTHROUGH.
2540 #define WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA 3
2541 #define WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_RAW_PASSTHROUGH 3
2542 #define WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_RAW_TRANSFORM 4
2543 #define WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_PARSED 5
2544 
2545 static inline wuffs_base__more_information  //
wuffs_base__empty_more_information()2546 wuffs_base__empty_more_information() {
2547   wuffs_base__more_information ret;
2548   ret.flavor = 0;
2549   ret.w = 0;
2550   ret.x = 0;
2551   ret.y = 0;
2552   ret.z = 0;
2553   return ret;
2554 }
2555 
2556 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)2557 wuffs_base__more_information__set(wuffs_base__more_information* m,
2558                                   uint32_t flavor,
2559                                   uint32_t w,
2560                                   uint64_t x,
2561                                   uint64_t y,
2562                                   uint64_t z) {
2563   if (!m) {
2564     return;
2565   }
2566   m->flavor = flavor;
2567   m->w = w;
2568   m->x = x;
2569   m->y = y;
2570   m->z = z;
2571 }
2572 
2573 static inline uint32_t  //
wuffs_base__more_information__io_redirect__fourcc(const wuffs_base__more_information * m)2574 wuffs_base__more_information__io_redirect__fourcc(
2575     const wuffs_base__more_information* m) {
2576   return m->w;
2577 }
2578 
2579 static inline wuffs_base__range_ie_u64  //
wuffs_base__more_information__io_redirect__range(const wuffs_base__more_information * m)2580 wuffs_base__more_information__io_redirect__range(
2581     const wuffs_base__more_information* m) {
2582   wuffs_base__range_ie_u64 ret;
2583   ret.min_incl = m->y;
2584   ret.max_excl = m->z;
2585   return ret;
2586 }
2587 
2588 static inline uint64_t  //
wuffs_base__more_information__io_seek__position(const wuffs_base__more_information * m)2589 wuffs_base__more_information__io_seek__position(
2590     const wuffs_base__more_information* m) {
2591   return m->x;
2592 }
2593 
2594 static inline uint32_t  //
wuffs_base__more_information__metadata__fourcc(const wuffs_base__more_information * m)2595 wuffs_base__more_information__metadata__fourcc(
2596     const wuffs_base__more_information* m) {
2597   return m->w;
2598 }
2599 
2600 // Deprecated: use
2601 // wuffs_base__more_information__metadata_raw_passthrough__range.
2602 static inline wuffs_base__range_ie_u64  //
wuffs_base__more_information__metadata__range(const wuffs_base__more_information * m)2603 wuffs_base__more_information__metadata__range(
2604     const wuffs_base__more_information* m) {
2605   wuffs_base__range_ie_u64 ret;
2606   ret.min_incl = m->y;
2607   ret.max_excl = m->z;
2608   return ret;
2609 }
2610 
2611 static inline wuffs_base__range_ie_u64  //
wuffs_base__more_information__metadata_raw_passthrough__range(const wuffs_base__more_information * m)2612 wuffs_base__more_information__metadata_raw_passthrough__range(
2613     const wuffs_base__more_information* m) {
2614   wuffs_base__range_ie_u64 ret;
2615   ret.min_incl = m->y;
2616   ret.max_excl = m->z;
2617   return ret;
2618 }
2619 
2620 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__WHITE_X 0
2621 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__WHITE_Y 1
2622 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__RED_X 2
2623 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__RED_Y 3
2624 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__GREEN_X 4
2625 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__GREEN_Y 5
2626 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__BLUE_X 6
2627 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__BLUE_Y 7
2628 
2629 // wuffs_base__more_information__metadata_parsed__chrm returns chromaticity
2630 // values (scaled by 100000) like the PNG "cHRM" chunk. For example, the sRGB
2631 // color space corresponds to:
2632 //  - ETC__CHRM__WHITE_X 31270
2633 //  - ETC__CHRM__WHITE_Y 32900
2634 //  - ETC__CHRM__RED_X   64000
2635 //  - ETC__CHRM__RED_Y   33000
2636 //  - ETC__CHRM__GREEN_X 30000
2637 //  - ETC__CHRM__GREEN_Y 60000
2638 //  - ETC__CHRM__BLUE_X  15000
2639 //  - ETC__CHRM__BLUE_Y   6000
2640 //
2641 // See
2642 // https://ciechanow.ski/color-spaces/#chromaticity-and-white-point-coordinates
2643 static inline int32_t  //
wuffs_base__more_information__metadata_parsed__chrm(const wuffs_base__more_information * m,uint32_t component)2644 wuffs_base__more_information__metadata_parsed__chrm(
2645     const wuffs_base__more_information* m,
2646     uint32_t component) {
2647   // After the flavor and the w field (holding a FourCC), a
2648   // wuffs_base__more_information holds 24 bytes of data in three uint64_t
2649   // typed fields (x, y and z). We pack the eight chromaticity values (wx, wy,
2650   // rx, ..., by), basically int24_t values, into 24 bytes like this:
2651   //  -    LSB                 MSB
2652   //  - x: wx wx wx wy wy wy rx rx
2653   //  - y: rx ry ry ry gx gx gx gy
2654   //  - z: gy gy bx bx bx by by by
2655   uint32_t u = 0;
2656   switch (component & 7) {
2657     case 0:
2658       u = ((uint32_t)(m->x >> 0));
2659       break;
2660     case 1:
2661       u = ((uint32_t)(m->x >> 24));
2662       break;
2663     case 2:
2664       u = ((uint32_t)((m->x >> 48) | (m->y << 16)));
2665       break;
2666     case 3:
2667       u = ((uint32_t)(m->y >> 8));
2668       break;
2669     case 4:
2670       u = ((uint32_t)(m->y >> 32));
2671       break;
2672     case 5:
2673       u = ((uint32_t)((m->y >> 56) | (m->z << 8)));
2674       break;
2675     case 6:
2676       u = ((uint32_t)(m->z >> 16));
2677       break;
2678     case 7:
2679       u = ((uint32_t)(m->z >> 40));
2680       break;
2681   }
2682   // The left-right shifts sign-extend from 24-bit to 32-bit integers.
2683   return ((int32_t)(u << 8)) >> 8;
2684 }
2685 
2686 // wuffs_base__more_information__metadata_parsed__gama returns inverse gamma
2687 // correction values (scaled by 100000) like the PNG "gAMA" chunk. For example,
2688 // for gamma = 2.2, this returns 45455 (approximating 100000 / 2.2).
2689 static inline uint32_t  //
wuffs_base__more_information__metadata_parsed__gama(const wuffs_base__more_information * m)2690 wuffs_base__more_information__metadata_parsed__gama(
2691     const wuffs_base__more_information* m) {
2692   return ((uint32_t)(m->x));
2693 }
2694 
2695 #define WUFFS_BASE__SRGB_RENDERING_INTENT__PERCEPTUAL 0
2696 #define WUFFS_BASE__SRGB_RENDERING_INTENT__RELATIVE_COLORIMETRIC 1
2697 #define WUFFS_BASE__SRGB_RENDERING_INTENT__SATURATION 2
2698 #define WUFFS_BASE__SRGB_RENDERING_INTENT__ABSOLUTE_COLORIMETRIC 3
2699 
2700 // wuffs_base__more_information__metadata_parsed__srgb returns the sRGB
2701 // rendering intent like the PNG "sRGB" chunk.
2702 static inline uint32_t  //
wuffs_base__more_information__metadata_parsed__srgb(const wuffs_base__more_information * m)2703 wuffs_base__more_information__metadata_parsed__srgb(
2704     const wuffs_base__more_information* m) {
2705   return m->x & 3;
2706 }
2707 
2708 #ifdef __cplusplus
2709 
2710 inline void  //
set(uint32_t flavor_arg,uint32_t w_arg,uint64_t x_arg,uint64_t y_arg,uint64_t z_arg)2711 wuffs_base__more_information::set(uint32_t flavor_arg,
2712                                   uint32_t w_arg,
2713                                   uint64_t x_arg,
2714                                   uint64_t y_arg,
2715                                   uint64_t z_arg) {
2716   wuffs_base__more_information__set(this, flavor_arg, w_arg, x_arg, y_arg,
2717                                     z_arg);
2718 }
2719 
2720 inline uint32_t  //
io_redirect__fourcc()2721 wuffs_base__more_information::io_redirect__fourcc() const {
2722   return wuffs_base__more_information__io_redirect__fourcc(this);
2723 }
2724 
2725 inline wuffs_base__range_ie_u64  //
io_redirect__range()2726 wuffs_base__more_information::io_redirect__range() const {
2727   return wuffs_base__more_information__io_redirect__range(this);
2728 }
2729 
2730 inline uint64_t  //
io_seek__position()2731 wuffs_base__more_information::io_seek__position() const {
2732   return wuffs_base__more_information__io_seek__position(this);
2733 }
2734 
2735 inline uint32_t  //
metadata__fourcc()2736 wuffs_base__more_information::metadata__fourcc() const {
2737   return wuffs_base__more_information__metadata__fourcc(this);
2738 }
2739 
2740 inline wuffs_base__range_ie_u64  //
metadata__range()2741 wuffs_base__more_information::metadata__range() const {
2742   return wuffs_base__more_information__metadata__range(this);
2743 }
2744 
2745 inline wuffs_base__range_ie_u64  //
metadata_raw_passthrough__range()2746 wuffs_base__more_information::metadata_raw_passthrough__range() const {
2747   return wuffs_base__more_information__metadata_raw_passthrough__range(this);
2748 }
2749 
2750 inline int32_t  //
metadata_parsed__chrm(uint32_t component)2751 wuffs_base__more_information::metadata_parsed__chrm(uint32_t component) const {
2752   return wuffs_base__more_information__metadata_parsed__chrm(this, component);
2753 }
2754 
2755 inline uint32_t  //
metadata_parsed__gama()2756 wuffs_base__more_information::metadata_parsed__gama() const {
2757   return wuffs_base__more_information__metadata_parsed__gama(this);
2758 }
2759 
2760 inline uint32_t  //
metadata_parsed__srgb()2761 wuffs_base__more_information::metadata_parsed__srgb() const {
2762   return wuffs_base__more_information__metadata_parsed__srgb(this);
2763 }
2764 
2765 #endif  // __cplusplus
2766 
2767 // ---------------- I/O
2768 //
2769 // See (/doc/note/io-input-output.md).
2770 
2771 // wuffs_base__io_buffer_meta is the metadata for a wuffs_base__io_buffer's
2772 // data.
2773 typedef struct wuffs_base__io_buffer_meta__struct {
2774   size_t wi;     // Write index. Invariant: wi <= len.
2775   size_t ri;     // Read  index. Invariant: ri <= wi.
2776   uint64_t pos;  // Buffer position (relative to the start of stream).
2777   bool closed;   // No further writes are expected.
2778 } wuffs_base__io_buffer_meta;
2779 
2780 // wuffs_base__io_buffer is a 1-dimensional buffer (a pointer and length) plus
2781 // additional metadata.
2782 //
2783 // A value with all fields zero is a valid, empty buffer.
2784 typedef struct wuffs_base__io_buffer__struct {
2785   wuffs_base__slice_u8 data;
2786   wuffs_base__io_buffer_meta meta;
2787 
2788 #ifdef __cplusplus
2789   inline bool is_valid() const;
2790   inline void compact();
2791   inline size_t reader_length() const;
2792   inline uint8_t* reader_pointer() const;
2793   inline uint64_t reader_position() const;
2794   inline wuffs_base__slice_u8 reader_slice() const;
2795   inline size_t writer_length() const;
2796   inline uint8_t* writer_pointer() const;
2797   inline uint64_t writer_position() const;
2798   inline wuffs_base__slice_u8 writer_slice() const;
2799 
2800   // Deprecated: use reader_position.
2801   inline uint64_t reader_io_position() const;
2802   // Deprecated: use writer_position.
2803   inline uint64_t writer_io_position() const;
2804 #endif  // __cplusplus
2805 
2806 } wuffs_base__io_buffer;
2807 
2808 static inline wuffs_base__io_buffer  //
wuffs_base__make_io_buffer(wuffs_base__slice_u8 data,wuffs_base__io_buffer_meta meta)2809 wuffs_base__make_io_buffer(wuffs_base__slice_u8 data,
2810                            wuffs_base__io_buffer_meta meta) {
2811   wuffs_base__io_buffer ret;
2812   ret.data = data;
2813   ret.meta = meta;
2814   return ret;
2815 }
2816 
2817 static inline wuffs_base__io_buffer_meta  //
wuffs_base__make_io_buffer_meta(size_t wi,size_t ri,uint64_t pos,bool closed)2818 wuffs_base__make_io_buffer_meta(size_t wi,
2819                                 size_t ri,
2820                                 uint64_t pos,
2821                                 bool closed) {
2822   wuffs_base__io_buffer_meta ret;
2823   ret.wi = wi;
2824   ret.ri = ri;
2825   ret.pos = pos;
2826   ret.closed = closed;
2827   return ret;
2828 }
2829 
2830 static inline wuffs_base__io_buffer  //
wuffs_base__ptr_u8__reader(uint8_t * ptr,size_t len,bool closed)2831 wuffs_base__ptr_u8__reader(uint8_t* ptr, size_t len, bool closed) {
2832   wuffs_base__io_buffer ret;
2833   ret.data.ptr = ptr;
2834   ret.data.len = len;
2835   ret.meta.wi = len;
2836   ret.meta.ri = 0;
2837   ret.meta.pos = 0;
2838   ret.meta.closed = closed;
2839   return ret;
2840 }
2841 
2842 static inline wuffs_base__io_buffer  //
wuffs_base__ptr_u8__writer(uint8_t * ptr,size_t len)2843 wuffs_base__ptr_u8__writer(uint8_t* ptr, size_t len) {
2844   wuffs_base__io_buffer ret;
2845   ret.data.ptr = ptr;
2846   ret.data.len = len;
2847   ret.meta.wi = 0;
2848   ret.meta.ri = 0;
2849   ret.meta.pos = 0;
2850   ret.meta.closed = false;
2851   return ret;
2852 }
2853 
2854 static inline wuffs_base__io_buffer  //
wuffs_base__slice_u8__reader(wuffs_base__slice_u8 s,bool closed)2855 wuffs_base__slice_u8__reader(wuffs_base__slice_u8 s, bool closed) {
2856   wuffs_base__io_buffer ret;
2857   ret.data.ptr = s.ptr;
2858   ret.data.len = s.len;
2859   ret.meta.wi = s.len;
2860   ret.meta.ri = 0;
2861   ret.meta.pos = 0;
2862   ret.meta.closed = closed;
2863   return ret;
2864 }
2865 
2866 static inline wuffs_base__io_buffer  //
wuffs_base__slice_u8__writer(wuffs_base__slice_u8 s)2867 wuffs_base__slice_u8__writer(wuffs_base__slice_u8 s) {
2868   wuffs_base__io_buffer ret;
2869   ret.data.ptr = s.ptr;
2870   ret.data.len = s.len;
2871   ret.meta.wi = 0;
2872   ret.meta.ri = 0;
2873   ret.meta.pos = 0;
2874   ret.meta.closed = false;
2875   return ret;
2876 }
2877 
2878 static inline wuffs_base__io_buffer  //
wuffs_base__empty_io_buffer()2879 wuffs_base__empty_io_buffer() {
2880   wuffs_base__io_buffer ret;
2881   ret.data.ptr = NULL;
2882   ret.data.len = 0;
2883   ret.meta.wi = 0;
2884   ret.meta.ri = 0;
2885   ret.meta.pos = 0;
2886   ret.meta.closed = false;
2887   return ret;
2888 }
2889 
2890 static inline wuffs_base__io_buffer_meta  //
wuffs_base__empty_io_buffer_meta()2891 wuffs_base__empty_io_buffer_meta() {
2892   wuffs_base__io_buffer_meta ret;
2893   ret.wi = 0;
2894   ret.ri = 0;
2895   ret.pos = 0;
2896   ret.closed = false;
2897   return ret;
2898 }
2899 
2900 static inline bool  //
wuffs_base__io_buffer__is_valid(const wuffs_base__io_buffer * buf)2901 wuffs_base__io_buffer__is_valid(const wuffs_base__io_buffer* buf) {
2902   if (buf) {
2903     if (buf->data.ptr) {
2904       return (buf->meta.ri <= buf->meta.wi) && (buf->meta.wi <= buf->data.len);
2905     } else {
2906       return (buf->meta.ri == 0) && (buf->meta.wi == 0) && (buf->data.len == 0);
2907     }
2908   }
2909   return false;
2910 }
2911 
2912 // wuffs_base__io_buffer__compact moves any written but unread bytes to the
2913 // start of the buffer.
2914 static inline void  //
wuffs_base__io_buffer__compact(wuffs_base__io_buffer * buf)2915 wuffs_base__io_buffer__compact(wuffs_base__io_buffer* buf) {
2916   if (!buf || (buf->meta.ri == 0)) {
2917     return;
2918   }
2919   buf->meta.pos = wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.ri);
2920   size_t n = buf->meta.wi - buf->meta.ri;
2921   if (n != 0) {
2922     memmove(buf->data.ptr, buf->data.ptr + buf->meta.ri, n);
2923   }
2924   buf->meta.wi = n;
2925   buf->meta.ri = 0;
2926 }
2927 
2928 // Deprecated. Use wuffs_base__io_buffer__reader_position.
2929 static inline uint64_t  //
wuffs_base__io_buffer__reader_io_position(const wuffs_base__io_buffer * buf)2930 wuffs_base__io_buffer__reader_io_position(const wuffs_base__io_buffer* buf) {
2931   return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.ri) : 0;
2932 }
2933 
2934 static inline size_t  //
wuffs_base__io_buffer__reader_length(const wuffs_base__io_buffer * buf)2935 wuffs_base__io_buffer__reader_length(const wuffs_base__io_buffer* buf) {
2936   return buf ? buf->meta.wi - buf->meta.ri : 0;
2937 }
2938 
2939 static inline uint8_t*  //
wuffs_base__io_buffer__reader_pointer(const wuffs_base__io_buffer * buf)2940 wuffs_base__io_buffer__reader_pointer(const wuffs_base__io_buffer* buf) {
2941   return buf ? (buf->data.ptr + buf->meta.ri) : NULL;
2942 }
2943 
2944 static inline uint64_t  //
wuffs_base__io_buffer__reader_position(const wuffs_base__io_buffer * buf)2945 wuffs_base__io_buffer__reader_position(const wuffs_base__io_buffer* buf) {
2946   return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.ri) : 0;
2947 }
2948 
2949 static inline wuffs_base__slice_u8  //
wuffs_base__io_buffer__reader_slice(const wuffs_base__io_buffer * buf)2950 wuffs_base__io_buffer__reader_slice(const wuffs_base__io_buffer* buf) {
2951   return buf ? wuffs_base__make_slice_u8(buf->data.ptr + buf->meta.ri,
2952                                          buf->meta.wi - buf->meta.ri)
2953              : wuffs_base__empty_slice_u8();
2954 }
2955 
2956 // Deprecated. Use wuffs_base__io_buffer__writer_position.
2957 static inline uint64_t  //
wuffs_base__io_buffer__writer_io_position(const wuffs_base__io_buffer * buf)2958 wuffs_base__io_buffer__writer_io_position(const wuffs_base__io_buffer* buf) {
2959   return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.wi) : 0;
2960 }
2961 
2962 static inline size_t  //
wuffs_base__io_buffer__writer_length(const wuffs_base__io_buffer * buf)2963 wuffs_base__io_buffer__writer_length(const wuffs_base__io_buffer* buf) {
2964   return buf ? buf->data.len - buf->meta.wi : 0;
2965 }
2966 
2967 static inline uint8_t*  //
wuffs_base__io_buffer__writer_pointer(const wuffs_base__io_buffer * buf)2968 wuffs_base__io_buffer__writer_pointer(const wuffs_base__io_buffer* buf) {
2969   return buf ? (buf->data.ptr + buf->meta.wi) : NULL;
2970 }
2971 
2972 static inline uint64_t  //
wuffs_base__io_buffer__writer_position(const wuffs_base__io_buffer * buf)2973 wuffs_base__io_buffer__writer_position(const wuffs_base__io_buffer* buf) {
2974   return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.wi) : 0;
2975 }
2976 
2977 static inline wuffs_base__slice_u8  //
wuffs_base__io_buffer__writer_slice(const wuffs_base__io_buffer * buf)2978 wuffs_base__io_buffer__writer_slice(const wuffs_base__io_buffer* buf) {
2979   return buf ? wuffs_base__make_slice_u8(buf->data.ptr + buf->meta.wi,
2980                                          buf->data.len - buf->meta.wi)
2981              : wuffs_base__empty_slice_u8();
2982 }
2983 
2984 #ifdef __cplusplus
2985 
2986 inline bool  //
is_valid()2987 wuffs_base__io_buffer::is_valid() const {
2988   return wuffs_base__io_buffer__is_valid(this);
2989 }
2990 
2991 inline void  //
compact()2992 wuffs_base__io_buffer::compact() {
2993   wuffs_base__io_buffer__compact(this);
2994 }
2995 
2996 inline uint64_t  //
reader_io_position()2997 wuffs_base__io_buffer::reader_io_position() const {
2998   return wuffs_base__io_buffer__reader_io_position(this);
2999 }
3000 
3001 inline size_t  //
reader_length()3002 wuffs_base__io_buffer::reader_length() const {
3003   return wuffs_base__io_buffer__reader_length(this);
3004 }
3005 
3006 inline uint8_t*  //
reader_pointer()3007 wuffs_base__io_buffer::reader_pointer() const {
3008   return wuffs_base__io_buffer__reader_pointer(this);
3009 }
3010 
3011 inline uint64_t  //
reader_position()3012 wuffs_base__io_buffer::reader_position() const {
3013   return wuffs_base__io_buffer__reader_position(this);
3014 }
3015 
3016 inline wuffs_base__slice_u8  //
reader_slice()3017 wuffs_base__io_buffer::reader_slice() const {
3018   return wuffs_base__io_buffer__reader_slice(this);
3019 }
3020 
3021 inline uint64_t  //
writer_io_position()3022 wuffs_base__io_buffer::writer_io_position() const {
3023   return wuffs_base__io_buffer__writer_io_position(this);
3024 }
3025 
3026 inline size_t  //
writer_length()3027 wuffs_base__io_buffer::writer_length() const {
3028   return wuffs_base__io_buffer__writer_length(this);
3029 }
3030 
3031 inline uint8_t*  //
writer_pointer()3032 wuffs_base__io_buffer::writer_pointer() const {
3033   return wuffs_base__io_buffer__writer_pointer(this);
3034 }
3035 
3036 inline uint64_t  //
writer_position()3037 wuffs_base__io_buffer::writer_position() const {
3038   return wuffs_base__io_buffer__writer_position(this);
3039 }
3040 
3041 inline wuffs_base__slice_u8  //
writer_slice()3042 wuffs_base__io_buffer::writer_slice() const {
3043   return wuffs_base__io_buffer__writer_slice(this);
3044 }
3045 
3046 #endif  // __cplusplus
3047 
3048 // ---------------- Tokens
3049 
3050 // wuffs_base__token is an element of a byte stream's tokenization.
3051 //
3052 // See https://github.com/google/wuffs/blob/main/doc/note/tokens.md
3053 typedef struct wuffs_base__token__struct {
3054   uint64_t repr;
3055 
3056 #ifdef __cplusplus
3057   inline int64_t value() const;
3058   inline int64_t value_extension() const;
3059   inline int64_t value_major() const;
3060   inline int64_t value_base_category() const;
3061   inline uint64_t value_minor() const;
3062   inline uint64_t value_base_detail() const;
3063   inline int64_t value_base_detail__sign_extended() const;
3064   inline bool continued() const;
3065   inline uint64_t length() const;
3066 #endif  // __cplusplus
3067 
3068 } wuffs_base__token;
3069 
3070 static inline wuffs_base__token  //
wuffs_base__make_token(uint64_t repr)3071 wuffs_base__make_token(uint64_t repr) {
3072   wuffs_base__token ret;
3073   ret.repr = repr;
3074   return ret;
3075 }
3076 
3077 // --------
3078 
3079 #define WUFFS_BASE__TOKEN__LENGTH__MAX_INCL 0xFFFF
3080 
3081 #define WUFFS_BASE__TOKEN__VALUE__SHIFT 17
3082 #define WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT 17
3083 #define WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT 42
3084 #define WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT 17
3085 #define WUFFS_BASE__TOKEN__VALUE_BASE_CATEGORY__SHIFT 38
3086 #define WUFFS_BASE__TOKEN__VALUE_BASE_DETAIL__SHIFT 17
3087 #define WUFFS_BASE__TOKEN__CONTINUED__SHIFT 16
3088 #define WUFFS_BASE__TOKEN__LENGTH__SHIFT 0
3089 
3090 #define WUFFS_BASE__TOKEN__VALUE_EXTENSION__NUM_BITS 46
3091 
3092 // --------
3093 
3094 #define WUFFS_BASE__TOKEN__VBC__FILLER 0
3095 #define WUFFS_BASE__TOKEN__VBC__STRUCTURE 1
3096 #define WUFFS_BASE__TOKEN__VBC__STRING 2
3097 #define WUFFS_BASE__TOKEN__VBC__UNICODE_CODE_POINT 3
3098 #define WUFFS_BASE__TOKEN__VBC__LITERAL 4
3099 #define WUFFS_BASE__TOKEN__VBC__NUMBER 5
3100 #define WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_SIGNED 6
3101 #define WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_UNSIGNED 7
3102 
3103 // --------
3104 
3105 #define WUFFS_BASE__TOKEN__VBD__FILLER__PUNCTUATION 0x00001
3106 #define WUFFS_BASE__TOKEN__VBD__FILLER__COMMENT_BLOCK 0x00002
3107 #define WUFFS_BASE__TOKEN__VBD__FILLER__COMMENT_LINE 0x00004
3108 
3109 // COMMENT_ANY is a bit-wise or of COMMENT_BLOCK AND COMMENT_LINE.
3110 #define WUFFS_BASE__TOKEN__VBD__FILLER__COMMENT_ANY 0x00006
3111 
3112 // --------
3113 
3114 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH 0x00001
3115 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__POP 0x00002
3116 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_NONE 0x00010
3117 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_LIST 0x00020
3118 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_DICT 0x00040
3119 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_NONE 0x01000
3120 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_LIST 0x02000
3121 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_DICT 0x04000
3122 
3123 // --------
3124 
3125 // DEFINITELY_FOO means that the destination bytes (and also the source bytes,
3126 // for 1_DST_1_SRC_COPY) are in the FOO format. Definitely means that the lack
3127 // of the bit means "maybe FOO". It does not necessarily mean "not FOO".
3128 //
3129 // CHAIN_ETC means that decoding the entire token chain forms a UTF-8 or ASCII
3130 // string, not just this current token. CHAIN_ETC_UTF_8 therefore distinguishes
3131 // Unicode (UTF-8) strings from byte strings. MUST means that the the token
3132 // producer (e.g. parser) must verify this. SHOULD means that the token
3133 // consumer (e.g. renderer) should verify this.
3134 //
3135 // When a CHAIN_ETC_UTF_8 bit is set, the parser must ensure that non-ASCII
3136 // code points (with multi-byte UTF-8 encodings) do not straddle token
3137 // boundaries. Checking UTF-8 validity can inspect each token separately.
3138 //
3139 // The lack of any particular bit is conservative: it is valid for all-ASCII
3140 // strings, in a single- or multi-token chain, to have none of these bits set.
3141 #define WUFFS_BASE__TOKEN__VBD__STRING__DEFINITELY_UTF_8 0x00001
3142 #define WUFFS_BASE__TOKEN__VBD__STRING__CHAIN_MUST_BE_UTF_8 0x00002
3143 #define WUFFS_BASE__TOKEN__VBD__STRING__CHAIN_SHOULD_BE_UTF_8 0x00004
3144 #define WUFFS_BASE__TOKEN__VBD__STRING__DEFINITELY_ASCII 0x00010
3145 #define WUFFS_BASE__TOKEN__VBD__STRING__CHAIN_MUST_BE_ASCII 0x00020
3146 #define WUFFS_BASE__TOKEN__VBD__STRING__CHAIN_SHOULD_BE_ASCII 0x00040
3147 
3148 // CONVERT_D_DST_S_SRC means that multiples of S source bytes (possibly padded)
3149 // produces multiples of D destination bytes. For example,
3150 // CONVERT_1_DST_4_SRC_BACKSLASH_X means a source like "\\x23\\x67\\xAB", where
3151 // 12 src bytes encode 3 dst bytes.
3152 //
3153 // Post-processing may further transform those D destination bytes (e.g. treat
3154 // "\\xFF" as the Unicode code point U+00FF instead of the byte 0xFF), but that
3155 // is out of scope of this VBD's semantics.
3156 //
3157 // When src is the empty string, multiple conversion algorithms are applicable
3158 // (so these bits are not necessarily mutually exclusive), all producing the
3159 // same empty dst string.
3160 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_0_DST_1_SRC_DROP 0x00100
3161 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_1_SRC_COPY 0x00200
3162 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_2_SRC_HEXADECIMAL 0x00400
3163 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_4_SRC_BACKSLASH_X 0x00800
3164 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_3_DST_4_SRC_BASE_64_STD 0x01000
3165 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_3_DST_4_SRC_BASE_64_URL 0x02000
3166 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_4_DST_5_SRC_ASCII_85 0x04000
3167 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_5_DST_8_SRC_BASE_32_HEX 0x08000
3168 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_5_DST_8_SRC_BASE_32_STD 0x10000
3169 
3170 // --------
3171 
3172 #define WUFFS_BASE__TOKEN__VBD__LITERAL__UNDEFINED 0x00001
3173 #define WUFFS_BASE__TOKEN__VBD__LITERAL__NULL 0x00002
3174 #define WUFFS_BASE__TOKEN__VBD__LITERAL__FALSE 0x00004
3175 #define WUFFS_BASE__TOKEN__VBD__LITERAL__TRUE 0x00008
3176 
3177 // --------
3178 
3179 // For a source string of "123" or "0x9A", it is valid for a tokenizer to
3180 // return any combination of:
3181 //  - WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_FLOATING_POINT.
3182 //  - WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_SIGNED.
3183 //  - WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_UNSIGNED.
3184 //
3185 // For a source string of "+123" or "-0x9A", only the first two are valid.
3186 //
3187 // For a source string of "123.", only the first one is valid.
3188 #define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_FLOATING_POINT 0x00001
3189 #define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_SIGNED 0x00002
3190 #define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_UNSIGNED 0x00004
3191 
3192 #define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_NEG_INF 0x00010
3193 #define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_POS_INF 0x00020
3194 #define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_NEG_NAN 0x00040
3195 #define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_POS_NAN 0x00080
3196 
3197 // The number 300 might be represented as "\x01\x2C", "\x2C\x01\x00\x00" or
3198 // "300", which are big-endian, little-endian or text. For binary formats, the
3199 // token length (after adjusting for FORMAT_IGNORE_ETC) discriminates
3200 // e.g. u16 little-endian vs u32 little-endian.
3201 #define WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_BINARY_BIG_ENDIAN 0x00100
3202 #define WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_BINARY_LITTLE_ENDIAN 0x00200
3203 #define WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_TEXT 0x00400
3204 
3205 #define WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_IGNORE_FIRST_BYTE 0x01000
3206 
3207 // --------
3208 
3209 // wuffs_base__token__value returns the token's high 46 bits, sign-extended. A
3210 // negative value means an extended token, non-negative means a simple token.
3211 static inline int64_t  //
wuffs_base__token__value(const wuffs_base__token * t)3212 wuffs_base__token__value(const wuffs_base__token* t) {
3213   return ((int64_t)(t->repr)) >> WUFFS_BASE__TOKEN__VALUE__SHIFT;
3214 }
3215 
3216 // wuffs_base__token__value_extension returns a negative value if the token was
3217 // not an extended token.
3218 static inline int64_t  //
wuffs_base__token__value_extension(const wuffs_base__token * t)3219 wuffs_base__token__value_extension(const wuffs_base__token* t) {
3220   return (~(int64_t)(t->repr)) >> WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT;
3221 }
3222 
3223 // wuffs_base__token__value_major returns a negative value if the token was not
3224 // a simple token.
3225 static inline int64_t  //
wuffs_base__token__value_major(const wuffs_base__token * t)3226 wuffs_base__token__value_major(const wuffs_base__token* t) {
3227   return ((int64_t)(t->repr)) >> WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT;
3228 }
3229 
3230 // wuffs_base__token__value_base_category returns a negative value if the token
3231 // was not a simple token.
3232 static inline int64_t  //
wuffs_base__token__value_base_category(const wuffs_base__token * t)3233 wuffs_base__token__value_base_category(const wuffs_base__token* t) {
3234   return ((int64_t)(t->repr)) >> WUFFS_BASE__TOKEN__VALUE_BASE_CATEGORY__SHIFT;
3235 }
3236 
3237 static inline uint64_t  //
wuffs_base__token__value_minor(const wuffs_base__token * t)3238 wuffs_base__token__value_minor(const wuffs_base__token* t) {
3239   return (t->repr >> WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) & 0x1FFFFFF;
3240 }
3241 
3242 static inline uint64_t  //
wuffs_base__token__value_base_detail(const wuffs_base__token * t)3243 wuffs_base__token__value_base_detail(const wuffs_base__token* t) {
3244   return (t->repr >> WUFFS_BASE__TOKEN__VALUE_BASE_DETAIL__SHIFT) & 0x1FFFFF;
3245 }
3246 
3247 static inline int64_t  //
wuffs_base__token__value_base_detail__sign_extended(const wuffs_base__token * t)3248 wuffs_base__token__value_base_detail__sign_extended(
3249     const wuffs_base__token* t) {
3250   // The VBD is 21 bits in the middle of t->repr. Left shift the high (64 - 21
3251   // - ETC__SHIFT) bits off, then right shift (sign-extending) back down.
3252   uint64_t u = t->repr << (43 - WUFFS_BASE__TOKEN__VALUE_BASE_DETAIL__SHIFT);
3253   return ((int64_t)u) >> 43;
3254 }
3255 
3256 static inline bool  //
wuffs_base__token__continued(const wuffs_base__token * t)3257 wuffs_base__token__continued(const wuffs_base__token* t) {
3258   return t->repr & 0x10000;
3259 }
3260 
3261 static inline uint64_t  //
wuffs_base__token__length(const wuffs_base__token * t)3262 wuffs_base__token__length(const wuffs_base__token* t) {
3263   return (t->repr >> WUFFS_BASE__TOKEN__LENGTH__SHIFT) & 0xFFFF;
3264 }
3265 
3266 #ifdef __cplusplus
3267 
3268 inline int64_t  //
value()3269 wuffs_base__token::value() const {
3270   return wuffs_base__token__value(this);
3271 }
3272 
3273 inline int64_t  //
value_extension()3274 wuffs_base__token::value_extension() const {
3275   return wuffs_base__token__value_extension(this);
3276 }
3277 
3278 inline int64_t  //
value_major()3279 wuffs_base__token::value_major() const {
3280   return wuffs_base__token__value_major(this);
3281 }
3282 
3283 inline int64_t  //
value_base_category()3284 wuffs_base__token::value_base_category() const {
3285   return wuffs_base__token__value_base_category(this);
3286 }
3287 
3288 inline uint64_t  //
value_minor()3289 wuffs_base__token::value_minor() const {
3290   return wuffs_base__token__value_minor(this);
3291 }
3292 
3293 inline uint64_t  //
value_base_detail()3294 wuffs_base__token::value_base_detail() const {
3295   return wuffs_base__token__value_base_detail(this);
3296 }
3297 
3298 inline int64_t  //
value_base_detail__sign_extended()3299 wuffs_base__token::value_base_detail__sign_extended() const {
3300   return wuffs_base__token__value_base_detail__sign_extended(this);
3301 }
3302 
3303 inline bool  //
continued()3304 wuffs_base__token::continued() const {
3305   return wuffs_base__token__continued(this);
3306 }
3307 
3308 inline uint64_t  //
length()3309 wuffs_base__token::length() const {
3310   return wuffs_base__token__length(this);
3311 }
3312 
3313 #endif  // __cplusplus
3314 
3315 // --------
3316 
3317 typedef WUFFS_BASE__SLICE(wuffs_base__token) wuffs_base__slice_token;
3318 
3319 static inline wuffs_base__slice_token  //
wuffs_base__make_slice_token(wuffs_base__token * ptr,size_t len)3320 wuffs_base__make_slice_token(wuffs_base__token* ptr, size_t len) {
3321   wuffs_base__slice_token ret;
3322   ret.ptr = ptr;
3323   ret.len = len;
3324   return ret;
3325 }
3326 
3327 static inline wuffs_base__slice_token  //
wuffs_base__empty_slice_token()3328 wuffs_base__empty_slice_token() {
3329   wuffs_base__slice_token ret;
3330   ret.ptr = NULL;
3331   ret.len = 0;
3332   return ret;
3333 }
3334 
3335 // --------
3336 
3337 // wuffs_base__token_buffer_meta is the metadata for a
3338 // wuffs_base__token_buffer's data.
3339 typedef struct wuffs_base__token_buffer_meta__struct {
3340   size_t wi;     // Write index. Invariant: wi <= len.
3341   size_t ri;     // Read  index. Invariant: ri <= wi.
3342   uint64_t pos;  // Position of the buffer start relative to the stream start.
3343   bool closed;   // No further writes are expected.
3344 } wuffs_base__token_buffer_meta;
3345 
3346 // wuffs_base__token_buffer is a 1-dimensional buffer (a pointer and length)
3347 // plus additional metadata.
3348 //
3349 // A value with all fields zero is a valid, empty buffer.
3350 typedef struct wuffs_base__token_buffer__struct {
3351   wuffs_base__slice_token data;
3352   wuffs_base__token_buffer_meta meta;
3353 
3354 #ifdef __cplusplus
3355   inline bool is_valid() const;
3356   inline void compact();
3357   inline uint64_t reader_length() const;
3358   inline wuffs_base__token* reader_pointer() const;
3359   inline wuffs_base__slice_token reader_slice() const;
3360   inline uint64_t reader_token_position() const;
3361   inline uint64_t writer_length() const;
3362   inline uint64_t writer_token_position() const;
3363   inline wuffs_base__token* writer_pointer() const;
3364   inline wuffs_base__slice_token writer_slice() const;
3365 #endif  // __cplusplus
3366 
3367 } wuffs_base__token_buffer;
3368 
3369 static inline wuffs_base__token_buffer  //
wuffs_base__make_token_buffer(wuffs_base__slice_token data,wuffs_base__token_buffer_meta meta)3370 wuffs_base__make_token_buffer(wuffs_base__slice_token data,
3371                               wuffs_base__token_buffer_meta meta) {
3372   wuffs_base__token_buffer ret;
3373   ret.data = data;
3374   ret.meta = meta;
3375   return ret;
3376 }
3377 
3378 static inline wuffs_base__token_buffer_meta  //
wuffs_base__make_token_buffer_meta(size_t wi,size_t ri,uint64_t pos,bool closed)3379 wuffs_base__make_token_buffer_meta(size_t wi,
3380                                    size_t ri,
3381                                    uint64_t pos,
3382                                    bool closed) {
3383   wuffs_base__token_buffer_meta ret;
3384   ret.wi = wi;
3385   ret.ri = ri;
3386   ret.pos = pos;
3387   ret.closed = closed;
3388   return ret;
3389 }
3390 
3391 static inline wuffs_base__token_buffer  //
wuffs_base__slice_token__reader(wuffs_base__slice_token s,bool closed)3392 wuffs_base__slice_token__reader(wuffs_base__slice_token s, bool closed) {
3393   wuffs_base__token_buffer ret;
3394   ret.data.ptr = s.ptr;
3395   ret.data.len = s.len;
3396   ret.meta.wi = s.len;
3397   ret.meta.ri = 0;
3398   ret.meta.pos = 0;
3399   ret.meta.closed = closed;
3400   return ret;
3401 }
3402 
3403 static inline wuffs_base__token_buffer  //
wuffs_base__slice_token__writer(wuffs_base__slice_token s)3404 wuffs_base__slice_token__writer(wuffs_base__slice_token s) {
3405   wuffs_base__token_buffer ret;
3406   ret.data.ptr = s.ptr;
3407   ret.data.len = s.len;
3408   ret.meta.wi = 0;
3409   ret.meta.ri = 0;
3410   ret.meta.pos = 0;
3411   ret.meta.closed = false;
3412   return ret;
3413 }
3414 
3415 static inline wuffs_base__token_buffer  //
wuffs_base__empty_token_buffer()3416 wuffs_base__empty_token_buffer() {
3417   wuffs_base__token_buffer ret;
3418   ret.data.ptr = NULL;
3419   ret.data.len = 0;
3420   ret.meta.wi = 0;
3421   ret.meta.ri = 0;
3422   ret.meta.pos = 0;
3423   ret.meta.closed = false;
3424   return ret;
3425 }
3426 
3427 static inline wuffs_base__token_buffer_meta  //
wuffs_base__empty_token_buffer_meta()3428 wuffs_base__empty_token_buffer_meta() {
3429   wuffs_base__token_buffer_meta ret;
3430   ret.wi = 0;
3431   ret.ri = 0;
3432   ret.pos = 0;
3433   ret.closed = false;
3434   return ret;
3435 }
3436 
3437 static inline bool  //
wuffs_base__token_buffer__is_valid(const wuffs_base__token_buffer * buf)3438 wuffs_base__token_buffer__is_valid(const wuffs_base__token_buffer* buf) {
3439   if (buf) {
3440     if (buf->data.ptr) {
3441       return (buf->meta.ri <= buf->meta.wi) && (buf->meta.wi <= buf->data.len);
3442     } else {
3443       return (buf->meta.ri == 0) && (buf->meta.wi == 0) && (buf->data.len == 0);
3444     }
3445   }
3446   return false;
3447 }
3448 
3449 // wuffs_base__token_buffer__compact moves any written but unread tokens to the
3450 // start of the buffer.
3451 static inline void  //
wuffs_base__token_buffer__compact(wuffs_base__token_buffer * buf)3452 wuffs_base__token_buffer__compact(wuffs_base__token_buffer* buf) {
3453   if (!buf || (buf->meta.ri == 0)) {
3454     return;
3455   }
3456   buf->meta.pos = wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.ri);
3457   size_t n = buf->meta.wi - buf->meta.ri;
3458   if (n != 0) {
3459     memmove(buf->data.ptr, buf->data.ptr + buf->meta.ri,
3460             n * sizeof(wuffs_base__token));
3461   }
3462   buf->meta.wi = n;
3463   buf->meta.ri = 0;
3464 }
3465 
3466 static inline uint64_t  //
wuffs_base__token_buffer__reader_length(const wuffs_base__token_buffer * buf)3467 wuffs_base__token_buffer__reader_length(const wuffs_base__token_buffer* buf) {
3468   return buf ? buf->meta.wi - buf->meta.ri : 0;
3469 }
3470 
3471 static inline wuffs_base__token*  //
wuffs_base__token_buffer__reader_pointer(const wuffs_base__token_buffer * buf)3472 wuffs_base__token_buffer__reader_pointer(const wuffs_base__token_buffer* buf) {
3473   return buf ? (buf->data.ptr + buf->meta.ri) : NULL;
3474 }
3475 
3476 static inline wuffs_base__slice_token  //
wuffs_base__token_buffer__reader_slice(const wuffs_base__token_buffer * buf)3477 wuffs_base__token_buffer__reader_slice(const wuffs_base__token_buffer* buf) {
3478   return buf ? wuffs_base__make_slice_token(buf->data.ptr + buf->meta.ri,
3479                                             buf->meta.wi - buf->meta.ri)
3480              : wuffs_base__empty_slice_token();
3481 }
3482 
3483 static inline uint64_t  //
wuffs_base__token_buffer__reader_token_position(const wuffs_base__token_buffer * buf)3484 wuffs_base__token_buffer__reader_token_position(
3485     const wuffs_base__token_buffer* buf) {
3486   return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.ri) : 0;
3487 }
3488 
3489 static inline uint64_t  //
wuffs_base__token_buffer__writer_length(const wuffs_base__token_buffer * buf)3490 wuffs_base__token_buffer__writer_length(const wuffs_base__token_buffer* buf) {
3491   return buf ? buf->data.len - buf->meta.wi : 0;
3492 }
3493 
3494 static inline wuffs_base__token*  //
wuffs_base__token_buffer__writer_pointer(const wuffs_base__token_buffer * buf)3495 wuffs_base__token_buffer__writer_pointer(const wuffs_base__token_buffer* buf) {
3496   return buf ? (buf->data.ptr + buf->meta.wi) : NULL;
3497 }
3498 
3499 static inline wuffs_base__slice_token  //
wuffs_base__token_buffer__writer_slice(const wuffs_base__token_buffer * buf)3500 wuffs_base__token_buffer__writer_slice(const wuffs_base__token_buffer* buf) {
3501   return buf ? wuffs_base__make_slice_token(buf->data.ptr + buf->meta.wi,
3502                                             buf->data.len - buf->meta.wi)
3503              : wuffs_base__empty_slice_token();
3504 }
3505 
3506 static inline uint64_t  //
wuffs_base__token_buffer__writer_token_position(const wuffs_base__token_buffer * buf)3507 wuffs_base__token_buffer__writer_token_position(
3508     const wuffs_base__token_buffer* buf) {
3509   return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.wi) : 0;
3510 }
3511 
3512 #ifdef __cplusplus
3513 
3514 inline bool  //
is_valid()3515 wuffs_base__token_buffer::is_valid() const {
3516   return wuffs_base__token_buffer__is_valid(this);
3517 }
3518 
3519 inline void  //
compact()3520 wuffs_base__token_buffer::compact() {
3521   wuffs_base__token_buffer__compact(this);
3522 }
3523 
3524 inline uint64_t  //
reader_length()3525 wuffs_base__token_buffer::reader_length() const {
3526   return wuffs_base__token_buffer__reader_length(this);
3527 }
3528 
3529 inline wuffs_base__token*  //
reader_pointer()3530 wuffs_base__token_buffer::reader_pointer() const {
3531   return wuffs_base__token_buffer__reader_pointer(this);
3532 }
3533 
3534 inline wuffs_base__slice_token  //
reader_slice()3535 wuffs_base__token_buffer::reader_slice() const {
3536   return wuffs_base__token_buffer__reader_slice(this);
3537 }
3538 
3539 inline uint64_t  //
reader_token_position()3540 wuffs_base__token_buffer::reader_token_position() const {
3541   return wuffs_base__token_buffer__reader_token_position(this);
3542 }
3543 
3544 inline uint64_t  //
writer_length()3545 wuffs_base__token_buffer::writer_length() const {
3546   return wuffs_base__token_buffer__writer_length(this);
3547 }
3548 
3549 inline wuffs_base__token*  //
writer_pointer()3550 wuffs_base__token_buffer::writer_pointer() const {
3551   return wuffs_base__token_buffer__writer_pointer(this);
3552 }
3553 
3554 inline wuffs_base__slice_token  //
writer_slice()3555 wuffs_base__token_buffer::writer_slice() const {
3556   return wuffs_base__token_buffer__writer_slice(this);
3557 }
3558 
3559 inline uint64_t  //
writer_token_position()3560 wuffs_base__token_buffer::writer_token_position() const {
3561   return wuffs_base__token_buffer__writer_token_position(this);
3562 }
3563 
3564 #endif  // __cplusplus
3565 
3566 // ---------------- Memory Allocation
3567 
3568 // The memory allocation related functions in this section aren't used by Wuffs
3569 // per se, but they may be helpful to the code that uses Wuffs.
3570 
3571 // wuffs_base__malloc_slice_uxx wraps calling a malloc-like function, except
3572 // that it takes a uint64_t number of elements instead of a size_t size in
3573 // bytes, and it returns a slice (a pointer and a length) instead of just a
3574 // pointer.
3575 //
3576 // You can pass the C stdlib's malloc as the malloc_func.
3577 //
3578 // It returns an empty slice (containing a NULL ptr field) if (num_uxx *
3579 // sizeof(uintxx_t)) would overflow SIZE_MAX.
3580 
3581 static inline wuffs_base__slice_u8  //
wuffs_base__malloc_slice_u8(void * (* malloc_func)(size_t),uint64_t num_u8)3582 wuffs_base__malloc_slice_u8(void* (*malloc_func)(size_t), uint64_t num_u8) {
3583   if (malloc_func && (num_u8 <= (SIZE_MAX / sizeof(uint8_t)))) {
3584     void* p = (*malloc_func)((size_t)(num_u8 * sizeof(uint8_t)));
3585     if (p) {
3586       return wuffs_base__make_slice_u8((uint8_t*)(p), (size_t)num_u8);
3587     }
3588   }
3589   return wuffs_base__make_slice_u8(NULL, 0);
3590 }
3591 
3592 static inline wuffs_base__slice_u16  //
wuffs_base__malloc_slice_u16(void * (* malloc_func)(size_t),uint64_t num_u16)3593 wuffs_base__malloc_slice_u16(void* (*malloc_func)(size_t), uint64_t num_u16) {
3594   if (malloc_func && (num_u16 <= (SIZE_MAX / sizeof(uint16_t)))) {
3595     void* p = (*malloc_func)((size_t)(num_u16 * sizeof(uint16_t)));
3596     if (p) {
3597       return wuffs_base__make_slice_u16((uint16_t*)(p), (size_t)num_u16);
3598     }
3599   }
3600   return wuffs_base__make_slice_u16(NULL, 0);
3601 }
3602 
3603 static inline wuffs_base__slice_u32  //
wuffs_base__malloc_slice_u32(void * (* malloc_func)(size_t),uint64_t num_u32)3604 wuffs_base__malloc_slice_u32(void* (*malloc_func)(size_t), uint64_t num_u32) {
3605   if (malloc_func && (num_u32 <= (SIZE_MAX / sizeof(uint32_t)))) {
3606     void* p = (*malloc_func)((size_t)(num_u32 * sizeof(uint32_t)));
3607     if (p) {
3608       return wuffs_base__make_slice_u32((uint32_t*)(p), (size_t)num_u32);
3609     }
3610   }
3611   return wuffs_base__make_slice_u32(NULL, 0);
3612 }
3613 
3614 static inline wuffs_base__slice_u64  //
wuffs_base__malloc_slice_u64(void * (* malloc_func)(size_t),uint64_t num_u64)3615 wuffs_base__malloc_slice_u64(void* (*malloc_func)(size_t), uint64_t num_u64) {
3616   if (malloc_func && (num_u64 <= (SIZE_MAX / sizeof(uint64_t)))) {
3617     void* p = (*malloc_func)((size_t)(num_u64 * sizeof(uint64_t)));
3618     if (p) {
3619       return wuffs_base__make_slice_u64((uint64_t*)(p), (size_t)num_u64);
3620     }
3621   }
3622   return wuffs_base__make_slice_u64(NULL, 0);
3623 }
3624 
3625 // ---------------- Images
3626 
3627 // wuffs_base__color_u32_argb_premul is an 8 bit per channel premultiplied
3628 // Alpha, Red, Green, Blue color, as a uint32_t value. Its value is always
3629 // 0xAARRGGBB (Alpha most significant, Blue least), regardless of endianness.
3630 typedef uint32_t wuffs_base__color_u32_argb_premul;
3631 
3632 // wuffs_base__color_u32_argb_premul__is_valid returns whether c's Red, Green
3633 // and Blue channels are all less than or equal to its Alpha channel. c uses
3634 // premultiplied alpha, so 50% opaque 100% saturated red is 0x7F7F_0000 and a
3635 // value like 0x7F80_0000 is invalid.
3636 static inline bool  //
wuffs_base__color_u32_argb_premul__is_valid(wuffs_base__color_u32_argb_premul c)3637 wuffs_base__color_u32_argb_premul__is_valid(
3638     wuffs_base__color_u32_argb_premul c) {
3639   uint32_t a = 0xFF & (c >> 24);
3640   uint32_t r = 0xFF & (c >> 16);
3641   uint32_t g = 0xFF & (c >> 8);
3642   uint32_t b = 0xFF & (c >> 0);
3643   return (a >= r) && (a >= g) && (a >= b);
3644 }
3645 
3646 static inline uint16_t  //
wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(wuffs_base__color_u32_argb_premul c)3647 wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
3648     wuffs_base__color_u32_argb_premul c) {
3649   uint32_t r5 = 0xF800 & (c >> 8);
3650   uint32_t g6 = 0x07E0 & (c >> 5);
3651   uint32_t b5 = 0x001F & (c >> 3);
3652   return (uint16_t)(r5 | g6 | b5);
3653 }
3654 
3655 static inline wuffs_base__color_u32_argb_premul  //
wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(uint16_t rgb_565)3656 wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(uint16_t rgb_565) {
3657   uint32_t b5 = 0x1F & (rgb_565 >> 0);
3658   uint32_t b = (b5 << 3) | (b5 >> 2);
3659   uint32_t g6 = 0x3F & (rgb_565 >> 5);
3660   uint32_t g = (g6 << 2) | (g6 >> 4);
3661   uint32_t r5 = 0x1F & (rgb_565 >> 11);
3662   uint32_t r = (r5 << 3) | (r5 >> 2);
3663   return 0xFF000000 | (r << 16) | (g << 8) | (b << 0);
3664 }
3665 
3666 static inline uint8_t  //
wuffs_base__color_u32_argb_premul__as__color_u8_gray(wuffs_base__color_u32_argb_premul c)3667 wuffs_base__color_u32_argb_premul__as__color_u8_gray(
3668     wuffs_base__color_u32_argb_premul c) {
3669   // Work in 16-bit color.
3670   uint32_t cr = 0x101 * (0xFF & (c >> 16));
3671   uint32_t cg = 0x101 * (0xFF & (c >> 8));
3672   uint32_t cb = 0x101 * (0xFF & (c >> 0));
3673 
3674   // These coefficients (the fractions 0.299, 0.587 and 0.114) are the same
3675   // as those given by the JFIF specification.
3676   //
3677   // Note that 19595 + 38470 + 7471 equals 65536, also known as (1 << 16). We
3678   // shift by 24, not just by 16, because the return value is 8-bit color, not
3679   // 16-bit color.
3680   uint32_t weighted_average = (19595 * cr) + (38470 * cg) + (7471 * cb) + 32768;
3681   return (uint8_t)(weighted_average >> 24);
3682 }
3683 
3684 static inline uint16_t  //
wuffs_base__color_u32_argb_premul__as__color_u16_gray(wuffs_base__color_u32_argb_premul c)3685 wuffs_base__color_u32_argb_premul__as__color_u16_gray(
3686     wuffs_base__color_u32_argb_premul c) {
3687   // Work in 16-bit color.
3688   uint32_t cr = 0x101 * (0xFF & (c >> 16));
3689   uint32_t cg = 0x101 * (0xFF & (c >> 8));
3690   uint32_t cb = 0x101 * (0xFF & (c >> 0));
3691 
3692   // These coefficients (the fractions 0.299, 0.587 and 0.114) are the same
3693   // as those given by the JFIF specification.
3694   //
3695   // Note that 19595 + 38470 + 7471 equals 65536, also known as (1 << 16).
3696   uint32_t weighted_average = (19595 * cr) + (38470 * cg) + (7471 * cb) + 32768;
3697   return (uint16_t)(weighted_average >> 16);
3698 }
3699 
3700 // wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul converts
3701 // from non-premultiplied alpha to premultiplied alpha.
3702 static inline wuffs_base__color_u32_argb_premul  //
wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(uint32_t argb_nonpremul)3703 wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
3704     uint32_t argb_nonpremul) {
3705   // Multiplying by 0x101 (twice, once for alpha and once for color) converts
3706   // from 8-bit to 16-bit color. Shifting right by 8 undoes that.
3707   //
3708   // Working in the higher bit depth can produce slightly different (and
3709   // arguably slightly more accurate) results. For example, given 8-bit blue
3710   // and alpha of 0x80 and 0x81:
3711   //
3712   //  - ((0x80   * 0x81  ) / 0xFF  )      = 0x40        = 0x40
3713   //  - ((0x8080 * 0x8181) / 0xFFFF) >> 8 = 0x4101 >> 8 = 0x41
3714   uint32_t a = 0xFF & (argb_nonpremul >> 24);
3715   uint32_t a16 = a * (0x101 * 0x101);
3716 
3717   uint32_t r = 0xFF & (argb_nonpremul >> 16);
3718   r = ((r * a16) / 0xFFFF) >> 8;
3719   uint32_t g = 0xFF & (argb_nonpremul >> 8);
3720   g = ((g * a16) / 0xFFFF) >> 8;
3721   uint32_t b = 0xFF & (argb_nonpremul >> 0);
3722   b = ((b * a16) / 0xFFFF) >> 8;
3723 
3724   return (a << 24) | (r << 16) | (g << 8) | (b << 0);
3725 }
3726 
3727 // wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul converts
3728 // from premultiplied alpha to non-premultiplied alpha.
3729 static inline uint32_t  //
wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(wuffs_base__color_u32_argb_premul c)3730 wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
3731     wuffs_base__color_u32_argb_premul c) {
3732   uint32_t a = 0xFF & (c >> 24);
3733   if (a == 0xFF) {
3734     return c;
3735   } else if (a == 0) {
3736     return 0;
3737   }
3738   uint32_t a16 = a * 0x101;
3739 
3740   uint32_t r = 0xFF & (c >> 16);
3741   r = ((r * (0x101 * 0xFFFF)) / a16) >> 8;
3742   uint32_t g = 0xFF & (c >> 8);
3743   g = ((g * (0x101 * 0xFFFF)) / a16) >> 8;
3744   uint32_t b = 0xFF & (c >> 0);
3745   b = ((b * (0x101 * 0xFFFF)) / a16) >> 8;
3746 
3747   return (a << 24) | (r << 16) | (g << 8) | (b << 0);
3748 }
3749 
3750 // wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul converts
3751 // from 4x16LE non-premultiplied alpha to 4x8 premultiplied alpha.
3752 static inline wuffs_base__color_u32_argb_premul  //
wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(uint64_t argb_nonpremul)3753 wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(
3754     uint64_t argb_nonpremul) {
3755   uint32_t a16 = ((uint32_t)(0xFFFF & (argb_nonpremul >> 48)));
3756 
3757   uint32_t r16 = ((uint32_t)(0xFFFF & (argb_nonpremul >> 32)));
3758   r16 = (r16 * a16) / 0xFFFF;
3759   uint32_t g16 = ((uint32_t)(0xFFFF & (argb_nonpremul >> 16)));
3760   g16 = (g16 * a16) / 0xFFFF;
3761   uint32_t b16 = ((uint32_t)(0xFFFF & (argb_nonpremul >> 0)));
3762   b16 = (b16 * a16) / 0xFFFF;
3763 
3764   return ((a16 >> 8) << 24) | ((r16 >> 8) << 16) | ((g16 >> 8) << 8) |
3765          ((b16 >> 8) << 0);
3766 }
3767 
3768 // wuffs_base__color_u32_argb_premul__as__color_u64_argb_nonpremul converts
3769 // from 4x8 premultiplied alpha to 4x16LE non-premultiplied alpha.
3770 static inline uint64_t  //
wuffs_base__color_u32_argb_premul__as__color_u64_argb_nonpremul(wuffs_base__color_u32_argb_premul c)3771 wuffs_base__color_u32_argb_premul__as__color_u64_argb_nonpremul(
3772     wuffs_base__color_u32_argb_premul c) {
3773   uint32_t a = 0xFF & (c >> 24);
3774   if (a == 0xFF) {
3775     uint64_t r16 = 0x101 * (0xFF & (c >> 16));
3776     uint64_t g16 = 0x101 * (0xFF & (c >> 8));
3777     uint64_t b16 = 0x101 * (0xFF & (c >> 0));
3778     return 0xFFFF000000000000u | (r16 << 32) | (g16 << 16) | (b16 << 0);
3779   } else if (a == 0) {
3780     return 0;
3781   }
3782   uint64_t a16 = a * 0x101;
3783 
3784   uint64_t r = 0xFF & (c >> 16);
3785   uint64_t r16 = (r * (0x101 * 0xFFFF)) / a16;
3786   uint64_t g = 0xFF & (c >> 8);
3787   uint64_t g16 = (g * (0x101 * 0xFFFF)) / a16;
3788   uint64_t b = 0xFF & (c >> 0);
3789   uint64_t b16 = (b * (0x101 * 0xFFFF)) / a16;
3790 
3791   return (a16 << 48) | (r16 << 32) | (g16 << 16) | (b16 << 0);
3792 }
3793 
3794 static inline uint64_t  //
wuffs_base__color_u32__as__color_u64(uint32_t c)3795 wuffs_base__color_u32__as__color_u64(uint32_t c) {
3796   uint64_t a16 = 0x101 * (0xFF & (c >> 24));
3797   uint64_t r16 = 0x101 * (0xFF & (c >> 16));
3798   uint64_t g16 = 0x101 * (0xFF & (c >> 8));
3799   uint64_t b16 = 0x101 * (0xFF & (c >> 0));
3800   return (a16 << 48) | (r16 << 32) | (g16 << 16) | (b16 << 0);
3801 }
3802 
3803 static inline uint32_t  //
wuffs_base__color_u64__as__color_u32(uint64_t c)3804 wuffs_base__color_u64__as__color_u32(uint64_t c) {
3805   uint32_t a = ((uint32_t)(0xFF & (c >> 56)));
3806   uint32_t r = ((uint32_t)(0xFF & (c >> 40)));
3807   uint32_t g = ((uint32_t)(0xFF & (c >> 24)));
3808   uint32_t b = ((uint32_t)(0xFF & (c >> 8)));
3809   return (a << 24) | (r << 16) | (g << 8) | (b << 0);
3810 }
3811 
3812 // --------
3813 
3814 typedef uint8_t wuffs_base__pixel_blend;
3815 
3816 // wuffs_base__pixel_blend encodes how to blend source and destination pixels,
3817 // accounting for transparency. It encompasses the Porter-Duff compositing
3818 // operators as well as the other blending modes defined by PDF.
3819 //
3820 // TODO: implement the other modes.
3821 #define WUFFS_BASE__PIXEL_BLEND__SRC ((wuffs_base__pixel_blend)0)
3822 #define WUFFS_BASE__PIXEL_BLEND__SRC_OVER ((wuffs_base__pixel_blend)1)
3823 
3824 // --------
3825 
3826 // wuffs_base__pixel_alpha_transparency is a pixel format's alpha channel
3827 // model. It is a property of the pixel format in general, not of a specific
3828 // pixel. An RGBA pixel format (with alpha) can still have fully opaque pixels.
3829 typedef uint32_t wuffs_base__pixel_alpha_transparency;
3830 
3831 #define WUFFS_BASE__PIXEL_ALPHA_TRANSPARENCY__OPAQUE 0
3832 #define WUFFS_BASE__PIXEL_ALPHA_TRANSPARENCY__NONPREMULTIPLIED_ALPHA 1
3833 #define WUFFS_BASE__PIXEL_ALPHA_TRANSPARENCY__PREMULTIPLIED_ALPHA 2
3834 #define WUFFS_BASE__PIXEL_ALPHA_TRANSPARENCY__BINARY_ALPHA 3
3835 
3836 // Deprecated: use WUFFS_BASE__PIXEL_ALPHA_TRANSPARENCY__NONPREMULTIPLIED_ALPHA
3837 // instead.
3838 #define WUFFS_BASE__PIXEL_ALPHA_TRANSPARENCY__NON_PREMULTIPLIED_ALPHA 1
3839 
3840 // --------
3841 
3842 #define WUFFS_BASE__PIXEL_FORMAT__NUM_PLANES_MAX 4
3843 
3844 #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__INDEX_PLANE 0
3845 #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE 3
3846 
3847 // A palette is 256 entries × 4 bytes per entry (e.g. BGRA).
3848 #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH 1024
3849 
3850 // wuffs_base__pixel_format encodes the format of the bytes that constitute an
3851 // image frame's pixel data.
3852 //
3853 // See https://github.com/google/wuffs/blob/main/doc/note/pixel-formats.md
3854 //
3855 // Do not manipulate its bits directly; they are private implementation
3856 // details. Use methods such as wuffs_base__pixel_format__num_planes instead.
3857 typedef struct wuffs_base__pixel_format__struct {
3858   uint32_t repr;
3859 
3860 #ifdef __cplusplus
3861   inline bool is_valid() const;
3862   inline uint32_t bits_per_pixel() const;
3863   inline bool is_direct() const;
3864   inline bool is_indexed() const;
3865   inline bool is_interleaved() const;
3866   inline bool is_planar() const;
3867   inline uint32_t num_planes() const;
3868   inline wuffs_base__pixel_alpha_transparency transparency() const;
3869 #endif  // __cplusplus
3870 
3871 } wuffs_base__pixel_format;
3872 
3873 static inline wuffs_base__pixel_format  //
wuffs_base__make_pixel_format(uint32_t repr)3874 wuffs_base__make_pixel_format(uint32_t repr) {
3875   wuffs_base__pixel_format f;
3876   f.repr = repr;
3877   return f;
3878 }
3879 
3880 // Common 8-bit-depth pixel formats. This list is not exhaustive; not all valid
3881 // wuffs_base__pixel_format values are present.
3882 
3883 #define WUFFS_BASE__PIXEL_FORMAT__INVALID 0x00000000
3884 
3885 #define WUFFS_BASE__PIXEL_FORMAT__A 0x02000008
3886 
3887 #define WUFFS_BASE__PIXEL_FORMAT__Y 0x20000008
3888 #define WUFFS_BASE__PIXEL_FORMAT__Y_16LE 0x2000000B
3889 #define WUFFS_BASE__PIXEL_FORMAT__Y_16BE 0x2010000B
3890 #define WUFFS_BASE__PIXEL_FORMAT__YA_NONPREMUL 0x21000008
3891 #define WUFFS_BASE__PIXEL_FORMAT__YA_PREMUL 0x22000008
3892 
3893 #define WUFFS_BASE__PIXEL_FORMAT__YCBCR 0x40020888
3894 #define WUFFS_BASE__PIXEL_FORMAT__YCBCRA_NONPREMUL 0x41038888
3895 #define WUFFS_BASE__PIXEL_FORMAT__YCBCRK 0x50038888
3896 
3897 #define WUFFS_BASE__PIXEL_FORMAT__YCOCG 0x60020888
3898 #define WUFFS_BASE__PIXEL_FORMAT__YCOCGA_NONPREMUL 0x61038888
3899 #define WUFFS_BASE__PIXEL_FORMAT__YCOCGK 0x70038888
3900 
3901 #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL 0x81040008
3902 #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL 0x82040008
3903 #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY 0x83040008
3904 
3905 #define WUFFS_BASE__PIXEL_FORMAT__BGR_565 0x80000565
3906 #define WUFFS_BASE__PIXEL_FORMAT__BGR 0x80000888
3907 #define WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL 0x81008888
3908 #define WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE 0x8100BBBB
3909 #define WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL 0x82008888
3910 #define WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE 0x8200BBBB
3911 #define WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY 0x83008888
3912 #define WUFFS_BASE__PIXEL_FORMAT__BGRX 0x90008888
3913 
3914 #define WUFFS_BASE__PIXEL_FORMAT__RGB 0xA0000888
3915 #define WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL 0xA1008888
3916 #define WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL_4X16LE 0xA100BBBB
3917 #define WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL 0xA2008888
3918 #define WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL_4X16LE 0xA200BBBB
3919 #define WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY 0xA3008888
3920 #define WUFFS_BASE__PIXEL_FORMAT__RGBX 0xB0008888
3921 
3922 #define WUFFS_BASE__PIXEL_FORMAT__CMY 0xC0020888
3923 #define WUFFS_BASE__PIXEL_FORMAT__CMYK 0xD0038888
3924 
3925 extern const uint32_t wuffs_base__pixel_format__bits_per_channel[16];
3926 
3927 static inline bool  //
wuffs_base__pixel_format__is_valid(const wuffs_base__pixel_format * f)3928 wuffs_base__pixel_format__is_valid(const wuffs_base__pixel_format* f) {
3929   return f->repr != 0;
3930 }
3931 
3932 // wuffs_base__pixel_format__bits_per_pixel returns the number of bits per
3933 // pixel for interleaved pixel formats, and returns 0 for planar pixel formats.
3934 static inline uint32_t  //
wuffs_base__pixel_format__bits_per_pixel(const wuffs_base__pixel_format * f)3935 wuffs_base__pixel_format__bits_per_pixel(const wuffs_base__pixel_format* f) {
3936   if (((f->repr >> 16) & 0x03) != 0) {
3937     return 0;
3938   }
3939   return wuffs_base__pixel_format__bits_per_channel[0x0F & (f->repr >> 0)] +
3940          wuffs_base__pixel_format__bits_per_channel[0x0F & (f->repr >> 4)] +
3941          wuffs_base__pixel_format__bits_per_channel[0x0F & (f->repr >> 8)] +
3942          wuffs_base__pixel_format__bits_per_channel[0x0F & (f->repr >> 12)];
3943 }
3944 
3945 static inline bool  //
wuffs_base__pixel_format__is_direct(const wuffs_base__pixel_format * f)3946 wuffs_base__pixel_format__is_direct(const wuffs_base__pixel_format* f) {
3947   return ((f->repr >> 18) & 0x01) == 0;
3948 }
3949 
3950 static inline bool  //
wuffs_base__pixel_format__is_indexed(const wuffs_base__pixel_format * f)3951 wuffs_base__pixel_format__is_indexed(const wuffs_base__pixel_format* f) {
3952   return ((f->repr >> 18) & 0x01) != 0;
3953 }
3954 
3955 static inline bool  //
wuffs_base__pixel_format__is_interleaved(const wuffs_base__pixel_format * f)3956 wuffs_base__pixel_format__is_interleaved(const wuffs_base__pixel_format* f) {
3957   return ((f->repr >> 16) & 0x03) == 0;
3958 }
3959 
3960 static inline bool  //
wuffs_base__pixel_format__is_planar(const wuffs_base__pixel_format * f)3961 wuffs_base__pixel_format__is_planar(const wuffs_base__pixel_format* f) {
3962   return ((f->repr >> 16) & 0x03) != 0;
3963 }
3964 
3965 static inline uint32_t  //
wuffs_base__pixel_format__num_planes(const wuffs_base__pixel_format * f)3966 wuffs_base__pixel_format__num_planes(const wuffs_base__pixel_format* f) {
3967   return ((f->repr >> 16) & 0x03) + 1;
3968 }
3969 
3970 static inline wuffs_base__pixel_alpha_transparency  //
wuffs_base__pixel_format__transparency(const wuffs_base__pixel_format * f)3971 wuffs_base__pixel_format__transparency(const wuffs_base__pixel_format* f) {
3972   return (wuffs_base__pixel_alpha_transparency)((f->repr >> 24) & 0x03);
3973 }
3974 
3975 #ifdef __cplusplus
3976 
3977 inline bool  //
is_valid()3978 wuffs_base__pixel_format::is_valid() const {
3979   return wuffs_base__pixel_format__is_valid(this);
3980 }
3981 
3982 inline uint32_t  //
bits_per_pixel()3983 wuffs_base__pixel_format::bits_per_pixel() const {
3984   return wuffs_base__pixel_format__bits_per_pixel(this);
3985 }
3986 
3987 inline bool  //
is_direct()3988 wuffs_base__pixel_format::is_direct() const {
3989   return wuffs_base__pixel_format__is_direct(this);
3990 }
3991 
3992 inline bool  //
is_indexed()3993 wuffs_base__pixel_format::is_indexed() const {
3994   return wuffs_base__pixel_format__is_indexed(this);
3995 }
3996 
3997 inline bool  //
is_interleaved()3998 wuffs_base__pixel_format::is_interleaved() const {
3999   return wuffs_base__pixel_format__is_interleaved(this);
4000 }
4001 
4002 inline bool  //
is_planar()4003 wuffs_base__pixel_format::is_planar() const {
4004   return wuffs_base__pixel_format__is_planar(this);
4005 }
4006 
4007 inline uint32_t  //
num_planes()4008 wuffs_base__pixel_format::num_planes() const {
4009   return wuffs_base__pixel_format__num_planes(this);
4010 }
4011 
4012 inline wuffs_base__pixel_alpha_transparency  //
transparency()4013 wuffs_base__pixel_format::transparency() const {
4014   return wuffs_base__pixel_format__transparency(this);
4015 }
4016 
4017 #endif  // __cplusplus
4018 
4019 // --------
4020 
4021 // wuffs_base__pixel_subsampling encodes whether sample values cover one pixel
4022 // or cover multiple pixels.
4023 //
4024 // See https://github.com/google/wuffs/blob/main/doc/note/pixel-subsampling.md
4025 //
4026 // Do not manipulate its bits directly; they are private implementation
4027 // details. Use methods such as wuffs_base__pixel_subsampling__bias_x instead.
4028 typedef struct wuffs_base__pixel_subsampling__struct {
4029   uint32_t repr;
4030 
4031 #ifdef __cplusplus
4032   inline uint32_t bias_x(uint32_t plane) const;
4033   inline uint32_t denominator_x(uint32_t plane) const;
4034   inline uint32_t bias_y(uint32_t plane) const;
4035   inline uint32_t denominator_y(uint32_t plane) const;
4036 #endif  // __cplusplus
4037 
4038 } wuffs_base__pixel_subsampling;
4039 
4040 static inline wuffs_base__pixel_subsampling  //
wuffs_base__make_pixel_subsampling(uint32_t repr)4041 wuffs_base__make_pixel_subsampling(uint32_t repr) {
4042   wuffs_base__pixel_subsampling s;
4043   s.repr = repr;
4044   return s;
4045 }
4046 
4047 #define WUFFS_BASE__PIXEL_SUBSAMPLING__NONE 0x00000000
4048 
4049 #define WUFFS_BASE__PIXEL_SUBSAMPLING__444 0x000000
4050 #define WUFFS_BASE__PIXEL_SUBSAMPLING__440 0x010100
4051 #define WUFFS_BASE__PIXEL_SUBSAMPLING__422 0x101000
4052 #define WUFFS_BASE__PIXEL_SUBSAMPLING__420 0x111100
4053 #define WUFFS_BASE__PIXEL_SUBSAMPLING__411 0x303000
4054 #define WUFFS_BASE__PIXEL_SUBSAMPLING__410 0x313100
4055 
4056 static inline uint32_t  //
wuffs_base__pixel_subsampling__bias_x(const wuffs_base__pixel_subsampling * s,uint32_t plane)4057 wuffs_base__pixel_subsampling__bias_x(const wuffs_base__pixel_subsampling* s,
4058                                       uint32_t plane) {
4059   uint32_t shift = ((plane & 0x03) * 8) + 6;
4060   return (s->repr >> shift) & 0x03;
4061 }
4062 
4063 static inline uint32_t  //
wuffs_base__pixel_subsampling__denominator_x(const wuffs_base__pixel_subsampling * s,uint32_t plane)4064 wuffs_base__pixel_subsampling__denominator_x(
4065     const wuffs_base__pixel_subsampling* s,
4066     uint32_t plane) {
4067   uint32_t shift = ((plane & 0x03) * 8) + 4;
4068   return ((s->repr >> shift) & 0x03) + 1;
4069 }
4070 
4071 static inline uint32_t  //
wuffs_base__pixel_subsampling__bias_y(const wuffs_base__pixel_subsampling * s,uint32_t plane)4072 wuffs_base__pixel_subsampling__bias_y(const wuffs_base__pixel_subsampling* s,
4073                                       uint32_t plane) {
4074   uint32_t shift = ((plane & 0x03) * 8) + 2;
4075   return (s->repr >> shift) & 0x03;
4076 }
4077 
4078 static inline uint32_t  //
wuffs_base__pixel_subsampling__denominator_y(const wuffs_base__pixel_subsampling * s,uint32_t plane)4079 wuffs_base__pixel_subsampling__denominator_y(
4080     const wuffs_base__pixel_subsampling* s,
4081     uint32_t plane) {
4082   uint32_t shift = ((plane & 0x03) * 8) + 0;
4083   return ((s->repr >> shift) & 0x03) + 1;
4084 }
4085 
4086 #ifdef __cplusplus
4087 
4088 inline uint32_t  //
bias_x(uint32_t plane)4089 wuffs_base__pixel_subsampling::bias_x(uint32_t plane) const {
4090   return wuffs_base__pixel_subsampling__bias_x(this, plane);
4091 }
4092 
4093 inline uint32_t  //
denominator_x(uint32_t plane)4094 wuffs_base__pixel_subsampling::denominator_x(uint32_t plane) const {
4095   return wuffs_base__pixel_subsampling__denominator_x(this, plane);
4096 }
4097 
4098 inline uint32_t  //
bias_y(uint32_t plane)4099 wuffs_base__pixel_subsampling::bias_y(uint32_t plane) const {
4100   return wuffs_base__pixel_subsampling__bias_y(this, plane);
4101 }
4102 
4103 inline uint32_t  //
denominator_y(uint32_t plane)4104 wuffs_base__pixel_subsampling::denominator_y(uint32_t plane) const {
4105   return wuffs_base__pixel_subsampling__denominator_y(this, plane);
4106 }
4107 
4108 #endif  // __cplusplus
4109 
4110 // --------
4111 
4112 typedef struct wuffs_base__pixel_config__struct {
4113   // Do not access the private_impl's fields directly. There is no API/ABI
4114   // compatibility or safety guarantee if you do so.
4115   struct {
4116     wuffs_base__pixel_format pixfmt;
4117     wuffs_base__pixel_subsampling pixsub;
4118     uint32_t width;
4119     uint32_t height;
4120   } private_impl;
4121 
4122 #ifdef __cplusplus
4123   inline void set(uint32_t pixfmt_repr,
4124                   uint32_t pixsub_repr,
4125                   uint32_t width,
4126                   uint32_t height);
4127   inline void invalidate();
4128   inline bool is_valid() const;
4129   inline wuffs_base__pixel_format pixel_format() const;
4130   inline wuffs_base__pixel_subsampling pixel_subsampling() const;
4131   inline wuffs_base__rect_ie_u32 bounds() const;
4132   inline uint32_t width() const;
4133   inline uint32_t height() const;
4134   inline uint64_t pixbuf_len() const;
4135 #endif  // __cplusplus
4136 
4137 } wuffs_base__pixel_config;
4138 
4139 static inline wuffs_base__pixel_config  //
wuffs_base__null_pixel_config()4140 wuffs_base__null_pixel_config() {
4141   wuffs_base__pixel_config ret;
4142   ret.private_impl.pixfmt.repr = 0;
4143   ret.private_impl.pixsub.repr = 0;
4144   ret.private_impl.width = 0;
4145   ret.private_impl.height = 0;
4146   return ret;
4147 }
4148 
4149 // TODO: Should this function return bool? An error type?
4150 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)4151 wuffs_base__pixel_config__set(wuffs_base__pixel_config* c,
4152                               uint32_t pixfmt_repr,
4153                               uint32_t pixsub_repr,
4154                               uint32_t width,
4155                               uint32_t height) {
4156   if (!c) {
4157     return;
4158   }
4159   if (pixfmt_repr) {
4160     uint64_t wh = ((uint64_t)width) * ((uint64_t)height);
4161     // TODO: handle things other than 1 byte per pixel.
4162     if (wh <= ((uint64_t)SIZE_MAX)) {
4163       c->private_impl.pixfmt.repr = pixfmt_repr;
4164       c->private_impl.pixsub.repr = pixsub_repr;
4165       c->private_impl.width = width;
4166       c->private_impl.height = height;
4167       return;
4168     }
4169   }
4170 
4171   c->private_impl.pixfmt.repr = 0;
4172   c->private_impl.pixsub.repr = 0;
4173   c->private_impl.width = 0;
4174   c->private_impl.height = 0;
4175 }
4176 
4177 static inline void  //
wuffs_base__pixel_config__invalidate(wuffs_base__pixel_config * c)4178 wuffs_base__pixel_config__invalidate(wuffs_base__pixel_config* c) {
4179   if (c) {
4180     c->private_impl.pixfmt.repr = 0;
4181     c->private_impl.pixsub.repr = 0;
4182     c->private_impl.width = 0;
4183     c->private_impl.height = 0;
4184   }
4185 }
4186 
4187 static inline bool  //
wuffs_base__pixel_config__is_valid(const wuffs_base__pixel_config * c)4188 wuffs_base__pixel_config__is_valid(const wuffs_base__pixel_config* c) {
4189   return c && c->private_impl.pixfmt.repr;
4190 }
4191 
4192 static inline wuffs_base__pixel_format  //
wuffs_base__pixel_config__pixel_format(const wuffs_base__pixel_config * c)4193 wuffs_base__pixel_config__pixel_format(const wuffs_base__pixel_config* c) {
4194   return c ? c->private_impl.pixfmt : wuffs_base__make_pixel_format(0);
4195 }
4196 
4197 static inline wuffs_base__pixel_subsampling  //
wuffs_base__pixel_config__pixel_subsampling(const wuffs_base__pixel_config * c)4198 wuffs_base__pixel_config__pixel_subsampling(const wuffs_base__pixel_config* c) {
4199   return c ? c->private_impl.pixsub : wuffs_base__make_pixel_subsampling(0);
4200 }
4201 
4202 static inline wuffs_base__rect_ie_u32  //
wuffs_base__pixel_config__bounds(const wuffs_base__pixel_config * c)4203 wuffs_base__pixel_config__bounds(const wuffs_base__pixel_config* c) {
4204   if (c) {
4205     wuffs_base__rect_ie_u32 ret;
4206     ret.min_incl_x = 0;
4207     ret.min_incl_y = 0;
4208     ret.max_excl_x = c->private_impl.width;
4209     ret.max_excl_y = c->private_impl.height;
4210     return ret;
4211   }
4212 
4213   wuffs_base__rect_ie_u32 ret;
4214   ret.min_incl_x = 0;
4215   ret.min_incl_y = 0;
4216   ret.max_excl_x = 0;
4217   ret.max_excl_y = 0;
4218   return ret;
4219 }
4220 
4221 static inline uint32_t  //
wuffs_base__pixel_config__width(const wuffs_base__pixel_config * c)4222 wuffs_base__pixel_config__width(const wuffs_base__pixel_config* c) {
4223   return c ? c->private_impl.width : 0;
4224 }
4225 
4226 static inline uint32_t  //
wuffs_base__pixel_config__height(const wuffs_base__pixel_config * c)4227 wuffs_base__pixel_config__height(const wuffs_base__pixel_config* c) {
4228   return c ? c->private_impl.height : 0;
4229 }
4230 
4231 // TODO: this is the right API for planar (not interleaved) pixbufs? Should it
4232 // allow decoding into a color model different from the format's intrinsic one?
4233 // For example, decoding a JPEG image straight to RGBA instead of to YCbCr?
4234 static inline uint64_t  //
wuffs_base__pixel_config__pixbuf_len(const wuffs_base__pixel_config * c)4235 wuffs_base__pixel_config__pixbuf_len(const wuffs_base__pixel_config* c) {
4236   if (!c) {
4237     return 0;
4238   }
4239   if (wuffs_base__pixel_format__is_planar(&c->private_impl.pixfmt)) {
4240     // TODO: support planar pixel formats, concious of pixel subsampling.
4241     return 0;
4242   }
4243   uint32_t bits_per_pixel =
4244       wuffs_base__pixel_format__bits_per_pixel(&c->private_impl.pixfmt);
4245   if ((bits_per_pixel == 0) || ((bits_per_pixel % 8) != 0)) {
4246     // TODO: support fraction-of-byte pixels, e.g. 1 bit per pixel?
4247     return 0;
4248   }
4249   uint64_t bytes_per_pixel = bits_per_pixel / 8;
4250 
4251   uint64_t n =
4252       ((uint64_t)c->private_impl.width) * ((uint64_t)c->private_impl.height);
4253   if (n > (UINT64_MAX / bytes_per_pixel)) {
4254     return 0;
4255   }
4256   n *= bytes_per_pixel;
4257 
4258   if (wuffs_base__pixel_format__is_indexed(&c->private_impl.pixfmt)) {
4259     if (n >
4260         (UINT64_MAX - WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH)) {
4261       return 0;
4262     }
4263     n += WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
4264   }
4265 
4266   return n;
4267 }
4268 
4269 #ifdef __cplusplus
4270 
4271 inline void  //
set(uint32_t pixfmt_repr,uint32_t pixsub_repr,uint32_t width,uint32_t height)4272 wuffs_base__pixel_config::set(uint32_t pixfmt_repr,
4273                               uint32_t pixsub_repr,
4274                               uint32_t width,
4275                               uint32_t height) {
4276   wuffs_base__pixel_config__set(this, pixfmt_repr, pixsub_repr, width, height);
4277 }
4278 
4279 inline void  //
invalidate()4280 wuffs_base__pixel_config::invalidate() {
4281   wuffs_base__pixel_config__invalidate(this);
4282 }
4283 
4284 inline bool  //
is_valid()4285 wuffs_base__pixel_config::is_valid() const {
4286   return wuffs_base__pixel_config__is_valid(this);
4287 }
4288 
4289 inline wuffs_base__pixel_format  //
pixel_format()4290 wuffs_base__pixel_config::pixel_format() const {
4291   return wuffs_base__pixel_config__pixel_format(this);
4292 }
4293 
4294 inline wuffs_base__pixel_subsampling  //
pixel_subsampling()4295 wuffs_base__pixel_config::pixel_subsampling() const {
4296   return wuffs_base__pixel_config__pixel_subsampling(this);
4297 }
4298 
4299 inline wuffs_base__rect_ie_u32  //
bounds()4300 wuffs_base__pixel_config::bounds() const {
4301   return wuffs_base__pixel_config__bounds(this);
4302 }
4303 
4304 inline uint32_t  //
width()4305 wuffs_base__pixel_config::width() const {
4306   return wuffs_base__pixel_config__width(this);
4307 }
4308 
4309 inline uint32_t  //
height()4310 wuffs_base__pixel_config::height() const {
4311   return wuffs_base__pixel_config__height(this);
4312 }
4313 
4314 inline uint64_t  //
pixbuf_len()4315 wuffs_base__pixel_config::pixbuf_len() const {
4316   return wuffs_base__pixel_config__pixbuf_len(this);
4317 }
4318 
4319 #endif  // __cplusplus
4320 
4321 // --------
4322 
4323 typedef struct wuffs_base__image_config__struct {
4324   wuffs_base__pixel_config pixcfg;
4325 
4326   // Do not access the private_impl's fields directly. There is no API/ABI
4327   // compatibility or safety guarantee if you do so.
4328   struct {
4329     uint64_t first_frame_io_position;
4330     bool first_frame_is_opaque;
4331   } private_impl;
4332 
4333 #ifdef __cplusplus
4334   inline void set(uint32_t pixfmt_repr,
4335                   uint32_t pixsub_repr,
4336                   uint32_t width,
4337                   uint32_t height,
4338                   uint64_t first_frame_io_position,
4339                   bool first_frame_is_opaque);
4340   inline void invalidate();
4341   inline bool is_valid() const;
4342   inline uint64_t first_frame_io_position() const;
4343   inline bool first_frame_is_opaque() const;
4344 #endif  // __cplusplus
4345 
4346 } wuffs_base__image_config;
4347 
4348 static inline wuffs_base__image_config  //
wuffs_base__null_image_config()4349 wuffs_base__null_image_config() {
4350   wuffs_base__image_config ret;
4351   ret.pixcfg = wuffs_base__null_pixel_config();
4352   ret.private_impl.first_frame_io_position = 0;
4353   ret.private_impl.first_frame_is_opaque = false;
4354   return ret;
4355 }
4356 
4357 // TODO: Should this function return bool? An error type?
4358 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)4359 wuffs_base__image_config__set(wuffs_base__image_config* c,
4360                               uint32_t pixfmt_repr,
4361                               uint32_t pixsub_repr,
4362                               uint32_t width,
4363                               uint32_t height,
4364                               uint64_t first_frame_io_position,
4365                               bool first_frame_is_opaque) {
4366   if (!c) {
4367     return;
4368   }
4369   if (pixfmt_repr) {
4370     c->pixcfg.private_impl.pixfmt.repr = pixfmt_repr;
4371     c->pixcfg.private_impl.pixsub.repr = pixsub_repr;
4372     c->pixcfg.private_impl.width = width;
4373     c->pixcfg.private_impl.height = height;
4374     c->private_impl.first_frame_io_position = first_frame_io_position;
4375     c->private_impl.first_frame_is_opaque = first_frame_is_opaque;
4376     return;
4377   }
4378 
4379   c->pixcfg.private_impl.pixfmt.repr = 0;
4380   c->pixcfg.private_impl.pixsub.repr = 0;
4381   c->pixcfg.private_impl.width = 0;
4382   c->pixcfg.private_impl.height = 0;
4383   c->private_impl.first_frame_io_position = 0;
4384   c->private_impl.first_frame_is_opaque = 0;
4385 }
4386 
4387 static inline void  //
wuffs_base__image_config__invalidate(wuffs_base__image_config * c)4388 wuffs_base__image_config__invalidate(wuffs_base__image_config* c) {
4389   if (c) {
4390     c->pixcfg.private_impl.pixfmt.repr = 0;
4391     c->pixcfg.private_impl.pixsub.repr = 0;
4392     c->pixcfg.private_impl.width = 0;
4393     c->pixcfg.private_impl.height = 0;
4394     c->private_impl.first_frame_io_position = 0;
4395     c->private_impl.first_frame_is_opaque = 0;
4396   }
4397 }
4398 
4399 static inline bool  //
wuffs_base__image_config__is_valid(const wuffs_base__image_config * c)4400 wuffs_base__image_config__is_valid(const wuffs_base__image_config* c) {
4401   return c && wuffs_base__pixel_config__is_valid(&(c->pixcfg));
4402 }
4403 
4404 static inline uint64_t  //
wuffs_base__image_config__first_frame_io_position(const wuffs_base__image_config * c)4405 wuffs_base__image_config__first_frame_io_position(
4406     const wuffs_base__image_config* c) {
4407   return c ? c->private_impl.first_frame_io_position : 0;
4408 }
4409 
4410 static inline bool  //
wuffs_base__image_config__first_frame_is_opaque(const wuffs_base__image_config * c)4411 wuffs_base__image_config__first_frame_is_opaque(
4412     const wuffs_base__image_config* c) {
4413   return c ? c->private_impl.first_frame_is_opaque : false;
4414 }
4415 
4416 #ifdef __cplusplus
4417 
4418 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)4419 wuffs_base__image_config::set(uint32_t pixfmt_repr,
4420                               uint32_t pixsub_repr,
4421                               uint32_t width,
4422                               uint32_t height,
4423                               uint64_t first_frame_io_position,
4424                               bool first_frame_is_opaque) {
4425   wuffs_base__image_config__set(this, pixfmt_repr, pixsub_repr, width, height,
4426                                 first_frame_io_position, first_frame_is_opaque);
4427 }
4428 
4429 inline void  //
invalidate()4430 wuffs_base__image_config::invalidate() {
4431   wuffs_base__image_config__invalidate(this);
4432 }
4433 
4434 inline bool  //
is_valid()4435 wuffs_base__image_config::is_valid() const {
4436   return wuffs_base__image_config__is_valid(this);
4437 }
4438 
4439 inline uint64_t  //
first_frame_io_position()4440 wuffs_base__image_config::first_frame_io_position() const {
4441   return wuffs_base__image_config__first_frame_io_position(this);
4442 }
4443 
4444 inline bool  //
first_frame_is_opaque()4445 wuffs_base__image_config::first_frame_is_opaque() const {
4446   return wuffs_base__image_config__first_frame_is_opaque(this);
4447 }
4448 
4449 #endif  // __cplusplus
4450 
4451 // --------
4452 
4453 // wuffs_base__animation_disposal encodes, for an animated image, how to
4454 // dispose of a frame after displaying it:
4455 //  - None means to draw the next frame on top of this one.
4456 //  - Restore Background means to clear the frame's dirty rectangle to "the
4457 //    background color" (in practice, this means transparent black) before
4458 //    drawing the next frame.
4459 //  - Restore Previous means to undo the current frame, so that the next frame
4460 //    is drawn on top of the previous one.
4461 typedef uint8_t wuffs_base__animation_disposal;
4462 
4463 #define WUFFS_BASE__ANIMATION_DISPOSAL__NONE ((wuffs_base__animation_disposal)0)
4464 #define WUFFS_BASE__ANIMATION_DISPOSAL__RESTORE_BACKGROUND \
4465   ((wuffs_base__animation_disposal)1)
4466 #define WUFFS_BASE__ANIMATION_DISPOSAL__RESTORE_PREVIOUS \
4467   ((wuffs_base__animation_disposal)2)
4468 
4469 // --------
4470 
4471 typedef struct wuffs_base__frame_config__struct {
4472   // Do not access the private_impl's fields directly. There is no API/ABI
4473   // compatibility or safety guarantee if you do so.
4474   struct {
4475     wuffs_base__rect_ie_u32 bounds;
4476     wuffs_base__flicks duration;
4477     uint64_t index;
4478     uint64_t io_position;
4479     wuffs_base__animation_disposal disposal;
4480     bool opaque_within_bounds;
4481     bool overwrite_instead_of_blend;
4482     wuffs_base__color_u32_argb_premul background_color;
4483   } private_impl;
4484 
4485 #ifdef __cplusplus
4486   inline void set(wuffs_base__rect_ie_u32 bounds,
4487                   wuffs_base__flicks duration,
4488                   uint64_t index,
4489                   uint64_t io_position,
4490                   wuffs_base__animation_disposal disposal,
4491                   bool opaque_within_bounds,
4492                   bool overwrite_instead_of_blend,
4493                   wuffs_base__color_u32_argb_premul background_color);
4494   inline wuffs_base__rect_ie_u32 bounds() const;
4495   inline uint32_t width() const;
4496   inline uint32_t height() const;
4497   inline wuffs_base__flicks duration() const;
4498   inline uint64_t index() const;
4499   inline uint64_t io_position() const;
4500   inline wuffs_base__animation_disposal disposal() const;
4501   inline bool opaque_within_bounds() const;
4502   inline bool overwrite_instead_of_blend() const;
4503   inline wuffs_base__color_u32_argb_premul background_color() const;
4504 #endif  // __cplusplus
4505 
4506 } wuffs_base__frame_config;
4507 
4508 static inline wuffs_base__frame_config  //
wuffs_base__null_frame_config()4509 wuffs_base__null_frame_config() {
4510   wuffs_base__frame_config ret;
4511   ret.private_impl.bounds = wuffs_base__make_rect_ie_u32(0, 0, 0, 0);
4512   ret.private_impl.duration = 0;
4513   ret.private_impl.index = 0;
4514   ret.private_impl.io_position = 0;
4515   ret.private_impl.disposal = 0;
4516   ret.private_impl.opaque_within_bounds = false;
4517   ret.private_impl.overwrite_instead_of_blend = false;
4518   return ret;
4519 }
4520 
4521 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)4522 wuffs_base__frame_config__set(
4523     wuffs_base__frame_config* c,
4524     wuffs_base__rect_ie_u32 bounds,
4525     wuffs_base__flicks duration,
4526     uint64_t index,
4527     uint64_t io_position,
4528     wuffs_base__animation_disposal disposal,
4529     bool opaque_within_bounds,
4530     bool overwrite_instead_of_blend,
4531     wuffs_base__color_u32_argb_premul background_color) {
4532   if (!c) {
4533     return;
4534   }
4535 
4536   c->private_impl.bounds = bounds;
4537   c->private_impl.duration = duration;
4538   c->private_impl.index = index;
4539   c->private_impl.io_position = io_position;
4540   c->private_impl.disposal = disposal;
4541   c->private_impl.opaque_within_bounds = opaque_within_bounds;
4542   c->private_impl.overwrite_instead_of_blend = overwrite_instead_of_blend;
4543   c->private_impl.background_color = background_color;
4544 }
4545 
4546 static inline wuffs_base__rect_ie_u32  //
wuffs_base__frame_config__bounds(const wuffs_base__frame_config * c)4547 wuffs_base__frame_config__bounds(const wuffs_base__frame_config* c) {
4548   if (c) {
4549     return c->private_impl.bounds;
4550   }
4551 
4552   wuffs_base__rect_ie_u32 ret;
4553   ret.min_incl_x = 0;
4554   ret.min_incl_y = 0;
4555   ret.max_excl_x = 0;
4556   ret.max_excl_y = 0;
4557   return ret;
4558 }
4559 
4560 static inline uint32_t  //
wuffs_base__frame_config__width(const wuffs_base__frame_config * c)4561 wuffs_base__frame_config__width(const wuffs_base__frame_config* c) {
4562   return c ? wuffs_base__rect_ie_u32__width(&c->private_impl.bounds) : 0;
4563 }
4564 
4565 static inline uint32_t  //
wuffs_base__frame_config__height(const wuffs_base__frame_config * c)4566 wuffs_base__frame_config__height(const wuffs_base__frame_config* c) {
4567   return c ? wuffs_base__rect_ie_u32__height(&c->private_impl.bounds) : 0;
4568 }
4569 
4570 // wuffs_base__frame_config__duration returns the amount of time to display
4571 // this frame. Zero means to display forever - a still (non-animated) image.
4572 static inline wuffs_base__flicks  //
wuffs_base__frame_config__duration(const wuffs_base__frame_config * c)4573 wuffs_base__frame_config__duration(const wuffs_base__frame_config* c) {
4574   return c ? c->private_impl.duration : 0;
4575 }
4576 
4577 // wuffs_base__frame_config__index returns the index of this frame. The first
4578 // frame in an image has index 0, the second frame has index 1, and so on.
4579 static inline uint64_t  //
wuffs_base__frame_config__index(const wuffs_base__frame_config * c)4580 wuffs_base__frame_config__index(const wuffs_base__frame_config* c) {
4581   return c ? c->private_impl.index : 0;
4582 }
4583 
4584 // wuffs_base__frame_config__io_position returns the I/O stream position before
4585 // the frame config.
4586 static inline uint64_t  //
wuffs_base__frame_config__io_position(const wuffs_base__frame_config * c)4587 wuffs_base__frame_config__io_position(const wuffs_base__frame_config* c) {
4588   return c ? c->private_impl.io_position : 0;
4589 }
4590 
4591 // wuffs_base__frame_config__disposal returns, for an animated image, how to
4592 // dispose of this frame after displaying it.
4593 static inline wuffs_base__animation_disposal  //
wuffs_base__frame_config__disposal(const wuffs_base__frame_config * c)4594 wuffs_base__frame_config__disposal(const wuffs_base__frame_config* c) {
4595   return c ? c->private_impl.disposal : 0;
4596 }
4597 
4598 // wuffs_base__frame_config__opaque_within_bounds returns whether all pixels
4599 // within the frame's bounds are fully opaque. It makes no claim about pixels
4600 // outside the frame bounds but still inside the overall image. The two
4601 // bounding rectangles can differ for animated images.
4602 //
4603 // Its semantics are conservative. It is valid for a fully opaque frame to have
4604 // this value be false: a false negative.
4605 //
4606 // If true, drawing the frame with WUFFS_BASE__PIXEL_BLEND__SRC and
4607 // WUFFS_BASE__PIXEL_BLEND__SRC_OVER should be equivalent, in terms of
4608 // resultant pixels, but the former may be faster.
4609 static inline bool  //
wuffs_base__frame_config__opaque_within_bounds(const wuffs_base__frame_config * c)4610 wuffs_base__frame_config__opaque_within_bounds(
4611     const wuffs_base__frame_config* c) {
4612   return c && c->private_impl.opaque_within_bounds;
4613 }
4614 
4615 // wuffs_base__frame_config__overwrite_instead_of_blend returns, for an
4616 // animated image, whether to ignore the previous image state (within the frame
4617 // bounds) when drawing this incremental frame. Equivalently, whether to use
4618 // WUFFS_BASE__PIXEL_BLEND__SRC instead of WUFFS_BASE__PIXEL_BLEND__SRC_OVER.
4619 //
4620 // The WebP spec (https://developers.google.com/speed/webp/docs/riff_container)
4621 // calls this the "Blending method" bit. WebP's "Do not blend" corresponds to
4622 // Wuffs' "overwrite_instead_of_blend".
4623 static inline bool  //
wuffs_base__frame_config__overwrite_instead_of_blend(const wuffs_base__frame_config * c)4624 wuffs_base__frame_config__overwrite_instead_of_blend(
4625     const wuffs_base__frame_config* c) {
4626   return c && c->private_impl.overwrite_instead_of_blend;
4627 }
4628 
4629 static inline wuffs_base__color_u32_argb_premul  //
wuffs_base__frame_config__background_color(const wuffs_base__frame_config * c)4630 wuffs_base__frame_config__background_color(const wuffs_base__frame_config* c) {
4631   return c ? c->private_impl.background_color : 0;
4632 }
4633 
4634 #ifdef __cplusplus
4635 
4636 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)4637 wuffs_base__frame_config::set(
4638     wuffs_base__rect_ie_u32 bounds,
4639     wuffs_base__flicks duration,
4640     uint64_t index,
4641     uint64_t io_position,
4642     wuffs_base__animation_disposal disposal,
4643     bool opaque_within_bounds,
4644     bool overwrite_instead_of_blend,
4645     wuffs_base__color_u32_argb_premul background_color) {
4646   wuffs_base__frame_config__set(this, bounds, duration, index, io_position,
4647                                 disposal, opaque_within_bounds,
4648                                 overwrite_instead_of_blend, background_color);
4649 }
4650 
4651 inline wuffs_base__rect_ie_u32  //
bounds()4652 wuffs_base__frame_config::bounds() const {
4653   return wuffs_base__frame_config__bounds(this);
4654 }
4655 
4656 inline uint32_t  //
width()4657 wuffs_base__frame_config::width() const {
4658   return wuffs_base__frame_config__width(this);
4659 }
4660 
4661 inline uint32_t  //
height()4662 wuffs_base__frame_config::height() const {
4663   return wuffs_base__frame_config__height(this);
4664 }
4665 
4666 inline wuffs_base__flicks  //
duration()4667 wuffs_base__frame_config::duration() const {
4668   return wuffs_base__frame_config__duration(this);
4669 }
4670 
4671 inline uint64_t  //
index()4672 wuffs_base__frame_config::index() const {
4673   return wuffs_base__frame_config__index(this);
4674 }
4675 
4676 inline uint64_t  //
io_position()4677 wuffs_base__frame_config::io_position() const {
4678   return wuffs_base__frame_config__io_position(this);
4679 }
4680 
4681 inline wuffs_base__animation_disposal  //
disposal()4682 wuffs_base__frame_config::disposal() const {
4683   return wuffs_base__frame_config__disposal(this);
4684 }
4685 
4686 inline bool  //
opaque_within_bounds()4687 wuffs_base__frame_config::opaque_within_bounds() const {
4688   return wuffs_base__frame_config__opaque_within_bounds(this);
4689 }
4690 
4691 inline bool  //
overwrite_instead_of_blend()4692 wuffs_base__frame_config::overwrite_instead_of_blend() const {
4693   return wuffs_base__frame_config__overwrite_instead_of_blend(this);
4694 }
4695 
4696 inline wuffs_base__color_u32_argb_premul  //
background_color()4697 wuffs_base__frame_config::background_color() const {
4698   return wuffs_base__frame_config__background_color(this);
4699 }
4700 
4701 #endif  // __cplusplus
4702 
4703 // --------
4704 
4705 typedef struct wuffs_base__pixel_buffer__struct {
4706   wuffs_base__pixel_config pixcfg;
4707 
4708   // Do not access the private_impl's fields directly. There is no API/ABI
4709   // compatibility or safety guarantee if you do so.
4710   struct {
4711     wuffs_base__table_u8 planes[WUFFS_BASE__PIXEL_FORMAT__NUM_PLANES_MAX];
4712     // TODO: color spaces.
4713   } private_impl;
4714 
4715 #ifdef __cplusplus
4716   inline wuffs_base__status set_interleaved(
4717       const wuffs_base__pixel_config* pixcfg,
4718       wuffs_base__table_u8 primary_memory,
4719       wuffs_base__slice_u8 palette_memory);
4720   inline wuffs_base__status set_from_slice(
4721       const wuffs_base__pixel_config* pixcfg,
4722       wuffs_base__slice_u8 pixbuf_memory);
4723   inline wuffs_base__status set_from_table(
4724       const wuffs_base__pixel_config* pixcfg,
4725       wuffs_base__table_u8 primary_memory);
4726   inline wuffs_base__slice_u8 palette();
4727   inline wuffs_base__slice_u8 palette_or_else(wuffs_base__slice_u8 fallback);
4728   inline wuffs_base__pixel_format pixel_format() const;
4729   inline wuffs_base__table_u8 plane(uint32_t p);
4730   inline wuffs_base__color_u32_argb_premul color_u32_at(uint32_t x,
4731                                                         uint32_t y) const;
4732   inline wuffs_base__status set_color_u32_at(
4733       uint32_t x,
4734       uint32_t y,
4735       wuffs_base__color_u32_argb_premul color);
4736   inline wuffs_base__status set_color_u32_fill_rect(
4737       wuffs_base__rect_ie_u32 rect,
4738       wuffs_base__color_u32_argb_premul color);
4739 #endif  // __cplusplus
4740 
4741 } wuffs_base__pixel_buffer;
4742 
4743 static inline wuffs_base__pixel_buffer  //
wuffs_base__null_pixel_buffer()4744 wuffs_base__null_pixel_buffer() {
4745   wuffs_base__pixel_buffer ret;
4746   ret.pixcfg = wuffs_base__null_pixel_config();
4747   ret.private_impl.planes[0] = wuffs_base__empty_table_u8();
4748   ret.private_impl.planes[1] = wuffs_base__empty_table_u8();
4749   ret.private_impl.planes[2] = wuffs_base__empty_table_u8();
4750   ret.private_impl.planes[3] = wuffs_base__empty_table_u8();
4751   return ret;
4752 }
4753 
4754 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)4755 wuffs_base__pixel_buffer__set_interleaved(
4756     wuffs_base__pixel_buffer* pb,
4757     const wuffs_base__pixel_config* pixcfg,
4758     wuffs_base__table_u8 primary_memory,
4759     wuffs_base__slice_u8 palette_memory) {
4760   if (!pb) {
4761     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
4762   }
4763   memset(pb, 0, sizeof(*pb));
4764   if (!pixcfg ||
4765       wuffs_base__pixel_format__is_planar(&pixcfg->private_impl.pixfmt)) {
4766     return wuffs_base__make_status(wuffs_base__error__bad_argument);
4767   }
4768   if (wuffs_base__pixel_format__is_indexed(&pixcfg->private_impl.pixfmt) &&
4769       (palette_memory.len <
4770        WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH)) {
4771     return wuffs_base__make_status(
4772         wuffs_base__error__bad_argument_length_too_short);
4773   }
4774   uint32_t bits_per_pixel =
4775       wuffs_base__pixel_format__bits_per_pixel(&pixcfg->private_impl.pixfmt);
4776   if ((bits_per_pixel == 0) || ((bits_per_pixel % 8) != 0)) {
4777     // TODO: support fraction-of-byte pixels, e.g. 1 bit per pixel?
4778     return wuffs_base__make_status(wuffs_base__error__unsupported_option);
4779   }
4780   uint64_t bytes_per_pixel = bits_per_pixel / 8;
4781 
4782   uint64_t width_in_bytes =
4783       ((uint64_t)pixcfg->private_impl.width) * bytes_per_pixel;
4784   if ((width_in_bytes > primary_memory.width) ||
4785       (pixcfg->private_impl.height > primary_memory.height)) {
4786     return wuffs_base__make_status(wuffs_base__error__bad_argument);
4787   }
4788 
4789   pb->pixcfg = *pixcfg;
4790   pb->private_impl.planes[0] = primary_memory;
4791   if (wuffs_base__pixel_format__is_indexed(&pixcfg->private_impl.pixfmt)) {
4792     wuffs_base__table_u8* tab =
4793         &pb->private_impl
4794              .planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE];
4795     tab->ptr = palette_memory.ptr;
4796     tab->width = WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
4797     tab->height = 1;
4798     tab->stride = WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
4799   }
4800   return wuffs_base__make_status(NULL);
4801 }
4802 
4803 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)4804 wuffs_base__pixel_buffer__set_from_slice(wuffs_base__pixel_buffer* pb,
4805                                          const wuffs_base__pixel_config* pixcfg,
4806                                          wuffs_base__slice_u8 pixbuf_memory) {
4807   if (!pb) {
4808     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
4809   }
4810   memset(pb, 0, sizeof(*pb));
4811   if (!pixcfg) {
4812     return wuffs_base__make_status(wuffs_base__error__bad_argument);
4813   }
4814   if (wuffs_base__pixel_format__is_planar(&pixcfg->private_impl.pixfmt)) {
4815     // TODO: support planar pixel formats, concious of pixel subsampling.
4816     return wuffs_base__make_status(wuffs_base__error__unsupported_option);
4817   }
4818   uint32_t bits_per_pixel =
4819       wuffs_base__pixel_format__bits_per_pixel(&pixcfg->private_impl.pixfmt);
4820   if ((bits_per_pixel == 0) || ((bits_per_pixel % 8) != 0)) {
4821     // TODO: support fraction-of-byte pixels, e.g. 1 bit per pixel?
4822     return wuffs_base__make_status(wuffs_base__error__unsupported_option);
4823   }
4824   uint64_t bytes_per_pixel = bits_per_pixel / 8;
4825 
4826   uint8_t* ptr = pixbuf_memory.ptr;
4827   uint64_t len = pixbuf_memory.len;
4828   if (wuffs_base__pixel_format__is_indexed(&pixcfg->private_impl.pixfmt)) {
4829     // Split a WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH byte
4830     // chunk (1024 bytes = 256 palette entries × 4 bytes per entry) from the
4831     // start of pixbuf_memory. We split from the start, not the end, so that
4832     // the both chunks' pointers have the same alignment as the original
4833     // pointer, up to an alignment of 1024.
4834     if (len < WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
4835       return wuffs_base__make_status(
4836           wuffs_base__error__bad_argument_length_too_short);
4837     }
4838     wuffs_base__table_u8* tab =
4839         &pb->private_impl
4840              .planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE];
4841     tab->ptr = ptr;
4842     tab->width = WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
4843     tab->height = 1;
4844     tab->stride = WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
4845     ptr += WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
4846     len -= WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
4847   }
4848 
4849   uint64_t wh = ((uint64_t)pixcfg->private_impl.width) *
4850                 ((uint64_t)pixcfg->private_impl.height);
4851   size_t width = (size_t)(pixcfg->private_impl.width);
4852   if ((wh > (UINT64_MAX / bytes_per_pixel)) ||
4853       (width > (SIZE_MAX / bytes_per_pixel))) {
4854     return wuffs_base__make_status(wuffs_base__error__bad_argument);
4855   }
4856   wh *= bytes_per_pixel;
4857   width = ((size_t)(width * bytes_per_pixel));
4858   if (wh > len) {
4859     return wuffs_base__make_status(
4860         wuffs_base__error__bad_argument_length_too_short);
4861   }
4862 
4863   pb->pixcfg = *pixcfg;
4864   wuffs_base__table_u8* tab = &pb->private_impl.planes[0];
4865   tab->ptr = ptr;
4866   tab->width = width;
4867   tab->height = pixcfg->private_impl.height;
4868   tab->stride = width;
4869   return wuffs_base__make_status(NULL);
4870 }
4871 
4872 // Deprecated: does not handle indexed pixel configurations. Use
4873 // wuffs_base__pixel_buffer__set_interleaved instead.
4874 static inline wuffs_base__status  //
wuffs_base__pixel_buffer__set_from_table(wuffs_base__pixel_buffer * pb,const wuffs_base__pixel_config * pixcfg,wuffs_base__table_u8 primary_memory)4875 wuffs_base__pixel_buffer__set_from_table(wuffs_base__pixel_buffer* pb,
4876                                          const wuffs_base__pixel_config* pixcfg,
4877                                          wuffs_base__table_u8 primary_memory) {
4878   if (!pb) {
4879     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
4880   }
4881   memset(pb, 0, sizeof(*pb));
4882   if (!pixcfg ||
4883       wuffs_base__pixel_format__is_indexed(&pixcfg->private_impl.pixfmt) ||
4884       wuffs_base__pixel_format__is_planar(&pixcfg->private_impl.pixfmt)) {
4885     return wuffs_base__make_status(wuffs_base__error__bad_argument);
4886   }
4887   uint32_t bits_per_pixel =
4888       wuffs_base__pixel_format__bits_per_pixel(&pixcfg->private_impl.pixfmt);
4889   if ((bits_per_pixel == 0) || ((bits_per_pixel % 8) != 0)) {
4890     // TODO: support fraction-of-byte pixels, e.g. 1 bit per pixel?
4891     return wuffs_base__make_status(wuffs_base__error__unsupported_option);
4892   }
4893   uint64_t bytes_per_pixel = bits_per_pixel / 8;
4894 
4895   uint64_t width_in_bytes =
4896       ((uint64_t)pixcfg->private_impl.width) * bytes_per_pixel;
4897   if ((width_in_bytes > primary_memory.width) ||
4898       (pixcfg->private_impl.height > primary_memory.height)) {
4899     return wuffs_base__make_status(wuffs_base__error__bad_argument);
4900   }
4901 
4902   pb->pixcfg = *pixcfg;
4903   pb->private_impl.planes[0] = primary_memory;
4904   return wuffs_base__make_status(NULL);
4905 }
4906 
4907 // wuffs_base__pixel_buffer__palette returns the palette color data. If
4908 // non-empty, it will have length
4909 // WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH.
4910 static inline wuffs_base__slice_u8  //
wuffs_base__pixel_buffer__palette(wuffs_base__pixel_buffer * pb)4911 wuffs_base__pixel_buffer__palette(wuffs_base__pixel_buffer* pb) {
4912   if (pb &&
4913       wuffs_base__pixel_format__is_indexed(&pb->pixcfg.private_impl.pixfmt)) {
4914     wuffs_base__table_u8* tab =
4915         &pb->private_impl
4916              .planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE];
4917     if ((tab->width ==
4918          WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) &&
4919         (tab->height == 1)) {
4920       return wuffs_base__make_slice_u8(
4921           tab->ptr, WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH);
4922     }
4923   }
4924   return wuffs_base__make_slice_u8(NULL, 0);
4925 }
4926 
4927 static inline wuffs_base__slice_u8  //
wuffs_base__pixel_buffer__palette_or_else(wuffs_base__pixel_buffer * pb,wuffs_base__slice_u8 fallback)4928 wuffs_base__pixel_buffer__palette_or_else(wuffs_base__pixel_buffer* pb,
4929                                           wuffs_base__slice_u8 fallback) {
4930   if (pb &&
4931       wuffs_base__pixel_format__is_indexed(&pb->pixcfg.private_impl.pixfmt)) {
4932     wuffs_base__table_u8* tab =
4933         &pb->private_impl
4934              .planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE];
4935     if ((tab->width ==
4936          WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) &&
4937         (tab->height == 1)) {
4938       return wuffs_base__make_slice_u8(
4939           tab->ptr, WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH);
4940     }
4941   }
4942   return fallback;
4943 }
4944 
4945 static inline wuffs_base__pixel_format  //
wuffs_base__pixel_buffer__pixel_format(const wuffs_base__pixel_buffer * pb)4946 wuffs_base__pixel_buffer__pixel_format(const wuffs_base__pixel_buffer* pb) {
4947   if (pb) {
4948     return pb->pixcfg.private_impl.pixfmt;
4949   }
4950   return wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__INVALID);
4951 }
4952 
4953 static inline wuffs_base__table_u8  //
wuffs_base__pixel_buffer__plane(wuffs_base__pixel_buffer * pb,uint32_t p)4954 wuffs_base__pixel_buffer__plane(wuffs_base__pixel_buffer* pb, uint32_t p) {
4955   if (pb && (p < WUFFS_BASE__PIXEL_FORMAT__NUM_PLANES_MAX)) {
4956     return pb->private_impl.planes[p];
4957   }
4958 
4959   wuffs_base__table_u8 ret;
4960   ret.ptr = NULL;
4961   ret.width = 0;
4962   ret.height = 0;
4963   ret.stride = 0;
4964   return ret;
4965 }
4966 
4967 WUFFS_BASE__MAYBE_STATIC wuffs_base__color_u32_argb_premul  //
4968 wuffs_base__pixel_buffer__color_u32_at(const wuffs_base__pixel_buffer* pb,
4969                                        uint32_t x,
4970                                        uint32_t y);
4971 
4972 WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
4973 wuffs_base__pixel_buffer__set_color_u32_at(
4974     wuffs_base__pixel_buffer* pb,
4975     uint32_t x,
4976     uint32_t y,
4977     wuffs_base__color_u32_argb_premul color);
4978 
4979 WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
4980 wuffs_base__pixel_buffer__set_color_u32_fill_rect(
4981     wuffs_base__pixel_buffer* pb,
4982     wuffs_base__rect_ie_u32 rect,
4983     wuffs_base__color_u32_argb_premul color);
4984 
4985 #ifdef __cplusplus
4986 
4987 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)4988 wuffs_base__pixel_buffer::set_interleaved(
4989     const wuffs_base__pixel_config* pixcfg_arg,
4990     wuffs_base__table_u8 primary_memory,
4991     wuffs_base__slice_u8 palette_memory) {
4992   return wuffs_base__pixel_buffer__set_interleaved(
4993       this, pixcfg_arg, primary_memory, palette_memory);
4994 }
4995 
4996 inline wuffs_base__status  //
set_from_slice(const wuffs_base__pixel_config * pixcfg_arg,wuffs_base__slice_u8 pixbuf_memory)4997 wuffs_base__pixel_buffer::set_from_slice(
4998     const wuffs_base__pixel_config* pixcfg_arg,
4999     wuffs_base__slice_u8 pixbuf_memory) {
5000   return wuffs_base__pixel_buffer__set_from_slice(this, pixcfg_arg,
5001                                                   pixbuf_memory);
5002 }
5003 
5004 inline wuffs_base__status  //
set_from_table(const wuffs_base__pixel_config * pixcfg_arg,wuffs_base__table_u8 primary_memory)5005 wuffs_base__pixel_buffer::set_from_table(
5006     const wuffs_base__pixel_config* pixcfg_arg,
5007     wuffs_base__table_u8 primary_memory) {
5008   return wuffs_base__pixel_buffer__set_from_table(this, pixcfg_arg,
5009                                                   primary_memory);
5010 }
5011 
5012 inline wuffs_base__slice_u8  //
palette()5013 wuffs_base__pixel_buffer::palette() {
5014   return wuffs_base__pixel_buffer__palette(this);
5015 }
5016 
5017 inline wuffs_base__slice_u8  //
palette_or_else(wuffs_base__slice_u8 fallback)5018 wuffs_base__pixel_buffer::palette_or_else(wuffs_base__slice_u8 fallback) {
5019   return wuffs_base__pixel_buffer__palette_or_else(this, fallback);
5020 }
5021 
5022 inline wuffs_base__pixel_format  //
pixel_format()5023 wuffs_base__pixel_buffer::pixel_format() const {
5024   return wuffs_base__pixel_buffer__pixel_format(this);
5025 }
5026 
5027 inline wuffs_base__table_u8  //
plane(uint32_t p)5028 wuffs_base__pixel_buffer::plane(uint32_t p) {
5029   return wuffs_base__pixel_buffer__plane(this, p);
5030 }
5031 
5032 inline wuffs_base__color_u32_argb_premul  //
color_u32_at(uint32_t x,uint32_t y)5033 wuffs_base__pixel_buffer::color_u32_at(uint32_t x, uint32_t y) const {
5034   return wuffs_base__pixel_buffer__color_u32_at(this, x, y);
5035 }
5036 
5037 WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
5038 wuffs_base__pixel_buffer__set_color_u32_fill_rect(
5039     wuffs_base__pixel_buffer* pb,
5040     wuffs_base__rect_ie_u32 rect,
5041     wuffs_base__color_u32_argb_premul color);
5042 
5043 inline wuffs_base__status  //
set_color_u32_at(uint32_t x,uint32_t y,wuffs_base__color_u32_argb_premul color)5044 wuffs_base__pixel_buffer::set_color_u32_at(
5045     uint32_t x,
5046     uint32_t y,
5047     wuffs_base__color_u32_argb_premul color) {
5048   return wuffs_base__pixel_buffer__set_color_u32_at(this, x, y, color);
5049 }
5050 
5051 inline wuffs_base__status  //
set_color_u32_fill_rect(wuffs_base__rect_ie_u32 rect,wuffs_base__color_u32_argb_premul color)5052 wuffs_base__pixel_buffer::set_color_u32_fill_rect(
5053     wuffs_base__rect_ie_u32 rect,
5054     wuffs_base__color_u32_argb_premul color) {
5055   return wuffs_base__pixel_buffer__set_color_u32_fill_rect(this, rect, color);
5056 }
5057 
5058 #endif  // __cplusplus
5059 
5060 // --------
5061 
5062 typedef struct wuffs_base__decode_frame_options__struct {
5063   // Do not access the private_impl's fields directly. There is no API/ABI
5064   // compatibility or safety guarantee if you do so.
5065   struct {
5066     uint8_t TODO;
5067   } private_impl;
5068 
5069 #ifdef __cplusplus
5070 #endif  // __cplusplus
5071 
5072 } wuffs_base__decode_frame_options;
5073 
5074 #ifdef __cplusplus
5075 
5076 #endif  // __cplusplus
5077 
5078 // --------
5079 
5080 // wuffs_base__pixel_palette__closest_element returns the index of the palette
5081 // element that minimizes the sum of squared differences of the four ARGB
5082 // channels, working in premultiplied alpha. Ties favor the smaller index.
5083 //
5084 // The palette_slice.len may equal (N*4), for N less than 256, which means that
5085 // only the first N palette elements are considered. It returns 0 when N is 0.
5086 //
5087 // Applying this function on a per-pixel basis will not produce whole-of-image
5088 // dithering.
5089 WUFFS_BASE__MAYBE_STATIC uint8_t  //
5090 wuffs_base__pixel_palette__closest_element(
5091     wuffs_base__slice_u8 palette_slice,
5092     wuffs_base__pixel_format palette_format,
5093     wuffs_base__color_u32_argb_premul c);
5094 
5095 // --------
5096 
5097 // TODO: should the func type take restrict pointers?
5098 typedef uint64_t (*wuffs_base__pixel_swizzler__func)(uint8_t* dst_ptr,
5099                                                      size_t dst_len,
5100                                                      uint8_t* dst_palette_ptr,
5101                                                      size_t dst_palette_len,
5102                                                      const uint8_t* src_ptr,
5103                                                      size_t src_len);
5104 
5105 typedef uint64_t (*wuffs_base__pixel_swizzler__transparent_black_func)(
5106     uint8_t* dst_ptr,
5107     size_t dst_len,
5108     uint8_t* dst_palette_ptr,
5109     size_t dst_palette_len,
5110     uint64_t num_pixels,
5111     uint32_t dst_pixfmt_bytes_per_pixel);
5112 
5113 typedef struct wuffs_base__pixel_swizzler__struct {
5114   // Do not access the private_impl's fields directly. There is no API/ABI
5115   // compatibility or safety guarantee if you do so.
5116   struct {
5117     wuffs_base__pixel_swizzler__func func;
5118     wuffs_base__pixel_swizzler__transparent_black_func transparent_black_func;
5119     uint32_t dst_pixfmt_bytes_per_pixel;
5120     uint32_t src_pixfmt_bytes_per_pixel;
5121   } private_impl;
5122 
5123 #ifdef __cplusplus
5124   inline wuffs_base__status prepare(wuffs_base__pixel_format dst_pixfmt,
5125                                     wuffs_base__slice_u8 dst_palette,
5126                                     wuffs_base__pixel_format src_pixfmt,
5127                                     wuffs_base__slice_u8 src_palette,
5128                                     wuffs_base__pixel_blend blend);
5129   inline uint64_t swizzle_interleaved_from_slice(
5130       wuffs_base__slice_u8 dst,
5131       wuffs_base__slice_u8 dst_palette,
5132       wuffs_base__slice_u8 src) const;
5133 #endif  // __cplusplus
5134 
5135 } wuffs_base__pixel_swizzler;
5136 
5137 // wuffs_base__pixel_swizzler__prepare readies the pixel swizzler so that its
5138 // other methods may be called.
5139 //
5140 // For modular builds that divide the base module into sub-modules, using this
5141 // function requires the WUFFS_CONFIG__MODULE__BASE__PIXCONV sub-module, not
5142 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5143 WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
5144 wuffs_base__pixel_swizzler__prepare(wuffs_base__pixel_swizzler* p,
5145                                     wuffs_base__pixel_format dst_pixfmt,
5146                                     wuffs_base__slice_u8 dst_palette,
5147                                     wuffs_base__pixel_format src_pixfmt,
5148                                     wuffs_base__slice_u8 src_palette,
5149                                     wuffs_base__pixel_blend blend);
5150 
5151 // wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice converts pixels
5152 // from a source format to a destination format.
5153 //
5154 // For modular builds that divide the base module into sub-modules, using this
5155 // function requires the WUFFS_CONFIG__MODULE__BASE__PIXCONV sub-module, not
5156 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5157 WUFFS_BASE__MAYBE_STATIC uint64_t  //
5158 wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(
5159     const wuffs_base__pixel_swizzler* p,
5160     wuffs_base__slice_u8 dst,
5161     wuffs_base__slice_u8 dst_palette,
5162     wuffs_base__slice_u8 src);
5163 
5164 #ifdef __cplusplus
5165 
5166 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)5167 wuffs_base__pixel_swizzler::prepare(wuffs_base__pixel_format dst_pixfmt,
5168                                     wuffs_base__slice_u8 dst_palette,
5169                                     wuffs_base__pixel_format src_pixfmt,
5170                                     wuffs_base__slice_u8 src_palette,
5171                                     wuffs_base__pixel_blend blend) {
5172   return wuffs_base__pixel_swizzler__prepare(this, dst_pixfmt, dst_palette,
5173                                              src_pixfmt, src_palette, blend);
5174 }
5175 
5176 uint64_t  //
swizzle_interleaved_from_slice(wuffs_base__slice_u8 dst,wuffs_base__slice_u8 dst_palette,wuffs_base__slice_u8 src)5177 wuffs_base__pixel_swizzler::swizzle_interleaved_from_slice(
5178     wuffs_base__slice_u8 dst,
5179     wuffs_base__slice_u8 dst_palette,
5180     wuffs_base__slice_u8 src) const {
5181   return wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(
5182       this, dst, dst_palette, src);
5183 }
5184 
5185 #endif  // __cplusplus
5186 
5187 // ---------------- String Conversions
5188 
5189 // Options (bitwise or'ed together) for wuffs_base__parse_number_xxx
5190 // functions. The XXX options apply to both integer and floating point. The FXX
5191 // options apply only to floating point.
5192 
5193 #define WUFFS_BASE__PARSE_NUMBER_XXX__DEFAULT_OPTIONS ((uint32_t)0x00000000)
5194 
5195 // WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_MULTIPLE_LEADING_ZEROES means to accept
5196 // inputs like "00", "0644" and "00.7". By default, they are rejected.
5197 #define WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_MULTIPLE_LEADING_ZEROES \
5198   ((uint32_t)0x00000001)
5199 
5200 // WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES means to accept inputs like
5201 // "1__2" and "_3.141_592". By default, they are rejected.
5202 #define WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES ((uint32_t)0x00000002)
5203 
5204 // WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA means to accept
5205 // "1,5" and not "1.5" as one-and-a-half.
5206 //
5207 // If the caller wants to accept either, it is responsible for canonicalizing
5208 // the input before calling wuffs_base__parse_number_fxx. The caller also has
5209 // more context on e.g. exactly how to treat something like "$1,234".
5210 #define WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA \
5211   ((uint32_t)0x00000010)
5212 
5213 // WUFFS_BASE__PARSE_NUMBER_FXX__REJECT_INF_AND_NAN means to reject inputs that
5214 // would lead to infinite or Not-a-Number floating point values. By default,
5215 // they are accepted.
5216 //
5217 // This affects the literal "inf" as input, but also affects inputs like
5218 // "1e999" that would overflow double-precision floating point.
5219 #define WUFFS_BASE__PARSE_NUMBER_FXX__REJECT_INF_AND_NAN ((uint32_t)0x00000020)
5220 
5221 // --------
5222 
5223 // Options (bitwise or'ed together) for wuffs_base__render_number_xxx
5224 // functions. The XXX options apply to both integer and floating point. The FXX
5225 // options apply only to floating point.
5226 
5227 #define WUFFS_BASE__RENDER_NUMBER_XXX__DEFAULT_OPTIONS ((uint32_t)0x00000000)
5228 
5229 // WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT means to render to the right side
5230 // (higher indexes) of the destination slice, leaving any untouched bytes on
5231 // the left side (lower indexes). The default is vice versa: rendering on the
5232 // left with slack on the right.
5233 #define WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT ((uint32_t)0x00000100)
5234 
5235 // WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN means to render the leading
5236 // "+" for non-negative numbers: "+0" and "+12.3" instead of "0" and "12.3".
5237 #define WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN ((uint32_t)0x00000200)
5238 
5239 // WUFFS_BASE__RENDER_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA means to render
5240 // one-and-a-half as "1,5" instead of "1.5".
5241 #define WUFFS_BASE__RENDER_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA \
5242   ((uint32_t)0x00001000)
5243 
5244 // WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_ETC means whether to never
5245 // (EXPONENT_ABSENT, equivalent to printf's "%f") or to always
5246 // (EXPONENT_PRESENT, equivalent to printf's "%e") render a floating point
5247 // number as "1.23e+05" instead of "123000".
5248 //
5249 // Having both bits set is the same has having neither bit set, where the
5250 // notation used depends on whether the exponent is sufficiently large: "0.5"
5251 // is preferred over "5e-01" but "5e-09" is preferred over "0.000000005".
5252 #define WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_ABSENT ((uint32_t)0x00002000)
5253 #define WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_PRESENT ((uint32_t)0x00004000)
5254 
5255 // WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION means to render the
5256 // smallest number of digits so that parsing the resultant string will recover
5257 // the same double-precision floating point number.
5258 //
5259 // For example, double-precision cannot distinguish between 0.3 and
5260 // 0.299999999999999988897769753748434595763683319091796875, so when this bit
5261 // is set, rendering the latter will produce "0.3" but rendering
5262 // 0.3000000000000000444089209850062616169452667236328125 will produce
5263 // "0.30000000000000004".
5264 #define WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION \
5265   ((uint32_t)0x00008000)
5266 
5267 // ---------------- IEEE 754 Floating Point
5268 
5269 // wuffs_base__ieee_754_bit_representation__etc converts between a double
5270 // precision numerical value and its IEEE 754 representations:
5271 //  - 16-bit: 1 sign bit,  5 exponent bits, 10 explicit significand bits.
5272 //  - 32-bit: 1 sign bit,  8 exponent bits, 23 explicit significand bits.
5273 //  - 64-bit: 1 sign bit, 11 exponent bits, 52 explicit significand bits.
5274 //
5275 // For example, it converts between:
5276 //  - +1.0 and 0x3C00, 0x3F80_0000 or 0x3FF0_0000_0000_0000.
5277 //  - +5.5 and 0x4580, 0x40B0_0000 or 0x4016_0000_0000_0000.
5278 //  - -inf and 0xFC00, 0xFF80_0000 or 0xFFF0_0000_0000_0000.
5279 //
5280 // Converting from f64 to shorter formats (f16 or f32, represented in C as
5281 // uint16_t and uint32_t) may be lossy. Such functions have names that look
5282 // like etc_truncate, as converting finite numbers produce equal or smaller
5283 // (closer-to-zero) finite numbers. For example, 1048576.0 is a perfectly valid
5284 // f64 number, but converting it to a f16 (with truncation) produces 65504.0,
5285 // the largest finite f16 number. Truncating a f64-typed value d to f32 does
5286 // not always produce the same result as the C-style cast ((float)d), as
5287 // casting can convert from finite numbers to infinite ones.
5288 //
5289 // Converting infinities or NaNs produces infinities or NaNs and always report
5290 // no loss, even though there a multiple NaN representations so that round-
5291 // tripping a f64-typed NaN may produce a different 64 bits. Nonetheless, the
5292 // etc_truncate functions preserve a NaN's "quiet vs signaling" bit.
5293 //
5294 // See https://en.wikipedia.org/wiki/Double-precision_floating-point_format
5295 
5296 typedef struct wuffs_base__lossy_value_u16__struct {
5297   uint16_t value;
5298   bool lossy;
5299 } wuffs_base__lossy_value_u16;
5300 
5301 typedef struct wuffs_base__lossy_value_u32__struct {
5302   uint32_t value;
5303   bool lossy;
5304 } wuffs_base__lossy_value_u32;
5305 
5306 WUFFS_BASE__MAYBE_STATIC wuffs_base__lossy_value_u16  //
5307 wuffs_base__ieee_754_bit_representation__from_f64_to_u16_truncate(double f);
5308 
5309 WUFFS_BASE__MAYBE_STATIC wuffs_base__lossy_value_u32  //
5310 wuffs_base__ieee_754_bit_representation__from_f64_to_u32_truncate(double f);
5311 
5312 static inline uint64_t  //
wuffs_base__ieee_754_bit_representation__from_f64_to_u64(double f)5313 wuffs_base__ieee_754_bit_representation__from_f64_to_u64(double f) {
5314   uint64_t u = 0;
5315   if (sizeof(uint64_t) == sizeof(double)) {
5316     memcpy(&u, &f, sizeof(uint64_t));
5317   }
5318   return u;
5319 }
5320 
5321 static inline double  //
wuffs_base__ieee_754_bit_representation__from_u16_to_f64(uint16_t u)5322 wuffs_base__ieee_754_bit_representation__from_u16_to_f64(uint16_t u) {
5323   uint64_t v = ((uint64_t)(u & 0x8000)) << 48;
5324 
5325   do {
5326     uint64_t exp = (u >> 10) & 0x1F;
5327     uint64_t man = u & 0x3FF;
5328     if (exp == 0x1F) {  // Infinity or NaN.
5329       exp = 2047;
5330     } else if (exp != 0) {  // Normal.
5331       exp += 1008;          // 1008 = 1023 - 15, the difference in biases.
5332     } else if (man != 0) {  // Subnormal but non-zero.
5333       uint32_t clz = wuffs_base__count_leading_zeroes_u64(man);
5334       exp = 1062 - clz;  // 1062 = 1008 + 64 - 10.
5335       man = 0x3FF & (man << (clz - 53));
5336     } else {  // Zero.
5337       break;
5338     }
5339     v |= (exp << 52) | (man << 42);
5340   } while (0);
5341 
5342   double f = 0;
5343   if (sizeof(uint64_t) == sizeof(double)) {
5344     memcpy(&f, &v, sizeof(uint64_t));
5345   }
5346   return f;
5347 }
5348 
5349 static inline double  //
wuffs_base__ieee_754_bit_representation__from_u32_to_f64(uint32_t u)5350 wuffs_base__ieee_754_bit_representation__from_u32_to_f64(uint32_t u) {
5351   float f = 0;
5352   if (sizeof(uint32_t) == sizeof(float)) {
5353     memcpy(&f, &u, sizeof(uint32_t));
5354   }
5355   return (double)f;
5356 }
5357 
5358 static inline double  //
wuffs_base__ieee_754_bit_representation__from_u64_to_f64(uint64_t u)5359 wuffs_base__ieee_754_bit_representation__from_u64_to_f64(uint64_t u) {
5360   double f = 0;
5361   if (sizeof(uint64_t) == sizeof(double)) {
5362     memcpy(&f, &u, sizeof(uint64_t));
5363   }
5364   return f;
5365 }
5366 
5367 // ---------------- Parsing and Rendering Numbers
5368 
5369 // wuffs_base__parse_number_f64 parses the floating point number in s. For
5370 // example, if s contains the bytes "1.5" then it will return the double 1.5.
5371 //
5372 // It returns an error if s does not contain a floating point number.
5373 //
5374 // It does not necessarily return an error if the conversion is lossy, e.g. if
5375 // s is "0.3", which double-precision floating point cannot represent exactly.
5376 //
5377 // Similarly, the returned value may be infinite (and no error returned) even
5378 // if s was not "inf", when the input is nominally finite but sufficiently
5379 // larger than DBL_MAX, about 1.8e+308.
5380 //
5381 // It is similar to the C standard library's strtod function, but:
5382 //  - Errors are returned in-band (in a result type), not out-of-band (errno).
5383 //  - It takes a slice (a pointer and length), not a NUL-terminated C string.
5384 //  - It does not take an optional endptr argument. It does not allow a partial
5385 //    parse: it returns an error unless all of s is consumed.
5386 //  - It does not allow whitespace, leading or otherwise.
5387 //  - It does not allow hexadecimal floating point numbers.
5388 //  - It is not affected by i18n / l10n settings such as environment variables.
5389 //
5390 // The options argument can change these, but by default, it:
5391 //  - Allows "inf", "+Infinity" and "-NAN", case insensitive. Similarly,
5392 //    without an explicit opt-out, it would successfully parse "1e999" as
5393 //    infinity, even though it overflows double-precision floating point.
5394 //  - Rejects underscores. With an explicit opt-in, "_3.141_592" would
5395 //    successfully parse as an approximation to π.
5396 //  - Rejects unnecessary leading zeroes: "00", "0644" and "00.7".
5397 //  - Uses a dot '1.5' instead of a comma '1,5' for the decimal separator.
5398 //
5399 // For modular builds that divide the base module into sub-modules, using this
5400 // function requires the WUFFS_CONFIG__MODULE__BASE__FLOATCONV sub-module, not
5401 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5402 WUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64  //
5403 wuffs_base__parse_number_f64(wuffs_base__slice_u8 s, uint32_t options);
5404 
5405 // wuffs_base__parse_number_i64 parses the ASCII integer in s. For example, if
5406 // s contains the bytes "-123" then it will return the int64_t -123.
5407 //
5408 // It returns an error if s does not contain an integer or if the integer
5409 // within would overflow an int64_t.
5410 //
5411 // It is similar to wuffs_base__parse_number_u64 but it returns a signed
5412 // integer, not an unsigned integer. It also allows a leading '+' or '-'.
5413 //
5414 // For modular builds that divide the base module into sub-modules, using this
5415 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5416 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5417 WUFFS_BASE__MAYBE_STATIC wuffs_base__result_i64  //
5418 wuffs_base__parse_number_i64(wuffs_base__slice_u8 s, uint32_t options);
5419 
5420 // wuffs_base__parse_number_u64 parses the ASCII integer in s. For example, if
5421 // s contains the bytes "123" then it will return the uint64_t 123.
5422 //
5423 // It returns an error if s does not contain an integer or if the integer
5424 // within would overflow a uint64_t.
5425 //
5426 // It is similar to the C standard library's strtoull function, but:
5427 //  - Errors are returned in-band (in a result type), not out-of-band (errno).
5428 //  - It takes a slice (a pointer and length), not a NUL-terminated C string.
5429 //  - It does not take an optional endptr argument. It does not allow a partial
5430 //    parse: it returns an error unless all of s is consumed.
5431 //  - It does not allow whitespace, leading or otherwise.
5432 //  - It does not allow a leading '+' or '-'.
5433 //  - It does not take a base argument (e.g. base 10 vs base 16). Instead, it
5434 //    always accepts both decimal (e.g "1234", "0d5678") and hexadecimal (e.g.
5435 //    "0x9aBC"). The caller is responsible for prior filtering of e.g. hex
5436 //    numbers if they are unwanted. For example, Wuffs' JSON decoder will only
5437 //    produce a wuffs_base__token for decimal numbers, not hexadecimal.
5438 //  - It is not affected by i18n / l10n settings such as environment variables.
5439 //
5440 // The options argument can change these, but by default, it:
5441 //  - Rejects underscores. With an explicit opt-in, "__0D_1_002" would
5442 //    successfully parse as "one thousand and two". Underscores are still
5443 //    rejected inside the optional 2-byte opening "0d" or "0X" that denotes
5444 //    base-10 or base-16.
5445 //  - Rejects unnecessary leading zeroes: "00" and "0644".
5446 //
5447 // For modular builds that divide the base module into sub-modules, using this
5448 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5449 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5450 WUFFS_BASE__MAYBE_STATIC wuffs_base__result_u64  //
5451 wuffs_base__parse_number_u64(wuffs_base__slice_u8 s, uint32_t options);
5452 
5453 // --------
5454 
5455 // WUFFS_BASE__I64__BYTE_LENGTH__MAX_INCL is the string length of
5456 // "-9223372036854775808" and "+9223372036854775807", INT64_MIN and INT64_MAX.
5457 #define WUFFS_BASE__I64__BYTE_LENGTH__MAX_INCL 20
5458 
5459 // WUFFS_BASE__U64__BYTE_LENGTH__MAX_INCL is the string length of
5460 // "+18446744073709551615", UINT64_MAX.
5461 #define WUFFS_BASE__U64__BYTE_LENGTH__MAX_INCL 21
5462 
5463 // wuffs_base__render_number_f64 writes the decimal encoding of x to dst and
5464 // returns the number of bytes written. If dst is shorter than the entire
5465 // encoding, it returns 0 (and no bytes are written).
5466 //
5467 // For those familiar with C's printf or Go's fmt.Printf functions:
5468 //  - "%e" means the WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_PRESENT option.
5469 //  - "%f" means the WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_ABSENT  option.
5470 //  - "%g" means neither or both bits are set.
5471 //
5472 // The precision argument controls the number of digits rendered, excluding the
5473 // exponent (the "e+05" in "1.23e+05"):
5474 //  - for "%e" and "%f" it is the number of digits after the decimal separator,
5475 //  - for "%g" it is the number of significant digits (and trailing zeroes are
5476 //    removed).
5477 //
5478 // A precision of 6 gives similar output to printf's defaults.
5479 //
5480 // A precision greater than 4095 is equivalent to 4095.
5481 //
5482 // The precision argument is ignored when the
5483 // WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION option is set. This is
5484 // similar to Go's strconv.FormatFloat with a negative (i.e. non-sensical)
5485 // precision, but there is no corresponding feature in C's printf.
5486 //
5487 // Extreme values of x will be rendered as "NaN", "Inf" (or "+Inf" if the
5488 // WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN option is set) or "-Inf".
5489 //
5490 // For modular builds that divide the base module into sub-modules, using this
5491 // function requires the WUFFS_CONFIG__MODULE__BASE__FLOATCONV sub-module, not
5492 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5493 WUFFS_BASE__MAYBE_STATIC size_t  //
5494 wuffs_base__render_number_f64(wuffs_base__slice_u8 dst,
5495                               double x,
5496                               uint32_t precision,
5497                               uint32_t options);
5498 
5499 // wuffs_base__render_number_i64 writes the decimal encoding of x to dst and
5500 // returns the number of bytes written. If dst is shorter than the entire
5501 // encoding, it returns 0 (and no bytes are written).
5502 //
5503 // dst will never be too short if its length is at least 20, also known as
5504 // WUFFS_BASE__I64__BYTE_LENGTH__MAX_INCL.
5505 //
5506 // For modular builds that divide the base module into sub-modules, using this
5507 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5508 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5509 WUFFS_BASE__MAYBE_STATIC size_t  //
5510 wuffs_base__render_number_i64(wuffs_base__slice_u8 dst,
5511                               int64_t x,
5512                               uint32_t options);
5513 
5514 // wuffs_base__render_number_u64 writes the decimal encoding of x to dst and
5515 // returns the number of bytes written. If dst is shorter than the entire
5516 // encoding, it returns 0 (and no bytes are written).
5517 //
5518 // dst will never be too short if its length is at least 21, also known as
5519 // WUFFS_BASE__U64__BYTE_LENGTH__MAX_INCL.
5520 //
5521 // For modular builds that divide the base module into sub-modules, using this
5522 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5523 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5524 WUFFS_BASE__MAYBE_STATIC size_t  //
5525 wuffs_base__render_number_u64(wuffs_base__slice_u8 dst,
5526                               uint64_t x,
5527                               uint32_t options);
5528 
5529 // ---------------- Base-16
5530 
5531 // Options (bitwise or'ed together) for wuffs_base__base_16__xxx functions.
5532 
5533 #define WUFFS_BASE__BASE_16__DEFAULT_OPTIONS ((uint32_t)0x00000000)
5534 
5535 // wuffs_base__base_16__decode2 converts "6A6b" to "jk", where e.g. 'j' is
5536 // U+006A. There are 2 src bytes for every dst byte.
5537 //
5538 // It assumes that the src bytes are two hexadecimal digits (0-9, A-F, a-f),
5539 // repeated. It may write nonsense bytes if not, although it will not read or
5540 // write out of bounds.
5541 //
5542 // For modular builds that divide the base module into sub-modules, using this
5543 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5544 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5545 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output  //
5546 wuffs_base__base_16__decode2(wuffs_base__slice_u8 dst,
5547                              wuffs_base__slice_u8 src,
5548                              bool src_closed,
5549                              uint32_t options);
5550 
5551 // wuffs_base__base_16__decode4 converts both "\\x6A\\x6b" and "??6a??6B" to
5552 // "jk", where e.g. 'j' is U+006A. There are 4 src bytes for every dst byte.
5553 //
5554 // It assumes that the src bytes are two ignored bytes and then two hexadecimal
5555 // digits (0-9, A-F, a-f), repeated. It may write nonsense bytes if not,
5556 // although it will not read or write out of bounds.
5557 //
5558 // For modular builds that divide the base module into sub-modules, using this
5559 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5560 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5561 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output  //
5562 wuffs_base__base_16__decode4(wuffs_base__slice_u8 dst,
5563                              wuffs_base__slice_u8 src,
5564                              bool src_closed,
5565                              uint32_t options);
5566 
5567 // wuffs_base__base_16__encode2 converts "jk" to "6A6B", where e.g. 'j' is
5568 // U+006A. There are 2 dst bytes for every src byte.
5569 //
5570 // For modular builds that divide the base module into sub-modules, using this
5571 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5572 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5573 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output  //
5574 wuffs_base__base_16__encode2(wuffs_base__slice_u8 dst,
5575                              wuffs_base__slice_u8 src,
5576                              bool src_closed,
5577                              uint32_t options);
5578 
5579 // wuffs_base__base_16__encode4 converts "jk" to "\\x6A\\x6B", where e.g. 'j'
5580 // is U+006A. There are 4 dst bytes for every src byte.
5581 //
5582 // For modular builds that divide the base module into sub-modules, using this
5583 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5584 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5585 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output  //
5586 wuffs_base__base_16__encode2(wuffs_base__slice_u8 dst,
5587                              wuffs_base__slice_u8 src,
5588                              bool src_closed,
5589                              uint32_t options);
5590 
5591 // ---------------- Base-64
5592 
5593 // Options (bitwise or'ed together) for wuffs_base__base_64__xxx functions.
5594 
5595 #define WUFFS_BASE__BASE_64__DEFAULT_OPTIONS ((uint32_t)0x00000000)
5596 
5597 // WUFFS_BASE__BASE_64__DECODE_ALLOW_PADDING means that, when decoding base-64,
5598 // the input may (but does not need to) be padded with '=' bytes so that the
5599 // overall encoded length in bytes is a multiple of 4. A successful decoding
5600 // will return a num_src that includes those padding bytes.
5601 //
5602 // Excess padding (e.g. three final '='s) will be rejected as bad data.
5603 #define WUFFS_BASE__BASE_64__DECODE_ALLOW_PADDING ((uint32_t)0x00000001)
5604 
5605 // WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING means that, when encoding base-64,
5606 // the output will be padded with '=' bytes so that the overall encoded length
5607 // in bytes is a multiple of 4.
5608 #define WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING ((uint32_t)0x00000002)
5609 
5610 // WUFFS_BASE__BASE_64__URL_ALPHABET means that, for base-64, the URL-friendly
5611 // and file-name-friendly alphabet be used, as per RFC 4648 section 5. When
5612 // this option bit is off, the standard alphabet from section 4 is used.
5613 #define WUFFS_BASE__BASE_64__URL_ALPHABET ((uint32_t)0x00000100)
5614 
5615 // wuffs_base__base_64__decode transforms base-64 encoded bytes from src to
5616 // arbitrary bytes in dst.
5617 //
5618 // It will not permit line breaks or other whitespace in src. Filtering those
5619 // out is the responsibility of the caller.
5620 //
5621 // For modular builds that divide the base module into sub-modules, using this
5622 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5623 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5624 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output  //
5625 wuffs_base__base_64__decode(wuffs_base__slice_u8 dst,
5626                             wuffs_base__slice_u8 src,
5627                             bool src_closed,
5628                             uint32_t options);
5629 
5630 // wuffs_base__base_64__encode transforms arbitrary bytes from src to base-64
5631 // encoded bytes in dst.
5632 //
5633 // For modular builds that divide the base module into sub-modules, using this
5634 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5635 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5636 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output  //
5637 wuffs_base__base_64__encode(wuffs_base__slice_u8 dst,
5638                             wuffs_base__slice_u8 src,
5639                             bool src_closed,
5640                             uint32_t options);
5641 
5642 // ---------------- Unicode and UTF-8
5643 
5644 #define WUFFS_BASE__UNICODE_CODE_POINT__MIN_INCL 0x00000000
5645 #define WUFFS_BASE__UNICODE_CODE_POINT__MAX_INCL 0x0010FFFF
5646 
5647 #define WUFFS_BASE__UNICODE_REPLACEMENT_CHARACTER 0x0000FFFD
5648 
5649 #define WUFFS_BASE__UNICODE_SURROGATE__MIN_INCL 0x0000D800
5650 #define WUFFS_BASE__UNICODE_SURROGATE__MAX_INCL 0x0000DFFF
5651 
5652 #define WUFFS_BASE__ASCII__MIN_INCL 0x00
5653 #define WUFFS_BASE__ASCII__MAX_INCL 0x7F
5654 
5655 #define WUFFS_BASE__UTF_8__BYTE_LENGTH__MIN_INCL 1
5656 #define WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL 4
5657 
5658 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_1__CODE_POINT__MIN_INCL 0x00000000
5659 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_1__CODE_POINT__MAX_INCL 0x0000007F
5660 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_2__CODE_POINT__MIN_INCL 0x00000080
5661 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_2__CODE_POINT__MAX_INCL 0x000007FF
5662 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_3__CODE_POINT__MIN_INCL 0x00000800
5663 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_3__CODE_POINT__MAX_INCL 0x0000FFFF
5664 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_4__CODE_POINT__MIN_INCL 0x00010000
5665 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_4__CODE_POINT__MAX_INCL 0x0010FFFF
5666 
5667 // --------
5668 
5669 // wuffs_base__utf_8__next__output is the type returned by
5670 // wuffs_base__utf_8__next.
5671 typedef struct wuffs_base__utf_8__next__output__struct {
5672   uint32_t code_point;
5673   uint32_t byte_length;
5674 
5675 #ifdef __cplusplus
5676   inline bool is_valid() const;
5677 #endif  // __cplusplus
5678 
5679 } wuffs_base__utf_8__next__output;
5680 
5681 static inline wuffs_base__utf_8__next__output  //
wuffs_base__make_utf_8__next__output(uint32_t code_point,uint32_t byte_length)5682 wuffs_base__make_utf_8__next__output(uint32_t code_point,
5683                                      uint32_t byte_length) {
5684   wuffs_base__utf_8__next__output ret;
5685   ret.code_point = code_point;
5686   ret.byte_length = byte_length;
5687   return ret;
5688 }
5689 
5690 static inline bool  //
wuffs_base__utf_8__next__output__is_valid(const wuffs_base__utf_8__next__output * o)5691 wuffs_base__utf_8__next__output__is_valid(
5692     const wuffs_base__utf_8__next__output* o) {
5693   if (o) {
5694     uint32_t cp = o->code_point;
5695     switch (o->byte_length) {
5696       case 1:
5697         return (cp <= 0x7F);
5698       case 2:
5699         return (0x080 <= cp) && (cp <= 0x7FF);
5700       case 3:
5701         // Avoid the 0xD800 ..= 0xDFFF surrogate range.
5702         return ((0x0800 <= cp) && (cp <= 0xD7FF)) ||
5703                ((0xE000 <= cp) && (cp <= 0xFFFF));
5704       case 4:
5705         return (0x00010000 <= cp) && (cp <= 0x0010FFFF);
5706     }
5707   }
5708   return false;
5709 }
5710 
5711 #ifdef __cplusplus
5712 
5713 inline bool  //
is_valid()5714 wuffs_base__utf_8__next__output::is_valid() const {
5715   return wuffs_base__utf_8__next__output__is_valid(this);
5716 }
5717 
5718 #endif  // __cplusplus
5719 
5720 // --------
5721 
5722 // wuffs_base__utf_8__encode writes the UTF-8 encoding of code_point to s and
5723 // returns the number of bytes written. If code_point is invalid, or if s is
5724 // shorter than the entire encoding, it returns 0 (and no bytes are written).
5725 //
5726 // s will never be too short if its length is at least 4, also known as
5727 // WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL.
5728 //
5729 // For modular builds that divide the base module into sub-modules, using this
5730 // function requires the WUFFS_CONFIG__MODULE__BASE__UTF8 sub-module, not just
5731 // WUFFS_CONFIG__MODULE__BASE__CORE.
5732 WUFFS_BASE__MAYBE_STATIC size_t  //
5733 wuffs_base__utf_8__encode(wuffs_base__slice_u8 dst, uint32_t code_point);
5734 
5735 // wuffs_base__utf_8__next returns the next UTF-8 code point (and that code
5736 // point's byte length) at the start of the read-only slice (s_ptr, s_len).
5737 //
5738 // There are exactly two cases in which this function returns something where
5739 // wuffs_base__utf_8__next__output__is_valid is false:
5740 //  - If s is empty then it returns {.code_point=0, .byte_length=0}.
5741 //  - If s is non-empty and starts with invalid UTF-8 then it returns
5742 //    {.code_point=WUFFS_BASE__UNICODE_REPLACEMENT_CHARACTER, .byte_length=1}.
5743 //
5744 // Otherwise, it returns something where
5745 // wuffs_base__utf_8__next__output__is_valid is true.
5746 //
5747 // In any case, it always returns an output that satisfies both of:
5748 //  - (output.code_point  <= WUFFS_BASE__UNICODE_CODE_POINT__MAX_INCL).
5749 //  - (output.byte_length <= s_len).
5750 //
5751 // If s is a sub-slice of a larger slice of valid UTF-8, but that sub-slice
5752 // boundary occurs in the middle of a multi-byte UTF-8 encoding of a single
5753 // code point, then this function may return something invalid. It is the
5754 // caller's responsibility to split on or otherwise manage UTF-8 boundaries.
5755 //
5756 // For modular builds that divide the base module into sub-modules, using this
5757 // function requires the WUFFS_CONFIG__MODULE__BASE__UTF8 sub-module, not just
5758 // WUFFS_CONFIG__MODULE__BASE__CORE.
5759 WUFFS_BASE__MAYBE_STATIC wuffs_base__utf_8__next__output  //
5760 wuffs_base__utf_8__next(const uint8_t* s_ptr, size_t s_len);
5761 
5762 // wuffs_base__utf_8__next_from_end is like wuffs_base__utf_8__next except that
5763 // it looks at the end of (s_ptr, s_len) instead of the start.
5764 //
5765 // For modular builds that divide the base module into sub-modules, using this
5766 // function requires the WUFFS_CONFIG__MODULE__BASE__UTF8 sub-module, not just
5767 // WUFFS_CONFIG__MODULE__BASE__CORE.
5768 WUFFS_BASE__MAYBE_STATIC wuffs_base__utf_8__next__output  //
5769 wuffs_base__utf_8__next_from_end(const uint8_t* s_ptr, size_t s_len);
5770 
5771 // wuffs_base__utf_8__longest_valid_prefix returns the largest n such that the
5772 // sub-slice s[..n] is valid UTF-8, where s is the read-only slice (s_ptr,
5773 // s_len).
5774 //
5775 // In particular, it returns s_len if and only if all of s is valid UTF-8.
5776 //
5777 // If s is a sub-slice of a larger slice of valid UTF-8, but that sub-slice
5778 // boundary occurs in the middle of a multi-byte UTF-8 encoding of a single
5779 // code point, then this function will return less than s_len. It is the
5780 // caller's responsibility to split on or otherwise manage UTF-8 boundaries.
5781 //
5782 // For modular builds that divide the base module into sub-modules, using this
5783 // function requires the WUFFS_CONFIG__MODULE__BASE__UTF8 sub-module, not just
5784 // WUFFS_CONFIG__MODULE__BASE__CORE.
5785 WUFFS_BASE__MAYBE_STATIC size_t  //
5786 wuffs_base__utf_8__longest_valid_prefix(const uint8_t* s_ptr, size_t s_len);
5787 
5788 // wuffs_base__ascii__longest_valid_prefix returns the largest n such that the
5789 // sub-slice s[..n] is valid ASCII, where s is the read-only slice (s_ptr,
5790 // s_len).
5791 //
5792 // In particular, it returns s_len if and only if all of s is valid ASCII.
5793 // Equivalently, when none of the bytes in s have the 0x80 high bit set.
5794 //
5795 // For modular builds that divide the base module into sub-modules, using this
5796 // function requires the WUFFS_CONFIG__MODULE__BASE__UTF8 sub-module, not just
5797 // WUFFS_CONFIG__MODULE__BASE__CORE.
5798 WUFFS_BASE__MAYBE_STATIC size_t  //
5799 wuffs_base__ascii__longest_valid_prefix(const uint8_t* s_ptr, size_t s_len);
5800 
5801 // ---------------- Interface Declarations.
5802 
5803 // For modular builds that divide the base module into sub-modules, using these
5804 // functions require the WUFFS_CONFIG__MODULE__BASE__INTERFACES sub-module, not
5805 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5806 
5807 // --------
5808 
5809 extern const char wuffs_base__hasher_u32__vtable_name[];
5810 
5811 typedef struct wuffs_base__hasher_u32__func_ptrs__struct {
5812   wuffs_base__empty_struct (*set_quirk_enabled)(
5813     void* self,
5814     uint32_t a_quirk,
5815     bool a_enabled);
5816   uint32_t (*update_u32)(
5817     void* self,
5818     wuffs_base__slice_u8 a_x);
5819 } wuffs_base__hasher_u32__func_ptrs;
5820 
5821 typedef struct wuffs_base__hasher_u32__struct wuffs_base__hasher_u32;
5822 
5823 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
5824 wuffs_base__hasher_u32__set_quirk_enabled(
5825     wuffs_base__hasher_u32* self,
5826     uint32_t a_quirk,
5827     bool a_enabled);
5828 
5829 WUFFS_BASE__MAYBE_STATIC uint32_t
5830 wuffs_base__hasher_u32__update_u32(
5831     wuffs_base__hasher_u32* self,
5832     wuffs_base__slice_u8 a_x);
5833 
5834 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
5835 
5836 struct wuffs_base__hasher_u32__struct {
5837   struct {
5838     uint32_t magic;
5839     uint32_t active_coroutine;
5840     wuffs_base__vtable first_vtable;
5841   } private_impl;
5842 
5843 #ifdef __cplusplus
5844 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
5845   using unique_ptr = std::unique_ptr<wuffs_base__hasher_u32, decltype(&free)>;
5846 #endif
5847 
5848   inline wuffs_base__empty_struct
set_quirk_enabledwuffs_base__hasher_u32__struct5849   set_quirk_enabled(
5850       uint32_t a_quirk,
5851       bool a_enabled) {
5852     return wuffs_base__hasher_u32__set_quirk_enabled(
5853         this, a_quirk, a_enabled);
5854   }
5855 
5856   inline uint32_t
update_u32wuffs_base__hasher_u32__struct5857   update_u32(
5858       wuffs_base__slice_u8 a_x) {
5859     return wuffs_base__hasher_u32__update_u32(
5860         this, a_x);
5861   }
5862 
5863 #endif  // __cplusplus
5864 };  // struct wuffs_base__hasher_u32__struct
5865 
5866 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
5867 
5868 // --------
5869 
5870 extern const char wuffs_base__image_decoder__vtable_name[];
5871 
5872 typedef struct wuffs_base__image_decoder__func_ptrs__struct {
5873   wuffs_base__status (*decode_frame)(
5874     void* self,
5875     wuffs_base__pixel_buffer* a_dst,
5876     wuffs_base__io_buffer* a_src,
5877     wuffs_base__pixel_blend a_blend,
5878     wuffs_base__slice_u8 a_workbuf,
5879     wuffs_base__decode_frame_options* a_opts);
5880   wuffs_base__status (*decode_frame_config)(
5881     void* self,
5882     wuffs_base__frame_config* a_dst,
5883     wuffs_base__io_buffer* a_src);
5884   wuffs_base__status (*decode_image_config)(
5885     void* self,
5886     wuffs_base__image_config* a_dst,
5887     wuffs_base__io_buffer* a_src);
5888   wuffs_base__rect_ie_u32 (*frame_dirty_rect)(
5889     const void* self);
5890   uint32_t (*num_animation_loops)(
5891     const void* self);
5892   uint64_t (*num_decoded_frame_configs)(
5893     const void* self);
5894   uint64_t (*num_decoded_frames)(
5895     const void* self);
5896   wuffs_base__status (*restart_frame)(
5897     void* self,
5898     uint64_t a_index,
5899     uint64_t a_io_position);
5900   wuffs_base__empty_struct (*set_quirk_enabled)(
5901     void* self,
5902     uint32_t a_quirk,
5903     bool a_enabled);
5904   wuffs_base__empty_struct (*set_report_metadata)(
5905     void* self,
5906     uint32_t a_fourcc,
5907     bool a_report);
5908   wuffs_base__status (*tell_me_more)(
5909     void* self,
5910     wuffs_base__io_buffer* a_dst,
5911     wuffs_base__more_information* a_minfo,
5912     wuffs_base__io_buffer* a_src);
5913   wuffs_base__range_ii_u64 (*workbuf_len)(
5914     const void* self);
5915 } wuffs_base__image_decoder__func_ptrs;
5916 
5917 typedef struct wuffs_base__image_decoder__struct wuffs_base__image_decoder;
5918 
5919 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
5920 wuffs_base__image_decoder__decode_frame(
5921     wuffs_base__image_decoder* self,
5922     wuffs_base__pixel_buffer* a_dst,
5923     wuffs_base__io_buffer* a_src,
5924     wuffs_base__pixel_blend a_blend,
5925     wuffs_base__slice_u8 a_workbuf,
5926     wuffs_base__decode_frame_options* a_opts);
5927 
5928 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
5929 wuffs_base__image_decoder__decode_frame_config(
5930     wuffs_base__image_decoder* self,
5931     wuffs_base__frame_config* a_dst,
5932     wuffs_base__io_buffer* a_src);
5933 
5934 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
5935 wuffs_base__image_decoder__decode_image_config(
5936     wuffs_base__image_decoder* self,
5937     wuffs_base__image_config* a_dst,
5938     wuffs_base__io_buffer* a_src);
5939 
5940 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
5941 wuffs_base__image_decoder__frame_dirty_rect(
5942     const wuffs_base__image_decoder* self);
5943 
5944 WUFFS_BASE__MAYBE_STATIC uint32_t
5945 wuffs_base__image_decoder__num_animation_loops(
5946     const wuffs_base__image_decoder* self);
5947 
5948 WUFFS_BASE__MAYBE_STATIC uint64_t
5949 wuffs_base__image_decoder__num_decoded_frame_configs(
5950     const wuffs_base__image_decoder* self);
5951 
5952 WUFFS_BASE__MAYBE_STATIC uint64_t
5953 wuffs_base__image_decoder__num_decoded_frames(
5954     const wuffs_base__image_decoder* self);
5955 
5956 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
5957 wuffs_base__image_decoder__restart_frame(
5958     wuffs_base__image_decoder* self,
5959     uint64_t a_index,
5960     uint64_t a_io_position);
5961 
5962 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
5963 wuffs_base__image_decoder__set_quirk_enabled(
5964     wuffs_base__image_decoder* self,
5965     uint32_t a_quirk,
5966     bool a_enabled);
5967 
5968 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
5969 wuffs_base__image_decoder__set_report_metadata(
5970     wuffs_base__image_decoder* self,
5971     uint32_t a_fourcc,
5972     bool a_report);
5973 
5974 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
5975 wuffs_base__image_decoder__tell_me_more(
5976     wuffs_base__image_decoder* self,
5977     wuffs_base__io_buffer* a_dst,
5978     wuffs_base__more_information* a_minfo,
5979     wuffs_base__io_buffer* a_src);
5980 
5981 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
5982 wuffs_base__image_decoder__workbuf_len(
5983     const wuffs_base__image_decoder* self);
5984 
5985 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
5986 
5987 struct wuffs_base__image_decoder__struct {
5988   struct {
5989     uint32_t magic;
5990     uint32_t active_coroutine;
5991     wuffs_base__vtable first_vtable;
5992   } private_impl;
5993 
5994 #ifdef __cplusplus
5995 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
5996   using unique_ptr = std::unique_ptr<wuffs_base__image_decoder, decltype(&free)>;
5997 #endif
5998 
5999   inline wuffs_base__status
decode_framewuffs_base__image_decoder__struct6000   decode_frame(
6001       wuffs_base__pixel_buffer* a_dst,
6002       wuffs_base__io_buffer* a_src,
6003       wuffs_base__pixel_blend a_blend,
6004       wuffs_base__slice_u8 a_workbuf,
6005       wuffs_base__decode_frame_options* a_opts) {
6006     return wuffs_base__image_decoder__decode_frame(
6007         this, a_dst, a_src, a_blend, a_workbuf, a_opts);
6008   }
6009 
6010   inline wuffs_base__status
decode_frame_configwuffs_base__image_decoder__struct6011   decode_frame_config(
6012       wuffs_base__frame_config* a_dst,
6013       wuffs_base__io_buffer* a_src) {
6014     return wuffs_base__image_decoder__decode_frame_config(
6015         this, a_dst, a_src);
6016   }
6017 
6018   inline wuffs_base__status
decode_image_configwuffs_base__image_decoder__struct6019   decode_image_config(
6020       wuffs_base__image_config* a_dst,
6021       wuffs_base__io_buffer* a_src) {
6022     return wuffs_base__image_decoder__decode_image_config(
6023         this, a_dst, a_src);
6024   }
6025 
6026   inline wuffs_base__rect_ie_u32
frame_dirty_rectwuffs_base__image_decoder__struct6027   frame_dirty_rect() const {
6028     return wuffs_base__image_decoder__frame_dirty_rect(this);
6029   }
6030 
6031   inline uint32_t
num_animation_loopswuffs_base__image_decoder__struct6032   num_animation_loops() const {
6033     return wuffs_base__image_decoder__num_animation_loops(this);
6034   }
6035 
6036   inline uint64_t
num_decoded_frame_configswuffs_base__image_decoder__struct6037   num_decoded_frame_configs() const {
6038     return wuffs_base__image_decoder__num_decoded_frame_configs(this);
6039   }
6040 
6041   inline uint64_t
num_decoded_frameswuffs_base__image_decoder__struct6042   num_decoded_frames() const {
6043     return wuffs_base__image_decoder__num_decoded_frames(this);
6044   }
6045 
6046   inline wuffs_base__status
restart_framewuffs_base__image_decoder__struct6047   restart_frame(
6048       uint64_t a_index,
6049       uint64_t a_io_position) {
6050     return wuffs_base__image_decoder__restart_frame(
6051         this, a_index, a_io_position);
6052   }
6053 
6054   inline wuffs_base__empty_struct
set_quirk_enabledwuffs_base__image_decoder__struct6055   set_quirk_enabled(
6056       uint32_t a_quirk,
6057       bool a_enabled) {
6058     return wuffs_base__image_decoder__set_quirk_enabled(
6059         this, a_quirk, a_enabled);
6060   }
6061 
6062   inline wuffs_base__empty_struct
set_report_metadatawuffs_base__image_decoder__struct6063   set_report_metadata(
6064       uint32_t a_fourcc,
6065       bool a_report) {
6066     return wuffs_base__image_decoder__set_report_metadata(
6067         this, a_fourcc, a_report);
6068   }
6069 
6070   inline wuffs_base__status
tell_me_morewuffs_base__image_decoder__struct6071   tell_me_more(
6072       wuffs_base__io_buffer* a_dst,
6073       wuffs_base__more_information* a_minfo,
6074       wuffs_base__io_buffer* a_src) {
6075     return wuffs_base__image_decoder__tell_me_more(
6076         this, a_dst, a_minfo, a_src);
6077   }
6078 
6079   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_base__image_decoder__struct6080   workbuf_len() const {
6081     return wuffs_base__image_decoder__workbuf_len(this);
6082   }
6083 
6084 #endif  // __cplusplus
6085 };  // struct wuffs_base__image_decoder__struct
6086 
6087 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6088 
6089 // --------
6090 
6091 extern const char wuffs_base__io_transformer__vtable_name[];
6092 
6093 typedef struct wuffs_base__io_transformer__func_ptrs__struct {
6094   wuffs_base__empty_struct (*set_quirk_enabled)(
6095     void* self,
6096     uint32_t a_quirk,
6097     bool a_enabled);
6098   wuffs_base__status (*transform_io)(
6099     void* self,
6100     wuffs_base__io_buffer* a_dst,
6101     wuffs_base__io_buffer* a_src,
6102     wuffs_base__slice_u8 a_workbuf);
6103   wuffs_base__range_ii_u64 (*workbuf_len)(
6104     const void* self);
6105 } wuffs_base__io_transformer__func_ptrs;
6106 
6107 typedef struct wuffs_base__io_transformer__struct wuffs_base__io_transformer;
6108 
6109 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
6110 wuffs_base__io_transformer__set_quirk_enabled(
6111     wuffs_base__io_transformer* self,
6112     uint32_t a_quirk,
6113     bool a_enabled);
6114 
6115 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6116 wuffs_base__io_transformer__transform_io(
6117     wuffs_base__io_transformer* self,
6118     wuffs_base__io_buffer* a_dst,
6119     wuffs_base__io_buffer* a_src,
6120     wuffs_base__slice_u8 a_workbuf);
6121 
6122 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
6123 wuffs_base__io_transformer__workbuf_len(
6124     const wuffs_base__io_transformer* self);
6125 
6126 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6127 
6128 struct wuffs_base__io_transformer__struct {
6129   struct {
6130     uint32_t magic;
6131     uint32_t active_coroutine;
6132     wuffs_base__vtable first_vtable;
6133   } private_impl;
6134 
6135 #ifdef __cplusplus
6136 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6137   using unique_ptr = std::unique_ptr<wuffs_base__io_transformer, decltype(&free)>;
6138 #endif
6139 
6140   inline wuffs_base__empty_struct
set_quirk_enabledwuffs_base__io_transformer__struct6141   set_quirk_enabled(
6142       uint32_t a_quirk,
6143       bool a_enabled) {
6144     return wuffs_base__io_transformer__set_quirk_enabled(
6145         this, a_quirk, a_enabled);
6146   }
6147 
6148   inline wuffs_base__status
transform_iowuffs_base__io_transformer__struct6149   transform_io(
6150       wuffs_base__io_buffer* a_dst,
6151       wuffs_base__io_buffer* a_src,
6152       wuffs_base__slice_u8 a_workbuf) {
6153     return wuffs_base__io_transformer__transform_io(
6154         this, a_dst, a_src, a_workbuf);
6155   }
6156 
6157   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_base__io_transformer__struct6158   workbuf_len() const {
6159     return wuffs_base__io_transformer__workbuf_len(this);
6160   }
6161 
6162 #endif  // __cplusplus
6163 };  // struct wuffs_base__io_transformer__struct
6164 
6165 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6166 
6167 // --------
6168 
6169 extern const char wuffs_base__token_decoder__vtable_name[];
6170 
6171 typedef struct wuffs_base__token_decoder__func_ptrs__struct {
6172   wuffs_base__status (*decode_tokens)(
6173     void* self,
6174     wuffs_base__token_buffer* a_dst,
6175     wuffs_base__io_buffer* a_src,
6176     wuffs_base__slice_u8 a_workbuf);
6177   wuffs_base__empty_struct (*set_quirk_enabled)(
6178     void* self,
6179     uint32_t a_quirk,
6180     bool a_enabled);
6181   wuffs_base__range_ii_u64 (*workbuf_len)(
6182     const void* self);
6183 } wuffs_base__token_decoder__func_ptrs;
6184 
6185 typedef struct wuffs_base__token_decoder__struct wuffs_base__token_decoder;
6186 
6187 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6188 wuffs_base__token_decoder__decode_tokens(
6189     wuffs_base__token_decoder* self,
6190     wuffs_base__token_buffer* a_dst,
6191     wuffs_base__io_buffer* a_src,
6192     wuffs_base__slice_u8 a_workbuf);
6193 
6194 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
6195 wuffs_base__token_decoder__set_quirk_enabled(
6196     wuffs_base__token_decoder* self,
6197     uint32_t a_quirk,
6198     bool a_enabled);
6199 
6200 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
6201 wuffs_base__token_decoder__workbuf_len(
6202     const wuffs_base__token_decoder* self);
6203 
6204 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6205 
6206 struct wuffs_base__token_decoder__struct {
6207   struct {
6208     uint32_t magic;
6209     uint32_t active_coroutine;
6210     wuffs_base__vtable first_vtable;
6211   } private_impl;
6212 
6213 #ifdef __cplusplus
6214 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6215   using unique_ptr = std::unique_ptr<wuffs_base__token_decoder, decltype(&free)>;
6216 #endif
6217 
6218   inline wuffs_base__status
decode_tokenswuffs_base__token_decoder__struct6219   decode_tokens(
6220       wuffs_base__token_buffer* a_dst,
6221       wuffs_base__io_buffer* a_src,
6222       wuffs_base__slice_u8 a_workbuf) {
6223     return wuffs_base__token_decoder__decode_tokens(
6224         this, a_dst, a_src, a_workbuf);
6225   }
6226 
6227   inline wuffs_base__empty_struct
set_quirk_enabledwuffs_base__token_decoder__struct6228   set_quirk_enabled(
6229       uint32_t a_quirk,
6230       bool a_enabled) {
6231     return wuffs_base__token_decoder__set_quirk_enabled(
6232         this, a_quirk, a_enabled);
6233   }
6234 
6235   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_base__token_decoder__struct6236   workbuf_len() const {
6237     return wuffs_base__token_decoder__workbuf_len(this);
6238   }
6239 
6240 #endif  // __cplusplus
6241 };  // struct wuffs_base__token_decoder__struct
6242 
6243 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6244 
6245 // ----------------
6246 
6247 #ifdef __cplusplus
6248 }  // extern "C"
6249 #endif
6250 
6251 // ---------------- Status Codes
6252 
6253 // ---------------- Public Consts
6254 
6255 // ---------------- Struct Declarations
6256 
6257 typedef struct wuffs_adler32__hasher__struct wuffs_adler32__hasher;
6258 
6259 #ifdef __cplusplus
6260 extern "C" {
6261 #endif
6262 
6263 // ---------------- Public Initializer Prototypes
6264 
6265 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
6266 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
6267 //
6268 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
6269 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
6270 
6271 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
6272 wuffs_adler32__hasher__initialize(
6273     wuffs_adler32__hasher* self,
6274     size_t sizeof_star_self,
6275     uint64_t wuffs_version,
6276     uint32_t options);
6277 
6278 size_t
6279 sizeof__wuffs_adler32__hasher();
6280 
6281 // ---------------- Allocs
6282 
6283 // These functions allocate and initialize Wuffs structs. They return NULL if
6284 // memory allocation fails. If they return non-NULL, there is no need to call
6285 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
6286 // calling free on the returned pointer. That pointer is effectively a C++
6287 // std::unique_ptr<T, decltype(&free)>.
6288 
6289 wuffs_adler32__hasher*
6290 wuffs_adler32__hasher__alloc();
6291 
6292 static inline wuffs_base__hasher_u32*
wuffs_adler32__hasher__alloc_as__wuffs_base__hasher_u32()6293 wuffs_adler32__hasher__alloc_as__wuffs_base__hasher_u32() {
6294   return (wuffs_base__hasher_u32*)(wuffs_adler32__hasher__alloc());
6295 }
6296 
6297 // ---------------- Upcasts
6298 
6299 static inline wuffs_base__hasher_u32*
wuffs_adler32__hasher__upcast_as__wuffs_base__hasher_u32(wuffs_adler32__hasher * p)6300 wuffs_adler32__hasher__upcast_as__wuffs_base__hasher_u32(
6301     wuffs_adler32__hasher* p) {
6302   return (wuffs_base__hasher_u32*)p;
6303 }
6304 
6305 // ---------------- Public Function Prototypes
6306 
6307 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
6308 wuffs_adler32__hasher__set_quirk_enabled(
6309     wuffs_adler32__hasher* self,
6310     uint32_t a_quirk,
6311     bool a_enabled);
6312 
6313 WUFFS_BASE__MAYBE_STATIC uint32_t
6314 wuffs_adler32__hasher__update_u32(
6315     wuffs_adler32__hasher* self,
6316     wuffs_base__slice_u8 a_x);
6317 
6318 #ifdef __cplusplus
6319 }  // extern "C"
6320 #endif
6321 
6322 // ---------------- Struct Definitions
6323 
6324 // These structs' fields, and the sizeof them, are private implementation
6325 // details that aren't guaranteed to be stable across Wuffs versions.
6326 //
6327 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
6328 
6329 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6330 
6331 struct wuffs_adler32__hasher__struct {
6332   // Do not access the private_impl's or private_data's fields directly. There
6333   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
6334   // the wuffs_foo__bar__baz functions.
6335   //
6336   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
6337   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
6338 
6339   struct {
6340     uint32_t magic;
6341     uint32_t active_coroutine;
6342     wuffs_base__vtable vtable_for__wuffs_base__hasher_u32;
6343     wuffs_base__vtable null_vtable;
6344 
6345     uint32_t f_state;
6346     bool f_started;
6347 
6348     wuffs_base__empty_struct (*choosy_up)(
6349         wuffs_adler32__hasher* self,
6350         wuffs_base__slice_u8 a_x);
6351   } private_impl;
6352 
6353 #ifdef __cplusplus
6354 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6355   using unique_ptr = std::unique_ptr<wuffs_adler32__hasher, decltype(&free)>;
6356 
6357   // On failure, the alloc_etc functions return nullptr. They don't throw.
6358 
6359   static inline unique_ptr
allocwuffs_adler32__hasher__struct6360   alloc() {
6361     return unique_ptr(wuffs_adler32__hasher__alloc(), &free);
6362   }
6363 
6364   static inline wuffs_base__hasher_u32::unique_ptr
alloc_as__wuffs_base__hasher_u32wuffs_adler32__hasher__struct6365   alloc_as__wuffs_base__hasher_u32() {
6366     return wuffs_base__hasher_u32::unique_ptr(
6367         wuffs_adler32__hasher__alloc_as__wuffs_base__hasher_u32(), &free);
6368   }
6369 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6370 
6371 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
6372   // Disallow constructing or copying an object via standard C++ mechanisms,
6373   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
6374   // size and field layout is not part of the public, stable, memory-safe API.
6375   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
6376   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
6377   // their first argument) rather than tweaking bar.private_impl.qux fields.
6378   //
6379   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
6380   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
6381   // order to provide convenience methods. These forward on "this", so that you
6382   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
6383   wuffs_adler32__hasher__struct() = delete;
6384   wuffs_adler32__hasher__struct(const wuffs_adler32__hasher__struct&) = delete;
6385   wuffs_adler32__hasher__struct& operator=(
6386       const wuffs_adler32__hasher__struct&) = delete;
6387 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
6388 
6389 #if !defined(WUFFS_IMPLEMENTATION)
6390   // As above, the size of the struct is not part of the public API, and unless
6391   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
6392   // allocated, not stack allocated. Its size is not intended to be known at
6393   // compile time, but it is unfortunately divulged as a side effect of
6394   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
6395   // instead of "sizeof T", invoking the operator. To make the two values
6396   // different, so that passing the latter will be rejected by the initialize
6397   // function, we add an arbitrary amount of dead weight.
6398   uint8_t dead_weight[123000000];  // 123 MB.
6399 #endif  // !defined(WUFFS_IMPLEMENTATION)
6400 
6401   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_adler32__hasher__struct6402   initialize(
6403       size_t sizeof_star_self,
6404       uint64_t wuffs_version,
6405       uint32_t options) {
6406     return wuffs_adler32__hasher__initialize(
6407         this, sizeof_star_self, wuffs_version, options);
6408   }
6409 
6410   inline wuffs_base__hasher_u32*
upcast_as__wuffs_base__hasher_u32wuffs_adler32__hasher__struct6411   upcast_as__wuffs_base__hasher_u32() {
6412     return (wuffs_base__hasher_u32*)this;
6413   }
6414 
6415   inline wuffs_base__empty_struct
set_quirk_enabledwuffs_adler32__hasher__struct6416   set_quirk_enabled(
6417       uint32_t a_quirk,
6418       bool a_enabled) {
6419     return wuffs_adler32__hasher__set_quirk_enabled(this, a_quirk, a_enabled);
6420   }
6421 
6422   inline uint32_t
update_u32wuffs_adler32__hasher__struct6423   update_u32(
6424       wuffs_base__slice_u8 a_x) {
6425     return wuffs_adler32__hasher__update_u32(this, a_x);
6426   }
6427 
6428 #endif  // __cplusplus
6429 };  // struct wuffs_adler32__hasher__struct
6430 
6431 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6432 
6433 // ---------------- Status Codes
6434 
6435 extern const char wuffs_bmp__error__bad_header[];
6436 extern const char wuffs_bmp__error__bad_rle_compression[];
6437 extern const char wuffs_bmp__error__unsupported_bmp_file[];
6438 
6439 // ---------------- Public Consts
6440 
6441 #define WUFFS_BMP__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
6442 
6443 // ---------------- Struct Declarations
6444 
6445 typedef struct wuffs_bmp__decoder__struct wuffs_bmp__decoder;
6446 
6447 #ifdef __cplusplus
6448 extern "C" {
6449 #endif
6450 
6451 // ---------------- Public Initializer Prototypes
6452 
6453 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
6454 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
6455 //
6456 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
6457 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
6458 
6459 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
6460 wuffs_bmp__decoder__initialize(
6461     wuffs_bmp__decoder* self,
6462     size_t sizeof_star_self,
6463     uint64_t wuffs_version,
6464     uint32_t options);
6465 
6466 size_t
6467 sizeof__wuffs_bmp__decoder();
6468 
6469 // ---------------- Allocs
6470 
6471 // These functions allocate and initialize Wuffs structs. They return NULL if
6472 // memory allocation fails. If they return non-NULL, there is no need to call
6473 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
6474 // calling free on the returned pointer. That pointer is effectively a C++
6475 // std::unique_ptr<T, decltype(&free)>.
6476 
6477 wuffs_bmp__decoder*
6478 wuffs_bmp__decoder__alloc();
6479 
6480 static inline wuffs_base__image_decoder*
wuffs_bmp__decoder__alloc_as__wuffs_base__image_decoder()6481 wuffs_bmp__decoder__alloc_as__wuffs_base__image_decoder() {
6482   return (wuffs_base__image_decoder*)(wuffs_bmp__decoder__alloc());
6483 }
6484 
6485 // ---------------- Upcasts
6486 
6487 static inline wuffs_base__image_decoder*
wuffs_bmp__decoder__upcast_as__wuffs_base__image_decoder(wuffs_bmp__decoder * p)6488 wuffs_bmp__decoder__upcast_as__wuffs_base__image_decoder(
6489     wuffs_bmp__decoder* p) {
6490   return (wuffs_base__image_decoder*)p;
6491 }
6492 
6493 // ---------------- Public Function Prototypes
6494 
6495 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
6496 wuffs_bmp__decoder__set_quirk_enabled(
6497     wuffs_bmp__decoder* self,
6498     uint32_t a_quirk,
6499     bool a_enabled);
6500 
6501 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6502 wuffs_bmp__decoder__decode_image_config(
6503     wuffs_bmp__decoder* self,
6504     wuffs_base__image_config* a_dst,
6505     wuffs_base__io_buffer* a_src);
6506 
6507 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6508 wuffs_bmp__decoder__decode_frame_config(
6509     wuffs_bmp__decoder* self,
6510     wuffs_base__frame_config* a_dst,
6511     wuffs_base__io_buffer* a_src);
6512 
6513 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6514 wuffs_bmp__decoder__decode_frame(
6515     wuffs_bmp__decoder* self,
6516     wuffs_base__pixel_buffer* a_dst,
6517     wuffs_base__io_buffer* a_src,
6518     wuffs_base__pixel_blend a_blend,
6519     wuffs_base__slice_u8 a_workbuf,
6520     wuffs_base__decode_frame_options* a_opts);
6521 
6522 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
6523 wuffs_bmp__decoder__frame_dirty_rect(
6524     const wuffs_bmp__decoder* self);
6525 
6526 WUFFS_BASE__MAYBE_STATIC uint32_t
6527 wuffs_bmp__decoder__num_animation_loops(
6528     const wuffs_bmp__decoder* self);
6529 
6530 WUFFS_BASE__MAYBE_STATIC uint64_t
6531 wuffs_bmp__decoder__num_decoded_frame_configs(
6532     const wuffs_bmp__decoder* self);
6533 
6534 WUFFS_BASE__MAYBE_STATIC uint64_t
6535 wuffs_bmp__decoder__num_decoded_frames(
6536     const wuffs_bmp__decoder* self);
6537 
6538 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6539 wuffs_bmp__decoder__restart_frame(
6540     wuffs_bmp__decoder* self,
6541     uint64_t a_index,
6542     uint64_t a_io_position);
6543 
6544 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
6545 wuffs_bmp__decoder__set_report_metadata(
6546     wuffs_bmp__decoder* self,
6547     uint32_t a_fourcc,
6548     bool a_report);
6549 
6550 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6551 wuffs_bmp__decoder__tell_me_more(
6552     wuffs_bmp__decoder* self,
6553     wuffs_base__io_buffer* a_dst,
6554     wuffs_base__more_information* a_minfo,
6555     wuffs_base__io_buffer* a_src);
6556 
6557 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
6558 wuffs_bmp__decoder__workbuf_len(
6559     const wuffs_bmp__decoder* self);
6560 
6561 #ifdef __cplusplus
6562 }  // extern "C"
6563 #endif
6564 
6565 // ---------------- Struct Definitions
6566 
6567 // These structs' fields, and the sizeof them, are private implementation
6568 // details that aren't guaranteed to be stable across Wuffs versions.
6569 //
6570 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
6571 
6572 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6573 
6574 struct wuffs_bmp__decoder__struct {
6575   // Do not access the private_impl's or private_data's fields directly. There
6576   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
6577   // the wuffs_foo__bar__baz functions.
6578   //
6579   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
6580   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
6581 
6582   struct {
6583     uint32_t magic;
6584     uint32_t active_coroutine;
6585     wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
6586     wuffs_base__vtable null_vtable;
6587 
6588     uint32_t f_width;
6589     uint32_t f_height;
6590     uint8_t f_call_sequence;
6591     bool f_top_down;
6592     uint32_t f_pad_per_row;
6593     uint32_t f_src_pixfmt;
6594     uint32_t f_io_redirect_fourcc;
6595     uint64_t f_io_redirect_pos;
6596     uint64_t f_frame_config_io_position;
6597     uint32_t f_bitmap_info_len;
6598     uint32_t f_padding;
6599     uint32_t f_bits_per_pixel;
6600     uint32_t f_compression;
6601     uint32_t f_channel_masks[4];
6602     uint8_t f_channel_shifts[4];
6603     uint8_t f_channel_num_bits[4];
6604     uint32_t f_dst_x;
6605     uint32_t f_dst_y;
6606     uint32_t f_dst_y_inc;
6607     uint32_t f_pending_pad;
6608     uint32_t f_rle_state;
6609     uint32_t f_rle_length;
6610     uint8_t f_rle_delta_x;
6611     bool f_rle_padded;
6612     wuffs_base__pixel_swizzler f_swizzler;
6613 
6614     uint32_t p_decode_image_config[1];
6615     uint32_t p_decode_frame_config[1];
6616     uint32_t p_decode_frame[1];
6617     uint32_t p_read_palette[1];
6618   } private_impl;
6619 
6620   struct {
6621     uint8_t f_scratch[2048];
6622     uint8_t f_src_palette[1024];
6623 
6624     struct {
6625       uint64_t scratch;
6626     } s_decode_image_config[1];
6627     struct {
6628       wuffs_base__status v_status;
6629       uint64_t scratch;
6630     } s_decode_frame[1];
6631     struct {
6632       uint32_t v_i;
6633       uint64_t scratch;
6634     } s_read_palette[1];
6635   } private_data;
6636 
6637 #ifdef __cplusplus
6638 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6639   using unique_ptr = std::unique_ptr<wuffs_bmp__decoder, decltype(&free)>;
6640 
6641   // On failure, the alloc_etc functions return nullptr. They don't throw.
6642 
6643   static inline unique_ptr
allocwuffs_bmp__decoder__struct6644   alloc() {
6645     return unique_ptr(wuffs_bmp__decoder__alloc(), &free);
6646   }
6647 
6648   static inline wuffs_base__image_decoder::unique_ptr
alloc_as__wuffs_base__image_decoderwuffs_bmp__decoder__struct6649   alloc_as__wuffs_base__image_decoder() {
6650     return wuffs_base__image_decoder::unique_ptr(
6651         wuffs_bmp__decoder__alloc_as__wuffs_base__image_decoder(), &free);
6652   }
6653 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6654 
6655 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
6656   // Disallow constructing or copying an object via standard C++ mechanisms,
6657   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
6658   // size and field layout is not part of the public, stable, memory-safe API.
6659   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
6660   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
6661   // their first argument) rather than tweaking bar.private_impl.qux fields.
6662   //
6663   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
6664   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
6665   // order to provide convenience methods. These forward on "this", so that you
6666   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
6667   wuffs_bmp__decoder__struct() = delete;
6668   wuffs_bmp__decoder__struct(const wuffs_bmp__decoder__struct&) = delete;
6669   wuffs_bmp__decoder__struct& operator=(
6670       const wuffs_bmp__decoder__struct&) = delete;
6671 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
6672 
6673 #if !defined(WUFFS_IMPLEMENTATION)
6674   // As above, the size of the struct is not part of the public API, and unless
6675   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
6676   // allocated, not stack allocated. Its size is not intended to be known at
6677   // compile time, but it is unfortunately divulged as a side effect of
6678   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
6679   // instead of "sizeof T", invoking the operator. To make the two values
6680   // different, so that passing the latter will be rejected by the initialize
6681   // function, we add an arbitrary amount of dead weight.
6682   uint8_t dead_weight[123000000];  // 123 MB.
6683 #endif  // !defined(WUFFS_IMPLEMENTATION)
6684 
6685   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_bmp__decoder__struct6686   initialize(
6687       size_t sizeof_star_self,
6688       uint64_t wuffs_version,
6689       uint32_t options) {
6690     return wuffs_bmp__decoder__initialize(
6691         this, sizeof_star_self, wuffs_version, options);
6692   }
6693 
6694   inline wuffs_base__image_decoder*
upcast_as__wuffs_base__image_decoderwuffs_bmp__decoder__struct6695   upcast_as__wuffs_base__image_decoder() {
6696     return (wuffs_base__image_decoder*)this;
6697   }
6698 
6699   inline wuffs_base__empty_struct
set_quirk_enabledwuffs_bmp__decoder__struct6700   set_quirk_enabled(
6701       uint32_t a_quirk,
6702       bool a_enabled) {
6703     return wuffs_bmp__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
6704   }
6705 
6706   inline wuffs_base__status
decode_image_configwuffs_bmp__decoder__struct6707   decode_image_config(
6708       wuffs_base__image_config* a_dst,
6709       wuffs_base__io_buffer* a_src) {
6710     return wuffs_bmp__decoder__decode_image_config(this, a_dst, a_src);
6711   }
6712 
6713   inline wuffs_base__status
decode_frame_configwuffs_bmp__decoder__struct6714   decode_frame_config(
6715       wuffs_base__frame_config* a_dst,
6716       wuffs_base__io_buffer* a_src) {
6717     return wuffs_bmp__decoder__decode_frame_config(this, a_dst, a_src);
6718   }
6719 
6720   inline wuffs_base__status
decode_framewuffs_bmp__decoder__struct6721   decode_frame(
6722       wuffs_base__pixel_buffer* a_dst,
6723       wuffs_base__io_buffer* a_src,
6724       wuffs_base__pixel_blend a_blend,
6725       wuffs_base__slice_u8 a_workbuf,
6726       wuffs_base__decode_frame_options* a_opts) {
6727     return wuffs_bmp__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
6728   }
6729 
6730   inline wuffs_base__rect_ie_u32
frame_dirty_rectwuffs_bmp__decoder__struct6731   frame_dirty_rect() const {
6732     return wuffs_bmp__decoder__frame_dirty_rect(this);
6733   }
6734 
6735   inline uint32_t
num_animation_loopswuffs_bmp__decoder__struct6736   num_animation_loops() const {
6737     return wuffs_bmp__decoder__num_animation_loops(this);
6738   }
6739 
6740   inline uint64_t
num_decoded_frame_configswuffs_bmp__decoder__struct6741   num_decoded_frame_configs() const {
6742     return wuffs_bmp__decoder__num_decoded_frame_configs(this);
6743   }
6744 
6745   inline uint64_t
num_decoded_frameswuffs_bmp__decoder__struct6746   num_decoded_frames() const {
6747     return wuffs_bmp__decoder__num_decoded_frames(this);
6748   }
6749 
6750   inline wuffs_base__status
restart_framewuffs_bmp__decoder__struct6751   restart_frame(
6752       uint64_t a_index,
6753       uint64_t a_io_position) {
6754     return wuffs_bmp__decoder__restart_frame(this, a_index, a_io_position);
6755   }
6756 
6757   inline wuffs_base__empty_struct
set_report_metadatawuffs_bmp__decoder__struct6758   set_report_metadata(
6759       uint32_t a_fourcc,
6760       bool a_report) {
6761     return wuffs_bmp__decoder__set_report_metadata(this, a_fourcc, a_report);
6762   }
6763 
6764   inline wuffs_base__status
tell_me_morewuffs_bmp__decoder__struct6765   tell_me_more(
6766       wuffs_base__io_buffer* a_dst,
6767       wuffs_base__more_information* a_minfo,
6768       wuffs_base__io_buffer* a_src) {
6769     return wuffs_bmp__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
6770   }
6771 
6772   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_bmp__decoder__struct6773   workbuf_len() const {
6774     return wuffs_bmp__decoder__workbuf_len(this);
6775   }
6776 
6777 #endif  // __cplusplus
6778 };  // struct wuffs_bmp__decoder__struct
6779 
6780 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6781 
6782 // ---------------- Status Codes
6783 
6784 extern const char wuffs_cbor__error__bad_input[];
6785 extern const char wuffs_cbor__error__unsupported_recursion_depth[];
6786 
6787 // ---------------- Public Consts
6788 
6789 #define WUFFS_CBOR__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
6790 
6791 #define WUFFS_CBOR__DECODER_DEPTH_MAX_INCL 1024
6792 
6793 #define WUFFS_CBOR__DECODER_DST_TOKEN_BUFFER_LENGTH_MIN_INCL 2
6794 
6795 #define WUFFS_CBOR__DECODER_SRC_IO_BUFFER_LENGTH_MIN_INCL 9
6796 
6797 #define WUFFS_CBOR__TOKEN_VALUE_MAJOR 787997
6798 
6799 #define WUFFS_CBOR__TOKEN_VALUE_MINOR__DETAIL_MASK 262143
6800 
6801 #define WUFFS_CBOR__TOKEN_VALUE_MINOR__MINUS_1_MINUS_X 16777216
6802 
6803 #define WUFFS_CBOR__TOKEN_VALUE_MINOR__SIMPLE_VALUE 8388608
6804 
6805 #define WUFFS_CBOR__TOKEN_VALUE_MINOR__TAG 4194304
6806 
6807 // ---------------- Struct Declarations
6808 
6809 typedef struct wuffs_cbor__decoder__struct wuffs_cbor__decoder;
6810 
6811 #ifdef __cplusplus
6812 extern "C" {
6813 #endif
6814 
6815 // ---------------- Public Initializer Prototypes
6816 
6817 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
6818 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
6819 //
6820 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
6821 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
6822 
6823 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
6824 wuffs_cbor__decoder__initialize(
6825     wuffs_cbor__decoder* self,
6826     size_t sizeof_star_self,
6827     uint64_t wuffs_version,
6828     uint32_t options);
6829 
6830 size_t
6831 sizeof__wuffs_cbor__decoder();
6832 
6833 // ---------------- Allocs
6834 
6835 // These functions allocate and initialize Wuffs structs. They return NULL if
6836 // memory allocation fails. If they return non-NULL, there is no need to call
6837 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
6838 // calling free on the returned pointer. That pointer is effectively a C++
6839 // std::unique_ptr<T, decltype(&free)>.
6840 
6841 wuffs_cbor__decoder*
6842 wuffs_cbor__decoder__alloc();
6843 
6844 static inline wuffs_base__token_decoder*
wuffs_cbor__decoder__alloc_as__wuffs_base__token_decoder()6845 wuffs_cbor__decoder__alloc_as__wuffs_base__token_decoder() {
6846   return (wuffs_base__token_decoder*)(wuffs_cbor__decoder__alloc());
6847 }
6848 
6849 // ---------------- Upcasts
6850 
6851 static inline wuffs_base__token_decoder*
wuffs_cbor__decoder__upcast_as__wuffs_base__token_decoder(wuffs_cbor__decoder * p)6852 wuffs_cbor__decoder__upcast_as__wuffs_base__token_decoder(
6853     wuffs_cbor__decoder* p) {
6854   return (wuffs_base__token_decoder*)p;
6855 }
6856 
6857 // ---------------- Public Function Prototypes
6858 
6859 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
6860 wuffs_cbor__decoder__set_quirk_enabled(
6861     wuffs_cbor__decoder* self,
6862     uint32_t a_quirk,
6863     bool a_enabled);
6864 
6865 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
6866 wuffs_cbor__decoder__workbuf_len(
6867     const wuffs_cbor__decoder* self);
6868 
6869 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6870 wuffs_cbor__decoder__decode_tokens(
6871     wuffs_cbor__decoder* self,
6872     wuffs_base__token_buffer* a_dst,
6873     wuffs_base__io_buffer* a_src,
6874     wuffs_base__slice_u8 a_workbuf);
6875 
6876 #ifdef __cplusplus
6877 }  // extern "C"
6878 #endif
6879 
6880 // ---------------- Struct Definitions
6881 
6882 // These structs' fields, and the sizeof them, are private implementation
6883 // details that aren't guaranteed to be stable across Wuffs versions.
6884 //
6885 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
6886 
6887 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6888 
6889 struct wuffs_cbor__decoder__struct {
6890   // Do not access the private_impl's or private_data's fields directly. There
6891   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
6892   // the wuffs_foo__bar__baz functions.
6893   //
6894   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
6895   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
6896 
6897   struct {
6898     uint32_t magic;
6899     uint32_t active_coroutine;
6900     wuffs_base__vtable vtable_for__wuffs_base__token_decoder;
6901     wuffs_base__vtable null_vtable;
6902 
6903     bool f_end_of_data;
6904 
6905     uint32_t p_decode_tokens[1];
6906   } private_impl;
6907 
6908   struct {
6909     uint32_t f_stack[64];
6910     uint64_t f_container_num_remaining[1024];
6911 
6912     struct {
6913       uint64_t v_string_length;
6914       uint32_t v_depth;
6915       uint32_t v_token_length;
6916       bool v_tagged;
6917       uint8_t v_indefinite_string_major_type;
6918     } s_decode_tokens[1];
6919   } private_data;
6920 
6921 #ifdef __cplusplus
6922 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6923   using unique_ptr = std::unique_ptr<wuffs_cbor__decoder, decltype(&free)>;
6924 
6925   // On failure, the alloc_etc functions return nullptr. They don't throw.
6926 
6927   static inline unique_ptr
allocwuffs_cbor__decoder__struct6928   alloc() {
6929     return unique_ptr(wuffs_cbor__decoder__alloc(), &free);
6930   }
6931 
6932   static inline wuffs_base__token_decoder::unique_ptr
alloc_as__wuffs_base__token_decoderwuffs_cbor__decoder__struct6933   alloc_as__wuffs_base__token_decoder() {
6934     return wuffs_base__token_decoder::unique_ptr(
6935         wuffs_cbor__decoder__alloc_as__wuffs_base__token_decoder(), &free);
6936   }
6937 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6938 
6939 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
6940   // Disallow constructing or copying an object via standard C++ mechanisms,
6941   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
6942   // size and field layout is not part of the public, stable, memory-safe API.
6943   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
6944   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
6945   // their first argument) rather than tweaking bar.private_impl.qux fields.
6946   //
6947   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
6948   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
6949   // order to provide convenience methods. These forward on "this", so that you
6950   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
6951   wuffs_cbor__decoder__struct() = delete;
6952   wuffs_cbor__decoder__struct(const wuffs_cbor__decoder__struct&) = delete;
6953   wuffs_cbor__decoder__struct& operator=(
6954       const wuffs_cbor__decoder__struct&) = delete;
6955 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
6956 
6957 #if !defined(WUFFS_IMPLEMENTATION)
6958   // As above, the size of the struct is not part of the public API, and unless
6959   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
6960   // allocated, not stack allocated. Its size is not intended to be known at
6961   // compile time, but it is unfortunately divulged as a side effect of
6962   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
6963   // instead of "sizeof T", invoking the operator. To make the two values
6964   // different, so that passing the latter will be rejected by the initialize
6965   // function, we add an arbitrary amount of dead weight.
6966   uint8_t dead_weight[123000000];  // 123 MB.
6967 #endif  // !defined(WUFFS_IMPLEMENTATION)
6968 
6969   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_cbor__decoder__struct6970   initialize(
6971       size_t sizeof_star_self,
6972       uint64_t wuffs_version,
6973       uint32_t options) {
6974     return wuffs_cbor__decoder__initialize(
6975         this, sizeof_star_self, wuffs_version, options);
6976   }
6977 
6978   inline wuffs_base__token_decoder*
upcast_as__wuffs_base__token_decoderwuffs_cbor__decoder__struct6979   upcast_as__wuffs_base__token_decoder() {
6980     return (wuffs_base__token_decoder*)this;
6981   }
6982 
6983   inline wuffs_base__empty_struct
set_quirk_enabledwuffs_cbor__decoder__struct6984   set_quirk_enabled(
6985       uint32_t a_quirk,
6986       bool a_enabled) {
6987     return wuffs_cbor__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
6988   }
6989 
6990   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_cbor__decoder__struct6991   workbuf_len() const {
6992     return wuffs_cbor__decoder__workbuf_len(this);
6993   }
6994 
6995   inline wuffs_base__status
decode_tokenswuffs_cbor__decoder__struct6996   decode_tokens(
6997       wuffs_base__token_buffer* a_dst,
6998       wuffs_base__io_buffer* a_src,
6999       wuffs_base__slice_u8 a_workbuf) {
7000     return wuffs_cbor__decoder__decode_tokens(this, a_dst, a_src, a_workbuf);
7001   }
7002 
7003 #endif  // __cplusplus
7004 };  // struct wuffs_cbor__decoder__struct
7005 
7006 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7007 
7008 // ---------------- Status Codes
7009 
7010 // ---------------- Public Consts
7011 
7012 // ---------------- Struct Declarations
7013 
7014 typedef struct wuffs_crc32__ieee_hasher__struct wuffs_crc32__ieee_hasher;
7015 
7016 #ifdef __cplusplus
7017 extern "C" {
7018 #endif
7019 
7020 // ---------------- Public Initializer Prototypes
7021 
7022 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
7023 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
7024 //
7025 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
7026 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
7027 
7028 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
7029 wuffs_crc32__ieee_hasher__initialize(
7030     wuffs_crc32__ieee_hasher* self,
7031     size_t sizeof_star_self,
7032     uint64_t wuffs_version,
7033     uint32_t options);
7034 
7035 size_t
7036 sizeof__wuffs_crc32__ieee_hasher();
7037 
7038 // ---------------- Allocs
7039 
7040 // These functions allocate and initialize Wuffs structs. They return NULL if
7041 // memory allocation fails. If they return non-NULL, there is no need to call
7042 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
7043 // calling free on the returned pointer. That pointer is effectively a C++
7044 // std::unique_ptr<T, decltype(&free)>.
7045 
7046 wuffs_crc32__ieee_hasher*
7047 wuffs_crc32__ieee_hasher__alloc();
7048 
7049 static inline wuffs_base__hasher_u32*
wuffs_crc32__ieee_hasher__alloc_as__wuffs_base__hasher_u32()7050 wuffs_crc32__ieee_hasher__alloc_as__wuffs_base__hasher_u32() {
7051   return (wuffs_base__hasher_u32*)(wuffs_crc32__ieee_hasher__alloc());
7052 }
7053 
7054 // ---------------- Upcasts
7055 
7056 static inline wuffs_base__hasher_u32*
wuffs_crc32__ieee_hasher__upcast_as__wuffs_base__hasher_u32(wuffs_crc32__ieee_hasher * p)7057 wuffs_crc32__ieee_hasher__upcast_as__wuffs_base__hasher_u32(
7058     wuffs_crc32__ieee_hasher* p) {
7059   return (wuffs_base__hasher_u32*)p;
7060 }
7061 
7062 // ---------------- Public Function Prototypes
7063 
7064 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
7065 wuffs_crc32__ieee_hasher__set_quirk_enabled(
7066     wuffs_crc32__ieee_hasher* self,
7067     uint32_t a_quirk,
7068     bool a_enabled);
7069 
7070 WUFFS_BASE__MAYBE_STATIC uint32_t
7071 wuffs_crc32__ieee_hasher__update_u32(
7072     wuffs_crc32__ieee_hasher* self,
7073     wuffs_base__slice_u8 a_x);
7074 
7075 #ifdef __cplusplus
7076 }  // extern "C"
7077 #endif
7078 
7079 // ---------------- Struct Definitions
7080 
7081 // These structs' fields, and the sizeof them, are private implementation
7082 // details that aren't guaranteed to be stable across Wuffs versions.
7083 //
7084 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
7085 
7086 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7087 
7088 struct wuffs_crc32__ieee_hasher__struct {
7089   // Do not access the private_impl's or private_data's fields directly. There
7090   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
7091   // the wuffs_foo__bar__baz functions.
7092   //
7093   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
7094   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
7095 
7096   struct {
7097     uint32_t magic;
7098     uint32_t active_coroutine;
7099     wuffs_base__vtable vtable_for__wuffs_base__hasher_u32;
7100     wuffs_base__vtable null_vtable;
7101 
7102     uint32_t f_state;
7103 
7104     wuffs_base__empty_struct (*choosy_up)(
7105         wuffs_crc32__ieee_hasher* self,
7106         wuffs_base__slice_u8 a_x);
7107   } private_impl;
7108 
7109 #ifdef __cplusplus
7110 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
7111   using unique_ptr = std::unique_ptr<wuffs_crc32__ieee_hasher, decltype(&free)>;
7112 
7113   // On failure, the alloc_etc functions return nullptr. They don't throw.
7114 
7115   static inline unique_ptr
allocwuffs_crc32__ieee_hasher__struct7116   alloc() {
7117     return unique_ptr(wuffs_crc32__ieee_hasher__alloc(), &free);
7118   }
7119 
7120   static inline wuffs_base__hasher_u32::unique_ptr
alloc_as__wuffs_base__hasher_u32wuffs_crc32__ieee_hasher__struct7121   alloc_as__wuffs_base__hasher_u32() {
7122     return wuffs_base__hasher_u32::unique_ptr(
7123         wuffs_crc32__ieee_hasher__alloc_as__wuffs_base__hasher_u32(), &free);
7124   }
7125 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
7126 
7127 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
7128   // Disallow constructing or copying an object via standard C++ mechanisms,
7129   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
7130   // size and field layout is not part of the public, stable, memory-safe API.
7131   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
7132   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
7133   // their first argument) rather than tweaking bar.private_impl.qux fields.
7134   //
7135   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
7136   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
7137   // order to provide convenience methods. These forward on "this", so that you
7138   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
7139   wuffs_crc32__ieee_hasher__struct() = delete;
7140   wuffs_crc32__ieee_hasher__struct(const wuffs_crc32__ieee_hasher__struct&) = delete;
7141   wuffs_crc32__ieee_hasher__struct& operator=(
7142       const wuffs_crc32__ieee_hasher__struct&) = delete;
7143 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
7144 
7145 #if !defined(WUFFS_IMPLEMENTATION)
7146   // As above, the size of the struct is not part of the public API, and unless
7147   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
7148   // allocated, not stack allocated. Its size is not intended to be known at
7149   // compile time, but it is unfortunately divulged as a side effect of
7150   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
7151   // instead of "sizeof T", invoking the operator. To make the two values
7152   // different, so that passing the latter will be rejected by the initialize
7153   // function, we add an arbitrary amount of dead weight.
7154   uint8_t dead_weight[123000000];  // 123 MB.
7155 #endif  // !defined(WUFFS_IMPLEMENTATION)
7156 
7157   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_crc32__ieee_hasher__struct7158   initialize(
7159       size_t sizeof_star_self,
7160       uint64_t wuffs_version,
7161       uint32_t options) {
7162     return wuffs_crc32__ieee_hasher__initialize(
7163         this, sizeof_star_self, wuffs_version, options);
7164   }
7165 
7166   inline wuffs_base__hasher_u32*
upcast_as__wuffs_base__hasher_u32wuffs_crc32__ieee_hasher__struct7167   upcast_as__wuffs_base__hasher_u32() {
7168     return (wuffs_base__hasher_u32*)this;
7169   }
7170 
7171   inline wuffs_base__empty_struct
set_quirk_enabledwuffs_crc32__ieee_hasher__struct7172   set_quirk_enabled(
7173       uint32_t a_quirk,
7174       bool a_enabled) {
7175     return wuffs_crc32__ieee_hasher__set_quirk_enabled(this, a_quirk, a_enabled);
7176   }
7177 
7178   inline uint32_t
update_u32wuffs_crc32__ieee_hasher__struct7179   update_u32(
7180       wuffs_base__slice_u8 a_x) {
7181     return wuffs_crc32__ieee_hasher__update_u32(this, a_x);
7182   }
7183 
7184 #endif  // __cplusplus
7185 };  // struct wuffs_crc32__ieee_hasher__struct
7186 
7187 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7188 
7189 // ---------------- Status Codes
7190 
7191 extern const char wuffs_deflate__error__bad_huffman_code_over_subscribed[];
7192 extern const char wuffs_deflate__error__bad_huffman_code_under_subscribed[];
7193 extern const char wuffs_deflate__error__bad_huffman_code_length_count[];
7194 extern const char wuffs_deflate__error__bad_huffman_code_length_repetition[];
7195 extern const char wuffs_deflate__error__bad_huffman_code[];
7196 extern const char wuffs_deflate__error__bad_huffman_minimum_code_length[];
7197 extern const char wuffs_deflate__error__bad_block[];
7198 extern const char wuffs_deflate__error__bad_distance[];
7199 extern const char wuffs_deflate__error__bad_distance_code_count[];
7200 extern const char wuffs_deflate__error__bad_literal_length_code_count[];
7201 extern const char wuffs_deflate__error__inconsistent_stored_block_length[];
7202 extern const char wuffs_deflate__error__missing_end_of_block_code[];
7203 extern const char wuffs_deflate__error__no_huffman_codes[];
7204 
7205 // ---------------- Public Consts
7206 
7207 #define WUFFS_DEFLATE__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 1
7208 
7209 // ---------------- Struct Declarations
7210 
7211 typedef struct wuffs_deflate__decoder__struct wuffs_deflate__decoder;
7212 
7213 #ifdef __cplusplus
7214 extern "C" {
7215 #endif
7216 
7217 // ---------------- Public Initializer Prototypes
7218 
7219 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
7220 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
7221 //
7222 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
7223 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
7224 
7225 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
7226 wuffs_deflate__decoder__initialize(
7227     wuffs_deflate__decoder* self,
7228     size_t sizeof_star_self,
7229     uint64_t wuffs_version,
7230     uint32_t options);
7231 
7232 size_t
7233 sizeof__wuffs_deflate__decoder();
7234 
7235 // ---------------- Allocs
7236 
7237 // These functions allocate and initialize Wuffs structs. They return NULL if
7238 // memory allocation fails. If they return non-NULL, there is no need to call
7239 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
7240 // calling free on the returned pointer. That pointer is effectively a C++
7241 // std::unique_ptr<T, decltype(&free)>.
7242 
7243 wuffs_deflate__decoder*
7244 wuffs_deflate__decoder__alloc();
7245 
7246 static inline wuffs_base__io_transformer*
wuffs_deflate__decoder__alloc_as__wuffs_base__io_transformer()7247 wuffs_deflate__decoder__alloc_as__wuffs_base__io_transformer() {
7248   return (wuffs_base__io_transformer*)(wuffs_deflate__decoder__alloc());
7249 }
7250 
7251 // ---------------- Upcasts
7252 
7253 static inline wuffs_base__io_transformer*
wuffs_deflate__decoder__upcast_as__wuffs_base__io_transformer(wuffs_deflate__decoder * p)7254 wuffs_deflate__decoder__upcast_as__wuffs_base__io_transformer(
7255     wuffs_deflate__decoder* p) {
7256   return (wuffs_base__io_transformer*)p;
7257 }
7258 
7259 // ---------------- Public Function Prototypes
7260 
7261 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
7262 wuffs_deflate__decoder__add_history(
7263     wuffs_deflate__decoder* self,
7264     wuffs_base__slice_u8 a_hist);
7265 
7266 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
7267 wuffs_deflate__decoder__set_quirk_enabled(
7268     wuffs_deflate__decoder* self,
7269     uint32_t a_quirk,
7270     bool a_enabled);
7271 
7272 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
7273 wuffs_deflate__decoder__workbuf_len(
7274     const wuffs_deflate__decoder* self);
7275 
7276 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7277 wuffs_deflate__decoder__transform_io(
7278     wuffs_deflate__decoder* self,
7279     wuffs_base__io_buffer* a_dst,
7280     wuffs_base__io_buffer* a_src,
7281     wuffs_base__slice_u8 a_workbuf);
7282 
7283 #ifdef __cplusplus
7284 }  // extern "C"
7285 #endif
7286 
7287 // ---------------- Struct Definitions
7288 
7289 // These structs' fields, and the sizeof them, are private implementation
7290 // details that aren't guaranteed to be stable across Wuffs versions.
7291 //
7292 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
7293 
7294 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7295 
7296 struct wuffs_deflate__decoder__struct {
7297   // Do not access the private_impl's or private_data's fields directly. There
7298   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
7299   // the wuffs_foo__bar__baz functions.
7300   //
7301   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
7302   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
7303 
7304   struct {
7305     uint32_t magic;
7306     uint32_t active_coroutine;
7307     wuffs_base__vtable vtable_for__wuffs_base__io_transformer;
7308     wuffs_base__vtable null_vtable;
7309 
7310     uint32_t f_bits;
7311     uint32_t f_n_bits;
7312     uint64_t f_transformed_history_count;
7313     uint32_t f_history_index;
7314     uint32_t f_n_huffs_bits[2];
7315     bool f_end_of_block;
7316 
7317     uint32_t p_transform_io[1];
7318     uint32_t p_decode_blocks[1];
7319     uint32_t p_decode_uncompressed[1];
7320     uint32_t p_init_dynamic_huffman[1];
7321     wuffs_base__status (*choosy_decode_huffman_fast64)(
7322         wuffs_deflate__decoder* self,
7323         wuffs_base__io_buffer* a_dst,
7324         wuffs_base__io_buffer* a_src);
7325     uint32_t p_decode_huffman_slow[1];
7326   } private_impl;
7327 
7328   struct {
7329     uint32_t f_huffs[2][1024];
7330     uint8_t f_history[33025];
7331     uint8_t f_code_lengths[320];
7332 
7333     struct {
7334       uint32_t v_final;
7335     } s_decode_blocks[1];
7336     struct {
7337       uint32_t v_length;
7338       uint64_t scratch;
7339     } s_decode_uncompressed[1];
7340     struct {
7341       uint32_t v_bits;
7342       uint32_t v_n_bits;
7343       uint32_t v_n_lit;
7344       uint32_t v_n_dist;
7345       uint32_t v_n_clen;
7346       uint32_t v_i;
7347       uint32_t v_mask;
7348       uint32_t v_table_entry;
7349       uint32_t v_n_extra_bits;
7350       uint8_t v_rep_symbol;
7351       uint32_t v_rep_count;
7352     } s_init_dynamic_huffman[1];
7353     struct {
7354       uint32_t v_bits;
7355       uint32_t v_n_bits;
7356       uint32_t v_table_entry;
7357       uint32_t v_table_entry_n_bits;
7358       uint32_t v_lmask;
7359       uint32_t v_dmask;
7360       uint32_t v_redir_top;
7361       uint32_t v_redir_mask;
7362       uint32_t v_length;
7363       uint32_t v_dist_minus_1;
7364       uint32_t v_hlen;
7365       uint32_t v_hdist;
7366       uint64_t scratch;
7367     } s_decode_huffman_slow[1];
7368   } private_data;
7369 
7370 #ifdef __cplusplus
7371 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
7372   using unique_ptr = std::unique_ptr<wuffs_deflate__decoder, decltype(&free)>;
7373 
7374   // On failure, the alloc_etc functions return nullptr. They don't throw.
7375 
7376   static inline unique_ptr
allocwuffs_deflate__decoder__struct7377   alloc() {
7378     return unique_ptr(wuffs_deflate__decoder__alloc(), &free);
7379   }
7380 
7381   static inline wuffs_base__io_transformer::unique_ptr
alloc_as__wuffs_base__io_transformerwuffs_deflate__decoder__struct7382   alloc_as__wuffs_base__io_transformer() {
7383     return wuffs_base__io_transformer::unique_ptr(
7384         wuffs_deflate__decoder__alloc_as__wuffs_base__io_transformer(), &free);
7385   }
7386 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
7387 
7388 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
7389   // Disallow constructing or copying an object via standard C++ mechanisms,
7390   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
7391   // size and field layout is not part of the public, stable, memory-safe API.
7392   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
7393   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
7394   // their first argument) rather than tweaking bar.private_impl.qux fields.
7395   //
7396   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
7397   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
7398   // order to provide convenience methods. These forward on "this", so that you
7399   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
7400   wuffs_deflate__decoder__struct() = delete;
7401   wuffs_deflate__decoder__struct(const wuffs_deflate__decoder__struct&) = delete;
7402   wuffs_deflate__decoder__struct& operator=(
7403       const wuffs_deflate__decoder__struct&) = delete;
7404 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
7405 
7406 #if !defined(WUFFS_IMPLEMENTATION)
7407   // As above, the size of the struct is not part of the public API, and unless
7408   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
7409   // allocated, not stack allocated. Its size is not intended to be known at
7410   // compile time, but it is unfortunately divulged as a side effect of
7411   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
7412   // instead of "sizeof T", invoking the operator. To make the two values
7413   // different, so that passing the latter will be rejected by the initialize
7414   // function, we add an arbitrary amount of dead weight.
7415   uint8_t dead_weight[123000000];  // 123 MB.
7416 #endif  // !defined(WUFFS_IMPLEMENTATION)
7417 
7418   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_deflate__decoder__struct7419   initialize(
7420       size_t sizeof_star_self,
7421       uint64_t wuffs_version,
7422       uint32_t options) {
7423     return wuffs_deflate__decoder__initialize(
7424         this, sizeof_star_self, wuffs_version, options);
7425   }
7426 
7427   inline wuffs_base__io_transformer*
upcast_as__wuffs_base__io_transformerwuffs_deflate__decoder__struct7428   upcast_as__wuffs_base__io_transformer() {
7429     return (wuffs_base__io_transformer*)this;
7430   }
7431 
7432   inline wuffs_base__empty_struct
add_historywuffs_deflate__decoder__struct7433   add_history(
7434       wuffs_base__slice_u8 a_hist) {
7435     return wuffs_deflate__decoder__add_history(this, a_hist);
7436   }
7437 
7438   inline wuffs_base__empty_struct
set_quirk_enabledwuffs_deflate__decoder__struct7439   set_quirk_enabled(
7440       uint32_t a_quirk,
7441       bool a_enabled) {
7442     return wuffs_deflate__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
7443   }
7444 
7445   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_deflate__decoder__struct7446   workbuf_len() const {
7447     return wuffs_deflate__decoder__workbuf_len(this);
7448   }
7449 
7450   inline wuffs_base__status
transform_iowuffs_deflate__decoder__struct7451   transform_io(
7452       wuffs_base__io_buffer* a_dst,
7453       wuffs_base__io_buffer* a_src,
7454       wuffs_base__slice_u8 a_workbuf) {
7455     return wuffs_deflate__decoder__transform_io(this, a_dst, a_src, a_workbuf);
7456   }
7457 
7458 #endif  // __cplusplus
7459 };  // struct wuffs_deflate__decoder__struct
7460 
7461 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7462 
7463 // ---------------- Status Codes
7464 
7465 extern const char wuffs_lzw__error__bad_code[];
7466 
7467 // ---------------- Public Consts
7468 
7469 #define WUFFS_LZW__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
7470 
7471 // ---------------- Struct Declarations
7472 
7473 typedef struct wuffs_lzw__decoder__struct wuffs_lzw__decoder;
7474 
7475 #ifdef __cplusplus
7476 extern "C" {
7477 #endif
7478 
7479 // ---------------- Public Initializer Prototypes
7480 
7481 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
7482 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
7483 //
7484 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
7485 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
7486 
7487 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
7488 wuffs_lzw__decoder__initialize(
7489     wuffs_lzw__decoder* self,
7490     size_t sizeof_star_self,
7491     uint64_t wuffs_version,
7492     uint32_t options);
7493 
7494 size_t
7495 sizeof__wuffs_lzw__decoder();
7496 
7497 // ---------------- Allocs
7498 
7499 // These functions allocate and initialize Wuffs structs. They return NULL if
7500 // memory allocation fails. If they return non-NULL, there is no need to call
7501 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
7502 // calling free on the returned pointer. That pointer is effectively a C++
7503 // std::unique_ptr<T, decltype(&free)>.
7504 
7505 wuffs_lzw__decoder*
7506 wuffs_lzw__decoder__alloc();
7507 
7508 static inline wuffs_base__io_transformer*
wuffs_lzw__decoder__alloc_as__wuffs_base__io_transformer()7509 wuffs_lzw__decoder__alloc_as__wuffs_base__io_transformer() {
7510   return (wuffs_base__io_transformer*)(wuffs_lzw__decoder__alloc());
7511 }
7512 
7513 // ---------------- Upcasts
7514 
7515 static inline wuffs_base__io_transformer*
wuffs_lzw__decoder__upcast_as__wuffs_base__io_transformer(wuffs_lzw__decoder * p)7516 wuffs_lzw__decoder__upcast_as__wuffs_base__io_transformer(
7517     wuffs_lzw__decoder* p) {
7518   return (wuffs_base__io_transformer*)p;
7519 }
7520 
7521 // ---------------- Public Function Prototypes
7522 
7523 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
7524 wuffs_lzw__decoder__set_quirk_enabled(
7525     wuffs_lzw__decoder* self,
7526     uint32_t a_quirk,
7527     bool a_enabled);
7528 
7529 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
7530 wuffs_lzw__decoder__set_literal_width(
7531     wuffs_lzw__decoder* self,
7532     uint32_t a_lw);
7533 
7534 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
7535 wuffs_lzw__decoder__workbuf_len(
7536     const wuffs_lzw__decoder* self);
7537 
7538 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7539 wuffs_lzw__decoder__transform_io(
7540     wuffs_lzw__decoder* self,
7541     wuffs_base__io_buffer* a_dst,
7542     wuffs_base__io_buffer* a_src,
7543     wuffs_base__slice_u8 a_workbuf);
7544 
7545 WUFFS_BASE__MAYBE_STATIC wuffs_base__slice_u8
7546 wuffs_lzw__decoder__flush(
7547     wuffs_lzw__decoder* self);
7548 
7549 #ifdef __cplusplus
7550 }  // extern "C"
7551 #endif
7552 
7553 // ---------------- Struct Definitions
7554 
7555 // These structs' fields, and the sizeof them, are private implementation
7556 // details that aren't guaranteed to be stable across Wuffs versions.
7557 //
7558 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
7559 
7560 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7561 
7562 struct wuffs_lzw__decoder__struct {
7563   // Do not access the private_impl's or private_data's fields directly. There
7564   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
7565   // the wuffs_foo__bar__baz functions.
7566   //
7567   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
7568   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
7569 
7570   struct {
7571     uint32_t magic;
7572     uint32_t active_coroutine;
7573     wuffs_base__vtable vtable_for__wuffs_base__io_transformer;
7574     wuffs_base__vtable null_vtable;
7575 
7576     uint32_t f_set_literal_width_arg;
7577     uint32_t f_literal_width;
7578     uint32_t f_clear_code;
7579     uint32_t f_end_code;
7580     uint32_t f_save_code;
7581     uint32_t f_prev_code;
7582     uint32_t f_width;
7583     uint32_t f_bits;
7584     uint32_t f_n_bits;
7585     uint32_t f_output_ri;
7586     uint32_t f_output_wi;
7587     uint32_t f_read_from_return_value;
7588     uint16_t f_prefixes[4096];
7589 
7590     uint32_t p_transform_io[1];
7591     uint32_t p_write_to[1];
7592   } private_impl;
7593 
7594   struct {
7595     uint8_t f_suffixes[4096][8];
7596     uint16_t f_lm1s[4096];
7597     uint8_t f_output[8199];
7598   } private_data;
7599 
7600 #ifdef __cplusplus
7601 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
7602   using unique_ptr = std::unique_ptr<wuffs_lzw__decoder, decltype(&free)>;
7603 
7604   // On failure, the alloc_etc functions return nullptr. They don't throw.
7605 
7606   static inline unique_ptr
allocwuffs_lzw__decoder__struct7607   alloc() {
7608     return unique_ptr(wuffs_lzw__decoder__alloc(), &free);
7609   }
7610 
7611   static inline wuffs_base__io_transformer::unique_ptr
alloc_as__wuffs_base__io_transformerwuffs_lzw__decoder__struct7612   alloc_as__wuffs_base__io_transformer() {
7613     return wuffs_base__io_transformer::unique_ptr(
7614         wuffs_lzw__decoder__alloc_as__wuffs_base__io_transformer(), &free);
7615   }
7616 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
7617 
7618 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
7619   // Disallow constructing or copying an object via standard C++ mechanisms,
7620   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
7621   // size and field layout is not part of the public, stable, memory-safe API.
7622   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
7623   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
7624   // their first argument) rather than tweaking bar.private_impl.qux fields.
7625   //
7626   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
7627   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
7628   // order to provide convenience methods. These forward on "this", so that you
7629   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
7630   wuffs_lzw__decoder__struct() = delete;
7631   wuffs_lzw__decoder__struct(const wuffs_lzw__decoder__struct&) = delete;
7632   wuffs_lzw__decoder__struct& operator=(
7633       const wuffs_lzw__decoder__struct&) = delete;
7634 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
7635 
7636 #if !defined(WUFFS_IMPLEMENTATION)
7637   // As above, the size of the struct is not part of the public API, and unless
7638   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
7639   // allocated, not stack allocated. Its size is not intended to be known at
7640   // compile time, but it is unfortunately divulged as a side effect of
7641   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
7642   // instead of "sizeof T", invoking the operator. To make the two values
7643   // different, so that passing the latter will be rejected by the initialize
7644   // function, we add an arbitrary amount of dead weight.
7645   uint8_t dead_weight[123000000];  // 123 MB.
7646 #endif  // !defined(WUFFS_IMPLEMENTATION)
7647 
7648   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_lzw__decoder__struct7649   initialize(
7650       size_t sizeof_star_self,
7651       uint64_t wuffs_version,
7652       uint32_t options) {
7653     return wuffs_lzw__decoder__initialize(
7654         this, sizeof_star_self, wuffs_version, options);
7655   }
7656 
7657   inline wuffs_base__io_transformer*
upcast_as__wuffs_base__io_transformerwuffs_lzw__decoder__struct7658   upcast_as__wuffs_base__io_transformer() {
7659     return (wuffs_base__io_transformer*)this;
7660   }
7661 
7662   inline wuffs_base__empty_struct
set_quirk_enabledwuffs_lzw__decoder__struct7663   set_quirk_enabled(
7664       uint32_t a_quirk,
7665       bool a_enabled) {
7666     return wuffs_lzw__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
7667   }
7668 
7669   inline wuffs_base__empty_struct
set_literal_widthwuffs_lzw__decoder__struct7670   set_literal_width(
7671       uint32_t a_lw) {
7672     return wuffs_lzw__decoder__set_literal_width(this, a_lw);
7673   }
7674 
7675   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_lzw__decoder__struct7676   workbuf_len() const {
7677     return wuffs_lzw__decoder__workbuf_len(this);
7678   }
7679 
7680   inline wuffs_base__status
transform_iowuffs_lzw__decoder__struct7681   transform_io(
7682       wuffs_base__io_buffer* a_dst,
7683       wuffs_base__io_buffer* a_src,
7684       wuffs_base__slice_u8 a_workbuf) {
7685     return wuffs_lzw__decoder__transform_io(this, a_dst, a_src, a_workbuf);
7686   }
7687 
7688   inline wuffs_base__slice_u8
flushwuffs_lzw__decoder__struct7689   flush() {
7690     return wuffs_lzw__decoder__flush(this);
7691   }
7692 
7693 #endif  // __cplusplus
7694 };  // struct wuffs_lzw__decoder__struct
7695 
7696 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7697 
7698 // ---------------- Status Codes
7699 
7700 extern const char wuffs_gif__error__bad_extension_label[];
7701 extern const char wuffs_gif__error__bad_frame_size[];
7702 extern const char wuffs_gif__error__bad_graphic_control[];
7703 extern const char wuffs_gif__error__bad_header[];
7704 extern const char wuffs_gif__error__bad_literal_width[];
7705 extern const char wuffs_gif__error__bad_palette[];
7706 
7707 // ---------------- Public Consts
7708 
7709 #define WUFFS_GIF__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
7710 
7711 #define WUFFS_GIF__QUIRK_DELAY_NUM_DECODED_FRAMES 1041635328
7712 
7713 #define WUFFS_GIF__QUIRK_FIRST_FRAME_LOCAL_PALETTE_MEANS_BLACK_BACKGROUND 1041635329
7714 
7715 #define WUFFS_GIF__QUIRK_HONOR_BACKGROUND_COLOR 1041635330
7716 
7717 #define WUFFS_GIF__QUIRK_IGNORE_TOO_MUCH_PIXEL_DATA 1041635331
7718 
7719 #define WUFFS_GIF__QUIRK_IMAGE_BOUNDS_ARE_STRICT 1041635332
7720 
7721 #define WUFFS_GIF__QUIRK_REJECT_EMPTY_FRAME 1041635333
7722 
7723 #define WUFFS_GIF__QUIRK_REJECT_EMPTY_PALETTE 1041635334
7724 
7725 // ---------------- Struct Declarations
7726 
7727 typedef struct wuffs_gif__decoder__struct wuffs_gif__decoder;
7728 
7729 #ifdef __cplusplus
7730 extern "C" {
7731 #endif
7732 
7733 // ---------------- Public Initializer Prototypes
7734 
7735 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
7736 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
7737 //
7738 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
7739 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
7740 
7741 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
7742 wuffs_gif__decoder__initialize(
7743     wuffs_gif__decoder* self,
7744     size_t sizeof_star_self,
7745     uint64_t wuffs_version,
7746     uint32_t options);
7747 
7748 size_t
7749 sizeof__wuffs_gif__decoder();
7750 
7751 // ---------------- Allocs
7752 
7753 // These functions allocate and initialize Wuffs structs. They return NULL if
7754 // memory allocation fails. If they return non-NULL, there is no need to call
7755 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
7756 // calling free on the returned pointer. That pointer is effectively a C++
7757 // std::unique_ptr<T, decltype(&free)>.
7758 
7759 wuffs_gif__decoder*
7760 wuffs_gif__decoder__alloc();
7761 
7762 static inline wuffs_base__image_decoder*
wuffs_gif__decoder__alloc_as__wuffs_base__image_decoder()7763 wuffs_gif__decoder__alloc_as__wuffs_base__image_decoder() {
7764   return (wuffs_base__image_decoder*)(wuffs_gif__decoder__alloc());
7765 }
7766 
7767 // ---------------- Upcasts
7768 
7769 static inline wuffs_base__image_decoder*
wuffs_gif__decoder__upcast_as__wuffs_base__image_decoder(wuffs_gif__decoder * p)7770 wuffs_gif__decoder__upcast_as__wuffs_base__image_decoder(
7771     wuffs_gif__decoder* p) {
7772   return (wuffs_base__image_decoder*)p;
7773 }
7774 
7775 // ---------------- Public Function Prototypes
7776 
7777 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
7778 wuffs_gif__decoder__set_quirk_enabled(
7779     wuffs_gif__decoder* self,
7780     uint32_t a_quirk,
7781     bool a_enabled);
7782 
7783 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7784 wuffs_gif__decoder__decode_image_config(
7785     wuffs_gif__decoder* self,
7786     wuffs_base__image_config* a_dst,
7787     wuffs_base__io_buffer* a_src);
7788 
7789 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
7790 wuffs_gif__decoder__set_report_metadata(
7791     wuffs_gif__decoder* self,
7792     uint32_t a_fourcc,
7793     bool a_report);
7794 
7795 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7796 wuffs_gif__decoder__tell_me_more(
7797     wuffs_gif__decoder* self,
7798     wuffs_base__io_buffer* a_dst,
7799     wuffs_base__more_information* a_minfo,
7800     wuffs_base__io_buffer* a_src);
7801 
7802 WUFFS_BASE__MAYBE_STATIC uint32_t
7803 wuffs_gif__decoder__num_animation_loops(
7804     const wuffs_gif__decoder* self);
7805 
7806 WUFFS_BASE__MAYBE_STATIC uint64_t
7807 wuffs_gif__decoder__num_decoded_frame_configs(
7808     const wuffs_gif__decoder* self);
7809 
7810 WUFFS_BASE__MAYBE_STATIC uint64_t
7811 wuffs_gif__decoder__num_decoded_frames(
7812     const wuffs_gif__decoder* self);
7813 
7814 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
7815 wuffs_gif__decoder__frame_dirty_rect(
7816     const wuffs_gif__decoder* self);
7817 
7818 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
7819 wuffs_gif__decoder__workbuf_len(
7820     const wuffs_gif__decoder* self);
7821 
7822 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7823 wuffs_gif__decoder__restart_frame(
7824     wuffs_gif__decoder* self,
7825     uint64_t a_index,
7826     uint64_t a_io_position);
7827 
7828 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7829 wuffs_gif__decoder__decode_frame_config(
7830     wuffs_gif__decoder* self,
7831     wuffs_base__frame_config* a_dst,
7832     wuffs_base__io_buffer* a_src);
7833 
7834 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7835 wuffs_gif__decoder__decode_frame(
7836     wuffs_gif__decoder* self,
7837     wuffs_base__pixel_buffer* a_dst,
7838     wuffs_base__io_buffer* a_src,
7839     wuffs_base__pixel_blend a_blend,
7840     wuffs_base__slice_u8 a_workbuf,
7841     wuffs_base__decode_frame_options* a_opts);
7842 
7843 #ifdef __cplusplus
7844 }  // extern "C"
7845 #endif
7846 
7847 // ---------------- Struct Definitions
7848 
7849 // These structs' fields, and the sizeof them, are private implementation
7850 // details that aren't guaranteed to be stable across Wuffs versions.
7851 //
7852 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
7853 
7854 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7855 
7856 struct wuffs_gif__decoder__struct {
7857   // Do not access the private_impl's or private_data's fields directly. There
7858   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
7859   // the wuffs_foo__bar__baz functions.
7860   //
7861   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
7862   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
7863 
7864   struct {
7865     uint32_t magic;
7866     uint32_t active_coroutine;
7867     wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
7868     wuffs_base__vtable null_vtable;
7869 
7870     uint32_t f_width;
7871     uint32_t f_height;
7872     uint8_t f_call_sequence;
7873     bool f_ignore_metadata;
7874     bool f_report_metadata_iccp;
7875     bool f_report_metadata_xmp;
7876     uint32_t f_metadata_fourcc;
7877     uint64_t f_metadata_io_position;
7878     bool f_quirks[7];
7879     bool f_delayed_num_decoded_frames;
7880     bool f_end_of_data;
7881     bool f_restarted;
7882     bool f_previous_lzw_decode_ended_abruptly;
7883     bool f_has_global_palette;
7884     uint8_t f_interlace;
7885     bool f_seen_num_animation_loops_value;
7886     uint32_t f_num_animation_loops_value;
7887     uint32_t f_background_color_u32_argb_premul;
7888     uint32_t f_black_color_u32_argb_premul;
7889     bool f_gc_has_transparent_index;
7890     uint8_t f_gc_transparent_index;
7891     uint8_t f_gc_disposal;
7892     uint64_t f_gc_duration;
7893     uint64_t f_frame_config_io_position;
7894     uint64_t f_num_decoded_frame_configs_value;
7895     uint64_t f_num_decoded_frames_value;
7896     uint32_t f_frame_rect_x0;
7897     uint32_t f_frame_rect_y0;
7898     uint32_t f_frame_rect_x1;
7899     uint32_t f_frame_rect_y1;
7900     uint32_t f_dst_x;
7901     uint32_t f_dst_y;
7902     uint32_t f_dirty_max_excl_y;
7903     uint64_t f_compressed_ri;
7904     uint64_t f_compressed_wi;
7905     wuffs_base__pixel_swizzler f_swizzler;
7906 
7907     uint32_t p_decode_image_config[1];
7908     uint32_t p_tell_me_more[1];
7909     uint32_t p_decode_frame_config[1];
7910     uint32_t p_skip_frame[1];
7911     uint32_t p_decode_frame[1];
7912     uint32_t p_decode_up_to_id_part1[1];
7913     uint32_t p_decode_header[1];
7914     uint32_t p_decode_lsd[1];
7915     uint32_t p_decode_extension[1];
7916     uint32_t p_skip_blocks[1];
7917     uint32_t p_decode_ae[1];
7918     uint32_t p_decode_gc[1];
7919     uint32_t p_decode_id_part0[1];
7920     uint32_t p_decode_id_part1[1];
7921     uint32_t p_decode_id_part2[1];
7922   } private_impl;
7923 
7924   struct {
7925     uint8_t f_compressed[4096];
7926     uint8_t f_palettes[2][1024];
7927     uint8_t f_dst_palette[1024];
7928     wuffs_lzw__decoder f_lzw;
7929 
7930     struct {
7931       uint32_t v_background_color;
7932     } s_decode_frame_config[1];
7933     struct {
7934       uint64_t scratch;
7935     } s_skip_frame[1];
7936     struct {
7937       uint8_t v_c[6];
7938       uint32_t v_i;
7939     } s_decode_header[1];
7940     struct {
7941       uint8_t v_flags;
7942       uint8_t v_background_color_index;
7943       uint32_t v_num_palette_entries;
7944       uint32_t v_i;
7945       uint64_t scratch;
7946     } s_decode_lsd[1];
7947     struct {
7948       uint64_t scratch;
7949     } s_skip_blocks[1];
7950     struct {
7951       uint8_t v_block_size;
7952       bool v_is_animexts;
7953       bool v_is_netscape;
7954       bool v_is_iccp;
7955       bool v_is_xmp;
7956       uint64_t scratch;
7957     } s_decode_ae[1];
7958     struct {
7959       uint64_t scratch;
7960     } s_decode_gc[1];
7961     struct {
7962       uint64_t scratch;
7963     } s_decode_id_part0[1];
7964     struct {
7965       uint8_t v_which_palette;
7966       uint32_t v_num_palette_entries;
7967       uint32_t v_i;
7968       uint64_t scratch;
7969     } s_decode_id_part1[1];
7970     struct {
7971       uint64_t v_block_size;
7972       bool v_need_block_size;
7973       wuffs_base__status v_lzw_status;
7974       uint64_t scratch;
7975     } s_decode_id_part2[1];
7976   } private_data;
7977 
7978 #ifdef __cplusplus
7979 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
7980   using unique_ptr = std::unique_ptr<wuffs_gif__decoder, decltype(&free)>;
7981 
7982   // On failure, the alloc_etc functions return nullptr. They don't throw.
7983 
7984   static inline unique_ptr
allocwuffs_gif__decoder__struct7985   alloc() {
7986     return unique_ptr(wuffs_gif__decoder__alloc(), &free);
7987   }
7988 
7989   static inline wuffs_base__image_decoder::unique_ptr
alloc_as__wuffs_base__image_decoderwuffs_gif__decoder__struct7990   alloc_as__wuffs_base__image_decoder() {
7991     return wuffs_base__image_decoder::unique_ptr(
7992         wuffs_gif__decoder__alloc_as__wuffs_base__image_decoder(), &free);
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_gif__decoder__struct() = delete;
8009   wuffs_gif__decoder__struct(const wuffs_gif__decoder__struct&) = delete;
8010   wuffs_gif__decoder__struct& operator=(
8011       const wuffs_gif__decoder__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_gif__decoder__struct8027   initialize(
8028       size_t sizeof_star_self,
8029       uint64_t wuffs_version,
8030       uint32_t options) {
8031     return wuffs_gif__decoder__initialize(
8032         this, sizeof_star_self, wuffs_version, options);
8033   }
8034 
8035   inline wuffs_base__image_decoder*
upcast_as__wuffs_base__image_decoderwuffs_gif__decoder__struct8036   upcast_as__wuffs_base__image_decoder() {
8037     return (wuffs_base__image_decoder*)this;
8038   }
8039 
8040   inline wuffs_base__empty_struct
set_quirk_enabledwuffs_gif__decoder__struct8041   set_quirk_enabled(
8042       uint32_t a_quirk,
8043       bool a_enabled) {
8044     return wuffs_gif__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
8045   }
8046 
8047   inline wuffs_base__status
decode_image_configwuffs_gif__decoder__struct8048   decode_image_config(
8049       wuffs_base__image_config* a_dst,
8050       wuffs_base__io_buffer* a_src) {
8051     return wuffs_gif__decoder__decode_image_config(this, a_dst, a_src);
8052   }
8053 
8054   inline wuffs_base__empty_struct
set_report_metadatawuffs_gif__decoder__struct8055   set_report_metadata(
8056       uint32_t a_fourcc,
8057       bool a_report) {
8058     return wuffs_gif__decoder__set_report_metadata(this, a_fourcc, a_report);
8059   }
8060 
8061   inline wuffs_base__status
tell_me_morewuffs_gif__decoder__struct8062   tell_me_more(
8063       wuffs_base__io_buffer* a_dst,
8064       wuffs_base__more_information* a_minfo,
8065       wuffs_base__io_buffer* a_src) {
8066     return wuffs_gif__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
8067   }
8068 
8069   inline uint32_t
num_animation_loopswuffs_gif__decoder__struct8070   num_animation_loops() const {
8071     return wuffs_gif__decoder__num_animation_loops(this);
8072   }
8073 
8074   inline uint64_t
num_decoded_frame_configswuffs_gif__decoder__struct8075   num_decoded_frame_configs() const {
8076     return wuffs_gif__decoder__num_decoded_frame_configs(this);
8077   }
8078 
8079   inline uint64_t
num_decoded_frameswuffs_gif__decoder__struct8080   num_decoded_frames() const {
8081     return wuffs_gif__decoder__num_decoded_frames(this);
8082   }
8083 
8084   inline wuffs_base__rect_ie_u32
frame_dirty_rectwuffs_gif__decoder__struct8085   frame_dirty_rect() const {
8086     return wuffs_gif__decoder__frame_dirty_rect(this);
8087   }
8088 
8089   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_gif__decoder__struct8090   workbuf_len() const {
8091     return wuffs_gif__decoder__workbuf_len(this);
8092   }
8093 
8094   inline wuffs_base__status
restart_framewuffs_gif__decoder__struct8095   restart_frame(
8096       uint64_t a_index,
8097       uint64_t a_io_position) {
8098     return wuffs_gif__decoder__restart_frame(this, a_index, a_io_position);
8099   }
8100 
8101   inline wuffs_base__status
decode_frame_configwuffs_gif__decoder__struct8102   decode_frame_config(
8103       wuffs_base__frame_config* a_dst,
8104       wuffs_base__io_buffer* a_src) {
8105     return wuffs_gif__decoder__decode_frame_config(this, a_dst, a_src);
8106   }
8107 
8108   inline wuffs_base__status
decode_framewuffs_gif__decoder__struct8109   decode_frame(
8110       wuffs_base__pixel_buffer* a_dst,
8111       wuffs_base__io_buffer* a_src,
8112       wuffs_base__pixel_blend a_blend,
8113       wuffs_base__slice_u8 a_workbuf,
8114       wuffs_base__decode_frame_options* a_opts) {
8115     return wuffs_gif__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
8116   }
8117 
8118 #endif  // __cplusplus
8119 };  // struct wuffs_gif__decoder__struct
8120 
8121 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
8122 
8123 // ---------------- Status Codes
8124 
8125 extern const char wuffs_gzip__error__bad_checksum[];
8126 extern const char wuffs_gzip__error__bad_compression_method[];
8127 extern const char wuffs_gzip__error__bad_encoding_flags[];
8128 extern const char wuffs_gzip__error__bad_header[];
8129 
8130 // ---------------- Public Consts
8131 
8132 #define WUFFS_GZIP__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 1
8133 
8134 // ---------------- Struct Declarations
8135 
8136 typedef struct wuffs_gzip__decoder__struct wuffs_gzip__decoder;
8137 
8138 #ifdef __cplusplus
8139 extern "C" {
8140 #endif
8141 
8142 // ---------------- Public Initializer Prototypes
8143 
8144 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
8145 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
8146 //
8147 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
8148 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
8149 
8150 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
8151 wuffs_gzip__decoder__initialize(
8152     wuffs_gzip__decoder* self,
8153     size_t sizeof_star_self,
8154     uint64_t wuffs_version,
8155     uint32_t options);
8156 
8157 size_t
8158 sizeof__wuffs_gzip__decoder();
8159 
8160 // ---------------- Allocs
8161 
8162 // These functions allocate and initialize Wuffs structs. They return NULL if
8163 // memory allocation fails. If they return non-NULL, there is no need to call
8164 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
8165 // calling free on the returned pointer. That pointer is effectively a C++
8166 // std::unique_ptr<T, decltype(&free)>.
8167 
8168 wuffs_gzip__decoder*
8169 wuffs_gzip__decoder__alloc();
8170 
8171 static inline wuffs_base__io_transformer*
wuffs_gzip__decoder__alloc_as__wuffs_base__io_transformer()8172 wuffs_gzip__decoder__alloc_as__wuffs_base__io_transformer() {
8173   return (wuffs_base__io_transformer*)(wuffs_gzip__decoder__alloc());
8174 }
8175 
8176 // ---------------- Upcasts
8177 
8178 static inline wuffs_base__io_transformer*
wuffs_gzip__decoder__upcast_as__wuffs_base__io_transformer(wuffs_gzip__decoder * p)8179 wuffs_gzip__decoder__upcast_as__wuffs_base__io_transformer(
8180     wuffs_gzip__decoder* p) {
8181   return (wuffs_base__io_transformer*)p;
8182 }
8183 
8184 // ---------------- Public Function Prototypes
8185 
8186 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
8187 wuffs_gzip__decoder__set_quirk_enabled(
8188     wuffs_gzip__decoder* self,
8189     uint32_t a_quirk,
8190     bool a_enabled);
8191 
8192 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
8193 wuffs_gzip__decoder__workbuf_len(
8194     const wuffs_gzip__decoder* self);
8195 
8196 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8197 wuffs_gzip__decoder__transform_io(
8198     wuffs_gzip__decoder* self,
8199     wuffs_base__io_buffer* a_dst,
8200     wuffs_base__io_buffer* a_src,
8201     wuffs_base__slice_u8 a_workbuf);
8202 
8203 #ifdef __cplusplus
8204 }  // extern "C"
8205 #endif
8206 
8207 // ---------------- Struct Definitions
8208 
8209 // These structs' fields, and the sizeof them, are private implementation
8210 // details that aren't guaranteed to be stable across Wuffs versions.
8211 //
8212 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
8213 
8214 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
8215 
8216 struct wuffs_gzip__decoder__struct {
8217   // Do not access the private_impl's or private_data's fields directly. There
8218   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
8219   // the wuffs_foo__bar__baz functions.
8220   //
8221   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
8222   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
8223 
8224   struct {
8225     uint32_t magic;
8226     uint32_t active_coroutine;
8227     wuffs_base__vtable vtable_for__wuffs_base__io_transformer;
8228     wuffs_base__vtable null_vtable;
8229 
8230     bool f_ignore_checksum;
8231 
8232     uint32_t p_transform_io[1];
8233   } private_impl;
8234 
8235   struct {
8236     wuffs_crc32__ieee_hasher f_checksum;
8237     wuffs_deflate__decoder f_flate;
8238 
8239     struct {
8240       uint8_t v_flags;
8241       uint32_t v_checksum_got;
8242       uint32_t v_decoded_length_got;
8243       uint32_t v_checksum_want;
8244       uint64_t scratch;
8245     } s_transform_io[1];
8246   } private_data;
8247 
8248 #ifdef __cplusplus
8249 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
8250   using unique_ptr = std::unique_ptr<wuffs_gzip__decoder, decltype(&free)>;
8251 
8252   // On failure, the alloc_etc functions return nullptr. They don't throw.
8253 
8254   static inline unique_ptr
allocwuffs_gzip__decoder__struct8255   alloc() {
8256     return unique_ptr(wuffs_gzip__decoder__alloc(), &free);
8257   }
8258 
8259   static inline wuffs_base__io_transformer::unique_ptr
alloc_as__wuffs_base__io_transformerwuffs_gzip__decoder__struct8260   alloc_as__wuffs_base__io_transformer() {
8261     return wuffs_base__io_transformer::unique_ptr(
8262         wuffs_gzip__decoder__alloc_as__wuffs_base__io_transformer(), &free);
8263   }
8264 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
8265 
8266 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
8267   // Disallow constructing or copying an object via standard C++ mechanisms,
8268   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
8269   // size and field layout is not part of the public, stable, memory-safe API.
8270   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
8271   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
8272   // their first argument) rather than tweaking bar.private_impl.qux fields.
8273   //
8274   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
8275   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
8276   // order to provide convenience methods. These forward on "this", so that you
8277   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
8278   wuffs_gzip__decoder__struct() = delete;
8279   wuffs_gzip__decoder__struct(const wuffs_gzip__decoder__struct&) = delete;
8280   wuffs_gzip__decoder__struct& operator=(
8281       const wuffs_gzip__decoder__struct&) = delete;
8282 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
8283 
8284 #if !defined(WUFFS_IMPLEMENTATION)
8285   // As above, the size of the struct is not part of the public API, and unless
8286   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
8287   // allocated, not stack allocated. Its size is not intended to be known at
8288   // compile time, but it is unfortunately divulged as a side effect of
8289   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
8290   // instead of "sizeof T", invoking the operator. To make the two values
8291   // different, so that passing the latter will be rejected by the initialize
8292   // function, we add an arbitrary amount of dead weight.
8293   uint8_t dead_weight[123000000];  // 123 MB.
8294 #endif  // !defined(WUFFS_IMPLEMENTATION)
8295 
8296   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_gzip__decoder__struct8297   initialize(
8298       size_t sizeof_star_self,
8299       uint64_t wuffs_version,
8300       uint32_t options) {
8301     return wuffs_gzip__decoder__initialize(
8302         this, sizeof_star_self, wuffs_version, options);
8303   }
8304 
8305   inline wuffs_base__io_transformer*
upcast_as__wuffs_base__io_transformerwuffs_gzip__decoder__struct8306   upcast_as__wuffs_base__io_transformer() {
8307     return (wuffs_base__io_transformer*)this;
8308   }
8309 
8310   inline wuffs_base__empty_struct
set_quirk_enabledwuffs_gzip__decoder__struct8311   set_quirk_enabled(
8312       uint32_t a_quirk,
8313       bool a_enabled) {
8314     return wuffs_gzip__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
8315   }
8316 
8317   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_gzip__decoder__struct8318   workbuf_len() const {
8319     return wuffs_gzip__decoder__workbuf_len(this);
8320   }
8321 
8322   inline wuffs_base__status
transform_iowuffs_gzip__decoder__struct8323   transform_io(
8324       wuffs_base__io_buffer* a_dst,
8325       wuffs_base__io_buffer* a_src,
8326       wuffs_base__slice_u8 a_workbuf) {
8327     return wuffs_gzip__decoder__transform_io(this, a_dst, a_src, a_workbuf);
8328   }
8329 
8330 #endif  // __cplusplus
8331 };  // struct wuffs_gzip__decoder__struct
8332 
8333 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
8334 
8335 // ---------------- Status Codes
8336 
8337 extern const char wuffs_json__error__bad_c0_control_code[];
8338 extern const char wuffs_json__error__bad_utf_8[];
8339 extern const char wuffs_json__error__bad_backslash_escape[];
8340 extern const char wuffs_json__error__bad_input[];
8341 extern const char wuffs_json__error__bad_new_line_in_a_string[];
8342 extern const char wuffs_json__error__bad_quirk_combination[];
8343 extern const char wuffs_json__error__unsupported_number_length[];
8344 extern const char wuffs_json__error__unsupported_recursion_depth[];
8345 
8346 // ---------------- Public Consts
8347 
8348 #define WUFFS_JSON__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
8349 
8350 #define WUFFS_JSON__DECODER_DEPTH_MAX_INCL 1024
8351 
8352 #define WUFFS_JSON__DECODER_DST_TOKEN_BUFFER_LENGTH_MIN_INCL 1
8353 
8354 #define WUFFS_JSON__DECODER_SRC_IO_BUFFER_LENGTH_MIN_INCL 100
8355 
8356 #define WUFFS_JSON__QUIRK_ALLOW_ASCII_CONTROL_CODES 1225364480
8357 
8358 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_A 1225364481
8359 
8360 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_CAPITAL_U 1225364482
8361 
8362 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_E 1225364483
8363 
8364 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_NEW_LINE 1225364484
8365 
8366 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_QUESTION_MARK 1225364485
8367 
8368 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_SINGLE_QUOTE 1225364486
8369 
8370 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_V 1225364487
8371 
8372 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_X_AS_CODE_POINTS 1225364489
8373 
8374 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_ZERO 1225364490
8375 
8376 #define WUFFS_JSON__QUIRK_ALLOW_COMMENT_BLOCK 1225364491
8377 
8378 #define WUFFS_JSON__QUIRK_ALLOW_COMMENT_LINE 1225364492
8379 
8380 #define WUFFS_JSON__QUIRK_ALLOW_EXTRA_COMMA 1225364493
8381 
8382 #define WUFFS_JSON__QUIRK_ALLOW_INF_NAN_NUMBERS 1225364494
8383 
8384 #define WUFFS_JSON__QUIRK_ALLOW_LEADING_ASCII_RECORD_SEPARATOR 1225364495
8385 
8386 #define WUFFS_JSON__QUIRK_ALLOW_LEADING_UNICODE_BYTE_ORDER_MARK 1225364496
8387 
8388 #define WUFFS_JSON__QUIRK_ALLOW_TRAILING_FILLER 1225364497
8389 
8390 #define WUFFS_JSON__QUIRK_EXPECT_TRAILING_NEW_LINE_OR_EOF 1225364498
8391 
8392 #define WUFFS_JSON__QUIRK_JSON_POINTER_ALLOW_TILDE_N_TILDE_R_TILDE_T 1225364499
8393 
8394 #define WUFFS_JSON__QUIRK_REPLACE_INVALID_UNICODE 1225364500
8395 
8396 // ---------------- Struct Declarations
8397 
8398 typedef struct wuffs_json__decoder__struct wuffs_json__decoder;
8399 
8400 #ifdef __cplusplus
8401 extern "C" {
8402 #endif
8403 
8404 // ---------------- Public Initializer Prototypes
8405 
8406 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
8407 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
8408 //
8409 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
8410 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
8411 
8412 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
8413 wuffs_json__decoder__initialize(
8414     wuffs_json__decoder* self,
8415     size_t sizeof_star_self,
8416     uint64_t wuffs_version,
8417     uint32_t options);
8418 
8419 size_t
8420 sizeof__wuffs_json__decoder();
8421 
8422 // ---------------- Allocs
8423 
8424 // These functions allocate and initialize Wuffs structs. They return NULL if
8425 // memory allocation fails. If they return non-NULL, there is no need to call
8426 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
8427 // calling free on the returned pointer. That pointer is effectively a C++
8428 // std::unique_ptr<T, decltype(&free)>.
8429 
8430 wuffs_json__decoder*
8431 wuffs_json__decoder__alloc();
8432 
8433 static inline wuffs_base__token_decoder*
wuffs_json__decoder__alloc_as__wuffs_base__token_decoder()8434 wuffs_json__decoder__alloc_as__wuffs_base__token_decoder() {
8435   return (wuffs_base__token_decoder*)(wuffs_json__decoder__alloc());
8436 }
8437 
8438 // ---------------- Upcasts
8439 
8440 static inline wuffs_base__token_decoder*
wuffs_json__decoder__upcast_as__wuffs_base__token_decoder(wuffs_json__decoder * p)8441 wuffs_json__decoder__upcast_as__wuffs_base__token_decoder(
8442     wuffs_json__decoder* p) {
8443   return (wuffs_base__token_decoder*)p;
8444 }
8445 
8446 // ---------------- Public Function Prototypes
8447 
8448 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
8449 wuffs_json__decoder__set_quirk_enabled(
8450     wuffs_json__decoder* self,
8451     uint32_t a_quirk,
8452     bool a_enabled);
8453 
8454 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
8455 wuffs_json__decoder__workbuf_len(
8456     const wuffs_json__decoder* self);
8457 
8458 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8459 wuffs_json__decoder__decode_tokens(
8460     wuffs_json__decoder* self,
8461     wuffs_base__token_buffer* a_dst,
8462     wuffs_base__io_buffer* a_src,
8463     wuffs_base__slice_u8 a_workbuf);
8464 
8465 #ifdef __cplusplus
8466 }  // extern "C"
8467 #endif
8468 
8469 // ---------------- Struct Definitions
8470 
8471 // These structs' fields, and the sizeof them, are private implementation
8472 // details that aren't guaranteed to be stable across Wuffs versions.
8473 //
8474 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
8475 
8476 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
8477 
8478 struct wuffs_json__decoder__struct {
8479   // Do not access the private_impl's or private_data's fields directly. There
8480   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
8481   // the wuffs_foo__bar__baz functions.
8482   //
8483   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
8484   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
8485 
8486   struct {
8487     uint32_t magic;
8488     uint32_t active_coroutine;
8489     wuffs_base__vtable vtable_for__wuffs_base__token_decoder;
8490     wuffs_base__vtable null_vtable;
8491 
8492     bool f_quirks[21];
8493     bool f_allow_leading_ars;
8494     bool f_allow_leading_ubom;
8495     bool f_end_of_data;
8496     uint8_t f_trailer_stop;
8497     uint8_t f_comment_type;
8498 
8499     uint32_t p_decode_tokens[1];
8500     uint32_t p_decode_leading[1];
8501     uint32_t p_decode_comment[1];
8502     uint32_t p_decode_inf_nan[1];
8503     uint32_t p_decode_trailer[1];
8504   } private_impl;
8505 
8506   struct {
8507     uint32_t f_stack[32];
8508 
8509     struct {
8510       uint32_t v_depth;
8511       uint32_t v_expect;
8512       uint32_t v_expect_after_value;
8513     } s_decode_tokens[1];
8514     struct {
8515       uint32_t v_neg;
8516     } s_decode_inf_nan[1];
8517   } private_data;
8518 
8519 #ifdef __cplusplus
8520 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
8521   using unique_ptr = std::unique_ptr<wuffs_json__decoder, decltype(&free)>;
8522 
8523   // On failure, the alloc_etc functions return nullptr. They don't throw.
8524 
8525   static inline unique_ptr
allocwuffs_json__decoder__struct8526   alloc() {
8527     return unique_ptr(wuffs_json__decoder__alloc(), &free);
8528   }
8529 
8530   static inline wuffs_base__token_decoder::unique_ptr
alloc_as__wuffs_base__token_decoderwuffs_json__decoder__struct8531   alloc_as__wuffs_base__token_decoder() {
8532     return wuffs_base__token_decoder::unique_ptr(
8533         wuffs_json__decoder__alloc_as__wuffs_base__token_decoder(), &free);
8534   }
8535 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
8536 
8537 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
8538   // Disallow constructing or copying an object via standard C++ mechanisms,
8539   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
8540   // size and field layout is not part of the public, stable, memory-safe API.
8541   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
8542   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
8543   // their first argument) rather than tweaking bar.private_impl.qux fields.
8544   //
8545   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
8546   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
8547   // order to provide convenience methods. These forward on "this", so that you
8548   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
8549   wuffs_json__decoder__struct() = delete;
8550   wuffs_json__decoder__struct(const wuffs_json__decoder__struct&) = delete;
8551   wuffs_json__decoder__struct& operator=(
8552       const wuffs_json__decoder__struct&) = delete;
8553 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
8554 
8555 #if !defined(WUFFS_IMPLEMENTATION)
8556   // As above, the size of the struct is not part of the public API, and unless
8557   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
8558   // allocated, not stack allocated. Its size is not intended to be known at
8559   // compile time, but it is unfortunately divulged as a side effect of
8560   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
8561   // instead of "sizeof T", invoking the operator. To make the two values
8562   // different, so that passing the latter will be rejected by the initialize
8563   // function, we add an arbitrary amount of dead weight.
8564   uint8_t dead_weight[123000000];  // 123 MB.
8565 #endif  // !defined(WUFFS_IMPLEMENTATION)
8566 
8567   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_json__decoder__struct8568   initialize(
8569       size_t sizeof_star_self,
8570       uint64_t wuffs_version,
8571       uint32_t options) {
8572     return wuffs_json__decoder__initialize(
8573         this, sizeof_star_self, wuffs_version, options);
8574   }
8575 
8576   inline wuffs_base__token_decoder*
upcast_as__wuffs_base__token_decoderwuffs_json__decoder__struct8577   upcast_as__wuffs_base__token_decoder() {
8578     return (wuffs_base__token_decoder*)this;
8579   }
8580 
8581   inline wuffs_base__empty_struct
set_quirk_enabledwuffs_json__decoder__struct8582   set_quirk_enabled(
8583       uint32_t a_quirk,
8584       bool a_enabled) {
8585     return wuffs_json__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
8586   }
8587 
8588   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_json__decoder__struct8589   workbuf_len() const {
8590     return wuffs_json__decoder__workbuf_len(this);
8591   }
8592 
8593   inline wuffs_base__status
decode_tokenswuffs_json__decoder__struct8594   decode_tokens(
8595       wuffs_base__token_buffer* a_dst,
8596       wuffs_base__io_buffer* a_src,
8597       wuffs_base__slice_u8 a_workbuf) {
8598     return wuffs_json__decoder__decode_tokens(this, a_dst, a_src, a_workbuf);
8599   }
8600 
8601 #endif  // __cplusplus
8602 };  // struct wuffs_json__decoder__struct
8603 
8604 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
8605 
8606 // ---------------- Status Codes
8607 
8608 extern const char wuffs_nie__error__bad_header[];
8609 extern const char wuffs_nie__error__unsupported_nie_file[];
8610 
8611 // ---------------- Public Consts
8612 
8613 #define WUFFS_NIE__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
8614 
8615 // ---------------- Struct Declarations
8616 
8617 typedef struct wuffs_nie__decoder__struct wuffs_nie__decoder;
8618 
8619 #ifdef __cplusplus
8620 extern "C" {
8621 #endif
8622 
8623 // ---------------- Public Initializer Prototypes
8624 
8625 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
8626 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
8627 //
8628 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
8629 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
8630 
8631 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
8632 wuffs_nie__decoder__initialize(
8633     wuffs_nie__decoder* self,
8634     size_t sizeof_star_self,
8635     uint64_t wuffs_version,
8636     uint32_t options);
8637 
8638 size_t
8639 sizeof__wuffs_nie__decoder();
8640 
8641 // ---------------- Allocs
8642 
8643 // These functions allocate and initialize Wuffs structs. They return NULL if
8644 // memory allocation fails. If they return non-NULL, there is no need to call
8645 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
8646 // calling free on the returned pointer. That pointer is effectively a C++
8647 // std::unique_ptr<T, decltype(&free)>.
8648 
8649 wuffs_nie__decoder*
8650 wuffs_nie__decoder__alloc();
8651 
8652 static inline wuffs_base__image_decoder*
wuffs_nie__decoder__alloc_as__wuffs_base__image_decoder()8653 wuffs_nie__decoder__alloc_as__wuffs_base__image_decoder() {
8654   return (wuffs_base__image_decoder*)(wuffs_nie__decoder__alloc());
8655 }
8656 
8657 // ---------------- Upcasts
8658 
8659 static inline wuffs_base__image_decoder*
wuffs_nie__decoder__upcast_as__wuffs_base__image_decoder(wuffs_nie__decoder * p)8660 wuffs_nie__decoder__upcast_as__wuffs_base__image_decoder(
8661     wuffs_nie__decoder* p) {
8662   return (wuffs_base__image_decoder*)p;
8663 }
8664 
8665 // ---------------- Public Function Prototypes
8666 
8667 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
8668 wuffs_nie__decoder__set_quirk_enabled(
8669     wuffs_nie__decoder* self,
8670     uint32_t a_quirk,
8671     bool a_enabled);
8672 
8673 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8674 wuffs_nie__decoder__decode_image_config(
8675     wuffs_nie__decoder* self,
8676     wuffs_base__image_config* a_dst,
8677     wuffs_base__io_buffer* a_src);
8678 
8679 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8680 wuffs_nie__decoder__decode_frame_config(
8681     wuffs_nie__decoder* self,
8682     wuffs_base__frame_config* a_dst,
8683     wuffs_base__io_buffer* a_src);
8684 
8685 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8686 wuffs_nie__decoder__decode_frame(
8687     wuffs_nie__decoder* self,
8688     wuffs_base__pixel_buffer* a_dst,
8689     wuffs_base__io_buffer* a_src,
8690     wuffs_base__pixel_blend a_blend,
8691     wuffs_base__slice_u8 a_workbuf,
8692     wuffs_base__decode_frame_options* a_opts);
8693 
8694 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
8695 wuffs_nie__decoder__frame_dirty_rect(
8696     const wuffs_nie__decoder* self);
8697 
8698 WUFFS_BASE__MAYBE_STATIC uint32_t
8699 wuffs_nie__decoder__num_animation_loops(
8700     const wuffs_nie__decoder* self);
8701 
8702 WUFFS_BASE__MAYBE_STATIC uint64_t
8703 wuffs_nie__decoder__num_decoded_frame_configs(
8704     const wuffs_nie__decoder* self);
8705 
8706 WUFFS_BASE__MAYBE_STATIC uint64_t
8707 wuffs_nie__decoder__num_decoded_frames(
8708     const wuffs_nie__decoder* self);
8709 
8710 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8711 wuffs_nie__decoder__restart_frame(
8712     wuffs_nie__decoder* self,
8713     uint64_t a_index,
8714     uint64_t a_io_position);
8715 
8716 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
8717 wuffs_nie__decoder__set_report_metadata(
8718     wuffs_nie__decoder* self,
8719     uint32_t a_fourcc,
8720     bool a_report);
8721 
8722 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8723 wuffs_nie__decoder__tell_me_more(
8724     wuffs_nie__decoder* self,
8725     wuffs_base__io_buffer* a_dst,
8726     wuffs_base__more_information* a_minfo,
8727     wuffs_base__io_buffer* a_src);
8728 
8729 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
8730 wuffs_nie__decoder__workbuf_len(
8731     const wuffs_nie__decoder* self);
8732 
8733 #ifdef __cplusplus
8734 }  // extern "C"
8735 #endif
8736 
8737 // ---------------- Struct Definitions
8738 
8739 // These structs' fields, and the sizeof them, are private implementation
8740 // details that aren't guaranteed to be stable across Wuffs versions.
8741 //
8742 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
8743 
8744 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
8745 
8746 struct wuffs_nie__decoder__struct {
8747   // Do not access the private_impl's or private_data's fields directly. There
8748   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
8749   // the wuffs_foo__bar__baz functions.
8750   //
8751   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
8752   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
8753 
8754   struct {
8755     uint32_t magic;
8756     uint32_t active_coroutine;
8757     wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
8758     wuffs_base__vtable null_vtable;
8759 
8760     uint32_t f_pixfmt;
8761     uint32_t f_width;
8762     uint32_t f_height;
8763     uint8_t f_call_sequence;
8764     uint32_t f_dst_x;
8765     uint32_t f_dst_y;
8766     wuffs_base__pixel_swizzler f_swizzler;
8767 
8768     uint32_t p_decode_image_config[1];
8769     uint32_t p_decode_frame_config[1];
8770     uint32_t p_decode_frame[1];
8771   } private_impl;
8772 
8773   struct {
8774     struct {
8775       uint64_t scratch;
8776     } s_decode_image_config[1];
8777   } private_data;
8778 
8779 #ifdef __cplusplus
8780 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
8781   using unique_ptr = std::unique_ptr<wuffs_nie__decoder, decltype(&free)>;
8782 
8783   // On failure, the alloc_etc functions return nullptr. They don't throw.
8784 
8785   static inline unique_ptr
allocwuffs_nie__decoder__struct8786   alloc() {
8787     return unique_ptr(wuffs_nie__decoder__alloc(), &free);
8788   }
8789 
8790   static inline wuffs_base__image_decoder::unique_ptr
alloc_as__wuffs_base__image_decoderwuffs_nie__decoder__struct8791   alloc_as__wuffs_base__image_decoder() {
8792     return wuffs_base__image_decoder::unique_ptr(
8793         wuffs_nie__decoder__alloc_as__wuffs_base__image_decoder(), &free);
8794   }
8795 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
8796 
8797 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
8798   // Disallow constructing or copying an object via standard C++ mechanisms,
8799   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
8800   // size and field layout is not part of the public, stable, memory-safe API.
8801   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
8802   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
8803   // their first argument) rather than tweaking bar.private_impl.qux fields.
8804   //
8805   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
8806   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
8807   // order to provide convenience methods. These forward on "this", so that you
8808   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
8809   wuffs_nie__decoder__struct() = delete;
8810   wuffs_nie__decoder__struct(const wuffs_nie__decoder__struct&) = delete;
8811   wuffs_nie__decoder__struct& operator=(
8812       const wuffs_nie__decoder__struct&) = delete;
8813 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
8814 
8815 #if !defined(WUFFS_IMPLEMENTATION)
8816   // As above, the size of the struct is not part of the public API, and unless
8817   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
8818   // allocated, not stack allocated. Its size is not intended to be known at
8819   // compile time, but it is unfortunately divulged as a side effect of
8820   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
8821   // instead of "sizeof T", invoking the operator. To make the two values
8822   // different, so that passing the latter will be rejected by the initialize
8823   // function, we add an arbitrary amount of dead weight.
8824   uint8_t dead_weight[123000000];  // 123 MB.
8825 #endif  // !defined(WUFFS_IMPLEMENTATION)
8826 
8827   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_nie__decoder__struct8828   initialize(
8829       size_t sizeof_star_self,
8830       uint64_t wuffs_version,
8831       uint32_t options) {
8832     return wuffs_nie__decoder__initialize(
8833         this, sizeof_star_self, wuffs_version, options);
8834   }
8835 
8836   inline wuffs_base__image_decoder*
upcast_as__wuffs_base__image_decoderwuffs_nie__decoder__struct8837   upcast_as__wuffs_base__image_decoder() {
8838     return (wuffs_base__image_decoder*)this;
8839   }
8840 
8841   inline wuffs_base__empty_struct
set_quirk_enabledwuffs_nie__decoder__struct8842   set_quirk_enabled(
8843       uint32_t a_quirk,
8844       bool a_enabled) {
8845     return wuffs_nie__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
8846   }
8847 
8848   inline wuffs_base__status
decode_image_configwuffs_nie__decoder__struct8849   decode_image_config(
8850       wuffs_base__image_config* a_dst,
8851       wuffs_base__io_buffer* a_src) {
8852     return wuffs_nie__decoder__decode_image_config(this, a_dst, a_src);
8853   }
8854 
8855   inline wuffs_base__status
decode_frame_configwuffs_nie__decoder__struct8856   decode_frame_config(
8857       wuffs_base__frame_config* a_dst,
8858       wuffs_base__io_buffer* a_src) {
8859     return wuffs_nie__decoder__decode_frame_config(this, a_dst, a_src);
8860   }
8861 
8862   inline wuffs_base__status
decode_framewuffs_nie__decoder__struct8863   decode_frame(
8864       wuffs_base__pixel_buffer* a_dst,
8865       wuffs_base__io_buffer* a_src,
8866       wuffs_base__pixel_blend a_blend,
8867       wuffs_base__slice_u8 a_workbuf,
8868       wuffs_base__decode_frame_options* a_opts) {
8869     return wuffs_nie__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
8870   }
8871 
8872   inline wuffs_base__rect_ie_u32
frame_dirty_rectwuffs_nie__decoder__struct8873   frame_dirty_rect() const {
8874     return wuffs_nie__decoder__frame_dirty_rect(this);
8875   }
8876 
8877   inline uint32_t
num_animation_loopswuffs_nie__decoder__struct8878   num_animation_loops() const {
8879     return wuffs_nie__decoder__num_animation_loops(this);
8880   }
8881 
8882   inline uint64_t
num_decoded_frame_configswuffs_nie__decoder__struct8883   num_decoded_frame_configs() const {
8884     return wuffs_nie__decoder__num_decoded_frame_configs(this);
8885   }
8886 
8887   inline uint64_t
num_decoded_frameswuffs_nie__decoder__struct8888   num_decoded_frames() const {
8889     return wuffs_nie__decoder__num_decoded_frames(this);
8890   }
8891 
8892   inline wuffs_base__status
restart_framewuffs_nie__decoder__struct8893   restart_frame(
8894       uint64_t a_index,
8895       uint64_t a_io_position) {
8896     return wuffs_nie__decoder__restart_frame(this, a_index, a_io_position);
8897   }
8898 
8899   inline wuffs_base__empty_struct
set_report_metadatawuffs_nie__decoder__struct8900   set_report_metadata(
8901       uint32_t a_fourcc,
8902       bool a_report) {
8903     return wuffs_nie__decoder__set_report_metadata(this, a_fourcc, a_report);
8904   }
8905 
8906   inline wuffs_base__status
tell_me_morewuffs_nie__decoder__struct8907   tell_me_more(
8908       wuffs_base__io_buffer* a_dst,
8909       wuffs_base__more_information* a_minfo,
8910       wuffs_base__io_buffer* a_src) {
8911     return wuffs_nie__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
8912   }
8913 
8914   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_nie__decoder__struct8915   workbuf_len() const {
8916     return wuffs_nie__decoder__workbuf_len(this);
8917   }
8918 
8919 #endif  // __cplusplus
8920 };  // struct wuffs_nie__decoder__struct
8921 
8922 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
8923 
8924 // ---------------- Status Codes
8925 
8926 extern const char wuffs_zlib__note__dictionary_required[];
8927 extern const char wuffs_zlib__error__bad_checksum[];
8928 extern const char wuffs_zlib__error__bad_compression_method[];
8929 extern const char wuffs_zlib__error__bad_compression_window_size[];
8930 extern const char wuffs_zlib__error__bad_parity_check[];
8931 extern const char wuffs_zlib__error__incorrect_dictionary[];
8932 
8933 // ---------------- Public Consts
8934 
8935 #define WUFFS_ZLIB__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 1
8936 
8937 // ---------------- Struct Declarations
8938 
8939 typedef struct wuffs_zlib__decoder__struct wuffs_zlib__decoder;
8940 
8941 #ifdef __cplusplus
8942 extern "C" {
8943 #endif
8944 
8945 // ---------------- Public Initializer Prototypes
8946 
8947 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
8948 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
8949 //
8950 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
8951 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
8952 
8953 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
8954 wuffs_zlib__decoder__initialize(
8955     wuffs_zlib__decoder* self,
8956     size_t sizeof_star_self,
8957     uint64_t wuffs_version,
8958     uint32_t options);
8959 
8960 size_t
8961 sizeof__wuffs_zlib__decoder();
8962 
8963 // ---------------- Allocs
8964 
8965 // These functions allocate and initialize Wuffs structs. They return NULL if
8966 // memory allocation fails. If they return non-NULL, there is no need to call
8967 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
8968 // calling free on the returned pointer. That pointer is effectively a C++
8969 // std::unique_ptr<T, decltype(&free)>.
8970 
8971 wuffs_zlib__decoder*
8972 wuffs_zlib__decoder__alloc();
8973 
8974 static inline wuffs_base__io_transformer*
wuffs_zlib__decoder__alloc_as__wuffs_base__io_transformer()8975 wuffs_zlib__decoder__alloc_as__wuffs_base__io_transformer() {
8976   return (wuffs_base__io_transformer*)(wuffs_zlib__decoder__alloc());
8977 }
8978 
8979 // ---------------- Upcasts
8980 
8981 static inline wuffs_base__io_transformer*
wuffs_zlib__decoder__upcast_as__wuffs_base__io_transformer(wuffs_zlib__decoder * p)8982 wuffs_zlib__decoder__upcast_as__wuffs_base__io_transformer(
8983     wuffs_zlib__decoder* p) {
8984   return (wuffs_base__io_transformer*)p;
8985 }
8986 
8987 // ---------------- Public Function Prototypes
8988 
8989 WUFFS_BASE__MAYBE_STATIC uint32_t
8990 wuffs_zlib__decoder__dictionary_id(
8991     const wuffs_zlib__decoder* self);
8992 
8993 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
8994 wuffs_zlib__decoder__add_dictionary(
8995     wuffs_zlib__decoder* self,
8996     wuffs_base__slice_u8 a_dict);
8997 
8998 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
8999 wuffs_zlib__decoder__set_quirk_enabled(
9000     wuffs_zlib__decoder* self,
9001     uint32_t a_quirk,
9002     bool a_enabled);
9003 
9004 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
9005 wuffs_zlib__decoder__workbuf_len(
9006     const wuffs_zlib__decoder* self);
9007 
9008 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9009 wuffs_zlib__decoder__transform_io(
9010     wuffs_zlib__decoder* self,
9011     wuffs_base__io_buffer* a_dst,
9012     wuffs_base__io_buffer* a_src,
9013     wuffs_base__slice_u8 a_workbuf);
9014 
9015 #ifdef __cplusplus
9016 }  // extern "C"
9017 #endif
9018 
9019 // ---------------- Struct Definitions
9020 
9021 // These structs' fields, and the sizeof them, are private implementation
9022 // details that aren't guaranteed to be stable across Wuffs versions.
9023 //
9024 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
9025 
9026 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
9027 
9028 struct wuffs_zlib__decoder__struct {
9029   // Do not access the private_impl's or private_data's fields directly. There
9030   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
9031   // the wuffs_foo__bar__baz functions.
9032   //
9033   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
9034   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
9035 
9036   struct {
9037     uint32_t magic;
9038     uint32_t active_coroutine;
9039     wuffs_base__vtable vtable_for__wuffs_base__io_transformer;
9040     wuffs_base__vtable null_vtable;
9041 
9042     bool f_bad_call_sequence;
9043     bool f_header_complete;
9044     bool f_got_dictionary;
9045     bool f_want_dictionary;
9046     bool f_ignore_checksum;
9047     uint32_t f_dict_id_got;
9048     uint32_t f_dict_id_want;
9049 
9050     uint32_t p_transform_io[1];
9051   } private_impl;
9052 
9053   struct {
9054     wuffs_adler32__hasher f_checksum;
9055     wuffs_adler32__hasher f_dict_id_hasher;
9056     wuffs_deflate__decoder f_flate;
9057 
9058     struct {
9059       uint32_t v_checksum_got;
9060       uint64_t scratch;
9061     } s_transform_io[1];
9062   } private_data;
9063 
9064 #ifdef __cplusplus
9065 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
9066   using unique_ptr = std::unique_ptr<wuffs_zlib__decoder, decltype(&free)>;
9067 
9068   // On failure, the alloc_etc functions return nullptr. They don't throw.
9069 
9070   static inline unique_ptr
allocwuffs_zlib__decoder__struct9071   alloc() {
9072     return unique_ptr(wuffs_zlib__decoder__alloc(), &free);
9073   }
9074 
9075   static inline wuffs_base__io_transformer::unique_ptr
alloc_as__wuffs_base__io_transformerwuffs_zlib__decoder__struct9076   alloc_as__wuffs_base__io_transformer() {
9077     return wuffs_base__io_transformer::unique_ptr(
9078         wuffs_zlib__decoder__alloc_as__wuffs_base__io_transformer(), &free);
9079   }
9080 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
9081 
9082 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
9083   // Disallow constructing or copying an object via standard C++ mechanisms,
9084   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
9085   // size and field layout is not part of the public, stable, memory-safe API.
9086   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
9087   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
9088   // their first argument) rather than tweaking bar.private_impl.qux fields.
9089   //
9090   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
9091   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
9092   // order to provide convenience methods. These forward on "this", so that you
9093   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
9094   wuffs_zlib__decoder__struct() = delete;
9095   wuffs_zlib__decoder__struct(const wuffs_zlib__decoder__struct&) = delete;
9096   wuffs_zlib__decoder__struct& operator=(
9097       const wuffs_zlib__decoder__struct&) = delete;
9098 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
9099 
9100 #if !defined(WUFFS_IMPLEMENTATION)
9101   // As above, the size of the struct is not part of the public API, and unless
9102   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
9103   // allocated, not stack allocated. Its size is not intended to be known at
9104   // compile time, but it is unfortunately divulged as a side effect of
9105   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
9106   // instead of "sizeof T", invoking the operator. To make the two values
9107   // different, so that passing the latter will be rejected by the initialize
9108   // function, we add an arbitrary amount of dead weight.
9109   uint8_t dead_weight[123000000];  // 123 MB.
9110 #endif  // !defined(WUFFS_IMPLEMENTATION)
9111 
9112   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_zlib__decoder__struct9113   initialize(
9114       size_t sizeof_star_self,
9115       uint64_t wuffs_version,
9116       uint32_t options) {
9117     return wuffs_zlib__decoder__initialize(
9118         this, sizeof_star_self, wuffs_version, options);
9119   }
9120 
9121   inline wuffs_base__io_transformer*
upcast_as__wuffs_base__io_transformerwuffs_zlib__decoder__struct9122   upcast_as__wuffs_base__io_transformer() {
9123     return (wuffs_base__io_transformer*)this;
9124   }
9125 
9126   inline uint32_t
dictionary_idwuffs_zlib__decoder__struct9127   dictionary_id() const {
9128     return wuffs_zlib__decoder__dictionary_id(this);
9129   }
9130 
9131   inline wuffs_base__empty_struct
add_dictionarywuffs_zlib__decoder__struct9132   add_dictionary(
9133       wuffs_base__slice_u8 a_dict) {
9134     return wuffs_zlib__decoder__add_dictionary(this, a_dict);
9135   }
9136 
9137   inline wuffs_base__empty_struct
set_quirk_enabledwuffs_zlib__decoder__struct9138   set_quirk_enabled(
9139       uint32_t a_quirk,
9140       bool a_enabled) {
9141     return wuffs_zlib__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
9142   }
9143 
9144   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_zlib__decoder__struct9145   workbuf_len() const {
9146     return wuffs_zlib__decoder__workbuf_len(this);
9147   }
9148 
9149   inline wuffs_base__status
transform_iowuffs_zlib__decoder__struct9150   transform_io(
9151       wuffs_base__io_buffer* a_dst,
9152       wuffs_base__io_buffer* a_src,
9153       wuffs_base__slice_u8 a_workbuf) {
9154     return wuffs_zlib__decoder__transform_io(this, a_dst, a_src, a_workbuf);
9155   }
9156 
9157 #endif  // __cplusplus
9158 };  // struct wuffs_zlib__decoder__struct
9159 
9160 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
9161 
9162 // ---------------- Status Codes
9163 
9164 extern const char wuffs_png__error__bad_animation_sequence_number[];
9165 extern const char wuffs_png__error__bad_checksum[];
9166 extern const char wuffs_png__error__bad_chunk[];
9167 extern const char wuffs_png__error__bad_filter[];
9168 extern const char wuffs_png__error__bad_header[];
9169 extern const char wuffs_png__error__bad_text_chunk_not_latin_1[];
9170 extern const char wuffs_png__error__missing_palette[];
9171 extern const char wuffs_png__error__unsupported_png_compression_method[];
9172 extern const char wuffs_png__error__unsupported_png_file[];
9173 
9174 // ---------------- Public Consts
9175 
9176 #define WUFFS_PNG__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
9177 
9178 #define WUFFS_PNG__DECODER_SRC_IO_BUFFER_LENGTH_MIN_INCL 8
9179 
9180 // ---------------- Struct Declarations
9181 
9182 typedef struct wuffs_png__decoder__struct wuffs_png__decoder;
9183 
9184 #ifdef __cplusplus
9185 extern "C" {
9186 #endif
9187 
9188 // ---------------- Public Initializer Prototypes
9189 
9190 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
9191 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
9192 //
9193 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
9194 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
9195 
9196 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
9197 wuffs_png__decoder__initialize(
9198     wuffs_png__decoder* self,
9199     size_t sizeof_star_self,
9200     uint64_t wuffs_version,
9201     uint32_t options);
9202 
9203 size_t
9204 sizeof__wuffs_png__decoder();
9205 
9206 // ---------------- Allocs
9207 
9208 // These functions allocate and initialize Wuffs structs. They return NULL if
9209 // memory allocation fails. If they return non-NULL, there is no need to call
9210 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
9211 // calling free on the returned pointer. That pointer is effectively a C++
9212 // std::unique_ptr<T, decltype(&free)>.
9213 
9214 wuffs_png__decoder*
9215 wuffs_png__decoder__alloc();
9216 
9217 static inline wuffs_base__image_decoder*
wuffs_png__decoder__alloc_as__wuffs_base__image_decoder()9218 wuffs_png__decoder__alloc_as__wuffs_base__image_decoder() {
9219   return (wuffs_base__image_decoder*)(wuffs_png__decoder__alloc());
9220 }
9221 
9222 // ---------------- Upcasts
9223 
9224 static inline wuffs_base__image_decoder*
wuffs_png__decoder__upcast_as__wuffs_base__image_decoder(wuffs_png__decoder * p)9225 wuffs_png__decoder__upcast_as__wuffs_base__image_decoder(
9226     wuffs_png__decoder* p) {
9227   return (wuffs_base__image_decoder*)p;
9228 }
9229 
9230 // ---------------- Public Function Prototypes
9231 
9232 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
9233 wuffs_png__decoder__set_quirk_enabled(
9234     wuffs_png__decoder* self,
9235     uint32_t a_quirk,
9236     bool a_enabled);
9237 
9238 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9239 wuffs_png__decoder__decode_image_config(
9240     wuffs_png__decoder* self,
9241     wuffs_base__image_config* a_dst,
9242     wuffs_base__io_buffer* a_src);
9243 
9244 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9245 wuffs_png__decoder__decode_frame_config(
9246     wuffs_png__decoder* self,
9247     wuffs_base__frame_config* a_dst,
9248     wuffs_base__io_buffer* a_src);
9249 
9250 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9251 wuffs_png__decoder__decode_frame(
9252     wuffs_png__decoder* self,
9253     wuffs_base__pixel_buffer* a_dst,
9254     wuffs_base__io_buffer* a_src,
9255     wuffs_base__pixel_blend a_blend,
9256     wuffs_base__slice_u8 a_workbuf,
9257     wuffs_base__decode_frame_options* a_opts);
9258 
9259 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
9260 wuffs_png__decoder__frame_dirty_rect(
9261     const wuffs_png__decoder* self);
9262 
9263 WUFFS_BASE__MAYBE_STATIC uint32_t
9264 wuffs_png__decoder__num_animation_loops(
9265     const wuffs_png__decoder* self);
9266 
9267 WUFFS_BASE__MAYBE_STATIC uint64_t
9268 wuffs_png__decoder__num_decoded_frame_configs(
9269     const wuffs_png__decoder* self);
9270 
9271 WUFFS_BASE__MAYBE_STATIC uint64_t
9272 wuffs_png__decoder__num_decoded_frames(
9273     const wuffs_png__decoder* self);
9274 
9275 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9276 wuffs_png__decoder__restart_frame(
9277     wuffs_png__decoder* self,
9278     uint64_t a_index,
9279     uint64_t a_io_position);
9280 
9281 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
9282 wuffs_png__decoder__set_report_metadata(
9283     wuffs_png__decoder* self,
9284     uint32_t a_fourcc,
9285     bool a_report);
9286 
9287 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9288 wuffs_png__decoder__tell_me_more(
9289     wuffs_png__decoder* self,
9290     wuffs_base__io_buffer* a_dst,
9291     wuffs_base__more_information* a_minfo,
9292     wuffs_base__io_buffer* a_src);
9293 
9294 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
9295 wuffs_png__decoder__workbuf_len(
9296     const wuffs_png__decoder* self);
9297 
9298 #ifdef __cplusplus
9299 }  // extern "C"
9300 #endif
9301 
9302 // ---------------- Struct Definitions
9303 
9304 // These structs' fields, and the sizeof them, are private implementation
9305 // details that aren't guaranteed to be stable across Wuffs versions.
9306 //
9307 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
9308 
9309 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
9310 
9311 struct wuffs_png__decoder__struct {
9312   // Do not access the private_impl's or private_data's fields directly. There
9313   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
9314   // the wuffs_foo__bar__baz functions.
9315   //
9316   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
9317   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
9318 
9319   struct {
9320     uint32_t magic;
9321     uint32_t active_coroutine;
9322     wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
9323     wuffs_base__vtable null_vtable;
9324 
9325     uint32_t f_width;
9326     uint32_t f_height;
9327     uint64_t f_pass_bytes_per_row;
9328     uint64_t f_workbuf_wi;
9329     uint64_t f_workbuf_hist_pos_base;
9330     uint64_t f_overall_workbuf_length;
9331     uint64_t f_pass_workbuf_length;
9332     uint8_t f_call_sequence;
9333     bool f_report_metadata_chrm;
9334     bool f_report_metadata_gama;
9335     bool f_report_metadata_iccp;
9336     bool f_report_metadata_kvp;
9337     bool f_report_metadata_srgb;
9338     bool f_ignore_checksum;
9339     uint8_t f_depth;
9340     uint8_t f_color_type;
9341     uint8_t f_filter_distance;
9342     uint8_t f_interlace_pass;
9343     bool f_seen_actl;
9344     bool f_seen_chrm;
9345     bool f_seen_fctl;
9346     bool f_seen_gama;
9347     bool f_seen_iccp;
9348     bool f_seen_idat;
9349     bool f_seen_plte;
9350     bool f_seen_srgb;
9351     bool f_seen_trns;
9352     bool f_metadata_is_zlib_compressed;
9353     bool f_zlib_is_dirty;
9354     uint32_t f_chunk_type;
9355     uint8_t f_chunk_type_array[4];
9356     uint32_t f_chunk_length;
9357     uint64_t f_remap_transparency;
9358     uint32_t f_dst_pixfmt;
9359     uint32_t f_src_pixfmt;
9360     uint32_t f_num_animation_frames_value;
9361     uint32_t f_num_animation_loops_value;
9362     uint32_t f_num_decoded_frame_configs_value;
9363     uint32_t f_num_decoded_frames_value;
9364     uint32_t f_frame_rect_x0;
9365     uint32_t f_frame_rect_y0;
9366     uint32_t f_frame_rect_x1;
9367     uint32_t f_frame_rect_y1;
9368     uint32_t f_first_rect_x0;
9369     uint32_t f_first_rect_y0;
9370     uint32_t f_first_rect_x1;
9371     uint32_t f_first_rect_y1;
9372     uint64_t f_frame_config_io_position;
9373     uint64_t f_first_config_io_position;
9374     uint64_t f_frame_duration;
9375     uint64_t f_first_duration;
9376     uint8_t f_frame_disposal;
9377     uint8_t f_first_disposal;
9378     bool f_frame_overwrite_instead_of_blend;
9379     bool f_first_overwrite_instead_of_blend;
9380     uint32_t f_next_animation_seq_num;
9381     uint32_t f_metadata_flavor;
9382     uint32_t f_metadata_fourcc;
9383     uint64_t f_metadata_x;
9384     uint64_t f_metadata_y;
9385     uint64_t f_metadata_z;
9386     uint32_t f_ztxt_ri;
9387     uint32_t f_ztxt_wi;
9388     uint64_t f_ztxt_hist_pos;
9389     wuffs_base__pixel_swizzler f_swizzler;
9390 
9391     wuffs_base__empty_struct (*choosy_filter_1)(
9392         wuffs_png__decoder* self,
9393         wuffs_base__slice_u8 a_curr);
9394     wuffs_base__empty_struct (*choosy_filter_3)(
9395         wuffs_png__decoder* self,
9396         wuffs_base__slice_u8 a_curr,
9397         wuffs_base__slice_u8 a_prev);
9398     wuffs_base__empty_struct (*choosy_filter_4)(
9399         wuffs_png__decoder* self,
9400         wuffs_base__slice_u8 a_curr,
9401         wuffs_base__slice_u8 a_prev);
9402     uint32_t p_decode_image_config[1];
9403     uint32_t p_decode_ihdr[1];
9404     uint32_t p_decode_other_chunk[1];
9405     uint32_t p_decode_actl[1];
9406     uint32_t p_decode_chrm[1];
9407     uint32_t p_decode_fctl[1];
9408     uint32_t p_decode_gama[1];
9409     uint32_t p_decode_iccp[1];
9410     uint32_t p_decode_plte[1];
9411     uint32_t p_decode_srgb[1];
9412     uint32_t p_decode_trns[1];
9413     uint32_t p_decode_frame_config[1];
9414     uint32_t p_skip_frame[1];
9415     uint32_t p_decode_frame[1];
9416     uint32_t p_decode_pass[1];
9417     uint32_t p_tell_me_more[1];
9418     wuffs_base__status (*choosy_filter_and_swizzle)(
9419         wuffs_png__decoder* self,
9420         wuffs_base__pixel_buffer* a_dst,
9421         wuffs_base__slice_u8 a_workbuf);
9422   } private_impl;
9423 
9424   struct {
9425     wuffs_crc32__ieee_hasher f_crc32;
9426     wuffs_zlib__decoder f_zlib;
9427     uint8_t f_dst_palette[1024];
9428     uint8_t f_src_palette[1024];
9429 
9430     struct {
9431       uint32_t v_checksum_have;
9432       uint64_t scratch;
9433     } s_decode_image_config[1];
9434     struct {
9435       uint64_t scratch;
9436     } s_decode_ihdr[1];
9437     struct {
9438       uint64_t scratch;
9439     } s_decode_other_chunk[1];
9440     struct {
9441       uint64_t scratch;
9442     } s_decode_actl[1];
9443     struct {
9444       uint64_t scratch;
9445     } s_decode_chrm[1];
9446     struct {
9447       uint32_t v_x0;
9448       uint32_t v_x1;
9449       uint32_t v_y1;
9450       uint64_t scratch;
9451     } s_decode_fctl[1];
9452     struct {
9453       uint64_t scratch;
9454     } s_decode_gama[1];
9455     struct {
9456       uint32_t v_num_entries;
9457       uint32_t v_i;
9458       uint64_t scratch;
9459     } s_decode_plte[1];
9460     struct {
9461       uint32_t v_i;
9462       uint32_t v_n;
9463       uint64_t scratch;
9464     } s_decode_trns[1];
9465     struct {
9466       uint64_t scratch;
9467     } s_decode_frame_config[1];
9468     struct {
9469       uint64_t scratch;
9470     } s_skip_frame[1];
9471     struct {
9472       uint64_t scratch;
9473     } s_decode_frame[1];
9474     struct {
9475       uint64_t scratch;
9476     } s_decode_pass[1];
9477     struct {
9478       wuffs_base__status v_zlib_status;
9479       uint64_t scratch;
9480     } s_tell_me_more[1];
9481   } private_data;
9482 
9483 #ifdef __cplusplus
9484 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
9485   using unique_ptr = std::unique_ptr<wuffs_png__decoder, decltype(&free)>;
9486 
9487   // On failure, the alloc_etc functions return nullptr. They don't throw.
9488 
9489   static inline unique_ptr
allocwuffs_png__decoder__struct9490   alloc() {
9491     return unique_ptr(wuffs_png__decoder__alloc(), &free);
9492   }
9493 
9494   static inline wuffs_base__image_decoder::unique_ptr
alloc_as__wuffs_base__image_decoderwuffs_png__decoder__struct9495   alloc_as__wuffs_base__image_decoder() {
9496     return wuffs_base__image_decoder::unique_ptr(
9497         wuffs_png__decoder__alloc_as__wuffs_base__image_decoder(), &free);
9498   }
9499 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
9500 
9501 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
9502   // Disallow constructing or copying an object via standard C++ mechanisms,
9503   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
9504   // size and field layout is not part of the public, stable, memory-safe API.
9505   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
9506   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
9507   // their first argument) rather than tweaking bar.private_impl.qux fields.
9508   //
9509   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
9510   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
9511   // order to provide convenience methods. These forward on "this", so that you
9512   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
9513   wuffs_png__decoder__struct() = delete;
9514   wuffs_png__decoder__struct(const wuffs_png__decoder__struct&) = delete;
9515   wuffs_png__decoder__struct& operator=(
9516       const wuffs_png__decoder__struct&) = delete;
9517 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
9518 
9519 #if !defined(WUFFS_IMPLEMENTATION)
9520   // As above, the size of the struct is not part of the public API, and unless
9521   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
9522   // allocated, not stack allocated. Its size is not intended to be known at
9523   // compile time, but it is unfortunately divulged as a side effect of
9524   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
9525   // instead of "sizeof T", invoking the operator. To make the two values
9526   // different, so that passing the latter will be rejected by the initialize
9527   // function, we add an arbitrary amount of dead weight.
9528   uint8_t dead_weight[123000000];  // 123 MB.
9529 #endif  // !defined(WUFFS_IMPLEMENTATION)
9530 
9531   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_png__decoder__struct9532   initialize(
9533       size_t sizeof_star_self,
9534       uint64_t wuffs_version,
9535       uint32_t options) {
9536     return wuffs_png__decoder__initialize(
9537         this, sizeof_star_self, wuffs_version, options);
9538   }
9539 
9540   inline wuffs_base__image_decoder*
upcast_as__wuffs_base__image_decoderwuffs_png__decoder__struct9541   upcast_as__wuffs_base__image_decoder() {
9542     return (wuffs_base__image_decoder*)this;
9543   }
9544 
9545   inline wuffs_base__empty_struct
set_quirk_enabledwuffs_png__decoder__struct9546   set_quirk_enabled(
9547       uint32_t a_quirk,
9548       bool a_enabled) {
9549     return wuffs_png__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
9550   }
9551 
9552   inline wuffs_base__status
decode_image_configwuffs_png__decoder__struct9553   decode_image_config(
9554       wuffs_base__image_config* a_dst,
9555       wuffs_base__io_buffer* a_src) {
9556     return wuffs_png__decoder__decode_image_config(this, a_dst, a_src);
9557   }
9558 
9559   inline wuffs_base__status
decode_frame_configwuffs_png__decoder__struct9560   decode_frame_config(
9561       wuffs_base__frame_config* a_dst,
9562       wuffs_base__io_buffer* a_src) {
9563     return wuffs_png__decoder__decode_frame_config(this, a_dst, a_src);
9564   }
9565 
9566   inline wuffs_base__status
decode_framewuffs_png__decoder__struct9567   decode_frame(
9568       wuffs_base__pixel_buffer* a_dst,
9569       wuffs_base__io_buffer* a_src,
9570       wuffs_base__pixel_blend a_blend,
9571       wuffs_base__slice_u8 a_workbuf,
9572       wuffs_base__decode_frame_options* a_opts) {
9573     return wuffs_png__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
9574   }
9575 
9576   inline wuffs_base__rect_ie_u32
frame_dirty_rectwuffs_png__decoder__struct9577   frame_dirty_rect() const {
9578     return wuffs_png__decoder__frame_dirty_rect(this);
9579   }
9580 
9581   inline uint32_t
num_animation_loopswuffs_png__decoder__struct9582   num_animation_loops() const {
9583     return wuffs_png__decoder__num_animation_loops(this);
9584   }
9585 
9586   inline uint64_t
num_decoded_frame_configswuffs_png__decoder__struct9587   num_decoded_frame_configs() const {
9588     return wuffs_png__decoder__num_decoded_frame_configs(this);
9589   }
9590 
9591   inline uint64_t
num_decoded_frameswuffs_png__decoder__struct9592   num_decoded_frames() const {
9593     return wuffs_png__decoder__num_decoded_frames(this);
9594   }
9595 
9596   inline wuffs_base__status
restart_framewuffs_png__decoder__struct9597   restart_frame(
9598       uint64_t a_index,
9599       uint64_t a_io_position) {
9600     return wuffs_png__decoder__restart_frame(this, a_index, a_io_position);
9601   }
9602 
9603   inline wuffs_base__empty_struct
set_report_metadatawuffs_png__decoder__struct9604   set_report_metadata(
9605       uint32_t a_fourcc,
9606       bool a_report) {
9607     return wuffs_png__decoder__set_report_metadata(this, a_fourcc, a_report);
9608   }
9609 
9610   inline wuffs_base__status
tell_me_morewuffs_png__decoder__struct9611   tell_me_more(
9612       wuffs_base__io_buffer* a_dst,
9613       wuffs_base__more_information* a_minfo,
9614       wuffs_base__io_buffer* a_src) {
9615     return wuffs_png__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
9616   }
9617 
9618   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_png__decoder__struct9619   workbuf_len() const {
9620     return wuffs_png__decoder__workbuf_len(this);
9621   }
9622 
9623 #endif  // __cplusplus
9624 };  // struct wuffs_png__decoder__struct
9625 
9626 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
9627 
9628 // ---------------- Status Codes
9629 
9630 extern const char wuffs_wbmp__error__bad_header[];
9631 
9632 // ---------------- Public Consts
9633 
9634 #define WUFFS_WBMP__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
9635 
9636 // ---------------- Struct Declarations
9637 
9638 typedef struct wuffs_wbmp__decoder__struct wuffs_wbmp__decoder;
9639 
9640 #ifdef __cplusplus
9641 extern "C" {
9642 #endif
9643 
9644 // ---------------- Public Initializer Prototypes
9645 
9646 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
9647 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
9648 //
9649 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
9650 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
9651 
9652 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
9653 wuffs_wbmp__decoder__initialize(
9654     wuffs_wbmp__decoder* self,
9655     size_t sizeof_star_self,
9656     uint64_t wuffs_version,
9657     uint32_t options);
9658 
9659 size_t
9660 sizeof__wuffs_wbmp__decoder();
9661 
9662 // ---------------- Allocs
9663 
9664 // These functions allocate and initialize Wuffs structs. They return NULL if
9665 // memory allocation fails. If they return non-NULL, there is no need to call
9666 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
9667 // calling free on the returned pointer. That pointer is effectively a C++
9668 // std::unique_ptr<T, decltype(&free)>.
9669 
9670 wuffs_wbmp__decoder*
9671 wuffs_wbmp__decoder__alloc();
9672 
9673 static inline wuffs_base__image_decoder*
wuffs_wbmp__decoder__alloc_as__wuffs_base__image_decoder()9674 wuffs_wbmp__decoder__alloc_as__wuffs_base__image_decoder() {
9675   return (wuffs_base__image_decoder*)(wuffs_wbmp__decoder__alloc());
9676 }
9677 
9678 // ---------------- Upcasts
9679 
9680 static inline wuffs_base__image_decoder*
wuffs_wbmp__decoder__upcast_as__wuffs_base__image_decoder(wuffs_wbmp__decoder * p)9681 wuffs_wbmp__decoder__upcast_as__wuffs_base__image_decoder(
9682     wuffs_wbmp__decoder* p) {
9683   return (wuffs_base__image_decoder*)p;
9684 }
9685 
9686 // ---------------- Public Function Prototypes
9687 
9688 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
9689 wuffs_wbmp__decoder__set_quirk_enabled(
9690     wuffs_wbmp__decoder* self,
9691     uint32_t a_quirk,
9692     bool a_enabled);
9693 
9694 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9695 wuffs_wbmp__decoder__decode_image_config(
9696     wuffs_wbmp__decoder* self,
9697     wuffs_base__image_config* a_dst,
9698     wuffs_base__io_buffer* a_src);
9699 
9700 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9701 wuffs_wbmp__decoder__decode_frame_config(
9702     wuffs_wbmp__decoder* self,
9703     wuffs_base__frame_config* a_dst,
9704     wuffs_base__io_buffer* a_src);
9705 
9706 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9707 wuffs_wbmp__decoder__decode_frame(
9708     wuffs_wbmp__decoder* self,
9709     wuffs_base__pixel_buffer* a_dst,
9710     wuffs_base__io_buffer* a_src,
9711     wuffs_base__pixel_blend a_blend,
9712     wuffs_base__slice_u8 a_workbuf,
9713     wuffs_base__decode_frame_options* a_opts);
9714 
9715 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
9716 wuffs_wbmp__decoder__frame_dirty_rect(
9717     const wuffs_wbmp__decoder* self);
9718 
9719 WUFFS_BASE__MAYBE_STATIC uint32_t
9720 wuffs_wbmp__decoder__num_animation_loops(
9721     const wuffs_wbmp__decoder* self);
9722 
9723 WUFFS_BASE__MAYBE_STATIC uint64_t
9724 wuffs_wbmp__decoder__num_decoded_frame_configs(
9725     const wuffs_wbmp__decoder* self);
9726 
9727 WUFFS_BASE__MAYBE_STATIC uint64_t
9728 wuffs_wbmp__decoder__num_decoded_frames(
9729     const wuffs_wbmp__decoder* self);
9730 
9731 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9732 wuffs_wbmp__decoder__restart_frame(
9733     wuffs_wbmp__decoder* self,
9734     uint64_t a_index,
9735     uint64_t a_io_position);
9736 
9737 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
9738 wuffs_wbmp__decoder__set_report_metadata(
9739     wuffs_wbmp__decoder* self,
9740     uint32_t a_fourcc,
9741     bool a_report);
9742 
9743 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9744 wuffs_wbmp__decoder__tell_me_more(
9745     wuffs_wbmp__decoder* self,
9746     wuffs_base__io_buffer* a_dst,
9747     wuffs_base__more_information* a_minfo,
9748     wuffs_base__io_buffer* a_src);
9749 
9750 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
9751 wuffs_wbmp__decoder__workbuf_len(
9752     const wuffs_wbmp__decoder* self);
9753 
9754 #ifdef __cplusplus
9755 }  // extern "C"
9756 #endif
9757 
9758 // ---------------- Struct Definitions
9759 
9760 // These structs' fields, and the sizeof them, are private implementation
9761 // details that aren't guaranteed to be stable across Wuffs versions.
9762 //
9763 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
9764 
9765 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
9766 
9767 struct wuffs_wbmp__decoder__struct {
9768   // Do not access the private_impl's or private_data's fields directly. There
9769   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
9770   // the wuffs_foo__bar__baz functions.
9771   //
9772   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
9773   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
9774 
9775   struct {
9776     uint32_t magic;
9777     uint32_t active_coroutine;
9778     wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
9779     wuffs_base__vtable null_vtable;
9780 
9781     uint32_t f_width;
9782     uint32_t f_height;
9783     uint8_t f_call_sequence;
9784     uint64_t f_frame_config_io_position;
9785     wuffs_base__pixel_swizzler f_swizzler;
9786 
9787     uint32_t p_decode_image_config[1];
9788     uint32_t p_decode_frame_config[1];
9789     uint32_t p_decode_frame[1];
9790   } private_impl;
9791 
9792   struct {
9793     struct {
9794       uint32_t v_i;
9795       uint32_t v_x32;
9796     } s_decode_image_config[1];
9797     struct {
9798       uint64_t v_dst_bytes_per_pixel;
9799       uint32_t v_dst_x;
9800       uint32_t v_dst_y;
9801       uint8_t v_src[1];
9802       uint8_t v_c;
9803     } s_decode_frame[1];
9804   } private_data;
9805 
9806 #ifdef __cplusplus
9807 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
9808   using unique_ptr = std::unique_ptr<wuffs_wbmp__decoder, decltype(&free)>;
9809 
9810   // On failure, the alloc_etc functions return nullptr. They don't throw.
9811 
9812   static inline unique_ptr
allocwuffs_wbmp__decoder__struct9813   alloc() {
9814     return unique_ptr(wuffs_wbmp__decoder__alloc(), &free);
9815   }
9816 
9817   static inline wuffs_base__image_decoder::unique_ptr
alloc_as__wuffs_base__image_decoderwuffs_wbmp__decoder__struct9818   alloc_as__wuffs_base__image_decoder() {
9819     return wuffs_base__image_decoder::unique_ptr(
9820         wuffs_wbmp__decoder__alloc_as__wuffs_base__image_decoder(), &free);
9821   }
9822 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
9823 
9824 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
9825   // Disallow constructing or copying an object via standard C++ mechanisms,
9826   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
9827   // size and field layout is not part of the public, stable, memory-safe API.
9828   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
9829   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
9830   // their first argument) rather than tweaking bar.private_impl.qux fields.
9831   //
9832   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
9833   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
9834   // order to provide convenience methods. These forward on "this", so that you
9835   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
9836   wuffs_wbmp__decoder__struct() = delete;
9837   wuffs_wbmp__decoder__struct(const wuffs_wbmp__decoder__struct&) = delete;
9838   wuffs_wbmp__decoder__struct& operator=(
9839       const wuffs_wbmp__decoder__struct&) = delete;
9840 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
9841 
9842 #if !defined(WUFFS_IMPLEMENTATION)
9843   // As above, the size of the struct is not part of the public API, and unless
9844   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
9845   // allocated, not stack allocated. Its size is not intended to be known at
9846   // compile time, but it is unfortunately divulged as a side effect of
9847   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
9848   // instead of "sizeof T", invoking the operator. To make the two values
9849   // different, so that passing the latter will be rejected by the initialize
9850   // function, we add an arbitrary amount of dead weight.
9851   uint8_t dead_weight[123000000];  // 123 MB.
9852 #endif  // !defined(WUFFS_IMPLEMENTATION)
9853 
9854   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_wbmp__decoder__struct9855   initialize(
9856       size_t sizeof_star_self,
9857       uint64_t wuffs_version,
9858       uint32_t options) {
9859     return wuffs_wbmp__decoder__initialize(
9860         this, sizeof_star_self, wuffs_version, options);
9861   }
9862 
9863   inline wuffs_base__image_decoder*
upcast_as__wuffs_base__image_decoderwuffs_wbmp__decoder__struct9864   upcast_as__wuffs_base__image_decoder() {
9865     return (wuffs_base__image_decoder*)this;
9866   }
9867 
9868   inline wuffs_base__empty_struct
set_quirk_enabledwuffs_wbmp__decoder__struct9869   set_quirk_enabled(
9870       uint32_t a_quirk,
9871       bool a_enabled) {
9872     return wuffs_wbmp__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
9873   }
9874 
9875   inline wuffs_base__status
decode_image_configwuffs_wbmp__decoder__struct9876   decode_image_config(
9877       wuffs_base__image_config* a_dst,
9878       wuffs_base__io_buffer* a_src) {
9879     return wuffs_wbmp__decoder__decode_image_config(this, a_dst, a_src);
9880   }
9881 
9882   inline wuffs_base__status
decode_frame_configwuffs_wbmp__decoder__struct9883   decode_frame_config(
9884       wuffs_base__frame_config* a_dst,
9885       wuffs_base__io_buffer* a_src) {
9886     return wuffs_wbmp__decoder__decode_frame_config(this, a_dst, a_src);
9887   }
9888 
9889   inline wuffs_base__status
decode_framewuffs_wbmp__decoder__struct9890   decode_frame(
9891       wuffs_base__pixel_buffer* a_dst,
9892       wuffs_base__io_buffer* a_src,
9893       wuffs_base__pixel_blend a_blend,
9894       wuffs_base__slice_u8 a_workbuf,
9895       wuffs_base__decode_frame_options* a_opts) {
9896     return wuffs_wbmp__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
9897   }
9898 
9899   inline wuffs_base__rect_ie_u32
frame_dirty_rectwuffs_wbmp__decoder__struct9900   frame_dirty_rect() const {
9901     return wuffs_wbmp__decoder__frame_dirty_rect(this);
9902   }
9903 
9904   inline uint32_t
num_animation_loopswuffs_wbmp__decoder__struct9905   num_animation_loops() const {
9906     return wuffs_wbmp__decoder__num_animation_loops(this);
9907   }
9908 
9909   inline uint64_t
num_decoded_frame_configswuffs_wbmp__decoder__struct9910   num_decoded_frame_configs() const {
9911     return wuffs_wbmp__decoder__num_decoded_frame_configs(this);
9912   }
9913 
9914   inline uint64_t
num_decoded_frameswuffs_wbmp__decoder__struct9915   num_decoded_frames() const {
9916     return wuffs_wbmp__decoder__num_decoded_frames(this);
9917   }
9918 
9919   inline wuffs_base__status
restart_framewuffs_wbmp__decoder__struct9920   restart_frame(
9921       uint64_t a_index,
9922       uint64_t a_io_position) {
9923     return wuffs_wbmp__decoder__restart_frame(this, a_index, a_io_position);
9924   }
9925 
9926   inline wuffs_base__empty_struct
set_report_metadatawuffs_wbmp__decoder__struct9927   set_report_metadata(
9928       uint32_t a_fourcc,
9929       bool a_report) {
9930     return wuffs_wbmp__decoder__set_report_metadata(this, a_fourcc, a_report);
9931   }
9932 
9933   inline wuffs_base__status
tell_me_morewuffs_wbmp__decoder__struct9934   tell_me_more(
9935       wuffs_base__io_buffer* a_dst,
9936       wuffs_base__more_information* a_minfo,
9937       wuffs_base__io_buffer* a_src) {
9938     return wuffs_wbmp__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
9939   }
9940 
9941   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_wbmp__decoder__struct9942   workbuf_len() const {
9943     return wuffs_wbmp__decoder__workbuf_len(this);
9944   }
9945 
9946 #endif  // __cplusplus
9947 };  // struct wuffs_wbmp__decoder__struct
9948 
9949 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
9950 
9951 #if defined(__cplusplus) && defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
9952 
9953 // ---------------- Auxiliary - Base
9954 
9955 // Auxiliary code is discussed at
9956 // https://github.com/google/wuffs/blob/main/doc/note/auxiliary-code.md
9957 
9958 #include <stdio.h>
9959 
9960 #include <string>
9961 
9962 namespace wuffs_aux {
9963 
9964 using IOBuffer = wuffs_base__io_buffer;
9965 
9966 // MemOwner represents ownership of some memory. Dynamically allocated memory
9967 // (e.g. from malloc or new) is typically paired with free or delete, invoked
9968 // when the std::unique_ptr is destroyed. Statically allocated memory might use
9969 // MemOwner(nullptr, &free), even if that statically allocated memory is not
9970 // nullptr, since calling free(nullptr) is a no-op.
9971 using MemOwner = std::unique_ptr<void, decltype(&free)>;
9972 
9973 namespace sync_io {
9974 
9975 // --------
9976 
9977 // DynIOBuffer is an IOBuffer that is backed by a dynamically sized byte array.
9978 // It owns that backing array and will free it in its destructor.
9979 //
9980 // The array size can be explicitly extended (by calling the grow method) but,
9981 // unlike a C++ std::vector, there is no implicit extension (e.g. by calling
9982 // std::vector::insert) and its maximum size is capped by the max_incl
9983 // constructor argument.
9984 //
9985 // It contains an IOBuffer-typed field whose reader side provides access to
9986 // previously written bytes and whose writer side provides access to the
9987 // allocated but not-yet-written-to slack space. For Go programmers, this slack
9988 // space is roughly analogous to the s[len(s):cap(s)] space of a slice s.
9989 class DynIOBuffer {
9990  public:
9991   enum GrowResult {
9992     OK = 0,
9993     FailedMaxInclExceeded = 1,
9994     FailedOutOfMemory = 2,
9995   };
9996 
9997   // m_buf holds the dynamically sized byte array and its read/write indexes:
9998   //  - m_buf.meta.wi  is roughly analogous to a Go slice's length.
9999   //  - m_buf.data.len is roughly analogous to a Go slice's capacity. It is
10000   //    also equal to the m_buf.data.ptr malloc/realloc size.
10001   //
10002   // Users should not modify the m_buf.data.ptr or m_buf.data.len fields (as
10003   // they are conceptually private to this class), but they can modify the
10004   // bytes referenced by that pointer-length pair (e.g. compactions).
10005   IOBuffer m_buf;
10006 
10007   // m_max_incl is an inclusive upper bound on the backing array size.
10008   const uint64_t m_max_incl;
10009 
10010   // Constructor and destructor.
10011   explicit DynIOBuffer(uint64_t max_incl);
10012   ~DynIOBuffer();
10013 
10014   // Drop frees the byte array and resets m_buf. The DynIOBuffer can still be
10015   // used after a drop call. It just restarts from zero.
10016   void drop();
10017 
10018   // grow ensures that the byte array size is at least min_incl and at most
10019   // max_incl. It returns FailedMaxInclExceeded if that would require
10020   // allocating more than max_incl bytes, including the case where (min_incl >
10021   // max_incl). It returns FailedOutOfMemory if memory allocation failed.
10022   GrowResult grow(uint64_t min_incl);
10023 
10024  private:
10025   // Delete the copy and assign constructors.
10026   DynIOBuffer(const DynIOBuffer&) = delete;
10027   DynIOBuffer& operator=(const DynIOBuffer&) = delete;
10028 
10029   static uint64_t round_up(uint64_t min_incl, uint64_t max_incl);
10030 };
10031 
10032 // --------
10033 
10034 class Input {
10035  public:
10036   virtual ~Input();
10037 
10038   virtual IOBuffer* BringsItsOwnIOBuffer();
10039   virtual std::string CopyIn(IOBuffer* dst) = 0;
10040 };
10041 
10042 // --------
10043 
10044 // FileInput is an Input that reads from a file source.
10045 //
10046 // It does not take responsibility for closing the file when done.
10047 class FileInput : public Input {
10048  public:
10049   FileInput(FILE* f);
10050 
10051   virtual std::string CopyIn(IOBuffer* dst);
10052 
10053  private:
10054   FILE* m_f;
10055 
10056   // Delete the copy and assign constructors.
10057   FileInput(const FileInput&) = delete;
10058   FileInput& operator=(const FileInput&) = delete;
10059 };
10060 
10061 // --------
10062 
10063 // MemoryInput is an Input that reads from an in-memory source.
10064 //
10065 // It does not take responsibility for freeing the memory when done.
10066 class MemoryInput : public Input {
10067  public:
10068   MemoryInput(const char* ptr, size_t len);
10069   MemoryInput(const uint8_t* ptr, size_t len);
10070 
10071   virtual IOBuffer* BringsItsOwnIOBuffer();
10072   virtual std::string CopyIn(IOBuffer* dst);
10073 
10074  private:
10075   IOBuffer m_io;
10076 
10077   // Delete the copy and assign constructors.
10078   MemoryInput(const MemoryInput&) = delete;
10079   MemoryInput& operator=(const MemoryInput&) = delete;
10080 };
10081 
10082 // --------
10083 
10084 }  // namespace sync_io
10085 
10086 }  // namespace wuffs_aux
10087 
10088 // ---------------- Auxiliary - CBOR
10089 
10090 namespace wuffs_aux {
10091 
10092 struct DecodeCborResult {
10093   DecodeCborResult(std::string&& error_message0, uint64_t cursor_position0);
10094 
10095   std::string error_message;
10096   uint64_t cursor_position;
10097 };
10098 
10099 class DecodeCborCallbacks {
10100  public:
10101   virtual ~DecodeCborCallbacks();
10102 
10103   // AppendXxx are called for leaf nodes: literals, numbers, strings, etc.
10104 
10105   virtual std::string AppendNull() = 0;
10106   virtual std::string AppendUndefined() = 0;
10107   virtual std::string AppendBool(bool val) = 0;
10108   virtual std::string AppendF64(double val) = 0;
10109   virtual std::string AppendI64(int64_t val) = 0;
10110   virtual std::string AppendU64(uint64_t val) = 0;
10111   virtual std::string AppendByteString(std::string&& val) = 0;
10112   virtual std::string AppendTextString(std::string&& val) = 0;
10113   virtual std::string AppendMinus1MinusX(uint64_t val) = 0;
10114   virtual std::string AppendCborSimpleValue(uint8_t val) = 0;
10115   virtual std::string AppendCborTag(uint64_t val) = 0;
10116 
10117   // Push and Pop are called for container nodes: CBOR arrays (lists) and CBOR
10118   // maps (dictionaries).
10119   //
10120   // The flags bits combine exactly one of:
10121   //  - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_NONE
10122   //  - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_LIST
10123   //  - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_DICT
10124   // and exactly one of:
10125   //  - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_NONE
10126   //  - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_LIST
10127   //  - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_DICT
10128 
10129   virtual std::string Push(uint32_t flags) = 0;
10130   virtual std::string Pop(uint32_t flags) = 0;
10131 
10132   // Done is always the last Callback method called by DecodeCbor, whether or
10133   // not parsing the input as CBOR encountered an error. Even when successful,
10134   // trailing data may remain in input and buffer.
10135   //
10136   // Do not keep a reference to buffer or buffer.data.ptr after Done returns,
10137   // as DecodeCbor may then de-allocate the backing array.
10138   //
10139   // The default Done implementation is a no-op.
10140   virtual void  //
10141   Done(DecodeCborResult& result, sync_io::Input& input, IOBuffer& buffer);
10142 };
10143 
10144 // The FooArgBar types add structure to Foo's optional arguments. They wrap
10145 // inner representations for several reasons:
10146 //  - It provides a home for the DefaultValue static method, for Foo callers
10147 //    that want to override some but not all optional arguments.
10148 //  - It provides the "Bar" name at Foo call sites, which can help self-
10149 //    document Foo calls with many arguemnts.
10150 //  - It provides some type safety against accidentally transposing or omitting
10151 //    adjacent fundamentally-numeric-typed optional arguments.
10152 
10153 // DecodeCborArgQuirks wraps an optional argument to DecodeCbor.
10154 struct DecodeCborArgQuirks {
10155   explicit DecodeCborArgQuirks(wuffs_base__slice_u32 repr0);
10156   explicit DecodeCborArgQuirks(uint32_t* ptr, size_t len);
10157 
10158   // DefaultValue returns an empty slice.
10159   static DecodeCborArgQuirks DefaultValue();
10160 
10161   wuffs_base__slice_u32 repr;
10162 };
10163 
10164 // DecodeCbor calls callbacks based on the CBOR-formatted data in input.
10165 //
10166 // On success, the returned error_message is empty and cursor_position counts
10167 // the number of bytes consumed. On failure, error_message is non-empty and
10168 // cursor_position is the location of the error. That error may be a content
10169 // error (invalid CBOR) or an input error (e.g. network failure).
10170 DecodeCborResult  //
10171 DecodeCbor(DecodeCborCallbacks& callbacks,
10172            sync_io::Input& input,
10173            DecodeCborArgQuirks quirks = DecodeCborArgQuirks::DefaultValue());
10174 
10175 }  // namespace wuffs_aux
10176 
10177 // ---------------- Auxiliary - Image
10178 
10179 namespace wuffs_aux {
10180 
10181 struct DecodeImageResult {
10182   DecodeImageResult(MemOwner&& pixbuf_mem_owner0,
10183                     wuffs_base__pixel_buffer pixbuf0,
10184                     std::string&& error_message0);
10185   DecodeImageResult(std::string&& error_message0);
10186 
10187   MemOwner pixbuf_mem_owner;
10188   wuffs_base__pixel_buffer pixbuf;
10189   std::string error_message;
10190 };
10191 
10192 // DecodeImageCallbacks are the callbacks given to DecodeImage. They are always
10193 // called in this order:
10194 //  1. SelectDecoder
10195 //  2. HandleMetadata
10196 //  3. SelectPixfmt
10197 //  4. AllocPixbuf
10198 //  5. AllocWorkbuf
10199 //  6. Done
10200 //
10201 // It may return early - the third callback might not be invoked if the second
10202 // one fails - but the final callback (Done) is always invoked.
10203 class DecodeImageCallbacks {
10204  public:
10205   // AllocPixbufResult holds a memory allocation (the result of malloc or new,
10206   // a statically allocated pointer, etc), or an error message. The memory is
10207   // de-allocated when mem_owner goes out of scope and is destroyed.
10208   struct AllocPixbufResult {
10209     AllocPixbufResult(MemOwner&& mem_owner0, wuffs_base__pixel_buffer pixbuf0);
10210     AllocPixbufResult(std::string&& error_message0);
10211 
10212     MemOwner mem_owner;
10213     wuffs_base__pixel_buffer pixbuf;
10214     std::string error_message;
10215   };
10216 
10217   // AllocWorkbufResult holds a memory allocation (the result of malloc or new,
10218   // a statically allocated pointer, etc), or an error message. The memory is
10219   // de-allocated when mem_owner goes out of scope and is destroyed.
10220   struct AllocWorkbufResult {
10221     AllocWorkbufResult(MemOwner&& mem_owner0, wuffs_base__slice_u8 workbuf0);
10222     AllocWorkbufResult(std::string&& error_message0);
10223 
10224     MemOwner mem_owner;
10225     wuffs_base__slice_u8 workbuf;
10226     std::string error_message;
10227   };
10228 
10229   virtual ~DecodeImageCallbacks();
10230 
10231   // SelectDecoder returns the image decoder for the input data's file format.
10232   // Returning a nullptr means failure (DecodeImage_UnsupportedImageFormat).
10233   //
10234   // Common formats will have a FourCC value in the range [1 ..= 0x7FFF_FFFF],
10235   // such as WUFFS_BASE__FOURCC__JPEG. A zero FourCC value means that the
10236   // caller is responsible for examining the opening bytes (a prefix) of the
10237   // input data. SelectDecoder implementations should not modify those bytes.
10238   //
10239   // SelectDecoder might be called more than once, since some image file
10240   // formats can wrap others. For example, a nominal BMP file can actually
10241   // contain a JPEG or a PNG.
10242   //
10243   // The default SelectDecoder accepts the FOURCC codes listed below. For
10244   // modular builds (i.e. when #define'ing WUFFS_CONFIG__MODULES), acceptance
10245   // of the ETC file format is optional (for each value of ETC) and depends on
10246   // the corresponding module to be enabled at compile time (i.e. #define'ing
10247   // WUFFS_CONFIG__MODULE__ETC).
10248   //  - WUFFS_BASE__FOURCC__BMP
10249   //  - WUFFS_BASE__FOURCC__GIF
10250   //  - WUFFS_BASE__FOURCC__NIE
10251   //  - WUFFS_BASE__FOURCC__PNG
10252   //  - WUFFS_BASE__FOURCC__WBMP
10253   virtual wuffs_base__image_decoder::unique_ptr  //
10254   SelectDecoder(uint32_t fourcc, wuffs_base__slice_u8 prefix);
10255 
10256   // HandleMetadata acknowledges image metadata. minfo.flavor will be one of:
10257   //  - WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_RAW_PASSTHROUGH
10258   //  - WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_PARSED
10259   // If it is ETC__METADATA_RAW_ETC then raw contains the metadata bytes. Those
10260   // bytes should not be retained beyond the the HandleMetadata call.
10261   //
10262   // minfo.metadata__fourcc() will typically match one of the
10263   // DecodeImageArgFlags bits. For example, if (REPORT_METADATA_CHRM |
10264   // REPORT_METADATA_GAMA) was passed to DecodeImage then the metadata FourCC
10265   // will be either WUFFS_BASE__FOURCC__CHRM or WUFFS_BASE__FOURCC__GAMA.
10266   //
10267   // It returns an error message, or an empty string on success.
10268   virtual std::string  //
10269   HandleMetadata(const wuffs_base__more_information& minfo,
10270                  wuffs_base__slice_u8 raw);
10271 
10272   // SelectPixfmt returns the destination pixel format for AllocPixbuf. It
10273   // should return wuffs_base__make_pixel_format(etc) called with one of:
10274   //  - WUFFS_BASE__PIXEL_FORMAT__BGR_565
10275   //  - WUFFS_BASE__PIXEL_FORMAT__BGR
10276   //  - WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL
10277   //  - WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE
10278   //  - WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL
10279   //  - WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL
10280   //  - WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL
10281   // or return image_config.pixcfg.pixel_format(). The latter means to use the
10282   // image file's natural pixel format. For example, GIF images' natural pixel
10283   // format is an indexed one.
10284   //
10285   // Returning otherwise means failure (DecodeImage_UnsupportedPixelFormat).
10286   //
10287   // The default SelectPixfmt implementation returns
10288   // wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL) which
10289   // is 4 bytes per pixel (8 bits per channel × 4 channels).
10290   virtual wuffs_base__pixel_format  //
10291   SelectPixfmt(const wuffs_base__image_config& image_config);
10292 
10293   // AllocPixbuf allocates the pixel buffer.
10294   //
10295   // allow_uninitialized_memory will be true if a valid background_color was
10296   // passed to DecodeImage, since the pixel buffer's contents will be
10297   // overwritten with that color after AllocPixbuf returns.
10298   //
10299   // The default AllocPixbuf implementation allocates either uninitialized or
10300   // zeroed memory. Zeroed memory typically corresponds to filling with opaque
10301   // black or transparent black, depending on the pixel format.
10302   virtual AllocPixbufResult  //
10303   AllocPixbuf(const wuffs_base__image_config& image_config,
10304               bool allow_uninitialized_memory);
10305 
10306   // AllocWorkbuf allocates the work buffer. The allocated buffer's length
10307   // should be at least len_range.min_incl, but larger allocations (up to
10308   // len_range.max_incl) may have better performance (by using more memory).
10309   //
10310   // The default AllocWorkbuf implementation allocates len_range.max_incl bytes
10311   // of either uninitialized or zeroed memory.
10312   virtual AllocWorkbufResult  //
10313   AllocWorkbuf(wuffs_base__range_ii_u64 len_range,
10314                bool allow_uninitialized_memory);
10315 
10316   // Done is always the last Callback method called by DecodeImage, whether or
10317   // not parsing the input encountered an error. Even when successful, trailing
10318   // data may remain in input and buffer.
10319   //
10320   // The image_decoder is the one returned by SelectDecoder (if SelectDecoder
10321   // was successful), or a no-op unique_ptr otherwise. Like any unique_ptr,
10322   // ownership moves to the Done implementation.
10323   //
10324   // Do not keep a reference to buffer or buffer.data.ptr after Done returns,
10325   // as DecodeImage may then de-allocate the backing array.
10326   //
10327   // The default Done implementation is a no-op, other than running the
10328   // image_decoder unique_ptr destructor.
10329   virtual void  //
10330   Done(DecodeImageResult& result,
10331        sync_io::Input& input,
10332        IOBuffer& buffer,
10333        wuffs_base__image_decoder::unique_ptr image_decoder);
10334 };
10335 
10336 extern const char DecodeImage_BufferIsTooShort[];
10337 extern const char DecodeImage_MaxInclDimensionExceeded[];
10338 extern const char DecodeImage_MaxInclMetadataLengthExceeded[];
10339 extern const char DecodeImage_OutOfMemory[];
10340 extern const char DecodeImage_UnexpectedEndOfFile[];
10341 extern const char DecodeImage_UnsupportedImageFormat[];
10342 extern const char DecodeImage_UnsupportedMetadata[];
10343 extern const char DecodeImage_UnsupportedPixelBlend[];
10344 extern const char DecodeImage_UnsupportedPixelConfiguration[];
10345 extern const char DecodeImage_UnsupportedPixelFormat[];
10346 
10347 // The FooArgBar types add structure to Foo's optional arguments. They wrap
10348 // inner representations for several reasons:
10349 //  - It provides a home for the DefaultValue static method, for Foo callers
10350 //    that want to override some but not all optional arguments.
10351 //  - It provides the "Bar" name at Foo call sites, which can help self-
10352 //    document Foo calls with many arguemnts.
10353 //  - It provides some type safety against accidentally transposing or omitting
10354 //    adjacent fundamentally-numeric-typed optional arguments.
10355 
10356 // DecodeImageArgQuirks wraps an optional argument to DecodeImage.
10357 struct DecodeImageArgQuirks {
10358   explicit DecodeImageArgQuirks(wuffs_base__slice_u32 repr0);
10359   explicit DecodeImageArgQuirks(uint32_t* ptr, size_t len);
10360 
10361   // DefaultValue returns an empty slice.
10362   static DecodeImageArgQuirks DefaultValue();
10363 
10364   wuffs_base__slice_u32 repr;
10365 };
10366 
10367 // DecodeImageArgFlags wraps an optional argument to DecodeImage.
10368 struct DecodeImageArgFlags {
10369   explicit DecodeImageArgFlags(uint64_t repr0);
10370 
10371   // DefaultValue returns 0.
10372   static DecodeImageArgFlags DefaultValue();
10373 
10374   // TODO: support all of the REPORT_METADATA_ETC flags, not just CHRM, GAMA,
10375   // ICCP, KVP, SRGB and XMP.
10376 
10377   // Background Color.
10378   static constexpr uint64_t REPORT_METADATA_BGCL = 0x0001;
10379   // Primary Chromaticities and White Point.
10380   static constexpr uint64_t REPORT_METADATA_CHRM = 0x0002;
10381   // Exchangeable Image File Format.
10382   static constexpr uint64_t REPORT_METADATA_EXIF = 0x0004;
10383   // Gamma Correction.
10384   static constexpr uint64_t REPORT_METADATA_GAMA = 0x0008;
10385   // International Color Consortium Profile.
10386   static constexpr uint64_t REPORT_METADATA_ICCP = 0x0010;
10387   // Key-Value Pair.
10388   //
10389   // For PNG files, this includes iTXt, tEXt and zTXt chunks. In the
10390   // HandleMetadata callback, the raw argument contains UTF-8 strings.
10391   static constexpr uint64_t REPORT_METADATA_KVP = 0x0020;
10392   // Modification Time.
10393   static constexpr uint64_t REPORT_METADATA_MTIM = 0x0040;
10394   // Offset (2-Dimensional).
10395   static constexpr uint64_t REPORT_METADATA_OFS2 = 0x0080;
10396   // Physical Dimensions.
10397   static constexpr uint64_t REPORT_METADATA_PHYD = 0x0100;
10398   // Standard Red Green Blue (Rendering Intent).
10399   static constexpr uint64_t REPORT_METADATA_SRGB = 0x0200;
10400   // Extensible Metadata Platform.
10401   static constexpr uint64_t REPORT_METADATA_XMP = 0x0400;
10402 
10403   uint64_t repr;
10404 };
10405 
10406 // DecodeImageArgPixelBlend wraps an optional argument to DecodeImage.
10407 struct DecodeImageArgPixelBlend {
10408   explicit DecodeImageArgPixelBlend(wuffs_base__pixel_blend repr0);
10409 
10410   // DefaultValue returns WUFFS_BASE__PIXEL_BLEND__SRC.
10411   static DecodeImageArgPixelBlend DefaultValue();
10412 
10413   wuffs_base__pixel_blend repr;
10414 };
10415 
10416 // DecodeImageArgBackgroundColor wraps an optional argument to DecodeImage.
10417 struct DecodeImageArgBackgroundColor {
10418   explicit DecodeImageArgBackgroundColor(
10419       wuffs_base__color_u32_argb_premul repr0);
10420 
10421   // DefaultValue returns 1, an invalid wuffs_base__color_u32_argb_premul.
10422   static DecodeImageArgBackgroundColor DefaultValue();
10423 
10424   wuffs_base__color_u32_argb_premul repr;
10425 };
10426 
10427 // DecodeImageArgMaxInclDimension wraps an optional argument to DecodeImage.
10428 struct DecodeImageArgMaxInclDimension {
10429   explicit DecodeImageArgMaxInclDimension(uint32_t repr0);
10430 
10431   // DefaultValue returns 1048575 = 0x000F_FFFF, more than 1 million pixels.
10432   static DecodeImageArgMaxInclDimension DefaultValue();
10433 
10434   uint32_t repr;
10435 };
10436 
10437 // DecodeImageArgMaxInclMetadataLength wraps an optional argument to
10438 // DecodeImage.
10439 struct DecodeImageArgMaxInclMetadataLength {
10440   explicit DecodeImageArgMaxInclMetadataLength(uint64_t repr0);
10441 
10442   // DefaultValue returns 16777215 = 0x00FF_FFFF, one less than 16 MiB.
10443   static DecodeImageArgMaxInclMetadataLength DefaultValue();
10444 
10445   uint64_t repr;
10446 };
10447 
10448 // DecodeImage decodes the image data in input. A variety of image file formats
10449 // can be decoded, depending on what callbacks.SelectDecoder returns.
10450 //
10451 // For animated formats, only the first frame is returned, since the API is
10452 // simpler for synchronous I/O and having DecodeImage only return when
10453 // completely done, but rendering animation often involves handling other
10454 // events in between animation frames. To decode multiple frames of animated
10455 // images, or for asynchronous I/O (e.g. when decoding an image streamed over
10456 // the network), use Wuffs' lower level C API instead of its higher level,
10457 // simplified C++ API (the wuffs_aux API).
10458 //
10459 // The DecodeImageResult's fields depend on whether decoding succeeded:
10460 //  - On total success, the error_message is empty and pixbuf.pixcfg.is_valid()
10461 //    is true.
10462 //  - On partial success (e.g. the input file was truncated but we are still
10463 //    able to decode some of the pixels), error_message is non-empty but
10464 //    pixbuf.pixcfg.is_valid() is still true. It is up to the caller whether to
10465 //    accept or reject partial success.
10466 //  - On failure, the error_message is non_empty and pixbuf.pixcfg.is_valid()
10467 //    is false.
10468 //
10469 // The callbacks allocate the pixel buffer memory and work buffer memory. On
10470 // success, pixel buffer memory ownership is passed to the DecodeImage caller
10471 // as the returned pixbuf_mem_owner. Regardless of success or failure, the work
10472 // buffer memory is deleted.
10473 //
10474 // The pixel_blend (one of the constants listed below) determines how to
10475 // composite the decoded image over the pixel buffer's original pixels (as
10476 // returned by callbacks.AllocPixbuf):
10477 //  - WUFFS_BASE__PIXEL_BLEND__SRC
10478 //  - WUFFS_BASE__PIXEL_BLEND__SRC_OVER
10479 //
10480 // The background_color is used to fill the pixel buffer after
10481 // callbacks.AllocPixbuf returns, if it is valid in the
10482 // wuffs_base__color_u32_argb_premul__is_valid sense. The default value,
10483 // 0x0000_0001, is not valid since its Blue channel value (0x01) is greater
10484 // than its Alpha channel value (0x00). A valid background_color will typically
10485 // be overwritten when pixel_blend is WUFFS_BASE__PIXEL_BLEND__SRC, but might
10486 // still be visible on partial (not total) success or when pixel_blend is
10487 // WUFFS_BASE__PIXEL_BLEND__SRC_OVER and the decoded image is not fully opaque.
10488 //
10489 // Decoding fails (with DecodeImage_MaxInclDimensionExceeded) if the image's
10490 // width or height is greater than max_incl_dimension or if any opted-in (via
10491 // flags bits) metadata is longer than max_incl_metadata_length.
10492 DecodeImageResult  //
10493 DecodeImage(DecodeImageCallbacks& callbacks,
10494             sync_io::Input& input,
10495             DecodeImageArgQuirks quirks = DecodeImageArgQuirks::DefaultValue(),
10496             DecodeImageArgFlags flags = DecodeImageArgFlags::DefaultValue(),
10497             DecodeImageArgPixelBlend pixel_blend =
10498                 DecodeImageArgPixelBlend::DefaultValue(),
10499             DecodeImageArgBackgroundColor background_color =
10500                 DecodeImageArgBackgroundColor::DefaultValue(),
10501             DecodeImageArgMaxInclDimension max_incl_dimension =
10502                 DecodeImageArgMaxInclDimension::DefaultValue(),
10503             DecodeImageArgMaxInclMetadataLength max_incl_metadata_length =
10504                 DecodeImageArgMaxInclMetadataLength::DefaultValue());
10505 
10506 }  // namespace wuffs_aux
10507 
10508 // ---------------- Auxiliary - JSON
10509 
10510 namespace wuffs_aux {
10511 
10512 struct DecodeJsonResult {
10513   DecodeJsonResult(std::string&& error_message0, uint64_t cursor_position0);
10514 
10515   std::string error_message;
10516   uint64_t cursor_position;
10517 };
10518 
10519 class DecodeJsonCallbacks {
10520  public:
10521   virtual ~DecodeJsonCallbacks();
10522 
10523   // AppendXxx are called for leaf nodes: literals, numbers and strings. For
10524   // strings, the Callbacks implementation is responsible for tracking map keys
10525   // versus other values.
10526 
10527   virtual std::string AppendNull() = 0;
10528   virtual std::string AppendBool(bool val) = 0;
10529   virtual std::string AppendF64(double val) = 0;
10530   virtual std::string AppendI64(int64_t val) = 0;
10531   virtual std::string AppendTextString(std::string&& val) = 0;
10532 
10533   // Push and Pop are called for container nodes: JSON arrays (lists) and JSON
10534   // objects (dictionaries).
10535   //
10536   // The flags bits combine exactly one of:
10537   //  - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_NONE
10538   //  - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_LIST
10539   //  - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_DICT
10540   // and exactly one of:
10541   //  - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_NONE
10542   //  - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_LIST
10543   //  - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_DICT
10544 
10545   virtual std::string Push(uint32_t flags) = 0;
10546   virtual std::string Pop(uint32_t flags) = 0;
10547 
10548   // Done is always the last Callback method called by DecodeJson, whether or
10549   // not parsing the input as JSON encountered an error. Even when successful,
10550   // trailing data may remain in input and buffer. See "Unintuitive JSON
10551   // Parsing" (https://nullprogram.com/blog/2019/12/28/) which discusses JSON
10552   // parsing and when it stops.
10553   //
10554   // Do not keep a reference to buffer or buffer.data.ptr after Done returns,
10555   // as DecodeJson may then de-allocate the backing array.
10556   //
10557   // The default Done implementation is a no-op.
10558   virtual void  //
10559   Done(DecodeJsonResult& result, sync_io::Input& input, IOBuffer& buffer);
10560 };
10561 
10562 extern const char DecodeJson_BadJsonPointer[];
10563 extern const char DecodeJson_NoMatch[];
10564 
10565 // The FooArgBar types add structure to Foo's optional arguments. They wrap
10566 // inner representations for several reasons:
10567 //  - It provides a home for the DefaultValue static method, for Foo callers
10568 //    that want to override some but not all optional arguments.
10569 //  - It provides the "Bar" name at Foo call sites, which can help self-
10570 //    document Foo calls with many arguemnts.
10571 //  - It provides some type safety against accidentally transposing or omitting
10572 //    adjacent fundamentally-numeric-typed optional arguments.
10573 
10574 // DecodeJsonArgQuirks wraps an optional argument to DecodeJson.
10575 struct DecodeJsonArgQuirks {
10576   explicit DecodeJsonArgQuirks(wuffs_base__slice_u32 repr0);
10577   explicit DecodeJsonArgQuirks(uint32_t* ptr, size_t len);
10578 
10579   // DefaultValue returns an empty slice.
10580   static DecodeJsonArgQuirks DefaultValue();
10581 
10582   wuffs_base__slice_u32 repr;
10583 };
10584 
10585 // DecodeJsonArgJsonPointer wraps an optional argument to DecodeJson.
10586 struct DecodeJsonArgJsonPointer {
10587   explicit DecodeJsonArgJsonPointer(std::string repr0);
10588 
10589   // DefaultValue returns an empty string.
10590   static DecodeJsonArgJsonPointer DefaultValue();
10591 
10592   std::string repr;
10593 };
10594 
10595 // DecodeJson calls callbacks based on the JSON-formatted data in input.
10596 //
10597 // On success, the returned error_message is empty and cursor_position counts
10598 // the number of bytes consumed. On failure, error_message is non-empty and
10599 // cursor_position is the location of the error. That error may be a content
10600 // error (invalid JSON) or an input error (e.g. network failure).
10601 //
10602 // json_pointer is a query in the JSON Pointer (RFC 6901) syntax. The callbacks
10603 // run for the input's sub-node that matches the query. DecodeJson_NoMatch is
10604 // returned if no matching sub-node was found. The empty query matches the
10605 // input's root node, consistent with JSON Pointer semantics.
10606 //
10607 // The JSON Pointer implementation is greedy: duplicate keys are not rejected
10608 // but only the first match for each '/'-separated fragment is followed.
10609 DecodeJsonResult  //
10610 DecodeJson(DecodeJsonCallbacks& callbacks,
10611            sync_io::Input& input,
10612            DecodeJsonArgQuirks quirks = DecodeJsonArgQuirks::DefaultValue(),
10613            DecodeJsonArgJsonPointer json_pointer =
10614                DecodeJsonArgJsonPointer::DefaultValue());
10615 
10616 }  // namespace wuffs_aux
10617 
10618 #endif  // defined(__cplusplus) && defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
10619 
10620 // ‼ WUFFS C HEADER ENDS HERE.
10621 #ifdef WUFFS_IMPLEMENTATION
10622 
10623 #ifdef __cplusplus
10624 extern "C" {
10625 #endif
10626 
10627 // ---------------- Fundamentals
10628 
10629 // WUFFS_BASE__MAGIC is a magic number to check that initializers are called.
10630 // It's not foolproof, given C doesn't automatically zero memory before use,
10631 // but it should catch 99.99% of cases.
10632 //
10633 // Its (non-zero) value is arbitrary, based on md5sum("wuffs").
10634 #define WUFFS_BASE__MAGIC ((uint32_t)0x3CCB6C71)
10635 
10636 // WUFFS_BASE__DISABLED is a magic number to indicate that a non-recoverable
10637 // error was previously encountered.
10638 //
10639 // Its (non-zero) value is arbitrary, based on md5sum("disabled").
10640 #define WUFFS_BASE__DISABLED ((uint32_t)0x075AE3D2)
10641 
10642 // Use switch cases for coroutine suspension points, similar to the technique
10643 // in https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
10644 //
10645 // The implicit fallthrough is intentional.
10646 //
10647 // We use trivial macros instead of an explicit assignment and case statement
10648 // so that clang-format doesn't get confused by the unusual "case"s.
10649 #define WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0 case 0:;
10650 #define WUFFS_BASE__COROUTINE_SUSPENSION_POINT(n) \
10651   coro_susp_point = n;                            \
10652   case n:;
10653 
10654 #define WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(n) \
10655   if (!status.repr) {                                           \
10656     goto ok;                                                    \
10657   } else if (*status.repr != '$') {                             \
10658     goto exit;                                                  \
10659   }                                                             \
10660   coro_susp_point = n;                                          \
10661   goto suspend;                                                 \
10662   case n:;
10663 
10664 // The "defined(__clang__)" isn't redundant. While vanilla clang defines
10665 // __GNUC__, clang-cl (which mimics MSVC's cl.exe) does not.
10666 #if defined(__GNUC__) || defined(__clang__)
10667 #define WUFFS_BASE__LIKELY(expr) (__builtin_expect(!!(expr), 1))
10668 #define WUFFS_BASE__UNLIKELY(expr) (__builtin_expect(!!(expr), 0))
10669 #else
10670 #define WUFFS_BASE__LIKELY(expr) (expr)
10671 #define WUFFS_BASE__UNLIKELY(expr) (expr)
10672 #endif
10673 
10674 // --------
10675 
10676 static inline wuffs_base__empty_struct  //
wuffs_base__ignore_status(wuffs_base__status z)10677 wuffs_base__ignore_status(wuffs_base__status z) {
10678   return wuffs_base__make_empty_struct();
10679 }
10680 
10681 static inline wuffs_base__status  //
wuffs_base__status__ensure_not_a_suspension(wuffs_base__status z)10682 wuffs_base__status__ensure_not_a_suspension(wuffs_base__status z) {
10683   if (z.repr && (*z.repr == '$')) {
10684     z.repr = wuffs_base__error__cannot_return_a_suspension;
10685   }
10686   return z;
10687 }
10688 
10689 // --------
10690 
10691 // wuffs_base__iterate_total_advance returns the exclusive pointer-offset at
10692 // which iteration should stop. The overall slice has length total_len, each
10693 // iteration's sub-slice has length iter_len and are placed iter_advance apart.
10694 //
10695 // The iter_advance may not be larger than iter_len. The iter_advance may be
10696 // smaller than iter_len, in which case the sub-slices will overlap.
10697 //
10698 // The return value r satisfies ((0 <= r) && (r <= total_len)).
10699 //
10700 // For example, if total_len = 15, iter_len = 5 and iter_advance = 3, there are
10701 // four iterations at offsets 0, 3, 6 and 9. This function returns 12.
10702 //
10703 // 0123456789012345
10704 // [....]
10705 //    [....]
10706 //       [....]
10707 //          [....]
10708 //             $
10709 // 0123456789012345
10710 //
10711 // For example, if total_len = 15, iter_len = 5 and iter_advance = 5, there are
10712 // three iterations at offsets 0, 5 and 10. This function returns 15.
10713 //
10714 // 0123456789012345
10715 // [....]
10716 //      [....]
10717 //           [....]
10718 //                $
10719 // 0123456789012345
10720 static inline size_t  //
wuffs_base__iterate_total_advance(size_t total_len,size_t iter_len,size_t iter_advance)10721 wuffs_base__iterate_total_advance(size_t total_len,
10722                                   size_t iter_len,
10723                                   size_t iter_advance) {
10724   if (total_len >= iter_len) {
10725     size_t n = total_len - iter_len;
10726     return ((n / iter_advance) * iter_advance) + iter_advance;
10727   }
10728   return 0;
10729 }
10730 
10731 // ---------------- Numeric Types
10732 
10733 extern const uint8_t wuffs_base__low_bits_mask__u8[8];
10734 extern const uint16_t wuffs_base__low_bits_mask__u16[16];
10735 extern const uint32_t wuffs_base__low_bits_mask__u32[32];
10736 extern const uint64_t wuffs_base__low_bits_mask__u64[64];
10737 
10738 #define WUFFS_BASE__LOW_BITS_MASK__U8(n) (wuffs_base__low_bits_mask__u8[n])
10739 #define WUFFS_BASE__LOW_BITS_MASK__U16(n) (wuffs_base__low_bits_mask__u16[n])
10740 #define WUFFS_BASE__LOW_BITS_MASK__U32(n) (wuffs_base__low_bits_mask__u32[n])
10741 #define WUFFS_BASE__LOW_BITS_MASK__U64(n) (wuffs_base__low_bits_mask__u64[n])
10742 
10743 // --------
10744 
10745 static inline void  //
wuffs_base__u8__sat_add_indirect(uint8_t * x,uint8_t y)10746 wuffs_base__u8__sat_add_indirect(uint8_t* x, uint8_t y) {
10747   *x = wuffs_base__u8__sat_add(*x, y);
10748 }
10749 
10750 static inline void  //
wuffs_base__u8__sat_sub_indirect(uint8_t * x,uint8_t y)10751 wuffs_base__u8__sat_sub_indirect(uint8_t* x, uint8_t y) {
10752   *x = wuffs_base__u8__sat_sub(*x, y);
10753 }
10754 
10755 static inline void  //
wuffs_base__u16__sat_add_indirect(uint16_t * x,uint16_t y)10756 wuffs_base__u16__sat_add_indirect(uint16_t* x, uint16_t y) {
10757   *x = wuffs_base__u16__sat_add(*x, y);
10758 }
10759 
10760 static inline void  //
wuffs_base__u16__sat_sub_indirect(uint16_t * x,uint16_t y)10761 wuffs_base__u16__sat_sub_indirect(uint16_t* x, uint16_t y) {
10762   *x = wuffs_base__u16__sat_sub(*x, y);
10763 }
10764 
10765 static inline void  //
wuffs_base__u32__sat_add_indirect(uint32_t * x,uint32_t y)10766 wuffs_base__u32__sat_add_indirect(uint32_t* x, uint32_t y) {
10767   *x = wuffs_base__u32__sat_add(*x, y);
10768 }
10769 
10770 static inline void  //
wuffs_base__u32__sat_sub_indirect(uint32_t * x,uint32_t y)10771 wuffs_base__u32__sat_sub_indirect(uint32_t* x, uint32_t y) {
10772   *x = wuffs_base__u32__sat_sub(*x, y);
10773 }
10774 
10775 static inline void  //
wuffs_base__u64__sat_add_indirect(uint64_t * x,uint64_t y)10776 wuffs_base__u64__sat_add_indirect(uint64_t* x, uint64_t y) {
10777   *x = wuffs_base__u64__sat_add(*x, y);
10778 }
10779 
10780 static inline void  //
wuffs_base__u64__sat_sub_indirect(uint64_t * x,uint64_t y)10781 wuffs_base__u64__sat_sub_indirect(uint64_t* x, uint64_t y) {
10782   *x = wuffs_base__u64__sat_sub(*x, y);
10783 }
10784 
10785 // ---------------- Slices and Tables
10786 
10787 // wuffs_base__slice_u8__prefix returns up to the first up_to bytes of s.
10788 static inline wuffs_base__slice_u8  //
wuffs_base__slice_u8__prefix(wuffs_base__slice_u8 s,uint64_t up_to)10789 wuffs_base__slice_u8__prefix(wuffs_base__slice_u8 s, uint64_t up_to) {
10790   if (((uint64_t)(s.len)) > up_to) {
10791     s.len = ((size_t)up_to);
10792   }
10793   return s;
10794 }
10795 
10796 // wuffs_base__slice_u8__suffix returns up to the last up_to bytes of s.
10797 static inline wuffs_base__slice_u8  //
wuffs_base__slice_u8__suffix(wuffs_base__slice_u8 s,uint64_t up_to)10798 wuffs_base__slice_u8__suffix(wuffs_base__slice_u8 s, uint64_t up_to) {
10799   if (((uint64_t)(s.len)) > up_to) {
10800     s.ptr += ((uint64_t)(s.len)) - up_to;
10801     s.len = ((size_t)up_to);
10802   }
10803   return s;
10804 }
10805 
10806 // wuffs_base__slice_u8__copy_from_slice calls memmove(dst.ptr, src.ptr, len)
10807 // where len is the minimum of dst.len and src.len.
10808 //
10809 // Passing a wuffs_base__slice_u8 with all fields NULL or zero (a valid, empty
10810 // slice) is valid and results in a no-op.
10811 static inline uint64_t  //
wuffs_base__slice_u8__copy_from_slice(wuffs_base__slice_u8 dst,wuffs_base__slice_u8 src)10812 wuffs_base__slice_u8__copy_from_slice(wuffs_base__slice_u8 dst,
10813                                       wuffs_base__slice_u8 src) {
10814   size_t len = dst.len < src.len ? dst.len : src.len;
10815   if (len > 0) {
10816     memmove(dst.ptr, src.ptr, len);
10817   }
10818   return len;
10819 }
10820 
10821 // --------
10822 
10823 static inline wuffs_base__slice_u8  //
wuffs_base__table_u8__row_u32(wuffs_base__table_u8 t,uint32_t y)10824 wuffs_base__table_u8__row_u32(wuffs_base__table_u8 t, uint32_t y) {
10825   if (y < t.height) {
10826     return wuffs_base__make_slice_u8(t.ptr + (t.stride * y), t.width);
10827   }
10828   return wuffs_base__make_slice_u8(NULL, 0);
10829 }
10830 
10831 // ---------------- Slices and Tables (Utility)
10832 
10833 #define wuffs_base__utility__empty_slice_u8 wuffs_base__empty_slice_u8
10834 
10835 // ---------------- Ranges and Rects
10836 
10837 static inline uint32_t  //
wuffs_base__range_ii_u32__get_min_incl(const wuffs_base__range_ii_u32 * r)10838 wuffs_base__range_ii_u32__get_min_incl(const wuffs_base__range_ii_u32* r) {
10839   return r->min_incl;
10840 }
10841 
10842 static inline uint32_t  //
wuffs_base__range_ii_u32__get_max_incl(const wuffs_base__range_ii_u32 * r)10843 wuffs_base__range_ii_u32__get_max_incl(const wuffs_base__range_ii_u32* r) {
10844   return r->max_incl;
10845 }
10846 
10847 static inline uint32_t  //
wuffs_base__range_ie_u32__get_min_incl(const wuffs_base__range_ie_u32 * r)10848 wuffs_base__range_ie_u32__get_min_incl(const wuffs_base__range_ie_u32* r) {
10849   return r->min_incl;
10850 }
10851 
10852 static inline uint32_t  //
wuffs_base__range_ie_u32__get_max_excl(const wuffs_base__range_ie_u32 * r)10853 wuffs_base__range_ie_u32__get_max_excl(const wuffs_base__range_ie_u32* r) {
10854   return r->max_excl;
10855 }
10856 
10857 static inline uint64_t  //
wuffs_base__range_ii_u64__get_min_incl(const wuffs_base__range_ii_u64 * r)10858 wuffs_base__range_ii_u64__get_min_incl(const wuffs_base__range_ii_u64* r) {
10859   return r->min_incl;
10860 }
10861 
10862 static inline uint64_t  //
wuffs_base__range_ii_u64__get_max_incl(const wuffs_base__range_ii_u64 * r)10863 wuffs_base__range_ii_u64__get_max_incl(const wuffs_base__range_ii_u64* r) {
10864   return r->max_incl;
10865 }
10866 
10867 static inline uint64_t  //
wuffs_base__range_ie_u64__get_min_incl(const wuffs_base__range_ie_u64 * r)10868 wuffs_base__range_ie_u64__get_min_incl(const wuffs_base__range_ie_u64* r) {
10869   return r->min_incl;
10870 }
10871 
10872 static inline uint64_t  //
wuffs_base__range_ie_u64__get_max_excl(const wuffs_base__range_ie_u64 * r)10873 wuffs_base__range_ie_u64__get_max_excl(const wuffs_base__range_ie_u64* r) {
10874   return r->max_excl;
10875 }
10876 
10877 // ---------------- Ranges and Rects (Utility)
10878 
10879 #define wuffs_base__utility__empty_range_ii_u32 wuffs_base__empty_range_ii_u32
10880 #define wuffs_base__utility__empty_range_ie_u32 wuffs_base__empty_range_ie_u32
10881 #define wuffs_base__utility__empty_range_ii_u64 wuffs_base__empty_range_ii_u64
10882 #define wuffs_base__utility__empty_range_ie_u64 wuffs_base__empty_range_ie_u64
10883 #define wuffs_base__utility__empty_rect_ii_u32 wuffs_base__empty_rect_ii_u32
10884 #define wuffs_base__utility__empty_rect_ie_u32 wuffs_base__empty_rect_ie_u32
10885 #define wuffs_base__utility__make_range_ii_u32 wuffs_base__make_range_ii_u32
10886 #define wuffs_base__utility__make_range_ie_u32 wuffs_base__make_range_ie_u32
10887 #define wuffs_base__utility__make_range_ii_u64 wuffs_base__make_range_ii_u64
10888 #define wuffs_base__utility__make_range_ie_u64 wuffs_base__make_range_ie_u64
10889 #define wuffs_base__utility__make_rect_ii_u32 wuffs_base__make_rect_ii_u32
10890 #define wuffs_base__utility__make_rect_ie_u32 wuffs_base__make_rect_ie_u32
10891 
10892 // ---------------- I/O
10893 
10894 static inline uint64_t  //
wuffs_base__io__count_since(uint64_t mark,uint64_t index)10895 wuffs_base__io__count_since(uint64_t mark, uint64_t index) {
10896   if (index >= mark) {
10897     return index - mark;
10898   }
10899   return 0;
10900 }
10901 
10902 // TODO: drop the "const" in "const uint8_t* ptr". Some though required about
10903 // the base.io_reader.since method returning a mutable "slice base.u8".
10904 #if defined(__GNUC__)
10905 #pragma GCC diagnostic push
10906 #pragma GCC diagnostic ignored "-Wcast-qual"
10907 #endif
10908 static inline wuffs_base__slice_u8  //
wuffs_base__io__since(uint64_t mark,uint64_t index,const uint8_t * ptr)10909 wuffs_base__io__since(uint64_t mark, uint64_t index, const uint8_t* ptr) {
10910   if (index >= mark) {
10911     return wuffs_base__make_slice_u8(((uint8_t*)ptr) + mark,
10912                                      ((size_t)(index - mark)));
10913   }
10914   return wuffs_base__make_slice_u8(NULL, 0);
10915 }
10916 #if defined(__GNUC__)
10917 #pragma GCC diagnostic pop
10918 #endif
10919 
10920 // --------
10921 
10922 static inline void  //
wuffs_base__io_reader__limit(const uint8_t ** ptr_io2_r,const uint8_t * iop_r,uint64_t limit)10923 wuffs_base__io_reader__limit(const uint8_t** ptr_io2_r,
10924                              const uint8_t* iop_r,
10925                              uint64_t limit) {
10926   if (((uint64_t)(*ptr_io2_r - iop_r)) > limit) {
10927     *ptr_io2_r = iop_r + limit;
10928   }
10929 }
10930 
10931 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)10932 wuffs_base__io_reader__limited_copy_u32_to_slice(const uint8_t** ptr_iop_r,
10933                                                  const uint8_t* io2_r,
10934                                                  uint32_t length,
10935                                                  wuffs_base__slice_u8 dst) {
10936   const uint8_t* iop_r = *ptr_iop_r;
10937   size_t n = dst.len;
10938   if (n > length) {
10939     n = length;
10940   }
10941   if (n > ((size_t)(io2_r - iop_r))) {
10942     n = (size_t)(io2_r - iop_r);
10943   }
10944   if (n > 0) {
10945     memmove(dst.ptr, iop_r, n);
10946     *ptr_iop_r += n;
10947   }
10948   return (uint32_t)(n);
10949 }
10950 
10951 // wuffs_base__io_reader__match7 returns whether the io_reader's upcoming bytes
10952 // start with the given prefix (up to 7 bytes long). It is peek-like, not
10953 // read-like, in that there are no side-effects.
10954 //
10955 // The low 3 bits of a hold the prefix length, n.
10956 //
10957 // The high 56 bits of a hold the prefix itself, in little-endian order. The
10958 // first prefix byte is in bits 8..=15, the second prefix byte is in bits
10959 // 16..=23, etc. The high (8 * (7 - n)) bits are ignored.
10960 //
10961 // There are three possible return values:
10962 //  - 0 means success.
10963 //  - 1 means inconclusive, equivalent to "$short read".
10964 //  - 2 means failure.
10965 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)10966 wuffs_base__io_reader__match7(const uint8_t* iop_r,
10967                               const uint8_t* io2_r,
10968                               wuffs_base__io_buffer* r,
10969                               uint64_t a) {
10970   uint32_t n = a & 7;
10971   a >>= 8;
10972   if ((io2_r - iop_r) >= 8) {
10973     uint64_t x = wuffs_base__peek_u64le__no_bounds_check(iop_r);
10974     uint32_t shift = 8 * (8 - n);
10975     return ((a << shift) == (x << shift)) ? 0 : 2;
10976   }
10977   for (; n > 0; n--) {
10978     if (iop_r >= io2_r) {
10979       return (r && r->meta.closed) ? 2 : 1;
10980     } else if (*iop_r != ((uint8_t)(a))) {
10981       return 2;
10982     }
10983     iop_r++;
10984     a >>= 8;
10985   }
10986   return 0;
10987 }
10988 
10989 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)10990 wuffs_base__io_reader__set(wuffs_base__io_buffer* b,
10991                            const uint8_t** ptr_iop_r,
10992                            const uint8_t** ptr_io0_r,
10993                            const uint8_t** ptr_io1_r,
10994                            const uint8_t** ptr_io2_r,
10995                            wuffs_base__slice_u8 data,
10996                            uint64_t history_position) {
10997   b->data = data;
10998   b->meta.wi = data.len;
10999   b->meta.ri = 0;
11000   b->meta.pos = history_position;
11001   b->meta.closed = false;
11002 
11003   *ptr_iop_r = data.ptr;
11004   *ptr_io0_r = data.ptr;
11005   *ptr_io1_r = data.ptr;
11006   *ptr_io2_r = data.ptr + data.len;
11007 
11008   return b;
11009 }
11010 
11011 // --------
11012 
11013 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)11014 wuffs_base__io_writer__copy_from_slice(uint8_t** ptr_iop_w,
11015                                        uint8_t* io2_w,
11016                                        wuffs_base__slice_u8 src) {
11017   uint8_t* iop_w = *ptr_iop_w;
11018   size_t n = src.len;
11019   if (n > ((size_t)(io2_w - iop_w))) {
11020     n = (size_t)(io2_w - iop_w);
11021   }
11022   if (n > 0) {
11023     memmove(iop_w, src.ptr, n);
11024     *ptr_iop_w += n;
11025   }
11026   return (uint64_t)(n);
11027 }
11028 
11029 static inline void  //
wuffs_base__io_writer__limit(uint8_t ** ptr_io2_w,uint8_t * iop_w,uint64_t limit)11030 wuffs_base__io_writer__limit(uint8_t** ptr_io2_w,
11031                              uint8_t* iop_w,
11032                              uint64_t limit) {
11033   if (((uint64_t)(*ptr_io2_w - iop_w)) > limit) {
11034     *ptr_io2_w = iop_w + limit;
11035   }
11036 }
11037 
11038 static inline uint32_t  //
wuffs_base__io_writer__limited_copy_u32_from_history(uint8_t ** ptr_iop_w,uint8_t * io1_w,uint8_t * io2_w,uint32_t length,uint32_t distance)11039 wuffs_base__io_writer__limited_copy_u32_from_history(uint8_t** ptr_iop_w,
11040                                                      uint8_t* io1_w,
11041                                                      uint8_t* io2_w,
11042                                                      uint32_t length,
11043                                                      uint32_t distance) {
11044   if (!distance) {
11045     return 0;
11046   }
11047   uint8_t* p = *ptr_iop_w;
11048   if ((size_t)(p - io1_w) < (size_t)(distance)) {
11049     return 0;
11050   }
11051   uint8_t* q = p - distance;
11052   size_t n = (size_t)(io2_w - p);
11053   if ((size_t)(length) > n) {
11054     length = (uint32_t)(n);
11055   } else {
11056     n = (size_t)(length);
11057   }
11058   // TODO: unrolling by 3 seems best for the std/deflate benchmarks, but that
11059   // is mostly because 3 is the minimum length for the deflate format. This
11060   // function implementation shouldn't overfit to that one format. Perhaps the
11061   // limited_copy_u32_from_history Wuffs method should also take an unroll hint
11062   // argument, and the cgen can look if that argument is the constant
11063   // expression '3'.
11064   //
11065   // See also wuffs_base__io_writer__limited_copy_u32_from_history_fast below.
11066   for (; n >= 3; n -= 3) {
11067     *p++ = *q++;
11068     *p++ = *q++;
11069     *p++ = *q++;
11070   }
11071   for (; n; n--) {
11072     *p++ = *q++;
11073   }
11074   *ptr_iop_w = p;
11075   return length;
11076 }
11077 
11078 // wuffs_base__io_writer__limited_copy_u32_from_history_fast is like the
11079 // wuffs_base__io_writer__limited_copy_u32_from_history function above, but has
11080 // stronger pre-conditions.
11081 //
11082 // The caller needs to prove that:
11083 //  - length   <= (io2_w      - *ptr_iop_w)
11084 //  - distance >= 1
11085 //  - distance <= (*ptr_iop_w - io1_w)
11086 static inline uint32_t  //
wuffs_base__io_writer__limited_copy_u32_from_history_fast(uint8_t ** ptr_iop_w,uint8_t * io1_w,uint8_t * io2_w,uint32_t length,uint32_t distance)11087 wuffs_base__io_writer__limited_copy_u32_from_history_fast(uint8_t** ptr_iop_w,
11088                                                           uint8_t* io1_w,
11089                                                           uint8_t* io2_w,
11090                                                           uint32_t length,
11091                                                           uint32_t distance) {
11092   uint8_t* p = *ptr_iop_w;
11093   uint8_t* q = p - distance;
11094   uint32_t n = length;
11095   for (; n >= 3; n -= 3) {
11096     *p++ = *q++;
11097     *p++ = *q++;
11098     *p++ = *q++;
11099   }
11100   for (; n; n--) {
11101     *p++ = *q++;
11102   }
11103   *ptr_iop_w = p;
11104   return length;
11105 }
11106 
11107 // wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast
11108 // copies the previous byte (the one immediately before *ptr_iop_w), copying 8
11109 // byte chunks at a time. Each chunk contains 8 repetitions of the same byte.
11110 //
11111 // In terms of number of bytes copied, length is rounded up to a multiple of 8.
11112 // As a special case, a zero length rounds up to 8 (even though 0 is already a
11113 // multiple of 8), since there is always at least one 8 byte chunk copied.
11114 //
11115 // In terms of advancing *ptr_iop_w, length is not rounded up.
11116 //
11117 // The caller needs to prove that:
11118 //  - (length + 8) <= (io2_w      - *ptr_iop_w)
11119 //  - distance     == 1
11120 //  - distance     <= (*ptr_iop_w - io1_w)
11121 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 * io1_w,uint8_t * io2_w,uint32_t length,uint32_t distance)11122 wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast(
11123     uint8_t** ptr_iop_w,
11124     uint8_t* io1_w,
11125     uint8_t* io2_w,
11126     uint32_t length,
11127     uint32_t distance) {
11128   uint8_t* p = *ptr_iop_w;
11129   uint64_t x = p[-1];
11130   x |= x << 8;
11131   x |= x << 16;
11132   x |= x << 32;
11133   uint32_t n = length;
11134   while (1) {
11135     wuffs_base__poke_u64le__no_bounds_check(p, x);
11136     if (n <= 8) {
11137       p += n;
11138       break;
11139     }
11140     p += 8;
11141     n -= 8;
11142   }
11143   *ptr_iop_w = p;
11144   return length;
11145 }
11146 
11147 // wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast is
11148 // like the wuffs_base__io_writer__limited_copy_u32_from_history_fast function
11149 // above, but copies 8 byte chunks at a time.
11150 //
11151 // In terms of number of bytes copied, length is rounded up to a multiple of 8.
11152 // As a special case, a zero length rounds up to 8 (even though 0 is already a
11153 // multiple of 8), since there is always at least one 8 byte chunk copied.
11154 //
11155 // In terms of advancing *ptr_iop_w, length is not rounded up.
11156 //
11157 // The caller needs to prove that:
11158 //  - (length + 8) <= (io2_w      - *ptr_iop_w)
11159 //  - distance     >= 8
11160 //  - distance     <= (*ptr_iop_w - io1_w)
11161 static inline uint32_t  //
wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast(uint8_t ** ptr_iop_w,uint8_t * io1_w,uint8_t * io2_w,uint32_t length,uint32_t distance)11162 wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast(
11163     uint8_t** ptr_iop_w,
11164     uint8_t* io1_w,
11165     uint8_t* io2_w,
11166     uint32_t length,
11167     uint32_t distance) {
11168   uint8_t* p = *ptr_iop_w;
11169   uint8_t* q = p - distance;
11170   uint32_t n = length;
11171   while (1) {
11172     memcpy(p, q, 8);
11173     if (n <= 8) {
11174       p += n;
11175       break;
11176     }
11177     p += 8;
11178     q += 8;
11179     n -= 8;
11180   }
11181   *ptr_iop_w = p;
11182   return length;
11183 }
11184 
11185 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)11186 wuffs_base__io_writer__limited_copy_u32_from_reader(uint8_t** ptr_iop_w,
11187                                                     uint8_t* io2_w,
11188                                                     uint32_t length,
11189                                                     const uint8_t** ptr_iop_r,
11190                                                     const uint8_t* io2_r) {
11191   uint8_t* iop_w = *ptr_iop_w;
11192   size_t n = length;
11193   if (n > ((size_t)(io2_w - iop_w))) {
11194     n = (size_t)(io2_w - iop_w);
11195   }
11196   const uint8_t* iop_r = *ptr_iop_r;
11197   if (n > ((size_t)(io2_r - iop_r))) {
11198     n = (size_t)(io2_r - iop_r);
11199   }
11200   if (n > 0) {
11201     memmove(iop_w, iop_r, n);
11202     *ptr_iop_w += n;
11203     *ptr_iop_r += n;
11204   }
11205   return (uint32_t)(n);
11206 }
11207 
11208 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)11209 wuffs_base__io_writer__limited_copy_u32_from_slice(uint8_t** ptr_iop_w,
11210                                                    uint8_t* io2_w,
11211                                                    uint32_t length,
11212                                                    wuffs_base__slice_u8 src) {
11213   uint8_t* iop_w = *ptr_iop_w;
11214   size_t n = src.len;
11215   if (n > length) {
11216     n = length;
11217   }
11218   if (n > ((size_t)(io2_w - iop_w))) {
11219     n = (size_t)(io2_w - iop_w);
11220   }
11221   if (n > 0) {
11222     memmove(iop_w, src.ptr, n);
11223     *ptr_iop_w += n;
11224   }
11225   return (uint32_t)(n);
11226 }
11227 
11228 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)11229 wuffs_base__io_writer__set(wuffs_base__io_buffer* b,
11230                            uint8_t** ptr_iop_w,
11231                            uint8_t** ptr_io0_w,
11232                            uint8_t** ptr_io1_w,
11233                            uint8_t** ptr_io2_w,
11234                            wuffs_base__slice_u8 data,
11235                            uint64_t history_position) {
11236   b->data = data;
11237   b->meta.wi = 0;
11238   b->meta.ri = 0;
11239   b->meta.pos = history_position;
11240   b->meta.closed = false;
11241 
11242   *ptr_iop_w = data.ptr;
11243   *ptr_io0_w = data.ptr;
11244   *ptr_io1_w = data.ptr;
11245   *ptr_io2_w = data.ptr + data.len;
11246 
11247   return b;
11248 }
11249 
11250 // ---------------- I/O (Utility)
11251 
11252 #define wuffs_base__utility__empty_io_reader wuffs_base__empty_io_reader
11253 #define wuffs_base__utility__empty_io_writer wuffs_base__empty_io_writer
11254 
11255 // ---------------- Tokens
11256 
11257 // ---------------- Tokens (Utility)
11258 
11259 // ---------------- Memory Allocation
11260 
11261 // ---------------- Images
11262 
11263 WUFFS_BASE__MAYBE_STATIC uint64_t  //
11264 wuffs_base__pixel_swizzler__limited_swizzle_u32_interleaved_from_reader(
11265     const wuffs_base__pixel_swizzler* p,
11266     uint32_t up_to_num_pixels,
11267     wuffs_base__slice_u8 dst,
11268     wuffs_base__slice_u8 dst_palette,
11269     const uint8_t** ptr_iop_r,
11270     const uint8_t* io2_r);
11271 
11272 WUFFS_BASE__MAYBE_STATIC uint64_t  //
11273 wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(
11274     const wuffs_base__pixel_swizzler* p,
11275     wuffs_base__slice_u8 dst,
11276     wuffs_base__slice_u8 dst_palette,
11277     const uint8_t** ptr_iop_r,
11278     const uint8_t* io2_r);
11279 
11280 WUFFS_BASE__MAYBE_STATIC uint64_t  //
11281 wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(
11282     const wuffs_base__pixel_swizzler* p,
11283     wuffs_base__slice_u8 dst,
11284     wuffs_base__slice_u8 dst_palette,
11285     uint64_t num_pixels);
11286 
11287 // ---------------- Images (Utility)
11288 
11289 #define wuffs_base__utility__make_pixel_format wuffs_base__make_pixel_format
11290 
11291 // ---------------- String Conversions
11292 
11293 // ---------------- Unicode and UTF-8
11294 
11295 // ----------------
11296 
11297 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
11298     defined(WUFFS_CONFIG__MODULE__BASE__CORE)
11299 
11300 const uint8_t wuffs_base__low_bits_mask__u8[8] = {
11301     0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F,
11302 };
11303 
11304 const uint16_t wuffs_base__low_bits_mask__u16[16] = {
11305     0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F,
11306     0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF,
11307 };
11308 
11309 const uint32_t wuffs_base__low_bits_mask__u32[32] = {
11310     0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000F, 0x0000001F,
11311     0x0000003F, 0x0000007F, 0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF,
11312     0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF, 0x0001FFFF,
11313     0x0003FFFF, 0x0007FFFF, 0x000FFFFF, 0x001FFFFF, 0x003FFFFF, 0x007FFFFF,
11314     0x00FFFFFF, 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF, 0x1FFFFFFF,
11315     0x3FFFFFFF, 0x7FFFFFFF,
11316 };
11317 
11318 const uint64_t wuffs_base__low_bits_mask__u64[64] = {
11319     0x0000000000000000, 0x0000000000000001, 0x0000000000000003,
11320     0x0000000000000007, 0x000000000000000F, 0x000000000000001F,
11321     0x000000000000003F, 0x000000000000007F, 0x00000000000000FF,
11322     0x00000000000001FF, 0x00000000000003FF, 0x00000000000007FF,
11323     0x0000000000000FFF, 0x0000000000001FFF, 0x0000000000003FFF,
11324     0x0000000000007FFF, 0x000000000000FFFF, 0x000000000001FFFF,
11325     0x000000000003FFFF, 0x000000000007FFFF, 0x00000000000FFFFF,
11326     0x00000000001FFFFF, 0x00000000003FFFFF, 0x00000000007FFFFF,
11327     0x0000000000FFFFFF, 0x0000000001FFFFFF, 0x0000000003FFFFFF,
11328     0x0000000007FFFFFF, 0x000000000FFFFFFF, 0x000000001FFFFFFF,
11329     0x000000003FFFFFFF, 0x000000007FFFFFFF, 0x00000000FFFFFFFF,
11330     0x00000001FFFFFFFF, 0x00000003FFFFFFFF, 0x00000007FFFFFFFF,
11331     0x0000000FFFFFFFFF, 0x0000001FFFFFFFFF, 0x0000003FFFFFFFFF,
11332     0x0000007FFFFFFFFF, 0x000000FFFFFFFFFF, 0x000001FFFFFFFFFF,
11333     0x000003FFFFFFFFFF, 0x000007FFFFFFFFFF, 0x00000FFFFFFFFFFF,
11334     0x00001FFFFFFFFFFF, 0x00003FFFFFFFFFFF, 0x00007FFFFFFFFFFF,
11335     0x0000FFFFFFFFFFFF, 0x0001FFFFFFFFFFFF, 0x0003FFFFFFFFFFFF,
11336     0x0007FFFFFFFFFFFF, 0x000FFFFFFFFFFFFF, 0x001FFFFFFFFFFFFF,
11337     0x003FFFFFFFFFFFFF, 0x007FFFFFFFFFFFFF, 0x00FFFFFFFFFFFFFF,
11338     0x01FFFFFFFFFFFFFF, 0x03FFFFFFFFFFFFFF, 0x07FFFFFFFFFFFFFF,
11339     0x0FFFFFFFFFFFFFFF, 0x1FFFFFFFFFFFFFFF, 0x3FFFFFFFFFFFFFFF,
11340     0x7FFFFFFFFFFFFFFF,
11341 };
11342 
11343 const uint32_t wuffs_base__pixel_format__bits_per_channel[16] = {
11344     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
11345     0x08, 0x0A, 0x0C, 0x10, 0x18, 0x20, 0x30, 0x40,
11346 };
11347 
11348 const char wuffs_base__note__i_o_redirect[] = "@base: I/O redirect";
11349 const char wuffs_base__note__end_of_data[] = "@base: end of data";
11350 const char wuffs_base__note__metadata_reported[] = "@base: metadata reported";
11351 const char wuffs_base__suspension__even_more_information[] = "$base: even more information";
11352 const char wuffs_base__suspension__mispositioned_read[] = "$base: mispositioned read";
11353 const char wuffs_base__suspension__mispositioned_write[] = "$base: mispositioned write";
11354 const char wuffs_base__suspension__short_read[] = "$base: short read";
11355 const char wuffs_base__suspension__short_write[] = "$base: short write";
11356 const char wuffs_base__error__bad_i_o_position[] = "#base: bad I/O position";
11357 const char wuffs_base__error__bad_argument_length_too_short[] = "#base: bad argument (length too short)";
11358 const char wuffs_base__error__bad_argument[] = "#base: bad argument";
11359 const char wuffs_base__error__bad_call_sequence[] = "#base: bad call sequence";
11360 const char wuffs_base__error__bad_data[] = "#base: bad data";
11361 const char wuffs_base__error__bad_receiver[] = "#base: bad receiver";
11362 const char wuffs_base__error__bad_restart[] = "#base: bad restart";
11363 const char wuffs_base__error__bad_sizeof_receiver[] = "#base: bad sizeof receiver";
11364 const char wuffs_base__error__bad_vtable[] = "#base: bad vtable";
11365 const char wuffs_base__error__bad_workbuf_length[] = "#base: bad workbuf length";
11366 const char wuffs_base__error__bad_wuffs_version[] = "#base: bad wuffs version";
11367 const char wuffs_base__error__cannot_return_a_suspension[] = "#base: cannot return a suspension";
11368 const char wuffs_base__error__disabled_by_previous_error[] = "#base: disabled by previous error";
11369 const char wuffs_base__error__initialize_falsely_claimed_already_zeroed[] = "#base: initialize falsely claimed already zeroed";
11370 const char wuffs_base__error__initialize_not_called[] = "#base: initialize not called";
11371 const char wuffs_base__error__interleaved_coroutine_calls[] = "#base: interleaved coroutine calls";
11372 const char wuffs_base__error__no_more_information[] = "#base: no more information";
11373 const char wuffs_base__error__not_enough_data[] = "#base: not enough data";
11374 const char wuffs_base__error__out_of_bounds[] = "#base: out of bounds";
11375 const char wuffs_base__error__unsupported_method[] = "#base: unsupported method";
11376 const char wuffs_base__error__unsupported_option[] = "#base: unsupported option";
11377 const char wuffs_base__error__unsupported_pixel_swizzler_option[] = "#base: unsupported pixel swizzler option";
11378 const char wuffs_base__error__too_much_data[] = "#base: too much data";
11379 
11380 const char wuffs_base__hasher_u32__vtable_name[] = "{vtable}wuffs_base__hasher_u32";
11381 const char wuffs_base__image_decoder__vtable_name[] = "{vtable}wuffs_base__image_decoder";
11382 const char wuffs_base__io_transformer__vtable_name[] = "{vtable}wuffs_base__io_transformer";
11383 const char wuffs_base__token_decoder__vtable_name[] = "{vtable}wuffs_base__token_decoder";
11384 
11385 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
11386         // defined(WUFFS_CONFIG__MODULE__BASE)  ||
11387         // defined(WUFFS_CONFIG__MODULE__BASE__CORE)
11388 
11389 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
11390     defined(WUFFS_CONFIG__MODULE__BASE__INTERFACES)
11391 
11392 // ---------------- Interface Definitions.
11393 
11394 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_base__hasher_u32__set_quirk_enabled(wuffs_base__hasher_u32 * self,uint32_t a_quirk,bool a_enabled)11395 wuffs_base__hasher_u32__set_quirk_enabled(
11396     wuffs_base__hasher_u32* self,
11397     uint32_t a_quirk,
11398     bool a_enabled) {
11399   if (!self) {
11400     return wuffs_base__make_empty_struct();
11401   }
11402   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
11403     return wuffs_base__make_empty_struct();
11404   }
11405 
11406   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
11407   int i;
11408   for (i = 0; i < 63; i++) {
11409     if (v->vtable_name == wuffs_base__hasher_u32__vtable_name) {
11410       const wuffs_base__hasher_u32__func_ptrs* func_ptrs =
11411           (const wuffs_base__hasher_u32__func_ptrs*)(v->function_pointers);
11412       return (*func_ptrs->set_quirk_enabled)(self, a_quirk, a_enabled);
11413     } else if (v->vtable_name == NULL) {
11414       break;
11415     }
11416     v++;
11417   }
11418 
11419   return wuffs_base__make_empty_struct();
11420 }
11421 
11422 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_base__hasher_u32__update_u32(wuffs_base__hasher_u32 * self,wuffs_base__slice_u8 a_x)11423 wuffs_base__hasher_u32__update_u32(
11424     wuffs_base__hasher_u32* self,
11425     wuffs_base__slice_u8 a_x) {
11426   if (!self) {
11427     return 0;
11428   }
11429   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
11430     return 0;
11431   }
11432 
11433   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
11434   int i;
11435   for (i = 0; i < 63; i++) {
11436     if (v->vtable_name == wuffs_base__hasher_u32__vtable_name) {
11437       const wuffs_base__hasher_u32__func_ptrs* func_ptrs =
11438           (const wuffs_base__hasher_u32__func_ptrs*)(v->function_pointers);
11439       return (*func_ptrs->update_u32)(self, a_x);
11440     } else if (v->vtable_name == NULL) {
11441       break;
11442     }
11443     v++;
11444   }
11445 
11446   return 0;
11447 }
11448 
11449 // --------
11450 
11451 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)11452 wuffs_base__image_decoder__decode_frame(
11453     wuffs_base__image_decoder* self,
11454     wuffs_base__pixel_buffer* a_dst,
11455     wuffs_base__io_buffer* a_src,
11456     wuffs_base__pixel_blend a_blend,
11457     wuffs_base__slice_u8 a_workbuf,
11458     wuffs_base__decode_frame_options* a_opts) {
11459   if (!self) {
11460     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
11461   }
11462   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
11463     return wuffs_base__make_status(
11464         (self->private_impl.magic == WUFFS_BASE__DISABLED)
11465             ? wuffs_base__error__disabled_by_previous_error
11466             : wuffs_base__error__initialize_not_called);
11467   }
11468 
11469   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
11470   int i;
11471   for (i = 0; i < 63; i++) {
11472     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
11473       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
11474           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
11475       return (*func_ptrs->decode_frame)(self, a_dst, a_src, a_blend, a_workbuf, a_opts);
11476     } else if (v->vtable_name == NULL) {
11477       break;
11478     }
11479     v++;
11480   }
11481 
11482   return wuffs_base__make_status(wuffs_base__error__bad_vtable);
11483 }
11484 
11485 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)11486 wuffs_base__image_decoder__decode_frame_config(
11487     wuffs_base__image_decoder* self,
11488     wuffs_base__frame_config* a_dst,
11489     wuffs_base__io_buffer* a_src) {
11490   if (!self) {
11491     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
11492   }
11493   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
11494     return wuffs_base__make_status(
11495         (self->private_impl.magic == WUFFS_BASE__DISABLED)
11496             ? wuffs_base__error__disabled_by_previous_error
11497             : wuffs_base__error__initialize_not_called);
11498   }
11499 
11500   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
11501   int i;
11502   for (i = 0; i < 63; i++) {
11503     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
11504       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
11505           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
11506       return (*func_ptrs->decode_frame_config)(self, a_dst, a_src);
11507     } else if (v->vtable_name == NULL) {
11508       break;
11509     }
11510     v++;
11511   }
11512 
11513   return wuffs_base__make_status(wuffs_base__error__bad_vtable);
11514 }
11515 
11516 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)11517 wuffs_base__image_decoder__decode_image_config(
11518     wuffs_base__image_decoder* self,
11519     wuffs_base__image_config* a_dst,
11520     wuffs_base__io_buffer* a_src) {
11521   if (!self) {
11522     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
11523   }
11524   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
11525     return wuffs_base__make_status(
11526         (self->private_impl.magic == WUFFS_BASE__DISABLED)
11527             ? wuffs_base__error__disabled_by_previous_error
11528             : wuffs_base__error__initialize_not_called);
11529   }
11530 
11531   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
11532   int i;
11533   for (i = 0; i < 63; i++) {
11534     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
11535       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
11536           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
11537       return (*func_ptrs->decode_image_config)(self, a_dst, a_src);
11538     } else if (v->vtable_name == NULL) {
11539       break;
11540     }
11541     v++;
11542   }
11543 
11544   return wuffs_base__make_status(wuffs_base__error__bad_vtable);
11545 }
11546 
11547 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
wuffs_base__image_decoder__frame_dirty_rect(const wuffs_base__image_decoder * self)11548 wuffs_base__image_decoder__frame_dirty_rect(
11549     const wuffs_base__image_decoder* self) {
11550   if (!self) {
11551     return wuffs_base__utility__empty_rect_ie_u32();
11552   }
11553   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
11554       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
11555     return wuffs_base__utility__empty_rect_ie_u32();
11556   }
11557 
11558   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
11559   int i;
11560   for (i = 0; i < 63; i++) {
11561     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
11562       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
11563           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
11564       return (*func_ptrs->frame_dirty_rect)(self);
11565     } else if (v->vtable_name == NULL) {
11566       break;
11567     }
11568     v++;
11569   }
11570 
11571   return wuffs_base__utility__empty_rect_ie_u32();
11572 }
11573 
11574 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_base__image_decoder__num_animation_loops(const wuffs_base__image_decoder * self)11575 wuffs_base__image_decoder__num_animation_loops(
11576     const wuffs_base__image_decoder* self) {
11577   if (!self) {
11578     return 0;
11579   }
11580   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
11581       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
11582     return 0;
11583   }
11584 
11585   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
11586   int i;
11587   for (i = 0; i < 63; i++) {
11588     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
11589       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
11590           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
11591       return (*func_ptrs->num_animation_loops)(self);
11592     } else if (v->vtable_name == NULL) {
11593       break;
11594     }
11595     v++;
11596   }
11597 
11598   return 0;
11599 }
11600 
11601 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_base__image_decoder__num_decoded_frame_configs(const wuffs_base__image_decoder * self)11602 wuffs_base__image_decoder__num_decoded_frame_configs(
11603     const wuffs_base__image_decoder* self) {
11604   if (!self) {
11605     return 0;
11606   }
11607   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
11608       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
11609     return 0;
11610   }
11611 
11612   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
11613   int i;
11614   for (i = 0; i < 63; i++) {
11615     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
11616       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
11617           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
11618       return (*func_ptrs->num_decoded_frame_configs)(self);
11619     } else if (v->vtable_name == NULL) {
11620       break;
11621     }
11622     v++;
11623   }
11624 
11625   return 0;
11626 }
11627 
11628 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_base__image_decoder__num_decoded_frames(const wuffs_base__image_decoder * self)11629 wuffs_base__image_decoder__num_decoded_frames(
11630     const wuffs_base__image_decoder* self) {
11631   if (!self) {
11632     return 0;
11633   }
11634   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
11635       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
11636     return 0;
11637   }
11638 
11639   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
11640   int i;
11641   for (i = 0; i < 63; i++) {
11642     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
11643       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
11644           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
11645       return (*func_ptrs->num_decoded_frames)(self);
11646     } else if (v->vtable_name == NULL) {
11647       break;
11648     }
11649     v++;
11650   }
11651 
11652   return 0;
11653 }
11654 
11655 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)11656 wuffs_base__image_decoder__restart_frame(
11657     wuffs_base__image_decoder* self,
11658     uint64_t a_index,
11659     uint64_t a_io_position) {
11660   if (!self) {
11661     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
11662   }
11663   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
11664     return wuffs_base__make_status(
11665         (self->private_impl.magic == WUFFS_BASE__DISABLED)
11666             ? wuffs_base__error__disabled_by_previous_error
11667             : wuffs_base__error__initialize_not_called);
11668   }
11669 
11670   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
11671   int i;
11672   for (i = 0; i < 63; i++) {
11673     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
11674       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
11675           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
11676       return (*func_ptrs->restart_frame)(self, a_index, a_io_position);
11677     } else if (v->vtable_name == NULL) {
11678       break;
11679     }
11680     v++;
11681   }
11682 
11683   return wuffs_base__make_status(wuffs_base__error__bad_vtable);
11684 }
11685 
11686 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_base__image_decoder__set_quirk_enabled(wuffs_base__image_decoder * self,uint32_t a_quirk,bool a_enabled)11687 wuffs_base__image_decoder__set_quirk_enabled(
11688     wuffs_base__image_decoder* self,
11689     uint32_t a_quirk,
11690     bool a_enabled) {
11691   if (!self) {
11692     return wuffs_base__make_empty_struct();
11693   }
11694   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
11695     return wuffs_base__make_empty_struct();
11696   }
11697 
11698   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
11699   int i;
11700   for (i = 0; i < 63; i++) {
11701     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
11702       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
11703           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
11704       return (*func_ptrs->set_quirk_enabled)(self, a_quirk, a_enabled);
11705     } else if (v->vtable_name == NULL) {
11706       break;
11707     }
11708     v++;
11709   }
11710 
11711   return wuffs_base__make_empty_struct();
11712 }
11713 
11714 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)11715 wuffs_base__image_decoder__set_report_metadata(
11716     wuffs_base__image_decoder* self,
11717     uint32_t a_fourcc,
11718     bool a_report) {
11719   if (!self) {
11720     return wuffs_base__make_empty_struct();
11721   }
11722   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
11723     return wuffs_base__make_empty_struct();
11724   }
11725 
11726   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
11727   int i;
11728   for (i = 0; i < 63; i++) {
11729     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
11730       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
11731           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
11732       return (*func_ptrs->set_report_metadata)(self, a_fourcc, a_report);
11733     } else if (v->vtable_name == NULL) {
11734       break;
11735     }
11736     v++;
11737   }
11738 
11739   return wuffs_base__make_empty_struct();
11740 }
11741 
11742 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)11743 wuffs_base__image_decoder__tell_me_more(
11744     wuffs_base__image_decoder* self,
11745     wuffs_base__io_buffer* a_dst,
11746     wuffs_base__more_information* a_minfo,
11747     wuffs_base__io_buffer* a_src) {
11748   if (!self) {
11749     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
11750   }
11751   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
11752     return wuffs_base__make_status(
11753         (self->private_impl.magic == WUFFS_BASE__DISABLED)
11754             ? wuffs_base__error__disabled_by_previous_error
11755             : wuffs_base__error__initialize_not_called);
11756   }
11757 
11758   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
11759   int i;
11760   for (i = 0; i < 63; i++) {
11761     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
11762       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
11763           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
11764       return (*func_ptrs->tell_me_more)(self, a_dst, a_minfo, a_src);
11765     } else if (v->vtable_name == NULL) {
11766       break;
11767     }
11768     v++;
11769   }
11770 
11771   return wuffs_base__make_status(wuffs_base__error__bad_vtable);
11772 }
11773 
11774 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_base__image_decoder__workbuf_len(const wuffs_base__image_decoder * self)11775 wuffs_base__image_decoder__workbuf_len(
11776     const wuffs_base__image_decoder* self) {
11777   if (!self) {
11778     return wuffs_base__utility__empty_range_ii_u64();
11779   }
11780   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
11781       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
11782     return wuffs_base__utility__empty_range_ii_u64();
11783   }
11784 
11785   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
11786   int i;
11787   for (i = 0; i < 63; i++) {
11788     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
11789       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
11790           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
11791       return (*func_ptrs->workbuf_len)(self);
11792     } else if (v->vtable_name == NULL) {
11793       break;
11794     }
11795     v++;
11796   }
11797 
11798   return wuffs_base__utility__empty_range_ii_u64();
11799 }
11800 
11801 // --------
11802 
11803 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_base__io_transformer__set_quirk_enabled(wuffs_base__io_transformer * self,uint32_t a_quirk,bool a_enabled)11804 wuffs_base__io_transformer__set_quirk_enabled(
11805     wuffs_base__io_transformer* self,
11806     uint32_t a_quirk,
11807     bool a_enabled) {
11808   if (!self) {
11809     return wuffs_base__make_empty_struct();
11810   }
11811   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
11812     return wuffs_base__make_empty_struct();
11813   }
11814 
11815   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
11816   int i;
11817   for (i = 0; i < 63; i++) {
11818     if (v->vtable_name == wuffs_base__io_transformer__vtable_name) {
11819       const wuffs_base__io_transformer__func_ptrs* func_ptrs =
11820           (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers);
11821       return (*func_ptrs->set_quirk_enabled)(self, a_quirk, a_enabled);
11822     } else if (v->vtable_name == NULL) {
11823       break;
11824     }
11825     v++;
11826   }
11827 
11828   return wuffs_base__make_empty_struct();
11829 }
11830 
11831 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)11832 wuffs_base__io_transformer__transform_io(
11833     wuffs_base__io_transformer* self,
11834     wuffs_base__io_buffer* a_dst,
11835     wuffs_base__io_buffer* a_src,
11836     wuffs_base__slice_u8 a_workbuf) {
11837   if (!self) {
11838     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
11839   }
11840   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
11841     return wuffs_base__make_status(
11842         (self->private_impl.magic == WUFFS_BASE__DISABLED)
11843             ? wuffs_base__error__disabled_by_previous_error
11844             : wuffs_base__error__initialize_not_called);
11845   }
11846 
11847   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
11848   int i;
11849   for (i = 0; i < 63; i++) {
11850     if (v->vtable_name == wuffs_base__io_transformer__vtable_name) {
11851       const wuffs_base__io_transformer__func_ptrs* func_ptrs =
11852           (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers);
11853       return (*func_ptrs->transform_io)(self, a_dst, a_src, a_workbuf);
11854     } else if (v->vtable_name == NULL) {
11855       break;
11856     }
11857     v++;
11858   }
11859 
11860   return wuffs_base__make_status(wuffs_base__error__bad_vtable);
11861 }
11862 
11863 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_base__io_transformer__workbuf_len(const wuffs_base__io_transformer * self)11864 wuffs_base__io_transformer__workbuf_len(
11865     const wuffs_base__io_transformer* self) {
11866   if (!self) {
11867     return wuffs_base__utility__empty_range_ii_u64();
11868   }
11869   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
11870       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
11871     return wuffs_base__utility__empty_range_ii_u64();
11872   }
11873 
11874   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
11875   int i;
11876   for (i = 0; i < 63; i++) {
11877     if (v->vtable_name == wuffs_base__io_transformer__vtable_name) {
11878       const wuffs_base__io_transformer__func_ptrs* func_ptrs =
11879           (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers);
11880       return (*func_ptrs->workbuf_len)(self);
11881     } else if (v->vtable_name == NULL) {
11882       break;
11883     }
11884     v++;
11885   }
11886 
11887   return wuffs_base__utility__empty_range_ii_u64();
11888 }
11889 
11890 // --------
11891 
11892 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)11893 wuffs_base__token_decoder__decode_tokens(
11894     wuffs_base__token_decoder* self,
11895     wuffs_base__token_buffer* a_dst,
11896     wuffs_base__io_buffer* a_src,
11897     wuffs_base__slice_u8 a_workbuf) {
11898   if (!self) {
11899     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
11900   }
11901   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
11902     return wuffs_base__make_status(
11903         (self->private_impl.magic == WUFFS_BASE__DISABLED)
11904             ? wuffs_base__error__disabled_by_previous_error
11905             : wuffs_base__error__initialize_not_called);
11906   }
11907 
11908   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
11909   int i;
11910   for (i = 0; i < 63; i++) {
11911     if (v->vtable_name == wuffs_base__token_decoder__vtable_name) {
11912       const wuffs_base__token_decoder__func_ptrs* func_ptrs =
11913           (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers);
11914       return (*func_ptrs->decode_tokens)(self, a_dst, a_src, a_workbuf);
11915     } else if (v->vtable_name == NULL) {
11916       break;
11917     }
11918     v++;
11919   }
11920 
11921   return wuffs_base__make_status(wuffs_base__error__bad_vtable);
11922 }
11923 
11924 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_base__token_decoder__set_quirk_enabled(wuffs_base__token_decoder * self,uint32_t a_quirk,bool a_enabled)11925 wuffs_base__token_decoder__set_quirk_enabled(
11926     wuffs_base__token_decoder* self,
11927     uint32_t a_quirk,
11928     bool a_enabled) {
11929   if (!self) {
11930     return wuffs_base__make_empty_struct();
11931   }
11932   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
11933     return wuffs_base__make_empty_struct();
11934   }
11935 
11936   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
11937   int i;
11938   for (i = 0; i < 63; i++) {
11939     if (v->vtable_name == wuffs_base__token_decoder__vtable_name) {
11940       const wuffs_base__token_decoder__func_ptrs* func_ptrs =
11941           (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers);
11942       return (*func_ptrs->set_quirk_enabled)(self, a_quirk, a_enabled);
11943     } else if (v->vtable_name == NULL) {
11944       break;
11945     }
11946     v++;
11947   }
11948 
11949   return wuffs_base__make_empty_struct();
11950 }
11951 
11952 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_base__token_decoder__workbuf_len(const wuffs_base__token_decoder * self)11953 wuffs_base__token_decoder__workbuf_len(
11954     const wuffs_base__token_decoder* self) {
11955   if (!self) {
11956     return wuffs_base__utility__empty_range_ii_u64();
11957   }
11958   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
11959       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
11960     return wuffs_base__utility__empty_range_ii_u64();
11961   }
11962 
11963   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
11964   int i;
11965   for (i = 0; i < 63; i++) {
11966     if (v->vtable_name == wuffs_base__token_decoder__vtable_name) {
11967       const wuffs_base__token_decoder__func_ptrs* func_ptrs =
11968           (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers);
11969       return (*func_ptrs->workbuf_len)(self);
11970     } else if (v->vtable_name == NULL) {
11971       break;
11972     }
11973     v++;
11974   }
11975 
11976   return wuffs_base__utility__empty_range_ii_u64();
11977 }
11978 
11979 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
11980         // defined(WUFFS_CONFIG__MODULE__BASE) ||
11981         // defined(WUFFS_CONFIG__MODULE__BASE__INTERFACES)
11982 
11983 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
11984     defined(WUFFS_CONFIG__MODULE__BASE__FLOATCONV)
11985 
11986 // ---------------- IEEE 754 Floating Point
11987 
11988 // The etc__hpd_left_shift and etc__powers_of_5 tables were printed by
11989 // script/print-hpd-left-shift.go. That script has an optional -comments flag,
11990 // whose output is not copied here, which prints further detail.
11991 //
11992 // These tables are used in
11993 // wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits.
11994 
11995 // wuffs_base__private_implementation__hpd_left_shift[i] encodes the number of
11996 // new digits created after multiplying a positive integer by (1 << i): the
11997 // additional length in the decimal representation. For example, shifting "234"
11998 // by 3 (equivalent to multiplying by 8) will produce "1872". Going from a
11999 // 3-length string to a 4-length string means that 1 new digit was added (and
12000 // existing digits may have changed).
12001 //
12002 // Shifting by i can add either N or N-1 new digits, depending on whether the
12003 // original positive integer compares >= or < to the i'th power of 5 (as 10
12004 // equals 2 * 5). Comparison is lexicographic, not numerical.
12005 //
12006 // For example, shifting by 4 (i.e. multiplying by 16) can add 1 or 2 new
12007 // digits, depending on a lexicographic comparison to (5 ** 4), i.e. "625":
12008 //  - ("1"      << 4) is "16",       which adds 1 new digit.
12009 //  - ("5678"   << 4) is "90848",    which adds 1 new digit.
12010 //  - ("624"    << 4) is "9984",     which adds 1 new digit.
12011 //  - ("62498"  << 4) is "999968",   which adds 1 new digit.
12012 //  - ("625"    << 4) is "10000",    which adds 2 new digits.
12013 //  - ("625001" << 4) is "10000016", which adds 2 new digits.
12014 //  - ("7008"   << 4) is "112128",   which adds 2 new digits.
12015 //  - ("99"     << 4) is "1584",     which adds 2 new digits.
12016 //
12017 // Thus, when i is 4, N is 2 and (5 ** i) is "625". This etc__hpd_left_shift
12018 // array encodes this as:
12019 //  - etc__hpd_left_shift[4] is 0x1006 = (2 << 11) | 0x0006.
12020 //  - etc__hpd_left_shift[5] is 0x1009 = (? << 11) | 0x0009.
12021 // where the ? isn't relevant for i == 4.
12022 //
12023 // The high 5 bits of etc__hpd_left_shift[i] is N, the higher of the two
12024 // possible number of new digits. The low 11 bits are an offset into the
12025 // etc__powers_of_5 array (of length 0x051C, so offsets fit in 11 bits). When i
12026 // is 4, its offset and the next one is 6 and 9, and etc__powers_of_5[6 .. 9]
12027 // is the string "\x06\x02\x05", so the relevant power of 5 is "625".
12028 //
12029 // Thanks to Ken Thompson for the original idea.
12030 static const uint16_t wuffs_base__private_implementation__hpd_left_shift[65] = {
12031     0x0000, 0x0800, 0x0801, 0x0803, 0x1006, 0x1009, 0x100D, 0x1812, 0x1817,
12032     0x181D, 0x2024, 0x202B, 0x2033, 0x203C, 0x2846, 0x2850, 0x285B, 0x3067,
12033     0x3073, 0x3080, 0x388E, 0x389C, 0x38AB, 0x38BB, 0x40CC, 0x40DD, 0x40EF,
12034     0x4902, 0x4915, 0x4929, 0x513E, 0x5153, 0x5169, 0x5180, 0x5998, 0x59B0,
12035     0x59C9, 0x61E3, 0x61FD, 0x6218, 0x6A34, 0x6A50, 0x6A6D, 0x6A8B, 0x72AA,
12036     0x72C9, 0x72E9, 0x7B0A, 0x7B2B, 0x7B4D, 0x8370, 0x8393, 0x83B7, 0x83DC,
12037     0x8C02, 0x8C28, 0x8C4F, 0x9477, 0x949F, 0x94C8, 0x9CF2, 0x051C, 0x051C,
12038     0x051C, 0x051C,
12039 };
12040 
12041 // wuffs_base__private_implementation__powers_of_5 contains the powers of 5,
12042 // concatenated together: "5", "25", "125", "625", "3125", etc.
12043 static const uint8_t wuffs_base__private_implementation__powers_of_5[0x051C] = {
12044     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,
12045     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,
12046     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,
12047     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,
12048     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,
12049     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,
12050     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,
12051     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,
12052     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,
12053     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,
12054     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,
12055     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,
12056     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,
12057     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,
12058     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,
12059     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,
12060     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,
12061     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,
12062     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,
12063     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,
12064     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,
12065     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,
12066     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,
12067     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,
12068     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,
12069     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,
12070     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,
12071     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,
12072     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,
12073     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,
12074     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,
12075     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,
12076     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,
12077     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,
12078     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,
12079     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,
12080     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,
12081     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,
12082     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,
12083     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,
12084     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,
12085     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,
12086     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,
12087     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,
12088     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,
12089     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,
12090     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,
12091     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,
12092     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,
12093     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,
12094     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,
12095     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,
12096     6, 9, 1, 4, 0, 6, 2, 5,
12097 };
12098 
12099 // --------
12100 
12101 // wuffs_base__private_implementation__powers_of_10 contains truncated
12102 // approximations to the powers of 10, ranging from 1e-307 to 1e+288 inclusive,
12103 // as 596 pairs of uint64_t values (a 128-bit mantissa).
12104 //
12105 // There's also an implicit third column (implied by a linear formula involving
12106 // the base-10 exponent) that is the base-2 exponent, biased by a magic
12107 // constant. That constant (1214 or 0x04BE) equals 1023 + 191. 1023 is the bias
12108 // for IEEE 754 double-precision floating point. 191 is ((3 * 64) - 1) and
12109 // wuffs_base__private_implementation__parse_number_f64_eisel_lemire works with
12110 // multiples-of-64-bit mantissas.
12111 //
12112 // For example, the third row holds the approximation to 1e-305:
12113 //   0xE0B62E29_29ABA83C_331ACDAB_FE94DE87 * (2 ** (0x0049 - 0x04BE))
12114 //
12115 // Similarly, 1e+4 is approximated by:
12116 //   0x9C400000_00000000_00000000_00000000 * (2 ** (0x044C - 0x04BE))
12117 //
12118 // Similarly, 1e+68 is approximated by:
12119 //   0xED63A231_D4C4FB27_4CA7AAA8_63EE4BDD * (2 ** (0x0520 - 0x04BE))
12120 //
12121 // This table was generated by by script/print-mpb-powers-of-10.go
12122 static const uint64_t wuffs_base__private_implementation__powers_of_10[596][2] =
12123     {
12124         {0xA5D3B6D479F8E056, 0x8FD0C16206306BAB},  // 1e-307
12125         {0x8F48A4899877186C, 0xB3C4F1BA87BC8696},  // 1e-306
12126         {0x331ACDABFE94DE87, 0xE0B62E2929ABA83C},  // 1e-305
12127         {0x9FF0C08B7F1D0B14, 0x8C71DCD9BA0B4925},  // 1e-304
12128         {0x07ECF0AE5EE44DD9, 0xAF8E5410288E1B6F},  // 1e-303
12129         {0xC9E82CD9F69D6150, 0xDB71E91432B1A24A},  // 1e-302
12130         {0xBE311C083A225CD2, 0x892731AC9FAF056E},  // 1e-301
12131         {0x6DBD630A48AAF406, 0xAB70FE17C79AC6CA},  // 1e-300
12132         {0x092CBBCCDAD5B108, 0xD64D3D9DB981787D},  // 1e-299
12133         {0x25BBF56008C58EA5, 0x85F0468293F0EB4E},  // 1e-298
12134         {0xAF2AF2B80AF6F24E, 0xA76C582338ED2621},  // 1e-297
12135         {0x1AF5AF660DB4AEE1, 0xD1476E2C07286FAA},  // 1e-296
12136         {0x50D98D9FC890ED4D, 0x82CCA4DB847945CA},  // 1e-295
12137         {0xE50FF107BAB528A0, 0xA37FCE126597973C},  // 1e-294
12138         {0x1E53ED49A96272C8, 0xCC5FC196FEFD7D0C},  // 1e-293
12139         {0x25E8E89C13BB0F7A, 0xFF77B1FCBEBCDC4F},  // 1e-292
12140         {0x77B191618C54E9AC, 0x9FAACF3DF73609B1},  // 1e-291
12141         {0xD59DF5B9EF6A2417, 0xC795830D75038C1D},  // 1e-290
12142         {0x4B0573286B44AD1D, 0xF97AE3D0D2446F25},  // 1e-289
12143         {0x4EE367F9430AEC32, 0x9BECCE62836AC577},  // 1e-288
12144         {0x229C41F793CDA73F, 0xC2E801FB244576D5},  // 1e-287
12145         {0x6B43527578C1110F, 0xF3A20279ED56D48A},  // 1e-286
12146         {0x830A13896B78AAA9, 0x9845418C345644D6},  // 1e-285
12147         {0x23CC986BC656D553, 0xBE5691EF416BD60C},  // 1e-284
12148         {0x2CBFBE86B7EC8AA8, 0xEDEC366B11C6CB8F},  // 1e-283
12149         {0x7BF7D71432F3D6A9, 0x94B3A202EB1C3F39},  // 1e-282
12150         {0xDAF5CCD93FB0CC53, 0xB9E08A83A5E34F07},  // 1e-281
12151         {0xD1B3400F8F9CFF68, 0xE858AD248F5C22C9},  // 1e-280
12152         {0x23100809B9C21FA1, 0x91376C36D99995BE},  // 1e-279
12153         {0xABD40A0C2832A78A, 0xB58547448FFFFB2D},  // 1e-278
12154         {0x16C90C8F323F516C, 0xE2E69915B3FFF9F9},  // 1e-277
12155         {0xAE3DA7D97F6792E3, 0x8DD01FAD907FFC3B},  // 1e-276
12156         {0x99CD11CFDF41779C, 0xB1442798F49FFB4A},  // 1e-275
12157         {0x40405643D711D583, 0xDD95317F31C7FA1D},  // 1e-274
12158         {0x482835EA666B2572, 0x8A7D3EEF7F1CFC52},  // 1e-273
12159         {0xDA3243650005EECF, 0xAD1C8EAB5EE43B66},  // 1e-272
12160         {0x90BED43E40076A82, 0xD863B256369D4A40},  // 1e-271
12161         {0x5A7744A6E804A291, 0x873E4F75E2224E68},  // 1e-270
12162         {0x711515D0A205CB36, 0xA90DE3535AAAE202},  // 1e-269
12163         {0x0D5A5B44CA873E03, 0xD3515C2831559A83},  // 1e-268
12164         {0xE858790AFE9486C2, 0x8412D9991ED58091},  // 1e-267
12165         {0x626E974DBE39A872, 0xA5178FFF668AE0B6},  // 1e-266
12166         {0xFB0A3D212DC8128F, 0xCE5D73FF402D98E3},  // 1e-265
12167         {0x7CE66634BC9D0B99, 0x80FA687F881C7F8E},  // 1e-264
12168         {0x1C1FFFC1EBC44E80, 0xA139029F6A239F72},  // 1e-263
12169         {0xA327FFB266B56220, 0xC987434744AC874E},  // 1e-262
12170         {0x4BF1FF9F0062BAA8, 0xFBE9141915D7A922},  // 1e-261
12171         {0x6F773FC3603DB4A9, 0x9D71AC8FADA6C9B5},  // 1e-260
12172         {0xCB550FB4384D21D3, 0xC4CE17B399107C22},  // 1e-259
12173         {0x7E2A53A146606A48, 0xF6019DA07F549B2B},  // 1e-258
12174         {0x2EDA7444CBFC426D, 0x99C102844F94E0FB},  // 1e-257
12175         {0xFA911155FEFB5308, 0xC0314325637A1939},  // 1e-256
12176         {0x793555AB7EBA27CA, 0xF03D93EEBC589F88},  // 1e-255
12177         {0x4BC1558B2F3458DE, 0x96267C7535B763B5},  // 1e-254
12178         {0x9EB1AAEDFB016F16, 0xBBB01B9283253CA2},  // 1e-253
12179         {0x465E15A979C1CADC, 0xEA9C227723EE8BCB},  // 1e-252
12180         {0x0BFACD89EC191EC9, 0x92A1958A7675175F},  // 1e-251
12181         {0xCEF980EC671F667B, 0xB749FAED14125D36},  // 1e-250
12182         {0x82B7E12780E7401A, 0xE51C79A85916F484},  // 1e-249
12183         {0xD1B2ECB8B0908810, 0x8F31CC0937AE58D2},  // 1e-248
12184         {0x861FA7E6DCB4AA15, 0xB2FE3F0B8599EF07},  // 1e-247
12185         {0x67A791E093E1D49A, 0xDFBDCECE67006AC9},  // 1e-246
12186         {0xE0C8BB2C5C6D24E0, 0x8BD6A141006042BD},  // 1e-245
12187         {0x58FAE9F773886E18, 0xAECC49914078536D},  // 1e-244
12188         {0xAF39A475506A899E, 0xDA7F5BF590966848},  // 1e-243
12189         {0x6D8406C952429603, 0x888F99797A5E012D},  // 1e-242
12190         {0xC8E5087BA6D33B83, 0xAAB37FD7D8F58178},  // 1e-241
12191         {0xFB1E4A9A90880A64, 0xD5605FCDCF32E1D6},  // 1e-240
12192         {0x5CF2EEA09A55067F, 0x855C3BE0A17FCD26},  // 1e-239
12193         {0xF42FAA48C0EA481E, 0xA6B34AD8C9DFC06F},  // 1e-238
12194         {0xF13B94DAF124DA26, 0xD0601D8EFC57B08B},  // 1e-237
12195         {0x76C53D08D6B70858, 0x823C12795DB6CE57},  // 1e-236
12196         {0x54768C4B0C64CA6E, 0xA2CB1717B52481ED},  // 1e-235
12197         {0xA9942F5DCF7DFD09, 0xCB7DDCDDA26DA268},  // 1e-234
12198         {0xD3F93B35435D7C4C, 0xFE5D54150B090B02},  // 1e-233
12199         {0xC47BC5014A1A6DAF, 0x9EFA548D26E5A6E1},  // 1e-232
12200         {0x359AB6419CA1091B, 0xC6B8E9B0709F109A},  // 1e-231
12201         {0xC30163D203C94B62, 0xF867241C8CC6D4C0},  // 1e-230
12202         {0x79E0DE63425DCF1D, 0x9B407691D7FC44F8},  // 1e-229
12203         {0x985915FC12F542E4, 0xC21094364DFB5636},  // 1e-228
12204         {0x3E6F5B7B17B2939D, 0xF294B943E17A2BC4},  // 1e-227
12205         {0xA705992CEECF9C42, 0x979CF3CA6CEC5B5A},  // 1e-226
12206         {0x50C6FF782A838353, 0xBD8430BD08277231},  // 1e-225
12207         {0xA4F8BF5635246428, 0xECE53CEC4A314EBD},  // 1e-224
12208         {0x871B7795E136BE99, 0x940F4613AE5ED136},  // 1e-223
12209         {0x28E2557B59846E3F, 0xB913179899F68584},  // 1e-222
12210         {0x331AEADA2FE589CF, 0xE757DD7EC07426E5},  // 1e-221
12211         {0x3FF0D2C85DEF7621, 0x9096EA6F3848984F},  // 1e-220
12212         {0x0FED077A756B53A9, 0xB4BCA50B065ABE63},  // 1e-219
12213         {0xD3E8495912C62894, 0xE1EBCE4DC7F16DFB},  // 1e-218
12214         {0x64712DD7ABBBD95C, 0x8D3360F09CF6E4BD},  // 1e-217
12215         {0xBD8D794D96AACFB3, 0xB080392CC4349DEC},  // 1e-216
12216         {0xECF0D7A0FC5583A0, 0xDCA04777F541C567},  // 1e-215
12217         {0xF41686C49DB57244, 0x89E42CAAF9491B60},  // 1e-214
12218         {0x311C2875C522CED5, 0xAC5D37D5B79B6239},  // 1e-213
12219         {0x7D633293366B828B, 0xD77485CB25823AC7},  // 1e-212
12220         {0xAE5DFF9C02033197, 0x86A8D39EF77164BC},  // 1e-211
12221         {0xD9F57F830283FDFC, 0xA8530886B54DBDEB},  // 1e-210
12222         {0xD072DF63C324FD7B, 0xD267CAA862A12D66},  // 1e-209
12223         {0x4247CB9E59F71E6D, 0x8380DEA93DA4BC60},  // 1e-208
12224         {0x52D9BE85F074E608, 0xA46116538D0DEB78},  // 1e-207
12225         {0x67902E276C921F8B, 0xCD795BE870516656},  // 1e-206
12226         {0x00BA1CD8A3DB53B6, 0x806BD9714632DFF6},  // 1e-205
12227         {0x80E8A40ECCD228A4, 0xA086CFCD97BF97F3},  // 1e-204
12228         {0x6122CD128006B2CD, 0xC8A883C0FDAF7DF0},  // 1e-203
12229         {0x796B805720085F81, 0xFAD2A4B13D1B5D6C},  // 1e-202
12230         {0xCBE3303674053BB0, 0x9CC3A6EEC6311A63},  // 1e-201
12231         {0xBEDBFC4411068A9C, 0xC3F490AA77BD60FC},  // 1e-200
12232         {0xEE92FB5515482D44, 0xF4F1B4D515ACB93B},  // 1e-199
12233         {0x751BDD152D4D1C4A, 0x991711052D8BF3C5},  // 1e-198
12234         {0xD262D45A78A0635D, 0xBF5CD54678EEF0B6},  // 1e-197
12235         {0x86FB897116C87C34, 0xEF340A98172AACE4},  // 1e-196
12236         {0xD45D35E6AE3D4DA0, 0x9580869F0E7AAC0E},  // 1e-195
12237         {0x8974836059CCA109, 0xBAE0A846D2195712},  // 1e-194
12238         {0x2BD1A438703FC94B, 0xE998D258869FACD7},  // 1e-193
12239         {0x7B6306A34627DDCF, 0x91FF83775423CC06},  // 1e-192
12240         {0x1A3BC84C17B1D542, 0xB67F6455292CBF08},  // 1e-191
12241         {0x20CABA5F1D9E4A93, 0xE41F3D6A7377EECA},  // 1e-190
12242         {0x547EB47B7282EE9C, 0x8E938662882AF53E},  // 1e-189
12243         {0xE99E619A4F23AA43, 0xB23867FB2A35B28D},  // 1e-188
12244         {0x6405FA00E2EC94D4, 0xDEC681F9F4C31F31},  // 1e-187
12245         {0xDE83BC408DD3DD04, 0x8B3C113C38F9F37E},  // 1e-186
12246         {0x9624AB50B148D445, 0xAE0B158B4738705E},  // 1e-185
12247         {0x3BADD624DD9B0957, 0xD98DDAEE19068C76},  // 1e-184
12248         {0xE54CA5D70A80E5D6, 0x87F8A8D4CFA417C9},  // 1e-183
12249         {0x5E9FCF4CCD211F4C, 0xA9F6D30A038D1DBC},  // 1e-182
12250         {0x7647C3200069671F, 0xD47487CC8470652B},  // 1e-181
12251         {0x29ECD9F40041E073, 0x84C8D4DFD2C63F3B},  // 1e-180
12252         {0xF468107100525890, 0xA5FB0A17C777CF09},  // 1e-179
12253         {0x7182148D4066EEB4, 0xCF79CC9DB955C2CC},  // 1e-178
12254         {0xC6F14CD848405530, 0x81AC1FE293D599BF},  // 1e-177
12255         {0xB8ADA00E5A506A7C, 0xA21727DB38CB002F},  // 1e-176
12256         {0xA6D90811F0E4851C, 0xCA9CF1D206FDC03B},  // 1e-175
12257         {0x908F4A166D1DA663, 0xFD442E4688BD304A},  // 1e-174
12258         {0x9A598E4E043287FE, 0x9E4A9CEC15763E2E},  // 1e-173
12259         {0x40EFF1E1853F29FD, 0xC5DD44271AD3CDBA},  // 1e-172
12260         {0xD12BEE59E68EF47C, 0xF7549530E188C128},  // 1e-171
12261         {0x82BB74F8301958CE, 0x9A94DD3E8CF578B9},  // 1e-170
12262         {0xE36A52363C1FAF01, 0xC13A148E3032D6E7},  // 1e-169
12263         {0xDC44E6C3CB279AC1, 0xF18899B1BC3F8CA1},  // 1e-168
12264         {0x29AB103A5EF8C0B9, 0x96F5600F15A7B7E5},  // 1e-167
12265         {0x7415D448F6B6F0E7, 0xBCB2B812DB11A5DE},  // 1e-166
12266         {0x111B495B3464AD21, 0xEBDF661791D60F56},  // 1e-165
12267         {0xCAB10DD900BEEC34, 0x936B9FCEBB25C995},  // 1e-164
12268         {0x3D5D514F40EEA742, 0xB84687C269EF3BFB},  // 1e-163
12269         {0x0CB4A5A3112A5112, 0xE65829B3046B0AFA},  // 1e-162
12270         {0x47F0E785EABA72AB, 0x8FF71A0FE2C2E6DC},  // 1e-161
12271         {0x59ED216765690F56, 0xB3F4E093DB73A093},  // 1e-160
12272         {0x306869C13EC3532C, 0xE0F218B8D25088B8},  // 1e-159
12273         {0x1E414218C73A13FB, 0x8C974F7383725573},  // 1e-158
12274         {0xE5D1929EF90898FA, 0xAFBD2350644EEACF},  // 1e-157
12275         {0xDF45F746B74ABF39, 0xDBAC6C247D62A583},  // 1e-156
12276         {0x6B8BBA8C328EB783, 0x894BC396CE5DA772},  // 1e-155
12277         {0x066EA92F3F326564, 0xAB9EB47C81F5114F},  // 1e-154
12278         {0xC80A537B0EFEFEBD, 0xD686619BA27255A2},  // 1e-153
12279         {0xBD06742CE95F5F36, 0x8613FD0145877585},  // 1e-152
12280         {0x2C48113823B73704, 0xA798FC4196E952E7},  // 1e-151
12281         {0xF75A15862CA504C5, 0xD17F3B51FCA3A7A0},  // 1e-150
12282         {0x9A984D73DBE722FB, 0x82EF85133DE648C4},  // 1e-149
12283         {0xC13E60D0D2E0EBBA, 0xA3AB66580D5FDAF5},  // 1e-148
12284         {0x318DF905079926A8, 0xCC963FEE10B7D1B3},  // 1e-147
12285         {0xFDF17746497F7052, 0xFFBBCFE994E5C61F},  // 1e-146
12286         {0xFEB6EA8BEDEFA633, 0x9FD561F1FD0F9BD3},  // 1e-145
12287         {0xFE64A52EE96B8FC0, 0xC7CABA6E7C5382C8},  // 1e-144
12288         {0x3DFDCE7AA3C673B0, 0xF9BD690A1B68637B},  // 1e-143
12289         {0x06BEA10CA65C084E, 0x9C1661A651213E2D},  // 1e-142
12290         {0x486E494FCFF30A62, 0xC31BFA0FE5698DB8},  // 1e-141
12291         {0x5A89DBA3C3EFCCFA, 0xF3E2F893DEC3F126},  // 1e-140
12292         {0xF89629465A75E01C, 0x986DDB5C6B3A76B7},  // 1e-139
12293         {0xF6BBB397F1135823, 0xBE89523386091465},  // 1e-138
12294         {0x746AA07DED582E2C, 0xEE2BA6C0678B597F},  // 1e-137
12295         {0xA8C2A44EB4571CDC, 0x94DB483840B717EF},  // 1e-136
12296         {0x92F34D62616CE413, 0xBA121A4650E4DDEB},  // 1e-135
12297         {0x77B020BAF9C81D17, 0xE896A0D7E51E1566},  // 1e-134
12298         {0x0ACE1474DC1D122E, 0x915E2486EF32CD60},  // 1e-133
12299         {0x0D819992132456BA, 0xB5B5ADA8AAFF80B8},  // 1e-132
12300         {0x10E1FFF697ED6C69, 0xE3231912D5BF60E6},  // 1e-131
12301         {0xCA8D3FFA1EF463C1, 0x8DF5EFABC5979C8F},  // 1e-130
12302         {0xBD308FF8A6B17CB2, 0xB1736B96B6FD83B3},  // 1e-129
12303         {0xAC7CB3F6D05DDBDE, 0xDDD0467C64BCE4A0},  // 1e-128
12304         {0x6BCDF07A423AA96B, 0x8AA22C0DBEF60EE4},  // 1e-127
12305         {0x86C16C98D2C953C6, 0xAD4AB7112EB3929D},  // 1e-126
12306         {0xE871C7BF077BA8B7, 0xD89D64D57A607744},  // 1e-125
12307         {0x11471CD764AD4972, 0x87625F056C7C4A8B},  // 1e-124
12308         {0xD598E40D3DD89BCF, 0xA93AF6C6C79B5D2D},  // 1e-123
12309         {0x4AFF1D108D4EC2C3, 0xD389B47879823479},  // 1e-122
12310         {0xCEDF722A585139BA, 0x843610CB4BF160CB},  // 1e-121
12311         {0xC2974EB4EE658828, 0xA54394FE1EEDB8FE},  // 1e-120
12312         {0x733D226229FEEA32, 0xCE947A3DA6A9273E},  // 1e-119
12313         {0x0806357D5A3F525F, 0x811CCC668829B887},  // 1e-118
12314         {0xCA07C2DCB0CF26F7, 0xA163FF802A3426A8},  // 1e-117
12315         {0xFC89B393DD02F0B5, 0xC9BCFF6034C13052},  // 1e-116
12316         {0xBBAC2078D443ACE2, 0xFC2C3F3841F17C67},  // 1e-115
12317         {0xD54B944B84AA4C0D, 0x9D9BA7832936EDC0},  // 1e-114
12318         {0x0A9E795E65D4DF11, 0xC5029163F384A931},  // 1e-113
12319         {0x4D4617B5FF4A16D5, 0xF64335BCF065D37D},  // 1e-112
12320         {0x504BCED1BF8E4E45, 0x99EA0196163FA42E},  // 1e-111
12321         {0xE45EC2862F71E1D6, 0xC06481FB9BCF8D39},  // 1e-110
12322         {0x5D767327BB4E5A4C, 0xF07DA27A82C37088},  // 1e-109
12323         {0x3A6A07F8D510F86F, 0x964E858C91BA2655},  // 1e-108
12324         {0x890489F70A55368B, 0xBBE226EFB628AFEA},  // 1e-107
12325         {0x2B45AC74CCEA842E, 0xEADAB0ABA3B2DBE5},  // 1e-106
12326         {0x3B0B8BC90012929D, 0x92C8AE6B464FC96F},  // 1e-105
12327         {0x09CE6EBB40173744, 0xB77ADA0617E3BBCB},  // 1e-104
12328         {0xCC420A6A101D0515, 0xE55990879DDCAABD},  // 1e-103
12329         {0x9FA946824A12232D, 0x8F57FA54C2A9EAB6},  // 1e-102
12330         {0x47939822DC96ABF9, 0xB32DF8E9F3546564},  // 1e-101
12331         {0x59787E2B93BC56F7, 0xDFF9772470297EBD},  // 1e-100
12332         {0x57EB4EDB3C55B65A, 0x8BFBEA76C619EF36},  // 1e-99
12333         {0xEDE622920B6B23F1, 0xAEFAE51477A06B03},  // 1e-98
12334         {0xE95FAB368E45ECED, 0xDAB99E59958885C4},  // 1e-97
12335         {0x11DBCB0218EBB414, 0x88B402F7FD75539B},  // 1e-96
12336         {0xD652BDC29F26A119, 0xAAE103B5FCD2A881},  // 1e-95
12337         {0x4BE76D3346F0495F, 0xD59944A37C0752A2},  // 1e-94
12338         {0x6F70A4400C562DDB, 0x857FCAE62D8493A5},  // 1e-93
12339         {0xCB4CCD500F6BB952, 0xA6DFBD9FB8E5B88E},  // 1e-92
12340         {0x7E2000A41346A7A7, 0xD097AD07A71F26B2},  // 1e-91
12341         {0x8ED400668C0C28C8, 0x825ECC24C873782F},  // 1e-90
12342         {0x728900802F0F32FA, 0xA2F67F2DFA90563B},  // 1e-89
12343         {0x4F2B40A03AD2FFB9, 0xCBB41EF979346BCA},  // 1e-88
12344         {0xE2F610C84987BFA8, 0xFEA126B7D78186BC},  // 1e-87
12345         {0x0DD9CA7D2DF4D7C9, 0x9F24B832E6B0F436},  // 1e-86
12346         {0x91503D1C79720DBB, 0xC6EDE63FA05D3143},  // 1e-85
12347         {0x75A44C6397CE912A, 0xF8A95FCF88747D94},  // 1e-84
12348         {0xC986AFBE3EE11ABA, 0x9B69DBE1B548CE7C},  // 1e-83
12349         {0xFBE85BADCE996168, 0xC24452DA229B021B},  // 1e-82
12350         {0xFAE27299423FB9C3, 0xF2D56790AB41C2A2},  // 1e-81
12351         {0xDCCD879FC967D41A, 0x97C560BA6B0919A5},  // 1e-80
12352         {0x5400E987BBC1C920, 0xBDB6B8E905CB600F},  // 1e-79
12353         {0x290123E9AAB23B68, 0xED246723473E3813},  // 1e-78
12354         {0xF9A0B6720AAF6521, 0x9436C0760C86E30B},  // 1e-77
12355         {0xF808E40E8D5B3E69, 0xB94470938FA89BCE},  // 1e-76
12356         {0xB60B1D1230B20E04, 0xE7958CB87392C2C2},  // 1e-75
12357         {0xB1C6F22B5E6F48C2, 0x90BD77F3483BB9B9},  // 1e-74
12358         {0x1E38AEB6360B1AF3, 0xB4ECD5F01A4AA828},  // 1e-73
12359         {0x25C6DA63C38DE1B0, 0xE2280B6C20DD5232},  // 1e-72
12360         {0x579C487E5A38AD0E, 0x8D590723948A535F},  // 1e-71
12361         {0x2D835A9DF0C6D851, 0xB0AF48EC79ACE837},  // 1e-70
12362         {0xF8E431456CF88E65, 0xDCDB1B2798182244},  // 1e-69
12363         {0x1B8E9ECB641B58FF, 0x8A08F0F8BF0F156B},  // 1e-68
12364         {0xE272467E3D222F3F, 0xAC8B2D36EED2DAC5},  // 1e-67
12365         {0x5B0ED81DCC6ABB0F, 0xD7ADF884AA879177},  // 1e-66
12366         {0x98E947129FC2B4E9, 0x86CCBB52EA94BAEA},  // 1e-65
12367         {0x3F2398D747B36224, 0xA87FEA27A539E9A5},  // 1e-64
12368         {0x8EEC7F0D19A03AAD, 0xD29FE4B18E88640E},  // 1e-63
12369         {0x1953CF68300424AC, 0x83A3EEEEF9153E89},  // 1e-62
12370         {0x5FA8C3423C052DD7, 0xA48CEAAAB75A8E2B},  // 1e-61
12371         {0x3792F412CB06794D, 0xCDB02555653131B6},  // 1e-60
12372         {0xE2BBD88BBEE40BD0, 0x808E17555F3EBF11},  // 1e-59
12373         {0x5B6ACEAEAE9D0EC4, 0xA0B19D2AB70E6ED6},  // 1e-58
12374         {0xF245825A5A445275, 0xC8DE047564D20A8B},  // 1e-57
12375         {0xEED6E2F0F0D56712, 0xFB158592BE068D2E},  // 1e-56
12376         {0x55464DD69685606B, 0x9CED737BB6C4183D},  // 1e-55
12377         {0xAA97E14C3C26B886, 0xC428D05AA4751E4C},  // 1e-54
12378         {0xD53DD99F4B3066A8, 0xF53304714D9265DF},  // 1e-53
12379         {0xE546A8038EFE4029, 0x993FE2C6D07B7FAB},  // 1e-52
12380         {0xDE98520472BDD033, 0xBF8FDB78849A5F96},  // 1e-51
12381         {0x963E66858F6D4440, 0xEF73D256A5C0F77C},  // 1e-50
12382         {0xDDE7001379A44AA8, 0x95A8637627989AAD},  // 1e-49
12383         {0x5560C018580D5D52, 0xBB127C53B17EC159},  // 1e-48
12384         {0xAAB8F01E6E10B4A6, 0xE9D71B689DDE71AF},  // 1e-47
12385         {0xCAB3961304CA70E8, 0x9226712162AB070D},  // 1e-46
12386         {0x3D607B97C5FD0D22, 0xB6B00D69BB55C8D1},  // 1e-45
12387         {0x8CB89A7DB77C506A, 0xE45C10C42A2B3B05},  // 1e-44
12388         {0x77F3608E92ADB242, 0x8EB98A7A9A5B04E3},  // 1e-43
12389         {0x55F038B237591ED3, 0xB267ED1940F1C61C},  // 1e-42
12390         {0x6B6C46DEC52F6688, 0xDF01E85F912E37A3},  // 1e-41
12391         {0x2323AC4B3B3DA015, 0x8B61313BBABCE2C6},  // 1e-40
12392         {0xABEC975E0A0D081A, 0xAE397D8AA96C1B77},  // 1e-39
12393         {0x96E7BD358C904A21, 0xD9C7DCED53C72255},  // 1e-38
12394         {0x7E50D64177DA2E54, 0x881CEA14545C7575},  // 1e-37
12395         {0xDDE50BD1D5D0B9E9, 0xAA242499697392D2},  // 1e-36
12396         {0x955E4EC64B44E864, 0xD4AD2DBFC3D07787},  // 1e-35
12397         {0xBD5AF13BEF0B113E, 0x84EC3C97DA624AB4},  // 1e-34
12398         {0xECB1AD8AEACDD58E, 0xA6274BBDD0FADD61},  // 1e-33
12399         {0x67DE18EDA5814AF2, 0xCFB11EAD453994BA},  // 1e-32
12400         {0x80EACF948770CED7, 0x81CEB32C4B43FCF4},  // 1e-31
12401         {0xA1258379A94D028D, 0xA2425FF75E14FC31},  // 1e-30
12402         {0x096EE45813A04330, 0xCAD2F7F5359A3B3E},  // 1e-29
12403         {0x8BCA9D6E188853FC, 0xFD87B5F28300CA0D},  // 1e-28
12404         {0x775EA264CF55347D, 0x9E74D1B791E07E48},  // 1e-27
12405         {0x95364AFE032A819D, 0xC612062576589DDA},  // 1e-26
12406         {0x3A83DDBD83F52204, 0xF79687AED3EEC551},  // 1e-25
12407         {0xC4926A9672793542, 0x9ABE14CD44753B52},  // 1e-24
12408         {0x75B7053C0F178293, 0xC16D9A0095928A27},  // 1e-23
12409         {0x5324C68B12DD6338, 0xF1C90080BAF72CB1},  // 1e-22
12410         {0xD3F6FC16EBCA5E03, 0x971DA05074DA7BEE},  // 1e-21
12411         {0x88F4BB1CA6BCF584, 0xBCE5086492111AEA},  // 1e-20
12412         {0x2B31E9E3D06C32E5, 0xEC1E4A7DB69561A5},  // 1e-19
12413         {0x3AFF322E62439FCF, 0x9392EE8E921D5D07},  // 1e-18
12414         {0x09BEFEB9FAD487C2, 0xB877AA3236A4B449},  // 1e-17
12415         {0x4C2EBE687989A9B3, 0xE69594BEC44DE15B},  // 1e-16
12416         {0x0F9D37014BF60A10, 0x901D7CF73AB0ACD9},  // 1e-15
12417         {0x538484C19EF38C94, 0xB424DC35095CD80F},  // 1e-14
12418         {0x2865A5F206B06FB9, 0xE12E13424BB40E13},  // 1e-13
12419         {0xF93F87B7442E45D3, 0x8CBCCC096F5088CB},  // 1e-12
12420         {0xF78F69A51539D748, 0xAFEBFF0BCB24AAFE},  // 1e-11
12421         {0xB573440E5A884D1B, 0xDBE6FECEBDEDD5BE},  // 1e-10
12422         {0x31680A88F8953030, 0x89705F4136B4A597},  // 1e-9
12423         {0xFDC20D2B36BA7C3D, 0xABCC77118461CEFC},  // 1e-8
12424         {0x3D32907604691B4C, 0xD6BF94D5E57A42BC},  // 1e-7
12425         {0xA63F9A49C2C1B10F, 0x8637BD05AF6C69B5},  // 1e-6
12426         {0x0FCF80DC33721D53, 0xA7C5AC471B478423},  // 1e-5
12427         {0xD3C36113404EA4A8, 0xD1B71758E219652B},  // 1e-4
12428         {0x645A1CAC083126E9, 0x83126E978D4FDF3B},  // 1e-3
12429         {0x3D70A3D70A3D70A3, 0xA3D70A3D70A3D70A},  // 1e-2
12430         {0xCCCCCCCCCCCCCCCC, 0xCCCCCCCCCCCCCCCC},  // 1e-1
12431         {0x0000000000000000, 0x8000000000000000},  // 1e0
12432         {0x0000000000000000, 0xA000000000000000},  // 1e1
12433         {0x0000000000000000, 0xC800000000000000},  // 1e2
12434         {0x0000000000000000, 0xFA00000000000000},  // 1e3
12435         {0x0000000000000000, 0x9C40000000000000},  // 1e4
12436         {0x0000000000000000, 0xC350000000000000},  // 1e5
12437         {0x0000000000000000, 0xF424000000000000},  // 1e6
12438         {0x0000000000000000, 0x9896800000000000},  // 1e7
12439         {0x0000000000000000, 0xBEBC200000000000},  // 1e8
12440         {0x0000000000000000, 0xEE6B280000000000},  // 1e9
12441         {0x0000000000000000, 0x9502F90000000000},  // 1e10
12442         {0x0000000000000000, 0xBA43B74000000000},  // 1e11
12443         {0x0000000000000000, 0xE8D4A51000000000},  // 1e12
12444         {0x0000000000000000, 0x9184E72A00000000},  // 1e13
12445         {0x0000000000000000, 0xB5E620F480000000},  // 1e14
12446         {0x0000000000000000, 0xE35FA931A0000000},  // 1e15
12447         {0x0000000000000000, 0x8E1BC9BF04000000},  // 1e16
12448         {0x0000000000000000, 0xB1A2BC2EC5000000},  // 1e17
12449         {0x0000000000000000, 0xDE0B6B3A76400000},  // 1e18
12450         {0x0000000000000000, 0x8AC7230489E80000},  // 1e19
12451         {0x0000000000000000, 0xAD78EBC5AC620000},  // 1e20
12452         {0x0000000000000000, 0xD8D726B7177A8000},  // 1e21
12453         {0x0000000000000000, 0x878678326EAC9000},  // 1e22
12454         {0x0000000000000000, 0xA968163F0A57B400},  // 1e23
12455         {0x0000000000000000, 0xD3C21BCECCEDA100},  // 1e24
12456         {0x0000000000000000, 0x84595161401484A0},  // 1e25
12457         {0x0000000000000000, 0xA56FA5B99019A5C8},  // 1e26
12458         {0x0000000000000000, 0xCECB8F27F4200F3A},  // 1e27
12459         {0x4000000000000000, 0x813F3978F8940984},  // 1e28
12460         {0x5000000000000000, 0xA18F07D736B90BE5},  // 1e29
12461         {0xA400000000000000, 0xC9F2C9CD04674EDE},  // 1e30
12462         {0x4D00000000000000, 0xFC6F7C4045812296},  // 1e31
12463         {0xF020000000000000, 0x9DC5ADA82B70B59D},  // 1e32
12464         {0x6C28000000000000, 0xC5371912364CE305},  // 1e33
12465         {0xC732000000000000, 0xF684DF56C3E01BC6},  // 1e34
12466         {0x3C7F400000000000, 0x9A130B963A6C115C},  // 1e35
12467         {0x4B9F100000000000, 0xC097CE7BC90715B3},  // 1e36
12468         {0x1E86D40000000000, 0xF0BDC21ABB48DB20},  // 1e37
12469         {0x1314448000000000, 0x96769950B50D88F4},  // 1e38
12470         {0x17D955A000000000, 0xBC143FA4E250EB31},  // 1e39
12471         {0x5DCFAB0800000000, 0xEB194F8E1AE525FD},  // 1e40
12472         {0x5AA1CAE500000000, 0x92EFD1B8D0CF37BE},  // 1e41
12473         {0xF14A3D9E40000000, 0xB7ABC627050305AD},  // 1e42
12474         {0x6D9CCD05D0000000, 0xE596B7B0C643C719},  // 1e43
12475         {0xE4820023A2000000, 0x8F7E32CE7BEA5C6F},  // 1e44
12476         {0xDDA2802C8A800000, 0xB35DBF821AE4F38B},  // 1e45
12477         {0xD50B2037AD200000, 0xE0352F62A19E306E},  // 1e46
12478         {0x4526F422CC340000, 0x8C213D9DA502DE45},  // 1e47
12479         {0x9670B12B7F410000, 0xAF298D050E4395D6},  // 1e48
12480         {0x3C0CDD765F114000, 0xDAF3F04651D47B4C},  // 1e49
12481         {0xA5880A69FB6AC800, 0x88D8762BF324CD0F},  // 1e50
12482         {0x8EEA0D047A457A00, 0xAB0E93B6EFEE0053},  // 1e51
12483         {0x72A4904598D6D880, 0xD5D238A4ABE98068},  // 1e52
12484         {0x47A6DA2B7F864750, 0x85A36366EB71F041},  // 1e53
12485         {0x999090B65F67D924, 0xA70C3C40A64E6C51},  // 1e54
12486         {0xFFF4B4E3F741CF6D, 0xD0CF4B50CFE20765},  // 1e55
12487         {0xBFF8F10E7A8921A4, 0x82818F1281ED449F},  // 1e56
12488         {0xAFF72D52192B6A0D, 0xA321F2D7226895C7},  // 1e57
12489         {0x9BF4F8A69F764490, 0xCBEA6F8CEB02BB39},  // 1e58
12490         {0x02F236D04753D5B4, 0xFEE50B7025C36A08},  // 1e59
12491         {0x01D762422C946590, 0x9F4F2726179A2245},  // 1e60
12492         {0x424D3AD2B7B97EF5, 0xC722F0EF9D80AAD6},  // 1e61
12493         {0xD2E0898765A7DEB2, 0xF8EBAD2B84E0D58B},  // 1e62
12494         {0x63CC55F49F88EB2F, 0x9B934C3B330C8577},  // 1e63
12495         {0x3CBF6B71C76B25FB, 0xC2781F49FFCFA6D5},  // 1e64
12496         {0x8BEF464E3945EF7A, 0xF316271C7FC3908A},  // 1e65
12497         {0x97758BF0E3CBB5AC, 0x97EDD871CFDA3A56},  // 1e66
12498         {0x3D52EEED1CBEA317, 0xBDE94E8E43D0C8EC},  // 1e67
12499         {0x4CA7AAA863EE4BDD, 0xED63A231D4C4FB27},  // 1e68
12500         {0x8FE8CAA93E74EF6A, 0x945E455F24FB1CF8},  // 1e69
12501         {0xB3E2FD538E122B44, 0xB975D6B6EE39E436},  // 1e70
12502         {0x60DBBCA87196B616, 0xE7D34C64A9C85D44},  // 1e71
12503         {0xBC8955E946FE31CD, 0x90E40FBEEA1D3A4A},  // 1e72
12504         {0x6BABAB6398BDBE41, 0xB51D13AEA4A488DD},  // 1e73
12505         {0xC696963C7EED2DD1, 0xE264589A4DCDAB14},  // 1e74
12506         {0xFC1E1DE5CF543CA2, 0x8D7EB76070A08AEC},  // 1e75
12507         {0x3B25A55F43294BCB, 0xB0DE65388CC8ADA8},  // 1e76
12508         {0x49EF0EB713F39EBE, 0xDD15FE86AFFAD912},  // 1e77
12509         {0x6E3569326C784337, 0x8A2DBF142DFCC7AB},  // 1e78
12510         {0x49C2C37F07965404, 0xACB92ED9397BF996},  // 1e79
12511         {0xDC33745EC97BE906, 0xD7E77A8F87DAF7FB},  // 1e80
12512         {0x69A028BB3DED71A3, 0x86F0AC99B4E8DAFD},  // 1e81
12513         {0xC40832EA0D68CE0C, 0xA8ACD7C0222311BC},  // 1e82
12514         {0xF50A3FA490C30190, 0xD2D80DB02AABD62B},  // 1e83
12515         {0x792667C6DA79E0FA, 0x83C7088E1AAB65DB},  // 1e84
12516         {0x577001B891185938, 0xA4B8CAB1A1563F52},  // 1e85
12517         {0xED4C0226B55E6F86, 0xCDE6FD5E09ABCF26},  // 1e86
12518         {0x544F8158315B05B4, 0x80B05E5AC60B6178},  // 1e87
12519         {0x696361AE3DB1C721, 0xA0DC75F1778E39D6},  // 1e88
12520         {0x03BC3A19CD1E38E9, 0xC913936DD571C84C},  // 1e89
12521         {0x04AB48A04065C723, 0xFB5878494ACE3A5F},  // 1e90
12522         {0x62EB0D64283F9C76, 0x9D174B2DCEC0E47B},  // 1e91
12523         {0x3BA5D0BD324F8394, 0xC45D1DF942711D9A},  // 1e92
12524         {0xCA8F44EC7EE36479, 0xF5746577930D6500},  // 1e93
12525         {0x7E998B13CF4E1ECB, 0x9968BF6ABBE85F20},  // 1e94
12526         {0x9E3FEDD8C321A67E, 0xBFC2EF456AE276E8},  // 1e95
12527         {0xC5CFE94EF3EA101E, 0xEFB3AB16C59B14A2},  // 1e96
12528         {0xBBA1F1D158724A12, 0x95D04AEE3B80ECE5},  // 1e97
12529         {0x2A8A6E45AE8EDC97, 0xBB445DA9CA61281F},  // 1e98
12530         {0xF52D09D71A3293BD, 0xEA1575143CF97226},  // 1e99
12531         {0x593C2626705F9C56, 0x924D692CA61BE758},  // 1e100
12532         {0x6F8B2FB00C77836C, 0xB6E0C377CFA2E12E},  // 1e101
12533         {0x0B6DFB9C0F956447, 0xE498F455C38B997A},  // 1e102
12534         {0x4724BD4189BD5EAC, 0x8EDF98B59A373FEC},  // 1e103
12535         {0x58EDEC91EC2CB657, 0xB2977EE300C50FE7},  // 1e104
12536         {0x2F2967B66737E3ED, 0xDF3D5E9BC0F653E1},  // 1e105
12537         {0xBD79E0D20082EE74, 0x8B865B215899F46C},  // 1e106
12538         {0xECD8590680A3AA11, 0xAE67F1E9AEC07187},  // 1e107
12539         {0xE80E6F4820CC9495, 0xDA01EE641A708DE9},  // 1e108
12540         {0x3109058D147FDCDD, 0x884134FE908658B2},  // 1e109
12541         {0xBD4B46F0599FD415, 0xAA51823E34A7EEDE},  // 1e110
12542         {0x6C9E18AC7007C91A, 0xD4E5E2CDC1D1EA96},  // 1e111
12543         {0x03E2CF6BC604DDB0, 0x850FADC09923329E},  // 1e112
12544         {0x84DB8346B786151C, 0xA6539930BF6BFF45},  // 1e113
12545         {0xE612641865679A63, 0xCFE87F7CEF46FF16},  // 1e114
12546         {0x4FCB7E8F3F60C07E, 0x81F14FAE158C5F6E},  // 1e115
12547         {0xE3BE5E330F38F09D, 0xA26DA3999AEF7749},  // 1e116
12548         {0x5CADF5BFD3072CC5, 0xCB090C8001AB551C},  // 1e117
12549         {0x73D9732FC7C8F7F6, 0xFDCB4FA002162A63},  // 1e118
12550         {0x2867E7FDDCDD9AFA, 0x9E9F11C4014DDA7E},  // 1e119
12551         {0xB281E1FD541501B8, 0xC646D63501A1511D},  // 1e120
12552         {0x1F225A7CA91A4226, 0xF7D88BC24209A565},  // 1e121
12553         {0x3375788DE9B06958, 0x9AE757596946075F},  // 1e122
12554         {0x0052D6B1641C83AE, 0xC1A12D2FC3978937},  // 1e123
12555         {0xC0678C5DBD23A49A, 0xF209787BB47D6B84},  // 1e124
12556         {0xF840B7BA963646E0, 0x9745EB4D50CE6332},  // 1e125
12557         {0xB650E5A93BC3D898, 0xBD176620A501FBFF},  // 1e126
12558         {0xA3E51F138AB4CEBE, 0xEC5D3FA8CE427AFF},  // 1e127
12559         {0xC66F336C36B10137, 0x93BA47C980E98CDF},  // 1e128
12560         {0xB80B0047445D4184, 0xB8A8D9BBE123F017},  // 1e129
12561         {0xA60DC059157491E5, 0xE6D3102AD96CEC1D},  // 1e130
12562         {0x87C89837AD68DB2F, 0x9043EA1AC7E41392},  // 1e131
12563         {0x29BABE4598C311FB, 0xB454E4A179DD1877},  // 1e132
12564         {0xF4296DD6FEF3D67A, 0xE16A1DC9D8545E94},  // 1e133
12565         {0x1899E4A65F58660C, 0x8CE2529E2734BB1D},  // 1e134
12566         {0x5EC05DCFF72E7F8F, 0xB01AE745B101E9E4},  // 1e135
12567         {0x76707543F4FA1F73, 0xDC21A1171D42645D},  // 1e136
12568         {0x6A06494A791C53A8, 0x899504AE72497EBA},  // 1e137
12569         {0x0487DB9D17636892, 0xABFA45DA0EDBDE69},  // 1e138
12570         {0x45A9D2845D3C42B6, 0xD6F8D7509292D603},  // 1e139
12571         {0x0B8A2392BA45A9B2, 0x865B86925B9BC5C2},  // 1e140
12572         {0x8E6CAC7768D7141E, 0xA7F26836F282B732},  // 1e141
12573         {0x3207D795430CD926, 0xD1EF0244AF2364FF},  // 1e142
12574         {0x7F44E6BD49E807B8, 0x8335616AED761F1F},  // 1e143
12575         {0x5F16206C9C6209A6, 0xA402B9C5A8D3A6E7},  // 1e144
12576         {0x36DBA887C37A8C0F, 0xCD036837130890A1},  // 1e145
12577         {0xC2494954DA2C9789, 0x802221226BE55A64},  // 1e146
12578         {0xF2DB9BAA10B7BD6C, 0xA02AA96B06DEB0FD},  // 1e147
12579         {0x6F92829494E5ACC7, 0xC83553C5C8965D3D},  // 1e148
12580         {0xCB772339BA1F17F9, 0xFA42A8B73ABBF48C},  // 1e149
12581         {0xFF2A760414536EFB, 0x9C69A97284B578D7},  // 1e150
12582         {0xFEF5138519684ABA, 0xC38413CF25E2D70D},  // 1e151
12583         {0x7EB258665FC25D69, 0xF46518C2EF5B8CD1},  // 1e152
12584         {0xEF2F773FFBD97A61, 0x98BF2F79D5993802},  // 1e153
12585         {0xAAFB550FFACFD8FA, 0xBEEEFB584AFF8603},  // 1e154
12586         {0x95BA2A53F983CF38, 0xEEAABA2E5DBF6784},  // 1e155
12587         {0xDD945A747BF26183, 0x952AB45CFA97A0B2},  // 1e156
12588         {0x94F971119AEEF9E4, 0xBA756174393D88DF},  // 1e157
12589         {0x7A37CD5601AAB85D, 0xE912B9D1478CEB17},  // 1e158
12590         {0xAC62E055C10AB33A, 0x91ABB422CCB812EE},  // 1e159
12591         {0x577B986B314D6009, 0xB616A12B7FE617AA},  // 1e160
12592         {0xED5A7E85FDA0B80B, 0xE39C49765FDF9D94},  // 1e161
12593         {0x14588F13BE847307, 0x8E41ADE9FBEBC27D},  // 1e162
12594         {0x596EB2D8AE258FC8, 0xB1D219647AE6B31C},  // 1e163
12595         {0x6FCA5F8ED9AEF3BB, 0xDE469FBD99A05FE3},  // 1e164
12596         {0x25DE7BB9480D5854, 0x8AEC23D680043BEE},  // 1e165
12597         {0xAF561AA79A10AE6A, 0xADA72CCC20054AE9},  // 1e166
12598         {0x1B2BA1518094DA04, 0xD910F7FF28069DA4},  // 1e167
12599         {0x90FB44D2F05D0842, 0x87AA9AFF79042286},  // 1e168
12600         {0x353A1607AC744A53, 0xA99541BF57452B28},  // 1e169
12601         {0x42889B8997915CE8, 0xD3FA922F2D1675F2},  // 1e170
12602         {0x69956135FEBADA11, 0x847C9B5D7C2E09B7},  // 1e171
12603         {0x43FAB9837E699095, 0xA59BC234DB398C25},  // 1e172
12604         {0x94F967E45E03F4BB, 0xCF02B2C21207EF2E},  // 1e173
12605         {0x1D1BE0EEBAC278F5, 0x8161AFB94B44F57D},  // 1e174
12606         {0x6462D92A69731732, 0xA1BA1BA79E1632DC},  // 1e175
12607         {0x7D7B8F7503CFDCFE, 0xCA28A291859BBF93},  // 1e176
12608         {0x5CDA735244C3D43E, 0xFCB2CB35E702AF78},  // 1e177
12609         {0x3A0888136AFA64A7, 0x9DEFBF01B061ADAB},  // 1e178
12610         {0x088AAA1845B8FDD0, 0xC56BAEC21C7A1916},  // 1e179
12611         {0x8AAD549E57273D45, 0xF6C69A72A3989F5B},  // 1e180
12612         {0x36AC54E2F678864B, 0x9A3C2087A63F6399},  // 1e181
12613         {0x84576A1BB416A7DD, 0xC0CB28A98FCF3C7F},  // 1e182
12614         {0x656D44A2A11C51D5, 0xF0FDF2D3F3C30B9F},  // 1e183
12615         {0x9F644AE5A4B1B325, 0x969EB7C47859E743},  // 1e184
12616         {0x873D5D9F0DDE1FEE, 0xBC4665B596706114},  // 1e185
12617         {0xA90CB506D155A7EA, 0xEB57FF22FC0C7959},  // 1e186
12618         {0x09A7F12442D588F2, 0x9316FF75DD87CBD8},  // 1e187
12619         {0x0C11ED6D538AEB2F, 0xB7DCBF5354E9BECE},  // 1e188
12620         {0x8F1668C8A86DA5FA, 0xE5D3EF282A242E81},  // 1e189
12621         {0xF96E017D694487BC, 0x8FA475791A569D10},  // 1e190
12622         {0x37C981DCC395A9AC, 0xB38D92D760EC4455},  // 1e191
12623         {0x85BBE253F47B1417, 0xE070F78D3927556A},  // 1e192
12624         {0x93956D7478CCEC8E, 0x8C469AB843B89562},  // 1e193
12625         {0x387AC8D1970027B2, 0xAF58416654A6BABB},  // 1e194
12626         {0x06997B05FCC0319E, 0xDB2E51BFE9D0696A},  // 1e195
12627         {0x441FECE3BDF81F03, 0x88FCF317F22241E2},  // 1e196
12628         {0xD527E81CAD7626C3, 0xAB3C2FDDEEAAD25A},  // 1e197
12629         {0x8A71E223D8D3B074, 0xD60B3BD56A5586F1},  // 1e198
12630         {0xF6872D5667844E49, 0x85C7056562757456},  // 1e199
12631         {0xB428F8AC016561DB, 0xA738C6BEBB12D16C},  // 1e200
12632         {0xE13336D701BEBA52, 0xD106F86E69D785C7},  // 1e201
12633         {0xECC0024661173473, 0x82A45B450226B39C},  // 1e202
12634         {0x27F002D7F95D0190, 0xA34D721642B06084},  // 1e203
12635         {0x31EC038DF7B441F4, 0xCC20CE9BD35C78A5},  // 1e204
12636         {0x7E67047175A15271, 0xFF290242C83396CE},  // 1e205
12637         {0x0F0062C6E984D386, 0x9F79A169BD203E41},  // 1e206
12638         {0x52C07B78A3E60868, 0xC75809C42C684DD1},  // 1e207
12639         {0xA7709A56CCDF8A82, 0xF92E0C3537826145},  // 1e208
12640         {0x88A66076400BB691, 0x9BBCC7A142B17CCB},  // 1e209
12641         {0x6ACFF893D00EA435, 0xC2ABF989935DDBFE},  // 1e210
12642         {0x0583F6B8C4124D43, 0xF356F7EBF83552FE},  // 1e211
12643         {0xC3727A337A8B704A, 0x98165AF37B2153DE},  // 1e212
12644         {0x744F18C0592E4C5C, 0xBE1BF1B059E9A8D6},  // 1e213
12645         {0x1162DEF06F79DF73, 0xEDA2EE1C7064130C},  // 1e214
12646         {0x8ADDCB5645AC2BA8, 0x9485D4D1C63E8BE7},  // 1e215
12647         {0x6D953E2BD7173692, 0xB9A74A0637CE2EE1},  // 1e216
12648         {0xC8FA8DB6CCDD0437, 0xE8111C87C5C1BA99},  // 1e217
12649         {0x1D9C9892400A22A2, 0x910AB1D4DB9914A0},  // 1e218
12650         {0x2503BEB6D00CAB4B, 0xB54D5E4A127F59C8},  // 1e219
12651         {0x2E44AE64840FD61D, 0xE2A0B5DC971F303A},  // 1e220
12652         {0x5CEAECFED289E5D2, 0x8DA471A9DE737E24},  // 1e221
12653         {0x7425A83E872C5F47, 0xB10D8E1456105DAD},  // 1e222
12654         {0xD12F124E28F77719, 0xDD50F1996B947518},  // 1e223
12655         {0x82BD6B70D99AAA6F, 0x8A5296FFE33CC92F},  // 1e224
12656         {0x636CC64D1001550B, 0xACE73CBFDC0BFB7B},  // 1e225
12657         {0x3C47F7E05401AA4E, 0xD8210BEFD30EFA5A},  // 1e226
12658         {0x65ACFAEC34810A71, 0x8714A775E3E95C78},  // 1e227
12659         {0x7F1839A741A14D0D, 0xA8D9D1535CE3B396},  // 1e228
12660         {0x1EDE48111209A050, 0xD31045A8341CA07C},  // 1e229
12661         {0x934AED0AAB460432, 0x83EA2B892091E44D},  // 1e230
12662         {0xF81DA84D5617853F, 0xA4E4B66B68B65D60},  // 1e231
12663         {0x36251260AB9D668E, 0xCE1DE40642E3F4B9},  // 1e232
12664         {0xC1D72B7C6B426019, 0x80D2AE83E9CE78F3},  // 1e233
12665         {0xB24CF65B8612F81F, 0xA1075A24E4421730},  // 1e234
12666         {0xDEE033F26797B627, 0xC94930AE1D529CFC},  // 1e235
12667         {0x169840EF017DA3B1, 0xFB9B7CD9A4A7443C},  // 1e236
12668         {0x8E1F289560EE864E, 0x9D412E0806E88AA5},  // 1e237
12669         {0xF1A6F2BAB92A27E2, 0xC491798A08A2AD4E},  // 1e238
12670         {0xAE10AF696774B1DB, 0xF5B5D7EC8ACB58A2},  // 1e239
12671         {0xACCA6DA1E0A8EF29, 0x9991A6F3D6BF1765},  // 1e240
12672         {0x17FD090A58D32AF3, 0xBFF610B0CC6EDD3F},  // 1e241
12673         {0xDDFC4B4CEF07F5B0, 0xEFF394DCFF8A948E},  // 1e242
12674         {0x4ABDAF101564F98E, 0x95F83D0A1FB69CD9},  // 1e243
12675         {0x9D6D1AD41ABE37F1, 0xBB764C4CA7A4440F},  // 1e244
12676         {0x84C86189216DC5ED, 0xEA53DF5FD18D5513},  // 1e245
12677         {0x32FD3CF5B4E49BB4, 0x92746B9BE2F8552C},  // 1e246
12678         {0x3FBC8C33221DC2A1, 0xB7118682DBB66A77},  // 1e247
12679         {0x0FABAF3FEAA5334A, 0xE4D5E82392A40515},  // 1e248
12680         {0x29CB4D87F2A7400E, 0x8F05B1163BA6832D},  // 1e249
12681         {0x743E20E9EF511012, 0xB2C71D5BCA9023F8},  // 1e250
12682         {0x914DA9246B255416, 0xDF78E4B2BD342CF6},  // 1e251
12683         {0x1AD089B6C2F7548E, 0x8BAB8EEFB6409C1A},  // 1e252
12684         {0xA184AC2473B529B1, 0xAE9672ABA3D0C320},  // 1e253
12685         {0xC9E5D72D90A2741E, 0xDA3C0F568CC4F3E8},  // 1e254
12686         {0x7E2FA67C7A658892, 0x8865899617FB1871},  // 1e255
12687         {0xDDBB901B98FEEAB7, 0xAA7EEBFB9DF9DE8D},  // 1e256
12688         {0x552A74227F3EA565, 0xD51EA6FA85785631},  // 1e257
12689         {0xD53A88958F87275F, 0x8533285C936B35DE},  // 1e258
12690         {0x8A892ABAF368F137, 0xA67FF273B8460356},  // 1e259
12691         {0x2D2B7569B0432D85, 0xD01FEF10A657842C},  // 1e260
12692         {0x9C3B29620E29FC73, 0x8213F56A67F6B29B},  // 1e261
12693         {0x8349F3BA91B47B8F, 0xA298F2C501F45F42},  // 1e262
12694         {0x241C70A936219A73, 0xCB3F2F7642717713},  // 1e263
12695         {0xED238CD383AA0110, 0xFE0EFB53D30DD4D7},  // 1e264
12696         {0xF4363804324A40AA, 0x9EC95D1463E8A506},  // 1e265
12697         {0xB143C6053EDCD0D5, 0xC67BB4597CE2CE48},  // 1e266
12698         {0xDD94B7868E94050A, 0xF81AA16FDC1B81DA},  // 1e267
12699         {0xCA7CF2B4191C8326, 0x9B10A4E5E9913128},  // 1e268
12700         {0xFD1C2F611F63A3F0, 0xC1D4CE1F63F57D72},  // 1e269
12701         {0xBC633B39673C8CEC, 0xF24A01A73CF2DCCF},  // 1e270
12702         {0xD5BE0503E085D813, 0x976E41088617CA01},  // 1e271
12703         {0x4B2D8644D8A74E18, 0xBD49D14AA79DBC82},  // 1e272
12704         {0xDDF8E7D60ED1219E, 0xEC9C459D51852BA2},  // 1e273
12705         {0xCABB90E5C942B503, 0x93E1AB8252F33B45},  // 1e274
12706         {0x3D6A751F3B936243, 0xB8DA1662E7B00A17},  // 1e275
12707         {0x0CC512670A783AD4, 0xE7109BFBA19C0C9D},  // 1e276
12708         {0x27FB2B80668B24C5, 0x906A617D450187E2},  // 1e277
12709         {0xB1F9F660802DEDF6, 0xB484F9DC9641E9DA},  // 1e278
12710         {0x5E7873F8A0396973, 0xE1A63853BBD26451},  // 1e279
12711         {0xDB0B487B6423E1E8, 0x8D07E33455637EB2},  // 1e280
12712         {0x91CE1A9A3D2CDA62, 0xB049DC016ABC5E5F},  // 1e281
12713         {0x7641A140CC7810FB, 0xDC5C5301C56B75F7},  // 1e282
12714         {0xA9E904C87FCB0A9D, 0x89B9B3E11B6329BA},  // 1e283
12715         {0x546345FA9FBDCD44, 0xAC2820D9623BF429},  // 1e284
12716         {0xA97C177947AD4095, 0xD732290FBACAF133},  // 1e285
12717         {0x49ED8EABCCCC485D, 0x867F59A9D4BED6C0},  // 1e286
12718         {0x5C68F256BFFF5A74, 0xA81F301449EE8C70},  // 1e287
12719         {0x73832EEC6FFF3111, 0xD226FC195C6A2F8C},  // 1e288
12720 };
12721 
12722 // wuffs_base__private_implementation__f64_powers_of_10 holds powers of 10 that
12723 // can be exactly represented by a float64 (what C calls a double).
12724 static const double wuffs_base__private_implementation__f64_powers_of_10[23] = {
12725     1e0,  1e1,  1e2,  1e3,  1e4,  1e5,  1e6,  1e7,  1e8,  1e9,  1e10, 1e11,
12726     1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22,
12727 };
12728 
12729 // ---------------- IEEE 754 Floating Point
12730 
12731 WUFFS_BASE__MAYBE_STATIC wuffs_base__lossy_value_u16  //
wuffs_base__ieee_754_bit_representation__from_f64_to_u16_truncate(double f)12732 wuffs_base__ieee_754_bit_representation__from_f64_to_u16_truncate(double f) {
12733   uint64_t u = 0;
12734   if (sizeof(uint64_t) == sizeof(double)) {
12735     memcpy(&u, &f, sizeof(uint64_t));
12736   }
12737   uint16_t neg = ((uint16_t)((u >> 63) << 15));
12738   u &= 0x7FFFFFFFFFFFFFFF;
12739   uint64_t exp = u >> 52;
12740   uint64_t man = u & 0x000FFFFFFFFFFFFF;
12741 
12742   if (exp == 0x7FF) {
12743     if (man == 0) {  // Infinity.
12744       wuffs_base__lossy_value_u16 ret;
12745       ret.value = neg | 0x7C00;
12746       ret.lossy = false;
12747       return ret;
12748     }
12749     // NaN. Shift the 52 mantissa bits to 10 mantissa bits, keeping the most
12750     // significant mantissa bit (quiet vs signaling NaNs). Also set the low 9
12751     // bits of ret.value so that the 10-bit mantissa is non-zero.
12752     wuffs_base__lossy_value_u16 ret;
12753     ret.value = neg | 0x7DFF | ((uint16_t)(man >> 42));
12754     ret.lossy = false;
12755     return ret;
12756 
12757   } else if (exp > 0x40E) {  // Truncate to the largest finite f16.
12758     wuffs_base__lossy_value_u16 ret;
12759     ret.value = neg | 0x7BFF;
12760     ret.lossy = true;
12761     return ret;
12762 
12763   } else if (exp <= 0x3E6) {  // Truncate to zero.
12764     wuffs_base__lossy_value_u16 ret;
12765     ret.value = neg;
12766     ret.lossy = (u != 0);
12767     return ret;
12768 
12769   } else if (exp <= 0x3F0) {  // Normal f64, subnormal f16.
12770     // Convert from a 53-bit mantissa (after realizing the implicit bit) to a
12771     // 10-bit mantissa and then adjust for the exponent.
12772     man |= 0x0010000000000000;
12773     uint32_t shift = ((uint32_t)(1051 - exp));  // 1051 = 0x3F0 + 53 - 10.
12774     uint64_t shifted_man = man >> shift;
12775     wuffs_base__lossy_value_u16 ret;
12776     ret.value = neg | ((uint16_t)shifted_man);
12777     ret.lossy = (shifted_man << shift) != man;
12778     return ret;
12779   }
12780 
12781   // Normal f64, normal f16.
12782 
12783   // Re-bias from 1023 to 15 and shift above f16's 10 mantissa bits.
12784   exp = (exp - 1008) << 10;  // 1008 = 1023 - 15 = 0x3FF - 0xF.
12785 
12786   // Convert from a 52-bit mantissa (excluding the implicit bit) to a 10-bit
12787   // mantissa (again excluding the implicit bit). We lose some information if
12788   // any of the bottom 42 bits are non-zero.
12789   wuffs_base__lossy_value_u16 ret;
12790   ret.value = neg | ((uint16_t)exp) | ((uint16_t)(man >> 42));
12791   ret.lossy = (man << 22) != 0;
12792   return ret;
12793 }
12794 
12795 WUFFS_BASE__MAYBE_STATIC wuffs_base__lossy_value_u32  //
wuffs_base__ieee_754_bit_representation__from_f64_to_u32_truncate(double f)12796 wuffs_base__ieee_754_bit_representation__from_f64_to_u32_truncate(double f) {
12797   uint64_t u = 0;
12798   if (sizeof(uint64_t) == sizeof(double)) {
12799     memcpy(&u, &f, sizeof(uint64_t));
12800   }
12801   uint32_t neg = ((uint32_t)(u >> 63)) << 31;
12802   u &= 0x7FFFFFFFFFFFFFFF;
12803   uint64_t exp = u >> 52;
12804   uint64_t man = u & 0x000FFFFFFFFFFFFF;
12805 
12806   if (exp == 0x7FF) {
12807     if (man == 0) {  // Infinity.
12808       wuffs_base__lossy_value_u32 ret;
12809       ret.value = neg | 0x7F800000;
12810       ret.lossy = false;
12811       return ret;
12812     }
12813     // NaN. Shift the 52 mantissa bits to 23 mantissa bits, keeping the most
12814     // significant mantissa bit (quiet vs signaling NaNs). Also set the low 22
12815     // bits of ret.value so that the 23-bit mantissa is non-zero.
12816     wuffs_base__lossy_value_u32 ret;
12817     ret.value = neg | 0x7FBFFFFF | ((uint32_t)(man >> 29));
12818     ret.lossy = false;
12819     return ret;
12820 
12821   } else if (exp > 0x47E) {  // Truncate to the largest finite f32.
12822     wuffs_base__lossy_value_u32 ret;
12823     ret.value = neg | 0x7F7FFFFF;
12824     ret.lossy = true;
12825     return ret;
12826 
12827   } else if (exp <= 0x369) {  // Truncate to zero.
12828     wuffs_base__lossy_value_u32 ret;
12829     ret.value = neg;
12830     ret.lossy = (u != 0);
12831     return ret;
12832 
12833   } else if (exp <= 0x380) {  // Normal f64, subnormal f32.
12834     // Convert from a 53-bit mantissa (after realizing the implicit bit) to a
12835     // 23-bit mantissa and then adjust for the exponent.
12836     man |= 0x0010000000000000;
12837     uint32_t shift = ((uint32_t)(926 - exp));  // 926 = 0x380 + 53 - 23.
12838     uint64_t shifted_man = man >> shift;
12839     wuffs_base__lossy_value_u32 ret;
12840     ret.value = neg | ((uint32_t)shifted_man);
12841     ret.lossy = (shifted_man << shift) != man;
12842     return ret;
12843   }
12844 
12845   // Normal f64, normal f32.
12846 
12847   // Re-bias from 1023 to 127 and shift above f32's 23 mantissa bits.
12848   exp = (exp - 896) << 23;  // 896 = 1023 - 127 = 0x3FF - 0x7F.
12849 
12850   // Convert from a 52-bit mantissa (excluding the implicit bit) to a 23-bit
12851   // mantissa (again excluding the implicit bit). We lose some information if
12852   // any of the bottom 29 bits are non-zero.
12853   wuffs_base__lossy_value_u32 ret;
12854   ret.value = neg | ((uint32_t)exp) | ((uint32_t)(man >> 29));
12855   ret.lossy = (man << 35) != 0;
12856   return ret;
12857 }
12858 
12859 // --------
12860 
12861 #define WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE 2047
12862 #define WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION 800
12863 
12864 // WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL is the largest N
12865 // such that ((10 << N) < (1 << 64)).
12866 #define WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL 60
12867 
12868 // wuffs_base__private_implementation__high_prec_dec (abbreviated as HPD) is a
12869 // fixed precision floating point decimal number, augmented with ±infinity
12870 // values, but it cannot represent NaN (Not a Number).
12871 //
12872 // "High precision" means that the mantissa holds 800 decimal digits. 800 is
12873 // WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION.
12874 //
12875 // An HPD isn't for general purpose arithmetic, only for conversions to and
12876 // from IEEE 754 double-precision floating point, where the largest and
12877 // smallest positive, finite values are approximately 1.8e+308 and 4.9e-324.
12878 // HPD exponents above +2047 mean infinity, below -2047 mean zero. The ±2047
12879 // bounds are further away from zero than ±(324 + 800), where 800 and 2047 is
12880 // WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION and
12881 // WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE.
12882 //
12883 // digits[.. num_digits] are the number's digits in big-endian order. The
12884 // uint8_t values are in the range [0 ..= 9], not ['0' ..= '9'], where e.g. '7'
12885 // is the ASCII value 0x37.
12886 //
12887 // decimal_point is the index (within digits) of the decimal point. It may be
12888 // negative or be larger than num_digits, in which case the explicit digits are
12889 // padded with implicit zeroes.
12890 //
12891 // For example, if num_digits is 3 and digits is "\x07\x08\x09":
12892 //  - A decimal_point of -2 means ".00789"
12893 //  - A decimal_point of -1 means ".0789"
12894 //  - A decimal_point of +0 means ".789"
12895 //  - A decimal_point of +1 means "7.89"
12896 //  - A decimal_point of +2 means "78.9"
12897 //  - A decimal_point of +3 means "789."
12898 //  - A decimal_point of +4 means "7890."
12899 //  - A decimal_point of +5 means "78900."
12900 //
12901 // As above, a decimal_point higher than +2047 means that the overall value is
12902 // infinity, lower than -2047 means zero.
12903 //
12904 // negative is a sign bit. An HPD can distinguish positive and negative zero.
12905 //
12906 // truncated is whether there are more than
12907 // WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION digits, and at
12908 // least one of those extra digits are non-zero. The existence of long-tail
12909 // digits can affect rounding.
12910 //
12911 // The "all fields are zero" value is valid, and represents the number +0.
12912 typedef struct wuffs_base__private_implementation__high_prec_dec__struct {
12913   uint32_t num_digits;
12914   int32_t decimal_point;
12915   bool negative;
12916   bool truncated;
12917   uint8_t digits[WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION];
12918 } wuffs_base__private_implementation__high_prec_dec;
12919 
12920 // wuffs_base__private_implementation__high_prec_dec__trim trims trailing
12921 // zeroes from the h->digits[.. h->num_digits] slice. They have no benefit,
12922 // since we explicitly track h->decimal_point.
12923 //
12924 // Preconditions:
12925 //  - h is non-NULL.
12926 static inline void  //
wuffs_base__private_implementation__high_prec_dec__trim(wuffs_base__private_implementation__high_prec_dec * h)12927 wuffs_base__private_implementation__high_prec_dec__trim(
12928     wuffs_base__private_implementation__high_prec_dec* h) {
12929   while ((h->num_digits > 0) && (h->digits[h->num_digits - 1] == 0)) {
12930     h->num_digits--;
12931   }
12932 }
12933 
12934 // wuffs_base__private_implementation__high_prec_dec__assign sets h to
12935 // represent the number x.
12936 //
12937 // Preconditions:
12938 //  - h is non-NULL.
12939 static void  //
wuffs_base__private_implementation__high_prec_dec__assign(wuffs_base__private_implementation__high_prec_dec * h,uint64_t x,bool negative)12940 wuffs_base__private_implementation__high_prec_dec__assign(
12941     wuffs_base__private_implementation__high_prec_dec* h,
12942     uint64_t x,
12943     bool negative) {
12944   uint32_t n = 0;
12945 
12946   // Set h->digits.
12947   if (x > 0) {
12948     // Calculate the digits, working right-to-left. After we determine n (how
12949     // many digits there are), copy from buf to h->digits.
12950     //
12951     // UINT64_MAX, 18446744073709551615, is 20 digits long. It can be faster to
12952     // copy a constant number of bytes than a variable number (20 instead of
12953     // n). Make buf large enough (and start writing to it from the middle) so
12954     // that can we always copy 20 bytes: the slice buf[(20-n) .. (40-n)].
12955     uint8_t buf[40] = {0};
12956     uint8_t* ptr = &buf[20];
12957     do {
12958       uint64_t remaining = x / 10;
12959       x -= remaining * 10;
12960       ptr--;
12961       *ptr = (uint8_t)x;
12962       n++;
12963       x = remaining;
12964     } while (x > 0);
12965     memcpy(h->digits, ptr, 20);
12966   }
12967 
12968   // Set h's other fields.
12969   h->num_digits = n;
12970   h->decimal_point = (int32_t)n;
12971   h->negative = negative;
12972   h->truncated = false;
12973   wuffs_base__private_implementation__high_prec_dec__trim(h);
12974 }
12975 
12976 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)12977 wuffs_base__private_implementation__high_prec_dec__parse(
12978     wuffs_base__private_implementation__high_prec_dec* h,
12979     wuffs_base__slice_u8 s,
12980     uint32_t options) {
12981   if (!h) {
12982     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
12983   }
12984   h->num_digits = 0;
12985   h->decimal_point = 0;
12986   h->negative = false;
12987   h->truncated = false;
12988 
12989   uint8_t* p = s.ptr;
12990   uint8_t* q = s.ptr + s.len;
12991 
12992   if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
12993     for (;; p++) {
12994       if (p >= q) {
12995         return wuffs_base__make_status(wuffs_base__error__bad_argument);
12996       } else if (*p != '_') {
12997         break;
12998       }
12999     }
13000   }
13001 
13002   // Parse sign.
13003   do {
13004     if (*p == '+') {
13005       p++;
13006     } else if (*p == '-') {
13007       h->negative = true;
13008       p++;
13009     } else {
13010       break;
13011     }
13012     if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
13013       for (;; p++) {
13014         if (p >= q) {
13015           return wuffs_base__make_status(wuffs_base__error__bad_argument);
13016         } else if (*p != '_') {
13017           break;
13018         }
13019       }
13020     }
13021   } while (0);
13022 
13023   // Parse digits, up to (and including) a '.', 'E' or 'e'. Examples for each
13024   // limb in this if-else chain:
13025   //  - "0.789"
13026   //  - "1002.789"
13027   //  - ".789"
13028   //  - Other (invalid input).
13029   uint32_t nd = 0;
13030   int32_t dp = 0;
13031   bool no_digits_before_separator = false;
13032   if (('0' == *p) &&
13033       !(options &
13034         WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_MULTIPLE_LEADING_ZEROES)) {
13035     p++;
13036     for (;; p++) {
13037       if (p >= q) {
13038         goto after_all;
13039       } else if (*p ==
13040                  ((options &
13041                    WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)
13042                       ? ','
13043                       : '.')) {
13044         p++;
13045         goto after_sep;
13046       } else if ((*p == 'E') || (*p == 'e')) {
13047         p++;
13048         goto after_exp;
13049       } else if ((*p != '_') ||
13050                  !(options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) {
13051         return wuffs_base__make_status(wuffs_base__error__bad_argument);
13052       }
13053     }
13054 
13055   } else if (('0' <= *p) && (*p <= '9')) {
13056     if (*p == '0') {
13057       for (; (p < q) && (*p == '0'); p++) {
13058       }
13059     } else {
13060       h->digits[nd++] = (uint8_t)(*p - '0');
13061       dp = (int32_t)nd;
13062       p++;
13063     }
13064 
13065     for (;; p++) {
13066       if (p >= q) {
13067         goto after_all;
13068       } else if (('0' <= *p) && (*p <= '9')) {
13069         if (nd < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
13070           h->digits[nd++] = (uint8_t)(*p - '0');
13071           dp = (int32_t)nd;
13072         } else if ('0' != *p) {
13073           // Long-tail non-zeroes set the truncated bit.
13074           h->truncated = true;
13075         }
13076       } else if (*p ==
13077                  ((options &
13078                    WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)
13079                       ? ','
13080                       : '.')) {
13081         p++;
13082         goto after_sep;
13083       } else if ((*p == 'E') || (*p == 'e')) {
13084         p++;
13085         goto after_exp;
13086       } else if ((*p != '_') ||
13087                  !(options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) {
13088         return wuffs_base__make_status(wuffs_base__error__bad_argument);
13089       }
13090     }
13091 
13092   } else if (*p == ((options &
13093                      WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)
13094                         ? ','
13095                         : '.')) {
13096     p++;
13097     no_digits_before_separator = true;
13098 
13099   } else {
13100     return wuffs_base__make_status(wuffs_base__error__bad_argument);
13101   }
13102 
13103 after_sep:
13104   for (;; p++) {
13105     if (p >= q) {
13106       goto after_all;
13107     } else if ('0' == *p) {
13108       if (nd == 0) {
13109         // Track leading zeroes implicitly.
13110         dp--;
13111       } else if (nd <
13112                  WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
13113         h->digits[nd++] = (uint8_t)(*p - '0');
13114       }
13115     } else if (('0' < *p) && (*p <= '9')) {
13116       if (nd < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
13117         h->digits[nd++] = (uint8_t)(*p - '0');
13118       } else {
13119         // Long-tail non-zeroes set the truncated bit.
13120         h->truncated = true;
13121       }
13122     } else if ((*p == 'E') || (*p == 'e')) {
13123       p++;
13124       goto after_exp;
13125     } else if ((*p != '_') ||
13126                !(options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) {
13127       return wuffs_base__make_status(wuffs_base__error__bad_argument);
13128     }
13129   }
13130 
13131 after_exp:
13132   do {
13133     if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
13134       for (;; p++) {
13135         if (p >= q) {
13136           return wuffs_base__make_status(wuffs_base__error__bad_argument);
13137         } else if (*p != '_') {
13138           break;
13139         }
13140       }
13141     }
13142 
13143     int32_t exp_sign = +1;
13144     if (*p == '+') {
13145       p++;
13146     } else if (*p == '-') {
13147       exp_sign = -1;
13148       p++;
13149     }
13150 
13151     int32_t exp = 0;
13152     const int32_t exp_large =
13153         WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE +
13154         WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION;
13155     bool saw_exp_digits = false;
13156     for (; p < q; p++) {
13157       if ((*p == '_') &&
13158           (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) {
13159         // No-op.
13160       } else if (('0' <= *p) && (*p <= '9')) {
13161         saw_exp_digits = true;
13162         if (exp < exp_large) {
13163           exp = (10 * exp) + ((int32_t)(*p - '0'));
13164         }
13165       } else {
13166         break;
13167       }
13168     }
13169     if (!saw_exp_digits) {
13170       return wuffs_base__make_status(wuffs_base__error__bad_argument);
13171     }
13172     dp += exp_sign * exp;
13173   } while (0);
13174 
13175 after_all:
13176   if (p != q) {
13177     return wuffs_base__make_status(wuffs_base__error__bad_argument);
13178   }
13179   h->num_digits = nd;
13180   if (nd == 0) {
13181     if (no_digits_before_separator) {
13182       return wuffs_base__make_status(wuffs_base__error__bad_argument);
13183     }
13184     h->decimal_point = 0;
13185   } else if (dp <
13186              -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
13187     h->decimal_point =
13188         -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE - 1;
13189   } else if (dp >
13190              +WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
13191     h->decimal_point =
13192         +WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE + 1;
13193   } else {
13194     h->decimal_point = dp;
13195   }
13196   wuffs_base__private_implementation__high_prec_dec__trim(h);
13197   return wuffs_base__make_status(NULL);
13198 }
13199 
13200 // --------
13201 
13202 // wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits
13203 // returns the number of additional decimal digits when left-shifting by shift.
13204 //
13205 // See below for preconditions.
13206 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)13207 wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits(
13208     wuffs_base__private_implementation__high_prec_dec* h,
13209     uint32_t shift) {
13210   // Masking with 0x3F should be unnecessary (assuming the preconditions) but
13211   // it's cheap and ensures that we don't overflow the
13212   // wuffs_base__private_implementation__hpd_left_shift array.
13213   shift &= 63;
13214 
13215   uint32_t x_a = wuffs_base__private_implementation__hpd_left_shift[shift];
13216   uint32_t x_b = wuffs_base__private_implementation__hpd_left_shift[shift + 1];
13217   uint32_t num_new_digits = x_a >> 11;
13218   uint32_t pow5_a = 0x7FF & x_a;
13219   uint32_t pow5_b = 0x7FF & x_b;
13220 
13221   const uint8_t* pow5 =
13222       &wuffs_base__private_implementation__powers_of_5[pow5_a];
13223   uint32_t i = 0;
13224   uint32_t n = pow5_b - pow5_a;
13225   for (; i < n; i++) {
13226     if (i >= h->num_digits) {
13227       return num_new_digits - 1;
13228     } else if (h->digits[i] == pow5[i]) {
13229       continue;
13230     } else if (h->digits[i] < pow5[i]) {
13231       return num_new_digits - 1;
13232     } else {
13233       return num_new_digits;
13234     }
13235   }
13236   return num_new_digits;
13237 }
13238 
13239 // --------
13240 
13241 // wuffs_base__private_implementation__high_prec_dec__rounded_integer returns
13242 // the integral (non-fractional) part of h, provided that it is 18 or fewer
13243 // decimal digits. For 19 or more digits, it returns UINT64_MAX. Note that:
13244 //  - (1 << 53) is    9007199254740992, which has 16 decimal digits.
13245 //  - (1 << 56) is   72057594037927936, which has 17 decimal digits.
13246 //  - (1 << 59) is  576460752303423488, which has 18 decimal digits.
13247 //  - (1 << 63) is 9223372036854775808, which has 19 decimal digits.
13248 // and that IEEE 754 double precision has 52 mantissa bits.
13249 //
13250 // That integral part is rounded-to-even: rounding 7.5 or 8.5 both give 8.
13251 //
13252 // h's negative bit is ignored: rounding -8.6 returns 9.
13253 //
13254 // See below for preconditions.
13255 static uint64_t  //
wuffs_base__private_implementation__high_prec_dec__rounded_integer(wuffs_base__private_implementation__high_prec_dec * h)13256 wuffs_base__private_implementation__high_prec_dec__rounded_integer(
13257     wuffs_base__private_implementation__high_prec_dec* h) {
13258   if ((h->num_digits == 0) || (h->decimal_point < 0)) {
13259     return 0;
13260   } else if (h->decimal_point > 18) {
13261     return UINT64_MAX;
13262   }
13263 
13264   uint32_t dp = (uint32_t)(h->decimal_point);
13265   uint64_t n = 0;
13266   uint32_t i = 0;
13267   for (; i < dp; i++) {
13268     n = (10 * n) + ((i < h->num_digits) ? h->digits[i] : 0);
13269   }
13270 
13271   bool round_up = false;
13272   if (dp < h->num_digits) {
13273     round_up = h->digits[dp] >= 5;
13274     if ((h->digits[dp] == 5) && (dp + 1 == h->num_digits)) {
13275       // We are exactly halfway. If we're truncated, round up, otherwise round
13276       // to even.
13277       round_up = h->truncated ||  //
13278                  ((dp > 0) && (1 & h->digits[dp - 1]));
13279     }
13280   }
13281   if (round_up) {
13282     n++;
13283   }
13284 
13285   return n;
13286 }
13287 
13288 // wuffs_base__private_implementation__high_prec_dec__small_xshift shifts h's
13289 // number (where 'x' is 'l' or 'r' for left or right) by a small shift value.
13290 //
13291 // Preconditions:
13292 //  - h is non-NULL.
13293 //  - h->decimal_point is "not extreme".
13294 //  - shift is non-zero.
13295 //  - shift is "a small shift".
13296 //
13297 // "Not extreme" means within
13298 // ±WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE.
13299 //
13300 // "A small shift" means not more than
13301 // WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL.
13302 //
13303 // wuffs_base__private_implementation__high_prec_dec__rounded_integer and
13304 // wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits
13305 // have the same preconditions.
13306 //
13307 // wuffs_base__private_implementation__high_prec_dec__lshift keeps the first
13308 // two preconditions but not the last two. Its shift argument is signed and
13309 // does not need to be "small": zero is a no-op, positive means left shift and
13310 // negative means right shift.
13311 
13312 static void  //
wuffs_base__private_implementation__high_prec_dec__small_lshift(wuffs_base__private_implementation__high_prec_dec * h,uint32_t shift)13313 wuffs_base__private_implementation__high_prec_dec__small_lshift(
13314     wuffs_base__private_implementation__high_prec_dec* h,
13315     uint32_t shift) {
13316   if (h->num_digits == 0) {
13317     return;
13318   }
13319   uint32_t num_new_digits =
13320       wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits(
13321           h, shift);
13322   uint32_t rx = h->num_digits - 1;                   // Read  index.
13323   uint32_t wx = h->num_digits - 1 + num_new_digits;  // Write index.
13324   uint64_t n = 0;
13325 
13326   // Repeat: pick up a digit, put down a digit, right to left.
13327   while (((int32_t)rx) >= 0) {
13328     n += ((uint64_t)(h->digits[rx])) << shift;
13329     uint64_t quo = n / 10;
13330     uint64_t rem = n - (10 * quo);
13331     if (wx < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
13332       h->digits[wx] = (uint8_t)rem;
13333     } else if (rem > 0) {
13334       h->truncated = true;
13335     }
13336     n = quo;
13337     wx--;
13338     rx--;
13339   }
13340 
13341   // Put down leading digits, right to left.
13342   while (n > 0) {
13343     uint64_t quo = n / 10;
13344     uint64_t rem = n - (10 * quo);
13345     if (wx < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
13346       h->digits[wx] = (uint8_t)rem;
13347     } else if (rem > 0) {
13348       h->truncated = true;
13349     }
13350     n = quo;
13351     wx--;
13352   }
13353 
13354   // Finish.
13355   h->num_digits += num_new_digits;
13356   if (h->num_digits >
13357       WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
13358     h->num_digits = WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION;
13359   }
13360   h->decimal_point += (int32_t)num_new_digits;
13361   wuffs_base__private_implementation__high_prec_dec__trim(h);
13362 }
13363 
13364 static void  //
wuffs_base__private_implementation__high_prec_dec__small_rshift(wuffs_base__private_implementation__high_prec_dec * h,uint32_t shift)13365 wuffs_base__private_implementation__high_prec_dec__small_rshift(
13366     wuffs_base__private_implementation__high_prec_dec* h,
13367     uint32_t shift) {
13368   uint32_t rx = 0;  // Read  index.
13369   uint32_t wx = 0;  // Write index.
13370   uint64_t n = 0;
13371 
13372   // Pick up enough leading digits to cover the first shift.
13373   while ((n >> shift) == 0) {
13374     if (rx < h->num_digits) {
13375       // Read a digit.
13376       n = (10 * n) + h->digits[rx++];
13377     } else if (n == 0) {
13378       // h's number used to be zero and remains zero.
13379       return;
13380     } else {
13381       // Read sufficient implicit trailing zeroes.
13382       while ((n >> shift) == 0) {
13383         n = 10 * n;
13384         rx++;
13385       }
13386       break;
13387     }
13388   }
13389   h->decimal_point -= ((int32_t)(rx - 1));
13390   if (h->decimal_point <
13391       -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
13392     // After the shift, h's number is effectively zero.
13393     h->num_digits = 0;
13394     h->decimal_point = 0;
13395     h->truncated = false;
13396     return;
13397   }
13398 
13399   // Repeat: pick up a digit, put down a digit, left to right.
13400   uint64_t mask = (((uint64_t)(1)) << shift) - 1;
13401   while (rx < h->num_digits) {
13402     uint8_t new_digit = ((uint8_t)(n >> shift));
13403     n = (10 * (n & mask)) + h->digits[rx++];
13404     h->digits[wx++] = new_digit;
13405   }
13406 
13407   // Put down trailing digits, left to right.
13408   while (n > 0) {
13409     uint8_t new_digit = ((uint8_t)(n >> shift));
13410     n = 10 * (n & mask);
13411     if (wx < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
13412       h->digits[wx++] = new_digit;
13413     } else if (new_digit > 0) {
13414       h->truncated = true;
13415     }
13416   }
13417 
13418   // Finish.
13419   h->num_digits = wx;
13420   wuffs_base__private_implementation__high_prec_dec__trim(h);
13421 }
13422 
13423 static void  //
wuffs_base__private_implementation__high_prec_dec__lshift(wuffs_base__private_implementation__high_prec_dec * h,int32_t shift)13424 wuffs_base__private_implementation__high_prec_dec__lshift(
13425     wuffs_base__private_implementation__high_prec_dec* h,
13426     int32_t shift) {
13427   if (shift > 0) {
13428     while (shift > +WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL) {
13429       wuffs_base__private_implementation__high_prec_dec__small_lshift(
13430           h, WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL);
13431       shift -= WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
13432     }
13433     wuffs_base__private_implementation__high_prec_dec__small_lshift(
13434         h, ((uint32_t)(+shift)));
13435   } else if (shift < 0) {
13436     while (shift < -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL) {
13437       wuffs_base__private_implementation__high_prec_dec__small_rshift(
13438           h, WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL);
13439       shift += WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
13440     }
13441     wuffs_base__private_implementation__high_prec_dec__small_rshift(
13442         h, ((uint32_t)(-shift)));
13443   }
13444 }
13445 
13446 // --------
13447 
13448 // wuffs_base__private_implementation__high_prec_dec__round_etc rounds h's
13449 // number. For those functions that take an n argument, rounding produces at
13450 // most n digits (which is not necessarily at most n decimal places). Negative
13451 // n values are ignored, as well as any n greater than or equal to h's number
13452 // of digits. The etc__round_just_enough function implicitly chooses an n to
13453 // implement WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION.
13454 //
13455 // Preconditions:
13456 //  - h is non-NULL.
13457 //  - h->decimal_point is "not extreme".
13458 //
13459 // "Not extreme" means within
13460 // ±WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE.
13461 
13462 static void  //
wuffs_base__private_implementation__high_prec_dec__round_down(wuffs_base__private_implementation__high_prec_dec * h,int32_t n)13463 wuffs_base__private_implementation__high_prec_dec__round_down(
13464     wuffs_base__private_implementation__high_prec_dec* h,
13465     int32_t n) {
13466   if ((n < 0) || (h->num_digits <= (uint32_t)n)) {
13467     return;
13468   }
13469   h->num_digits = (uint32_t)(n);
13470   wuffs_base__private_implementation__high_prec_dec__trim(h);
13471 }
13472 
13473 static void  //
wuffs_base__private_implementation__high_prec_dec__round_up(wuffs_base__private_implementation__high_prec_dec * h,int32_t n)13474 wuffs_base__private_implementation__high_prec_dec__round_up(
13475     wuffs_base__private_implementation__high_prec_dec* h,
13476     int32_t n) {
13477   if ((n < 0) || (h->num_digits <= (uint32_t)n)) {
13478     return;
13479   }
13480 
13481   for (n--; n >= 0; n--) {
13482     if (h->digits[n] < 9) {
13483       h->digits[n]++;
13484       h->num_digits = (uint32_t)(n + 1);
13485       return;
13486     }
13487   }
13488 
13489   // The number is all 9s. Change to a single 1 and adjust the decimal point.
13490   h->digits[0] = 1;
13491   h->num_digits = 1;
13492   h->decimal_point++;
13493 }
13494 
13495 static void  //
wuffs_base__private_implementation__high_prec_dec__round_nearest(wuffs_base__private_implementation__high_prec_dec * h,int32_t n)13496 wuffs_base__private_implementation__high_prec_dec__round_nearest(
13497     wuffs_base__private_implementation__high_prec_dec* h,
13498     int32_t n) {
13499   if ((n < 0) || (h->num_digits <= (uint32_t)n)) {
13500     return;
13501   }
13502   bool up = h->digits[n] >= 5;
13503   if ((h->digits[n] == 5) && ((n + 1) == ((int32_t)(h->num_digits)))) {
13504     up = h->truncated ||  //
13505          ((n > 0) && ((h->digits[n - 1] & 1) != 0));
13506   }
13507 
13508   if (up) {
13509     wuffs_base__private_implementation__high_prec_dec__round_up(h, n);
13510   } else {
13511     wuffs_base__private_implementation__high_prec_dec__round_down(h, n);
13512   }
13513 }
13514 
13515 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)13516 wuffs_base__private_implementation__high_prec_dec__round_just_enough(
13517     wuffs_base__private_implementation__high_prec_dec* h,
13518     int32_t exp2,
13519     uint64_t mantissa) {
13520   // The magic numbers 52 and 53 in this function are because IEEE 754 double
13521   // precision has 52 mantissa bits.
13522   //
13523   // Let f be the floating point number represented by exp2 and mantissa (and
13524   // also the number in h): the number (mantissa * (2 ** (exp2 - 52))).
13525   //
13526   // If f is zero or a small integer, we can return early.
13527   if ((mantissa == 0) ||
13528       ((exp2 < 53) && (h->decimal_point >= ((int32_t)(h->num_digits))))) {
13529     return;
13530   }
13531 
13532   // The smallest normal f has an exp2 of -1022 and a mantissa of (1 << 52).
13533   // Subnormal numbers have the same exp2 but a smaller mantissa.
13534   static const int32_t min_incl_normal_exp2 = -1022;
13535   static const uint64_t min_incl_normal_mantissa = 0x0010000000000000ul;
13536 
13537   // Compute lower and upper bounds such that any number between them (possibly
13538   // inclusive) will round to f. First, the lower bound. Our number f is:
13539   //   ((mantissa + 0)         * (2 ** (  exp2 - 52)))
13540   //
13541   // The next lowest floating point number is:
13542   //   ((mantissa - 1)         * (2 ** (  exp2 - 52)))
13543   // unless (mantissa - 1) drops the (1 << 52) bit and exp2 is not the
13544   // min_incl_normal_exp2. Either way, call it:
13545   //   ((l_mantissa)           * (2 ** (l_exp2 - 52)))
13546   //
13547   // The lower bound is halfway between them (noting that 52 became 53):
13548   //   (((2 * l_mantissa) + 1) * (2 ** (l_exp2 - 53)))
13549   int32_t l_exp2 = exp2;
13550   uint64_t l_mantissa = mantissa - 1;
13551   if ((exp2 > min_incl_normal_exp2) && (mantissa <= min_incl_normal_mantissa)) {
13552     l_exp2 = exp2 - 1;
13553     l_mantissa = (2 * mantissa) - 1;
13554   }
13555   wuffs_base__private_implementation__high_prec_dec lower;
13556   wuffs_base__private_implementation__high_prec_dec__assign(
13557       &lower, (2 * l_mantissa) + 1, false);
13558   wuffs_base__private_implementation__high_prec_dec__lshift(&lower,
13559                                                             l_exp2 - 53);
13560 
13561   // Next, the upper bound. Our number f is:
13562   //   ((mantissa + 0)       * (2 ** (exp2 - 52)))
13563   //
13564   // The next highest floating point number is:
13565   //   ((mantissa + 1)       * (2 ** (exp2 - 52)))
13566   //
13567   // The upper bound is halfway between them (noting that 52 became 53):
13568   //   (((2 * mantissa) + 1) * (2 ** (exp2 - 53)))
13569   wuffs_base__private_implementation__high_prec_dec upper;
13570   wuffs_base__private_implementation__high_prec_dec__assign(
13571       &upper, (2 * mantissa) + 1, false);
13572   wuffs_base__private_implementation__high_prec_dec__lshift(&upper, exp2 - 53);
13573 
13574   // The lower and upper bounds are possible outputs only if the original
13575   // mantissa is even, so that IEEE round-to-even would round to the original
13576   // mantissa and not its neighbors.
13577   bool inclusive = (mantissa & 1) == 0;
13578 
13579   // As we walk the digits, we want to know whether rounding up would fall
13580   // within the upper bound. This is tracked by upper_delta:
13581   //  - When -1, the digits of h and upper are the same so far.
13582   //  - When +0, we saw a difference of 1 between h and upper on a previous
13583   //    digit and subsequently only 9s for h and 0s for upper. Thus, rounding
13584   //    up may fall outside of the bound if !inclusive.
13585   //  - When +1, the difference is greater than 1 and we know that rounding up
13586   //    falls within the bound.
13587   //
13588   // This is a state machine with three states. The numerical value for each
13589   // state (-1, +0 or +1) isn't important, other than their order.
13590   int upper_delta = -1;
13591 
13592   // We can now figure out the shortest number of digits required. Walk the
13593   // digits until h has distinguished itself from lower or upper.
13594   //
13595   // The zi and zd variables are indexes and digits, for z in l (lower), h (the
13596   // number) and u (upper).
13597   //
13598   // The lower, h and upper numbers may have their decimal points at different
13599   // places. In this case, upper is the longest, so we iterate ui starting from
13600   // 0 and iterate li and hi starting from either 0 or -1.
13601   int32_t ui = 0;
13602   for (;; ui++) {
13603     // Calculate hd, the middle number's digit.
13604     int32_t hi = ui - upper.decimal_point + h->decimal_point;
13605     if (hi >= ((int32_t)(h->num_digits))) {
13606       break;
13607     }
13608     uint8_t hd = (((uint32_t)hi) < h->num_digits) ? h->digits[hi] : 0;
13609 
13610     // Calculate ld, the lower bound's digit.
13611     int32_t li = ui - upper.decimal_point + lower.decimal_point;
13612     uint8_t ld = (((uint32_t)li) < lower.num_digits) ? lower.digits[li] : 0;
13613 
13614     // We can round down (truncate) if lower has a different digit than h or if
13615     // lower is inclusive and is exactly the result of rounding down (i.e. we
13616     // have reached the final digit of lower).
13617     bool can_round_down =
13618         (ld != hd) ||  //
13619         (inclusive && ((li + 1) == ((int32_t)(lower.num_digits))));
13620 
13621     // Calculate ud, the upper bound's digit, and update upper_delta.
13622     uint8_t ud = (((uint32_t)ui) < upper.num_digits) ? upper.digits[ui] : 0;
13623     if (upper_delta < 0) {
13624       if ((hd + 1) < ud) {
13625         // For example:
13626         // h     = 12345???
13627         // upper = 12347???
13628         upper_delta = +1;
13629       } else if (hd != ud) {
13630         // For example:
13631         // h     = 12345???
13632         // upper = 12346???
13633         upper_delta = +0;
13634       }
13635     } else if (upper_delta == 0) {
13636       if ((hd != 9) || (ud != 0)) {
13637         // For example:
13638         // h     = 1234598?
13639         // upper = 1234600?
13640         upper_delta = +1;
13641       }
13642     }
13643 
13644     // We can round up if upper has a different digit than h and either upper
13645     // is inclusive or upper is bigger than the result of rounding up.
13646     bool can_round_up =
13647         (upper_delta > 0) ||    //
13648         ((upper_delta == 0) &&  //
13649          (inclusive || ((ui + 1) < ((int32_t)(upper.num_digits)))));
13650 
13651     // If we can round either way, round to nearest. If we can round only one
13652     // way, do it. If we can't round, continue the loop.
13653     if (can_round_down) {
13654       if (can_round_up) {
13655         wuffs_base__private_implementation__high_prec_dec__round_nearest(
13656             h, hi + 1);
13657         return;
13658       } else {
13659         wuffs_base__private_implementation__high_prec_dec__round_down(h,
13660                                                                       hi + 1);
13661         return;
13662       }
13663     } else {
13664       if (can_round_up) {
13665         wuffs_base__private_implementation__high_prec_dec__round_up(h, hi + 1);
13666         return;
13667       }
13668     }
13669   }
13670 }
13671 
13672 // --------
13673 
13674 // wuffs_base__private_implementation__parse_number_f64_eisel_lemire produces
13675 // the IEEE 754 double-precision value for an exact mantissa and base-10
13676 // exponent. For example:
13677 //  - when parsing "12345.678e+02", man is 12345678 and exp10 is -1.
13678 //  - when parsing "-12", man is 12 and exp10 is 0. Processing the leading
13679 //    minus sign is the responsibility of the caller, not this function.
13680 //
13681 // On success, it returns a non-negative int64_t such that the low 63 bits hold
13682 // the 11-bit exponent and 52-bit mantissa.
13683 //
13684 // On failure, it returns a negative value.
13685 //
13686 // The algorithm is based on an original idea by Michael Eisel that was refined
13687 // by Daniel Lemire. See
13688 // https://lemire.me/blog/2020/03/10/fast-float-parsing-in-practice/
13689 // and
13690 // https://nigeltao.github.io/blog/2020/eisel-lemire.html
13691 //
13692 // Preconditions:
13693 //  - man is non-zero.
13694 //  - exp10 is in the range [-307 ..= 288], the same range of the
13695 //    wuffs_base__private_implementation__powers_of_10 array.
13696 //
13697 // The exp10 range (and the fact that man is in the range [1 ..= UINT64_MAX],
13698 // approximately [1 ..= 1.85e+19]) means that (man * (10 ** exp10)) is in the
13699 // range [1e-307 ..= 1.85e+307]. This is entirely within the range of normal
13700 // (neither subnormal nor non-finite) f64 values: DBL_MIN and DBL_MAX are
13701 // approximately 2.23e–308 and 1.80e+308.
13702 static int64_t  //
wuffs_base__private_implementation__parse_number_f64_eisel_lemire(uint64_t man,int32_t exp10)13703 wuffs_base__private_implementation__parse_number_f64_eisel_lemire(
13704     uint64_t man,
13705     int32_t exp10) {
13706   // Look up the (possibly truncated) base-2 representation of (10 ** exp10).
13707   // The look-up table was constructed so that it is already normalized: the
13708   // table entry's mantissa's MSB (most significant bit) is on.
13709   const uint64_t* po10 =
13710       &wuffs_base__private_implementation__powers_of_10[exp10 + 307][0];
13711 
13712   // Normalize the man argument. The (man != 0) precondition means that a
13713   // non-zero bit exists.
13714   uint32_t clz = wuffs_base__count_leading_zeroes_u64(man);
13715   man <<= clz;
13716 
13717   // Calculate the return value's base-2 exponent. We might tweak it by ±1
13718   // later, but its initial value comes from a linear scaling of exp10,
13719   // converting from power-of-10 to power-of-2, and adjusting by clz.
13720   //
13721   // The magic constants are:
13722   //  - 1087 = 1023 + 64. The 1023 is the f64 exponent bias. The 64 is because
13723   //    the look-up table uses 64-bit mantissas.
13724   //  - 217706 is such that the ratio 217706 / 65536 ≈ 3.321930 is close enough
13725   //    (over the practical range of exp10) to log(10) / log(2) ≈ 3.321928.
13726   //  - 65536 = 1<<16 is arbitrary but a power of 2, so division is a shift.
13727   //
13728   // Equality of the linearly-scaled value and the actual power-of-2, over the
13729   // range of exp10 arguments that this function accepts, is confirmed by
13730   // script/print-mpb-powers-of-10.go
13731   uint64_t ret_exp2 =
13732       ((uint64_t)(((217706 * exp10) >> 16) + 1087)) - ((uint64_t)clz);
13733 
13734   // Multiply the two mantissas. Normalization means that both mantissas are at
13735   // least (1<<63), so the 128-bit product must be at least (1<<126). The high
13736   // 64 bits of the product, x_hi, must therefore be at least (1<<62).
13737   //
13738   // As a consequence, x_hi has either 0 or 1 leading zeroes. Shifting x_hi
13739   // right by either 9 or 10 bits (depending on x_hi's MSB) will therefore
13740   // leave the top 10 MSBs (bits 54 ..= 63) off and the 11th MSB (bit 53) on.
13741   wuffs_base__multiply_u64__output x = wuffs_base__multiply_u64(man, po10[1]);
13742   uint64_t x_hi = x.hi;
13743   uint64_t x_lo = x.lo;
13744 
13745   // Before we shift right by at least 9 bits, recall that the look-up table
13746   // entry was possibly truncated. We have so far only calculated a lower bound
13747   // for the product (man * e), where e is (10 ** exp10). The upper bound would
13748   // add a further (man * 1) to the 128-bit product, which overflows the lower
13749   // 64-bit limb if ((x_lo + man) < man).
13750   //
13751   // If overflow occurs, that adds 1 to x_hi. Since we're about to shift right
13752   // by at least 9 bits, that carried 1 can be ignored unless the higher 64-bit
13753   // limb's low 9 bits are all on.
13754   //
13755   // For example, parsing "9999999999999999999" will take the if-true branch
13756   // here, since:
13757   //  - x_hi = 0x4563918244F3FFFF
13758   //  - x_lo = 0x8000000000000000
13759   //  - man  = 0x8AC7230489E7FFFF
13760   if (((x_hi & 0x1FF) == 0x1FF) && ((x_lo + man) < man)) {
13761     // Refine our calculation of (man * e). Before, our approximation of e used
13762     // a "low resolution" 64-bit mantissa. Now use a "high resolution" 128-bit
13763     // mantissa. We've already calculated x = (man * bits_0_to_63_incl_of_e).
13764     // Now calculate y = (man * bits_64_to_127_incl_of_e).
13765     wuffs_base__multiply_u64__output y = wuffs_base__multiply_u64(man, po10[0]);
13766     uint64_t y_hi = y.hi;
13767     uint64_t y_lo = y.lo;
13768 
13769     // Merge the 128-bit x and 128-bit y, which overlap by 64 bits, to
13770     // calculate the 192-bit product of the 64-bit man by the 128-bit e.
13771     // As we exit this if-block, we only care about the high 128 bits
13772     // (merged_hi and merged_lo) of that 192-bit product.
13773     //
13774     // For example, parsing "1.234e-45" will take the if-true branch here,
13775     // since:
13776     //  - x_hi = 0x70B7E3696DB29FFF
13777     //  - x_lo = 0xE040000000000000
13778     //  - y_hi = 0x33718BBEAB0E0D7A
13779     //  - y_lo = 0xA880000000000000
13780     uint64_t merged_hi = x_hi;
13781     uint64_t merged_lo = x_lo + y_hi;
13782     if (merged_lo < x_lo) {
13783       merged_hi++;  // Carry the overflow bit.
13784     }
13785 
13786     // The "high resolution" approximation of e is still a lower bound. Once
13787     // again, see if the upper bound is large enough to produce a different
13788     // result. This time, if it does, give up instead of reaching for an even
13789     // more precise approximation to e.
13790     //
13791     // This three-part check is similar to the two-part check that guarded the
13792     // if block that we're now in, but it has an extra term for the middle 64
13793     // bits (checking that adding 1 to merged_lo would overflow).
13794     //
13795     // For example, parsing "5.9604644775390625e-8" will take the if-true
13796     // branch here, since:
13797     //  - merged_hi = 0x7FFFFFFFFFFFFFFF
13798     //  - merged_lo = 0xFFFFFFFFFFFFFFFF
13799     //  - y_lo      = 0x4DB3FFC120988200
13800     //  - man       = 0xD3C21BCECCEDA100
13801     if (((merged_hi & 0x1FF) == 0x1FF) && ((merged_lo + 1) == 0) &&
13802         (y_lo + man < man)) {
13803       return -1;
13804     }
13805 
13806     // Replace the 128-bit x with merged.
13807     x_hi = merged_hi;
13808     x_lo = merged_lo;
13809   }
13810 
13811   // As mentioned above, shifting x_hi right by either 9 or 10 bits will leave
13812   // the top 10 MSBs (bits 54 ..= 63) off and the 11th MSB (bit 53) on. If the
13813   // MSB (before shifting) was on, adjust ret_exp2 for the larger shift.
13814   //
13815   // Having bit 53 on (and higher bits off) means that ret_mantissa is a 54-bit
13816   // number.
13817   uint64_t msb = x_hi >> 63;
13818   uint64_t ret_mantissa = x_hi >> (msb + 9);
13819   ret_exp2 -= 1 ^ msb;
13820 
13821   // IEEE 754 rounds to-nearest with ties rounded to-even. Rounding to-even can
13822   // be tricky. If we're half-way between two exactly representable numbers
13823   // (x's low 73 bits are zero and the next 2 bits that matter are "01"), give
13824   // up instead of trying to pick the winner.
13825   //
13826   // Technically, we could tighten the condition by changing "73" to "73 or 74,
13827   // depending on msb", but a flat "73" is simpler.
13828   //
13829   // For example, parsing "1e+23" will take the if-true branch here, since:
13830   //  - x_hi          = 0x54B40B1F852BDA00
13831   //  - ret_mantissa  = 0x002A5A058FC295ED
13832   if ((x_lo == 0) && ((x_hi & 0x1FF) == 0) && ((ret_mantissa & 3) == 1)) {
13833     return -1;
13834   }
13835 
13836   // If we're not halfway then it's rounding to-nearest. Starting with a 54-bit
13837   // number, carry the lowest bit (bit 0) up if it's on. Regardless of whether
13838   // it was on or off, shifting right by one then produces a 53-bit number. If
13839   // carrying up overflowed, shift again.
13840   ret_mantissa += ret_mantissa & 1;
13841   ret_mantissa >>= 1;
13842   // This if block is equivalent to (but benchmarks slightly faster than) the
13843   // following branchless form:
13844   //    uint64_t overflow_adjustment = ret_mantissa >> 53;
13845   //    ret_mantissa >>= overflow_adjustment;
13846   //    ret_exp2 += overflow_adjustment;
13847   //
13848   // For example, parsing "7.2057594037927933e+16" will take the if-true
13849   // branch here, since:
13850   //  - x_hi          = 0x7FFFFFFFFFFFFE80
13851   //  - ret_mantissa  = 0x0020000000000000
13852   if ((ret_mantissa >> 53) > 0) {
13853     ret_mantissa >>= 1;
13854     ret_exp2++;
13855   }
13856 
13857   // Starting with a 53-bit number, IEEE 754 double-precision normal numbers
13858   // have an implicit mantissa bit. Mask that away and keep the low 52 bits.
13859   ret_mantissa &= 0x000FFFFFFFFFFFFF;
13860 
13861   // Pack the bits and return.
13862   return ((int64_t)(ret_mantissa | (ret_exp2 << 52)));
13863 }
13864 
13865 // --------
13866 
13867 static wuffs_base__result_f64  //
wuffs_base__private_implementation__parse_number_f64_special(wuffs_base__slice_u8 s,uint32_t options)13868 wuffs_base__private_implementation__parse_number_f64_special(
13869     wuffs_base__slice_u8 s,
13870     uint32_t options) {
13871   do {
13872     if (options & WUFFS_BASE__PARSE_NUMBER_FXX__REJECT_INF_AND_NAN) {
13873       goto fail;
13874     }
13875 
13876     uint8_t* p = s.ptr;
13877     uint8_t* q = s.ptr + s.len;
13878 
13879     for (; (p < q) && (*p == '_'); p++) {
13880     }
13881     if (p >= q) {
13882       goto fail;
13883     }
13884 
13885     // Parse sign.
13886     bool negative = false;
13887     do {
13888       if (*p == '+') {
13889         p++;
13890       } else if (*p == '-') {
13891         negative = true;
13892         p++;
13893       } else {
13894         break;
13895       }
13896       for (; (p < q) && (*p == '_'); p++) {
13897       }
13898     } while (0);
13899     if (p >= q) {
13900       goto fail;
13901     }
13902 
13903     bool nan = false;
13904     switch (p[0]) {
13905       case 'I':
13906       case 'i':
13907         if (((q - p) < 3) ||                     //
13908             ((p[1] != 'N') && (p[1] != 'n')) ||  //
13909             ((p[2] != 'F') && (p[2] != 'f'))) {
13910           goto fail;
13911         }
13912         p += 3;
13913 
13914         if ((p >= q) || (*p == '_')) {
13915           break;
13916         } else if (((q - p) < 5) ||                     //
13917                    ((p[0] != 'I') && (p[0] != 'i')) ||  //
13918                    ((p[1] != 'N') && (p[1] != 'n')) ||  //
13919                    ((p[2] != 'I') && (p[2] != 'i')) ||  //
13920                    ((p[3] != 'T') && (p[3] != 't')) ||  //
13921                    ((p[4] != 'Y') && (p[4] != 'y'))) {
13922           goto fail;
13923         }
13924         p += 5;
13925 
13926         if ((p >= q) || (*p == '_')) {
13927           break;
13928         }
13929         goto fail;
13930 
13931       case 'N':
13932       case 'n':
13933         if (((q - p) < 3) ||                     //
13934             ((p[1] != 'A') && (p[1] != 'a')) ||  //
13935             ((p[2] != 'N') && (p[2] != 'n'))) {
13936           goto fail;
13937         }
13938         p += 3;
13939 
13940         if ((p >= q) || (*p == '_')) {
13941           nan = true;
13942           break;
13943         }
13944         goto fail;
13945 
13946       default:
13947         goto fail;
13948     }
13949 
13950     // Finish.
13951     for (; (p < q) && (*p == '_'); p++) {
13952     }
13953     if (p != q) {
13954       goto fail;
13955     }
13956     wuffs_base__result_f64 ret;
13957     ret.status.repr = NULL;
13958     ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
13959         (nan ? 0x7FFFFFFFFFFFFFFF : 0x7FF0000000000000) |
13960         (negative ? 0x8000000000000000 : 0));
13961     return ret;
13962   } while (0);
13963 
13964 fail:
13965   do {
13966     wuffs_base__result_f64 ret;
13967     ret.status.repr = wuffs_base__error__bad_argument;
13968     ret.value = 0;
13969     return ret;
13970   } while (0);
13971 }
13972 
13973 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)13974 wuffs_base__private_implementation__high_prec_dec__to_f64(
13975     wuffs_base__private_implementation__high_prec_dec* h,
13976     uint32_t options) {
13977   do {
13978     // powers converts decimal powers of 10 to binary powers of 2. For example,
13979     // (10000 >> 13) is 1. It stops before the elements exceed 60, also known
13980     // as WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL.
13981     static const uint32_t num_powers = 19;
13982     static const uint8_t powers[19] = {
13983         0,  3,  6,  9,  13, 16, 19, 23, 26, 29,  //
13984         33, 36, 39, 43, 46, 49, 53, 56, 59,      //
13985     };
13986 
13987     // Handle zero and obvious extremes. The largest and smallest positive
13988     // finite f64 values are approximately 1.8e+308 and 4.9e-324.
13989     if ((h->num_digits == 0) || (h->decimal_point < -326)) {
13990       goto zero;
13991     } else if (h->decimal_point > 310) {
13992       goto infinity;
13993     }
13994 
13995     // Try the fast Eisel-Lemire algorithm again. Calculating the (man, exp10)
13996     // pair from the high_prec_dec h is more correct but slower than the
13997     // approach taken in wuffs_base__parse_number_f64. The latter is optimized
13998     // for the common cases (e.g. assuming no underscores or a leading '+'
13999     // sign) rather than the full set of cases allowed by the Wuffs API.
14000     if (h->num_digits <= 19) {
14001       uint64_t man = 0;
14002       uint32_t i;
14003       for (i = 0; i < h->num_digits; i++) {
14004         man = (10 * man) + h->digits[i];
14005       }
14006       int32_t exp10 = h->decimal_point - ((int32_t)(h->num_digits));
14007       if ((man != 0) && (-307 <= exp10) && (exp10 <= 288)) {
14008         int64_t r =
14009             wuffs_base__private_implementation__parse_number_f64_eisel_lemire(
14010                 man, exp10);
14011         if (r >= 0) {
14012           wuffs_base__result_f64 ret;
14013           ret.status.repr = NULL;
14014           ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
14015               ((uint64_t)r) | (((uint64_t)(h->negative)) << 63));
14016           return ret;
14017         }
14018       }
14019     }
14020 
14021     // When Eisel-Lemire fails, fall back to Simple Decimal Conversion. See
14022     // https://nigeltao.github.io/blog/2020/parse-number-f64-simple.html
14023     //
14024     // Scale by powers of 2 until we're in the range [½ .. 1], which gives us
14025     // our exponent (in base-2). First we shift right, possibly a little too
14026     // far, ending with a value certainly below 1 and possibly below ½...
14027     const int32_t f64_bias = -1023;
14028     int32_t exp2 = 0;
14029     while (h->decimal_point > 0) {
14030       uint32_t n = (uint32_t)(+h->decimal_point);
14031       uint32_t shift =
14032           (n < num_powers)
14033               ? powers[n]
14034               : WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
14035 
14036       wuffs_base__private_implementation__high_prec_dec__small_rshift(h, shift);
14037       if (h->decimal_point <
14038           -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
14039         goto zero;
14040       }
14041       exp2 += (int32_t)shift;
14042     }
14043     // ...then we shift left, putting us in [½ .. 1].
14044     while (h->decimal_point <= 0) {
14045       uint32_t shift;
14046       if (h->decimal_point == 0) {
14047         if (h->digits[0] >= 5) {
14048           break;
14049         }
14050         shift = (h->digits[0] < 2) ? 2 : 1;
14051       } else {
14052         uint32_t n = (uint32_t)(-h->decimal_point);
14053         shift = (n < num_powers)
14054                     ? powers[n]
14055                     : WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
14056       }
14057 
14058       wuffs_base__private_implementation__high_prec_dec__small_lshift(h, shift);
14059       if (h->decimal_point >
14060           +WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
14061         goto infinity;
14062       }
14063       exp2 -= (int32_t)shift;
14064     }
14065 
14066     // We're in the range [½ .. 1] but f64 uses [1 .. 2].
14067     exp2--;
14068 
14069     // The minimum normal exponent is (f64_bias + 1).
14070     while ((f64_bias + 1) > exp2) {
14071       uint32_t n = (uint32_t)((f64_bias + 1) - exp2);
14072       if (n > WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL) {
14073         n = WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
14074       }
14075       wuffs_base__private_implementation__high_prec_dec__small_rshift(h, n);
14076       exp2 += (int32_t)n;
14077     }
14078 
14079     // Check for overflow.
14080     if ((exp2 - f64_bias) >= 0x07FF) {  // (1 << 11) - 1.
14081       goto infinity;
14082     }
14083 
14084     // Extract 53 bits for the mantissa (in base-2).
14085     wuffs_base__private_implementation__high_prec_dec__small_lshift(h, 53);
14086     uint64_t man2 =
14087         wuffs_base__private_implementation__high_prec_dec__rounded_integer(h);
14088 
14089     // Rounding might have added one bit. If so, shift and re-check overflow.
14090     if ((man2 >> 53) != 0) {
14091       man2 >>= 1;
14092       exp2++;
14093       if ((exp2 - f64_bias) >= 0x07FF) {  // (1 << 11) - 1.
14094         goto infinity;
14095       }
14096     }
14097 
14098     // Handle subnormal numbers.
14099     if ((man2 >> 52) == 0) {
14100       exp2 = f64_bias;
14101     }
14102 
14103     // Pack the bits and return.
14104     uint64_t exp2_bits =
14105         (uint64_t)((exp2 - f64_bias) & 0x07FF);              // (1 << 11) - 1.
14106     uint64_t bits = (man2 & 0x000FFFFFFFFFFFFF) |            // (1 << 52) - 1.
14107                     (exp2_bits << 52) |                      //
14108                     (h->negative ? 0x8000000000000000 : 0);  // (1 << 63).
14109 
14110     wuffs_base__result_f64 ret;
14111     ret.status.repr = NULL;
14112     ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(bits);
14113     return ret;
14114   } while (0);
14115 
14116 zero:
14117   do {
14118     uint64_t bits = h->negative ? 0x8000000000000000 : 0;
14119 
14120     wuffs_base__result_f64 ret;
14121     ret.status.repr = NULL;
14122     ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(bits);
14123     return ret;
14124   } while (0);
14125 
14126 infinity:
14127   do {
14128     if (options & WUFFS_BASE__PARSE_NUMBER_FXX__REJECT_INF_AND_NAN) {
14129       wuffs_base__result_f64 ret;
14130       ret.status.repr = wuffs_base__error__bad_argument;
14131       ret.value = 0;
14132       return ret;
14133     }
14134 
14135     uint64_t bits = h->negative ? 0xFFF0000000000000 : 0x7FF0000000000000;
14136 
14137     wuffs_base__result_f64 ret;
14138     ret.status.repr = NULL;
14139     ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(bits);
14140     return ret;
14141   } while (0);
14142 }
14143 
14144 static inline bool  //
wuffs_base__private_implementation__is_decimal_digit(uint8_t c)14145 wuffs_base__private_implementation__is_decimal_digit(uint8_t c) {
14146   return ('0' <= c) && (c <= '9');
14147 }
14148 
14149 WUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64  //
wuffs_base__parse_number_f64(wuffs_base__slice_u8 s,uint32_t options)14150 wuffs_base__parse_number_f64(wuffs_base__slice_u8 s, uint32_t options) {
14151   // In practice, almost all "dd.ddddE±xxx" numbers can be represented
14152   // losslessly by a uint64_t mantissa "dddddd" and an int32_t base-10
14153   // exponent, adjusting "xxx" for the position (if present) of the decimal
14154   // separator '.' or ','.
14155   //
14156   // This (u64 man, i32 exp10) data structure is superficially similar to the
14157   // "Do It Yourself Floating Point" type from Loitsch (†), but the exponent
14158   // here is base-10, not base-2.
14159   //
14160   // If s's number fits in a (man, exp10), parse that pair with the
14161   // Eisel-Lemire algorithm. If not, or if Eisel-Lemire fails, parsing s with
14162   // the fallback algorithm is slower but comprehensive.
14163   //
14164   // † "Printing Floating-Point Numbers Quickly and Accurately with Integers"
14165   // (https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf).
14166   // Florian Loitsch is also the primary contributor to
14167   // https://github.com/google/double-conversion
14168   do {
14169     // Calculating that (man, exp10) pair needs to stay within s's bounds.
14170     // Provided that s isn't extremely long, work on a NUL-terminated copy of
14171     // s's contents. The NUL byte isn't a valid part of "±dd.ddddE±xxx".
14172     //
14173     // As the pointer p walks the contents, it's faster to repeatedly check "is
14174     // *p a valid digit" than "is p within bounds and *p a valid digit".
14175     if (s.len >= 256) {
14176       goto fallback;
14177     }
14178     uint8_t z[256];
14179     memcpy(&z[0], s.ptr, s.len);
14180     z[s.len] = 0;
14181     const uint8_t* p = &z[0];
14182 
14183     // Look for a leading minus sign. Technically, we could also look for an
14184     // optional plus sign, but the "script/process-json-numbers.c with -p"
14185     // benchmark is noticably slower if we do. It's optional and, in practice,
14186     // usually absent. Let the fallback catch it.
14187     bool negative = (*p == '-');
14188     if (negative) {
14189       p++;
14190     }
14191 
14192     // After walking "dd.dddd", comparing p later with p now will produce the
14193     // number of "d"s and "."s.
14194     const uint8_t* const start_of_digits_ptr = p;
14195 
14196     // Walk the "d"s before a '.', 'E', NUL byte, etc. If it starts with '0',
14197     // it must be a single '0'. If it starts with a non-zero decimal digit, it
14198     // can be a sequence of decimal digits.
14199     //
14200     // Update the man variable during the walk. It's OK if man overflows now.
14201     // We'll detect that later.
14202     uint64_t man;
14203     if (*p == '0') {
14204       man = 0;
14205       p++;
14206       if (wuffs_base__private_implementation__is_decimal_digit(*p)) {
14207         goto fallback;
14208       }
14209     } else if (wuffs_base__private_implementation__is_decimal_digit(*p)) {
14210       man = ((uint8_t)(*p - '0'));
14211       p++;
14212       for (; wuffs_base__private_implementation__is_decimal_digit(*p); p++) {
14213         man = (10 * man) + ((uint8_t)(*p - '0'));
14214       }
14215     } else {
14216       goto fallback;
14217     }
14218 
14219     // Walk the "d"s after the optional decimal separator ('.' or ','),
14220     // updating the man and exp10 variables.
14221     int32_t exp10 = 0;
14222     if (*p ==
14223         ((options & WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)
14224              ? ','
14225              : '.')) {
14226       p++;
14227       const uint8_t* first_after_separator_ptr = p;
14228       if (!wuffs_base__private_implementation__is_decimal_digit(*p)) {
14229         goto fallback;
14230       }
14231       man = (10 * man) + ((uint8_t)(*p - '0'));
14232       p++;
14233       for (; wuffs_base__private_implementation__is_decimal_digit(*p); p++) {
14234         man = (10 * man) + ((uint8_t)(*p - '0'));
14235       }
14236       exp10 = ((int32_t)(first_after_separator_ptr - p));
14237     }
14238 
14239     // Count the number of digits:
14240     //  - for an input of "314159",  digit_count is 6.
14241     //  - for an input of "3.14159", digit_count is 7.
14242     //
14243     // This is off-by-one if there is a decimal separator. That's OK for now.
14244     // We'll correct for that later. The "script/process-json-numbers.c with
14245     // -p" benchmark is noticably slower if we try to correct for that now.
14246     uint32_t digit_count = (uint32_t)(p - start_of_digits_ptr);
14247 
14248     // Update exp10 for the optional exponent, starting with 'E' or 'e'.
14249     if ((*p | 0x20) == 'e') {
14250       p++;
14251       int32_t exp_sign = +1;
14252       if (*p == '-') {
14253         p++;
14254         exp_sign = -1;
14255       } else if (*p == '+') {
14256         p++;
14257       }
14258       if (!wuffs_base__private_implementation__is_decimal_digit(*p)) {
14259         goto fallback;
14260       }
14261       int32_t exp_num = ((uint8_t)(*p - '0'));
14262       p++;
14263       // The rest of the exp_num walking has a peculiar control flow but, once
14264       // again, the "script/process-json-numbers.c with -p" benchmark is
14265       // sensitive to alternative formulations.
14266       if (wuffs_base__private_implementation__is_decimal_digit(*p)) {
14267         exp_num = (10 * exp_num) + ((uint8_t)(*p - '0'));
14268         p++;
14269       }
14270       if (wuffs_base__private_implementation__is_decimal_digit(*p)) {
14271         exp_num = (10 * exp_num) + ((uint8_t)(*p - '0'));
14272         p++;
14273       }
14274       while (wuffs_base__private_implementation__is_decimal_digit(*p)) {
14275         if (exp_num > 0x1000000) {
14276           goto fallback;
14277         }
14278         exp_num = (10 * exp_num) + ((uint8_t)(*p - '0'));
14279         p++;
14280       }
14281       exp10 += exp_sign * exp_num;
14282     }
14283 
14284     // The Wuffs API is that the original slice has no trailing data. It also
14285     // allows underscores, which we don't catch here but the fallback should.
14286     if (p != &z[s.len]) {
14287       goto fallback;
14288     }
14289 
14290     // Check that the uint64_t typed man variable has not overflowed, based on
14291     // digit_count.
14292     //
14293     // For reference:
14294     //   - (1 << 63) is  9223372036854775808, which has 19 decimal digits.
14295     //   - (1 << 64) is 18446744073709551616, which has 20 decimal digits.
14296     //   - 19 nines,  9999999999999999999, is  0x8AC7230489E7FFFF, which has 64
14297     //     bits and 16 hexadecimal digits.
14298     //   - 20 nines, 99999999999999999999, is 0x56BC75E2D630FFFFF, which has 67
14299     //     bits and 17 hexadecimal digits.
14300     if (digit_count > 19) {
14301       // Even if we have more than 19 pseudo-digits, it's not yet definitely an
14302       // overflow. Recall that digit_count might be off-by-one (too large) if
14303       // there's a decimal separator. It will also over-report the number of
14304       // meaningful digits if the input looks something like "0.000dddExxx".
14305       //
14306       // We adjust by the number of leading '0's and '.'s and re-compare to 19.
14307       // Once again, technically, we could skip ','s too, but that perturbs the
14308       // "script/process-json-numbers.c with -p" benchmark.
14309       const uint8_t* q = start_of_digits_ptr;
14310       for (; (*q == '0') || (*q == '.'); q++) {
14311       }
14312       digit_count -= (uint32_t)(q - start_of_digits_ptr);
14313       if (digit_count > 19) {
14314         goto fallback;
14315       }
14316     }
14317 
14318     // The wuffs_base__private_implementation__parse_number_f64_eisel_lemire
14319     // preconditions include that exp10 is in the range [-307 ..= 288].
14320     if ((exp10 < -307) || (288 < exp10)) {
14321       goto fallback;
14322     }
14323 
14324     // If both man and (10 ** exp10) are exactly representable by a double, we
14325     // don't need to run the Eisel-Lemire algorithm.
14326     if ((-22 <= exp10) && (exp10 <= 22) && ((man >> 53) == 0)) {
14327       double d = (double)man;
14328       if (exp10 >= 0) {
14329         d *= wuffs_base__private_implementation__f64_powers_of_10[+exp10];
14330       } else {
14331         d /= wuffs_base__private_implementation__f64_powers_of_10[-exp10];
14332       }
14333       wuffs_base__result_f64 ret;
14334       ret.status.repr = NULL;
14335       ret.value = negative ? -d : +d;
14336       return ret;
14337     }
14338 
14339     // The wuffs_base__private_implementation__parse_number_f64_eisel_lemire
14340     // preconditions include that man is non-zero. Parsing "0" should be caught
14341     // by the "If both man and (10 ** exp10)" above, but "0e99" might not.
14342     if (man == 0) {
14343       goto fallback;
14344     }
14345 
14346     // Our man and exp10 are in range. Run the Eisel-Lemire algorithm.
14347     int64_t r =
14348         wuffs_base__private_implementation__parse_number_f64_eisel_lemire(
14349             man, exp10);
14350     if (r < 0) {
14351       goto fallback;
14352     }
14353     wuffs_base__result_f64 ret;
14354     ret.status.repr = NULL;
14355     ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
14356         ((uint64_t)r) | (((uint64_t)negative) << 63));
14357     return ret;
14358   } while (0);
14359 
14360 fallback:
14361   do {
14362     wuffs_base__private_implementation__high_prec_dec h;
14363     wuffs_base__status status =
14364         wuffs_base__private_implementation__high_prec_dec__parse(&h, s,
14365                                                                  options);
14366     if (status.repr) {
14367       return wuffs_base__private_implementation__parse_number_f64_special(
14368           s, options);
14369     }
14370     return wuffs_base__private_implementation__high_prec_dec__to_f64(&h,
14371                                                                      options);
14372   } while (0);
14373 }
14374 
14375 // --------
14376 
14377 static inline size_t  //
wuffs_base__private_implementation__render_inf(wuffs_base__slice_u8 dst,bool neg,uint32_t options)14378 wuffs_base__private_implementation__render_inf(wuffs_base__slice_u8 dst,
14379                                                bool neg,
14380                                                uint32_t options) {
14381   if (neg) {
14382     if (dst.len < 4) {
14383       return 0;
14384     }
14385     wuffs_base__poke_u32le__no_bounds_check(dst.ptr, 0x666E492D);  // '-Inf'le.
14386     return 4;
14387   }
14388 
14389   if (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN) {
14390     if (dst.len < 4) {
14391       return 0;
14392     }
14393     wuffs_base__poke_u32le__no_bounds_check(dst.ptr, 0x666E492B);  // '+Inf'le.
14394     return 4;
14395   }
14396 
14397   if (dst.len < 3) {
14398     return 0;
14399   }
14400   wuffs_base__poke_u24le__no_bounds_check(dst.ptr, 0x666E49);  // 'Inf'le.
14401   return 3;
14402 }
14403 
14404 static inline size_t  //
wuffs_base__private_implementation__render_nan(wuffs_base__slice_u8 dst)14405 wuffs_base__private_implementation__render_nan(wuffs_base__slice_u8 dst) {
14406   if (dst.len < 3) {
14407     return 0;
14408   }
14409   wuffs_base__poke_u24le__no_bounds_check(dst.ptr, 0x4E614E);  // 'NaN'le.
14410   return 3;
14411 }
14412 
14413 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)14414 wuffs_base__private_implementation__high_prec_dec__render_exponent_absent(
14415     wuffs_base__slice_u8 dst,
14416     wuffs_base__private_implementation__high_prec_dec* h,
14417     uint32_t precision,
14418     uint32_t options) {
14419   size_t n = (h->negative ||
14420               (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN))
14421                  ? 1
14422                  : 0;
14423   if (h->decimal_point <= 0) {
14424     n += 1;
14425   } else {
14426     n += (size_t)(h->decimal_point);
14427   }
14428   if (precision > 0) {
14429     n += precision + 1;  // +1 for the '.'.
14430   }
14431 
14432   // Don't modify dst if the formatted number won't fit.
14433   if (n > dst.len) {
14434     return 0;
14435   }
14436 
14437   // Align-left or align-right.
14438   uint8_t* ptr = (options & WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT)
14439                      ? &dst.ptr[dst.len - n]
14440                      : &dst.ptr[0];
14441 
14442   // Leading "±".
14443   if (h->negative) {
14444     *ptr++ = '-';
14445   } else if (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN) {
14446     *ptr++ = '+';
14447   }
14448 
14449   // Integral digits.
14450   if (h->decimal_point <= 0) {
14451     *ptr++ = '0';
14452   } else {
14453     uint32_t m =
14454         wuffs_base__u32__min(h->num_digits, (uint32_t)(h->decimal_point));
14455     uint32_t i = 0;
14456     for (; i < m; i++) {
14457       *ptr++ = (uint8_t)('0' | h->digits[i]);
14458     }
14459     for (; i < (uint32_t)(h->decimal_point); i++) {
14460       *ptr++ = '0';
14461     }
14462   }
14463 
14464   // Separator and then fractional digits.
14465   if (precision > 0) {
14466     *ptr++ =
14467         (options & WUFFS_BASE__RENDER_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)
14468             ? ','
14469             : '.';
14470     uint32_t i = 0;
14471     for (; i < precision; i++) {
14472       uint32_t j = ((uint32_t)(h->decimal_point)) + i;
14473       *ptr++ = (uint8_t)('0' | ((j < h->num_digits) ? h->digits[j] : 0));
14474     }
14475   }
14476 
14477   return n;
14478 }
14479 
14480 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)14481 wuffs_base__private_implementation__high_prec_dec__render_exponent_present(
14482     wuffs_base__slice_u8 dst,
14483     wuffs_base__private_implementation__high_prec_dec* h,
14484     uint32_t precision,
14485     uint32_t options) {
14486   int32_t exp = 0;
14487   if (h->num_digits > 0) {
14488     exp = h->decimal_point - 1;
14489   }
14490   bool negative_exp = exp < 0;
14491   if (negative_exp) {
14492     exp = -exp;
14493   }
14494 
14495   size_t n = (h->negative ||
14496               (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN))
14497                  ? 4
14498                  : 3;  // Mininum 3 bytes: first digit and then "e±".
14499   if (precision > 0) {
14500     n += precision + 1;  // +1 for the '.'.
14501   }
14502   n += (exp < 100) ? 2 : 3;
14503 
14504   // Don't modify dst if the formatted number won't fit.
14505   if (n > dst.len) {
14506     return 0;
14507   }
14508 
14509   // Align-left or align-right.
14510   uint8_t* ptr = (options & WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT)
14511                      ? &dst.ptr[dst.len - n]
14512                      : &dst.ptr[0];
14513 
14514   // Leading "±".
14515   if (h->negative) {
14516     *ptr++ = '-';
14517   } else if (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN) {
14518     *ptr++ = '+';
14519   }
14520 
14521   // Integral digit.
14522   if (h->num_digits > 0) {
14523     *ptr++ = (uint8_t)('0' | h->digits[0]);
14524   } else {
14525     *ptr++ = '0';
14526   }
14527 
14528   // Separator and then fractional digits.
14529   if (precision > 0) {
14530     *ptr++ =
14531         (options & WUFFS_BASE__RENDER_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)
14532             ? ','
14533             : '.';
14534     uint32_t i = 1;
14535     uint32_t j = wuffs_base__u32__min(h->num_digits, precision + 1);
14536     for (; i < j; i++) {
14537       *ptr++ = (uint8_t)('0' | h->digits[i]);
14538     }
14539     for (; i <= precision; i++) {
14540       *ptr++ = '0';
14541     }
14542   }
14543 
14544   // Exponent: "e±" and then 2 or 3 digits.
14545   *ptr++ = 'e';
14546   *ptr++ = negative_exp ? '-' : '+';
14547   if (exp < 10) {
14548     *ptr++ = '0';
14549     *ptr++ = (uint8_t)('0' | exp);
14550   } else if (exp < 100) {
14551     *ptr++ = (uint8_t)('0' | (exp / 10));
14552     *ptr++ = (uint8_t)('0' | (exp % 10));
14553   } else {
14554     int32_t e = exp / 100;
14555     exp -= e * 100;
14556     *ptr++ = (uint8_t)('0' | e);
14557     *ptr++ = (uint8_t)('0' | (exp / 10));
14558     *ptr++ = (uint8_t)('0' | (exp % 10));
14559   }
14560 
14561   return n;
14562 }
14563 
14564 WUFFS_BASE__MAYBE_STATIC size_t  //
wuffs_base__render_number_f64(wuffs_base__slice_u8 dst,double x,uint32_t precision,uint32_t options)14565 wuffs_base__render_number_f64(wuffs_base__slice_u8 dst,
14566                               double x,
14567                               uint32_t precision,
14568                               uint32_t options) {
14569   // Decompose x (64 bits) into negativity (1 bit), base-2 exponent (11 bits
14570   // with a -1023 bias) and mantissa (52 bits).
14571   uint64_t bits = wuffs_base__ieee_754_bit_representation__from_f64_to_u64(x);
14572   bool neg = (bits >> 63) != 0;
14573   int32_t exp2 = ((int32_t)(bits >> 52)) & 0x7FF;
14574   uint64_t man = bits & 0x000FFFFFFFFFFFFFul;
14575 
14576   // Apply the exponent bias and set the implicit top bit of the mantissa,
14577   // unless x is subnormal. Also take care of Inf and NaN.
14578   if (exp2 == 0x7FF) {
14579     if (man != 0) {
14580       return wuffs_base__private_implementation__render_nan(dst);
14581     }
14582     return wuffs_base__private_implementation__render_inf(dst, neg, options);
14583   } else if (exp2 == 0) {
14584     exp2 = -1022;
14585   } else {
14586     exp2 -= 1023;
14587     man |= 0x0010000000000000ul;
14588   }
14589 
14590   // Ensure that precision isn't too large.
14591   if (precision > 4095) {
14592     precision = 4095;
14593   }
14594 
14595   // Convert from the (neg, exp2, man) tuple to an HPD.
14596   wuffs_base__private_implementation__high_prec_dec h;
14597   wuffs_base__private_implementation__high_prec_dec__assign(&h, man, neg);
14598   if (h.num_digits > 0) {
14599     wuffs_base__private_implementation__high_prec_dec__lshift(
14600         &h, exp2 - 52);  // 52 mantissa bits.
14601   }
14602 
14603   // Handle the "%e" and "%f" formats.
14604   switch (options & (WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_ABSENT |
14605                      WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_PRESENT)) {
14606     case WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_ABSENT:  // The "%"f" format.
14607       if (options & WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION) {
14608         wuffs_base__private_implementation__high_prec_dec__round_just_enough(
14609             &h, exp2, man);
14610         int32_t p = ((int32_t)(h.num_digits)) - h.decimal_point;
14611         precision = ((uint32_t)(wuffs_base__i32__max(0, p)));
14612       } else {
14613         wuffs_base__private_implementation__high_prec_dec__round_nearest(
14614             &h, ((int32_t)precision) + h.decimal_point);
14615       }
14616       return wuffs_base__private_implementation__high_prec_dec__render_exponent_absent(
14617           dst, &h, precision, options);
14618 
14619     case WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_PRESENT:  // The "%e" format.
14620       if (options & WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION) {
14621         wuffs_base__private_implementation__high_prec_dec__round_just_enough(
14622             &h, exp2, man);
14623         precision = (h.num_digits > 0) ? (h.num_digits - 1) : 0;
14624       } else {
14625         wuffs_base__private_implementation__high_prec_dec__round_nearest(
14626             &h, ((int32_t)precision) + 1);
14627       }
14628       return wuffs_base__private_implementation__high_prec_dec__render_exponent_present(
14629           dst, &h, precision, options);
14630   }
14631 
14632   // We have the "%g" format and so precision means the number of significant
14633   // digits, not the number of digits after the decimal separator. Perform
14634   // rounding and determine whether to use "%e" or "%f".
14635   int32_t e_threshold = 0;
14636   if (options & WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION) {
14637     wuffs_base__private_implementation__high_prec_dec__round_just_enough(
14638         &h, exp2, man);
14639     precision = h.num_digits;
14640     e_threshold = 6;
14641   } else {
14642     if (precision == 0) {
14643       precision = 1;
14644     }
14645     wuffs_base__private_implementation__high_prec_dec__round_nearest(
14646         &h, ((int32_t)precision));
14647     e_threshold = ((int32_t)precision);
14648     int32_t nd = ((int32_t)(h.num_digits));
14649     if ((e_threshold > nd) && (nd >= h.decimal_point)) {
14650       e_threshold = nd;
14651     }
14652   }
14653 
14654   // Use the "%e" format if the exponent is large.
14655   int32_t e = h.decimal_point - 1;
14656   if ((e < -4) || (e_threshold <= e)) {
14657     uint32_t p = wuffs_base__u32__min(precision, h.num_digits);
14658     return wuffs_base__private_implementation__high_prec_dec__render_exponent_present(
14659         dst, &h, (p > 0) ? (p - 1) : 0, options);
14660   }
14661 
14662   // Use the "%f" format otherwise.
14663   int32_t p = ((int32_t)precision);
14664   if (p > h.decimal_point) {
14665     p = ((int32_t)(h.num_digits));
14666   }
14667   precision = ((uint32_t)(wuffs_base__i32__max(0, p - h.decimal_point)));
14668   return wuffs_base__private_implementation__high_prec_dec__render_exponent_absent(
14669       dst, &h, precision, options);
14670 }
14671 
14672 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
14673         // defined(WUFFS_CONFIG__MODULE__BASE) ||
14674         // defined(WUFFS_CONFIG__MODULE__BASE__FLOATCONV)
14675 
14676 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
14677     defined(WUFFS_CONFIG__MODULE__BASE__INTCONV)
14678 
14679 // ---------------- Integer
14680 
14681 // wuffs_base__parse_number__foo_digits entries are 0x00 for invalid digits,
14682 // and (0x80 | v) for valid digits, where v is the 4 bit value.
14683 
14684 static const uint8_t wuffs_base__parse_number__decimal_digits[256] = {
14685     // 0     1     2     3     4     5     6     7
14686     // 8     9     A     B     C     D     E     F
14687     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x00 ..= 0x07.
14688     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x08 ..= 0x0F.
14689     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x10 ..= 0x17.
14690     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x18 ..= 0x1F.
14691     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x20 ..= 0x27.
14692     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x28 ..= 0x2F.
14693     0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,  // 0x30 ..= 0x37. '0'-'7'.
14694     0x88, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x38 ..= 0x3F. '8'-'9'.
14695 
14696     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x40 ..= 0x47.
14697     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x48 ..= 0x4F.
14698     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x50 ..= 0x57.
14699     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x58 ..= 0x5F.
14700     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x60 ..= 0x67.
14701     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x68 ..= 0x6F.
14702     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x70 ..= 0x77.
14703     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x78 ..= 0x7F.
14704 
14705     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x80 ..= 0x87.
14706     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x88 ..= 0x8F.
14707     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x90 ..= 0x97.
14708     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x98 ..= 0x9F.
14709     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xA0 ..= 0xA7.
14710     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xA8 ..= 0xAF.
14711     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xB0 ..= 0xB7.
14712     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xB8 ..= 0xBF.
14713 
14714     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xC0 ..= 0xC7.
14715     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xC8 ..= 0xCF.
14716     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xD0 ..= 0xD7.
14717     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xD8 ..= 0xDF.
14718     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xE0 ..= 0xE7.
14719     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xE8 ..= 0xEF.
14720     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xF0 ..= 0xF7.
14721     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xF8 ..= 0xFF.
14722     // 0     1     2     3     4     5     6     7
14723     // 8     9     A     B     C     D     E     F
14724 };
14725 
14726 static const uint8_t wuffs_base__parse_number__hexadecimal_digits[256] = {
14727     // 0     1     2     3     4     5     6     7
14728     // 8     9     A     B     C     D     E     F
14729     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x00 ..= 0x07.
14730     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x08 ..= 0x0F.
14731     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x10 ..= 0x17.
14732     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x18 ..= 0x1F.
14733     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x20 ..= 0x27.
14734     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x28 ..= 0x2F.
14735     0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,  // 0x30 ..= 0x37. '0'-'7'.
14736     0x88, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x38 ..= 0x3F. '8'-'9'.
14737 
14738     0x00, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x00,  // 0x40 ..= 0x47. 'A'-'F'.
14739     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x48 ..= 0x4F.
14740     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x50 ..= 0x57.
14741     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x58 ..= 0x5F.
14742     0x00, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x00,  // 0x60 ..= 0x67. 'a'-'f'.
14743     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x68 ..= 0x6F.
14744     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x70 ..= 0x77.
14745     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x78 ..= 0x7F.
14746 
14747     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x80 ..= 0x87.
14748     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x88 ..= 0x8F.
14749     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x90 ..= 0x97.
14750     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x98 ..= 0x9F.
14751     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xA0 ..= 0xA7.
14752     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xA8 ..= 0xAF.
14753     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xB0 ..= 0xB7.
14754     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xB8 ..= 0xBF.
14755 
14756     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xC0 ..= 0xC7.
14757     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xC8 ..= 0xCF.
14758     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xD0 ..= 0xD7.
14759     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xD8 ..= 0xDF.
14760     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xE0 ..= 0xE7.
14761     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xE8 ..= 0xEF.
14762     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xF0 ..= 0xF7.
14763     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xF8 ..= 0xFF.
14764     // 0     1     2     3     4     5     6     7
14765     // 8     9     A     B     C     D     E     F
14766 };
14767 
14768 static const uint8_t wuffs_base__private_implementation__encode_base16[16] = {
14769     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,  // 0x00 ..= 0x07.
14770     0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,  // 0x08 ..= 0x0F.
14771 };
14772 
14773 // --------
14774 
14775 WUFFS_BASE__MAYBE_STATIC wuffs_base__result_i64  //
wuffs_base__parse_number_i64(wuffs_base__slice_u8 s,uint32_t options)14776 wuffs_base__parse_number_i64(wuffs_base__slice_u8 s, uint32_t options) {
14777   uint8_t* p = s.ptr;
14778   uint8_t* q = s.ptr + s.len;
14779 
14780   if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
14781     for (; (p < q) && (*p == '_'); p++) {
14782     }
14783   }
14784 
14785   bool negative = false;
14786   if (p >= q) {
14787     goto fail_bad_argument;
14788   } else if (*p == '-') {
14789     p++;
14790     negative = true;
14791   } else if (*p == '+') {
14792     p++;
14793   }
14794 
14795   do {
14796     wuffs_base__result_u64 r = wuffs_base__parse_number_u64(
14797         wuffs_base__make_slice_u8(p, (size_t)(q - p)), options);
14798     if (r.status.repr != NULL) {
14799       wuffs_base__result_i64 ret;
14800       ret.status.repr = r.status.repr;
14801       ret.value = 0;
14802       return ret;
14803     } else if (negative) {
14804       if (r.value < 0x8000000000000000) {
14805         wuffs_base__result_i64 ret;
14806         ret.status.repr = NULL;
14807         ret.value = -(int64_t)(r.value);
14808         return ret;
14809       } else if (r.value == 0x8000000000000000) {
14810         wuffs_base__result_i64 ret;
14811         ret.status.repr = NULL;
14812         ret.value = INT64_MIN;
14813         return ret;
14814       }
14815       goto fail_out_of_bounds;
14816     } else if (r.value > 0x7FFFFFFFFFFFFFFF) {
14817       goto fail_out_of_bounds;
14818     } else {
14819       wuffs_base__result_i64 ret;
14820       ret.status.repr = NULL;
14821       ret.value = +(int64_t)(r.value);
14822       return ret;
14823     }
14824   } while (0);
14825 
14826 fail_bad_argument:
14827   do {
14828     wuffs_base__result_i64 ret;
14829     ret.status.repr = wuffs_base__error__bad_argument;
14830     ret.value = 0;
14831     return ret;
14832   } while (0);
14833 
14834 fail_out_of_bounds:
14835   do {
14836     wuffs_base__result_i64 ret;
14837     ret.status.repr = wuffs_base__error__out_of_bounds;
14838     ret.value = 0;
14839     return ret;
14840   } while (0);
14841 }
14842 
14843 WUFFS_BASE__MAYBE_STATIC wuffs_base__result_u64  //
wuffs_base__parse_number_u64(wuffs_base__slice_u8 s,uint32_t options)14844 wuffs_base__parse_number_u64(wuffs_base__slice_u8 s, uint32_t options) {
14845   uint8_t* p = s.ptr;
14846   uint8_t* q = s.ptr + s.len;
14847 
14848   if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
14849     for (; (p < q) && (*p == '_'); p++) {
14850     }
14851   }
14852 
14853   if (p >= q) {
14854     goto fail_bad_argument;
14855 
14856   } else if (*p == '0') {
14857     p++;
14858     if (p >= q) {
14859       goto ok_zero;
14860     }
14861     if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
14862       if (*p == '_') {
14863         p++;
14864         for (; p < q; p++) {
14865           if (*p != '_') {
14866             if (options &
14867                 WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_MULTIPLE_LEADING_ZEROES) {
14868               goto decimal;
14869             }
14870             goto fail_bad_argument;
14871           }
14872         }
14873         goto ok_zero;
14874       }
14875     }
14876 
14877     if ((*p == 'x') || (*p == 'X')) {
14878       p++;
14879       if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
14880         for (; (p < q) && (*p == '_'); p++) {
14881         }
14882       }
14883       if (p < q) {
14884         goto hexadecimal;
14885       }
14886 
14887     } else if ((*p == 'd') || (*p == 'D')) {
14888       p++;
14889       if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
14890         for (; (p < q) && (*p == '_'); p++) {
14891         }
14892       }
14893       if (p < q) {
14894         goto decimal;
14895       }
14896     }
14897 
14898     if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_MULTIPLE_LEADING_ZEROES) {
14899       goto decimal;
14900     }
14901     goto fail_bad_argument;
14902   }
14903 
14904 decimal:
14905   do {
14906     uint64_t v = wuffs_base__parse_number__decimal_digits[*p++];
14907     if (v == 0) {
14908       goto fail_bad_argument;
14909     }
14910     v &= 0x0F;
14911 
14912     // UINT64_MAX is 18446744073709551615, which is ((10 * max10) + max1).
14913     const uint64_t max10 = 1844674407370955161u;
14914     const uint8_t max1 = 5;
14915 
14916     for (; p < q; p++) {
14917       if ((*p == '_') &&
14918           (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) {
14919         continue;
14920       }
14921       uint8_t digit = wuffs_base__parse_number__decimal_digits[*p];
14922       if (digit == 0) {
14923         goto fail_bad_argument;
14924       }
14925       digit &= 0x0F;
14926       if ((v > max10) || ((v == max10) && (digit > max1))) {
14927         goto fail_out_of_bounds;
14928       }
14929       v = (10 * v) + ((uint64_t)(digit));
14930     }
14931 
14932     wuffs_base__result_u64 ret;
14933     ret.status.repr = NULL;
14934     ret.value = v;
14935     return ret;
14936   } while (0);
14937 
14938 hexadecimal:
14939   do {
14940     uint64_t v = wuffs_base__parse_number__hexadecimal_digits[*p++];
14941     if (v == 0) {
14942       goto fail_bad_argument;
14943     }
14944     v &= 0x0F;
14945 
14946     for (; p < q; p++) {
14947       if ((*p == '_') &&
14948           (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) {
14949         continue;
14950       }
14951       uint8_t digit = wuffs_base__parse_number__hexadecimal_digits[*p];
14952       if (digit == 0) {
14953         goto fail_bad_argument;
14954       }
14955       digit &= 0x0F;
14956       if ((v >> 60) != 0) {
14957         goto fail_out_of_bounds;
14958       }
14959       v = (v << 4) | ((uint64_t)(digit));
14960     }
14961 
14962     wuffs_base__result_u64 ret;
14963     ret.status.repr = NULL;
14964     ret.value = v;
14965     return ret;
14966   } while (0);
14967 
14968 ok_zero:
14969   do {
14970     wuffs_base__result_u64 ret;
14971     ret.status.repr = NULL;
14972     ret.value = 0;
14973     return ret;
14974   } while (0);
14975 
14976 fail_bad_argument:
14977   do {
14978     wuffs_base__result_u64 ret;
14979     ret.status.repr = wuffs_base__error__bad_argument;
14980     ret.value = 0;
14981     return ret;
14982   } while (0);
14983 
14984 fail_out_of_bounds:
14985   do {
14986     wuffs_base__result_u64 ret;
14987     ret.status.repr = wuffs_base__error__out_of_bounds;
14988     ret.value = 0;
14989     return ret;
14990   } while (0);
14991 }
14992 
14993 // --------
14994 
14995 // wuffs_base__render_number__first_hundred contains the decimal encodings of
14996 // the first one hundred numbers [0 ..= 99].
14997 static const uint8_t wuffs_base__render_number__first_hundred[200] = {
14998     '0', '0', '0', '1', '0', '2', '0', '3', '0', '4',  //
14999     '0', '5', '0', '6', '0', '7', '0', '8', '0', '9',  //
15000     '1', '0', '1', '1', '1', '2', '1', '3', '1', '4',  //
15001     '1', '5', '1', '6', '1', '7', '1', '8', '1', '9',  //
15002     '2', '0', '2', '1', '2', '2', '2', '3', '2', '4',  //
15003     '2', '5', '2', '6', '2', '7', '2', '8', '2', '9',  //
15004     '3', '0', '3', '1', '3', '2', '3', '3', '3', '4',  //
15005     '3', '5', '3', '6', '3', '7', '3', '8', '3', '9',  //
15006     '4', '0', '4', '1', '4', '2', '4', '3', '4', '4',  //
15007     '4', '5', '4', '6', '4', '7', '4', '8', '4', '9',  //
15008     '5', '0', '5', '1', '5', '2', '5', '3', '5', '4',  //
15009     '5', '5', '5', '6', '5', '7', '5', '8', '5', '9',  //
15010     '6', '0', '6', '1', '6', '2', '6', '3', '6', '4',  //
15011     '6', '5', '6', '6', '6', '7', '6', '8', '6', '9',  //
15012     '7', '0', '7', '1', '7', '2', '7', '3', '7', '4',  //
15013     '7', '5', '7', '6', '7', '7', '7', '8', '7', '9',  //
15014     '8', '0', '8', '1', '8', '2', '8', '3', '8', '4',  //
15015     '8', '5', '8', '6', '8', '7', '8', '8', '8', '9',  //
15016     '9', '0', '9', '1', '9', '2', '9', '3', '9', '4',  //
15017     '9', '5', '9', '6', '9', '7', '9', '8', '9', '9',  //
15018 };
15019 
15020 static size_t  //
wuffs_base__private_implementation__render_number_u64(wuffs_base__slice_u8 dst,uint64_t x,uint32_t options,bool neg)15021 wuffs_base__private_implementation__render_number_u64(wuffs_base__slice_u8 dst,
15022                                                       uint64_t x,
15023                                                       uint32_t options,
15024                                                       bool neg) {
15025   uint8_t buf[WUFFS_BASE__U64__BYTE_LENGTH__MAX_INCL];
15026   uint8_t* ptr = &buf[0] + sizeof(buf);
15027 
15028   while (x >= 100) {
15029     size_t index = ((size_t)((x % 100) * 2));
15030     x /= 100;
15031     uint8_t s0 = wuffs_base__render_number__first_hundred[index + 0];
15032     uint8_t s1 = wuffs_base__render_number__first_hundred[index + 1];
15033     ptr -= 2;
15034     ptr[0] = s0;
15035     ptr[1] = s1;
15036   }
15037 
15038   if (x < 10) {
15039     ptr -= 1;
15040     ptr[0] = (uint8_t)('0' + x);
15041   } else {
15042     size_t index = ((size_t)(x * 2));
15043     uint8_t s0 = wuffs_base__render_number__first_hundred[index + 0];
15044     uint8_t s1 = wuffs_base__render_number__first_hundred[index + 1];
15045     ptr -= 2;
15046     ptr[0] = s0;
15047     ptr[1] = s1;
15048   }
15049 
15050   if (neg) {
15051     ptr -= 1;
15052     ptr[0] = '-';
15053   } else if (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN) {
15054     ptr -= 1;
15055     ptr[0] = '+';
15056   }
15057 
15058   size_t n = sizeof(buf) - ((size_t)(ptr - &buf[0]));
15059   if (n > dst.len) {
15060     return 0;
15061   }
15062   memcpy(dst.ptr + ((options & WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT)
15063                         ? (dst.len - n)
15064                         : 0),
15065          ptr, n);
15066   return n;
15067 }
15068 
15069 WUFFS_BASE__MAYBE_STATIC size_t  //
wuffs_base__render_number_i64(wuffs_base__slice_u8 dst,int64_t x,uint32_t options)15070 wuffs_base__render_number_i64(wuffs_base__slice_u8 dst,
15071                               int64_t x,
15072                               uint32_t options) {
15073   uint64_t u = (uint64_t)x;
15074   bool neg = x < 0;
15075   if (neg) {
15076     u = 1 + ~u;
15077   }
15078   return wuffs_base__private_implementation__render_number_u64(dst, u, options,
15079                                                                neg);
15080 }
15081 
15082 WUFFS_BASE__MAYBE_STATIC size_t  //
wuffs_base__render_number_u64(wuffs_base__slice_u8 dst,uint64_t x,uint32_t options)15083 wuffs_base__render_number_u64(wuffs_base__slice_u8 dst,
15084                               uint64_t x,
15085                               uint32_t options) {
15086   return wuffs_base__private_implementation__render_number_u64(dst, x, options,
15087                                                                false);
15088 }
15089 
15090 // ---------------- Base-16
15091 
15092 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)15093 wuffs_base__base_16__decode2(wuffs_base__slice_u8 dst,
15094                              wuffs_base__slice_u8 src,
15095                              bool src_closed,
15096                              uint32_t options) {
15097   wuffs_base__transform__output o;
15098   size_t src_len2 = src.len / 2;
15099   size_t len;
15100   if (dst.len < src_len2) {
15101     len = dst.len;
15102     o.status.repr = wuffs_base__suspension__short_write;
15103   } else {
15104     len = src_len2;
15105     if (!src_closed) {
15106       o.status.repr = wuffs_base__suspension__short_read;
15107     } else if (src.len & 1) {
15108       o.status.repr = wuffs_base__error__bad_data;
15109     } else {
15110       o.status.repr = NULL;
15111     }
15112   }
15113 
15114   uint8_t* d = dst.ptr;
15115   uint8_t* s = src.ptr;
15116   size_t n = len;
15117 
15118   while (n--) {
15119     *d = (uint8_t)((wuffs_base__parse_number__hexadecimal_digits[s[0]] << 4) |
15120                    (wuffs_base__parse_number__hexadecimal_digits[s[1]] & 0x0F));
15121     d += 1;
15122     s += 2;
15123   }
15124 
15125   o.num_dst = len;
15126   o.num_src = len * 2;
15127   return o;
15128 }
15129 
15130 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)15131 wuffs_base__base_16__decode4(wuffs_base__slice_u8 dst,
15132                              wuffs_base__slice_u8 src,
15133                              bool src_closed,
15134                              uint32_t options) {
15135   wuffs_base__transform__output o;
15136   size_t src_len4 = src.len / 4;
15137   size_t len = dst.len < src_len4 ? dst.len : src_len4;
15138   if (dst.len < src_len4) {
15139     len = dst.len;
15140     o.status.repr = wuffs_base__suspension__short_write;
15141   } else {
15142     len = src_len4;
15143     if (!src_closed) {
15144       o.status.repr = wuffs_base__suspension__short_read;
15145     } else if (src.len & 1) {
15146       o.status.repr = wuffs_base__error__bad_data;
15147     } else {
15148       o.status.repr = NULL;
15149     }
15150   }
15151 
15152   uint8_t* d = dst.ptr;
15153   uint8_t* s = src.ptr;
15154   size_t n = len;
15155 
15156   while (n--) {
15157     *d = (uint8_t)((wuffs_base__parse_number__hexadecimal_digits[s[2]] << 4) |
15158                    (wuffs_base__parse_number__hexadecimal_digits[s[3]] & 0x0F));
15159     d += 1;
15160     s += 4;
15161   }
15162 
15163   o.num_dst = len;
15164   o.num_src = len * 4;
15165   return o;
15166 }
15167 
15168 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)15169 wuffs_base__base_16__encode2(wuffs_base__slice_u8 dst,
15170                              wuffs_base__slice_u8 src,
15171                              bool src_closed,
15172                              uint32_t options) {
15173   wuffs_base__transform__output o;
15174   size_t dst_len2 = dst.len / 2;
15175   size_t len;
15176   if (dst_len2 < src.len) {
15177     len = dst_len2;
15178     o.status.repr = wuffs_base__suspension__short_write;
15179   } else {
15180     len = src.len;
15181     if (!src_closed) {
15182       o.status.repr = wuffs_base__suspension__short_read;
15183     } else {
15184       o.status.repr = NULL;
15185     }
15186   }
15187 
15188   uint8_t* d = dst.ptr;
15189   uint8_t* s = src.ptr;
15190   size_t n = len;
15191 
15192   while (n--) {
15193     uint8_t c = *s;
15194     d[0] = wuffs_base__private_implementation__encode_base16[c >> 4];
15195     d[1] = wuffs_base__private_implementation__encode_base16[c & 0x0F];
15196     d += 2;
15197     s += 1;
15198   }
15199 
15200   o.num_dst = len * 2;
15201   o.num_src = len;
15202   return o;
15203 }
15204 
15205 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)15206 wuffs_base__base_16__encode4(wuffs_base__slice_u8 dst,
15207                              wuffs_base__slice_u8 src,
15208                              bool src_closed,
15209                              uint32_t options) {
15210   wuffs_base__transform__output o;
15211   size_t dst_len4 = dst.len / 4;
15212   size_t len;
15213   if (dst_len4 < src.len) {
15214     len = dst_len4;
15215     o.status.repr = wuffs_base__suspension__short_write;
15216   } else {
15217     len = src.len;
15218     if (!src_closed) {
15219       o.status.repr = wuffs_base__suspension__short_read;
15220     } else {
15221       o.status.repr = NULL;
15222     }
15223   }
15224 
15225   uint8_t* d = dst.ptr;
15226   uint8_t* s = src.ptr;
15227   size_t n = len;
15228 
15229   while (n--) {
15230     uint8_t c = *s;
15231     d[0] = '\\';
15232     d[1] = 'x';
15233     d[2] = wuffs_base__private_implementation__encode_base16[c >> 4];
15234     d[3] = wuffs_base__private_implementation__encode_base16[c & 0x0F];
15235     d += 4;
15236     s += 1;
15237   }
15238 
15239   o.num_dst = len * 4;
15240   o.num_src = len;
15241   return o;
15242 }
15243 
15244 // ---------------- Base-64
15245 
15246 // The two base-64 alphabets, std and url, differ only in the last two codes.
15247 //  - std: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
15248 //  - url: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
15249 
15250 static const uint8_t wuffs_base__base_64__decode_std[256] = {
15251     // 0     1     2     3     4     5     6     7
15252     // 8     9     A     B     C     D     E     F
15253     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x00 ..= 0x07.
15254     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x08 ..= 0x0F.
15255     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x10 ..= 0x17.
15256     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x18 ..= 0x1F.
15257     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x20 ..= 0x27.
15258     0x80, 0x80, 0x80, 0x3E, 0x80, 0x80, 0x80, 0x3F,  // 0x28 ..= 0x2F.
15259     0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,  // 0x30 ..= 0x37.
15260     0x3C, 0x3D, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x38 ..= 0x3F.
15261 
15262     0x80, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,  // 0x40 ..= 0x47.
15263     0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,  // 0x48 ..= 0x4F.
15264     0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,  // 0x50 ..= 0x57.
15265     0x17, 0x18, 0x19, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x58 ..= 0x5F.
15266     0x80, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,  // 0x60 ..= 0x67.
15267     0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,  // 0x68 ..= 0x6F.
15268     0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,  // 0x70 ..= 0x77.
15269     0x31, 0x32, 0x33, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x78 ..= 0x7F.
15270 
15271     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x80 ..= 0x87.
15272     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x88 ..= 0x8F.
15273     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x90 ..= 0x97.
15274     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x98 ..= 0x9F.
15275     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xA0 ..= 0xA7.
15276     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xA8 ..= 0xAF.
15277     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xB0 ..= 0xB7.
15278     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xB8 ..= 0xBF.
15279 
15280     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xC0 ..= 0xC7.
15281     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xC8 ..= 0xCF.
15282     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xD0 ..= 0xD7.
15283     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xD8 ..= 0xDF.
15284     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xE0 ..= 0xE7.
15285     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xE8 ..= 0xEF.
15286     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xF0 ..= 0xF7.
15287     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xF8 ..= 0xFF.
15288     // 0     1     2     3     4     5     6     7
15289     // 8     9     A     B     C     D     E     F
15290 };
15291 
15292 static const uint8_t wuffs_base__base_64__decode_url[256] = {
15293     // 0     1     2     3     4     5     6     7
15294     // 8     9     A     B     C     D     E     F
15295     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x00 ..= 0x07.
15296     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x08 ..= 0x0F.
15297     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x10 ..= 0x17.
15298     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x18 ..= 0x1F.
15299     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x20 ..= 0x27.
15300     0x80, 0x80, 0x80, 0x80, 0x80, 0x3E, 0x80, 0x80,  // 0x28 ..= 0x2F.
15301     0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,  // 0x30 ..= 0x37.
15302     0x3C, 0x3D, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x38 ..= 0x3F.
15303 
15304     0x80, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,  // 0x40 ..= 0x47.
15305     0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,  // 0x48 ..= 0x4F.
15306     0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,  // 0x50 ..= 0x57.
15307     0x17, 0x18, 0x19, 0x80, 0x80, 0x80, 0x80, 0x3F,  // 0x58 ..= 0x5F.
15308     0x80, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,  // 0x60 ..= 0x67.
15309     0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,  // 0x68 ..= 0x6F.
15310     0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,  // 0x70 ..= 0x77.
15311     0x31, 0x32, 0x33, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x78 ..= 0x7F.
15312 
15313     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x80 ..= 0x87.
15314     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x88 ..= 0x8F.
15315     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x90 ..= 0x97.
15316     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x98 ..= 0x9F.
15317     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xA0 ..= 0xA7.
15318     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xA8 ..= 0xAF.
15319     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xB0 ..= 0xB7.
15320     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xB8 ..= 0xBF.
15321 
15322     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xC0 ..= 0xC7.
15323     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xC8 ..= 0xCF.
15324     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xD0 ..= 0xD7.
15325     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xD8 ..= 0xDF.
15326     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xE0 ..= 0xE7.
15327     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xE8 ..= 0xEF.
15328     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xF0 ..= 0xF7.
15329     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xF8 ..= 0xFF.
15330     // 0     1     2     3     4     5     6     7
15331     // 8     9     A     B     C     D     E     F
15332 };
15333 
15334 static const uint8_t wuffs_base__base_64__encode_std[64] = {
15335     // 0     1     2     3     4     5     6     7
15336     // 8     9     A     B     C     D     E     F
15337     0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,  // 0x00 ..= 0x07.
15338     0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,  // 0x08 ..= 0x0F.
15339     0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,  // 0x10 ..= 0x17.
15340     0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,  // 0x18 ..= 0x1F.
15341     0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E,  // 0x20 ..= 0x27.
15342     0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,  // 0x28 ..= 0x2F.
15343     0x77, 0x78, 0x79, 0x7A, 0x30, 0x31, 0x32, 0x33,  // 0x30 ..= 0x37.
15344     0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2B, 0x2F,  // 0x38 ..= 0x3F.
15345 };
15346 
15347 static const uint8_t wuffs_base__base_64__encode_url[64] = {
15348     // 0     1     2     3     4     5     6     7
15349     // 8     9     A     B     C     D     E     F
15350     0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,  // 0x00 ..= 0x07.
15351     0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,  // 0x08 ..= 0x0F.
15352     0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,  // 0x10 ..= 0x17.
15353     0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,  // 0x18 ..= 0x1F.
15354     0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E,  // 0x20 ..= 0x27.
15355     0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,  // 0x28 ..= 0x2F.
15356     0x77, 0x78, 0x79, 0x7A, 0x30, 0x31, 0x32, 0x33,  // 0x30 ..= 0x37.
15357     0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2D, 0x5F,  // 0x38 ..= 0x3F.
15358 };
15359 
15360 // --------
15361 
15362 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)15363 wuffs_base__base_64__decode(wuffs_base__slice_u8 dst,
15364                             wuffs_base__slice_u8 src,
15365                             bool src_closed,
15366                             uint32_t options) {
15367   const uint8_t* alphabet = (options & WUFFS_BASE__BASE_64__URL_ALPHABET)
15368                                 ? wuffs_base__base_64__decode_url
15369                                 : wuffs_base__base_64__decode_std;
15370   wuffs_base__transform__output o;
15371   uint8_t* d_ptr = dst.ptr;
15372   size_t d_len = dst.len;
15373   const uint8_t* s_ptr = src.ptr;
15374   size_t s_len = src.len;
15375   bool pad = false;
15376 
15377   while (s_len >= 4) {
15378     uint32_t s = wuffs_base__peek_u32le__no_bounds_check(s_ptr);
15379     uint32_t s0 = alphabet[0xFF & (s >> 0)];
15380     uint32_t s1 = alphabet[0xFF & (s >> 8)];
15381     uint32_t s2 = alphabet[0xFF & (s >> 16)];
15382     uint32_t s3 = alphabet[0xFF & (s >> 24)];
15383 
15384     if (((s0 | s1 | s2 | s3) & 0xC0) != 0) {
15385       if (s_len > 4) {
15386         o.status.repr = wuffs_base__error__bad_data;
15387         goto done;
15388       } else if (!src_closed) {
15389         o.status.repr = wuffs_base__suspension__short_read;
15390         goto done;
15391       } else if ((options & WUFFS_BASE__BASE_64__DECODE_ALLOW_PADDING) &&
15392                  (s_ptr[3] == '=')) {
15393         pad = true;
15394         if (s_ptr[2] == '=') {
15395           goto src2;
15396         }
15397         goto src3;
15398       }
15399       o.status.repr = wuffs_base__error__bad_data;
15400       goto done;
15401     }
15402 
15403     if (d_len < 3) {
15404       o.status.repr = wuffs_base__suspension__short_write;
15405       goto done;
15406     }
15407 
15408     s_ptr += 4;
15409     s_len -= 4;
15410     s = (s0 << 18) | (s1 << 12) | (s2 << 6) | (s3 << 0);
15411     *d_ptr++ = (uint8_t)(s >> 16);
15412     *d_ptr++ = (uint8_t)(s >> 8);
15413     *d_ptr++ = (uint8_t)(s >> 0);
15414     d_len -= 3;
15415   }
15416 
15417   if (!src_closed) {
15418     o.status.repr = wuffs_base__suspension__short_read;
15419     goto done;
15420   }
15421 
15422   if (s_len == 0) {
15423     o.status.repr = NULL;
15424     goto done;
15425   } else if (s_len == 1) {
15426     o.status.repr = wuffs_base__error__bad_data;
15427     goto done;
15428   } else if (s_len == 2) {
15429     goto src2;
15430   }
15431 
15432 src3:
15433   do {
15434     uint32_t s = wuffs_base__peek_u24le__no_bounds_check(s_ptr);
15435     uint32_t s0 = alphabet[0xFF & (s >> 0)];
15436     uint32_t s1 = alphabet[0xFF & (s >> 8)];
15437     uint32_t s2 = alphabet[0xFF & (s >> 16)];
15438     if ((s0 & 0xC0) || (s1 & 0xC0) || (s2 & 0xC3)) {
15439       o.status.repr = wuffs_base__error__bad_data;
15440       goto done;
15441     }
15442     if (d_len < 2) {
15443       o.status.repr = wuffs_base__suspension__short_write;
15444       goto done;
15445     }
15446     s_ptr += pad ? 4 : 3;
15447     s = (s0 << 18) | (s1 << 12) | (s2 << 6);
15448     *d_ptr++ = (uint8_t)(s >> 16);
15449     *d_ptr++ = (uint8_t)(s >> 8);
15450     o.status.repr = NULL;
15451     goto done;
15452   } while (0);
15453 
15454 src2:
15455   do {
15456     uint32_t s = wuffs_base__peek_u16le__no_bounds_check(s_ptr);
15457     uint32_t s0 = alphabet[0xFF & (s >> 0)];
15458     uint32_t s1 = alphabet[0xFF & (s >> 8)];
15459     if ((s0 & 0xC0) || (s1 & 0xCF)) {
15460       o.status.repr = wuffs_base__error__bad_data;
15461       goto done;
15462     }
15463     if (d_len < 1) {
15464       o.status.repr = wuffs_base__suspension__short_write;
15465       goto done;
15466     }
15467     s_ptr += pad ? 4 : 2;
15468     s = (s0 << 18) | (s1 << 12);
15469     *d_ptr++ = (uint8_t)(s >> 16);
15470     o.status.repr = NULL;
15471     goto done;
15472   } while (0);
15473 
15474 done:
15475   o.num_dst = (size_t)(d_ptr - dst.ptr);
15476   o.num_src = (size_t)(s_ptr - src.ptr);
15477   return o;
15478 }
15479 
15480 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)15481 wuffs_base__base_64__encode(wuffs_base__slice_u8 dst,
15482                             wuffs_base__slice_u8 src,
15483                             bool src_closed,
15484                             uint32_t options) {
15485   const uint8_t* alphabet = (options & WUFFS_BASE__BASE_64__URL_ALPHABET)
15486                                 ? wuffs_base__base_64__encode_url
15487                                 : wuffs_base__base_64__encode_std;
15488   wuffs_base__transform__output o;
15489   uint8_t* d_ptr = dst.ptr;
15490   size_t d_len = dst.len;
15491   const uint8_t* s_ptr = src.ptr;
15492   size_t s_len = src.len;
15493 
15494   do {
15495     while (s_len >= 3) {
15496       if (d_len < 4) {
15497         o.status.repr = wuffs_base__suspension__short_write;
15498         goto done;
15499       }
15500       uint32_t s = wuffs_base__peek_u24be__no_bounds_check(s_ptr);
15501       s_ptr += 3;
15502       s_len -= 3;
15503       *d_ptr++ = alphabet[0x3F & (s >> 18)];
15504       *d_ptr++ = alphabet[0x3F & (s >> 12)];
15505       *d_ptr++ = alphabet[0x3F & (s >> 6)];
15506       *d_ptr++ = alphabet[0x3F & (s >> 0)];
15507       d_len -= 4;
15508     }
15509 
15510     if (!src_closed) {
15511       o.status.repr = wuffs_base__suspension__short_read;
15512       goto done;
15513     }
15514 
15515     if (s_len == 2) {
15516       if (d_len <
15517           ((options & WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING) ? 4 : 3)) {
15518         o.status.repr = wuffs_base__suspension__short_write;
15519         goto done;
15520       }
15521       uint32_t s = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(s_ptr)))
15522                    << 8;
15523       s_ptr += 2;
15524       *d_ptr++ = alphabet[0x3F & (s >> 18)];
15525       *d_ptr++ = alphabet[0x3F & (s >> 12)];
15526       *d_ptr++ = alphabet[0x3F & (s >> 6)];
15527       if (options & WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING) {
15528         *d_ptr++ = '=';
15529       }
15530       o.status.repr = NULL;
15531       goto done;
15532 
15533     } else if (s_len == 1) {
15534       if (d_len <
15535           ((options & WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING) ? 4 : 2)) {
15536         o.status.repr = wuffs_base__suspension__short_write;
15537         goto done;
15538       }
15539       uint32_t s = ((uint32_t)(wuffs_base__peek_u8__no_bounds_check(s_ptr)))
15540                    << 16;
15541       s_ptr += 1;
15542       *d_ptr++ = alphabet[0x3F & (s >> 18)];
15543       *d_ptr++ = alphabet[0x3F & (s >> 12)];
15544       if (options & WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING) {
15545         *d_ptr++ = '=';
15546         *d_ptr++ = '=';
15547       }
15548       o.status.repr = NULL;
15549       goto done;
15550 
15551     } else {
15552       o.status.repr = NULL;
15553       goto done;
15554     }
15555   } while (0);
15556 
15557 done:
15558   o.num_dst = (size_t)(d_ptr - dst.ptr);
15559   o.num_src = (size_t)(s_ptr - src.ptr);
15560   return o;
15561 }
15562 
15563 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
15564         // defined(WUFFS_CONFIG__MODULE__BASE) ||
15565         // defined(WUFFS_CONFIG__MODULE__BASE__INTCONV)
15566 
15567 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
15568     defined(WUFFS_CONFIG__MODULE__BASE__MAGIC)
15569 
15570 // ---------------- Magic Numbers
15571 
15572 WUFFS_BASE__MAYBE_STATIC int32_t  //
wuffs_base__magic_number_guess_fourcc(wuffs_base__slice_u8 prefix)15573 wuffs_base__magic_number_guess_fourcc(wuffs_base__slice_u8 prefix) {
15574   // table holds the 'magic numbers' (which are actually variable length
15575   // strings). The strings may contain NUL bytes, so the "const char* magic"
15576   // value starts with the length-minus-1 of the 'magic number'.
15577   //
15578   // Keep it sorted by magic[1], then magic[0] descending and finally by
15579   // magic[2:]. When multiple entries match, the longest one wins.
15580   //
15581   // The fourcc field might be negated, in which case there's further
15582   // specialization (see § below).
15583   static struct {
15584     int32_t fourcc;
15585     const char* magic;
15586   } table[] = {
15587       {-0x30302020, "\x01\x00\x00"},          // '00  'be
15588       {+0x424D5020, "\x01\x42\x4D"},          // BMP
15589       {+0x47494620, "\x03\x47\x49\x46\x38"},  // GIF
15590       {+0x54494646, "\x03\x49\x49\x2A\x00"},  // TIFF (little-endian)
15591       {+0x54494646, "\x03\x4D\x4D\x00\x2A"},  // TIFF (big-endian)
15592       {-0x52494646, "\x03\x52\x49\x46\x46"},  // RIFF
15593       {+0x4E494520, "\x02\x6E\xC3\xAF"},      // NIE
15594       {+0x504E4720, "\x03\x89\x50\x4E\x47"},  // PNG
15595       {+0x4A504547, "\x01\xFF\xD8"},          // JPEG
15596   };
15597   static const size_t table_len = sizeof(table) / sizeof(table[0]);
15598 
15599   if (prefix.len == 0) {
15600     return -1;
15601   }
15602   uint8_t pre_first_byte = prefix.ptr[0];
15603 
15604   int32_t fourcc = 0;
15605   size_t i;
15606   for (i = 0; i < table_len; i++) {
15607     uint8_t mag_first_byte = ((uint8_t)(table[i].magic[1]));
15608     if (pre_first_byte < mag_first_byte) {
15609       break;
15610     } else if (pre_first_byte > mag_first_byte) {
15611       continue;
15612     }
15613     fourcc = table[i].fourcc;
15614 
15615     uint8_t mag_remaining_len = ((uint8_t)(table[i].magic[0]));
15616     if (mag_remaining_len == 0) {
15617       goto match;
15618     }
15619 
15620     const char* mag_remaining_ptr = table[i].magic + 2;
15621     uint8_t* pre_remaining_ptr = prefix.ptr + 1;
15622     size_t pre_remaining_len = prefix.len - 1;
15623     if (pre_remaining_len < mag_remaining_len) {
15624       if (!memcmp(pre_remaining_ptr, mag_remaining_ptr, pre_remaining_len)) {
15625         return -1;
15626       }
15627     } else {
15628       if (!memcmp(pre_remaining_ptr, mag_remaining_ptr, mag_remaining_len)) {
15629         goto match;
15630       }
15631     }
15632   }
15633   return 0;
15634 
15635 match:
15636   // Negative FourCC values (see § above) are further specialized.
15637   if (fourcc < 0) {
15638     fourcc = -fourcc;
15639 
15640     if (fourcc == 0x52494646) {  // 'RIFF'be
15641       if (prefix.len < 16) {
15642         return -1;
15643       }
15644       uint32_t x = wuffs_base__peek_u32be__no_bounds_check(prefix.ptr + 8);
15645       if (x == 0x57454250) {  // 'WEBP'be
15646         uint32_t y = wuffs_base__peek_u32be__no_bounds_check(prefix.ptr + 12);
15647         if (y == 0x56503820) {         // 'VP8 'be
15648           return 0x57503820;           // 'WP8 'be
15649         } else if (y == 0x5650384C) {  // 'VP8L'be
15650           return 0x5750384C;           // 'WP8L'be
15651         }
15652       }
15653 
15654     } else if (fourcc == 0x30302020) {  // '00  'be
15655       // Binary data starting with multiple 0x00 NUL bytes is quite common.
15656       if (prefix.len < 4) {
15657         return -1;
15658       } else if ((prefix.ptr[2] != 0x00) &&
15659                  ((prefix.ptr[2] >= 0x80) || (prefix.ptr[3] != 0x00))) {
15660         // Roughly speaking, this could be a non-degenerate (non-0-width and
15661         // non-0-height) WBMP image.
15662         return 0x57424D50;  // 'WBMP'be
15663       } else if (((prefix.ptr[2] == 0x01) || (prefix.ptr[2] == 0x02)) &&
15664                  (prefix.ptr[3] == 0x00)) {
15665         return 0x49434F20;  // 'ICO 'be
15666       }
15667       return 0;
15668     }
15669   }
15670   return fourcc;
15671 }
15672 
15673 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
15674         // defined(WUFFS_CONFIG__MODULE__BASE) ||
15675         // defined(WUFFS_CONFIG__MODULE__BASE__MAGIC)
15676 
15677 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
15678     defined(WUFFS_CONFIG__MODULE__BASE__PIXCONV)
15679 
15680 // ---------------- Pixel Swizzler
15681 
15682 static inline uint32_t  //
wuffs_base__swap_u32_argb_abgr(uint32_t u)15683 wuffs_base__swap_u32_argb_abgr(uint32_t u) {
15684   uint32_t o = u & 0xFF00FF00ul;
15685   uint32_t r = u & 0x00FF0000ul;
15686   uint32_t b = u & 0x000000FFul;
15687   return o | (r >> 16) | (b << 16);
15688 }
15689 
15690 static inline uint64_t  //
wuffs_base__swap_u64_argb_abgr(uint64_t u)15691 wuffs_base__swap_u64_argb_abgr(uint64_t u) {
15692   uint64_t o = u & 0xFFFF0000FFFF0000ull;
15693   uint64_t r = u & 0x0000FFFF00000000ull;
15694   uint64_t b = u & 0x000000000000FFFFull;
15695   return o | (r >> 32) | (b << 32);
15696 }
15697 
15698 static inline uint32_t  //
wuffs_base__color_u64__as__color_u32__swap_u32_argb_abgr(uint64_t c)15699 wuffs_base__color_u64__as__color_u32__swap_u32_argb_abgr(uint64_t c) {
15700   uint32_t a = ((uint32_t)(0xFF & (c >> 56)));
15701   uint32_t r = ((uint32_t)(0xFF & (c >> 40)));
15702   uint32_t g = ((uint32_t)(0xFF & (c >> 24)));
15703   uint32_t b = ((uint32_t)(0xFF & (c >> 8)));
15704   return (a << 24) | (b << 16) | (g << 8) | (r << 0);
15705 }
15706 
15707 // --------
15708 
15709 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)15710 wuffs_base__pixel_buffer__color_u32_at(const wuffs_base__pixel_buffer* pb,
15711                                        uint32_t x,
15712                                        uint32_t y) {
15713   if (!pb || (x >= pb->pixcfg.private_impl.width) ||
15714       (y >= pb->pixcfg.private_impl.height)) {
15715     return 0;
15716   }
15717 
15718   if (wuffs_base__pixel_format__is_planar(&pb->pixcfg.private_impl.pixfmt)) {
15719     // TODO: support planar formats.
15720     return 0;
15721   }
15722 
15723   size_t stride = pb->private_impl.planes[0].stride;
15724   const uint8_t* row = pb->private_impl.planes[0].ptr + (stride * ((size_t)y));
15725 
15726   switch (pb->pixcfg.private_impl.pixfmt.repr) {
15727     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
15728     case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
15729       return wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x)));
15730 
15731     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL:
15732     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY: {
15733       uint8_t* palette = pb->private_impl.planes[3].ptr;
15734       return wuffs_base__peek_u32le__no_bounds_check(palette +
15735                                                      (4 * ((size_t)row[x])));
15736     }
15737 
15738       // Common formats above. Rarer formats below.
15739 
15740     case WUFFS_BASE__PIXEL_FORMAT__Y:
15741       return 0xFF000000 | (0x00010101 * ((uint32_t)(row[x])));
15742     case WUFFS_BASE__PIXEL_FORMAT__Y_16LE:
15743       return 0xFF000000 | (0x00010101 * ((uint32_t)(row[(2 * x) + 1])));
15744     case WUFFS_BASE__PIXEL_FORMAT__Y_16BE:
15745       return 0xFF000000 | (0x00010101 * ((uint32_t)(row[(2 * x) + 0])));
15746 
15747     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL: {
15748       uint8_t* palette = pb->private_impl.planes[3].ptr;
15749       return wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
15750           wuffs_base__peek_u32le__no_bounds_check(palette +
15751                                                   (4 * ((size_t)row[x]))));
15752     }
15753 
15754     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
15755       return wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
15756           wuffs_base__peek_u16le__no_bounds_check(row + (2 * ((size_t)x))));
15757     case WUFFS_BASE__PIXEL_FORMAT__BGR:
15758       return 0xFF000000 |
15759              wuffs_base__peek_u24le__no_bounds_check(row + (3 * ((size_t)x)));
15760     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
15761       return wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
15762           wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x))));
15763     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
15764       return wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(
15765           wuffs_base__peek_u64le__no_bounds_check(row + (8 * ((size_t)x))));
15766     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
15767       return 0xFF000000 |
15768              wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x)));
15769 
15770     case WUFFS_BASE__PIXEL_FORMAT__RGB:
15771       return wuffs_base__swap_u32_argb_abgr(
15772           0xFF000000 |
15773           wuffs_base__peek_u24le__no_bounds_check(row + (3 * ((size_t)x))));
15774     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
15775       return wuffs_base__swap_u32_argb_abgr(
15776           wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
15777               wuffs_base__peek_u32le__no_bounds_check(row +
15778                                                       (4 * ((size_t)x)))));
15779     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
15780     case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
15781       return wuffs_base__swap_u32_argb_abgr(
15782           wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x))));
15783     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
15784       return wuffs_base__swap_u32_argb_abgr(
15785           0xFF000000 |
15786           wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x))));
15787 
15788     default:
15789       // TODO: support more formats.
15790       break;
15791   }
15792 
15793   return 0;
15794 }
15795 
15796 // --------
15797 
15798 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)15799 wuffs_base__pixel_buffer__set_color_u32_at(
15800     wuffs_base__pixel_buffer* pb,
15801     uint32_t x,
15802     uint32_t y,
15803     wuffs_base__color_u32_argb_premul color) {
15804   if (!pb) {
15805     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
15806   }
15807   if ((x >= pb->pixcfg.private_impl.width) ||
15808       (y >= pb->pixcfg.private_impl.height)) {
15809     return wuffs_base__make_status(wuffs_base__error__bad_argument);
15810   }
15811 
15812   if (wuffs_base__pixel_format__is_planar(&pb->pixcfg.private_impl.pixfmt)) {
15813     // TODO: support planar formats.
15814     return wuffs_base__make_status(wuffs_base__error__unsupported_option);
15815   }
15816 
15817   size_t stride = pb->private_impl.planes[0].stride;
15818   uint8_t* row = pb->private_impl.planes[0].ptr + (stride * ((size_t)y));
15819 
15820   switch (pb->pixcfg.private_impl.pixfmt.repr) {
15821     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
15822     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
15823       wuffs_base__poke_u32le__no_bounds_check(row + (4 * ((size_t)x)), color);
15824       break;
15825 
15826       // Common formats above. Rarer formats below.
15827 
15828     case WUFFS_BASE__PIXEL_FORMAT__Y:
15829       wuffs_base__poke_u8__no_bounds_check(
15830           row + ((size_t)x),
15831           wuffs_base__color_u32_argb_premul__as__color_u8_gray(color));
15832       break;
15833     case WUFFS_BASE__PIXEL_FORMAT__Y_16LE:
15834       wuffs_base__poke_u16le__no_bounds_check(
15835           row + (2 * ((size_t)x)),
15836           wuffs_base__color_u32_argb_premul__as__color_u16_gray(color));
15837       break;
15838     case WUFFS_BASE__PIXEL_FORMAT__Y_16BE:
15839       wuffs_base__poke_u16be__no_bounds_check(
15840           row + (2 * ((size_t)x)),
15841           wuffs_base__color_u32_argb_premul__as__color_u16_gray(color));
15842       break;
15843 
15844     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:
15845     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL:
15846     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY:
15847       wuffs_base__poke_u8__no_bounds_check(
15848           row + ((size_t)x), wuffs_base__pixel_palette__closest_element(
15849                                  wuffs_base__pixel_buffer__palette(pb),
15850                                  pb->pixcfg.private_impl.pixfmt, color));
15851       break;
15852 
15853     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
15854       wuffs_base__poke_u16le__no_bounds_check(
15855           row + (2 * ((size_t)x)),
15856           wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(color));
15857       break;
15858     case WUFFS_BASE__PIXEL_FORMAT__BGR:
15859       wuffs_base__poke_u24le__no_bounds_check(row + (3 * ((size_t)x)), color);
15860       break;
15861     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
15862       wuffs_base__poke_u32le__no_bounds_check(
15863           row + (4 * ((size_t)x)),
15864           wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
15865               color));
15866       break;
15867     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
15868       wuffs_base__poke_u64le__no_bounds_check(
15869           row + (8 * ((size_t)x)),
15870           wuffs_base__color_u32_argb_premul__as__color_u64_argb_nonpremul(
15871               color));
15872       break;
15873 
15874     case WUFFS_BASE__PIXEL_FORMAT__RGB:
15875       wuffs_base__poke_u24le__no_bounds_check(
15876           row + (3 * ((size_t)x)), wuffs_base__swap_u32_argb_abgr(color));
15877       break;
15878     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
15879       wuffs_base__poke_u32le__no_bounds_check(
15880           row + (4 * ((size_t)x)),
15881           wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
15882               wuffs_base__swap_u32_argb_abgr(color)));
15883       break;
15884     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
15885     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
15886       wuffs_base__poke_u32le__no_bounds_check(
15887           row + (4 * ((size_t)x)), wuffs_base__swap_u32_argb_abgr(color));
15888       break;
15889 
15890     default:
15891       // TODO: support more formats.
15892       return wuffs_base__make_status(wuffs_base__error__unsupported_option);
15893   }
15894 
15895   return wuffs_base__make_status(NULL);
15896 }
15897 
15898 // --------
15899 
15900 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)15901 wuffs_base__pixel_buffer__set_color_u32_fill_rect__xx(
15902     wuffs_base__pixel_buffer* pb,
15903     wuffs_base__rect_ie_u32 rect,
15904     uint16_t color) {
15905   size_t stride = pb->private_impl.planes[0].stride;
15906   uint32_t width = wuffs_base__rect_ie_u32__width(&rect);
15907   if ((stride == (2 * ((uint64_t)width))) && (rect.min_incl_x == 0)) {
15908     uint8_t* ptr =
15909         pb->private_impl.planes[0].ptr + (stride * ((size_t)rect.min_incl_y));
15910     uint32_t height = wuffs_base__rect_ie_u32__height(&rect);
15911     size_t n;
15912     for (n = ((size_t)width) * ((size_t)height); n > 0; n--) {
15913       wuffs_base__poke_u16le__no_bounds_check(ptr, color);
15914       ptr += 2;
15915     }
15916     return;
15917   }
15918 
15919   uint32_t y;
15920   for (y = rect.min_incl_y; y < rect.max_excl_y; y++) {
15921     uint8_t* ptr = pb->private_impl.planes[0].ptr + (stride * ((size_t)y)) +
15922                    (2 * ((size_t)rect.min_incl_x));
15923     uint32_t n;
15924     for (n = width; n > 0; n--) {
15925       wuffs_base__poke_u16le__no_bounds_check(ptr, color);
15926       ptr += 2;
15927     }
15928   }
15929 }
15930 
15931 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)15932 wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxx(
15933     wuffs_base__pixel_buffer* pb,
15934     wuffs_base__rect_ie_u32 rect,
15935     uint32_t color) {
15936   size_t stride = pb->private_impl.planes[0].stride;
15937   uint32_t width = wuffs_base__rect_ie_u32__width(&rect);
15938   if ((stride == (3 * ((uint64_t)width))) && (rect.min_incl_x == 0)) {
15939     uint8_t* ptr =
15940         pb->private_impl.planes[0].ptr + (stride * ((size_t)rect.min_incl_y));
15941     uint32_t height = wuffs_base__rect_ie_u32__height(&rect);
15942     size_t n;
15943     for (n = ((size_t)width) * ((size_t)height); n > 0; n--) {
15944       wuffs_base__poke_u24le__no_bounds_check(ptr, color);
15945       ptr += 3;
15946     }
15947     return;
15948   }
15949 
15950   uint32_t y;
15951   for (y = rect.min_incl_y; y < rect.max_excl_y; y++) {
15952     uint8_t* ptr = pb->private_impl.planes[0].ptr + (stride * ((size_t)y)) +
15953                    (3 * ((size_t)rect.min_incl_x));
15954     uint32_t n;
15955     for (n = width; n > 0; n--) {
15956       wuffs_base__poke_u24le__no_bounds_check(ptr, color);
15957       ptr += 3;
15958     }
15959   }
15960 }
15961 
15962 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)15963 wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxx(
15964     wuffs_base__pixel_buffer* pb,
15965     wuffs_base__rect_ie_u32 rect,
15966     uint32_t color) {
15967   size_t stride = pb->private_impl.planes[0].stride;
15968   uint32_t width = wuffs_base__rect_ie_u32__width(&rect);
15969   if ((stride == (4 * ((uint64_t)width))) && (rect.min_incl_x == 0)) {
15970     uint8_t* ptr =
15971         pb->private_impl.planes[0].ptr + (stride * ((size_t)rect.min_incl_y));
15972     uint32_t height = wuffs_base__rect_ie_u32__height(&rect);
15973     size_t n;
15974     for (n = ((size_t)width) * ((size_t)height); n > 0; n--) {
15975       wuffs_base__poke_u32le__no_bounds_check(ptr, color);
15976       ptr += 4;
15977     }
15978     return;
15979   }
15980 
15981   uint32_t y;
15982   for (y = rect.min_incl_y; y < rect.max_excl_y; y++) {
15983     uint8_t* ptr = pb->private_impl.planes[0].ptr + (stride * ((size_t)y)) +
15984                    (4 * ((size_t)rect.min_incl_x));
15985     uint32_t n;
15986     for (n = width; n > 0; n--) {
15987       wuffs_base__poke_u32le__no_bounds_check(ptr, color);
15988       ptr += 4;
15989     }
15990   }
15991 }
15992 
15993 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)15994 wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxxxxxx(
15995     wuffs_base__pixel_buffer* pb,
15996     wuffs_base__rect_ie_u32 rect,
15997     uint64_t color) {
15998   size_t stride = pb->private_impl.planes[0].stride;
15999   uint32_t width = wuffs_base__rect_ie_u32__width(&rect);
16000   if ((stride == (8 * ((uint64_t)width))) && (rect.min_incl_x == 0)) {
16001     uint8_t* ptr =
16002         pb->private_impl.planes[0].ptr + (stride * ((size_t)rect.min_incl_y));
16003     uint32_t height = wuffs_base__rect_ie_u32__height(&rect);
16004     size_t n;
16005     for (n = ((size_t)width) * ((size_t)height); n > 0; n--) {
16006       wuffs_base__poke_u64le__no_bounds_check(ptr, color);
16007       ptr += 8;
16008     }
16009     return;
16010   }
16011 
16012   uint32_t y;
16013   for (y = rect.min_incl_y; y < rect.max_excl_y; y++) {
16014     uint8_t* ptr = pb->private_impl.planes[0].ptr + (stride * ((size_t)y)) +
16015                    (8 * ((size_t)rect.min_incl_x));
16016     uint32_t n;
16017     for (n = width; n > 0; n--) {
16018       wuffs_base__poke_u64le__no_bounds_check(ptr, color);
16019       ptr += 8;
16020     }
16021   }
16022 }
16023 
16024 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)16025 wuffs_base__pixel_buffer__set_color_u32_fill_rect(
16026     wuffs_base__pixel_buffer* pb,
16027     wuffs_base__rect_ie_u32 rect,
16028     wuffs_base__color_u32_argb_premul color) {
16029   if (!pb) {
16030     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
16031   } else if (wuffs_base__rect_ie_u32__is_empty(&rect)) {
16032     return wuffs_base__make_status(NULL);
16033   }
16034   wuffs_base__rect_ie_u32 bounds =
16035       wuffs_base__pixel_config__bounds(&pb->pixcfg);
16036   if (!wuffs_base__rect_ie_u32__contains_rect(&bounds, rect)) {
16037     return wuffs_base__make_status(wuffs_base__error__bad_argument);
16038   }
16039 
16040   if (wuffs_base__pixel_format__is_planar(&pb->pixcfg.private_impl.pixfmt)) {
16041     // TODO: support planar formats.
16042     return wuffs_base__make_status(wuffs_base__error__unsupported_option);
16043   }
16044 
16045   switch (pb->pixcfg.private_impl.pixfmt.repr) {
16046     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
16047     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
16048       wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxx(pb, rect, color);
16049       return wuffs_base__make_status(NULL);
16050 
16051       // Common formats above. Rarer formats below.
16052 
16053     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
16054       wuffs_base__pixel_buffer__set_color_u32_fill_rect__xx(
16055           pb, rect,
16056           wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(color));
16057       return wuffs_base__make_status(NULL);
16058 
16059     case WUFFS_BASE__PIXEL_FORMAT__BGR:
16060       wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxx(pb, rect, color);
16061       return wuffs_base__make_status(NULL);
16062 
16063     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
16064       wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxx(
16065           pb, rect,
16066           wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
16067               color));
16068       return wuffs_base__make_status(NULL);
16069 
16070     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
16071       wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxxxxxx(
16072           pb, rect,
16073           wuffs_base__color_u32_argb_premul__as__color_u64_argb_nonpremul(
16074               color));
16075       return wuffs_base__make_status(NULL);
16076 
16077     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
16078       wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxx(
16079           pb, rect,
16080           wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
16081               wuffs_base__swap_u32_argb_abgr(color)));
16082       return wuffs_base__make_status(NULL);
16083 
16084     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
16085     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
16086       wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxx(
16087           pb, rect, wuffs_base__swap_u32_argb_abgr(color));
16088       return wuffs_base__make_status(NULL);
16089   }
16090 
16091   uint32_t y;
16092   for (y = rect.min_incl_y; y < rect.max_excl_y; y++) {
16093     uint32_t x;
16094     for (x = rect.min_incl_x; x < rect.max_excl_x; x++) {
16095       wuffs_base__pixel_buffer__set_color_u32_at(pb, x, y, color);
16096     }
16097   }
16098   return wuffs_base__make_status(NULL);
16099 }
16100 
16101 // --------
16102 
16103 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)16104 wuffs_base__pixel_palette__closest_element(
16105     wuffs_base__slice_u8 palette_slice,
16106     wuffs_base__pixel_format palette_format,
16107     wuffs_base__color_u32_argb_premul c) {
16108   size_t n = palette_slice.len / 4;
16109   if (n > (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
16110     n = (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4);
16111   }
16112   size_t best_index = 0;
16113   uint64_t best_score = 0xFFFFFFFFFFFFFFFF;
16114 
16115   // Work in 16-bit color.
16116   uint32_t ca = 0x101 * (0xFF & (c >> 24));
16117   uint32_t cr = 0x101 * (0xFF & (c >> 16));
16118   uint32_t cg = 0x101 * (0xFF & (c >> 8));
16119   uint32_t cb = 0x101 * (0xFF & (c >> 0));
16120 
16121   switch (palette_format.repr) {
16122     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:
16123     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL:
16124     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY: {
16125       bool nonpremul = palette_format.repr ==
16126                        WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL;
16127 
16128       size_t i;
16129       for (i = 0; i < n; i++) {
16130         // Work in 16-bit color.
16131         uint32_t pb = 0x101 * ((uint32_t)(palette_slice.ptr[(4 * i) + 0]));
16132         uint32_t pg = 0x101 * ((uint32_t)(palette_slice.ptr[(4 * i) + 1]));
16133         uint32_t pr = 0x101 * ((uint32_t)(palette_slice.ptr[(4 * i) + 2]));
16134         uint32_t pa = 0x101 * ((uint32_t)(palette_slice.ptr[(4 * i) + 3]));
16135 
16136         // Convert to premultiplied alpha.
16137         if (nonpremul && (pa != 0xFFFF)) {
16138           pb = (pb * pa) / 0xFFFF;
16139           pg = (pg * pa) / 0xFFFF;
16140           pr = (pr * pa) / 0xFFFF;
16141         }
16142 
16143         // These deltas are conceptually int32_t (signed) but after squaring,
16144         // it's equivalent to work in uint32_t (unsigned).
16145         pb -= cb;
16146         pg -= cg;
16147         pr -= cr;
16148         pa -= ca;
16149         uint64_t score = ((uint64_t)(pb * pb)) + ((uint64_t)(pg * pg)) +
16150                          ((uint64_t)(pr * pr)) + ((uint64_t)(pa * pa));
16151         if (best_score > score) {
16152           best_score = score;
16153           best_index = i;
16154         }
16155       }
16156       break;
16157     }
16158   }
16159 
16160   return (uint8_t)best_index;
16161 }
16162 
16163 // --------
16164 
16165 static inline uint32_t  //
wuffs_base__composite_nonpremul_nonpremul_u32_axxx(uint32_t dst_nonpremul,uint32_t src_nonpremul)16166 wuffs_base__composite_nonpremul_nonpremul_u32_axxx(uint32_t dst_nonpremul,
16167                                                    uint32_t src_nonpremul) {
16168   // Extract 16-bit color components.
16169   uint32_t sa = 0x101 * (0xFF & (src_nonpremul >> 24));
16170   uint32_t sr = 0x101 * (0xFF & (src_nonpremul >> 16));
16171   uint32_t sg = 0x101 * (0xFF & (src_nonpremul >> 8));
16172   uint32_t sb = 0x101 * (0xFF & (src_nonpremul >> 0));
16173   uint32_t da = 0x101 * (0xFF & (dst_nonpremul >> 24));
16174   uint32_t dr = 0x101 * (0xFF & (dst_nonpremul >> 16));
16175   uint32_t dg = 0x101 * (0xFF & (dst_nonpremul >> 8));
16176   uint32_t db = 0x101 * (0xFF & (dst_nonpremul >> 0));
16177 
16178   // Convert dst from nonpremul to premul.
16179   dr = (dr * da) / 0xFFFF;
16180   dg = (dg * da) / 0xFFFF;
16181   db = (db * da) / 0xFFFF;
16182 
16183   // Calculate the inverse of the src-alpha: how much of the dst to keep.
16184   uint32_t ia = 0xFFFF - sa;
16185 
16186   // Composite src (nonpremul) over dst (premul).
16187   da = sa + ((da * ia) / 0xFFFF);
16188   dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
16189   dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
16190   db = ((sb * sa) + (db * ia)) / 0xFFFF;
16191 
16192   // Convert dst from premul to nonpremul.
16193   if (da != 0) {
16194     dr = (dr * 0xFFFF) / da;
16195     dg = (dg * 0xFFFF) / da;
16196     db = (db * 0xFFFF) / da;
16197   }
16198 
16199   // Convert from 16-bit color to 8-bit color.
16200   da >>= 8;
16201   dr >>= 8;
16202   dg >>= 8;
16203   db >>= 8;
16204 
16205   // Combine components.
16206   return (db << 0) | (dg << 8) | (dr << 16) | (da << 24);
16207 }
16208 
16209 static inline uint64_t  //
wuffs_base__composite_nonpremul_nonpremul_u64_axxx(uint64_t dst_nonpremul,uint64_t src_nonpremul)16210 wuffs_base__composite_nonpremul_nonpremul_u64_axxx(uint64_t dst_nonpremul,
16211                                                    uint64_t src_nonpremul) {
16212   // Extract components.
16213   uint64_t sa = 0xFFFF & (src_nonpremul >> 48);
16214   uint64_t sr = 0xFFFF & (src_nonpremul >> 32);
16215   uint64_t sg = 0xFFFF & (src_nonpremul >> 16);
16216   uint64_t sb = 0xFFFF & (src_nonpremul >> 0);
16217   uint64_t da = 0xFFFF & (dst_nonpremul >> 48);
16218   uint64_t dr = 0xFFFF & (dst_nonpremul >> 32);
16219   uint64_t dg = 0xFFFF & (dst_nonpremul >> 16);
16220   uint64_t db = 0xFFFF & (dst_nonpremul >> 0);
16221 
16222   // Convert dst from nonpremul to premul.
16223   dr = (dr * da) / 0xFFFF;
16224   dg = (dg * da) / 0xFFFF;
16225   db = (db * da) / 0xFFFF;
16226 
16227   // Calculate the inverse of the src-alpha: how much of the dst to keep.
16228   uint64_t ia = 0xFFFF - sa;
16229 
16230   // Composite src (nonpremul) over dst (premul).
16231   da = sa + ((da * ia) / 0xFFFF);
16232   dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
16233   dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
16234   db = ((sb * sa) + (db * ia)) / 0xFFFF;
16235 
16236   // Convert dst from premul to nonpremul.
16237   if (da != 0) {
16238     dr = (dr * 0xFFFF) / da;
16239     dg = (dg * 0xFFFF) / da;
16240     db = (db * 0xFFFF) / da;
16241   }
16242 
16243   // Combine components.
16244   return (db << 0) | (dg << 16) | (dr << 32) | (da << 48);
16245 }
16246 
16247 static inline uint32_t  //
wuffs_base__composite_nonpremul_premul_u32_axxx(uint32_t dst_nonpremul,uint32_t src_premul)16248 wuffs_base__composite_nonpremul_premul_u32_axxx(uint32_t dst_nonpremul,
16249                                                 uint32_t src_premul) {
16250   // Extract 16-bit color components.
16251   uint32_t sa = 0x101 * (0xFF & (src_premul >> 24));
16252   uint32_t sr = 0x101 * (0xFF & (src_premul >> 16));
16253   uint32_t sg = 0x101 * (0xFF & (src_premul >> 8));
16254   uint32_t sb = 0x101 * (0xFF & (src_premul >> 0));
16255   uint32_t da = 0x101 * (0xFF & (dst_nonpremul >> 24));
16256   uint32_t dr = 0x101 * (0xFF & (dst_nonpremul >> 16));
16257   uint32_t dg = 0x101 * (0xFF & (dst_nonpremul >> 8));
16258   uint32_t db = 0x101 * (0xFF & (dst_nonpremul >> 0));
16259 
16260   // Convert dst from nonpremul to premul.
16261   dr = (dr * da) / 0xFFFF;
16262   dg = (dg * da) / 0xFFFF;
16263   db = (db * da) / 0xFFFF;
16264 
16265   // Calculate the inverse of the src-alpha: how much of the dst to keep.
16266   uint32_t ia = 0xFFFF - sa;
16267 
16268   // Composite src (premul) over dst (premul).
16269   da = sa + ((da * ia) / 0xFFFF);
16270   dr = sr + ((dr * ia) / 0xFFFF);
16271   dg = sg + ((dg * ia) / 0xFFFF);
16272   db = sb + ((db * ia) / 0xFFFF);
16273 
16274   // Convert dst from premul to nonpremul.
16275   if (da != 0) {
16276     dr = (dr * 0xFFFF) / da;
16277     dg = (dg * 0xFFFF) / da;
16278     db = (db * 0xFFFF) / da;
16279   }
16280 
16281   // Convert from 16-bit color to 8-bit color.
16282   da >>= 8;
16283   dr >>= 8;
16284   dg >>= 8;
16285   db >>= 8;
16286 
16287   // Combine components.
16288   return (db << 0) | (dg << 8) | (dr << 16) | (da << 24);
16289 }
16290 
16291 static inline uint64_t  //
wuffs_base__composite_nonpremul_premul_u64_axxx(uint64_t dst_nonpremul,uint64_t src_premul)16292 wuffs_base__composite_nonpremul_premul_u64_axxx(uint64_t dst_nonpremul,
16293                                                 uint64_t src_premul) {
16294   // Extract components.
16295   uint64_t sa = 0xFFFF & (src_premul >> 48);
16296   uint64_t sr = 0xFFFF & (src_premul >> 32);
16297   uint64_t sg = 0xFFFF & (src_premul >> 16);
16298   uint64_t sb = 0xFFFF & (src_premul >> 0);
16299   uint64_t da = 0xFFFF & (dst_nonpremul >> 48);
16300   uint64_t dr = 0xFFFF & (dst_nonpremul >> 32);
16301   uint64_t dg = 0xFFFF & (dst_nonpremul >> 16);
16302   uint64_t db = 0xFFFF & (dst_nonpremul >> 0);
16303 
16304   // Convert dst from nonpremul to premul.
16305   dr = (dr * da) / 0xFFFF;
16306   dg = (dg * da) / 0xFFFF;
16307   db = (db * da) / 0xFFFF;
16308 
16309   // Calculate the inverse of the src-alpha: how much of the dst to keep.
16310   uint64_t ia = 0xFFFF - sa;
16311 
16312   // Composite src (premul) over dst (premul).
16313   da = sa + ((da * ia) / 0xFFFF);
16314   dr = sr + ((dr * ia) / 0xFFFF);
16315   dg = sg + ((dg * ia) / 0xFFFF);
16316   db = sb + ((db * ia) / 0xFFFF);
16317 
16318   // Convert dst from premul to nonpremul.
16319   if (da != 0) {
16320     dr = (dr * 0xFFFF) / da;
16321     dg = (dg * 0xFFFF) / da;
16322     db = (db * 0xFFFF) / da;
16323   }
16324 
16325   // Combine components.
16326   return (db << 0) | (dg << 16) | (dr << 32) | (da << 48);
16327 }
16328 
16329 static inline uint32_t  //
wuffs_base__composite_premul_nonpremul_u32_axxx(uint32_t dst_premul,uint32_t src_nonpremul)16330 wuffs_base__composite_premul_nonpremul_u32_axxx(uint32_t dst_premul,
16331                                                 uint32_t src_nonpremul) {
16332   // Extract 16-bit color components.
16333   uint32_t sa = 0x101 * (0xFF & (src_nonpremul >> 24));
16334   uint32_t sr = 0x101 * (0xFF & (src_nonpremul >> 16));
16335   uint32_t sg = 0x101 * (0xFF & (src_nonpremul >> 8));
16336   uint32_t sb = 0x101 * (0xFF & (src_nonpremul >> 0));
16337   uint32_t da = 0x101 * (0xFF & (dst_premul >> 24));
16338   uint32_t dr = 0x101 * (0xFF & (dst_premul >> 16));
16339   uint32_t dg = 0x101 * (0xFF & (dst_premul >> 8));
16340   uint32_t db = 0x101 * (0xFF & (dst_premul >> 0));
16341 
16342   // Calculate the inverse of the src-alpha: how much of the dst to keep.
16343   uint32_t ia = 0xFFFF - sa;
16344 
16345   // Composite src (nonpremul) over dst (premul).
16346   da = sa + ((da * ia) / 0xFFFF);
16347   dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
16348   dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
16349   db = ((sb * sa) + (db * ia)) / 0xFFFF;
16350 
16351   // Convert from 16-bit color to 8-bit color.
16352   da >>= 8;
16353   dr >>= 8;
16354   dg >>= 8;
16355   db >>= 8;
16356 
16357   // Combine components.
16358   return (db << 0) | (dg << 8) | (dr << 16) | (da << 24);
16359 }
16360 
16361 static inline uint64_t  //
wuffs_base__composite_premul_nonpremul_u64_axxx(uint64_t dst_premul,uint64_t src_nonpremul)16362 wuffs_base__composite_premul_nonpremul_u64_axxx(uint64_t dst_premul,
16363                                                 uint64_t src_nonpremul) {
16364   // Extract components.
16365   uint64_t sa = 0xFFFF & (src_nonpremul >> 48);
16366   uint64_t sr = 0xFFFF & (src_nonpremul >> 32);
16367   uint64_t sg = 0xFFFF & (src_nonpremul >> 16);
16368   uint64_t sb = 0xFFFF & (src_nonpremul >> 0);
16369   uint64_t da = 0xFFFF & (dst_premul >> 48);
16370   uint64_t dr = 0xFFFF & (dst_premul >> 32);
16371   uint64_t dg = 0xFFFF & (dst_premul >> 16);
16372   uint64_t db = 0xFFFF & (dst_premul >> 0);
16373 
16374   // Calculate the inverse of the src-alpha: how much of the dst to keep.
16375   uint64_t ia = 0xFFFF - sa;
16376 
16377   // Composite src (nonpremul) over dst (premul).
16378   da = sa + ((da * ia) / 0xFFFF);
16379   dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
16380   dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
16381   db = ((sb * sa) + (db * ia)) / 0xFFFF;
16382 
16383   // Combine components.
16384   return (db << 0) | (dg << 16) | (dr << 32) | (da << 48);
16385 }
16386 
16387 static inline uint32_t  //
wuffs_base__composite_premul_premul_u32_axxx(uint32_t dst_premul,uint32_t src_premul)16388 wuffs_base__composite_premul_premul_u32_axxx(uint32_t dst_premul,
16389                                              uint32_t src_premul) {
16390   // Extract 16-bit color components.
16391   uint32_t sa = 0x101 * (0xFF & (src_premul >> 24));
16392   uint32_t sr = 0x101 * (0xFF & (src_premul >> 16));
16393   uint32_t sg = 0x101 * (0xFF & (src_premul >> 8));
16394   uint32_t sb = 0x101 * (0xFF & (src_premul >> 0));
16395   uint32_t da = 0x101 * (0xFF & (dst_premul >> 24));
16396   uint32_t dr = 0x101 * (0xFF & (dst_premul >> 16));
16397   uint32_t dg = 0x101 * (0xFF & (dst_premul >> 8));
16398   uint32_t db = 0x101 * (0xFF & (dst_premul >> 0));
16399 
16400   // Calculate the inverse of the src-alpha: how much of the dst to keep.
16401   uint32_t ia = 0xFFFF - sa;
16402 
16403   // Composite src (premul) over dst (premul).
16404   da = sa + ((da * ia) / 0xFFFF);
16405   dr = sr + ((dr * ia) / 0xFFFF);
16406   dg = sg + ((dg * ia) / 0xFFFF);
16407   db = sb + ((db * ia) / 0xFFFF);
16408 
16409   // Convert from 16-bit color to 8-bit color.
16410   da >>= 8;
16411   dr >>= 8;
16412   dg >>= 8;
16413   db >>= 8;
16414 
16415   // Combine components.
16416   return (db << 0) | (dg << 8) | (dr << 16) | (da << 24);
16417 }
16418 
16419 // --------
16420 
16421 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)16422 wuffs_base__pixel_swizzler__squash_align4_bgr_565_8888(uint8_t* dst_ptr,
16423                                                        size_t dst_len,
16424                                                        const uint8_t* src_ptr,
16425                                                        size_t src_len,
16426                                                        bool nonpremul) {
16427   size_t len = (dst_len < src_len ? dst_len : src_len) / 4;
16428   uint8_t* d = dst_ptr;
16429   const uint8_t* s = src_ptr;
16430 
16431   size_t n = len;
16432   while (n--) {
16433     uint32_t argb = wuffs_base__peek_u32le__no_bounds_check(s);
16434     if (nonpremul) {
16435       argb =
16436           wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(argb);
16437     }
16438     uint32_t b5 = 0x1F & (argb >> (8 - 5));
16439     uint32_t g6 = 0x3F & (argb >> (16 - 6));
16440     uint32_t r5 = 0x1F & (argb >> (24 - 5));
16441     uint32_t alpha = argb & 0xFF000000;
16442     wuffs_base__poke_u32le__no_bounds_check(
16443         d, alpha | (r5 << 11) | (g6 << 5) | (b5 << 0));
16444     s += 4;
16445     d += 4;
16446   }
16447   return len;
16448 }
16449 
16450 // --------
16451 
16452 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)16453 wuffs_base__pixel_swizzler__swap_rgb_bgr(uint8_t* dst_ptr,
16454                                          size_t dst_len,
16455                                          uint8_t* dst_palette_ptr,
16456                                          size_t dst_palette_len,
16457                                          const uint8_t* src_ptr,
16458                                          size_t src_len) {
16459   size_t len = (dst_len < src_len ? dst_len : src_len) / 3;
16460   uint8_t* d = dst_ptr;
16461   const uint8_t* s = src_ptr;
16462 
16463   size_t n = len;
16464   while (n--) {
16465     uint8_t s0 = s[0];
16466     uint8_t s1 = s[1];
16467     uint8_t s2 = s[2];
16468     d[0] = s2;
16469     d[1] = s1;
16470     d[2] = s0;
16471     s += 3;
16472     d += 3;
16473   }
16474   return len;
16475 }
16476 
16477 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
16478 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
16479 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
16480 static uint64_t  //
wuffs_base__pixel_swizzler__swap_rgbx_bgrx__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)16481 wuffs_base__pixel_swizzler__swap_rgbx_bgrx__sse42(uint8_t* dst_ptr,
16482                                                   size_t dst_len,
16483                                                   uint8_t* dst_palette_ptr,
16484                                                   size_t dst_palette_len,
16485                                                   const uint8_t* src_ptr,
16486                                                   size_t src_len) {
16487   size_t len = (dst_len < src_len ? dst_len : src_len) / 4;
16488   uint8_t* d = dst_ptr;
16489   const uint8_t* s = src_ptr;
16490   size_t n = len;
16491 
16492   __m128i shuffle = _mm_set_epi8(+0x0F, +0x0C, +0x0D, +0x0E,  //
16493                                  +0x0B, +0x08, +0x09, +0x0A,  //
16494                                  +0x07, +0x04, +0x05, +0x06,  //
16495                                  +0x03, +0x00, +0x01, +0x02);
16496 
16497   while (n >= 4) {
16498     __m128i x;
16499     x = _mm_lddqu_si128((const __m128i*)(const void*)s);
16500     x = _mm_shuffle_epi8(x, shuffle);
16501     _mm_storeu_si128((__m128i*)(void*)d, x);
16502 
16503     s += 4 * 4;
16504     d += 4 * 4;
16505     n -= 4;
16506   }
16507 
16508   while (n--) {
16509     uint8_t s0 = s[0];
16510     uint8_t s1 = s[1];
16511     uint8_t s2 = s[2];
16512     uint8_t s3 = s[3];
16513     d[0] = s2;
16514     d[1] = s1;
16515     d[2] = s0;
16516     d[3] = s3;
16517     s += 4;
16518     d += 4;
16519   }
16520   return len;
16521 }
16522 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
16523 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
16524 
16525 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)16526 wuffs_base__pixel_swizzler__swap_rgbx_bgrx(uint8_t* dst_ptr,
16527                                            size_t dst_len,
16528                                            uint8_t* dst_palette_ptr,
16529                                            size_t dst_palette_len,
16530                                            const uint8_t* src_ptr,
16531                                            size_t src_len) {
16532   size_t len = (dst_len < src_len ? dst_len : src_len) / 4;
16533   uint8_t* d = dst_ptr;
16534   const uint8_t* s = src_ptr;
16535 
16536   size_t n = len;
16537   while (n--) {
16538     uint8_t s0 = s[0];
16539     uint8_t s1 = s[1];
16540     uint8_t s2 = s[2];
16541     uint8_t s3 = s[3];
16542     d[0] = s2;
16543     d[1] = s1;
16544     d[2] = s0;
16545     d[3] = s3;
16546     s += 4;
16547     d += 4;
16548   }
16549   return len;
16550 }
16551 
16552 // --------
16553 
16554 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)16555 wuffs_base__pixel_swizzler__copy_1_1(uint8_t* dst_ptr,
16556                                      size_t dst_len,
16557                                      uint8_t* dst_palette_ptr,
16558                                      size_t dst_palette_len,
16559                                      const uint8_t* src_ptr,
16560                                      size_t src_len) {
16561   size_t len = (dst_len < src_len) ? dst_len : src_len;
16562   if (len > 0) {
16563     memmove(dst_ptr, src_ptr, len);
16564   }
16565   return len;
16566 }
16567 
16568 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)16569 wuffs_base__pixel_swizzler__copy_2_2(uint8_t* dst_ptr,
16570                                      size_t dst_len,
16571                                      uint8_t* dst_palette_ptr,
16572                                      size_t dst_palette_len,
16573                                      const uint8_t* src_ptr,
16574                                      size_t src_len) {
16575   size_t dst_len2 = dst_len / 2;
16576   size_t src_len2 = src_len / 2;
16577   size_t len = (dst_len2 < src_len2) ? dst_len2 : src_len2;
16578   if (len > 0) {
16579     memmove(dst_ptr, src_ptr, len * 2);
16580   }
16581   return len;
16582 }
16583 
16584 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)16585 wuffs_base__pixel_swizzler__copy_3_3(uint8_t* dst_ptr,
16586                                      size_t dst_len,
16587                                      uint8_t* dst_palette_ptr,
16588                                      size_t dst_palette_len,
16589                                      const uint8_t* src_ptr,
16590                                      size_t src_len) {
16591   size_t dst_len3 = dst_len / 3;
16592   size_t src_len3 = src_len / 3;
16593   size_t len = (dst_len3 < src_len3) ? dst_len3 : src_len3;
16594   if (len > 0) {
16595     memmove(dst_ptr, src_ptr, len * 3);
16596   }
16597   return len;
16598 }
16599 
16600 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)16601 wuffs_base__pixel_swizzler__copy_4_4(uint8_t* dst_ptr,
16602                                      size_t dst_len,
16603                                      uint8_t* dst_palette_ptr,
16604                                      size_t dst_palette_len,
16605                                      const uint8_t* src_ptr,
16606                                      size_t src_len) {
16607   size_t dst_len4 = dst_len / 4;
16608   size_t src_len4 = src_len / 4;
16609   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
16610   if (len > 0) {
16611     memmove(dst_ptr, src_ptr, len * 4);
16612   }
16613   return len;
16614 }
16615 
16616 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)16617 wuffs_base__pixel_swizzler__copy_8_8(uint8_t* dst_ptr,
16618                                      size_t dst_len,
16619                                      uint8_t* dst_palette_ptr,
16620                                      size_t dst_palette_len,
16621                                      const uint8_t* src_ptr,
16622                                      size_t src_len) {
16623   size_t dst_len8 = dst_len / 8;
16624   size_t src_len8 = src_len / 8;
16625   size_t len = (dst_len8 < src_len8) ? dst_len8 : src_len8;
16626   if (len > 0) {
16627     memmove(dst_ptr, src_ptr, len * 8);
16628   }
16629   return len;
16630 }
16631 
16632 // --------
16633 
16634 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)16635 wuffs_base__pixel_swizzler__bgr_565__bgr(uint8_t* dst_ptr,
16636                                          size_t dst_len,
16637                                          uint8_t* dst_palette_ptr,
16638                                          size_t dst_palette_len,
16639                                          const uint8_t* src_ptr,
16640                                          size_t src_len) {
16641   size_t dst_len2 = dst_len / 2;
16642   size_t src_len3 = src_len / 3;
16643   size_t len = (dst_len2 < src_len3) ? dst_len2 : src_len3;
16644   uint8_t* d = dst_ptr;
16645   const uint8_t* s = src_ptr;
16646   size_t n = len;
16647 
16648   // TODO: unroll.
16649 
16650   while (n >= 1) {
16651     uint32_t b5 = s[0] >> 3;
16652     uint32_t g6 = s[1] >> 2;
16653     uint32_t r5 = s[2] >> 3;
16654     uint32_t rgb_565 = (r5 << 11) | (g6 << 5) | (b5 << 0);
16655     wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565);
16656 
16657     s += 1 * 3;
16658     d += 1 * 2;
16659     n -= 1;
16660   }
16661 
16662   return len;
16663 }
16664 
16665 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)16666 wuffs_base__pixel_swizzler__bgr_565__bgrx(uint8_t* dst_ptr,
16667                                           size_t dst_len,
16668                                           uint8_t* dst_palette_ptr,
16669                                           size_t dst_palette_len,
16670                                           const uint8_t* src_ptr,
16671                                           size_t src_len) {
16672   size_t dst_len2 = dst_len / 2;
16673   size_t src_len4 = src_len / 4;
16674   size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
16675   uint8_t* d = dst_ptr;
16676   const uint8_t* s = src_ptr;
16677   size_t n = len;
16678 
16679   // TODO: unroll.
16680 
16681   while (n >= 1) {
16682     uint32_t b5 = s[0] >> 3;
16683     uint32_t g6 = s[1] >> 2;
16684     uint32_t r5 = s[2] >> 3;
16685     uint32_t rgb_565 = (r5 << 11) | (g6 << 5) | (b5 << 0);
16686     wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565);
16687 
16688     s += 1 * 4;
16689     d += 1 * 2;
16690     n -= 1;
16691   }
16692 
16693   return len;
16694 }
16695 
16696 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)16697 wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul__src(
16698     uint8_t* dst_ptr,
16699     size_t dst_len,
16700     uint8_t* dst_palette_ptr,
16701     size_t dst_palette_len,
16702     const uint8_t* src_ptr,
16703     size_t src_len) {
16704   size_t dst_len2 = dst_len / 2;
16705   size_t src_len4 = src_len / 4;
16706   size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
16707   uint8_t* d = dst_ptr;
16708   const uint8_t* s = src_ptr;
16709   size_t n = len;
16710 
16711   // TODO: unroll.
16712 
16713   while (n >= 1) {
16714     wuffs_base__poke_u16le__no_bounds_check(
16715         d + (0 * 2),
16716         wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
16717             wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
16718                 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)))));
16719 
16720     s += 1 * 4;
16721     d += 1 * 2;
16722     n -= 1;
16723   }
16724 
16725   return len;
16726 }
16727 
16728 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)16729 wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul_4x16le__src(
16730     uint8_t* dst_ptr,
16731     size_t dst_len,
16732     uint8_t* dst_palette_ptr,
16733     size_t dst_palette_len,
16734     const uint8_t* src_ptr,
16735     size_t src_len) {
16736   size_t dst_len2 = dst_len / 2;
16737   size_t src_len8 = src_len / 8;
16738   size_t len = (dst_len2 < src_len8) ? dst_len2 : src_len8;
16739   uint8_t* d = dst_ptr;
16740   const uint8_t* s = src_ptr;
16741   size_t n = len;
16742 
16743   // TODO: unroll.
16744 
16745   while (n >= 1) {
16746     wuffs_base__poke_u16le__no_bounds_check(
16747         d + (0 * 2),
16748         wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
16749             wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(
16750                 wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)))));
16751 
16752     s += 1 * 8;
16753     d += 1 * 2;
16754     n -= 1;
16755   }
16756 
16757   return len;
16758 }
16759 
16760 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)16761 wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul__src_over(
16762     uint8_t* dst_ptr,
16763     size_t dst_len,
16764     uint8_t* dst_palette_ptr,
16765     size_t dst_palette_len,
16766     const uint8_t* src_ptr,
16767     size_t src_len) {
16768   size_t dst_len2 = dst_len / 2;
16769   size_t src_len4 = src_len / 4;
16770   size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
16771   uint8_t* d = dst_ptr;
16772   const uint8_t* s = src_ptr;
16773   size_t n = len;
16774 
16775   // TODO: unroll.
16776 
16777   while (n >= 1) {
16778     // Extract 16-bit color components.
16779     uint32_t sa = 0x101 * ((uint32_t)s[3]);
16780     uint32_t sr = 0x101 * ((uint32_t)s[2]);
16781     uint32_t sg = 0x101 * ((uint32_t)s[1]);
16782     uint32_t sb = 0x101 * ((uint32_t)s[0]);
16783 
16784     // Convert from 565 color to 16-bit color.
16785     uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2));
16786     uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11);
16787     uint32_t dr = (0x8421 * old_r5) >> 4;
16788     uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5);
16789     uint32_t dg = (0x1041 * old_g6) >> 2;
16790     uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0);
16791     uint32_t db = (0x8421 * old_b5) >> 4;
16792 
16793     // Calculate the inverse of the src-alpha: how much of the dst to keep.
16794     uint32_t ia = 0xFFFF - sa;
16795 
16796     // Composite src (nonpremul) over dst (premul).
16797     dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
16798     dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
16799     db = ((sb * sa) + (db * ia)) / 0xFFFF;
16800 
16801     // Convert from 16-bit color to 565 color and combine the components.
16802     uint32_t new_r5 = 0x1F & (dr >> 11);
16803     uint32_t new_g6 = 0x3F & (dg >> 10);
16804     uint32_t new_b5 = 0x1F & (db >> 11);
16805     uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0);
16806     wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565);
16807 
16808     s += 1 * 4;
16809     d += 1 * 2;
16810     n -= 1;
16811   }
16812 
16813   return len;
16814 }
16815 
16816 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)16817 wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul_4x16le__src_over(
16818     uint8_t* dst_ptr,
16819     size_t dst_len,
16820     uint8_t* dst_palette_ptr,
16821     size_t dst_palette_len,
16822     const uint8_t* src_ptr,
16823     size_t src_len) {
16824   size_t dst_len2 = dst_len / 2;
16825   size_t src_len8 = src_len / 8;
16826   size_t len = (dst_len2 < src_len8) ? dst_len2 : src_len8;
16827   uint8_t* d = dst_ptr;
16828   const uint8_t* s = src_ptr;
16829   size_t n = len;
16830 
16831   // TODO: unroll.
16832 
16833   while (n >= 1) {
16834     // Extract 16-bit color components.
16835     uint32_t sa = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 6));
16836     uint32_t sr = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 4));
16837     uint32_t sg = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 2));
16838     uint32_t sb = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 0));
16839 
16840     // Convert from 565 color to 16-bit color.
16841     uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2));
16842     uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11);
16843     uint32_t dr = (0x8421 * old_r5) >> 4;
16844     uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5);
16845     uint32_t dg = (0x1041 * old_g6) >> 2;
16846     uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0);
16847     uint32_t db = (0x8421 * old_b5) >> 4;
16848 
16849     // Calculate the inverse of the src-alpha: how much of the dst to keep.
16850     uint32_t ia = 0xFFFF - sa;
16851 
16852     // Composite src (nonpremul) over dst (premul).
16853     dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
16854     dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
16855     db = ((sb * sa) + (db * ia)) / 0xFFFF;
16856 
16857     // Convert from 16-bit color to 565 color and combine the components.
16858     uint32_t new_r5 = 0x1F & (dr >> 11);
16859     uint32_t new_g6 = 0x3F & (dg >> 10);
16860     uint32_t new_b5 = 0x1F & (db >> 11);
16861     uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0);
16862     wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565);
16863 
16864     s += 1 * 8;
16865     d += 1 * 2;
16866     n -= 1;
16867   }
16868 
16869   return len;
16870 }
16871 
16872 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)16873 wuffs_base__pixel_swizzler__bgr_565__bgra_premul__src(uint8_t* dst_ptr,
16874                                                       size_t dst_len,
16875                                                       uint8_t* dst_palette_ptr,
16876                                                       size_t dst_palette_len,
16877                                                       const uint8_t* src_ptr,
16878                                                       size_t src_len) {
16879   size_t dst_len2 = dst_len / 2;
16880   size_t src_len4 = src_len / 4;
16881   size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
16882   uint8_t* d = dst_ptr;
16883   const uint8_t* s = src_ptr;
16884   size_t n = len;
16885 
16886   // TODO: unroll.
16887 
16888   while (n >= 1) {
16889     wuffs_base__poke_u16le__no_bounds_check(
16890         d + (0 * 2), wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
16891                          wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))));
16892 
16893     s += 1 * 4;
16894     d += 1 * 2;
16895     n -= 1;
16896   }
16897 
16898   return len;
16899 }
16900 
16901 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)16902 wuffs_base__pixel_swizzler__bgr_565__bgra_premul__src_over(
16903     uint8_t* dst_ptr,
16904     size_t dst_len,
16905     uint8_t* dst_palette_ptr,
16906     size_t dst_palette_len,
16907     const uint8_t* src_ptr,
16908     size_t src_len) {
16909   size_t dst_len2 = dst_len / 2;
16910   size_t src_len4 = src_len / 4;
16911   size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
16912   uint8_t* d = dst_ptr;
16913   const uint8_t* s = src_ptr;
16914   size_t n = len;
16915 
16916   // TODO: unroll.
16917 
16918   while (n >= 1) {
16919     // Extract 16-bit color components.
16920     uint32_t sa = 0x101 * ((uint32_t)s[3]);
16921     uint32_t sr = 0x101 * ((uint32_t)s[2]);
16922     uint32_t sg = 0x101 * ((uint32_t)s[1]);
16923     uint32_t sb = 0x101 * ((uint32_t)s[0]);
16924 
16925     // Convert from 565 color to 16-bit color.
16926     uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2));
16927     uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11);
16928     uint32_t dr = (0x8421 * old_r5) >> 4;
16929     uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5);
16930     uint32_t dg = (0x1041 * old_g6) >> 2;
16931     uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0);
16932     uint32_t db = (0x8421 * old_b5) >> 4;
16933 
16934     // Calculate the inverse of the src-alpha: how much of the dst to keep.
16935     uint32_t ia = 0xFFFF - sa;
16936 
16937     // Composite src (premul) over dst (premul).
16938     dr = sr + ((dr * ia) / 0xFFFF);
16939     dg = sg + ((dg * ia) / 0xFFFF);
16940     db = sb + ((db * ia) / 0xFFFF);
16941 
16942     // Convert from 16-bit color to 565 color and combine the components.
16943     uint32_t new_r5 = 0x1F & (dr >> 11);
16944     uint32_t new_g6 = 0x3F & (dg >> 10);
16945     uint32_t new_b5 = 0x1F & (db >> 11);
16946     uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0);
16947     wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565);
16948 
16949     s += 1 * 4;
16950     d += 1 * 2;
16951     n -= 1;
16952   }
16953 
16954   return len;
16955 }
16956 
16957 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)16958 wuffs_base__pixel_swizzler__bgr_565__rgb(uint8_t* dst_ptr,
16959                                          size_t dst_len,
16960                                          uint8_t* dst_palette_ptr,
16961                                          size_t dst_palette_len,
16962                                          const uint8_t* src_ptr,
16963                                          size_t src_len) {
16964   size_t dst_len2 = dst_len / 2;
16965   size_t src_len3 = src_len / 3;
16966   size_t len = (dst_len2 < src_len3) ? dst_len2 : src_len3;
16967   uint8_t* d = dst_ptr;
16968   const uint8_t* s = src_ptr;
16969   size_t n = len;
16970 
16971   // TODO: unroll.
16972 
16973   while (n >= 1) {
16974     uint32_t r5 = s[0] >> 3;
16975     uint32_t g6 = s[1] >> 2;
16976     uint32_t b5 = s[2] >> 3;
16977     uint32_t rgb_565 = (r5 << 11) | (g6 << 5) | (b5 << 0);
16978     wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565);
16979 
16980     s += 1 * 3;
16981     d += 1 * 2;
16982     n -= 1;
16983   }
16984 
16985   return len;
16986 }
16987 
16988 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)16989 wuffs_base__pixel_swizzler__bgr_565__rgba_nonpremul__src(
16990     uint8_t* dst_ptr,
16991     size_t dst_len,
16992     uint8_t* dst_palette_ptr,
16993     size_t dst_palette_len,
16994     const uint8_t* src_ptr,
16995     size_t src_len) {
16996   size_t dst_len2 = dst_len / 2;
16997   size_t src_len4 = src_len / 4;
16998   size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
16999   uint8_t* d = dst_ptr;
17000   const uint8_t* s = src_ptr;
17001   size_t n = len;
17002 
17003   // TODO: unroll.
17004 
17005   while (n >= 1) {
17006     wuffs_base__poke_u16le__no_bounds_check(
17007         d + (0 * 2),
17008         wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
17009             wuffs_base__swap_u32_argb_abgr(
17010                 wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
17011                     wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))))));
17012 
17013     s += 1 * 4;
17014     d += 1 * 2;
17015     n -= 1;
17016   }
17017 
17018   return len;
17019 }
17020 
17021 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)17022 wuffs_base__pixel_swizzler__bgr_565__rgba_nonpremul__src_over(
17023     uint8_t* dst_ptr,
17024     size_t dst_len,
17025     uint8_t* dst_palette_ptr,
17026     size_t dst_palette_len,
17027     const uint8_t* src_ptr,
17028     size_t src_len) {
17029   size_t dst_len2 = dst_len / 2;
17030   size_t src_len4 = src_len / 4;
17031   size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
17032   uint8_t* d = dst_ptr;
17033   const uint8_t* s = src_ptr;
17034   size_t n = len;
17035 
17036   // TODO: unroll.
17037 
17038   while (n >= 1) {
17039     // Extract 16-bit color components.
17040     uint32_t sa = 0x101 * ((uint32_t)s[3]);
17041     uint32_t sb = 0x101 * ((uint32_t)s[2]);
17042     uint32_t sg = 0x101 * ((uint32_t)s[1]);
17043     uint32_t sr = 0x101 * ((uint32_t)s[0]);
17044 
17045     // Convert from 565 color to 16-bit color.
17046     uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2));
17047     uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11);
17048     uint32_t dr = (0x8421 * old_r5) >> 4;
17049     uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5);
17050     uint32_t dg = (0x1041 * old_g6) >> 2;
17051     uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0);
17052     uint32_t db = (0x8421 * old_b5) >> 4;
17053 
17054     // Calculate the inverse of the src-alpha: how much of the dst to keep.
17055     uint32_t ia = 0xFFFF - sa;
17056 
17057     // Composite src (nonpremul) over dst (premul).
17058     dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
17059     dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
17060     db = ((sb * sa) + (db * ia)) / 0xFFFF;
17061 
17062     // Convert from 16-bit color to 565 color and combine the components.
17063     uint32_t new_r5 = 0x1F & (dr >> 11);
17064     uint32_t new_g6 = 0x3F & (dg >> 10);
17065     uint32_t new_b5 = 0x1F & (db >> 11);
17066     uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0);
17067     wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565);
17068 
17069     s += 1 * 4;
17070     d += 1 * 2;
17071     n -= 1;
17072   }
17073 
17074   return len;
17075 }
17076 
17077 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)17078 wuffs_base__pixel_swizzler__bgr_565__rgba_premul__src(uint8_t* dst_ptr,
17079                                                       size_t dst_len,
17080                                                       uint8_t* dst_palette_ptr,
17081                                                       size_t dst_palette_len,
17082                                                       const uint8_t* src_ptr,
17083                                                       size_t src_len) {
17084   size_t dst_len2 = dst_len / 2;
17085   size_t src_len4 = src_len / 4;
17086   size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
17087   uint8_t* d = dst_ptr;
17088   const uint8_t* s = src_ptr;
17089   size_t n = len;
17090 
17091   // TODO: unroll.
17092 
17093   while (n >= 1) {
17094     wuffs_base__poke_u16le__no_bounds_check(
17095         d + (0 * 2),
17096         wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
17097             wuffs_base__swap_u32_argb_abgr(
17098                 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)))));
17099 
17100     s += 1 * 4;
17101     d += 1 * 2;
17102     n -= 1;
17103   }
17104 
17105   return len;
17106 }
17107 
17108 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)17109 wuffs_base__pixel_swizzler__bgr_565__rgba_premul__src_over(
17110     uint8_t* dst_ptr,
17111     size_t dst_len,
17112     uint8_t* dst_palette_ptr,
17113     size_t dst_palette_len,
17114     const uint8_t* src_ptr,
17115     size_t src_len) {
17116   size_t dst_len2 = dst_len / 2;
17117   size_t src_len4 = src_len / 4;
17118   size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
17119   uint8_t* d = dst_ptr;
17120   const uint8_t* s = src_ptr;
17121   size_t n = len;
17122 
17123   // TODO: unroll.
17124 
17125   while (n >= 1) {
17126     // Extract 16-bit color components.
17127     uint32_t sa = 0x101 * ((uint32_t)s[3]);
17128     uint32_t sb = 0x101 * ((uint32_t)s[2]);
17129     uint32_t sg = 0x101 * ((uint32_t)s[1]);
17130     uint32_t sr = 0x101 * ((uint32_t)s[0]);
17131 
17132     // Convert from 565 color to 16-bit color.
17133     uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2));
17134     uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11);
17135     uint32_t dr = (0x8421 * old_r5) >> 4;
17136     uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5);
17137     uint32_t dg = (0x1041 * old_g6) >> 2;
17138     uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0);
17139     uint32_t db = (0x8421 * old_b5) >> 4;
17140 
17141     // Calculate the inverse of the src-alpha: how much of the dst to keep.
17142     uint32_t ia = 0xFFFF - sa;
17143 
17144     // Composite src (premul) over dst (premul).
17145     dr = sr + ((dr * ia) / 0xFFFF);
17146     dg = sg + ((dg * ia) / 0xFFFF);
17147     db = sb + ((db * ia) / 0xFFFF);
17148 
17149     // Convert from 16-bit color to 565 color and combine the components.
17150     uint32_t new_r5 = 0x1F & (dr >> 11);
17151     uint32_t new_g6 = 0x3F & (dg >> 10);
17152     uint32_t new_b5 = 0x1F & (db >> 11);
17153     uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0);
17154     wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565);
17155 
17156     s += 1 * 4;
17157     d += 1 * 2;
17158     n -= 1;
17159   }
17160 
17161   return len;
17162 }
17163 
17164 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)17165 wuffs_base__pixel_swizzler__bgr_565__y(uint8_t* dst_ptr,
17166                                        size_t dst_len,
17167                                        uint8_t* dst_palette_ptr,
17168                                        size_t dst_palette_len,
17169                                        const uint8_t* src_ptr,
17170                                        size_t src_len) {
17171   size_t dst_len2 = dst_len / 2;
17172   size_t len = (dst_len2 < src_len) ? dst_len2 : src_len;
17173   uint8_t* d = dst_ptr;
17174   const uint8_t* s = src_ptr;
17175   size_t n = len;
17176 
17177   // TODO: unroll.
17178 
17179   while (n >= 1) {
17180     uint32_t y5 = s[0] >> 3;
17181     uint32_t y6 = s[0] >> 2;
17182     uint32_t rgb_565 = (y5 << 11) | (y6 << 5) | (y5 << 0);
17183     wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565);
17184 
17185     s += 1 * 1;
17186     d += 1 * 2;
17187     n -= 1;
17188   }
17189 
17190   return len;
17191 }
17192 
17193 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)17194 wuffs_base__pixel_swizzler__bgr_565__y_16be(uint8_t* dst_ptr,
17195                                             size_t dst_len,
17196                                             uint8_t* dst_palette_ptr,
17197                                             size_t dst_palette_len,
17198                                             const uint8_t* src_ptr,
17199                                             size_t src_len) {
17200   size_t dst_len2 = dst_len / 2;
17201   size_t src_len2 = src_len / 2;
17202   size_t len = (dst_len2 < src_len2) ? dst_len2 : src_len2;
17203   uint8_t* d = dst_ptr;
17204   const uint8_t* s = src_ptr;
17205   size_t n = len;
17206 
17207   // TODO: unroll.
17208 
17209   while (n >= 1) {
17210     uint32_t y5 = s[0] >> 3;
17211     uint32_t y6 = s[0] >> 2;
17212     uint32_t rgb_565 = (y5 << 11) | (y6 << 5) | (y5 << 0);
17213     wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565);
17214 
17215     s += 1 * 2;
17216     d += 1 * 2;
17217     n -= 1;
17218   }
17219 
17220   return len;
17221 }
17222 
17223 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)17224 wuffs_base__pixel_swizzler__bgr_565__index__src(uint8_t* dst_ptr,
17225                                                 size_t dst_len,
17226                                                 uint8_t* dst_palette_ptr,
17227                                                 size_t dst_palette_len,
17228                                                 const uint8_t* src_ptr,
17229                                                 size_t src_len) {
17230   if (dst_palette_len !=
17231       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
17232     return 0;
17233   }
17234   size_t dst_len2 = dst_len / 2;
17235   size_t len = (dst_len2 < src_len) ? dst_len2 : src_len;
17236   uint8_t* d = dst_ptr;
17237   const uint8_t* s = src_ptr;
17238   size_t n = len;
17239 
17240   const size_t loop_unroll_count = 4;
17241 
17242   while (n >= loop_unroll_count) {
17243     wuffs_base__poke_u16le__no_bounds_check(
17244         d + (0 * 2), wuffs_base__peek_u16le__no_bounds_check(
17245                          dst_palette_ptr + ((size_t)s[0] * 4)));
17246     wuffs_base__poke_u16le__no_bounds_check(
17247         d + (1 * 2), wuffs_base__peek_u16le__no_bounds_check(
17248                          dst_palette_ptr + ((size_t)s[1] * 4)));
17249     wuffs_base__poke_u16le__no_bounds_check(
17250         d + (2 * 2), wuffs_base__peek_u16le__no_bounds_check(
17251                          dst_palette_ptr + ((size_t)s[2] * 4)));
17252     wuffs_base__poke_u16le__no_bounds_check(
17253         d + (3 * 2), wuffs_base__peek_u16le__no_bounds_check(
17254                          dst_palette_ptr + ((size_t)s[3] * 4)));
17255 
17256     s += loop_unroll_count * 1;
17257     d += loop_unroll_count * 2;
17258     n -= loop_unroll_count;
17259   }
17260 
17261   while (n >= 1) {
17262     wuffs_base__poke_u16le__no_bounds_check(
17263         d + (0 * 2), wuffs_base__peek_u16le__no_bounds_check(
17264                          dst_palette_ptr + ((size_t)s[0] * 4)));
17265 
17266     s += 1 * 1;
17267     d += 1 * 2;
17268     n -= 1;
17269   }
17270 
17271   return len;
17272 }
17273 
17274 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)17275 wuffs_base__pixel_swizzler__bgr_565__index_bgra_nonpremul__src_over(
17276     uint8_t* dst_ptr,
17277     size_t dst_len,
17278     uint8_t* dst_palette_ptr,
17279     size_t dst_palette_len,
17280     const uint8_t* src_ptr,
17281     size_t src_len) {
17282   if (dst_palette_len !=
17283       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
17284     return 0;
17285   }
17286   size_t dst_len2 = dst_len / 2;
17287   size_t len = (dst_len2 < src_len) ? dst_len2 : src_len;
17288   uint8_t* d = dst_ptr;
17289   const uint8_t* s = src_ptr;
17290   size_t n = len;
17291 
17292   // TODO: unroll.
17293 
17294   while (n >= 1) {
17295     uint32_t d0 = wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
17296         wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2)));
17297     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
17298                                                           ((size_t)s[0] * 4));
17299     wuffs_base__poke_u16le__no_bounds_check(
17300         d + (0 * 2),
17301         wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
17302             wuffs_base__composite_premul_nonpremul_u32_axxx(d0, s0)));
17303 
17304     s += 1 * 1;
17305     d += 1 * 2;
17306     n -= 1;
17307   }
17308 
17309   return len;
17310 }
17311 
17312 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)17313 wuffs_base__pixel_swizzler__bgr_565__index_binary_alpha__src_over(
17314     uint8_t* dst_ptr,
17315     size_t dst_len,
17316     uint8_t* dst_palette_ptr,
17317     size_t dst_palette_len,
17318     const uint8_t* src_ptr,
17319     size_t src_len) {
17320   if (dst_palette_len !=
17321       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
17322     return 0;
17323   }
17324   size_t dst_len2 = dst_len / 2;
17325   size_t len = (dst_len2 < src_len) ? dst_len2 : src_len;
17326   uint8_t* d = dst_ptr;
17327   const uint8_t* s = src_ptr;
17328   size_t n = len;
17329 
17330   // TODO: unroll.
17331 
17332   while (n >= 1) {
17333     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
17334                                                           ((size_t)s[0] * 4));
17335     if (s0) {
17336       wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)s0);
17337     }
17338 
17339     s += 1 * 1;
17340     d += 1 * 2;
17341     n -= 1;
17342   }
17343 
17344   return len;
17345 }
17346 
17347 // --------
17348 
17349 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)17350 wuffs_base__pixel_swizzler__bgr__bgr_565(uint8_t* dst_ptr,
17351                                          size_t dst_len,
17352                                          uint8_t* dst_palette_ptr,
17353                                          size_t dst_palette_len,
17354                                          const uint8_t* src_ptr,
17355                                          size_t src_len) {
17356   size_t dst_len3 = dst_len / 3;
17357   size_t src_len2 = src_len / 2;
17358   size_t len = (dst_len3 < src_len2) ? dst_len3 : src_len2;
17359   uint8_t* d = dst_ptr;
17360   const uint8_t* s = src_ptr;
17361   size_t n = len;
17362 
17363   // TODO: unroll.
17364 
17365   while (n >= 1) {
17366     uint32_t s0 = wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
17367         wuffs_base__peek_u16le__no_bounds_check(s + (0 * 2)));
17368     wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
17369 
17370     s += 1 * 2;
17371     d += 1 * 3;
17372     n -= 1;
17373   }
17374 
17375   return len;
17376 }
17377 
17378 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)17379 wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src(uint8_t* dst_ptr,
17380                                                      size_t dst_len,
17381                                                      uint8_t* dst_palette_ptr,
17382                                                      size_t dst_palette_len,
17383                                                      const uint8_t* src_ptr,
17384                                                      size_t src_len) {
17385   size_t dst_len3 = dst_len / 3;
17386   size_t src_len4 = src_len / 4;
17387   size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
17388   uint8_t* d = dst_ptr;
17389   const uint8_t* s = src_ptr;
17390   size_t n = len;
17391 
17392   // TODO: unroll.
17393 
17394   while (n >= 1) {
17395     uint32_t s0 =
17396         wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
17397             wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
17398     wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
17399 
17400     s += 1 * 4;
17401     d += 1 * 3;
17402     n -= 1;
17403   }
17404 
17405   return len;
17406 }
17407 
17408 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)17409 wuffs_base__pixel_swizzler__bgr__bgra_nonpremul_4x16le__src(
17410     uint8_t* dst_ptr,
17411     size_t dst_len,
17412     uint8_t* dst_palette_ptr,
17413     size_t dst_palette_len,
17414     const uint8_t* src_ptr,
17415     size_t src_len) {
17416   size_t dst_len3 = dst_len / 3;
17417   size_t src_len8 = src_len / 8;
17418   size_t len = (dst_len3 < src_len8) ? dst_len3 : src_len8;
17419   uint8_t* d = dst_ptr;
17420   const uint8_t* s = src_ptr;
17421   size_t n = len;
17422 
17423   // TODO: unroll.
17424 
17425   while (n >= 1) {
17426     uint32_t s0 =
17427         wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(
17428             wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)));
17429     wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
17430 
17431     s += 1 * 8;
17432     d += 1 * 3;
17433     n -= 1;
17434   }
17435 
17436   return len;
17437 }
17438 
17439 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)17440 wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src_over(
17441     uint8_t* dst_ptr,
17442     size_t dst_len,
17443     uint8_t* dst_palette_ptr,
17444     size_t dst_palette_len,
17445     const uint8_t* src_ptr,
17446     size_t src_len) {
17447   size_t dst_len3 = dst_len / 3;
17448   size_t src_len4 = src_len / 4;
17449   size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
17450   uint8_t* d = dst_ptr;
17451   const uint8_t* s = src_ptr;
17452   size_t n = len;
17453 
17454   // TODO: unroll.
17455 
17456   while (n >= 1) {
17457     // Extract 16-bit color components.
17458     uint32_t sa = 0x101 * ((uint32_t)s[3]);
17459     uint32_t sr = 0x101 * ((uint32_t)s[2]);
17460     uint32_t sg = 0x101 * ((uint32_t)s[1]);
17461     uint32_t sb = 0x101 * ((uint32_t)s[0]);
17462     uint32_t dr = 0x101 * ((uint32_t)d[2]);
17463     uint32_t dg = 0x101 * ((uint32_t)d[1]);
17464     uint32_t db = 0x101 * ((uint32_t)d[0]);
17465 
17466     // Calculate the inverse of the src-alpha: how much of the dst to keep.
17467     uint32_t ia = 0xFFFF - sa;
17468 
17469     // Composite src (nonpremul) over dst (premul).
17470     dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
17471     dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
17472     db = ((sb * sa) + (db * ia)) / 0xFFFF;
17473 
17474     // Convert from 16-bit color to 8-bit color.
17475     d[0] = (uint8_t)(db >> 8);
17476     d[1] = (uint8_t)(dg >> 8);
17477     d[2] = (uint8_t)(dr >> 8);
17478 
17479     s += 1 * 4;
17480     d += 1 * 3;
17481     n -= 1;
17482   }
17483 
17484   return len;
17485 }
17486 
17487 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)17488 wuffs_base__pixel_swizzler__bgr__bgra_nonpremul_4x16le__src_over(
17489     uint8_t* dst_ptr,
17490     size_t dst_len,
17491     uint8_t* dst_palette_ptr,
17492     size_t dst_palette_len,
17493     const uint8_t* src_ptr,
17494     size_t src_len) {
17495   size_t dst_len3 = dst_len / 3;
17496   size_t src_len8 = src_len / 8;
17497   size_t len = (dst_len3 < src_len8) ? dst_len3 : src_len8;
17498   uint8_t* d = dst_ptr;
17499   const uint8_t* s = src_ptr;
17500   size_t n = len;
17501 
17502   // TODO: unroll.
17503 
17504   while (n >= 1) {
17505     // Extract 16-bit color components.
17506     uint32_t sa = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 6));
17507     uint32_t sr = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 4));
17508     uint32_t sg = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 2));
17509     uint32_t sb = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 0));
17510     uint32_t dr = 0x101 * ((uint32_t)d[2]);
17511     uint32_t dg = 0x101 * ((uint32_t)d[1]);
17512     uint32_t db = 0x101 * ((uint32_t)d[0]);
17513 
17514     // Calculate the inverse of the src-alpha: how much of the dst to keep.
17515     uint32_t ia = 0xFFFF - sa;
17516 
17517     // Composite src (nonpremul) over dst (premul).
17518     dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
17519     dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
17520     db = ((sb * sa) + (db * ia)) / 0xFFFF;
17521 
17522     // Convert from 16-bit color to 8-bit color.
17523     d[0] = (uint8_t)(db >> 8);
17524     d[1] = (uint8_t)(dg >> 8);
17525     d[2] = (uint8_t)(dr >> 8);
17526 
17527     s += 1 * 8;
17528     d += 1 * 3;
17529     n -= 1;
17530   }
17531 
17532   return len;
17533 }
17534 
17535 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)17536 wuffs_base__pixel_swizzler__bgr__bgra_premul__src(uint8_t* dst_ptr,
17537                                                   size_t dst_len,
17538                                                   uint8_t* dst_palette_ptr,
17539                                                   size_t dst_palette_len,
17540                                                   const uint8_t* src_ptr,
17541                                                   size_t src_len) {
17542   size_t dst_len3 = dst_len / 3;
17543   size_t src_len4 = src_len / 4;
17544   size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
17545   uint8_t* d = dst_ptr;
17546   const uint8_t* s = src_ptr;
17547   size_t n = len;
17548 
17549   while (n >= 1) {
17550     uint8_t s0 = s[0];
17551     uint8_t s1 = s[1];
17552     uint8_t s2 = s[2];
17553     d[0] = s0;
17554     d[1] = s1;
17555     d[2] = s2;
17556 
17557     s += 1 * 4;
17558     d += 1 * 3;
17559     n -= 1;
17560   }
17561 
17562   return len;
17563 }
17564 
17565 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)17566 wuffs_base__pixel_swizzler__bgr__bgra_premul__src_over(uint8_t* dst_ptr,
17567                                                        size_t dst_len,
17568                                                        uint8_t* dst_palette_ptr,
17569                                                        size_t dst_palette_len,
17570                                                        const uint8_t* src_ptr,
17571                                                        size_t src_len) {
17572   size_t dst_len3 = dst_len / 3;
17573   size_t src_len4 = src_len / 4;
17574   size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
17575   uint8_t* d = dst_ptr;
17576   const uint8_t* s = src_ptr;
17577   size_t n = len;
17578 
17579   while (n >= 1) {
17580     // Extract 16-bit color components.
17581     uint32_t sa = 0x101 * ((uint32_t)s[3]);
17582     uint32_t sr = 0x101 * ((uint32_t)s[2]);
17583     uint32_t sg = 0x101 * ((uint32_t)s[1]);
17584     uint32_t sb = 0x101 * ((uint32_t)s[0]);
17585     uint32_t dr = 0x101 * ((uint32_t)d[2]);
17586     uint32_t dg = 0x101 * ((uint32_t)d[1]);
17587     uint32_t db = 0x101 * ((uint32_t)d[0]);
17588 
17589     // Calculate the inverse of the src-alpha: how much of the dst to keep.
17590     uint32_t ia = 0xFFFF - sa;
17591 
17592     // Composite src (premul) over dst (premul).
17593     dr = sr + ((dr * ia) / 0xFFFF);
17594     dg = sg + ((dg * ia) / 0xFFFF);
17595     db = sb + ((db * ia) / 0xFFFF);
17596 
17597     // Convert from 16-bit color to 8-bit color.
17598     d[0] = (uint8_t)(db >> 8);
17599     d[1] = (uint8_t)(dg >> 8);
17600     d[2] = (uint8_t)(dr >> 8);
17601 
17602     s += 1 * 4;
17603     d += 1 * 3;
17604     n -= 1;
17605   }
17606 
17607   return len;
17608 }
17609 
17610 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)17611 wuffs_base__pixel_swizzler__bgr__rgba_nonpremul__src(uint8_t* dst_ptr,
17612                                                      size_t dst_len,
17613                                                      uint8_t* dst_palette_ptr,
17614                                                      size_t dst_palette_len,
17615                                                      const uint8_t* src_ptr,
17616                                                      size_t src_len) {
17617   size_t dst_len3 = dst_len / 3;
17618   size_t src_len4 = src_len / 4;
17619   size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
17620   uint8_t* d = dst_ptr;
17621   const uint8_t* s = src_ptr;
17622   size_t n = len;
17623 
17624   // TODO: unroll.
17625 
17626   while (n >= 1) {
17627     uint32_t s0 = wuffs_base__swap_u32_argb_abgr(
17628         wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
17629             wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))));
17630     wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
17631 
17632     s += 1 * 4;
17633     d += 1 * 3;
17634     n -= 1;
17635   }
17636 
17637   return len;
17638 }
17639 
17640 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)17641 wuffs_base__pixel_swizzler__bgr__rgba_nonpremul__src_over(
17642     uint8_t* dst_ptr,
17643     size_t dst_len,
17644     uint8_t* dst_palette_ptr,
17645     size_t dst_palette_len,
17646     const uint8_t* src_ptr,
17647     size_t src_len) {
17648   size_t dst_len3 = dst_len / 3;
17649   size_t src_len4 = src_len / 4;
17650   size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
17651   uint8_t* d = dst_ptr;
17652   const uint8_t* s = src_ptr;
17653   size_t n = len;
17654 
17655   // TODO: unroll.
17656 
17657   while (n >= 1) {
17658     // Extract 16-bit color components.
17659     uint32_t sa = 0x101 * ((uint32_t)s[3]);
17660     uint32_t sb = 0x101 * ((uint32_t)s[2]);
17661     uint32_t sg = 0x101 * ((uint32_t)s[1]);
17662     uint32_t sr = 0x101 * ((uint32_t)s[0]);
17663     uint32_t dr = 0x101 * ((uint32_t)d[2]);
17664     uint32_t dg = 0x101 * ((uint32_t)d[1]);
17665     uint32_t db = 0x101 * ((uint32_t)d[0]);
17666 
17667     // Calculate the inverse of the src-alpha: how much of the dst to keep.
17668     uint32_t ia = 0xFFFF - sa;
17669 
17670     // Composite src (nonpremul) over dst (premul).
17671     dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
17672     dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
17673     db = ((sb * sa) + (db * ia)) / 0xFFFF;
17674 
17675     // Convert from 16-bit color to 8-bit color.
17676     d[0] = (uint8_t)(db >> 8);
17677     d[1] = (uint8_t)(dg >> 8);
17678     d[2] = (uint8_t)(dr >> 8);
17679 
17680     s += 1 * 4;
17681     d += 1 * 3;
17682     n -= 1;
17683   }
17684 
17685   return len;
17686 }
17687 
17688 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)17689 wuffs_base__pixel_swizzler__bgr__rgba_premul__src(uint8_t* dst_ptr,
17690                                                   size_t dst_len,
17691                                                   uint8_t* dst_palette_ptr,
17692                                                   size_t dst_palette_len,
17693                                                   const uint8_t* src_ptr,
17694                                                   size_t src_len) {
17695   size_t dst_len3 = dst_len / 3;
17696   size_t src_len4 = src_len / 4;
17697   size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
17698   uint8_t* d = dst_ptr;
17699   const uint8_t* s = src_ptr;
17700   size_t n = len;
17701 
17702   while (n >= 1) {
17703     uint8_t s0 = s[0];
17704     uint8_t s1 = s[1];
17705     uint8_t s2 = s[2];
17706     d[0] = s2;
17707     d[1] = s1;
17708     d[2] = s0;
17709 
17710     s += 1 * 4;
17711     d += 1 * 3;
17712     n -= 1;
17713   }
17714 
17715   return len;
17716 }
17717 
17718 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)17719 wuffs_base__pixel_swizzler__bgr__rgba_premul__src_over(uint8_t* dst_ptr,
17720                                                        size_t dst_len,
17721                                                        uint8_t* dst_palette_ptr,
17722                                                        size_t dst_palette_len,
17723                                                        const uint8_t* src_ptr,
17724                                                        size_t src_len) {
17725   size_t dst_len3 = dst_len / 3;
17726   size_t src_len4 = src_len / 4;
17727   size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
17728   uint8_t* d = dst_ptr;
17729   const uint8_t* s = src_ptr;
17730   size_t n = len;
17731 
17732   while (n >= 1) {
17733     // Extract 16-bit color components.
17734     uint32_t sa = 0x101 * ((uint32_t)s[3]);
17735     uint32_t sb = 0x101 * ((uint32_t)s[2]);
17736     uint32_t sg = 0x101 * ((uint32_t)s[1]);
17737     uint32_t sr = 0x101 * ((uint32_t)s[0]);
17738     uint32_t dr = 0x101 * ((uint32_t)d[2]);
17739     uint32_t dg = 0x101 * ((uint32_t)d[1]);
17740     uint32_t db = 0x101 * ((uint32_t)d[0]);
17741 
17742     // Calculate the inverse of the src-alpha: how much of the dst to keep.
17743     uint32_t ia = 0xFFFF - sa;
17744 
17745     // Composite src (premul) over dst (premul).
17746     dr = sr + ((dr * ia) / 0xFFFF);
17747     dg = sg + ((dg * ia) / 0xFFFF);
17748     db = sb + ((db * ia) / 0xFFFF);
17749 
17750     // Convert from 16-bit color to 8-bit color.
17751     d[0] = (uint8_t)(db >> 8);
17752     d[1] = (uint8_t)(dg >> 8);
17753     d[2] = (uint8_t)(dr >> 8);
17754 
17755     s += 1 * 4;
17756     d += 1 * 3;
17757     n -= 1;
17758   }
17759 
17760   return len;
17761 }
17762 
17763 // --------
17764 
17765 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)17766 wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul__src_over(
17767     uint8_t* dst_ptr,
17768     size_t dst_len,
17769     uint8_t* dst_palette_ptr,
17770     size_t dst_palette_len,
17771     const uint8_t* src_ptr,
17772     size_t src_len) {
17773   size_t dst_len4 = dst_len / 4;
17774   size_t src_len4 = src_len / 4;
17775   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
17776   uint8_t* d = dst_ptr;
17777   const uint8_t* s = src_ptr;
17778   size_t n = len;
17779 
17780   while (n >= 1) {
17781     uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
17782     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
17783     wuffs_base__poke_u32le__no_bounds_check(
17784         d + (0 * 4),
17785         wuffs_base__composite_nonpremul_nonpremul_u32_axxx(d0, s0));
17786 
17787     s += 1 * 4;
17788     d += 1 * 4;
17789     n -= 1;
17790   }
17791 
17792   return len;
17793 }
17794 
17795 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)17796 wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul_4x16le__src(
17797     uint8_t* dst_ptr,
17798     size_t dst_len,
17799     uint8_t* dst_palette_ptr,
17800     size_t dst_palette_len,
17801     const uint8_t* src_ptr,
17802     size_t src_len) {
17803   size_t dst_len4 = dst_len / 4;
17804   size_t src_len8 = src_len / 8;
17805   size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
17806   uint8_t* d = dst_ptr;
17807   const uint8_t* s = src_ptr;
17808 
17809   size_t n = len;
17810   while (n >= 1) {
17811     wuffs_base__poke_u32le__no_bounds_check(
17812         d + (0 * 4), wuffs_base__color_u64__as__color_u32(
17813                          wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8))));
17814 
17815     s += 1 * 8;
17816     d += 1 * 4;
17817     n -= 1;
17818   }
17819   return len;
17820 }
17821 
17822 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)17823 wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul_4x16le__src_over(
17824     uint8_t* dst_ptr,
17825     size_t dst_len,
17826     uint8_t* dst_palette_ptr,
17827     size_t dst_palette_len,
17828     const uint8_t* src_ptr,
17829     size_t src_len) {
17830   size_t dst_len4 = dst_len / 4;
17831   size_t src_len8 = src_len / 8;
17832   size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
17833   uint8_t* d = dst_ptr;
17834   const uint8_t* s = src_ptr;
17835   size_t n = len;
17836 
17837   while (n >= 1) {
17838     uint64_t d0 = wuffs_base__color_u32__as__color_u64(
17839         wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)));
17840     uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8));
17841     wuffs_base__poke_u32le__no_bounds_check(
17842         d + (0 * 4),
17843         wuffs_base__color_u64__as__color_u32(
17844             wuffs_base__composite_nonpremul_nonpremul_u64_axxx(d0, s0)));
17845 
17846     s += 1 * 8;
17847     d += 1 * 4;
17848     n -= 1;
17849   }
17850 
17851   return len;
17852 }
17853 
17854 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)17855 wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src(
17856     uint8_t* dst_ptr,
17857     size_t dst_len,
17858     uint8_t* dst_palette_ptr,
17859     size_t dst_palette_len,
17860     const uint8_t* src_ptr,
17861     size_t src_len) {
17862   size_t dst_len4 = dst_len / 4;
17863   size_t src_len4 = src_len / 4;
17864   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
17865   uint8_t* d = dst_ptr;
17866   const uint8_t* s = src_ptr;
17867   size_t n = len;
17868 
17869   while (n >= 1) {
17870     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
17871     wuffs_base__poke_u32le__no_bounds_check(
17872         d + (0 * 4),
17873         wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(s0));
17874 
17875     s += 1 * 4;
17876     d += 1 * 4;
17877     n -= 1;
17878   }
17879 
17880   return len;
17881 }
17882 
17883 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)17884 wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src_over(
17885     uint8_t* dst_ptr,
17886     size_t dst_len,
17887     uint8_t* dst_palette_ptr,
17888     size_t dst_palette_len,
17889     const uint8_t* src_ptr,
17890     size_t src_len) {
17891   size_t dst_len4 = dst_len / 4;
17892   size_t src_len4 = src_len / 4;
17893   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
17894   uint8_t* d = dst_ptr;
17895   const uint8_t* s = src_ptr;
17896   size_t n = len;
17897 
17898   while (n >= 1) {
17899     uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
17900     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
17901     wuffs_base__poke_u32le__no_bounds_check(
17902         d + (0 * 4), wuffs_base__composite_nonpremul_premul_u32_axxx(d0, s0));
17903 
17904     s += 1 * 4;
17905     d += 1 * 4;
17906     n -= 1;
17907   }
17908 
17909   return len;
17910 }
17911 
17912 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)17913 wuffs_base__pixel_swizzler__bgra_nonpremul__index_bgra_nonpremul__src_over(
17914     uint8_t* dst_ptr,
17915     size_t dst_len,
17916     uint8_t* dst_palette_ptr,
17917     size_t dst_palette_len,
17918     const uint8_t* src_ptr,
17919     size_t src_len) {
17920   if (dst_palette_len !=
17921       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
17922     return 0;
17923   }
17924   size_t dst_len4 = dst_len / 4;
17925   size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
17926   uint8_t* d = dst_ptr;
17927   const uint8_t* s = src_ptr;
17928   size_t n = len;
17929 
17930   // TODO: unroll.
17931 
17932   while (n >= 1) {
17933     uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
17934     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
17935                                                           ((size_t)s[0] * 4));
17936     wuffs_base__poke_u32le__no_bounds_check(
17937         d + (0 * 4),
17938         wuffs_base__composite_nonpremul_nonpremul_u32_axxx(d0, s0));
17939 
17940     s += 1 * 1;
17941     d += 1 * 4;
17942     n -= 1;
17943   }
17944 
17945   return len;
17946 }
17947 
17948 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)17949 wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_nonpremul__src_over(
17950     uint8_t* dst_ptr,
17951     size_t dst_len,
17952     uint8_t* dst_palette_ptr,
17953     size_t dst_palette_len,
17954     const uint8_t* src_ptr,
17955     size_t src_len) {
17956   size_t dst_len4 = dst_len / 4;
17957   size_t src_len4 = src_len / 4;
17958   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
17959   uint8_t* d = dst_ptr;
17960   const uint8_t* s = src_ptr;
17961   size_t n = len;
17962 
17963   while (n >= 1) {
17964     uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
17965     uint32_t s0 = wuffs_base__swap_u32_argb_abgr(
17966         wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
17967     wuffs_base__poke_u32le__no_bounds_check(
17968         d + (0 * 4),
17969         wuffs_base__composite_nonpremul_nonpremul_u32_axxx(d0, s0));
17970 
17971     s += 1 * 4;
17972     d += 1 * 4;
17973     n -= 1;
17974   }
17975 
17976   return len;
17977 }
17978 
17979 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)17980 wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src(
17981     uint8_t* dst_ptr,
17982     size_t dst_len,
17983     uint8_t* dst_palette_ptr,
17984     size_t dst_palette_len,
17985     const uint8_t* src_ptr,
17986     size_t src_len) {
17987   size_t dst_len4 = dst_len / 4;
17988   size_t src_len4 = src_len / 4;
17989   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
17990   uint8_t* d = dst_ptr;
17991   const uint8_t* s = src_ptr;
17992   size_t n = len;
17993 
17994   while (n >= 1) {
17995     uint32_t s0 = wuffs_base__swap_u32_argb_abgr(
17996         wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
17997     wuffs_base__poke_u32le__no_bounds_check(
17998         d + (0 * 4),
17999         wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(s0));
18000 
18001     s += 1 * 4;
18002     d += 1 * 4;
18003     n -= 1;
18004   }
18005 
18006   return len;
18007 }
18008 
18009 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)18010 wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src_over(
18011     uint8_t* dst_ptr,
18012     size_t dst_len,
18013     uint8_t* dst_palette_ptr,
18014     size_t dst_palette_len,
18015     const uint8_t* src_ptr,
18016     size_t src_len) {
18017   size_t dst_len4 = dst_len / 4;
18018   size_t src_len4 = src_len / 4;
18019   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
18020   uint8_t* d = dst_ptr;
18021   const uint8_t* s = src_ptr;
18022   size_t n = len;
18023 
18024   while (n >= 1) {
18025     uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
18026     uint32_t s0 = wuffs_base__swap_u32_argb_abgr(
18027         wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
18028     wuffs_base__poke_u32le__no_bounds_check(
18029         d + (0 * 4), wuffs_base__composite_nonpremul_premul_u32_axxx(d0, s0));
18030 
18031     s += 1 * 4;
18032     d += 1 * 4;
18033     n -= 1;
18034   }
18035 
18036   return len;
18037 }
18038 
18039 // --------
18040 
18041 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)18042 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul__src(
18043     uint8_t* dst_ptr,
18044     size_t dst_len,
18045     uint8_t* dst_palette_ptr,
18046     size_t dst_palette_len,
18047     const uint8_t* src_ptr,
18048     size_t src_len) {
18049   size_t dst_len8 = dst_len / 8;
18050   size_t src_len4 = src_len / 4;
18051   size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
18052   uint8_t* d = dst_ptr;
18053   const uint8_t* s = src_ptr;
18054 
18055   size_t n = len;
18056   while (n >= 1) {
18057     uint8_t s0 = s[0];
18058     uint8_t s1 = s[1];
18059     uint8_t s2 = s[2];
18060     uint8_t s3 = s[3];
18061     d[0] = s0;
18062     d[1] = s0;
18063     d[2] = s1;
18064     d[3] = s1;
18065     d[4] = s2;
18066     d[5] = s2;
18067     d[6] = s3;
18068     d[7] = s3;
18069 
18070     s += 1 * 4;
18071     d += 1 * 8;
18072     n -= 1;
18073   }
18074   return len;
18075 }
18076 
18077 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)18078 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul__src_over(
18079     uint8_t* dst_ptr,
18080     size_t dst_len,
18081     uint8_t* dst_palette_ptr,
18082     size_t dst_palette_len,
18083     const uint8_t* src_ptr,
18084     size_t src_len) {
18085   size_t dst_len8 = dst_len / 8;
18086   size_t src_len4 = src_len / 4;
18087   size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
18088   uint8_t* d = dst_ptr;
18089   const uint8_t* s = src_ptr;
18090 
18091   size_t n = len;
18092   while (n >= 1) {
18093     uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8));
18094     uint64_t s0 = wuffs_base__color_u32__as__color_u64(
18095         wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
18096     wuffs_base__poke_u64le__no_bounds_check(
18097         d + (0 * 8),
18098         wuffs_base__composite_nonpremul_nonpremul_u64_axxx(d0, s0));
18099 
18100     s += 1 * 4;
18101     d += 1 * 8;
18102     n -= 1;
18103   }
18104   return len;
18105 }
18106 
18107 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)18108 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul_4x16le__src_over(
18109     uint8_t* dst_ptr,
18110     size_t dst_len,
18111     uint8_t* dst_palette_ptr,
18112     size_t dst_palette_len,
18113     const uint8_t* src_ptr,
18114     size_t src_len) {
18115   size_t dst_len8 = dst_len / 8;
18116   size_t src_len8 = src_len / 8;
18117   size_t len = (dst_len8 < src_len8) ? dst_len8 : src_len8;
18118   uint8_t* d = dst_ptr;
18119   const uint8_t* s = src_ptr;
18120 
18121   size_t n = len;
18122   while (n >= 1) {
18123     uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8));
18124     uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8));
18125     wuffs_base__poke_u64le__no_bounds_check(
18126         d + (0 * 8),
18127         wuffs_base__composite_nonpremul_nonpremul_u64_axxx(d0, s0));
18128 
18129     s += 1 * 8;
18130     d += 1 * 8;
18131     n -= 1;
18132   }
18133   return len;
18134 }
18135 
18136 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)18137 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_premul__src(
18138     uint8_t* dst_ptr,
18139     size_t dst_len,
18140     uint8_t* dst_palette_ptr,
18141     size_t dst_palette_len,
18142     const uint8_t* src_ptr,
18143     size_t src_len) {
18144   size_t dst_len8 = dst_len / 8;
18145   size_t src_len4 = src_len / 4;
18146   size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
18147   uint8_t* d = dst_ptr;
18148   const uint8_t* s = src_ptr;
18149 
18150   size_t n = len;
18151   while (n >= 1) {
18152     uint64_t s0 = wuffs_base__color_u32__as__color_u64(
18153         wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
18154             wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))));
18155     wuffs_base__poke_u64le__no_bounds_check(d + (0 * 8), s0);
18156 
18157     s += 1 * 4;
18158     d += 1 * 8;
18159     n -= 1;
18160   }
18161   return len;
18162 }
18163 
18164 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)18165 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_premul__src_over(
18166     uint8_t* dst_ptr,
18167     size_t dst_len,
18168     uint8_t* dst_palette_ptr,
18169     size_t dst_palette_len,
18170     const uint8_t* src_ptr,
18171     size_t src_len) {
18172   size_t dst_len8 = dst_len / 8;
18173   size_t src_len4 = src_len / 4;
18174   size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
18175   uint8_t* d = dst_ptr;
18176   const uint8_t* s = src_ptr;
18177 
18178   size_t n = len;
18179   while (n >= 1) {
18180     uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8));
18181     uint64_t s0 = wuffs_base__color_u32__as__color_u64(
18182         wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
18183     wuffs_base__poke_u64le__no_bounds_check(
18184         d + (0 * 8), wuffs_base__composite_nonpremul_premul_u64_axxx(d0, s0));
18185 
18186     s += 1 * 4;
18187     d += 1 * 8;
18188     n -= 1;
18189   }
18190   return len;
18191 }
18192 
18193 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)18194 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__index_bgra_nonpremul__src_over(
18195     uint8_t* dst_ptr,
18196     size_t dst_len,
18197     uint8_t* dst_palette_ptr,
18198     size_t dst_palette_len,
18199     const uint8_t* src_ptr,
18200     size_t src_len) {
18201   if (dst_palette_len !=
18202       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
18203     return 0;
18204   }
18205   size_t dst_len8 = dst_len / 8;
18206   size_t len = (dst_len8 < src_len) ? dst_len8 : src_len;
18207   uint8_t* d = dst_ptr;
18208   const uint8_t* s = src_ptr;
18209   size_t n = len;
18210 
18211   while (n >= 1) {
18212     uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8));
18213     uint64_t s0 = wuffs_base__color_u32__as__color_u64(
18214         wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
18215                                                 ((size_t)s[0] * 4)));
18216     wuffs_base__poke_u64le__no_bounds_check(
18217         d + (0 * 8),
18218         wuffs_base__composite_nonpremul_nonpremul_u64_axxx(d0, s0));
18219 
18220     s += 1 * 1;
18221     d += 1 * 8;
18222     n -= 1;
18223   }
18224 
18225   return len;
18226 }
18227 
18228 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)18229 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_nonpremul__src(
18230     uint8_t* dst_ptr,
18231     size_t dst_len,
18232     uint8_t* dst_palette_ptr,
18233     size_t dst_palette_len,
18234     const uint8_t* src_ptr,
18235     size_t src_len) {
18236   size_t dst_len8 = dst_len / 8;
18237   size_t src_len4 = src_len / 4;
18238   size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
18239   uint8_t* d = dst_ptr;
18240   const uint8_t* s = src_ptr;
18241 
18242   size_t n = len;
18243   while (n >= 1) {
18244     uint8_t s0 = s[0];
18245     uint8_t s1 = s[1];
18246     uint8_t s2 = s[2];
18247     uint8_t s3 = s[3];
18248     d[0] = s2;
18249     d[1] = s2;
18250     d[2] = s1;
18251     d[3] = s1;
18252     d[4] = s0;
18253     d[5] = s0;
18254     d[6] = s3;
18255     d[7] = s3;
18256 
18257     s += 1 * 4;
18258     d += 1 * 8;
18259     n -= 1;
18260   }
18261   return len;
18262 }
18263 
18264 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)18265 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_nonpremul__src_over(
18266     uint8_t* dst_ptr,
18267     size_t dst_len,
18268     uint8_t* dst_palette_ptr,
18269     size_t dst_palette_len,
18270     const uint8_t* src_ptr,
18271     size_t src_len) {
18272   size_t dst_len8 = dst_len / 8;
18273   size_t src_len4 = src_len / 4;
18274   size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
18275   uint8_t* d = dst_ptr;
18276   const uint8_t* s = src_ptr;
18277 
18278   size_t n = len;
18279   while (n >= 1) {
18280     uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8));
18281     uint64_t s0 =
18282         wuffs_base__color_u32__as__color_u64(wuffs_base__swap_u32_argb_abgr(
18283             wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))));
18284     wuffs_base__poke_u64le__no_bounds_check(
18285         d + (0 * 8),
18286         wuffs_base__composite_nonpremul_nonpremul_u64_axxx(d0, s0));
18287 
18288     s += 1 * 4;
18289     d += 1 * 8;
18290     n -= 1;
18291   }
18292   return len;
18293 }
18294 
18295 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)18296 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_premul__src(
18297     uint8_t* dst_ptr,
18298     size_t dst_len,
18299     uint8_t* dst_palette_ptr,
18300     size_t dst_palette_len,
18301     const uint8_t* src_ptr,
18302     size_t src_len) {
18303   size_t dst_len8 = dst_len / 8;
18304   size_t src_len4 = src_len / 4;
18305   size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
18306   uint8_t* d = dst_ptr;
18307   const uint8_t* s = src_ptr;
18308 
18309   size_t n = len;
18310   while (n >= 1) {
18311     uint64_t s0 = wuffs_base__color_u32__as__color_u64(
18312         wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
18313             wuffs_base__swap_u32_argb_abgr(
18314                 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)))));
18315     wuffs_base__poke_u64le__no_bounds_check(d + (0 * 8), s0);
18316 
18317     s += 1 * 4;
18318     d += 1 * 8;
18319     n -= 1;
18320   }
18321   return len;
18322 }
18323 
18324 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)18325 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_premul__src_over(
18326     uint8_t* dst_ptr,
18327     size_t dst_len,
18328     uint8_t* dst_palette_ptr,
18329     size_t dst_palette_len,
18330     const uint8_t* src_ptr,
18331     size_t src_len) {
18332   size_t dst_len8 = dst_len / 8;
18333   size_t src_len4 = src_len / 4;
18334   size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
18335   uint8_t* d = dst_ptr;
18336   const uint8_t* s = src_ptr;
18337 
18338   size_t n = len;
18339   while (n >= 1) {
18340     uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8));
18341     uint64_t s0 =
18342         wuffs_base__color_u32__as__color_u64(wuffs_base__swap_u32_argb_abgr(
18343             wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))));
18344     wuffs_base__poke_u64le__no_bounds_check(
18345         d + (0 * 8), wuffs_base__composite_nonpremul_premul_u64_axxx(d0, s0));
18346 
18347     s += 1 * 4;
18348     d += 1 * 8;
18349     n -= 1;
18350   }
18351   return len;
18352 }
18353 
18354 // --------
18355 
18356 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)18357 wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src(
18358     uint8_t* dst_ptr,
18359     size_t dst_len,
18360     uint8_t* dst_palette_ptr,
18361     size_t dst_palette_len,
18362     const uint8_t* src_ptr,
18363     size_t src_len) {
18364   size_t dst_len4 = dst_len / 4;
18365   size_t src_len4 = src_len / 4;
18366   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
18367   uint8_t* d = dst_ptr;
18368   const uint8_t* s = src_ptr;
18369   size_t n = len;
18370 
18371   // TODO: unroll.
18372 
18373   while (n >= 1) {
18374     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
18375     wuffs_base__poke_u32le__no_bounds_check(
18376         d + (0 * 4),
18377         wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(s0));
18378 
18379     s += 1 * 4;
18380     d += 1 * 4;
18381     n -= 1;
18382   }
18383 
18384   return len;
18385 }
18386 
18387 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)18388 wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul_4x16le__src(
18389     uint8_t* dst_ptr,
18390     size_t dst_len,
18391     uint8_t* dst_palette_ptr,
18392     size_t dst_palette_len,
18393     const uint8_t* src_ptr,
18394     size_t src_len) {
18395   size_t dst_len4 = dst_len / 4;
18396   size_t src_len8 = src_len / 8;
18397   size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
18398   uint8_t* d = dst_ptr;
18399   const uint8_t* s = src_ptr;
18400   size_t n = len;
18401 
18402   // TODO: unroll.
18403 
18404   while (n >= 1) {
18405     uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8));
18406     wuffs_base__poke_u32le__no_bounds_check(
18407         d + (0 * 4),
18408         wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(s0));
18409 
18410     s += 1 * 8;
18411     d += 1 * 4;
18412     n -= 1;
18413   }
18414 
18415   return len;
18416 }
18417 
18418 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)18419 wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src_over(
18420     uint8_t* dst_ptr,
18421     size_t dst_len,
18422     uint8_t* dst_palette_ptr,
18423     size_t dst_palette_len,
18424     const uint8_t* src_ptr,
18425     size_t src_len) {
18426   size_t dst_len4 = dst_len / 4;
18427   size_t src_len4 = src_len / 4;
18428   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
18429   uint8_t* d = dst_ptr;
18430   const uint8_t* s = src_ptr;
18431   size_t n = len;
18432 
18433   // TODO: unroll.
18434 
18435   while (n >= 1) {
18436     uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
18437     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
18438     wuffs_base__poke_u32le__no_bounds_check(
18439         d + (0 * 4), wuffs_base__composite_premul_nonpremul_u32_axxx(d0, s0));
18440 
18441     s += 1 * 4;
18442     d += 1 * 4;
18443     n -= 1;
18444   }
18445 
18446   return len;
18447 }
18448 
18449 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)18450 wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul_4x16le__src_over(
18451     uint8_t* dst_ptr,
18452     size_t dst_len,
18453     uint8_t* dst_palette_ptr,
18454     size_t dst_palette_len,
18455     const uint8_t* src_ptr,
18456     size_t src_len) {
18457   size_t dst_len4 = dst_len / 4;
18458   size_t src_len8 = src_len / 8;
18459   size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
18460   uint8_t* d = dst_ptr;
18461   const uint8_t* s = src_ptr;
18462   size_t n = len;
18463 
18464   // TODO: unroll.
18465 
18466   while (n >= 1) {
18467     uint64_t d0 = wuffs_base__color_u32__as__color_u64(
18468         wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)));
18469     uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8));
18470     wuffs_base__poke_u32le__no_bounds_check(
18471         d + (0 * 4),
18472         wuffs_base__color_u64__as__color_u32(
18473             wuffs_base__composite_premul_nonpremul_u64_axxx(d0, s0)));
18474 
18475     s += 1 * 8;
18476     d += 1 * 4;
18477     n -= 1;
18478   }
18479 
18480   return len;
18481 }
18482 
18483 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)18484 wuffs_base__pixel_swizzler__bgra_premul__bgra_premul__src_over(
18485     uint8_t* dst_ptr,
18486     size_t dst_len,
18487     uint8_t* dst_palette_ptr,
18488     size_t dst_palette_len,
18489     const uint8_t* src_ptr,
18490     size_t src_len) {
18491   size_t dst_len4 = dst_len / 4;
18492   size_t src_len4 = src_len / 4;
18493   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
18494   uint8_t* d = dst_ptr;
18495   const uint8_t* s = src_ptr;
18496   size_t n = len;
18497 
18498   // TODO: unroll.
18499 
18500   while (n >= 1) {
18501     uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
18502     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
18503     wuffs_base__poke_u32le__no_bounds_check(
18504         d + (0 * 4), wuffs_base__composite_premul_premul_u32_axxx(d0, s0));
18505 
18506     s += 1 * 4;
18507     d += 1 * 4;
18508     n -= 1;
18509   }
18510 
18511   return len;
18512 }
18513 
18514 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)18515 wuffs_base__pixel_swizzler__bgra_premul__index_bgra_nonpremul__src_over(
18516     uint8_t* dst_ptr,
18517     size_t dst_len,
18518     uint8_t* dst_palette_ptr,
18519     size_t dst_palette_len,
18520     const uint8_t* src_ptr,
18521     size_t src_len) {
18522   if (dst_palette_len !=
18523       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
18524     return 0;
18525   }
18526   size_t dst_len4 = dst_len / 4;
18527   size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
18528   uint8_t* d = dst_ptr;
18529   const uint8_t* s = src_ptr;
18530   size_t n = len;
18531 
18532   // TODO: unroll.
18533 
18534   while (n >= 1) {
18535     uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
18536     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
18537                                                           ((size_t)s[0] * 4));
18538     wuffs_base__poke_u32le__no_bounds_check(
18539         d + (0 * 4), wuffs_base__composite_premul_nonpremul_u32_axxx(d0, s0));
18540 
18541     s += 1 * 1;
18542     d += 1 * 4;
18543     n -= 1;
18544   }
18545 
18546   return len;
18547 }
18548 
18549 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)18550 wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src(
18551     uint8_t* dst_ptr,
18552     size_t dst_len,
18553     uint8_t* dst_palette_ptr,
18554     size_t dst_palette_len,
18555     const uint8_t* src_ptr,
18556     size_t src_len) {
18557   size_t dst_len4 = dst_len / 4;
18558   size_t src_len4 = src_len / 4;
18559   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
18560   uint8_t* d = dst_ptr;
18561   const uint8_t* s = src_ptr;
18562   size_t n = len;
18563 
18564   // TODO: unroll.
18565 
18566   while (n >= 1) {
18567     uint32_t s0 = wuffs_base__swap_u32_argb_abgr(
18568         wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
18569     wuffs_base__poke_u32le__no_bounds_check(
18570         d + (0 * 4),
18571         wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(s0));
18572 
18573     s += 1 * 4;
18574     d += 1 * 4;
18575     n -= 1;
18576   }
18577 
18578   return len;
18579 }
18580 
18581 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)18582 wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src_over(
18583     uint8_t* dst_ptr,
18584     size_t dst_len,
18585     uint8_t* dst_palette_ptr,
18586     size_t dst_palette_len,
18587     const uint8_t* src_ptr,
18588     size_t src_len) {
18589   size_t dst_len4 = dst_len / 4;
18590   size_t src_len4 = src_len / 4;
18591   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
18592   uint8_t* d = dst_ptr;
18593   const uint8_t* s = src_ptr;
18594   size_t n = len;
18595 
18596   // TODO: unroll.
18597 
18598   while (n >= 1) {
18599     uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
18600     uint32_t s0 = wuffs_base__swap_u32_argb_abgr(
18601         wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
18602     wuffs_base__poke_u32le__no_bounds_check(
18603         d + (0 * 4), wuffs_base__composite_premul_nonpremul_u32_axxx(d0, s0));
18604 
18605     s += 1 * 4;
18606     d += 1 * 4;
18607     n -= 1;
18608   }
18609 
18610   return len;
18611 }
18612 
18613 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)18614 wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul_4x16le__src(
18615     uint8_t* dst_ptr,
18616     size_t dst_len,
18617     uint8_t* dst_palette_ptr,
18618     size_t dst_palette_len,
18619     const uint8_t* src_ptr,
18620     size_t src_len) {
18621   size_t dst_len4 = dst_len / 4;
18622   size_t src_len8 = src_len / 8;
18623   size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
18624   uint8_t* d = dst_ptr;
18625   const uint8_t* s = src_ptr;
18626   size_t n = len;
18627 
18628   // TODO: unroll.
18629 
18630   while (n >= 1) {
18631     uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8));
18632     wuffs_base__poke_u32le__no_bounds_check(
18633         d + (0 * 4),
18634         wuffs_base__swap_u32_argb_abgr(
18635             wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(
18636                 s0)));
18637 
18638     s += 1 * 8;
18639     d += 1 * 4;
18640     n -= 1;
18641   }
18642 
18643   return len;
18644 }
18645 
18646 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)18647 wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul_4x16le__src_over(
18648     uint8_t* dst_ptr,
18649     size_t dst_len,
18650     uint8_t* dst_palette_ptr,
18651     size_t dst_palette_len,
18652     const uint8_t* src_ptr,
18653     size_t src_len) {
18654   size_t dst_len4 = dst_len / 4;
18655   size_t src_len8 = src_len / 8;
18656   size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
18657   uint8_t* d = dst_ptr;
18658   const uint8_t* s = src_ptr;
18659   size_t n = len;
18660 
18661   // TODO: unroll.
18662 
18663   while (n >= 1) {
18664     uint64_t d0 = wuffs_base__color_u32__as__color_u64(
18665         wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)));
18666     uint64_t s0 = wuffs_base__swap_u64_argb_abgr(
18667         wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)));
18668     wuffs_base__poke_u32le__no_bounds_check(
18669         d + (0 * 4),
18670         wuffs_base__color_u64__as__color_u32(
18671             wuffs_base__composite_premul_nonpremul_u64_axxx(d0, s0)));
18672 
18673     s += 1 * 8;
18674     d += 1 * 4;
18675     n -= 1;
18676   }
18677 
18678   return len;
18679 }
18680 
18681 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)18682 wuffs_base__pixel_swizzler__bgra_premul__rgba_premul__src_over(
18683     uint8_t* dst_ptr,
18684     size_t dst_len,
18685     uint8_t* dst_palette_ptr,
18686     size_t dst_palette_len,
18687     const uint8_t* src_ptr,
18688     size_t src_len) {
18689   size_t dst_len4 = dst_len / 4;
18690   size_t src_len4 = src_len / 4;
18691   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
18692   uint8_t* d = dst_ptr;
18693   const uint8_t* s = src_ptr;
18694   size_t n = len;
18695 
18696   while (n >= 1) {
18697     uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
18698     uint32_t s0 = wuffs_base__swap_u32_argb_abgr(
18699         wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
18700     wuffs_base__poke_u32le__no_bounds_check(
18701         d + (0 * 4), wuffs_base__composite_premul_premul_u32_axxx(d0, s0));
18702 
18703     s += 1 * 4;
18704     d += 1 * 4;
18705     n -= 1;
18706   }
18707 
18708   return len;
18709 }
18710 
18711 // --------
18712 
18713 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)18714 wuffs_base__pixel_swizzler__bgrw__bgr(uint8_t* dst_ptr,
18715                                       size_t dst_len,
18716                                       uint8_t* dst_palette_ptr,
18717                                       size_t dst_palette_len,
18718                                       const uint8_t* src_ptr,
18719                                       size_t src_len) {
18720   size_t dst_len4 = dst_len / 4;
18721   size_t src_len3 = src_len / 3;
18722   size_t len = (dst_len4 < src_len3) ? dst_len4 : src_len3;
18723   uint8_t* d = dst_ptr;
18724   const uint8_t* s = src_ptr;
18725   size_t n = len;
18726 
18727   // TODO: unroll.
18728 
18729   while (n >= 1) {
18730     wuffs_base__poke_u32le__no_bounds_check(
18731         d + (0 * 4),
18732         0xFF000000 | wuffs_base__peek_u24le__no_bounds_check(s + (0 * 3)));
18733 
18734     s += 1 * 3;
18735     d += 1 * 4;
18736     n -= 1;
18737   }
18738 
18739   return len;
18740 }
18741 
18742 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)18743 wuffs_base__pixel_swizzler__bgrw__bgr_565(uint8_t* dst_ptr,
18744                                           size_t dst_len,
18745                                           uint8_t* dst_palette_ptr,
18746                                           size_t dst_palette_len,
18747                                           const uint8_t* src_ptr,
18748                                           size_t src_len) {
18749   size_t dst_len4 = dst_len / 4;
18750   size_t src_len2 = src_len / 2;
18751   size_t len = (dst_len4 < src_len2) ? dst_len4 : src_len2;
18752   uint8_t* d = dst_ptr;
18753   const uint8_t* s = src_ptr;
18754   size_t n = len;
18755 
18756   // TODO: unroll.
18757 
18758   while (n >= 1) {
18759     wuffs_base__poke_u32le__no_bounds_check(
18760         d + (0 * 4), wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
18761                          wuffs_base__peek_u16le__no_bounds_check(s + (0 * 2))));
18762 
18763     s += 1 * 2;
18764     d += 1 * 4;
18765     n -= 1;
18766   }
18767 
18768   return len;
18769 }
18770 
18771 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)18772 wuffs_base__pixel_swizzler__bgrw__bgrx(uint8_t* dst_ptr,
18773                                        size_t dst_len,
18774                                        uint8_t* dst_palette_ptr,
18775                                        size_t dst_palette_len,
18776                                        const uint8_t* src_ptr,
18777                                        size_t src_len) {
18778   size_t dst_len4 = dst_len / 4;
18779   size_t src_len4 = src_len / 4;
18780   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
18781   uint8_t* d = dst_ptr;
18782   const uint8_t* s = src_ptr;
18783   size_t n = len;
18784 
18785   // TODO: unroll.
18786 
18787   while (n >= 1) {
18788     wuffs_base__poke_u32le__no_bounds_check(
18789         d + (0 * 4),
18790         0xFF000000 | wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
18791 
18792     s += 1 * 4;
18793     d += 1 * 4;
18794     n -= 1;
18795   }
18796 
18797   return len;
18798 }
18799 
18800 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
18801 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
18802 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
18803 static uint64_t  //
wuffs_base__pixel_swizzler__bgrw__rgb__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)18804 wuffs_base__pixel_swizzler__bgrw__rgb__sse42(uint8_t* dst_ptr,
18805                                              size_t dst_len,
18806                                              uint8_t* dst_palette_ptr,
18807                                              size_t dst_palette_len,
18808                                              const uint8_t* src_ptr,
18809                                              size_t src_len) {
18810   size_t dst_len4 = dst_len / 4;
18811   size_t src_len3 = src_len / 3;
18812   size_t len = (dst_len4 < src_len3) ? dst_len4 : src_len3;
18813   uint8_t* d = dst_ptr;
18814   const uint8_t* s = src_ptr;
18815   size_t n = len;
18816 
18817   __m128i shuffle = _mm_set_epi8(+0x00, +0x09, +0x0A, +0x0B,  //
18818                                  +0x00, +0x06, +0x07, +0x08,  //
18819                                  +0x00, +0x03, +0x04, +0x05,  //
18820                                  +0x00, +0x00, +0x01, +0x02);
18821   __m128i or_ff = _mm_set_epi8(-0x01, +0x00, +0x00, +0x00,  //
18822                                -0x01, +0x00, +0x00, +0x00,  //
18823                                -0x01, +0x00, +0x00, +0x00,  //
18824                                -0x01, +0x00, +0x00, +0x00);
18825 
18826   while (n >= 6) {
18827     __m128i x;
18828     x = _mm_lddqu_si128((const __m128i*)(const void*)s);
18829     x = _mm_shuffle_epi8(x, shuffle);
18830     x = _mm_or_si128(x, or_ff);
18831     _mm_storeu_si128((__m128i*)(void*)d, x);
18832 
18833     s += 4 * 3;
18834     d += 4 * 4;
18835     n -= 4;
18836   }
18837 
18838   while (n >= 1) {
18839     uint8_t b0 = s[0];
18840     uint8_t b1 = s[1];
18841     uint8_t b2 = s[2];
18842     d[0] = b2;
18843     d[1] = b1;
18844     d[2] = b0;
18845     d[3] = 0xFF;
18846 
18847     s += 1 * 3;
18848     d += 1 * 4;
18849     n -= 1;
18850   }
18851 
18852   return len;
18853 }
18854 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
18855 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
18856 
18857 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)18858 wuffs_base__pixel_swizzler__bgrw__rgb(uint8_t* dst_ptr,
18859                                       size_t dst_len,
18860                                       uint8_t* dst_palette_ptr,
18861                                       size_t dst_palette_len,
18862                                       const uint8_t* src_ptr,
18863                                       size_t src_len) {
18864   size_t dst_len4 = dst_len / 4;
18865   size_t src_len3 = src_len / 3;
18866   size_t len = (dst_len4 < src_len3) ? dst_len4 : src_len3;
18867   uint8_t* d = dst_ptr;
18868   const uint8_t* s = src_ptr;
18869   size_t n = len;
18870 
18871   while (n >= 1) {
18872     uint8_t b0 = s[0];
18873     uint8_t b1 = s[1];
18874     uint8_t b2 = s[2];
18875     d[0] = b2;
18876     d[1] = b1;
18877     d[2] = b0;
18878     d[3] = 0xFF;
18879 
18880     s += 1 * 3;
18881     d += 1 * 4;
18882     n -= 1;
18883   }
18884 
18885   return len;
18886 }
18887 
18888 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)18889 wuffs_base__pixel_swizzler__bgrw__rgbx(uint8_t* dst_ptr,
18890                                        size_t dst_len,
18891                                        uint8_t* dst_palette_ptr,
18892                                        size_t dst_palette_len,
18893                                        const uint8_t* src_ptr,
18894                                        size_t src_len) {
18895   size_t dst_len4 = dst_len / 4;
18896   size_t src_len4 = src_len / 4;
18897   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
18898   uint8_t* d = dst_ptr;
18899   const uint8_t* s = src_ptr;
18900   size_t n = len;
18901 
18902   // TODO: unroll.
18903 
18904   while (n >= 1) {
18905     uint8_t b0 = s[0];
18906     uint8_t b1 = s[1];
18907     uint8_t b2 = s[2];
18908     d[0] = b2;
18909     d[1] = b1;
18910     d[2] = b0;
18911     d[3] = 0xFF;
18912 
18913     s += 1 * 4;
18914     d += 1 * 4;
18915     n -= 1;
18916   }
18917 
18918   return len;
18919 }
18920 
18921 // --------
18922 
18923 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)18924 wuffs_base__pixel_swizzler__bgrw_4x16le__bgr(uint8_t* dst_ptr,
18925                                              size_t dst_len,
18926                                              uint8_t* dst_palette_ptr,
18927                                              size_t dst_palette_len,
18928                                              const uint8_t* src_ptr,
18929                                              size_t src_len) {
18930   size_t dst_len8 = dst_len / 8;
18931   size_t src_len3 = src_len / 3;
18932   size_t len = (dst_len8 < src_len3) ? dst_len8 : src_len3;
18933   uint8_t* d = dst_ptr;
18934   const uint8_t* s = src_ptr;
18935   size_t n = len;
18936 
18937   while (n >= 1) {
18938     uint8_t s0 = s[0];
18939     uint8_t s1 = s[1];
18940     uint8_t s2 = s[2];
18941     d[0] = s0;
18942     d[1] = s0;
18943     d[2] = s1;
18944     d[3] = s1;
18945     d[4] = s2;
18946     d[5] = s2;
18947     d[6] = 0xFF;
18948     d[7] = 0xFF;
18949 
18950     s += 1 * 3;
18951     d += 1 * 8;
18952     n -= 1;
18953   }
18954 
18955   return len;
18956 }
18957 
18958 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)18959 wuffs_base__pixel_swizzler__bgrw_4x16le__bgr_565(uint8_t* dst_ptr,
18960                                                  size_t dst_len,
18961                                                  uint8_t* dst_palette_ptr,
18962                                                  size_t dst_palette_len,
18963                                                  const uint8_t* src_ptr,
18964                                                  size_t src_len) {
18965   size_t dst_len8 = dst_len / 8;
18966   size_t src_len2 = src_len / 2;
18967   size_t len = (dst_len8 < src_len2) ? dst_len8 : src_len2;
18968   uint8_t* d = dst_ptr;
18969   const uint8_t* s = src_ptr;
18970   size_t n = len;
18971 
18972   while (n >= 1) {
18973     wuffs_base__poke_u64le__no_bounds_check(
18974         d + (0 * 8),
18975         wuffs_base__color_u32__as__color_u64(
18976             wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
18977                 wuffs_base__peek_u16le__no_bounds_check(s + (0 * 2)))));
18978 
18979     s += 1 * 2;
18980     d += 1 * 8;
18981     n -= 1;
18982   }
18983 
18984   return len;
18985 }
18986 
18987 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)18988 wuffs_base__pixel_swizzler__bgrw_4x16le__bgrx(uint8_t* dst_ptr,
18989                                               size_t dst_len,
18990                                               uint8_t* dst_palette_ptr,
18991                                               size_t dst_palette_len,
18992                                               const uint8_t* src_ptr,
18993                                               size_t src_len) {
18994   size_t dst_len8 = dst_len / 8;
18995   size_t src_len4 = src_len / 4;
18996   size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
18997   uint8_t* d = dst_ptr;
18998   const uint8_t* s = src_ptr;
18999   size_t n = len;
19000 
19001   while (n >= 1) {
19002     uint8_t s0 = s[0];
19003     uint8_t s1 = s[1];
19004     uint8_t s2 = s[2];
19005     d[0] = s0;
19006     d[1] = s0;
19007     d[2] = s1;
19008     d[3] = s1;
19009     d[4] = s2;
19010     d[5] = s2;
19011     d[6] = 0xFF;
19012     d[7] = 0xFF;
19013 
19014     s += 1 * 4;
19015     d += 1 * 8;
19016     n -= 1;
19017   }
19018 
19019   return len;
19020 }
19021 
19022 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)19023 wuffs_base__pixel_swizzler__bgrw_4x16le__rgb(uint8_t* dst_ptr,
19024                                              size_t dst_len,
19025                                              uint8_t* dst_palette_ptr,
19026                                              size_t dst_palette_len,
19027                                              const uint8_t* src_ptr,
19028                                              size_t src_len) {
19029   size_t dst_len8 = dst_len / 8;
19030   size_t src_len3 = src_len / 3;
19031   size_t len = (dst_len8 < src_len3) ? dst_len8 : src_len3;
19032   uint8_t* d = dst_ptr;
19033   const uint8_t* s = src_ptr;
19034   size_t n = len;
19035 
19036   while (n >= 1) {
19037     uint8_t s0 = s[0];
19038     uint8_t s1 = s[1];
19039     uint8_t s2 = s[2];
19040     d[0] = s2;
19041     d[1] = s2;
19042     d[2] = s1;
19043     d[3] = s1;
19044     d[4] = s0;
19045     d[5] = s0;
19046     d[6] = 0xFF;
19047     d[7] = 0xFF;
19048 
19049     s += 1 * 3;
19050     d += 1 * 8;
19051     n -= 1;
19052   }
19053 
19054   return len;
19055 }
19056 
19057 // --------
19058 
19059 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)19060 wuffs_base__pixel_swizzler__rgba_nonpremul__bgra_nonpremul_4x16le__src(
19061     uint8_t* dst_ptr,
19062     size_t dst_len,
19063     uint8_t* dst_palette_ptr,
19064     size_t dst_palette_len,
19065     const uint8_t* src_ptr,
19066     size_t src_len) {
19067   size_t dst_len4 = dst_len / 4;
19068   size_t src_len8 = src_len / 8;
19069   size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
19070   uint8_t* d = dst_ptr;
19071   const uint8_t* s = src_ptr;
19072 
19073   size_t n = len;
19074   while (n >= 1) {
19075     wuffs_base__poke_u32le__no_bounds_check(
19076         d + (0 * 4), wuffs_base__color_u64__as__color_u32__swap_u32_argb_abgr(
19077                          wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8))));
19078 
19079     s += 1 * 8;
19080     d += 1 * 4;
19081     n -= 1;
19082   }
19083   return len;
19084 }
19085 
19086 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)19087 wuffs_base__pixel_swizzler__rgba_nonpremul__bgra_nonpremul_4x16le__src_over(
19088     uint8_t* dst_ptr,
19089     size_t dst_len,
19090     uint8_t* dst_palette_ptr,
19091     size_t dst_palette_len,
19092     const uint8_t* src_ptr,
19093     size_t src_len) {
19094   size_t dst_len4 = dst_len / 4;
19095   size_t src_len8 = src_len / 8;
19096   size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
19097   uint8_t* d = dst_ptr;
19098   const uint8_t* s = src_ptr;
19099   size_t n = len;
19100 
19101   while (n >= 1) {
19102     uint64_t d0 = wuffs_base__color_u32__as__color_u64(
19103         wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)));
19104     uint64_t s0 = wuffs_base__swap_u64_argb_abgr(
19105         wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)));
19106     wuffs_base__poke_u32le__no_bounds_check(
19107         d + (0 * 4),
19108         wuffs_base__color_u64__as__color_u32(
19109             wuffs_base__composite_nonpremul_nonpremul_u64_axxx(d0, s0)));
19110 
19111     s += 1 * 8;
19112     d += 1 * 4;
19113     n -= 1;
19114   }
19115 
19116   return len;
19117 }
19118 
19119 // --------
19120 
19121 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)19122 wuffs_base__pixel_swizzler__rgbw__bgr_565(uint8_t* dst_ptr,
19123                                           size_t dst_len,
19124                                           uint8_t* dst_palette_ptr,
19125                                           size_t dst_palette_len,
19126                                           const uint8_t* src_ptr,
19127                                           size_t src_len) {
19128   size_t dst_len4 = dst_len / 4;
19129   size_t src_len2 = src_len / 2;
19130   size_t len = (dst_len4 < src_len2) ? dst_len4 : src_len2;
19131   uint8_t* d = dst_ptr;
19132   const uint8_t* s = src_ptr;
19133   size_t n = len;
19134 
19135   // TODO: unroll.
19136 
19137   while (n >= 1) {
19138     wuffs_base__poke_u32le__no_bounds_check(
19139         d + (0 * 4),
19140         wuffs_base__swap_u32_argb_abgr(
19141             wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
19142                 wuffs_base__peek_u16le__no_bounds_check(s + (0 * 2)))));
19143 
19144     s += 1 * 2;
19145     d += 1 * 4;
19146     n -= 1;
19147   }
19148 
19149   return len;
19150 }
19151 
19152 // --------
19153 
19154 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)19155 wuffs_base__pixel_swizzler__xxx__index__src(uint8_t* dst_ptr,
19156                                             size_t dst_len,
19157                                             uint8_t* dst_palette_ptr,
19158                                             size_t dst_palette_len,
19159                                             const uint8_t* src_ptr,
19160                                             size_t src_len) {
19161   if (dst_palette_len !=
19162       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
19163     return 0;
19164   }
19165   size_t dst_len3 = dst_len / 3;
19166   size_t len = (dst_len3 < src_len) ? dst_len3 : src_len;
19167   uint8_t* d = dst_ptr;
19168   const uint8_t* s = src_ptr;
19169   size_t n = len;
19170 
19171   const size_t loop_unroll_count = 4;
19172 
19173   // The comparison in the while condition is ">", not ">=", because with
19174   // ">=", the last 4-byte store could write past the end of the dst slice.
19175   //
19176   // Each 4-byte store writes one too many bytes, but a subsequent store
19177   // will overwrite that with the correct byte. There is always another
19178   // store, whether a 4-byte store in this loop or a 1-byte store in the
19179   // next loop.
19180   while (n > loop_unroll_count) {
19181     wuffs_base__poke_u32le__no_bounds_check(
19182         d + (0 * 3), wuffs_base__peek_u32le__no_bounds_check(
19183                          dst_palette_ptr + ((size_t)s[0] * 4)));
19184     wuffs_base__poke_u32le__no_bounds_check(
19185         d + (1 * 3), wuffs_base__peek_u32le__no_bounds_check(
19186                          dst_palette_ptr + ((size_t)s[1] * 4)));
19187     wuffs_base__poke_u32le__no_bounds_check(
19188         d + (2 * 3), wuffs_base__peek_u32le__no_bounds_check(
19189                          dst_palette_ptr + ((size_t)s[2] * 4)));
19190     wuffs_base__poke_u32le__no_bounds_check(
19191         d + (3 * 3), wuffs_base__peek_u32le__no_bounds_check(
19192                          dst_palette_ptr + ((size_t)s[3] * 4)));
19193 
19194     s += loop_unroll_count * 1;
19195     d += loop_unroll_count * 3;
19196     n -= loop_unroll_count;
19197   }
19198 
19199   while (n >= 1) {
19200     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
19201                                                           ((size_t)s[0] * 4));
19202     wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
19203 
19204     s += 1 * 1;
19205     d += 1 * 3;
19206     n -= 1;
19207   }
19208 
19209   return len;
19210 }
19211 
19212 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)19213 wuffs_base__pixel_swizzler__xxx__index_bgra_nonpremul__src_over(
19214     uint8_t* dst_ptr,
19215     size_t dst_len,
19216     uint8_t* dst_palette_ptr,
19217     size_t dst_palette_len,
19218     const uint8_t* src_ptr,
19219     size_t src_len) {
19220   if (dst_palette_len !=
19221       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
19222     return 0;
19223   }
19224   size_t dst_len3 = dst_len / 3;
19225   size_t len = (dst_len3 < src_len) ? dst_len3 : src_len;
19226   uint8_t* d = dst_ptr;
19227   const uint8_t* s = src_ptr;
19228   size_t n = len;
19229 
19230   // TODO: unroll.
19231 
19232   while (n >= 1) {
19233     uint32_t d0 =
19234         wuffs_base__peek_u24le__no_bounds_check(d + (0 * 3)) | 0xFF000000;
19235     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
19236                                                           ((size_t)s[0] * 4));
19237     wuffs_base__poke_u24le__no_bounds_check(
19238         d + (0 * 3), wuffs_base__composite_premul_nonpremul_u32_axxx(d0, s0));
19239 
19240     s += 1 * 1;
19241     d += 1 * 3;
19242     n -= 1;
19243   }
19244 
19245   return len;
19246 }
19247 
19248 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)19249 wuffs_base__pixel_swizzler__xxx__index_binary_alpha__src_over(
19250     uint8_t* dst_ptr,
19251     size_t dst_len,
19252     uint8_t* dst_palette_ptr,
19253     size_t dst_palette_len,
19254     const uint8_t* src_ptr,
19255     size_t src_len) {
19256   if (dst_palette_len !=
19257       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
19258     return 0;
19259   }
19260   size_t dst_len3 = dst_len / 3;
19261   size_t len = (dst_len3 < src_len) ? dst_len3 : src_len;
19262   uint8_t* d = dst_ptr;
19263   const uint8_t* s = src_ptr;
19264   size_t n = len;
19265 
19266   const size_t loop_unroll_count = 4;
19267 
19268   while (n >= loop_unroll_count) {
19269     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
19270                                                           ((size_t)s[0] * 4));
19271     if (s0) {
19272       wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
19273     }
19274     uint32_t s1 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
19275                                                           ((size_t)s[1] * 4));
19276     if (s1) {
19277       wuffs_base__poke_u24le__no_bounds_check(d + (1 * 3), s1);
19278     }
19279     uint32_t s2 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
19280                                                           ((size_t)s[2] * 4));
19281     if (s2) {
19282       wuffs_base__poke_u24le__no_bounds_check(d + (2 * 3), s2);
19283     }
19284     uint32_t s3 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
19285                                                           ((size_t)s[3] * 4));
19286     if (s3) {
19287       wuffs_base__poke_u24le__no_bounds_check(d + (3 * 3), s3);
19288     }
19289 
19290     s += loop_unroll_count * 1;
19291     d += loop_unroll_count * 3;
19292     n -= loop_unroll_count;
19293   }
19294 
19295   while (n >= 1) {
19296     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
19297                                                           ((size_t)s[0] * 4));
19298     if (s0) {
19299       wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
19300     }
19301 
19302     s += 1 * 1;
19303     d += 1 * 3;
19304     n -= 1;
19305   }
19306 
19307   return len;
19308 }
19309 
19310 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)19311 wuffs_base__pixel_swizzler__xxx__xxxx(uint8_t* dst_ptr,
19312                                       size_t dst_len,
19313                                       uint8_t* dst_palette_ptr,
19314                                       size_t dst_palette_len,
19315                                       const uint8_t* src_ptr,
19316                                       size_t src_len) {
19317   size_t dst_len3 = dst_len / 3;
19318   size_t src_len4 = src_len / 4;
19319   size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
19320   uint8_t* d = dst_ptr;
19321   const uint8_t* s = src_ptr;
19322   size_t n = len;
19323 
19324   // TODO: unroll.
19325 
19326   while (n >= 1) {
19327     wuffs_base__poke_u24le__no_bounds_check(
19328         d + (0 * 3), wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
19329 
19330     s += 1 * 4;
19331     d += 1 * 3;
19332     n -= 1;
19333   }
19334 
19335   return len;
19336 }
19337 
19338 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)19339 wuffs_base__pixel_swizzler__xxx__y(uint8_t* dst_ptr,
19340                                    size_t dst_len,
19341                                    uint8_t* dst_palette_ptr,
19342                                    size_t dst_palette_len,
19343                                    const uint8_t* src_ptr,
19344                                    size_t src_len) {
19345   size_t dst_len3 = dst_len / 3;
19346   size_t len = (dst_len3 < src_len) ? dst_len3 : src_len;
19347   uint8_t* d = dst_ptr;
19348   const uint8_t* s = src_ptr;
19349   size_t n = len;
19350 
19351   // TODO: unroll.
19352 
19353   while (n >= 1) {
19354     uint8_t s0 = s[0];
19355     d[0] = s0;
19356     d[1] = s0;
19357     d[2] = s0;
19358 
19359     s += 1 * 1;
19360     d += 1 * 3;
19361     n -= 1;
19362   }
19363 
19364   return len;
19365 }
19366 
19367 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)19368 wuffs_base__pixel_swizzler__xxx__y_16be(uint8_t* dst_ptr,
19369                                         size_t dst_len,
19370                                         uint8_t* dst_palette_ptr,
19371                                         size_t dst_palette_len,
19372                                         const uint8_t* src_ptr,
19373                                         size_t src_len) {
19374   size_t dst_len3 = dst_len / 3;
19375   size_t src_len2 = src_len / 2;
19376   size_t len = (dst_len3 < src_len2) ? dst_len3 : src_len2;
19377   uint8_t* d = dst_ptr;
19378   const uint8_t* s = src_ptr;
19379   size_t n = len;
19380 
19381   // TODO: unroll.
19382 
19383   while (n >= 1) {
19384     uint8_t s0 = s[0];
19385     d[0] = s0;
19386     d[1] = s0;
19387     d[2] = s0;
19388 
19389     s += 1 * 2;
19390     d += 1 * 3;
19391     n -= 1;
19392   }
19393 
19394   return len;
19395 }
19396 
19397 // --------
19398 
19399 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)19400 wuffs_base__pixel_swizzler__xxxx__index__src(uint8_t* dst_ptr,
19401                                              size_t dst_len,
19402                                              uint8_t* dst_palette_ptr,
19403                                              size_t dst_palette_len,
19404                                              const uint8_t* src_ptr,
19405                                              size_t src_len) {
19406   if (dst_palette_len !=
19407       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
19408     return 0;
19409   }
19410   size_t dst_len4 = dst_len / 4;
19411   size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
19412   uint8_t* d = dst_ptr;
19413   const uint8_t* s = src_ptr;
19414   size_t n = len;
19415 
19416   const size_t loop_unroll_count = 4;
19417 
19418   while (n >= loop_unroll_count) {
19419     wuffs_base__poke_u32le__no_bounds_check(
19420         d + (0 * 4), wuffs_base__peek_u32le__no_bounds_check(
19421                          dst_palette_ptr + ((size_t)s[0] * 4)));
19422     wuffs_base__poke_u32le__no_bounds_check(
19423         d + (1 * 4), wuffs_base__peek_u32le__no_bounds_check(
19424                          dst_palette_ptr + ((size_t)s[1] * 4)));
19425     wuffs_base__poke_u32le__no_bounds_check(
19426         d + (2 * 4), wuffs_base__peek_u32le__no_bounds_check(
19427                          dst_palette_ptr + ((size_t)s[2] * 4)));
19428     wuffs_base__poke_u32le__no_bounds_check(
19429         d + (3 * 4), wuffs_base__peek_u32le__no_bounds_check(
19430                          dst_palette_ptr + ((size_t)s[3] * 4)));
19431 
19432     s += loop_unroll_count * 1;
19433     d += loop_unroll_count * 4;
19434     n -= loop_unroll_count;
19435   }
19436 
19437   while (n >= 1) {
19438     wuffs_base__poke_u32le__no_bounds_check(
19439         d + (0 * 4), wuffs_base__peek_u32le__no_bounds_check(
19440                          dst_palette_ptr + ((size_t)s[0] * 4)));
19441 
19442     s += 1 * 1;
19443     d += 1 * 4;
19444     n -= 1;
19445   }
19446 
19447   return len;
19448 }
19449 
19450 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)19451 wuffs_base__pixel_swizzler__xxxx__index_binary_alpha__src_over(
19452     uint8_t* dst_ptr,
19453     size_t dst_len,
19454     uint8_t* dst_palette_ptr,
19455     size_t dst_palette_len,
19456     const uint8_t* src_ptr,
19457     size_t src_len) {
19458   if (dst_palette_len !=
19459       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
19460     return 0;
19461   }
19462   size_t dst_len4 = dst_len / 4;
19463   size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
19464   uint8_t* d = dst_ptr;
19465   const uint8_t* s = src_ptr;
19466   size_t n = len;
19467 
19468   const size_t loop_unroll_count = 4;
19469 
19470   while (n >= loop_unroll_count) {
19471     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
19472                                                           ((size_t)s[0] * 4));
19473     if (s0) {
19474       wuffs_base__poke_u32le__no_bounds_check(d + (0 * 4), s0);
19475     }
19476     uint32_t s1 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
19477                                                           ((size_t)s[1] * 4));
19478     if (s1) {
19479       wuffs_base__poke_u32le__no_bounds_check(d + (1 * 4), s1);
19480     }
19481     uint32_t s2 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
19482                                                           ((size_t)s[2] * 4));
19483     if (s2) {
19484       wuffs_base__poke_u32le__no_bounds_check(d + (2 * 4), s2);
19485     }
19486     uint32_t s3 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
19487                                                           ((size_t)s[3] * 4));
19488     if (s3) {
19489       wuffs_base__poke_u32le__no_bounds_check(d + (3 * 4), s3);
19490     }
19491 
19492     s += loop_unroll_count * 1;
19493     d += loop_unroll_count * 4;
19494     n -= loop_unroll_count;
19495   }
19496 
19497   while (n >= 1) {
19498     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
19499                                                           ((size_t)s[0] * 4));
19500     if (s0) {
19501       wuffs_base__poke_u32le__no_bounds_check(d + (0 * 4), s0);
19502     }
19503 
19504     s += 1 * 1;
19505     d += 1 * 4;
19506     n -= 1;
19507   }
19508 
19509   return len;
19510 }
19511 
19512 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
19513 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
19514 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
19515 static uint64_t  //
wuffs_base__pixel_swizzler__xxxx__y__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)19516 wuffs_base__pixel_swizzler__xxxx__y__sse42(uint8_t* dst_ptr,
19517                                            size_t dst_len,
19518                                            uint8_t* dst_palette_ptr,
19519                                            size_t dst_palette_len,
19520                                            const uint8_t* src_ptr,
19521                                            size_t src_len) {
19522   size_t dst_len4 = dst_len / 4;
19523   size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
19524   uint8_t* d = dst_ptr;
19525   const uint8_t* s = src_ptr;
19526   size_t n = len;
19527 
19528   __m128i shuffle = _mm_set_epi8(+0x03, +0x03, +0x03, +0x03,  //
19529                                  +0x02, +0x02, +0x02, +0x02,  //
19530                                  +0x01, +0x01, +0x01, +0x01,  //
19531                                  +0x00, +0x00, +0x00, +0x00);
19532   __m128i or_ff = _mm_set_epi8(-0x01, +0x00, +0x00, +0x00,  //
19533                                -0x01, +0x00, +0x00, +0x00,  //
19534                                -0x01, +0x00, +0x00, +0x00,  //
19535                                -0x01, +0x00, +0x00, +0x00);
19536 
19537   while (n >= 4) {
19538     __m128i x;
19539     x = _mm_cvtsi32_si128((int)(wuffs_base__peek_u32le__no_bounds_check(s)));
19540     x = _mm_shuffle_epi8(x, shuffle);
19541     x = _mm_or_si128(x, or_ff);
19542     _mm_storeu_si128((__m128i*)(void*)d, x);
19543 
19544     s += 4 * 1;
19545     d += 4 * 4;
19546     n -= 4;
19547   }
19548 
19549   while (n >= 1) {
19550     wuffs_base__poke_u32le__no_bounds_check(
19551         d + (0 * 4), 0xFF000000 | (0x010101 * (uint32_t)s[0]));
19552 
19553     s += 1 * 1;
19554     d += 1 * 4;
19555     n -= 1;
19556   }
19557 
19558   return len;
19559 }
19560 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
19561 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
19562 
19563 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)19564 wuffs_base__pixel_swizzler__xxxx__y(uint8_t* dst_ptr,
19565                                     size_t dst_len,
19566                                     uint8_t* dst_palette_ptr,
19567                                     size_t dst_palette_len,
19568                                     const uint8_t* src_ptr,
19569                                     size_t src_len) {
19570   size_t dst_len4 = dst_len / 4;
19571   size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
19572   uint8_t* d = dst_ptr;
19573   const uint8_t* s = src_ptr;
19574   size_t n = len;
19575 
19576   while (n >= 1) {
19577     wuffs_base__poke_u32le__no_bounds_check(
19578         d + (0 * 4), 0xFF000000 | (0x010101 * (uint32_t)s[0]));
19579 
19580     s += 1 * 1;
19581     d += 1 * 4;
19582     n -= 1;
19583   }
19584 
19585   return len;
19586 }
19587 
19588 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)19589 wuffs_base__pixel_swizzler__xxxx__y_16be(uint8_t* dst_ptr,
19590                                          size_t dst_len,
19591                                          uint8_t* dst_palette_ptr,
19592                                          size_t dst_palette_len,
19593                                          const uint8_t* src_ptr,
19594                                          size_t src_len) {
19595   size_t dst_len4 = dst_len / 4;
19596   size_t src_len2 = src_len / 2;
19597   size_t len = (dst_len4 < src_len2) ? dst_len4 : src_len2;
19598   uint8_t* d = dst_ptr;
19599   const uint8_t* s = src_ptr;
19600   size_t n = len;
19601 
19602   while (n >= 1) {
19603     wuffs_base__poke_u32le__no_bounds_check(
19604         d + (0 * 4), 0xFF000000 | (0x010101 * (uint32_t)s[0]));
19605 
19606     s += 1 * 2;
19607     d += 1 * 4;
19608     n -= 1;
19609   }
19610 
19611   return len;
19612 }
19613 
19614 // --------
19615 
19616 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)19617 wuffs_base__pixel_swizzler__xxxxxxxx__index__src(uint8_t* dst_ptr,
19618                                                  size_t dst_len,
19619                                                  uint8_t* dst_palette_ptr,
19620                                                  size_t dst_palette_len,
19621                                                  const uint8_t* src_ptr,
19622                                                  size_t src_len) {
19623   if (dst_palette_len !=
19624       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
19625     return 0;
19626   }
19627   size_t dst_len8 = dst_len / 8;
19628   size_t len = (dst_len8 < src_len) ? dst_len8 : src_len;
19629   uint8_t* d = dst_ptr;
19630   const uint8_t* s = src_ptr;
19631   size_t n = len;
19632 
19633   while (n >= 1) {
19634     wuffs_base__poke_u64le__no_bounds_check(
19635         d + (0 * 8), wuffs_base__color_u32__as__color_u64(
19636                          wuffs_base__peek_u32le__no_bounds_check(
19637                              dst_palette_ptr + ((size_t)s[0] * 4))));
19638 
19639     s += 1 * 1;
19640     d += 1 * 8;
19641     n -= 1;
19642   }
19643 
19644   return len;
19645 }
19646 
19647 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)19648 wuffs_base__pixel_swizzler__xxxxxxxx__index_binary_alpha__src_over(
19649     uint8_t* dst_ptr,
19650     size_t dst_len,
19651     uint8_t* dst_palette_ptr,
19652     size_t dst_palette_len,
19653     const uint8_t* src_ptr,
19654     size_t src_len) {
19655   if (dst_palette_len !=
19656       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
19657     return 0;
19658   }
19659   size_t dst_len8 = dst_len / 8;
19660   size_t len = (dst_len8 < src_len) ? dst_len8 : src_len;
19661   uint8_t* d = dst_ptr;
19662   const uint8_t* s = src_ptr;
19663   size_t n = len;
19664 
19665   while (n >= 1) {
19666     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
19667                                                           ((size_t)s[0] * 4));
19668     if (s0) {
19669       wuffs_base__poke_u64le__no_bounds_check(
19670           d + (0 * 8), wuffs_base__color_u32__as__color_u64(s0));
19671     }
19672 
19673     s += 1 * 1;
19674     d += 1 * 8;
19675     n -= 1;
19676   }
19677 
19678   return len;
19679 }
19680 
19681 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)19682 wuffs_base__pixel_swizzler__xxxxxxxx__y(uint8_t* dst_ptr,
19683                                         size_t dst_len,
19684                                         uint8_t* dst_palette_ptr,
19685                                         size_t dst_palette_len,
19686                                         const uint8_t* src_ptr,
19687                                         size_t src_len) {
19688   size_t dst_len8 = dst_len / 8;
19689   size_t len = (dst_len8 < src_len) ? dst_len8 : src_len;
19690   uint8_t* d = dst_ptr;
19691   const uint8_t* s = src_ptr;
19692   size_t n = len;
19693 
19694   while (n >= 1) {
19695     wuffs_base__poke_u64le__no_bounds_check(
19696         d + (0 * 8), 0xFFFF000000000000 | (0x010101010101 * (uint64_t)s[0]));
19697 
19698     s += 1 * 1;
19699     d += 1 * 8;
19700     n -= 1;
19701   }
19702 
19703   return len;
19704 }
19705 
19706 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)19707 wuffs_base__pixel_swizzler__xxxxxxxx__y_16be(uint8_t* dst_ptr,
19708                                              size_t dst_len,
19709                                              uint8_t* dst_palette_ptr,
19710                                              size_t dst_palette_len,
19711                                              const uint8_t* src_ptr,
19712                                              size_t src_len) {
19713   size_t dst_len8 = dst_len / 8;
19714   size_t src_len2 = src_len / 2;
19715   size_t len = (dst_len8 < src_len2) ? dst_len8 : src_len2;
19716   uint8_t* d = dst_ptr;
19717   const uint8_t* s = src_ptr;
19718   size_t n = len;
19719 
19720   while (n >= 1) {
19721     uint64_t s0 =
19722         ((uint64_t)(wuffs_base__peek_u16be__no_bounds_check(s + (0 * 2))));
19723     wuffs_base__poke_u64le__no_bounds_check(
19724         d + (0 * 8), 0xFFFF000000000000 | (0x000100010001 * s0));
19725 
19726     s += 1 * 2;
19727     d += 1 * 8;
19728     n -= 1;
19729   }
19730 
19731   return len;
19732 }
19733 
19734 // --------
19735 
19736 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)19737 wuffs_base__pixel_swizzler__y__y_16be(uint8_t* dst_ptr,
19738                                       size_t dst_len,
19739                                       uint8_t* dst_palette_ptr,
19740                                       size_t dst_palette_len,
19741                                       const uint8_t* src_ptr,
19742                                       size_t src_len) {
19743   size_t src_len2 = src_len / 2;
19744   size_t len = (dst_len < src_len2) ? dst_len : src_len2;
19745   uint8_t* d = dst_ptr;
19746   const uint8_t* s = src_ptr;
19747   size_t n = len;
19748 
19749   while (n >= 1) {
19750     d[0] = s[0];
19751 
19752     s += 1 * 2;
19753     d += 1 * 1;
19754     n -= 1;
19755   }
19756 
19757   return len;
19758 }
19759 
19760 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)19761 wuffs_base__pixel_swizzler__y_16le__y_16be(uint8_t* dst_ptr,
19762                                            size_t dst_len,
19763                                            uint8_t* dst_palette_ptr,
19764                                            size_t dst_palette_len,
19765                                            const uint8_t* src_ptr,
19766                                            size_t src_len) {
19767   size_t dst_len2 = dst_len / 2;
19768   size_t src_len2 = src_len / 2;
19769   size_t len = (dst_len2 < src_len2) ? dst_len2 : src_len2;
19770   uint8_t* d = dst_ptr;
19771   const uint8_t* s = src_ptr;
19772   size_t n = len;
19773 
19774   while (n >= 1) {
19775     uint8_t s0 = s[0];
19776     uint8_t s1 = s[1];
19777     d[0] = s1;
19778     d[1] = s0;
19779 
19780     s += 1 * 2;
19781     d += 1 * 2;
19782     n -= 1;
19783   }
19784 
19785   return len;
19786 }
19787 
19788 // --------
19789 
19790 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)19791 wuffs_base__pixel_swizzler__transparent_black_src(
19792     uint8_t* dst_ptr,
19793     size_t dst_len,
19794     uint8_t* dst_palette_ptr,
19795     size_t dst_palette_len,
19796     uint64_t num_pixels,
19797     uint32_t dst_pixfmt_bytes_per_pixel) {
19798   uint64_t n = ((uint64_t)dst_len) / dst_pixfmt_bytes_per_pixel;
19799   if (n > num_pixels) {
19800     n = num_pixels;
19801   }
19802   memset(dst_ptr, 0, ((size_t)(n * dst_pixfmt_bytes_per_pixel)));
19803   return n;
19804 }
19805 
19806 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)19807 wuffs_base__pixel_swizzler__transparent_black_src_over(
19808     uint8_t* dst_ptr,
19809     size_t dst_len,
19810     uint8_t* dst_palette_ptr,
19811     size_t dst_palette_len,
19812     uint64_t num_pixels,
19813     uint32_t dst_pixfmt_bytes_per_pixel) {
19814   uint64_t n = ((uint64_t)dst_len) / dst_pixfmt_bytes_per_pixel;
19815   if (n > num_pixels) {
19816     n = num_pixels;
19817   }
19818   return n;
19819 }
19820 
19821 // --------
19822 
19823 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)19824 wuffs_base__pixel_swizzler__prepare__y(wuffs_base__pixel_swizzler* p,
19825                                        wuffs_base__pixel_format dst_pixfmt,
19826                                        wuffs_base__slice_u8 dst_palette,
19827                                        wuffs_base__slice_u8 src_palette,
19828                                        wuffs_base__pixel_blend blend) {
19829   switch (dst_pixfmt.repr) {
19830     case WUFFS_BASE__PIXEL_FORMAT__Y:
19831       return wuffs_base__pixel_swizzler__copy_1_1;
19832 
19833     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
19834       return wuffs_base__pixel_swizzler__bgr_565__y;
19835 
19836     case WUFFS_BASE__PIXEL_FORMAT__BGR:
19837     case WUFFS_BASE__PIXEL_FORMAT__RGB:
19838       return wuffs_base__pixel_swizzler__xxx__y;
19839 
19840     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
19841     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
19842     case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
19843     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
19844     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
19845     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
19846     case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
19847     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
19848 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
19849       if (wuffs_base__cpu_arch__have_x86_sse42()) {
19850         return wuffs_base__pixel_swizzler__xxxx__y__sse42;
19851       }
19852 #endif
19853       return wuffs_base__pixel_swizzler__xxxx__y;
19854 
19855     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
19856     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE:
19857     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL_4X16LE:
19858     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL_4X16LE:
19859       return wuffs_base__pixel_swizzler__xxxxxxxx__y;
19860   }
19861   return NULL;
19862 }
19863 
19864 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)19865 wuffs_base__pixel_swizzler__prepare__y_16be(wuffs_base__pixel_swizzler* p,
19866                                             wuffs_base__pixel_format dst_pixfmt,
19867                                             wuffs_base__slice_u8 dst_palette,
19868                                             wuffs_base__slice_u8 src_palette,
19869                                             wuffs_base__pixel_blend blend) {
19870   switch (dst_pixfmt.repr) {
19871     case WUFFS_BASE__PIXEL_FORMAT__Y:
19872       return wuffs_base__pixel_swizzler__y__y_16be;
19873 
19874     case WUFFS_BASE__PIXEL_FORMAT__Y_16LE:
19875       return wuffs_base__pixel_swizzler__y_16le__y_16be;
19876 
19877     case WUFFS_BASE__PIXEL_FORMAT__Y_16BE:
19878       return wuffs_base__pixel_swizzler__copy_2_2;
19879 
19880     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
19881       return wuffs_base__pixel_swizzler__bgr_565__y_16be;
19882 
19883     case WUFFS_BASE__PIXEL_FORMAT__BGR:
19884     case WUFFS_BASE__PIXEL_FORMAT__RGB:
19885       return wuffs_base__pixel_swizzler__xxx__y_16be;
19886 
19887     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
19888     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
19889     case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
19890     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
19891     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
19892     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
19893     case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
19894     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
19895       return wuffs_base__pixel_swizzler__xxxx__y_16be;
19896 
19897     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
19898     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE:
19899     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL_4X16LE:
19900     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL_4X16LE:
19901       return wuffs_base__pixel_swizzler__xxxxxxxx__y_16be;
19902   }
19903   return NULL;
19904 }
19905 
19906 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)19907 wuffs_base__pixel_swizzler__prepare__indexed__bgra_nonpremul(
19908     wuffs_base__pixel_swizzler* p,
19909     wuffs_base__pixel_format dst_pixfmt,
19910     wuffs_base__slice_u8 dst_palette,
19911     wuffs_base__slice_u8 src_palette,
19912     wuffs_base__pixel_blend blend) {
19913   switch (dst_pixfmt.repr) {
19914     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:
19915       if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
19916           WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
19917         return NULL;
19918       }
19919       switch (blend) {
19920         case WUFFS_BASE__PIXEL_BLEND__SRC:
19921           return wuffs_base__pixel_swizzler__copy_1_1;
19922       }
19923       return NULL;
19924 
19925     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
19926       switch (blend) {
19927         case WUFFS_BASE__PIXEL_BLEND__SRC:
19928           if (wuffs_base__pixel_swizzler__squash_align4_bgr_565_8888(
19929                   dst_palette.ptr, dst_palette.len, src_palette.ptr,
19930                   src_palette.len, true) !=
19931               (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
19932             return NULL;
19933           }
19934           return wuffs_base__pixel_swizzler__bgr_565__index__src;
19935         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
19936           if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
19937               WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
19938             return NULL;
19939           }
19940           return wuffs_base__pixel_swizzler__bgr_565__index_bgra_nonpremul__src_over;
19941       }
19942       return NULL;
19943 
19944     case WUFFS_BASE__PIXEL_FORMAT__BGR:
19945       switch (blend) {
19946         case WUFFS_BASE__PIXEL_BLEND__SRC:
19947           if (wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src(
19948                   dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
19949                   src_palette.len) !=
19950               (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
19951             return NULL;
19952           }
19953           return wuffs_base__pixel_swizzler__xxx__index__src;
19954         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
19955           if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
19956               WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
19957             return NULL;
19958           }
19959           return wuffs_base__pixel_swizzler__xxx__index_bgra_nonpremul__src_over;
19960       }
19961       return NULL;
19962 
19963     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
19964       if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
19965           WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
19966         return NULL;
19967       }
19968       switch (blend) {
19969         case WUFFS_BASE__PIXEL_BLEND__SRC:
19970           return wuffs_base__pixel_swizzler__xxxx__index__src;
19971         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
19972           return wuffs_base__pixel_swizzler__bgra_nonpremul__index_bgra_nonpremul__src_over;
19973       }
19974       return NULL;
19975 
19976     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
19977       if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
19978           WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
19979         return NULL;
19980       }
19981       switch (blend) {
19982         case WUFFS_BASE__PIXEL_BLEND__SRC:
19983           return wuffs_base__pixel_swizzler__xxxxxxxx__index__src;
19984         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
19985           return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__index_bgra_nonpremul__src_over;
19986       }
19987       return NULL;
19988 
19989     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
19990       switch (blend) {
19991         case WUFFS_BASE__PIXEL_BLEND__SRC:
19992           if (wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src(
19993                   dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
19994                   src_palette.len) !=
19995               (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
19996             return NULL;
19997           }
19998           return wuffs_base__pixel_swizzler__xxxx__index__src;
19999         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20000           if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
20001               WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
20002             return NULL;
20003           }
20004           return wuffs_base__pixel_swizzler__bgra_premul__index_bgra_nonpremul__src_over;
20005       }
20006       return NULL;
20007 
20008     case WUFFS_BASE__PIXEL_FORMAT__RGB:
20009       // TODO.
20010       break;
20011 
20012     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
20013       if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx(
20014               dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
20015               src_palette.len) !=
20016           (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
20017         return NULL;
20018       }
20019       switch (blend) {
20020         case WUFFS_BASE__PIXEL_BLEND__SRC:
20021           return wuffs_base__pixel_swizzler__xxxx__index__src;
20022         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20023           return wuffs_base__pixel_swizzler__bgra_nonpremul__index_bgra_nonpremul__src_over;
20024       }
20025       return NULL;
20026 
20027     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
20028       switch (blend) {
20029         case WUFFS_BASE__PIXEL_BLEND__SRC:
20030           if (wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src(
20031                   dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
20032                   src_palette.len) !=
20033               (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
20034             return NULL;
20035           }
20036           return wuffs_base__pixel_swizzler__xxxx__index__src;
20037         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20038           if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx(
20039                   dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
20040                   src_palette.len) !=
20041               (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
20042             return NULL;
20043           }
20044           return wuffs_base__pixel_swizzler__bgra_premul__index_bgra_nonpremul__src_over;
20045       }
20046       return NULL;
20047 
20048     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
20049       // TODO.
20050       break;
20051   }
20052   return NULL;
20053 }
20054 
20055 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)20056 wuffs_base__pixel_swizzler__prepare__indexed__bgra_binary(
20057     wuffs_base__pixel_swizzler* p,
20058     wuffs_base__pixel_format dst_pixfmt,
20059     wuffs_base__slice_u8 dst_palette,
20060     wuffs_base__slice_u8 src_palette,
20061     wuffs_base__pixel_blend blend) {
20062   switch (dst_pixfmt.repr) {
20063     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:
20064     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL:
20065     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY:
20066       if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
20067           WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
20068         return NULL;
20069       }
20070       switch (blend) {
20071         case WUFFS_BASE__PIXEL_BLEND__SRC:
20072           return wuffs_base__pixel_swizzler__copy_1_1;
20073       }
20074       return NULL;
20075 
20076     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
20077       if (wuffs_base__pixel_swizzler__squash_align4_bgr_565_8888(
20078               dst_palette.ptr, dst_palette.len, src_palette.ptr,
20079               src_palette.len, false) !=
20080           (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
20081         return NULL;
20082       }
20083       switch (blend) {
20084         case WUFFS_BASE__PIXEL_BLEND__SRC:
20085           return wuffs_base__pixel_swizzler__bgr_565__index__src;
20086         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20087           return wuffs_base__pixel_swizzler__bgr_565__index_binary_alpha__src_over;
20088       }
20089       return NULL;
20090 
20091     case WUFFS_BASE__PIXEL_FORMAT__BGR:
20092       if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
20093           WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
20094         return NULL;
20095       }
20096       switch (blend) {
20097         case WUFFS_BASE__PIXEL_BLEND__SRC:
20098           return wuffs_base__pixel_swizzler__xxx__index__src;
20099         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20100           return wuffs_base__pixel_swizzler__xxx__index_binary_alpha__src_over;
20101       }
20102       return NULL;
20103 
20104     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
20105     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
20106     case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
20107       if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
20108           WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
20109         return NULL;
20110       }
20111       switch (blend) {
20112         case WUFFS_BASE__PIXEL_BLEND__SRC:
20113           return wuffs_base__pixel_swizzler__xxxx__index__src;
20114         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20115           return wuffs_base__pixel_swizzler__xxxx__index_binary_alpha__src_over;
20116       }
20117       return NULL;
20118 
20119     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
20120     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE:
20121       if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
20122           WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
20123         return NULL;
20124       }
20125       switch (blend) {
20126         case WUFFS_BASE__PIXEL_BLEND__SRC:
20127           return wuffs_base__pixel_swizzler__xxxxxxxx__index__src;
20128         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20129           return wuffs_base__pixel_swizzler__xxxxxxxx__index_binary_alpha__src_over;
20130       }
20131       return NULL;
20132 
20133     case WUFFS_BASE__PIXEL_FORMAT__RGB:
20134       if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx(
20135               dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
20136               src_palette.len) !=
20137           (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
20138         return NULL;
20139       }
20140       switch (blend) {
20141         case WUFFS_BASE__PIXEL_BLEND__SRC:
20142           return wuffs_base__pixel_swizzler__xxx__index__src;
20143         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20144           return wuffs_base__pixel_swizzler__xxx__index_binary_alpha__src_over;
20145       }
20146       return NULL;
20147 
20148     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
20149     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
20150     case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
20151       if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx(
20152               dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
20153               src_palette.len) !=
20154           (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
20155         return NULL;
20156       }
20157       switch (blend) {
20158         case WUFFS_BASE__PIXEL_BLEND__SRC:
20159           return wuffs_base__pixel_swizzler__xxxx__index__src;
20160         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20161           return wuffs_base__pixel_swizzler__xxxx__index_binary_alpha__src_over;
20162       }
20163       return NULL;
20164   }
20165   return NULL;
20166 }
20167 
20168 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)20169 wuffs_base__pixel_swizzler__prepare__bgr_565(
20170     wuffs_base__pixel_swizzler* p,
20171     wuffs_base__pixel_format dst_pixfmt,
20172     wuffs_base__slice_u8 dst_palette,
20173     wuffs_base__slice_u8 src_palette,
20174     wuffs_base__pixel_blend blend) {
20175   switch (dst_pixfmt.repr) {
20176     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
20177       return wuffs_base__pixel_swizzler__copy_2_2;
20178 
20179     case WUFFS_BASE__PIXEL_FORMAT__BGR:
20180       return wuffs_base__pixel_swizzler__bgr__bgr_565;
20181 
20182     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
20183     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
20184     case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
20185     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
20186       return wuffs_base__pixel_swizzler__bgrw__bgr_565;
20187 
20188     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
20189     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE:
20190       return wuffs_base__pixel_swizzler__bgrw_4x16le__bgr_565;
20191 
20192     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
20193     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
20194     case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
20195     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
20196       return wuffs_base__pixel_swizzler__rgbw__bgr_565;
20197   }
20198   return NULL;
20199 }
20200 
20201 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)20202 wuffs_base__pixel_swizzler__prepare__bgr(wuffs_base__pixel_swizzler* p,
20203                                          wuffs_base__pixel_format dst_pixfmt,
20204                                          wuffs_base__slice_u8 dst_palette,
20205                                          wuffs_base__slice_u8 src_palette,
20206                                          wuffs_base__pixel_blend blend) {
20207   switch (dst_pixfmt.repr) {
20208     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
20209       return wuffs_base__pixel_swizzler__bgr_565__bgr;
20210 
20211     case WUFFS_BASE__PIXEL_FORMAT__BGR:
20212       return wuffs_base__pixel_swizzler__copy_3_3;
20213 
20214     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
20215     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
20216     case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
20217     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
20218       return wuffs_base__pixel_swizzler__bgrw__bgr;
20219 
20220     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
20221     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE:
20222       return wuffs_base__pixel_swizzler__bgrw_4x16le__bgr;
20223 
20224     case WUFFS_BASE__PIXEL_FORMAT__RGB:
20225       return wuffs_base__pixel_swizzler__swap_rgb_bgr;
20226 
20227     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
20228     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
20229     case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
20230     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
20231 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
20232       if (wuffs_base__cpu_arch__have_x86_sse42()) {
20233         return wuffs_base__pixel_swizzler__bgrw__rgb__sse42;
20234       }
20235 #endif
20236       return wuffs_base__pixel_swizzler__bgrw__rgb;
20237   }
20238   return NULL;
20239 }
20240 
20241 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)20242 wuffs_base__pixel_swizzler__prepare__bgra_nonpremul(
20243     wuffs_base__pixel_swizzler* p,
20244     wuffs_base__pixel_format dst_pixfmt,
20245     wuffs_base__slice_u8 dst_palette,
20246     wuffs_base__slice_u8 src_palette,
20247     wuffs_base__pixel_blend blend) {
20248   switch (dst_pixfmt.repr) {
20249     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
20250       switch (blend) {
20251         case WUFFS_BASE__PIXEL_BLEND__SRC:
20252           return wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul__src;
20253         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20254           return wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul__src_over;
20255       }
20256       return NULL;
20257 
20258     case WUFFS_BASE__PIXEL_FORMAT__BGR:
20259       switch (blend) {
20260         case WUFFS_BASE__PIXEL_BLEND__SRC:
20261           return wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src;
20262         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20263           return wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src_over;
20264       }
20265       return NULL;
20266 
20267     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
20268       switch (blend) {
20269         case WUFFS_BASE__PIXEL_BLEND__SRC:
20270           return wuffs_base__pixel_swizzler__copy_4_4;
20271         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20272           return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul__src_over;
20273       }
20274       return NULL;
20275 
20276     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
20277       switch (blend) {
20278         case WUFFS_BASE__PIXEL_BLEND__SRC:
20279           return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul__src;
20280         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20281           return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul__src_over;
20282       }
20283       return NULL;
20284 
20285     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
20286       switch (blend) {
20287         case WUFFS_BASE__PIXEL_BLEND__SRC:
20288           return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src;
20289         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20290           return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src_over;
20291       }
20292       return NULL;
20293 
20294     case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
20295     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
20296       // TODO.
20297       break;
20298 
20299     case WUFFS_BASE__PIXEL_FORMAT__RGB:
20300       // TODO.
20301       break;
20302 
20303     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
20304       switch (blend) {
20305         case WUFFS_BASE__PIXEL_BLEND__SRC:
20306 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
20307           if (wuffs_base__cpu_arch__have_x86_sse42()) {
20308             return wuffs_base__pixel_swizzler__swap_rgbx_bgrx__sse42;
20309           }
20310 #endif
20311           return wuffs_base__pixel_swizzler__swap_rgbx_bgrx;
20312         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20313           return wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_nonpremul__src_over;
20314       }
20315       return NULL;
20316 
20317     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
20318       switch (blend) {
20319         case WUFFS_BASE__PIXEL_BLEND__SRC:
20320           return wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src;
20321         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20322           return wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src_over;
20323       }
20324       return NULL;
20325 
20326     case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
20327     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
20328       // TODO.
20329       break;
20330   }
20331   return NULL;
20332 }
20333 
20334 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)20335 wuffs_base__pixel_swizzler__prepare__bgra_nonpremul_4x16le(
20336     wuffs_base__pixel_swizzler* p,
20337     wuffs_base__pixel_format dst_pixfmt,
20338     wuffs_base__slice_u8 dst_palette,
20339     wuffs_base__slice_u8 src_palette,
20340     wuffs_base__pixel_blend blend) {
20341   switch (dst_pixfmt.repr) {
20342     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
20343       switch (blend) {
20344         case WUFFS_BASE__PIXEL_BLEND__SRC:
20345           return wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul_4x16le__src;
20346         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20347           return wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul_4x16le__src_over;
20348       }
20349       return NULL;
20350 
20351     case WUFFS_BASE__PIXEL_FORMAT__BGR:
20352       switch (blend) {
20353         case WUFFS_BASE__PIXEL_BLEND__SRC:
20354           return wuffs_base__pixel_swizzler__bgr__bgra_nonpremul_4x16le__src;
20355         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20356           return wuffs_base__pixel_swizzler__bgr__bgra_nonpremul_4x16le__src_over;
20357       }
20358       return NULL;
20359 
20360     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
20361       switch (blend) {
20362         case WUFFS_BASE__PIXEL_BLEND__SRC:
20363           return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul_4x16le__src;
20364         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20365           return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul_4x16le__src_over;
20366       }
20367       return NULL;
20368 
20369     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
20370       switch (blend) {
20371         case WUFFS_BASE__PIXEL_BLEND__SRC:
20372           return wuffs_base__pixel_swizzler__copy_8_8;
20373         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20374           return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul_4x16le__src_over;
20375       }
20376       return NULL;
20377 
20378     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
20379       switch (blend) {
20380         case WUFFS_BASE__PIXEL_BLEND__SRC:
20381           return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul_4x16le__src;
20382         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20383           return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul_4x16le__src_over;
20384       }
20385       return NULL;
20386 
20387     case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
20388     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
20389       // TODO.
20390       break;
20391 
20392     case WUFFS_BASE__PIXEL_FORMAT__RGB:
20393       // TODO.
20394       break;
20395 
20396     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
20397       switch (blend) {
20398         case WUFFS_BASE__PIXEL_BLEND__SRC:
20399           return wuffs_base__pixel_swizzler__rgba_nonpremul__bgra_nonpremul_4x16le__src;
20400         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20401           return wuffs_base__pixel_swizzler__rgba_nonpremul__bgra_nonpremul_4x16le__src_over;
20402       }
20403       break;
20404 
20405     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
20406       switch (blend) {
20407         case WUFFS_BASE__PIXEL_BLEND__SRC:
20408           return wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul_4x16le__src;
20409         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20410           return wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul_4x16le__src_over;
20411       }
20412       return NULL;
20413 
20414     case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
20415     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
20416       // TODO.
20417       break;
20418   }
20419   return NULL;
20420 }
20421 
20422 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)20423 wuffs_base__pixel_swizzler__prepare__bgra_premul(
20424     wuffs_base__pixel_swizzler* p,
20425     wuffs_base__pixel_format dst_pixfmt,
20426     wuffs_base__slice_u8 dst_palette,
20427     wuffs_base__slice_u8 src_palette,
20428     wuffs_base__pixel_blend blend) {
20429   switch (dst_pixfmt.repr) {
20430     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
20431       switch (blend) {
20432         case WUFFS_BASE__PIXEL_BLEND__SRC:
20433           return wuffs_base__pixel_swizzler__bgr_565__bgra_premul__src;
20434         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20435           return wuffs_base__pixel_swizzler__bgr_565__bgra_premul__src_over;
20436       }
20437       return NULL;
20438 
20439     case WUFFS_BASE__PIXEL_FORMAT__BGR:
20440       switch (blend) {
20441         case WUFFS_BASE__PIXEL_BLEND__SRC:
20442           return wuffs_base__pixel_swizzler__bgr__bgra_premul__src;
20443         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20444           return wuffs_base__pixel_swizzler__bgr__bgra_premul__src_over;
20445       }
20446       return NULL;
20447 
20448     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
20449       switch (blend) {
20450         case WUFFS_BASE__PIXEL_BLEND__SRC:
20451           return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src;
20452         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20453           return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src_over;
20454       }
20455       return NULL;
20456 
20457     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
20458       switch (blend) {
20459         case WUFFS_BASE__PIXEL_BLEND__SRC:
20460           return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_premul__src;
20461         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20462           return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_premul__src_over;
20463       }
20464       return NULL;
20465 
20466     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
20467       switch (blend) {
20468         case WUFFS_BASE__PIXEL_BLEND__SRC:
20469           return wuffs_base__pixel_swizzler__copy_4_4;
20470         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20471           return wuffs_base__pixel_swizzler__bgra_premul__bgra_premul__src_over;
20472       }
20473       return NULL;
20474 
20475     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
20476       switch (blend) {
20477         case WUFFS_BASE__PIXEL_BLEND__SRC:
20478           return wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src;
20479         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20480           return wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src_over;
20481       }
20482       return NULL;
20483 
20484     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
20485       switch (blend) {
20486         case WUFFS_BASE__PIXEL_BLEND__SRC:
20487 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
20488           if (wuffs_base__cpu_arch__have_x86_sse42()) {
20489             return wuffs_base__pixel_swizzler__swap_rgbx_bgrx__sse42;
20490           }
20491 #endif
20492           return wuffs_base__pixel_swizzler__swap_rgbx_bgrx;
20493         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20494           return wuffs_base__pixel_swizzler__bgra_premul__rgba_premul__src_over;
20495       }
20496       return NULL;
20497   }
20498   return NULL;
20499 }
20500 
20501 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)20502 wuffs_base__pixel_swizzler__prepare__bgrx(wuffs_base__pixel_swizzler* p,
20503                                           wuffs_base__pixel_format dst_pixfmt,
20504                                           wuffs_base__slice_u8 dst_palette,
20505                                           wuffs_base__slice_u8 src_palette,
20506                                           wuffs_base__pixel_blend blend) {
20507   switch (dst_pixfmt.repr) {
20508     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
20509       return wuffs_base__pixel_swizzler__bgr_565__bgrx;
20510 
20511     case WUFFS_BASE__PIXEL_FORMAT__BGR:
20512       return wuffs_base__pixel_swizzler__xxx__xxxx;
20513 
20514     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
20515     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
20516     case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
20517       return wuffs_base__pixel_swizzler__bgrw__bgrx;
20518 
20519     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
20520       return wuffs_base__pixel_swizzler__bgrw_4x16le__bgrx;
20521 
20522     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
20523       return wuffs_base__pixel_swizzler__copy_4_4;
20524 
20525     case WUFFS_BASE__PIXEL_FORMAT__RGB:
20526       // TODO.
20527       break;
20528 
20529     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
20530     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
20531     case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
20532     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
20533       return wuffs_base__pixel_swizzler__bgrw__rgbx;
20534   }
20535   return NULL;
20536 }
20537 
20538 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)20539 wuffs_base__pixel_swizzler__prepare__rgb(wuffs_base__pixel_swizzler* p,
20540                                          wuffs_base__pixel_format dst_pixfmt,
20541                                          wuffs_base__slice_u8 dst_palette,
20542                                          wuffs_base__slice_u8 src_palette,
20543                                          wuffs_base__pixel_blend blend) {
20544   switch (dst_pixfmt.repr) {
20545     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
20546       return wuffs_base__pixel_swizzler__bgr_565__rgb;
20547 
20548     case WUFFS_BASE__PIXEL_FORMAT__BGR:
20549       return wuffs_base__pixel_swizzler__swap_rgb_bgr;
20550 
20551     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
20552     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
20553     case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
20554     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
20555 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
20556       if (wuffs_base__cpu_arch__have_x86_sse42()) {
20557         return wuffs_base__pixel_swizzler__bgrw__rgb__sse42;
20558       }
20559 #endif
20560       return wuffs_base__pixel_swizzler__bgrw__rgb;
20561 
20562     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
20563       return wuffs_base__pixel_swizzler__bgrw_4x16le__rgb;
20564 
20565     case WUFFS_BASE__PIXEL_FORMAT__RGB:
20566       return wuffs_base__pixel_swizzler__copy_3_3;
20567 
20568     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
20569     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
20570     case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
20571     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
20572       return wuffs_base__pixel_swizzler__bgrw__bgr;
20573   }
20574   return NULL;
20575 }
20576 
20577 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)20578 wuffs_base__pixel_swizzler__prepare__rgba_nonpremul(
20579     wuffs_base__pixel_swizzler* p,
20580     wuffs_base__pixel_format dst_pixfmt,
20581     wuffs_base__slice_u8 dst_palette,
20582     wuffs_base__slice_u8 src_palette,
20583     wuffs_base__pixel_blend blend) {
20584   switch (dst_pixfmt.repr) {
20585     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
20586       switch (blend) {
20587         case WUFFS_BASE__PIXEL_BLEND__SRC:
20588           return wuffs_base__pixel_swizzler__bgr_565__rgba_nonpremul__src;
20589         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20590           return wuffs_base__pixel_swizzler__bgr_565__rgba_nonpremul__src_over;
20591       }
20592       return NULL;
20593 
20594     case WUFFS_BASE__PIXEL_FORMAT__BGR:
20595       switch (blend) {
20596         case WUFFS_BASE__PIXEL_BLEND__SRC:
20597           return wuffs_base__pixel_swizzler__bgr__rgba_nonpremul__src;
20598         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20599           return wuffs_base__pixel_swizzler__bgr__rgba_nonpremul__src_over;
20600       }
20601       return NULL;
20602 
20603     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
20604       switch (blend) {
20605         case WUFFS_BASE__PIXEL_BLEND__SRC:
20606 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
20607           if (wuffs_base__cpu_arch__have_x86_sse42()) {
20608             return wuffs_base__pixel_swizzler__swap_rgbx_bgrx__sse42;
20609           }
20610 #endif
20611           return wuffs_base__pixel_swizzler__swap_rgbx_bgrx;
20612         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20613           return wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_nonpremul__src_over;
20614       }
20615       return NULL;
20616 
20617     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
20618       switch (blend) {
20619         case WUFFS_BASE__PIXEL_BLEND__SRC:
20620           return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_nonpremul__src;
20621         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20622           return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_nonpremul__src_over;
20623       }
20624       return NULL;
20625 
20626     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
20627       switch (blend) {
20628         case WUFFS_BASE__PIXEL_BLEND__SRC:
20629           return wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src;
20630         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20631           return wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src_over;
20632       }
20633       return NULL;
20634 
20635     case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
20636     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
20637       // TODO.
20638       break;
20639 
20640     case WUFFS_BASE__PIXEL_FORMAT__RGB:
20641       // TODO.
20642       break;
20643 
20644     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
20645       switch (blend) {
20646         case WUFFS_BASE__PIXEL_BLEND__SRC:
20647           return wuffs_base__pixel_swizzler__copy_4_4;
20648         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20649           return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul__src_over;
20650       }
20651       return NULL;
20652 
20653     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
20654       switch (blend) {
20655         case WUFFS_BASE__PIXEL_BLEND__SRC:
20656           return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src;
20657         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20658           return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src_over;
20659       }
20660       return NULL;
20661 
20662     case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
20663     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
20664       // TODO.
20665       break;
20666   }
20667   return NULL;
20668 }
20669 
20670 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)20671 wuffs_base__pixel_swizzler__prepare__rgba_premul(
20672     wuffs_base__pixel_swizzler* p,
20673     wuffs_base__pixel_format dst_pixfmt,
20674     wuffs_base__slice_u8 dst_palette,
20675     wuffs_base__slice_u8 src_palette,
20676     wuffs_base__pixel_blend blend) {
20677   switch (dst_pixfmt.repr) {
20678     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
20679       switch (blend) {
20680         case WUFFS_BASE__PIXEL_BLEND__SRC:
20681           return wuffs_base__pixel_swizzler__bgr_565__rgba_premul__src;
20682         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20683           return wuffs_base__pixel_swizzler__bgr_565__rgba_premul__src_over;
20684       }
20685       return NULL;
20686 
20687     case WUFFS_BASE__PIXEL_FORMAT__BGR:
20688       switch (blend) {
20689         case WUFFS_BASE__PIXEL_BLEND__SRC:
20690           return wuffs_base__pixel_swizzler__bgr__rgba_premul__src;
20691         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20692           return wuffs_base__pixel_swizzler__bgr__rgba_premul__src_over;
20693       }
20694       return NULL;
20695 
20696     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
20697       switch (blend) {
20698         case WUFFS_BASE__PIXEL_BLEND__SRC:
20699           return wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src;
20700         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20701           return wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src_over;
20702       }
20703       return NULL;
20704 
20705     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
20706       switch (blend) {
20707         case WUFFS_BASE__PIXEL_BLEND__SRC:
20708           return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_premul__src;
20709         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20710           return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_premul__src_over;
20711       }
20712       return NULL;
20713 
20714     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
20715       switch (blend) {
20716         case WUFFS_BASE__PIXEL_BLEND__SRC:
20717 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
20718           if (wuffs_base__cpu_arch__have_x86_sse42()) {
20719             return wuffs_base__pixel_swizzler__swap_rgbx_bgrx__sse42;
20720           }
20721 #endif
20722           return wuffs_base__pixel_swizzler__swap_rgbx_bgrx;
20723         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20724           return wuffs_base__pixel_swizzler__bgra_premul__rgba_premul__src_over;
20725       }
20726       return NULL;
20727 
20728     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
20729       switch (blend) {
20730         case WUFFS_BASE__PIXEL_BLEND__SRC:
20731           return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src;
20732         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20733           return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src_over;
20734       }
20735       return NULL;
20736 
20737     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
20738       switch (blend) {
20739         case WUFFS_BASE__PIXEL_BLEND__SRC:
20740           return wuffs_base__pixel_swizzler__copy_4_4;
20741         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20742           return wuffs_base__pixel_swizzler__bgra_premul__bgra_premul__src_over;
20743       }
20744       return NULL;
20745   }
20746   return NULL;
20747 }
20748 
20749 // --------
20750 
20751 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)20752 wuffs_base__pixel_swizzler__prepare(wuffs_base__pixel_swizzler* p,
20753                                     wuffs_base__pixel_format dst_pixfmt,
20754                                     wuffs_base__slice_u8 dst_palette,
20755                                     wuffs_base__pixel_format src_pixfmt,
20756                                     wuffs_base__slice_u8 src_palette,
20757                                     wuffs_base__pixel_blend blend) {
20758   if (!p) {
20759     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
20760   }
20761   p->private_impl.func = NULL;
20762   p->private_impl.transparent_black_func = NULL;
20763   p->private_impl.dst_pixfmt_bytes_per_pixel = 0;
20764   p->private_impl.src_pixfmt_bytes_per_pixel = 0;
20765 
20766   wuffs_base__pixel_swizzler__func func = NULL;
20767   wuffs_base__pixel_swizzler__transparent_black_func transparent_black_func =
20768       NULL;
20769 
20770   uint32_t dst_pixfmt_bits_per_pixel =
20771       wuffs_base__pixel_format__bits_per_pixel(&dst_pixfmt);
20772   if ((dst_pixfmt_bits_per_pixel == 0) ||
20773       ((dst_pixfmt_bits_per_pixel & 7) != 0)) {
20774     return wuffs_base__make_status(
20775         wuffs_base__error__unsupported_pixel_swizzler_option);
20776   }
20777 
20778   uint32_t src_pixfmt_bits_per_pixel =
20779       wuffs_base__pixel_format__bits_per_pixel(&src_pixfmt);
20780   if ((src_pixfmt_bits_per_pixel == 0) ||
20781       ((src_pixfmt_bits_per_pixel & 7) != 0)) {
20782     return wuffs_base__make_status(
20783         wuffs_base__error__unsupported_pixel_swizzler_option);
20784   }
20785 
20786   // TODO: support many more formats.
20787 
20788   switch (blend) {
20789     case WUFFS_BASE__PIXEL_BLEND__SRC:
20790       transparent_black_func =
20791           wuffs_base__pixel_swizzler__transparent_black_src;
20792       break;
20793 
20794     case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20795       transparent_black_func =
20796           wuffs_base__pixel_swizzler__transparent_black_src_over;
20797       break;
20798   }
20799 
20800   switch (src_pixfmt.repr) {
20801     case WUFFS_BASE__PIXEL_FORMAT__Y:
20802       func = wuffs_base__pixel_swizzler__prepare__y(p, dst_pixfmt, dst_palette,
20803                                                     src_palette, blend);
20804       break;
20805 
20806     case WUFFS_BASE__PIXEL_FORMAT__Y_16BE:
20807       func = wuffs_base__pixel_swizzler__prepare__y_16be(
20808           p, dst_pixfmt, dst_palette, src_palette, blend);
20809       break;
20810 
20811     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:
20812       func = wuffs_base__pixel_swizzler__prepare__indexed__bgra_nonpremul(
20813           p, dst_pixfmt, dst_palette, src_palette, blend);
20814       break;
20815 
20816     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY:
20817       func = wuffs_base__pixel_swizzler__prepare__indexed__bgra_binary(
20818           p, dst_pixfmt, dst_palette, src_palette, blend);
20819       break;
20820 
20821     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
20822       func = wuffs_base__pixel_swizzler__prepare__bgr_565(
20823           p, dst_pixfmt, dst_palette, src_palette, blend);
20824       break;
20825 
20826     case WUFFS_BASE__PIXEL_FORMAT__BGR:
20827       func = wuffs_base__pixel_swizzler__prepare__bgr(
20828           p, dst_pixfmt, dst_palette, src_palette, blend);
20829       break;
20830 
20831     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
20832       func = wuffs_base__pixel_swizzler__prepare__bgra_nonpremul(
20833           p, dst_pixfmt, dst_palette, src_palette, blend);
20834       break;
20835 
20836     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
20837       func = wuffs_base__pixel_swizzler__prepare__bgra_nonpremul_4x16le(
20838           p, dst_pixfmt, dst_palette, src_palette, blend);
20839       break;
20840 
20841     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
20842       func = wuffs_base__pixel_swizzler__prepare__bgra_premul(
20843           p, dst_pixfmt, dst_palette, src_palette, blend);
20844       break;
20845 
20846     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
20847       func = wuffs_base__pixel_swizzler__prepare__bgrx(
20848           p, dst_pixfmt, dst_palette, src_palette, blend);
20849       break;
20850 
20851     case WUFFS_BASE__PIXEL_FORMAT__RGB:
20852       func = wuffs_base__pixel_swizzler__prepare__rgb(
20853           p, dst_pixfmt, dst_palette, src_palette, blend);
20854       break;
20855 
20856     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
20857       func = wuffs_base__pixel_swizzler__prepare__rgba_nonpremul(
20858           p, dst_pixfmt, dst_palette, src_palette, blend);
20859       break;
20860 
20861     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
20862       func = wuffs_base__pixel_swizzler__prepare__rgba_premul(
20863           p, dst_pixfmt, dst_palette, src_palette, blend);
20864       break;
20865   }
20866 
20867   p->private_impl.func = func;
20868   p->private_impl.transparent_black_func = transparent_black_func;
20869   p->private_impl.dst_pixfmt_bytes_per_pixel = dst_pixfmt_bits_per_pixel / 8;
20870   p->private_impl.src_pixfmt_bytes_per_pixel = src_pixfmt_bits_per_pixel / 8;
20871   return wuffs_base__make_status(
20872       func ? NULL : wuffs_base__error__unsupported_pixel_swizzler_option);
20873 }
20874 
20875 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)20876 wuffs_base__pixel_swizzler__limited_swizzle_u32_interleaved_from_reader(
20877     const wuffs_base__pixel_swizzler* p,
20878     uint32_t up_to_num_pixels,
20879     wuffs_base__slice_u8 dst,
20880     wuffs_base__slice_u8 dst_palette,
20881     const uint8_t** ptr_iop_r,
20882     const uint8_t* io2_r) {
20883   if (p && p->private_impl.func) {
20884     const uint8_t* iop_r = *ptr_iop_r;
20885     uint64_t src_len = wuffs_base__u64__min(
20886         ((uint64_t)up_to_num_pixels) *
20887             ((uint64_t)p->private_impl.src_pixfmt_bytes_per_pixel),
20888         ((uint64_t)(io2_r - iop_r)));
20889     uint64_t n =
20890         (*p->private_impl.func)(dst.ptr, dst.len, dst_palette.ptr,
20891                                 dst_palette.len, iop_r, (size_t)src_len);
20892     *ptr_iop_r += n * p->private_impl.src_pixfmt_bytes_per_pixel;
20893     return n;
20894   }
20895   return 0;
20896 }
20897 
20898 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)20899 wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(
20900     const wuffs_base__pixel_swizzler* p,
20901     wuffs_base__slice_u8 dst,
20902     wuffs_base__slice_u8 dst_palette,
20903     const uint8_t** ptr_iop_r,
20904     const uint8_t* io2_r) {
20905   if (p && p->private_impl.func) {
20906     const uint8_t* iop_r = *ptr_iop_r;
20907     uint64_t src_len = ((uint64_t)(io2_r - iop_r));
20908     uint64_t n =
20909         (*p->private_impl.func)(dst.ptr, dst.len, dst_palette.ptr,
20910                                 dst_palette.len, iop_r, (size_t)src_len);
20911     *ptr_iop_r += n * p->private_impl.src_pixfmt_bytes_per_pixel;
20912     return n;
20913   }
20914   return 0;
20915 }
20916 
20917 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)20918 wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(
20919     const wuffs_base__pixel_swizzler* p,
20920     wuffs_base__slice_u8 dst,
20921     wuffs_base__slice_u8 dst_palette,
20922     wuffs_base__slice_u8 src) {
20923   if (p && p->private_impl.func) {
20924     return (*p->private_impl.func)(dst.ptr, dst.len, dst_palette.ptr,
20925                                    dst_palette.len, src.ptr, src.len);
20926   }
20927   return 0;
20928 }
20929 
20930 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)20931 wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(
20932     const wuffs_base__pixel_swizzler* p,
20933     wuffs_base__slice_u8 dst,
20934     wuffs_base__slice_u8 dst_palette,
20935     uint64_t num_pixels) {
20936   if (p && p->private_impl.transparent_black_func) {
20937     return (*p->private_impl.transparent_black_func)(
20938         dst.ptr, dst.len, dst_palette.ptr, dst_palette.len, num_pixels,
20939         p->private_impl.dst_pixfmt_bytes_per_pixel);
20940   }
20941   return 0;
20942 }
20943 
20944 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
20945         // defined(WUFFS_CONFIG__MODULE__BASE) ||
20946         // defined(WUFFS_CONFIG__MODULE__BASE__PIXCONV)
20947 
20948 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
20949     defined(WUFFS_CONFIG__MODULE__BASE__UTF8)
20950 
20951 // ---------------- Unicode and UTF-8
20952 
20953 WUFFS_BASE__MAYBE_STATIC size_t  //
wuffs_base__utf_8__encode(wuffs_base__slice_u8 dst,uint32_t code_point)20954 wuffs_base__utf_8__encode(wuffs_base__slice_u8 dst, uint32_t code_point) {
20955   if (code_point <= 0x7F) {
20956     if (dst.len >= 1) {
20957       dst.ptr[0] = (uint8_t)(code_point);
20958       return 1;
20959     }
20960 
20961   } else if (code_point <= 0x07FF) {
20962     if (dst.len >= 2) {
20963       dst.ptr[0] = (uint8_t)(0xC0 | ((code_point >> 6)));
20964       dst.ptr[1] = (uint8_t)(0x80 | ((code_point >> 0) & 0x3F));
20965       return 2;
20966     }
20967 
20968   } else if (code_point <= 0xFFFF) {
20969     if ((dst.len >= 3) && ((code_point < 0xD800) || (0xDFFF < code_point))) {
20970       dst.ptr[0] = (uint8_t)(0xE0 | ((code_point >> 12)));
20971       dst.ptr[1] = (uint8_t)(0x80 | ((code_point >> 6) & 0x3F));
20972       dst.ptr[2] = (uint8_t)(0x80 | ((code_point >> 0) & 0x3F));
20973       return 3;
20974     }
20975 
20976   } else if (code_point <= 0x10FFFF) {
20977     if (dst.len >= 4) {
20978       dst.ptr[0] = (uint8_t)(0xF0 | ((code_point >> 18)));
20979       dst.ptr[1] = (uint8_t)(0x80 | ((code_point >> 12) & 0x3F));
20980       dst.ptr[2] = (uint8_t)(0x80 | ((code_point >> 6) & 0x3F));
20981       dst.ptr[3] = (uint8_t)(0x80 | ((code_point >> 0) & 0x3F));
20982       return 4;
20983     }
20984   }
20985 
20986   return 0;
20987 }
20988 
20989 // wuffs_base__utf_8__byte_length_minus_1 is the byte length (minus 1) of a
20990 // UTF-8 encoded code point, based on the encoding's initial byte.
20991 //  - 0x00 is 1-byte UTF-8 (ASCII).
20992 //  - 0x01 is the start of 2-byte UTF-8.
20993 //  - 0x02 is the start of 3-byte UTF-8.
20994 //  - 0x03 is the start of 4-byte UTF-8.
20995 //  - 0x40 is a UTF-8 tail byte.
20996 //  - 0x80 is invalid UTF-8.
20997 //
20998 // RFC 3629 (UTF-8) gives this grammar for valid UTF-8:
20999 //    UTF8-1      = %x00-7F
21000 //    UTF8-2      = %xC2-DF UTF8-tail
21001 //    UTF8-3      = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) /
21002 //                  %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )
21003 //    UTF8-4      = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) /
21004 //                  %xF4 %x80-8F 2( UTF8-tail )
21005 //    UTF8-tail   = %x80-BF
21006 static const uint8_t wuffs_base__utf_8__byte_length_minus_1[256] = {
21007     // 0     1     2     3     4     5     6     7
21008     // 8     9     A     B     C     D     E     F
21009     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x00 ..= 0x07.
21010     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x08 ..= 0x0F.
21011     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x10 ..= 0x17.
21012     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x18 ..= 0x1F.
21013     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x20 ..= 0x27.
21014     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x28 ..= 0x2F.
21015     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x30 ..= 0x37.
21016     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x38 ..= 0x3F.
21017 
21018     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x40 ..= 0x47.
21019     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x48 ..= 0x4F.
21020     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x50 ..= 0x57.
21021     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x58 ..= 0x5F.
21022     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x60 ..= 0x67.
21023     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x68 ..= 0x6F.
21024     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x70 ..= 0x77.
21025     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x78 ..= 0x7F.
21026 
21027     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  // 0x80 ..= 0x87.
21028     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  // 0x88 ..= 0x8F.
21029     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  // 0x90 ..= 0x97.
21030     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  // 0x98 ..= 0x9F.
21031     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  // 0xA0 ..= 0xA7.
21032     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  // 0xA8 ..= 0xAF.
21033     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  // 0xB0 ..= 0xB7.
21034     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  // 0xB8 ..= 0xBF.
21035 
21036     0x80, 0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  // 0xC0 ..= 0xC7.
21037     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  // 0xC8 ..= 0xCF.
21038     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  // 0xD0 ..= 0xD7.
21039     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  // 0xD8 ..= 0xDF.
21040     0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,  // 0xE0 ..= 0xE7.
21041     0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,  // 0xE8 ..= 0xEF.
21042     0x03, 0x03, 0x03, 0x03, 0x03, 0x80, 0x80, 0x80,  // 0xF0 ..= 0xF7.
21043     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xF8 ..= 0xFF.
21044     // 0     1     2     3     4     5     6     7
21045     // 8     9     A     B     C     D     E     F
21046 };
21047 
21048 WUFFS_BASE__MAYBE_STATIC wuffs_base__utf_8__next__output  //
wuffs_base__utf_8__next(const uint8_t * s_ptr,size_t s_len)21049 wuffs_base__utf_8__next(const uint8_t* s_ptr, size_t s_len) {
21050   if (s_len == 0) {
21051     return wuffs_base__make_utf_8__next__output(0, 0);
21052   }
21053   uint32_t c = s_ptr[0];
21054   switch (wuffs_base__utf_8__byte_length_minus_1[c & 0xFF]) {
21055     case 0:
21056       return wuffs_base__make_utf_8__next__output(c, 1);
21057 
21058     case 1:
21059       if (s_len < 2) {
21060         break;
21061       }
21062       c = wuffs_base__peek_u16le__no_bounds_check(s_ptr);
21063       if ((c & 0xC000) != 0x8000) {
21064         break;
21065       }
21066       c = (0x0007C0 & (c << 6)) | (0x00003F & (c >> 8));
21067       return wuffs_base__make_utf_8__next__output(c, 2);
21068 
21069     case 2:
21070       if (s_len < 3) {
21071         break;
21072       }
21073       c = wuffs_base__peek_u24le__no_bounds_check(s_ptr);
21074       if ((c & 0xC0C000) != 0x808000) {
21075         break;
21076       }
21077       c = (0x00F000 & (c << 12)) | (0x000FC0 & (c >> 2)) |
21078           (0x00003F & (c >> 16));
21079       if ((c <= 0x07FF) || ((0xD800 <= c) && (c <= 0xDFFF))) {
21080         break;
21081       }
21082       return wuffs_base__make_utf_8__next__output(c, 3);
21083 
21084     case 3:
21085       if (s_len < 4) {
21086         break;
21087       }
21088       c = wuffs_base__peek_u32le__no_bounds_check(s_ptr);
21089       if ((c & 0xC0C0C000) != 0x80808000) {
21090         break;
21091       }
21092       c = (0x1C0000 & (c << 18)) | (0x03F000 & (c << 4)) |
21093           (0x000FC0 & (c >> 10)) | (0x00003F & (c >> 24));
21094       if ((c <= 0xFFFF) || (0x110000 <= c)) {
21095         break;
21096       }
21097       return wuffs_base__make_utf_8__next__output(c, 4);
21098   }
21099 
21100   return wuffs_base__make_utf_8__next__output(
21101       WUFFS_BASE__UNICODE_REPLACEMENT_CHARACTER, 1);
21102 }
21103 
21104 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)21105 wuffs_base__utf_8__next_from_end(const uint8_t* s_ptr, size_t s_len) {
21106   if (s_len == 0) {
21107     return wuffs_base__make_utf_8__next__output(0, 0);
21108   }
21109   const uint8_t* ptr = &s_ptr[s_len - 1];
21110   if (*ptr < 0x80) {
21111     return wuffs_base__make_utf_8__next__output(*ptr, 1);
21112 
21113   } else if (*ptr < 0xC0) {
21114     const uint8_t* too_far = &s_ptr[(s_len > 4) ? (s_len - 4) : 0];
21115     uint32_t n = 1;
21116     while (ptr != too_far) {
21117       ptr--;
21118       n++;
21119       if (*ptr < 0x80) {
21120         break;
21121       } else if (*ptr < 0xC0) {
21122         continue;
21123       }
21124       wuffs_base__utf_8__next__output o = wuffs_base__utf_8__next(ptr, n);
21125       if (o.byte_length != n) {
21126         break;
21127       }
21128       return o;
21129     }
21130   }
21131 
21132   return wuffs_base__make_utf_8__next__output(
21133       WUFFS_BASE__UNICODE_REPLACEMENT_CHARACTER, 1);
21134 }
21135 
21136 WUFFS_BASE__MAYBE_STATIC size_t  //
wuffs_base__utf_8__longest_valid_prefix(const uint8_t * s_ptr,size_t s_len)21137 wuffs_base__utf_8__longest_valid_prefix(const uint8_t* s_ptr, size_t s_len) {
21138   // TODO: possibly optimize the all-ASCII case (4 or 8 bytes at a time).
21139   //
21140   // TODO: possibly optimize this by manually inlining the
21141   // wuffs_base__utf_8__next calls.
21142   size_t original_len = s_len;
21143   while (s_len > 0) {
21144     wuffs_base__utf_8__next__output o = wuffs_base__utf_8__next(s_ptr, s_len);
21145     if ((o.code_point > 0x7F) && (o.byte_length == 1)) {
21146       break;
21147     }
21148     s_ptr += o.byte_length;
21149     s_len -= o.byte_length;
21150   }
21151   return original_len - s_len;
21152 }
21153 
21154 WUFFS_BASE__MAYBE_STATIC size_t  //
wuffs_base__ascii__longest_valid_prefix(const uint8_t * s_ptr,size_t s_len)21155 wuffs_base__ascii__longest_valid_prefix(const uint8_t* s_ptr, size_t s_len) {
21156   // TODO: possibly optimize this by checking 4 or 8 bytes at a time.
21157   const uint8_t* original_ptr = s_ptr;
21158   const uint8_t* p = s_ptr;
21159   const uint8_t* q = s_ptr + s_len;
21160   for (; (p != q) && ((*p & 0x80) == 0); p++) {
21161   }
21162   return (size_t)(p - original_ptr);
21163 }
21164 
21165 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
21166         // defined(WUFFS_CONFIG__MODULE__BASE) ||
21167         // defined(WUFFS_CONFIG__MODULE__BASE__UTF8)
21168 
21169 #ifdef __cplusplus
21170 }  // extern "C"
21171 #endif
21172 
21173 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ADLER32)
21174 
21175 // ---------------- Status Codes Implementations
21176 
21177 // ---------------- Private Consts
21178 
21179 // ---------------- Private Initializer Prototypes
21180 
21181 // ---------------- Private Function Prototypes
21182 
21183 static wuffs_base__empty_struct
21184 wuffs_adler32__hasher__up(
21185     wuffs_adler32__hasher* self,
21186     wuffs_base__slice_u8 a_x);
21187 
21188 static wuffs_base__empty_struct
21189 wuffs_adler32__hasher__up__choosy_default(
21190     wuffs_adler32__hasher* self,
21191     wuffs_base__slice_u8 a_x);
21192 
21193 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
21194 static wuffs_base__empty_struct
21195 wuffs_adler32__hasher__up_arm_neon(
21196     wuffs_adler32__hasher* self,
21197     wuffs_base__slice_u8 a_x);
21198 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
21199 
21200 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
21201 static wuffs_base__empty_struct
21202 wuffs_adler32__hasher__up_x86_sse42(
21203     wuffs_adler32__hasher* self,
21204     wuffs_base__slice_u8 a_x);
21205 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
21206 
21207 // ---------------- VTables
21208 
21209 const wuffs_base__hasher_u32__func_ptrs
21210 wuffs_adler32__hasher__func_ptrs_for__wuffs_base__hasher_u32 = {
21211   (wuffs_base__empty_struct(*)(void*,
21212       uint32_t,
21213       bool))(&wuffs_adler32__hasher__set_quirk_enabled),
21214   (uint32_t(*)(void*,
21215       wuffs_base__slice_u8))(&wuffs_adler32__hasher__update_u32),
21216 };
21217 
21218 // ---------------- Initializer Implementations
21219 
21220 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)21221 wuffs_adler32__hasher__initialize(
21222     wuffs_adler32__hasher* self,
21223     size_t sizeof_star_self,
21224     uint64_t wuffs_version,
21225     uint32_t options){
21226   if (!self) {
21227     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
21228   }
21229   if (sizeof(*self) != sizeof_star_self) {
21230     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
21231   }
21232   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
21233       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
21234     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
21235   }
21236 
21237   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
21238     // The whole point of this if-check is to detect an uninitialized *self.
21239     // We disable the warning on GCC. Clang-5.0 does not have this warning.
21240 #if !defined(__clang__) && defined(__GNUC__)
21241 #pragma GCC diagnostic push
21242 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
21243 #endif
21244     if (self->private_impl.magic != 0) {
21245       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
21246     }
21247 #if !defined(__clang__) && defined(__GNUC__)
21248 #pragma GCC diagnostic pop
21249 #endif
21250   } else {
21251     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
21252       memset(self, 0, sizeof(*self));
21253       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
21254     } else {
21255       memset(&(self->private_impl), 0, sizeof(self->private_impl));
21256     }
21257   }
21258 
21259   self->private_impl.choosy_up = &wuffs_adler32__hasher__up__choosy_default;
21260 
21261   self->private_impl.magic = WUFFS_BASE__MAGIC;
21262   self->private_impl.vtable_for__wuffs_base__hasher_u32.vtable_name =
21263       wuffs_base__hasher_u32__vtable_name;
21264   self->private_impl.vtable_for__wuffs_base__hasher_u32.function_pointers =
21265       (const void*)(&wuffs_adler32__hasher__func_ptrs_for__wuffs_base__hasher_u32);
21266   return wuffs_base__make_status(NULL);
21267 }
21268 
21269 wuffs_adler32__hasher*
wuffs_adler32__hasher__alloc()21270 wuffs_adler32__hasher__alloc() {
21271   wuffs_adler32__hasher* x =
21272       (wuffs_adler32__hasher*)(calloc(sizeof(wuffs_adler32__hasher), 1));
21273   if (!x) {
21274     return NULL;
21275   }
21276   if (wuffs_adler32__hasher__initialize(
21277       x, sizeof(wuffs_adler32__hasher), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
21278     free(x);
21279     return NULL;
21280   }
21281   return x;
21282 }
21283 
21284 size_t
sizeof__wuffs_adler32__hasher()21285 sizeof__wuffs_adler32__hasher() {
21286   return sizeof(wuffs_adler32__hasher);
21287 }
21288 
21289 // ---------------- Function Implementations
21290 
21291 // -------- func adler32.hasher.set_quirk_enabled
21292 
21293 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_adler32__hasher__set_quirk_enabled(wuffs_adler32__hasher * self,uint32_t a_quirk,bool a_enabled)21294 wuffs_adler32__hasher__set_quirk_enabled(
21295     wuffs_adler32__hasher* self,
21296     uint32_t a_quirk,
21297     bool a_enabled) {
21298   return wuffs_base__make_empty_struct();
21299 }
21300 
21301 // -------- func adler32.hasher.update_u32
21302 
21303 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_adler32__hasher__update_u32(wuffs_adler32__hasher * self,wuffs_base__slice_u8 a_x)21304 wuffs_adler32__hasher__update_u32(
21305     wuffs_adler32__hasher* self,
21306     wuffs_base__slice_u8 a_x) {
21307   if (!self) {
21308     return 0;
21309   }
21310   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
21311     return 0;
21312   }
21313 
21314   if ( ! self->private_impl.f_started) {
21315     self->private_impl.f_started = true;
21316     self->private_impl.f_state = 1;
21317     self->private_impl.choosy_up = (
21318 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
21319         wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_adler32__hasher__up_arm_neon :
21320 #endif
21321 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
21322         wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_adler32__hasher__up_x86_sse42 :
21323 #endif
21324         self->private_impl.choosy_up);
21325   }
21326   wuffs_adler32__hasher__up(self, a_x);
21327   return self->private_impl.f_state;
21328 }
21329 
21330 // -------- func adler32.hasher.up
21331 
21332 static wuffs_base__empty_struct
wuffs_adler32__hasher__up(wuffs_adler32__hasher * self,wuffs_base__slice_u8 a_x)21333 wuffs_adler32__hasher__up(
21334     wuffs_adler32__hasher* self,
21335     wuffs_base__slice_u8 a_x) {
21336   return (*self->private_impl.choosy_up)(self, a_x);
21337 }
21338 
21339 static wuffs_base__empty_struct
wuffs_adler32__hasher__up__choosy_default(wuffs_adler32__hasher * self,wuffs_base__slice_u8 a_x)21340 wuffs_adler32__hasher__up__choosy_default(
21341     wuffs_adler32__hasher* self,
21342     wuffs_base__slice_u8 a_x) {
21343   uint32_t v_s1 = 0;
21344   uint32_t v_s2 = 0;
21345   wuffs_base__slice_u8 v_remaining = {0};
21346   wuffs_base__slice_u8 v_p = {0};
21347 
21348   v_s1 = ((self->private_impl.f_state) & 0xFFFF);
21349   v_s2 = ((self->private_impl.f_state) >> (32 - (16)));
21350   while (((uint64_t)(a_x.len)) > 0) {
21351     v_remaining = wuffs_base__slice_u8__subslice_j(a_x, 0);
21352     if (((uint64_t)(a_x.len)) > 5552) {
21353       v_remaining = wuffs_base__slice_u8__subslice_i(a_x, 5552);
21354       a_x = wuffs_base__slice_u8__subslice_j(a_x, 5552);
21355     }
21356     {
21357       wuffs_base__slice_u8 i_slice_p = a_x;
21358       v_p.ptr = i_slice_p.ptr;
21359       v_p.len = 1;
21360       uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 8) * 8);
21361       while (v_p.ptr < i_end0_p) {
21362         v_s1 += ((uint32_t)(v_p.ptr[0]));
21363         v_s2 += v_s1;
21364         v_p.ptr += 1;
21365         v_s1 += ((uint32_t)(v_p.ptr[0]));
21366         v_s2 += v_s1;
21367         v_p.ptr += 1;
21368         v_s1 += ((uint32_t)(v_p.ptr[0]));
21369         v_s2 += v_s1;
21370         v_p.ptr += 1;
21371         v_s1 += ((uint32_t)(v_p.ptr[0]));
21372         v_s2 += v_s1;
21373         v_p.ptr += 1;
21374         v_s1 += ((uint32_t)(v_p.ptr[0]));
21375         v_s2 += v_s1;
21376         v_p.ptr += 1;
21377         v_s1 += ((uint32_t)(v_p.ptr[0]));
21378         v_s2 += v_s1;
21379         v_p.ptr += 1;
21380         v_s1 += ((uint32_t)(v_p.ptr[0]));
21381         v_s2 += v_s1;
21382         v_p.ptr += 1;
21383         v_s1 += ((uint32_t)(v_p.ptr[0]));
21384         v_s2 += v_s1;
21385         v_p.ptr += 1;
21386       }
21387       v_p.len = 1;
21388       uint8_t* i_end1_p = i_slice_p.ptr + i_slice_p.len;
21389       while (v_p.ptr < i_end1_p) {
21390         v_s1 += ((uint32_t)(v_p.ptr[0]));
21391         v_s2 += v_s1;
21392         v_p.ptr += 1;
21393       }
21394       v_p.len = 0;
21395     }
21396     v_s1 %= 65521;
21397     v_s2 %= 65521;
21398     a_x = v_remaining;
21399   }
21400   self->private_impl.f_state = (((v_s2 & 65535) << 16) | (v_s1 & 65535));
21401   return wuffs_base__make_empty_struct();
21402 }
21403 
21404 // ‼ WUFFS MULTI-FILE SECTION +arm_neon
21405 // -------- func adler32.hasher.up_arm_neon
21406 
21407 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
21408 static wuffs_base__empty_struct
wuffs_adler32__hasher__up_arm_neon(wuffs_adler32__hasher * self,wuffs_base__slice_u8 a_x)21409 wuffs_adler32__hasher__up_arm_neon(
21410     wuffs_adler32__hasher* self,
21411     wuffs_base__slice_u8 a_x) {
21412   uint32_t v_s1 = 0;
21413   uint32_t v_s2 = 0;
21414   wuffs_base__slice_u8 v_remaining = {0};
21415   wuffs_base__slice_u8 v_p = {0};
21416   uint8x16_t v_p__left = {0};
21417   uint8x16_t v_p_right = {0};
21418   uint32x4_t v_v1 = {0};
21419   uint32x4_t v_v2 = {0};
21420   uint16x8_t v_col0 = {0};
21421   uint16x8_t v_col1 = {0};
21422   uint16x8_t v_col2 = {0};
21423   uint16x8_t v_col3 = {0};
21424   uint32x2_t v_sum1 = {0};
21425   uint32x2_t v_sum2 = {0};
21426   uint32x2_t v_sum12 = {0};
21427   uint32_t v_num_iterate_bytes = 0;
21428   uint64_t v_tail_index = 0;
21429 
21430   v_s1 = ((self->private_impl.f_state) & 0xFFFF);
21431   v_s2 = ((self->private_impl.f_state) >> (32 - (16)));
21432   while ((((uint64_t)(a_x.len)) > 0) && ((15 & ((uint32_t)(0xFFF & (uintptr_t)(a_x.ptr)))) != 0)) {
21433     v_s1 += ((uint32_t)(a_x.ptr[0]));
21434     v_s2 += v_s1;
21435     a_x = wuffs_base__slice_u8__subslice_i(a_x, 1);
21436   }
21437   v_s1 %= 65521;
21438   v_s2 %= 65521;
21439   while (((uint64_t)(a_x.len)) > 0) {
21440     v_remaining = wuffs_base__slice_u8__subslice_j(a_x, 0);
21441     if (((uint64_t)(a_x.len)) > 5536) {
21442       v_remaining = wuffs_base__slice_u8__subslice_i(a_x, 5536);
21443       a_x = wuffs_base__slice_u8__subslice_j(a_x, 5536);
21444     }
21445     v_num_iterate_bytes = ((uint32_t)((((uint64_t)(a_x.len)) & 4294967264)));
21446     v_s2 += ((uint32_t)(v_s1 * v_num_iterate_bytes));
21447     v_v1 = vdupq_n_u32(0);
21448     v_v2 = vdupq_n_u32(0);
21449     v_col0 = vdupq_n_u16(0);
21450     v_col1 = vdupq_n_u16(0);
21451     v_col2 = vdupq_n_u16(0);
21452     v_col3 = vdupq_n_u16(0);
21453     {
21454       wuffs_base__slice_u8 i_slice_p = a_x;
21455       v_p.ptr = i_slice_p.ptr;
21456       v_p.len = 32;
21457       uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 32) * 32);
21458       while (v_p.ptr < i_end0_p) {
21459         v_p__left = vld1q_u8(v_p.ptr);
21460         v_p_right = vld1q_u8(v_p.ptr + 16);
21461         v_v2 = vaddq_u32(v_v2, v_v1);
21462         v_v1 = vpadalq_u16(v_v1, vpadalq_u8(vpaddlq_u8(v_p__left), v_p_right));
21463         v_col0 = vaddw_u8(v_col0, vget_low_u8(v_p__left));
21464         v_col1 = vaddw_u8(v_col1, vget_high_u8(v_p__left));
21465         v_col2 = vaddw_u8(v_col2, vget_low_u8(v_p_right));
21466         v_col3 = vaddw_u8(v_col3, vget_high_u8(v_p_right));
21467         v_p.ptr += 32;
21468       }
21469       v_p.len = 0;
21470     }
21471     v_v2 = vshlq_n_u32(v_v2, 5);
21472     v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col0), ((uint16x4_t){32, 31, 30, 29}));
21473     v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col0), ((uint16x4_t){28, 27, 26, 25}));
21474     v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col1), ((uint16x4_t){24, 23, 22, 21}));
21475     v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col1), ((uint16x4_t){20, 19, 18, 17}));
21476     v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col2), ((uint16x4_t){16, 15, 14, 13}));
21477     v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col2), ((uint16x4_t){12, 11, 10, 9}));
21478     v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col3), ((uint16x4_t){8, 7, 6, 5}));
21479     v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col3), ((uint16x4_t){4, 3, 2, 1}));
21480     v_sum1 = vpadd_u32(vget_low_u32(v_v1), vget_high_u32(v_v1));
21481     v_sum2 = vpadd_u32(vget_low_u32(v_v2), vget_high_u32(v_v2));
21482     v_sum12 = vpadd_u32(v_sum1, v_sum2);
21483     v_s1 += vget_lane_u32(v_sum12, 0);
21484     v_s2 += vget_lane_u32(v_sum12, 1);
21485     v_tail_index = (((uint64_t)(a_x.len)) & 18446744073709551584u);
21486     if (v_tail_index < ((uint64_t)(a_x.len))) {
21487       {
21488         wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, v_tail_index);
21489         v_p.ptr = i_slice_p.ptr;
21490         v_p.len = 1;
21491         uint8_t* i_end0_p = i_slice_p.ptr + i_slice_p.len;
21492         while (v_p.ptr < i_end0_p) {
21493           v_s1 += ((uint32_t)(v_p.ptr[0]));
21494           v_s2 += v_s1;
21495           v_p.ptr += 1;
21496         }
21497         v_p.len = 0;
21498       }
21499     }
21500     v_s1 %= 65521;
21501     v_s2 %= 65521;
21502     a_x = v_remaining;
21503   }
21504   self->private_impl.f_state = (((v_s2 & 65535) << 16) | (v_s1 & 65535));
21505   return wuffs_base__make_empty_struct();
21506 }
21507 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
21508 // ‼ WUFFS MULTI-FILE SECTION -arm_neon
21509 
21510 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
21511 // -------- func adler32.hasher.up_x86_sse42
21512 
21513 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
21514 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
21515 static wuffs_base__empty_struct
wuffs_adler32__hasher__up_x86_sse42(wuffs_adler32__hasher * self,wuffs_base__slice_u8 a_x)21516 wuffs_adler32__hasher__up_x86_sse42(
21517     wuffs_adler32__hasher* self,
21518     wuffs_base__slice_u8 a_x) {
21519   uint32_t v_s1 = 0;
21520   uint32_t v_s2 = 0;
21521   wuffs_base__slice_u8 v_remaining = {0};
21522   wuffs_base__slice_u8 v_p = {0};
21523   __m128i v_zeroes = {0};
21524   __m128i v_ones = {0};
21525   __m128i v_weights__left = {0};
21526   __m128i v_weights_right = {0};
21527   __m128i v_q__left = {0};
21528   __m128i v_q_right = {0};
21529   __m128i v_v1 = {0};
21530   __m128i v_v2 = {0};
21531   __m128i v_v2j = {0};
21532   __m128i v_v2k = {0};
21533   uint32_t v_num_iterate_bytes = 0;
21534   uint64_t v_tail_index = 0;
21535 
21536   v_zeroes = _mm_set1_epi16((int16_t)(0));
21537   v_ones = _mm_set1_epi16((int16_t)(1));
21538   v_weights__left = _mm_set_epi8((int8_t)(17), (int8_t)(18), (int8_t)(19), (int8_t)(20), (int8_t)(21), (int8_t)(22), (int8_t)(23), (int8_t)(24), (int8_t)(25), (int8_t)(26), (int8_t)(27), (int8_t)(28), (int8_t)(29), (int8_t)(30), (int8_t)(31), (int8_t)(32));
21539   v_weights_right = _mm_set_epi8((int8_t)(1), (int8_t)(2), (int8_t)(3), (int8_t)(4), (int8_t)(5), (int8_t)(6), (int8_t)(7), (int8_t)(8), (int8_t)(9), (int8_t)(10), (int8_t)(11), (int8_t)(12), (int8_t)(13), (int8_t)(14), (int8_t)(15), (int8_t)(16));
21540   v_s1 = ((self->private_impl.f_state) & 0xFFFF);
21541   v_s2 = ((self->private_impl.f_state) >> (32 - (16)));
21542   while (((uint64_t)(a_x.len)) > 0) {
21543     v_remaining = wuffs_base__slice_u8__subslice_j(a_x, 0);
21544     if (((uint64_t)(a_x.len)) > 5536) {
21545       v_remaining = wuffs_base__slice_u8__subslice_i(a_x, 5536);
21546       a_x = wuffs_base__slice_u8__subslice_j(a_x, 5536);
21547     }
21548     v_num_iterate_bytes = ((uint32_t)((((uint64_t)(a_x.len)) & 4294967264)));
21549     v_s2 += ((uint32_t)(v_s1 * v_num_iterate_bytes));
21550     v_v1 = _mm_setzero_si128();
21551     v_v2j = _mm_setzero_si128();
21552     v_v2k = _mm_setzero_si128();
21553     {
21554       wuffs_base__slice_u8 i_slice_p = a_x;
21555       v_p.ptr = i_slice_p.ptr;
21556       v_p.len = 32;
21557       uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 32) * 32);
21558       while (v_p.ptr < i_end0_p) {
21559         v_q__left = _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr));
21560         v_q_right = _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 16));
21561         v_v2j = _mm_add_epi32(v_v2j, v_v1);
21562         v_v1 = _mm_add_epi32(v_v1, _mm_sad_epu8(v_q__left, v_zeroes));
21563         v_v1 = _mm_add_epi32(v_v1, _mm_sad_epu8(v_q_right, v_zeroes));
21564         v_v2k = _mm_add_epi32(v_v2k, _mm_madd_epi16(v_ones, _mm_maddubs_epi16(v_q__left, v_weights__left)));
21565         v_v2k = _mm_add_epi32(v_v2k, _mm_madd_epi16(v_ones, _mm_maddubs_epi16(v_q_right, v_weights_right)));
21566         v_p.ptr += 32;
21567       }
21568       v_p.len = 0;
21569     }
21570     v_v1 = _mm_add_epi32(v_v1, _mm_shuffle_epi32(v_v1, (int32_t)(177)));
21571     v_v1 = _mm_add_epi32(v_v1, _mm_shuffle_epi32(v_v1, (int32_t)(78)));
21572     v_s1 += ((uint32_t)(_mm_cvtsi128_si32(v_v1)));
21573     v_v2 = _mm_add_epi32(v_v2k, _mm_slli_epi32(v_v2j, (int32_t)(5)));
21574     v_v2 = _mm_add_epi32(v_v2, _mm_shuffle_epi32(v_v2, (int32_t)(177)));
21575     v_v2 = _mm_add_epi32(v_v2, _mm_shuffle_epi32(v_v2, (int32_t)(78)));
21576     v_s2 += ((uint32_t)(_mm_cvtsi128_si32(v_v2)));
21577     v_tail_index = (((uint64_t)(a_x.len)) & 18446744073709551584u);
21578     if (v_tail_index < ((uint64_t)(a_x.len))) {
21579       {
21580         wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, v_tail_index);
21581         v_p.ptr = i_slice_p.ptr;
21582         v_p.len = 1;
21583         uint8_t* i_end0_p = i_slice_p.ptr + i_slice_p.len;
21584         while (v_p.ptr < i_end0_p) {
21585           v_s1 += ((uint32_t)(v_p.ptr[0]));
21586           v_s2 += v_s1;
21587           v_p.ptr += 1;
21588         }
21589         v_p.len = 0;
21590       }
21591     }
21592     v_s1 %= 65521;
21593     v_s2 %= 65521;
21594     a_x = v_remaining;
21595   }
21596   self->private_impl.f_state = (((v_s2 & 65535) << 16) | (v_s1 & 65535));
21597   return wuffs_base__make_empty_struct();
21598 }
21599 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
21600 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
21601 
21602 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ADLER32)
21603 
21604 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BMP)
21605 
21606 // ---------------- Status Codes Implementations
21607 
21608 const char wuffs_bmp__error__bad_header[] = "#bmp: bad header";
21609 const char wuffs_bmp__error__bad_rle_compression[] = "#bmp: bad RLE compression";
21610 const char wuffs_bmp__error__unsupported_bmp_file[] = "#bmp: unsupported BMP file";
21611 const char wuffs_bmp__note__internal_note_short_read[] = "@bmp: internal note: short read";
21612 
21613 // ---------------- Private Consts
21614 
21615 #define WUFFS_BMP__COMPRESSION_NONE 0
21616 
21617 #define WUFFS_BMP__COMPRESSION_RLE8 1
21618 
21619 #define WUFFS_BMP__COMPRESSION_RLE4 2
21620 
21621 #define WUFFS_BMP__COMPRESSION_BITFIELDS 3
21622 
21623 #define WUFFS_BMP__COMPRESSION_JPEG 4
21624 
21625 #define WUFFS_BMP__COMPRESSION_PNG 5
21626 
21627 #define WUFFS_BMP__COMPRESSION_ALPHABITFIELDS 6
21628 
21629 #define WUFFS_BMP__COMPRESSION_LOW_BIT_DEPTH 256
21630 
21631 #define WUFFS_BMP__RLE_STATE_NEUTRAL 0
21632 
21633 #define WUFFS_BMP__RLE_STATE_RUN 1
21634 
21635 #define WUFFS_BMP__RLE_STATE_ESCAPE 2
21636 
21637 #define WUFFS_BMP__RLE_STATE_LITERAL 3
21638 
21639 #define WUFFS_BMP__RLE_STATE_DELTA_X 4
21640 
21641 #define WUFFS_BMP__RLE_STATE_DELTA_Y 5
21642 
21643 // ---------------- Private Initializer Prototypes
21644 
21645 // ---------------- Private Function Prototypes
21646 
21647 static wuffs_base__status
21648 wuffs_bmp__decoder__swizzle_none(
21649     wuffs_bmp__decoder* self,
21650     wuffs_base__pixel_buffer* a_dst,
21651     wuffs_base__io_buffer* a_src);
21652 
21653 static wuffs_base__status
21654 wuffs_bmp__decoder__swizzle_rle(
21655     wuffs_bmp__decoder* self,
21656     wuffs_base__pixel_buffer* a_dst,
21657     wuffs_base__io_buffer* a_src);
21658 
21659 static wuffs_base__status
21660 wuffs_bmp__decoder__swizzle_bitfields(
21661     wuffs_bmp__decoder* self,
21662     wuffs_base__pixel_buffer* a_dst,
21663     wuffs_base__io_buffer* a_src);
21664 
21665 static wuffs_base__status
21666 wuffs_bmp__decoder__swizzle_low_bit_depth(
21667     wuffs_bmp__decoder* self,
21668     wuffs_base__pixel_buffer* a_dst,
21669     wuffs_base__io_buffer* a_src);
21670 
21671 static wuffs_base__status
21672 wuffs_bmp__decoder__read_palette(
21673     wuffs_bmp__decoder* self,
21674     wuffs_base__io_buffer* a_src);
21675 
21676 static wuffs_base__status
21677 wuffs_bmp__decoder__process_masks(
21678     wuffs_bmp__decoder* self);
21679 
21680 // ---------------- VTables
21681 
21682 const wuffs_base__image_decoder__func_ptrs
21683 wuffs_bmp__decoder__func_ptrs_for__wuffs_base__image_decoder = {
21684   (wuffs_base__status(*)(void*,
21685       wuffs_base__pixel_buffer*,
21686       wuffs_base__io_buffer*,
21687       wuffs_base__pixel_blend,
21688       wuffs_base__slice_u8,
21689       wuffs_base__decode_frame_options*))(&wuffs_bmp__decoder__decode_frame),
21690   (wuffs_base__status(*)(void*,
21691       wuffs_base__frame_config*,
21692       wuffs_base__io_buffer*))(&wuffs_bmp__decoder__decode_frame_config),
21693   (wuffs_base__status(*)(void*,
21694       wuffs_base__image_config*,
21695       wuffs_base__io_buffer*))(&wuffs_bmp__decoder__decode_image_config),
21696   (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_bmp__decoder__frame_dirty_rect),
21697   (uint32_t(*)(const void*))(&wuffs_bmp__decoder__num_animation_loops),
21698   (uint64_t(*)(const void*))(&wuffs_bmp__decoder__num_decoded_frame_configs),
21699   (uint64_t(*)(const void*))(&wuffs_bmp__decoder__num_decoded_frames),
21700   (wuffs_base__status(*)(void*,
21701       uint64_t,
21702       uint64_t))(&wuffs_bmp__decoder__restart_frame),
21703   (wuffs_base__empty_struct(*)(void*,
21704       uint32_t,
21705       bool))(&wuffs_bmp__decoder__set_quirk_enabled),
21706   (wuffs_base__empty_struct(*)(void*,
21707       uint32_t,
21708       bool))(&wuffs_bmp__decoder__set_report_metadata),
21709   (wuffs_base__status(*)(void*,
21710       wuffs_base__io_buffer*,
21711       wuffs_base__more_information*,
21712       wuffs_base__io_buffer*))(&wuffs_bmp__decoder__tell_me_more),
21713   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_bmp__decoder__workbuf_len),
21714 };
21715 
21716 // ---------------- Initializer Implementations
21717 
21718 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)21719 wuffs_bmp__decoder__initialize(
21720     wuffs_bmp__decoder* self,
21721     size_t sizeof_star_self,
21722     uint64_t wuffs_version,
21723     uint32_t options){
21724   if (!self) {
21725     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
21726   }
21727   if (sizeof(*self) != sizeof_star_self) {
21728     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
21729   }
21730   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
21731       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
21732     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
21733   }
21734 
21735   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
21736     // The whole point of this if-check is to detect an uninitialized *self.
21737     // We disable the warning on GCC. Clang-5.0 does not have this warning.
21738 #if !defined(__clang__) && defined(__GNUC__)
21739 #pragma GCC diagnostic push
21740 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
21741 #endif
21742     if (self->private_impl.magic != 0) {
21743       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
21744     }
21745 #if !defined(__clang__) && defined(__GNUC__)
21746 #pragma GCC diagnostic pop
21747 #endif
21748   } else {
21749     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
21750       memset(self, 0, sizeof(*self));
21751       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
21752     } else {
21753       memset(&(self->private_impl), 0, sizeof(self->private_impl));
21754     }
21755   }
21756 
21757   self->private_impl.magic = WUFFS_BASE__MAGIC;
21758   self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
21759       wuffs_base__image_decoder__vtable_name;
21760   self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
21761       (const void*)(&wuffs_bmp__decoder__func_ptrs_for__wuffs_base__image_decoder);
21762   return wuffs_base__make_status(NULL);
21763 }
21764 
21765 wuffs_bmp__decoder*
wuffs_bmp__decoder__alloc()21766 wuffs_bmp__decoder__alloc() {
21767   wuffs_bmp__decoder* x =
21768       (wuffs_bmp__decoder*)(calloc(sizeof(wuffs_bmp__decoder), 1));
21769   if (!x) {
21770     return NULL;
21771   }
21772   if (wuffs_bmp__decoder__initialize(
21773       x, sizeof(wuffs_bmp__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
21774     free(x);
21775     return NULL;
21776   }
21777   return x;
21778 }
21779 
21780 size_t
sizeof__wuffs_bmp__decoder()21781 sizeof__wuffs_bmp__decoder() {
21782   return sizeof(wuffs_bmp__decoder);
21783 }
21784 
21785 // ---------------- Function Implementations
21786 
21787 // -------- func bmp.decoder.set_quirk_enabled
21788 
21789 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_bmp__decoder__set_quirk_enabled(wuffs_bmp__decoder * self,uint32_t a_quirk,bool a_enabled)21790 wuffs_bmp__decoder__set_quirk_enabled(
21791     wuffs_bmp__decoder* self,
21792     uint32_t a_quirk,
21793     bool a_enabled) {
21794   return wuffs_base__make_empty_struct();
21795 }
21796 
21797 // -------- func bmp.decoder.decode_image_config
21798 
21799 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)21800 wuffs_bmp__decoder__decode_image_config(
21801     wuffs_bmp__decoder* self,
21802     wuffs_base__image_config* a_dst,
21803     wuffs_base__io_buffer* a_src) {
21804   if (!self) {
21805     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
21806   }
21807   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
21808     return wuffs_base__make_status(
21809         (self->private_impl.magic == WUFFS_BASE__DISABLED)
21810         ? wuffs_base__error__disabled_by_previous_error
21811         : wuffs_base__error__initialize_not_called);
21812   }
21813   if (!a_src) {
21814     self->private_impl.magic = WUFFS_BASE__DISABLED;
21815     return wuffs_base__make_status(wuffs_base__error__bad_argument);
21816   }
21817   if ((self->private_impl.active_coroutine != 0) &&
21818       (self->private_impl.active_coroutine != 1)) {
21819     self->private_impl.magic = WUFFS_BASE__DISABLED;
21820     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
21821   }
21822   self->private_impl.active_coroutine = 0;
21823   wuffs_base__status status = wuffs_base__make_status(NULL);
21824 
21825   uint32_t v_magic = 0;
21826   uint32_t v_width = 0;
21827   uint32_t v_height = 0;
21828   uint32_t v_planes = 0;
21829   uint32_t v_dst_pixfmt = 0;
21830   uint32_t v_byte_width = 0;
21831 
21832   const uint8_t* iop_a_src = NULL;
21833   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
21834   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
21835   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
21836   if (a_src) {
21837     io0_a_src = a_src->data.ptr;
21838     io1_a_src = io0_a_src + a_src->meta.ri;
21839     iop_a_src = io1_a_src;
21840     io2_a_src = io0_a_src + a_src->meta.wi;
21841   }
21842 
21843   uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
21844   switch (coro_susp_point) {
21845     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
21846 
21847     if ((self->private_impl.f_call_sequence != 0) || (self->private_impl.f_io_redirect_fourcc == 1)) {
21848       status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
21849       goto exit;
21850     } else if (self->private_impl.f_io_redirect_fourcc != 0) {
21851       status = wuffs_base__make_status(wuffs_base__note__i_o_redirect);
21852       goto ok;
21853     }
21854     {
21855       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
21856       uint32_t t_0;
21857       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
21858         t_0 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
21859         iop_a_src += 2;
21860       } else {
21861         self->private_data.s_decode_image_config[0].scratch = 0;
21862         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
21863         while (true) {
21864           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
21865             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
21866             goto suspend;
21867           }
21868           uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
21869           uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
21870           *scratch <<= 8;
21871           *scratch >>= 8;
21872           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
21873           if (num_bits_0 == 8) {
21874             t_0 = ((uint32_t)(*scratch));
21875             break;
21876           }
21877           num_bits_0 += 8;
21878           *scratch |= ((uint64_t)(num_bits_0)) << 56;
21879         }
21880       }
21881       v_magic = t_0;
21882     }
21883     if (v_magic != 19778) {
21884       status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
21885       goto exit;
21886     }
21887     self->private_data.s_decode_image_config[0].scratch = 8;
21888     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
21889     if (self->private_data.s_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
21890       self->private_data.s_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
21891       iop_a_src = io2_a_src;
21892       status = wuffs_base__make_status(wuffs_base__suspension__short_read);
21893       goto suspend;
21894     }
21895     iop_a_src += self->private_data.s_decode_image_config[0].scratch;
21896     {
21897       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
21898       uint32_t t_1;
21899       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
21900         t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
21901         iop_a_src += 4;
21902       } else {
21903         self->private_data.s_decode_image_config[0].scratch = 0;
21904         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
21905         while (true) {
21906           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
21907             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
21908             goto suspend;
21909           }
21910           uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
21911           uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
21912           *scratch <<= 8;
21913           *scratch >>= 8;
21914           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
21915           if (num_bits_1 == 24) {
21916             t_1 = ((uint32_t)(*scratch));
21917             break;
21918           }
21919           num_bits_1 += 8;
21920           *scratch |= ((uint64_t)(num_bits_1)) << 56;
21921         }
21922       }
21923       self->private_impl.f_padding = t_1;
21924     }
21925     if (self->private_impl.f_padding < 14) {
21926       status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
21927       goto exit;
21928     }
21929     self->private_impl.f_padding -= 14;
21930     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))));
21931     {
21932       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
21933       uint32_t t_2;
21934       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
21935         t_2 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
21936         iop_a_src += 4;
21937       } else {
21938         self->private_data.s_decode_image_config[0].scratch = 0;
21939         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
21940         while (true) {
21941           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
21942             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
21943             goto suspend;
21944           }
21945           uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
21946           uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
21947           *scratch <<= 8;
21948           *scratch >>= 8;
21949           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
21950           if (num_bits_2 == 24) {
21951             t_2 = ((uint32_t)(*scratch));
21952             break;
21953           }
21954           num_bits_2 += 8;
21955           *scratch |= ((uint64_t)(num_bits_2)) << 56;
21956         }
21957       }
21958       self->private_impl.f_bitmap_info_len = t_2;
21959     }
21960     if (self->private_impl.f_padding < self->private_impl.f_bitmap_info_len) {
21961       status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
21962       goto exit;
21963     }
21964     self->private_impl.f_padding -= self->private_impl.f_bitmap_info_len;
21965     if (self->private_impl.f_bitmap_info_len == 12) {
21966       {
21967         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
21968         uint32_t t_3;
21969         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
21970           t_3 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
21971           iop_a_src += 2;
21972         } else {
21973           self->private_data.s_decode_image_config[0].scratch = 0;
21974           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
21975           while (true) {
21976             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
21977               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
21978               goto suspend;
21979             }
21980             uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
21981             uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56));
21982             *scratch <<= 8;
21983             *scratch >>= 8;
21984             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3;
21985             if (num_bits_3 == 8) {
21986               t_3 = ((uint32_t)(*scratch));
21987               break;
21988             }
21989             num_bits_3 += 8;
21990             *scratch |= ((uint64_t)(num_bits_3)) << 56;
21991           }
21992         }
21993         self->private_impl.f_width = t_3;
21994       }
21995       {
21996         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
21997         uint32_t t_4;
21998         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
21999           t_4 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
22000           iop_a_src += 2;
22001         } else {
22002           self->private_data.s_decode_image_config[0].scratch = 0;
22003           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
22004           while (true) {
22005             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22006               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22007               goto suspend;
22008             }
22009             uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22010             uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
22011             *scratch <<= 8;
22012             *scratch >>= 8;
22013             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
22014             if (num_bits_4 == 8) {
22015               t_4 = ((uint32_t)(*scratch));
22016               break;
22017             }
22018             num_bits_4 += 8;
22019             *scratch |= ((uint64_t)(num_bits_4)) << 56;
22020           }
22021         }
22022         self->private_impl.f_height = t_4;
22023       }
22024       {
22025         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
22026         uint32_t t_5;
22027         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
22028           t_5 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
22029           iop_a_src += 2;
22030         } else {
22031           self->private_data.s_decode_image_config[0].scratch = 0;
22032           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
22033           while (true) {
22034             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22035               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22036               goto suspend;
22037             }
22038             uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22039             uint32_t num_bits_5 = ((uint32_t)(*scratch >> 56));
22040             *scratch <<= 8;
22041             *scratch >>= 8;
22042             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_5;
22043             if (num_bits_5 == 8) {
22044               t_5 = ((uint32_t)(*scratch));
22045               break;
22046             }
22047             num_bits_5 += 8;
22048             *scratch |= ((uint64_t)(num_bits_5)) << 56;
22049           }
22050         }
22051         v_planes = t_5;
22052       }
22053       if (v_planes != 1) {
22054         status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
22055         goto exit;
22056       }
22057       {
22058         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
22059         uint32_t t_6;
22060         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
22061           t_6 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
22062           iop_a_src += 2;
22063         } else {
22064           self->private_data.s_decode_image_config[0].scratch = 0;
22065           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
22066           while (true) {
22067             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22068               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22069               goto suspend;
22070             }
22071             uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22072             uint32_t num_bits_6 = ((uint32_t)(*scratch >> 56));
22073             *scratch <<= 8;
22074             *scratch >>= 8;
22075             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_6;
22076             if (num_bits_6 == 8) {
22077               t_6 = ((uint32_t)(*scratch));
22078               break;
22079             }
22080             num_bits_6 += 8;
22081             *scratch |= ((uint64_t)(num_bits_6)) << 56;
22082           }
22083         }
22084         self->private_impl.f_bits_per_pixel = t_6;
22085       }
22086     } else if (self->private_impl.f_bitmap_info_len == 16) {
22087       {
22088         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
22089         uint32_t t_7;
22090         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
22091           t_7 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
22092           iop_a_src += 4;
22093         } else {
22094           self->private_data.s_decode_image_config[0].scratch = 0;
22095           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(17);
22096           while (true) {
22097             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22098               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22099               goto suspend;
22100             }
22101             uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22102             uint32_t num_bits_7 = ((uint32_t)(*scratch >> 56));
22103             *scratch <<= 8;
22104             *scratch >>= 8;
22105             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_7;
22106             if (num_bits_7 == 24) {
22107               t_7 = ((uint32_t)(*scratch));
22108               break;
22109             }
22110             num_bits_7 += 8;
22111             *scratch |= ((uint64_t)(num_bits_7)) << 56;
22112           }
22113         }
22114         v_width = t_7;
22115       }
22116       if (v_width >= 2147483648) {
22117         status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
22118         goto exit;
22119       }
22120       self->private_impl.f_width = v_width;
22121       {
22122         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(18);
22123         uint32_t t_8;
22124         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
22125           t_8 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
22126           iop_a_src += 4;
22127         } else {
22128           self->private_data.s_decode_image_config[0].scratch = 0;
22129           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(19);
22130           while (true) {
22131             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22132               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22133               goto suspend;
22134             }
22135             uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22136             uint32_t num_bits_8 = ((uint32_t)(*scratch >> 56));
22137             *scratch <<= 8;
22138             *scratch >>= 8;
22139             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_8;
22140             if (num_bits_8 == 24) {
22141               t_8 = ((uint32_t)(*scratch));
22142               break;
22143             }
22144             num_bits_8 += 8;
22145             *scratch |= ((uint64_t)(num_bits_8)) << 56;
22146           }
22147         }
22148         v_height = t_8;
22149       }
22150       if (v_height >= 2147483648) {
22151         status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
22152         goto exit;
22153       }
22154       self->private_impl.f_height = v_height;
22155       {
22156         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(20);
22157         uint32_t t_9;
22158         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
22159           t_9 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
22160           iop_a_src += 2;
22161         } else {
22162           self->private_data.s_decode_image_config[0].scratch = 0;
22163           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(21);
22164           while (true) {
22165             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22166               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22167               goto suspend;
22168             }
22169             uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22170             uint32_t num_bits_9 = ((uint32_t)(*scratch >> 56));
22171             *scratch <<= 8;
22172             *scratch >>= 8;
22173             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_9;
22174             if (num_bits_9 == 8) {
22175               t_9 = ((uint32_t)(*scratch));
22176               break;
22177             }
22178             num_bits_9 += 8;
22179             *scratch |= ((uint64_t)(num_bits_9)) << 56;
22180           }
22181         }
22182         v_planes = t_9;
22183       }
22184       if (v_planes != 1) {
22185         status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
22186         goto exit;
22187       }
22188       {
22189         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(22);
22190         uint32_t t_10;
22191         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
22192           t_10 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
22193           iop_a_src += 2;
22194         } else {
22195           self->private_data.s_decode_image_config[0].scratch = 0;
22196           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(23);
22197           while (true) {
22198             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22199               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22200               goto suspend;
22201             }
22202             uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22203             uint32_t num_bits_10 = ((uint32_t)(*scratch >> 56));
22204             *scratch <<= 8;
22205             *scratch >>= 8;
22206             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_10;
22207             if (num_bits_10 == 8) {
22208               t_10 = ((uint32_t)(*scratch));
22209               break;
22210             }
22211             num_bits_10 += 8;
22212             *scratch |= ((uint64_t)(num_bits_10)) << 56;
22213           }
22214         }
22215         self->private_impl.f_bits_per_pixel = t_10;
22216       }
22217     } else {
22218       {
22219         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(24);
22220         uint32_t t_11;
22221         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
22222           t_11 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
22223           iop_a_src += 4;
22224         } else {
22225           self->private_data.s_decode_image_config[0].scratch = 0;
22226           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(25);
22227           while (true) {
22228             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22229               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22230               goto suspend;
22231             }
22232             uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22233             uint32_t num_bits_11 = ((uint32_t)(*scratch >> 56));
22234             *scratch <<= 8;
22235             *scratch >>= 8;
22236             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_11;
22237             if (num_bits_11 == 24) {
22238               t_11 = ((uint32_t)(*scratch));
22239               break;
22240             }
22241             num_bits_11 += 8;
22242             *scratch |= ((uint64_t)(num_bits_11)) << 56;
22243           }
22244         }
22245         v_width = t_11;
22246       }
22247       if (v_width >= 2147483648) {
22248         status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
22249         goto exit;
22250       }
22251       self->private_impl.f_width = v_width;
22252       {
22253         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(26);
22254         uint32_t t_12;
22255         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
22256           t_12 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
22257           iop_a_src += 4;
22258         } else {
22259           self->private_data.s_decode_image_config[0].scratch = 0;
22260           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(27);
22261           while (true) {
22262             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22263               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22264               goto suspend;
22265             }
22266             uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22267             uint32_t num_bits_12 = ((uint32_t)(*scratch >> 56));
22268             *scratch <<= 8;
22269             *scratch >>= 8;
22270             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_12;
22271             if (num_bits_12 == 24) {
22272               t_12 = ((uint32_t)(*scratch));
22273               break;
22274             }
22275             num_bits_12 += 8;
22276             *scratch |= ((uint64_t)(num_bits_12)) << 56;
22277           }
22278         }
22279         v_height = t_12;
22280       }
22281       if (v_height == 2147483648) {
22282         status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
22283         goto exit;
22284       } else if (v_height >= 2147483648) {
22285         self->private_impl.f_height = (((uint32_t)(0 - v_height)) & 2147483647);
22286         self->private_impl.f_top_down = true;
22287       } else {
22288         self->private_impl.f_height = v_height;
22289       }
22290       {
22291         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(28);
22292         uint32_t t_13;
22293         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
22294           t_13 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
22295           iop_a_src += 2;
22296         } else {
22297           self->private_data.s_decode_image_config[0].scratch = 0;
22298           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(29);
22299           while (true) {
22300             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22301               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22302               goto suspend;
22303             }
22304             uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22305             uint32_t num_bits_13 = ((uint32_t)(*scratch >> 56));
22306             *scratch <<= 8;
22307             *scratch >>= 8;
22308             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_13;
22309             if (num_bits_13 == 8) {
22310               t_13 = ((uint32_t)(*scratch));
22311               break;
22312             }
22313             num_bits_13 += 8;
22314             *scratch |= ((uint64_t)(num_bits_13)) << 56;
22315           }
22316         }
22317         v_planes = t_13;
22318       }
22319       if (v_planes != 1) {
22320         status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
22321         goto exit;
22322       }
22323       {
22324         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(30);
22325         uint32_t t_14;
22326         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
22327           t_14 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
22328           iop_a_src += 2;
22329         } else {
22330           self->private_data.s_decode_image_config[0].scratch = 0;
22331           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(31);
22332           while (true) {
22333             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22334               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22335               goto suspend;
22336             }
22337             uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22338             uint32_t num_bits_14 = ((uint32_t)(*scratch >> 56));
22339             *scratch <<= 8;
22340             *scratch >>= 8;
22341             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_14;
22342             if (num_bits_14 == 8) {
22343               t_14 = ((uint32_t)(*scratch));
22344               break;
22345             }
22346             num_bits_14 += 8;
22347             *scratch |= ((uint64_t)(num_bits_14)) << 56;
22348           }
22349         }
22350         self->private_impl.f_bits_per_pixel = t_14;
22351       }
22352       {
22353         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(32);
22354         uint32_t t_15;
22355         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
22356           t_15 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
22357           iop_a_src += 4;
22358         } else {
22359           self->private_data.s_decode_image_config[0].scratch = 0;
22360           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(33);
22361           while (true) {
22362             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22363               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22364               goto suspend;
22365             }
22366             uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22367             uint32_t num_bits_15 = ((uint32_t)(*scratch >> 56));
22368             *scratch <<= 8;
22369             *scratch >>= 8;
22370             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_15;
22371             if (num_bits_15 == 24) {
22372               t_15 = ((uint32_t)(*scratch));
22373               break;
22374             }
22375             num_bits_15 += 8;
22376             *scratch |= ((uint64_t)(num_bits_15)) << 56;
22377           }
22378         }
22379         self->private_impl.f_compression = t_15;
22380       }
22381       if (self->private_impl.f_bits_per_pixel == 0) {
22382         if (self->private_impl.f_compression == 4) {
22383           self->private_impl.f_io_redirect_fourcc = 1246774599;
22384           status = wuffs_base__make_status(wuffs_base__note__i_o_redirect);
22385           goto ok;
22386         } else if (self->private_impl.f_compression == 5) {
22387           self->private_impl.f_io_redirect_fourcc = 1347307296;
22388           status = wuffs_base__make_status(wuffs_base__note__i_o_redirect);
22389           goto ok;
22390         }
22391         status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
22392         goto exit;
22393       }
22394       self->private_data.s_decode_image_config[0].scratch = 20;
22395       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(34);
22396       if (self->private_data.s_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
22397         self->private_data.s_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
22398         iop_a_src = io2_a_src;
22399         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22400         goto suspend;
22401       }
22402       iop_a_src += self->private_data.s_decode_image_config[0].scratch;
22403       if (self->private_impl.f_bitmap_info_len == 40) {
22404         if (self->private_impl.f_bits_per_pixel >= 16) {
22405           if (self->private_impl.f_padding >= 16) {
22406             self->private_impl.f_bitmap_info_len = 56;
22407             self->private_impl.f_padding -= 16;
22408           } else if (self->private_impl.f_padding >= 12) {
22409             self->private_impl.f_bitmap_info_len = 52;
22410             self->private_impl.f_padding -= 12;
22411           }
22412         }
22413       } else if ((self->private_impl.f_bitmap_info_len != 52) &&
22414           (self->private_impl.f_bitmap_info_len != 56) &&
22415           (self->private_impl.f_bitmap_info_len != 64) &&
22416           (self->private_impl.f_bitmap_info_len != 108) &&
22417           (self->private_impl.f_bitmap_info_len != 124)) {
22418         status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
22419         goto exit;
22420       }
22421       if (self->private_impl.f_compression == 6) {
22422         self->private_impl.f_compression = 3;
22423       }
22424       if (self->private_impl.f_compression == 3) {
22425         if (self->private_impl.f_bitmap_info_len >= 52) {
22426           {
22427             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(35);
22428             uint32_t t_16;
22429             if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
22430               t_16 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
22431               iop_a_src += 4;
22432             } else {
22433               self->private_data.s_decode_image_config[0].scratch = 0;
22434               WUFFS_BASE__COROUTINE_SUSPENSION_POINT(36);
22435               while (true) {
22436                 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22437                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22438                   goto suspend;
22439                 }
22440                 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22441                 uint32_t num_bits_16 = ((uint32_t)(*scratch >> 56));
22442                 *scratch <<= 8;
22443                 *scratch >>= 8;
22444                 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_16;
22445                 if (num_bits_16 == 24) {
22446                   t_16 = ((uint32_t)(*scratch));
22447                   break;
22448                 }
22449                 num_bits_16 += 8;
22450                 *scratch |= ((uint64_t)(num_bits_16)) << 56;
22451               }
22452             }
22453             self->private_impl.f_channel_masks[2] = t_16;
22454           }
22455           {
22456             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(37);
22457             uint32_t t_17;
22458             if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
22459               t_17 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
22460               iop_a_src += 4;
22461             } else {
22462               self->private_data.s_decode_image_config[0].scratch = 0;
22463               WUFFS_BASE__COROUTINE_SUSPENSION_POINT(38);
22464               while (true) {
22465                 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22466                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22467                   goto suspend;
22468                 }
22469                 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22470                 uint32_t num_bits_17 = ((uint32_t)(*scratch >> 56));
22471                 *scratch <<= 8;
22472                 *scratch >>= 8;
22473                 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_17;
22474                 if (num_bits_17 == 24) {
22475                   t_17 = ((uint32_t)(*scratch));
22476                   break;
22477                 }
22478                 num_bits_17 += 8;
22479                 *scratch |= ((uint64_t)(num_bits_17)) << 56;
22480               }
22481             }
22482             self->private_impl.f_channel_masks[1] = t_17;
22483           }
22484           {
22485             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(39);
22486             uint32_t t_18;
22487             if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
22488               t_18 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
22489               iop_a_src += 4;
22490             } else {
22491               self->private_data.s_decode_image_config[0].scratch = 0;
22492               WUFFS_BASE__COROUTINE_SUSPENSION_POINT(40);
22493               while (true) {
22494                 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22495                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22496                   goto suspend;
22497                 }
22498                 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22499                 uint32_t num_bits_18 = ((uint32_t)(*scratch >> 56));
22500                 *scratch <<= 8;
22501                 *scratch >>= 8;
22502                 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_18;
22503                 if (num_bits_18 == 24) {
22504                   t_18 = ((uint32_t)(*scratch));
22505                   break;
22506                 }
22507                 num_bits_18 += 8;
22508                 *scratch |= ((uint64_t)(num_bits_18)) << 56;
22509               }
22510             }
22511             self->private_impl.f_channel_masks[0] = t_18;
22512           }
22513           if (self->private_impl.f_bitmap_info_len >= 56) {
22514             {
22515               WUFFS_BASE__COROUTINE_SUSPENSION_POINT(41);
22516               uint32_t t_19;
22517               if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
22518                 t_19 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
22519                 iop_a_src += 4;
22520               } else {
22521                 self->private_data.s_decode_image_config[0].scratch = 0;
22522                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(42);
22523                 while (true) {
22524                   if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22525                     status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22526                     goto suspend;
22527                   }
22528                   uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22529                   uint32_t num_bits_19 = ((uint32_t)(*scratch >> 56));
22530                   *scratch <<= 8;
22531                   *scratch >>= 8;
22532                   *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_19;
22533                   if (num_bits_19 == 24) {
22534                     t_19 = ((uint32_t)(*scratch));
22535                     break;
22536                   }
22537                   num_bits_19 += 8;
22538                   *scratch |= ((uint64_t)(num_bits_19)) << 56;
22539                 }
22540               }
22541               self->private_impl.f_channel_masks[3] = t_19;
22542             }
22543             self->private_data.s_decode_image_config[0].scratch = ((uint32_t)(self->private_impl.f_bitmap_info_len - 56));
22544             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(43);
22545             if (self->private_data.s_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
22546               self->private_data.s_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
22547               iop_a_src = io2_a_src;
22548               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22549               goto suspend;
22550             }
22551             iop_a_src += self->private_data.s_decode_image_config[0].scratch;
22552           }
22553           if ((self->private_impl.f_channel_masks[0] == 255) && (self->private_impl.f_channel_masks[1] == 65280) && (self->private_impl.f_channel_masks[2] == 16711680)) {
22554             if (self->private_impl.f_bits_per_pixel == 24) {
22555               self->private_impl.f_compression = 0;
22556             } else if (self->private_impl.f_bits_per_pixel == 32) {
22557               if ((self->private_impl.f_channel_masks[3] == 0) || (self->private_impl.f_channel_masks[3] == 4278190080)) {
22558                 self->private_impl.f_compression = 0;
22559               }
22560             }
22561           }
22562           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(44);
22563           status = wuffs_bmp__decoder__process_masks(self);
22564           if (status.repr) {
22565             goto suspend;
22566           }
22567         }
22568       } else if (self->private_impl.f_bitmap_info_len >= 40) {
22569         self->private_data.s_decode_image_config[0].scratch = (self->private_impl.f_bitmap_info_len - 40);
22570         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(45);
22571         if (self->private_data.s_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
22572           self->private_data.s_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
22573           iop_a_src = io2_a_src;
22574           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22575           goto suspend;
22576         }
22577         iop_a_src += self->private_data.s_decode_image_config[0].scratch;
22578       } else {
22579         status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
22580         goto exit;
22581       }
22582     }
22583     if (self->private_impl.f_compression != 3) {
22584       if (self->private_impl.f_bits_per_pixel < 16) {
22585         if (a_src) {
22586           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
22587         }
22588         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(46);
22589         status = wuffs_bmp__decoder__read_palette(self, a_src);
22590         if (a_src) {
22591           iop_a_src = a_src->data.ptr + a_src->meta.ri;
22592         }
22593         if (status.repr) {
22594           goto suspend;
22595         }
22596       }
22597     }
22598     if (self->private_impl.f_compression == 0) {
22599       if ((self->private_impl.f_bits_per_pixel == 1) || (self->private_impl.f_bits_per_pixel == 2) || (self->private_impl.f_bits_per_pixel == 4)) {
22600         self->private_impl.f_src_pixfmt = 2198077448;
22601         self->private_impl.f_compression = 256;
22602       } else if (self->private_impl.f_bits_per_pixel == 8) {
22603         self->private_impl.f_src_pixfmt = 2198077448;
22604       } else if (self->private_impl.f_bits_per_pixel == 16) {
22605         self->private_impl.f_compression = 3;
22606         self->private_impl.f_channel_masks[0] = 31;
22607         self->private_impl.f_channel_masks[1] = 992;
22608         self->private_impl.f_channel_masks[2] = 31744;
22609         self->private_impl.f_channel_masks[3] = 0;
22610         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(47);
22611         status = wuffs_bmp__decoder__process_masks(self);
22612         if (status.repr) {
22613           goto suspend;
22614         }
22615         self->private_impl.f_src_pixfmt = 2164308923;
22616       } else if (self->private_impl.f_bits_per_pixel == 24) {
22617         self->private_impl.f_src_pixfmt = 2147485832;
22618       } else if (self->private_impl.f_bits_per_pixel == 32) {
22619         if (self->private_impl.f_channel_masks[3] == 0) {
22620           self->private_impl.f_src_pixfmt = 2415954056;
22621         } else {
22622           self->private_impl.f_src_pixfmt = 2164295816;
22623         }
22624       } else {
22625         status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
22626         goto exit;
22627       }
22628     } else if (self->private_impl.f_compression == 1) {
22629       if (self->private_impl.f_bits_per_pixel == 8) {
22630         self->private_impl.f_src_pixfmt = 2198077448;
22631       } else {
22632         status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
22633         goto exit;
22634       }
22635     } else if (self->private_impl.f_compression == 2) {
22636       if (self->private_impl.f_bits_per_pixel == 4) {
22637         self->private_impl.f_src_pixfmt = 2198077448;
22638       } else {
22639         status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
22640         goto exit;
22641       }
22642     } else if (self->private_impl.f_compression == 3) {
22643       if ((self->private_impl.f_bits_per_pixel == 16) || (self->private_impl.f_bits_per_pixel == 32)) {
22644         self->private_impl.f_src_pixfmt = 2164308923;
22645       } else {
22646         status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
22647         goto exit;
22648       }
22649     } else {
22650       status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
22651       goto exit;
22652     }
22653     if (((self->private_impl.f_bitmap_info_len < 40) || (self->private_impl.f_bitmap_info_len == 64)) &&
22654         (self->private_impl.f_bits_per_pixel != 1) &&
22655         (self->private_impl.f_bits_per_pixel != 4) &&
22656         (self->private_impl.f_bits_per_pixel != 8) &&
22657         (self->private_impl.f_bits_per_pixel != 24)) {
22658       status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
22659       goto exit;
22660     }
22661     if (self->private_impl.f_bits_per_pixel == 1) {
22662       v_byte_width = ((self->private_impl.f_width >> 3) + (((self->private_impl.f_width & 7) + 7) >> 3));
22663       self->private_impl.f_pad_per_row = ((4 - (v_byte_width & 3)) & 3);
22664     } else if (self->private_impl.f_bits_per_pixel == 2) {
22665       v_byte_width = ((self->private_impl.f_width >> 2) + (((self->private_impl.f_width & 3) + 3) >> 2));
22666       self->private_impl.f_pad_per_row = ((4 - (v_byte_width & 3)) & 3);
22667     } else if (self->private_impl.f_bits_per_pixel == 4) {
22668       v_byte_width = ((self->private_impl.f_width >> 1) + (self->private_impl.f_width & 1));
22669       self->private_impl.f_pad_per_row = ((4 - (v_byte_width & 3)) & 3);
22670     } else if (self->private_impl.f_bits_per_pixel == 8) {
22671       self->private_impl.f_pad_per_row = ((4 - (self->private_impl.f_width & 3)) & 3);
22672     } else if (self->private_impl.f_bits_per_pixel == 16) {
22673       self->private_impl.f_pad_per_row = ((self->private_impl.f_width & 1) * 2);
22674     } else if (self->private_impl.f_bits_per_pixel == 24) {
22675       self->private_impl.f_pad_per_row = (self->private_impl.f_width & 3);
22676     } else if (self->private_impl.f_bits_per_pixel == 32) {
22677       self->private_impl.f_pad_per_row = 0;
22678     }
22679     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)));
22680     if (a_dst != NULL) {
22681       v_dst_pixfmt = 2164295816;
22682       if ((self->private_impl.f_channel_num_bits[0] > 8) ||
22683           (self->private_impl.f_channel_num_bits[1] > 8) ||
22684           (self->private_impl.f_channel_num_bits[2] > 8) ||
22685           (self->private_impl.f_channel_num_bits[3] > 8)) {
22686         v_dst_pixfmt = 2164308923;
22687       }
22688       wuffs_base__image_config__set(
22689           a_dst,
22690           v_dst_pixfmt,
22691           0,
22692           self->private_impl.f_width,
22693           self->private_impl.f_height,
22694           self->private_impl.f_frame_config_io_position,
22695           (self->private_impl.f_channel_masks[3] == 0));
22696     }
22697     self->private_impl.f_call_sequence = 3;
22698 
22699     ok:
22700     self->private_impl.p_decode_image_config[0] = 0;
22701     goto exit;
22702   }
22703 
22704   goto suspend;
22705   suspend:
22706   self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
22707   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
22708 
22709   goto exit;
22710   exit:
22711   if (a_src) {
22712     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
22713   }
22714 
22715   if (wuffs_base__status__is_error(&status)) {
22716     self->private_impl.magic = WUFFS_BASE__DISABLED;
22717   }
22718   return status;
22719 }
22720 
22721 // -------- func bmp.decoder.decode_frame_config
22722 
22723 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)22724 wuffs_bmp__decoder__decode_frame_config(
22725     wuffs_bmp__decoder* self,
22726     wuffs_base__frame_config* a_dst,
22727     wuffs_base__io_buffer* a_src) {
22728   if (!self) {
22729     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
22730   }
22731   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
22732     return wuffs_base__make_status(
22733         (self->private_impl.magic == WUFFS_BASE__DISABLED)
22734         ? wuffs_base__error__disabled_by_previous_error
22735         : wuffs_base__error__initialize_not_called);
22736   }
22737   if (!a_src) {
22738     self->private_impl.magic = WUFFS_BASE__DISABLED;
22739     return wuffs_base__make_status(wuffs_base__error__bad_argument);
22740   }
22741   if ((self->private_impl.active_coroutine != 0) &&
22742       (self->private_impl.active_coroutine != 2)) {
22743     self->private_impl.magic = WUFFS_BASE__DISABLED;
22744     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
22745   }
22746   self->private_impl.active_coroutine = 0;
22747   wuffs_base__status status = wuffs_base__make_status(NULL);
22748 
22749   const uint8_t* iop_a_src = NULL;
22750   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
22751   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
22752   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
22753   if (a_src) {
22754     io0_a_src = a_src->data.ptr;
22755     io1_a_src = io0_a_src + a_src->meta.ri;
22756     iop_a_src = io1_a_src;
22757     io2_a_src = io0_a_src + a_src->meta.wi;
22758   }
22759 
22760   uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
22761   switch (coro_susp_point) {
22762     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
22763 
22764     if (self->private_impl.f_call_sequence < 3) {
22765       if (a_src) {
22766         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
22767       }
22768       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
22769       status = wuffs_bmp__decoder__decode_image_config(self, NULL, a_src);
22770       if (a_src) {
22771         iop_a_src = a_src->data.ptr + a_src->meta.ri;
22772       }
22773       if (status.repr) {
22774         goto suspend;
22775       }
22776     } else if (self->private_impl.f_call_sequence == 3) {
22777       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)))) {
22778         status = wuffs_base__make_status(wuffs_base__error__bad_restart);
22779         goto exit;
22780       }
22781     } else if (self->private_impl.f_call_sequence == 4) {
22782       self->private_impl.f_call_sequence = 255;
22783       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
22784       goto ok;
22785     } else {
22786       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
22787       goto ok;
22788     }
22789     if (a_dst != NULL) {
22790       wuffs_base__frame_config__set(
22791           a_dst,
22792           wuffs_base__utility__make_rect_ie_u32(
22793           0,
22794           0,
22795           self->private_impl.f_width,
22796           self->private_impl.f_height),
22797           ((wuffs_base__flicks)(0)),
22798           0,
22799           self->private_impl.f_frame_config_io_position,
22800           0,
22801           true,
22802           false,
22803           4278190080);
22804     }
22805     self->private_impl.f_call_sequence = 4;
22806 
22807     ok:
22808     self->private_impl.p_decode_frame_config[0] = 0;
22809     goto exit;
22810   }
22811 
22812   goto suspend;
22813   suspend:
22814   self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
22815   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
22816 
22817   goto exit;
22818   exit:
22819   if (a_src) {
22820     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
22821   }
22822 
22823   if (wuffs_base__status__is_error(&status)) {
22824     self->private_impl.magic = WUFFS_BASE__DISABLED;
22825   }
22826   return status;
22827 }
22828 
22829 // -------- func bmp.decoder.decode_frame
22830 
22831 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)22832 wuffs_bmp__decoder__decode_frame(
22833     wuffs_bmp__decoder* self,
22834     wuffs_base__pixel_buffer* a_dst,
22835     wuffs_base__io_buffer* a_src,
22836     wuffs_base__pixel_blend a_blend,
22837     wuffs_base__slice_u8 a_workbuf,
22838     wuffs_base__decode_frame_options* a_opts) {
22839   if (!self) {
22840     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
22841   }
22842   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
22843     return wuffs_base__make_status(
22844         (self->private_impl.magic == WUFFS_BASE__DISABLED)
22845         ? wuffs_base__error__disabled_by_previous_error
22846         : wuffs_base__error__initialize_not_called);
22847   }
22848   if (!a_dst || !a_src) {
22849     self->private_impl.magic = WUFFS_BASE__DISABLED;
22850     return wuffs_base__make_status(wuffs_base__error__bad_argument);
22851   }
22852   if ((self->private_impl.active_coroutine != 0) &&
22853       (self->private_impl.active_coroutine != 3)) {
22854     self->private_impl.magic = WUFFS_BASE__DISABLED;
22855     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
22856   }
22857   self->private_impl.active_coroutine = 0;
22858   wuffs_base__status status = wuffs_base__make_status(NULL);
22859 
22860   wuffs_base__status v_status = wuffs_base__make_status(NULL);
22861 
22862   const uint8_t* iop_a_src = NULL;
22863   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
22864   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
22865   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
22866   if (a_src) {
22867     io0_a_src = a_src->data.ptr;
22868     io1_a_src = io0_a_src + a_src->meta.ri;
22869     iop_a_src = io1_a_src;
22870     io2_a_src = io0_a_src + a_src->meta.wi;
22871   }
22872 
22873   uint32_t coro_susp_point = self->private_impl.p_decode_frame[0];
22874   if (coro_susp_point) {
22875     v_status = self->private_data.s_decode_frame[0].v_status;
22876   }
22877   switch (coro_susp_point) {
22878     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
22879 
22880     if (self->private_impl.f_call_sequence < 4) {
22881       if (a_src) {
22882         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
22883       }
22884       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
22885       status = wuffs_bmp__decoder__decode_frame_config(self, NULL, a_src);
22886       if (a_src) {
22887         iop_a_src = a_src->data.ptr + a_src->meta.ri;
22888       }
22889       if (status.repr) {
22890         goto suspend;
22891       }
22892     } else if (self->private_impl.f_call_sequence == 4) {
22893     } else {
22894       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
22895       goto ok;
22896     }
22897     self->private_data.s_decode_frame[0].scratch = self->private_impl.f_padding;
22898     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
22899     if (self->private_data.s_decode_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
22900       self->private_data.s_decode_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
22901       iop_a_src = io2_a_src;
22902       status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22903       goto suspend;
22904     }
22905     iop_a_src += self->private_data.s_decode_frame[0].scratch;
22906     if ((self->private_impl.f_width > 0) && (self->private_impl.f_height > 0)) {
22907       self->private_impl.f_dst_x = 0;
22908       if (self->private_impl.f_top_down) {
22909         self->private_impl.f_dst_y = 0;
22910         self->private_impl.f_dst_y_inc = 1;
22911       } else {
22912         self->private_impl.f_dst_y = ((uint32_t)(self->private_impl.f_height - 1));
22913         self->private_impl.f_dst_y_inc = 4294967295;
22914       }
22915       v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
22916           wuffs_base__pixel_buffer__pixel_format(a_dst),
22917           wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8((self->private_data.f_scratch) + 1024, 1024)),
22918           wuffs_base__utility__make_pixel_format(self->private_impl.f_src_pixfmt),
22919           wuffs_base__make_slice_u8(self->private_data.f_src_palette, 1024),
22920           a_blend);
22921       if ( ! wuffs_base__status__is_ok(&v_status)) {
22922         status = v_status;
22923         if (wuffs_base__status__is_error(&status)) {
22924           goto exit;
22925         } else if (wuffs_base__status__is_suspension(&status)) {
22926           status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
22927           goto exit;
22928         }
22929         goto ok;
22930       }
22931       while (true) {
22932         if (self->private_impl.f_compression == 0) {
22933           if (a_src) {
22934             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
22935           }
22936           v_status = wuffs_bmp__decoder__swizzle_none(self, a_dst, a_src);
22937           if (a_src) {
22938             iop_a_src = a_src->data.ptr + a_src->meta.ri;
22939           }
22940         } else if (self->private_impl.f_compression < 3) {
22941           if (a_src) {
22942             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
22943           }
22944           v_status = wuffs_bmp__decoder__swizzle_rle(self, a_dst, a_src);
22945           if (a_src) {
22946             iop_a_src = a_src->data.ptr + a_src->meta.ri;
22947           }
22948         } else if (self->private_impl.f_compression == 3) {
22949           if (a_src) {
22950             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
22951           }
22952           v_status = wuffs_bmp__decoder__swizzle_bitfields(self, a_dst, a_src);
22953           if (a_src) {
22954             iop_a_src = a_src->data.ptr + a_src->meta.ri;
22955           }
22956         } else {
22957           if (a_src) {
22958             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
22959           }
22960           v_status = wuffs_bmp__decoder__swizzle_low_bit_depth(self, a_dst, a_src);
22961           if (a_src) {
22962             iop_a_src = a_src->data.ptr + a_src->meta.ri;
22963           }
22964         }
22965         if (wuffs_base__status__is_ok(&v_status)) {
22966           goto label__0__break;
22967         } else if (v_status.repr != wuffs_bmp__note__internal_note_short_read) {
22968           status = v_status;
22969           if (wuffs_base__status__is_error(&status)) {
22970             goto exit;
22971           } else if (wuffs_base__status__is_suspension(&status)) {
22972             status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
22973             goto exit;
22974           }
22975           goto ok;
22976         }
22977         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22978         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
22979       }
22980       label__0__break:;
22981       self->private_data.s_decode_frame[0].scratch = self->private_impl.f_pending_pad;
22982       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
22983       if (self->private_data.s_decode_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
22984         self->private_data.s_decode_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
22985         iop_a_src = io2_a_src;
22986         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22987         goto suspend;
22988       }
22989       iop_a_src += self->private_data.s_decode_frame[0].scratch;
22990       self->private_impl.f_pending_pad = 0;
22991     }
22992     self->private_impl.f_call_sequence = 255;
22993 
22994     ok:
22995     self->private_impl.p_decode_frame[0] = 0;
22996     goto exit;
22997   }
22998 
22999   goto suspend;
23000   suspend:
23001   self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
23002   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
23003   self->private_data.s_decode_frame[0].v_status = v_status;
23004 
23005   goto exit;
23006   exit:
23007   if (a_src) {
23008     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23009   }
23010 
23011   if (wuffs_base__status__is_error(&status)) {
23012     self->private_impl.magic = WUFFS_BASE__DISABLED;
23013   }
23014   return status;
23015 }
23016 
23017 // -------- func bmp.decoder.swizzle_none
23018 
23019 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)23020 wuffs_bmp__decoder__swizzle_none(
23021     wuffs_bmp__decoder* self,
23022     wuffs_base__pixel_buffer* a_dst,
23023     wuffs_base__io_buffer* a_src) {
23024   wuffs_base__status status = wuffs_base__make_status(NULL);
23025 
23026   wuffs_base__pixel_format v_dst_pixfmt = {0};
23027   uint32_t v_dst_bits_per_pixel = 0;
23028   uint64_t v_dst_bytes_per_pixel = 0;
23029   uint64_t v_dst_bytes_per_row = 0;
23030   wuffs_base__slice_u8 v_dst_palette = {0};
23031   wuffs_base__table_u8 v_tab = {0};
23032   wuffs_base__slice_u8 v_dst = {0};
23033   uint64_t v_i = 0;
23034   uint64_t v_n = 0;
23035 
23036   const uint8_t* iop_a_src = NULL;
23037   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23038   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23039   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23040   if (a_src) {
23041     io0_a_src = a_src->data.ptr;
23042     io1_a_src = io0_a_src + a_src->meta.ri;
23043     iop_a_src = io1_a_src;
23044     io2_a_src = io0_a_src + a_src->meta.wi;
23045   }
23046 
23047   v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
23048   v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
23049   if ((v_dst_bits_per_pixel & 7) != 0) {
23050     status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
23051     goto exit;
23052   }
23053   v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8)));
23054   v_dst_bytes_per_row = (((uint64_t)(self->private_impl.f_width)) * v_dst_bytes_per_pixel);
23055   v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8((self->private_data.f_scratch) + 1024, 1024));
23056   v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0);
23057   label__outer__continue:;
23058   while (true) {
23059     while (self->private_impl.f_pending_pad > 0) {
23060       if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
23061         status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
23062         goto ok;
23063       }
23064       self->private_impl.f_pending_pad -= 1;
23065       iop_a_src += 1;
23066     }
23067     label__inner__continue:;
23068     while (true) {
23069       if (self->private_impl.f_dst_x == self->private_impl.f_width) {
23070         self->private_impl.f_dst_x = 0;
23071         self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc;
23072         if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
23073           if (self->private_impl.f_height > 0) {
23074             self->private_impl.f_pending_pad = self->private_impl.f_pad_per_row;
23075           }
23076           goto label__outer__break;
23077         } else if (self->private_impl.f_pad_per_row != 0) {
23078           self->private_impl.f_pending_pad = self->private_impl.f_pad_per_row;
23079           goto label__outer__continue;
23080         }
23081       }
23082       v_dst = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
23083       if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) {
23084         v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row);
23085       }
23086       v_i = (((uint64_t)(self->private_impl.f_dst_x)) * v_dst_bytes_per_pixel);
23087       if (v_i >= ((uint64_t)(v_dst.len))) {
23088         goto label__inner__continue;
23089       }
23090       v_n = wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(
23091           &self->private_impl.f_swizzler,
23092           wuffs_base__slice_u8__subslice_i(v_dst, v_i),
23093           v_dst_palette,
23094           &iop_a_src,
23095           io2_a_src);
23096       if (v_n == 0) {
23097         status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
23098         goto ok;
23099       }
23100       wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)((v_n & 4294967295))));
23101     }
23102   }
23103   label__outer__break:;
23104   status = wuffs_base__make_status(NULL);
23105   goto ok;
23106 
23107   ok:
23108   goto exit;
23109   exit:
23110   if (a_src) {
23111     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23112   }
23113 
23114   return status;
23115 }
23116 
23117 // -------- func bmp.decoder.swizzle_rle
23118 
23119 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)23120 wuffs_bmp__decoder__swizzle_rle(
23121     wuffs_bmp__decoder* self,
23122     wuffs_base__pixel_buffer* a_dst,
23123     wuffs_base__io_buffer* a_src) {
23124   wuffs_base__status status = wuffs_base__make_status(NULL);
23125 
23126   wuffs_base__pixel_format v_dst_pixfmt = {0};
23127   uint32_t v_dst_bits_per_pixel = 0;
23128   uint64_t v_dst_bytes_per_pixel = 0;
23129   uint64_t v_dst_bytes_per_row = 0;
23130   wuffs_base__slice_u8 v_dst_palette = {0};
23131   wuffs_base__table_u8 v_tab = {0};
23132   wuffs_base__slice_u8 v_row = {0};
23133   wuffs_base__slice_u8 v_dst = {0};
23134   uint64_t v_i = 0;
23135   uint64_t v_n = 0;
23136   uint32_t v_p0 = 0;
23137   uint8_t v_code = 0;
23138   uint8_t v_indexes[2] = {0};
23139   uint32_t v_rle_state = 0;
23140   uint32_t v_chunk_bits = 0;
23141   uint32_t v_chunk_count = 0;
23142 
23143   const uint8_t* iop_a_src = NULL;
23144   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23145   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23146   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23147   if (a_src) {
23148     io0_a_src = a_src->data.ptr;
23149     io1_a_src = io0_a_src + a_src->meta.ri;
23150     iop_a_src = io1_a_src;
23151     io2_a_src = io0_a_src + a_src->meta.wi;
23152   }
23153 
23154   v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
23155   v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
23156   if ((v_dst_bits_per_pixel & 7) != 0) {
23157     status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
23158     goto exit;
23159   }
23160   v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8)));
23161   v_dst_bytes_per_row = (((uint64_t)(self->private_impl.f_width)) * v_dst_bytes_per_pixel);
23162   v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8((self->private_data.f_scratch) + 1024, 1024));
23163   v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0);
23164   v_rle_state = self->private_impl.f_rle_state;
23165   label__outer__continue:;
23166   while (true) {
23167     v_row = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
23168     if (v_dst_bytes_per_row < ((uint64_t)(v_row.len))) {
23169       v_row = wuffs_base__slice_u8__subslice_j(v_row, v_dst_bytes_per_row);
23170     }
23171     label__middle__continue:;
23172     while (true) {
23173       v_i = (((uint64_t)(self->private_impl.f_dst_x)) * v_dst_bytes_per_pixel);
23174       if (v_i <= ((uint64_t)(v_row.len))) {
23175         v_dst = wuffs_base__slice_u8__subslice_i(v_row, v_i);
23176       } else {
23177         v_dst = wuffs_base__utility__empty_slice_u8();
23178       }
23179       while (true) {
23180         label__inner__continue:;
23181         while (true) {
23182           if (v_rle_state == 0) {
23183             if (((uint64_t)(io2_a_src - iop_a_src)) < 1) {
23184               goto label__goto_suspend__break;
23185             }
23186             v_code = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
23187             iop_a_src += 1;
23188             if (v_code == 0) {
23189               v_rle_state = 2;
23190               goto label__inner__continue;
23191             }
23192             self->private_impl.f_rle_length = ((uint32_t)(v_code));
23193             v_rle_state = 1;
23194             goto label__inner__continue;
23195           } else if (v_rle_state == 1) {
23196             if (((uint64_t)(io2_a_src - iop_a_src)) < 1) {
23197               goto label__goto_suspend__break;
23198             }
23199             v_code = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
23200             iop_a_src += 1;
23201             if (self->private_impl.f_bits_per_pixel == 8) {
23202               v_p0 = 0;
23203               while (v_p0 < self->private_impl.f_rle_length) {
23204                 self->private_data.f_scratch[v_p0] = v_code;
23205                 v_p0 += 1;
23206               }
23207             } else {
23208               v_indexes[0] = ((uint8_t)((v_code >> 4)));
23209               v_indexes[1] = (v_code & 15);
23210               v_p0 = 0;
23211               while (v_p0 < self->private_impl.f_rle_length) {
23212                 self->private_data.f_scratch[(v_p0 + 0)] = v_indexes[0];
23213                 self->private_data.f_scratch[(v_p0 + 1)] = v_indexes[1];
23214                 v_p0 += 2;
23215               }
23216             }
23217             wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, wuffs_base__slice_u8__subslice_j(wuffs_base__make_slice_u8(self->private_data.f_scratch, 2048), self->private_impl.f_rle_length));
23218             wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, self->private_impl.f_rle_length);
23219             v_rle_state = 0;
23220             goto label__middle__continue;
23221           } else if (v_rle_state == 2) {
23222             if (((uint64_t)(io2_a_src - iop_a_src)) < 1) {
23223               goto label__goto_suspend__break;
23224             }
23225             v_code = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
23226             iop_a_src += 1;
23227             if (v_code < 2) {
23228               if ((self->private_impl.f_dst_y >= self->private_impl.f_height) && (v_code == 0)) {
23229                 status = wuffs_base__make_status(wuffs_bmp__error__bad_rle_compression);
23230                 goto exit;
23231               }
23232               wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(&self->private_impl.f_swizzler, v_dst, v_dst_palette, 18446744073709551615u);
23233               self->private_impl.f_dst_x = 0;
23234               self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc;
23235               if (v_code > 0) {
23236                 goto label__outer__break;
23237               }
23238               v_rle_state = 0;
23239               goto label__outer__continue;
23240             } else if (v_code == 2) {
23241               v_rle_state = 4;
23242               goto label__inner__continue;
23243             }
23244             self->private_impl.f_rle_length = ((uint32_t)(v_code));
23245             self->private_impl.f_rle_padded = ((self->private_impl.f_bits_per_pixel == 8) && ((v_code & 1) != 0));
23246             v_rle_state = 3;
23247             goto label__inner__continue;
23248           } else if (v_rle_state == 3) {
23249             if (self->private_impl.f_bits_per_pixel == 8) {
23250               v_n = wuffs_base__pixel_swizzler__limited_swizzle_u32_interleaved_from_reader(
23251                   &self->private_impl.f_swizzler,
23252                   self->private_impl.f_rle_length,
23253                   v_dst,
23254                   v_dst_palette,
23255                   &iop_a_src,
23256                   io2_a_src);
23257               wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)((v_n & 4294967295))));
23258               wuffs_base__u32__sat_sub_indirect(&self->private_impl.f_rle_length, ((uint32_t)((v_n & 4294967295))));
23259             } else {
23260               v_chunk_count = ((self->private_impl.f_rle_length + 3) / 4);
23261               v_p0 = 0;
23262               while ((v_chunk_count > 0) && (((uint64_t)(io2_a_src - iop_a_src)) >= 2)) {
23263                 v_chunk_bits = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
23264                 iop_a_src += 2;
23265                 self->private_data.f_scratch[(v_p0 + 0)] = ((uint8_t)((15 & (v_chunk_bits >> 12))));
23266                 self->private_data.f_scratch[(v_p0 + 1)] = ((uint8_t)((15 & (v_chunk_bits >> 8))));
23267                 self->private_data.f_scratch[(v_p0 + 2)] = ((uint8_t)((15 & (v_chunk_bits >> 4))));
23268                 self->private_data.f_scratch[(v_p0 + 3)] = ((uint8_t)((15 & (v_chunk_bits >> 0))));
23269                 v_p0 = ((v_p0 & 255) + 4);
23270                 v_chunk_count -= 1;
23271               }
23272               v_p0 = wuffs_base__u32__min(v_p0, self->private_impl.f_rle_length);
23273               wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, wuffs_base__slice_u8__subslice_j(wuffs_base__make_slice_u8(self->private_data.f_scratch, 2048), v_p0));
23274               wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, v_p0);
23275               wuffs_base__u32__sat_sub_indirect(&self->private_impl.f_rle_length, v_p0);
23276             }
23277             if (self->private_impl.f_rle_length > 0) {
23278               goto label__goto_suspend__break;
23279             }
23280             if (self->private_impl.f_rle_padded) {
23281               if (((uint64_t)(io2_a_src - iop_a_src)) < 1) {
23282                 goto label__goto_suspend__break;
23283               }
23284               iop_a_src += 1;
23285               self->private_impl.f_rle_padded = false;
23286             }
23287             v_rle_state = 0;
23288             goto label__middle__continue;
23289           } else if (v_rle_state == 4) {
23290             if (((uint64_t)(io2_a_src - iop_a_src)) < 1) {
23291               goto label__goto_suspend__break;
23292             }
23293             self->private_impl.f_rle_delta_x = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
23294             iop_a_src += 1;
23295             v_rle_state = 5;
23296             goto label__inner__continue;
23297           }
23298           if (((uint64_t)(io2_a_src - iop_a_src)) < 1) {
23299             goto label__goto_suspend__break;
23300           }
23301           v_code = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
23302           iop_a_src += 1;
23303           if (self->private_impl.f_rle_delta_x > 0) {
23304             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)));
23305             wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(self->private_impl.f_rle_delta_x)));
23306             self->private_impl.f_rle_delta_x = 0;
23307             if (self->private_impl.f_dst_x > self->private_impl.f_width) {
23308               status = wuffs_base__make_status(wuffs_bmp__error__bad_rle_compression);
23309               goto exit;
23310             }
23311           }
23312           if (v_code > 0) {
23313 #if defined(__GNUC__)
23314 #pragma GCC diagnostic push
23315 #pragma GCC diagnostic ignored "-Wconversion"
23316 #endif
23317             v_code -= 1;
23318 #if defined(__GNUC__)
23319 #pragma GCC diagnostic pop
23320 #endif
23321             while (true) {
23322               self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc;
23323               if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
23324                 status = wuffs_base__make_status(wuffs_bmp__error__bad_rle_compression);
23325                 goto exit;
23326               }
23327               v_row = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
23328               if (v_dst_bytes_per_row < ((uint64_t)(v_row.len))) {
23329                 v_row = wuffs_base__slice_u8__subslice_j(v_row, v_dst_bytes_per_row);
23330               }
23331               if (v_code <= 0) {
23332                 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)));
23333                 goto label__0__break;
23334               }
23335               wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(&self->private_impl.f_swizzler, v_row, v_dst_palette, 18446744073709551615u);
23336 #if defined(__GNUC__)
23337 #pragma GCC diagnostic push
23338 #pragma GCC diagnostic ignored "-Wconversion"
23339 #endif
23340               v_code -= 1;
23341 #if defined(__GNUC__)
23342 #pragma GCC diagnostic pop
23343 #endif
23344             }
23345             label__0__break:;
23346           }
23347           v_rle_state = 0;
23348           goto label__middle__continue;
23349         }
23350       }
23351       label__goto_suspend__break:;
23352       self->private_impl.f_rle_state = v_rle_state;
23353       status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
23354       goto ok;
23355     }
23356   }
23357   label__outer__break:;
23358   while (self->private_impl.f_dst_y < self->private_impl.f_height) {
23359     v_row = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
23360     if (v_dst_bytes_per_row < ((uint64_t)(v_row.len))) {
23361       v_row = wuffs_base__slice_u8__subslice_j(v_row, v_dst_bytes_per_row);
23362     }
23363     wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(&self->private_impl.f_swizzler, v_row, v_dst_palette, 18446744073709551615u);
23364     self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc;
23365   }
23366   status = wuffs_base__make_status(NULL);
23367   goto ok;
23368 
23369   ok:
23370   goto exit;
23371   exit:
23372   if (a_src) {
23373     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23374   }
23375 
23376   return status;
23377 }
23378 
23379 // -------- func bmp.decoder.swizzle_bitfields
23380 
23381 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)23382 wuffs_bmp__decoder__swizzle_bitfields(
23383     wuffs_bmp__decoder* self,
23384     wuffs_base__pixel_buffer* a_dst,
23385     wuffs_base__io_buffer* a_src) {
23386   wuffs_base__status status = wuffs_base__make_status(NULL);
23387 
23388   wuffs_base__pixel_format v_dst_pixfmt = {0};
23389   uint32_t v_dst_bits_per_pixel = 0;
23390   uint64_t v_dst_bytes_per_pixel = 0;
23391   uint64_t v_dst_bytes_per_row = 0;
23392   wuffs_base__slice_u8 v_dst_palette = {0};
23393   wuffs_base__table_u8 v_tab = {0};
23394   wuffs_base__slice_u8 v_dst = {0};
23395   uint64_t v_i = 0;
23396   uint64_t v_n = 0;
23397   uint32_t v_p0 = 0;
23398   uint32_t v_p1 = 0;
23399   uint32_t v_p1_temp = 0;
23400   uint32_t v_num_bits = 0;
23401   uint32_t v_c = 0;
23402   uint32_t v_c32 = 0;
23403   uint32_t v_channel = 0;
23404 
23405   const uint8_t* iop_a_src = NULL;
23406   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23407   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23408   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23409   if (a_src) {
23410     io0_a_src = a_src->data.ptr;
23411     io1_a_src = io0_a_src + a_src->meta.ri;
23412     iop_a_src = io1_a_src;
23413     io2_a_src = io0_a_src + a_src->meta.wi;
23414   }
23415 
23416   v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
23417   v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
23418   if ((v_dst_bits_per_pixel & 7) != 0) {
23419     status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
23420     goto exit;
23421   }
23422   v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8)));
23423   v_dst_bytes_per_row = (((uint64_t)(self->private_impl.f_width)) * v_dst_bytes_per_pixel);
23424   v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8((self->private_data.f_scratch) + 1024, 1024));
23425   v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0);
23426   label__outer__continue:;
23427   while (true) {
23428     while (self->private_impl.f_pending_pad > 0) {
23429       if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
23430         status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
23431         goto ok;
23432       }
23433       self->private_impl.f_pending_pad -= 1;
23434       iop_a_src += 1;
23435     }
23436     label__inner__continue:;
23437     while (true) {
23438       if (self->private_impl.f_dst_x == self->private_impl.f_width) {
23439         self->private_impl.f_dst_x = 0;
23440         self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc;
23441         if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
23442           if (self->private_impl.f_height > 0) {
23443             self->private_impl.f_pending_pad = self->private_impl.f_pad_per_row;
23444           }
23445           goto label__outer__break;
23446         } else if (self->private_impl.f_pad_per_row != 0) {
23447           self->private_impl.f_pending_pad = self->private_impl.f_pad_per_row;
23448           goto label__outer__continue;
23449         }
23450       }
23451       v_p1_temp = ((uint32_t)(self->private_impl.f_width - self->private_impl.f_dst_x));
23452       v_p1 = wuffs_base__u32__min(v_p1_temp, 256);
23453       v_p0 = 0;
23454       while (v_p0 < v_p1) {
23455         if (self->private_impl.f_bits_per_pixel == 16) {
23456           if (((uint64_t)(io2_a_src - iop_a_src)) < 2) {
23457             goto label__0__break;
23458           }
23459           v_c32 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
23460           iop_a_src += 2;
23461         } else {
23462           if (((uint64_t)(io2_a_src - iop_a_src)) < 4) {
23463             goto label__0__break;
23464           }
23465           v_c32 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
23466           iop_a_src += 4;
23467         }
23468         v_channel = 0;
23469         while (v_channel < 4) {
23470           if (self->private_impl.f_channel_num_bits[v_channel] == 0) {
23471             self->private_data.f_scratch[((8 * v_p0) + (2 * v_channel) + 0)] = 255;
23472             self->private_data.f_scratch[((8 * v_p0) + (2 * v_channel) + 1)] = 255;
23473           } else {
23474             v_c = ((v_c32 & self->private_impl.f_channel_masks[v_channel]) >> self->private_impl.f_channel_shifts[v_channel]);
23475             v_num_bits = ((uint32_t)(self->private_impl.f_channel_num_bits[v_channel]));
23476             while (v_num_bits < 16) {
23477               v_c |= ((uint32_t)(v_c << v_num_bits));
23478               v_num_bits *= 2;
23479             }
23480             v_c >>= (v_num_bits - 16);
23481             self->private_data.f_scratch[((8 * v_p0) + (2 * v_channel) + 0)] = ((uint8_t)((255 & (v_c >> 0))));
23482             self->private_data.f_scratch[((8 * v_p0) + (2 * v_channel) + 1)] = ((uint8_t)((255 & (v_c >> 8))));
23483           }
23484           v_channel += 1;
23485         }
23486         v_p0 += 1;
23487       }
23488       label__0__break:;
23489       v_dst = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
23490       if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) {
23491         v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row);
23492       }
23493       v_i = (((uint64_t)(self->private_impl.f_dst_x)) * v_dst_bytes_per_pixel);
23494       if (v_i >= ((uint64_t)(v_dst.len))) {
23495         goto label__inner__continue;
23496       }
23497       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__slice_u8__subslice_j(wuffs_base__make_slice_u8(self->private_data.f_scratch, 2048), (8 * v_p0)));
23498       if (v_n == 0) {
23499         status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
23500         goto ok;
23501       }
23502       wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)((v_n & 4294967295))));
23503     }
23504   }
23505   label__outer__break:;
23506   status = wuffs_base__make_status(NULL);
23507   goto ok;
23508 
23509   ok:
23510   goto exit;
23511   exit:
23512   if (a_src) {
23513     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23514   }
23515 
23516   return status;
23517 }
23518 
23519 // -------- func bmp.decoder.swizzle_low_bit_depth
23520 
23521 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)23522 wuffs_bmp__decoder__swizzle_low_bit_depth(
23523     wuffs_bmp__decoder* self,
23524     wuffs_base__pixel_buffer* a_dst,
23525     wuffs_base__io_buffer* a_src) {
23526   wuffs_base__status status = wuffs_base__make_status(NULL);
23527 
23528   wuffs_base__pixel_format v_dst_pixfmt = {0};
23529   uint32_t v_dst_bits_per_pixel = 0;
23530   uint64_t v_dst_bytes_per_pixel = 0;
23531   uint64_t v_dst_bytes_per_row = 0;
23532   wuffs_base__slice_u8 v_dst_palette = {0};
23533   wuffs_base__table_u8 v_tab = {0};
23534   wuffs_base__slice_u8 v_dst = {0};
23535   uint64_t v_i = 0;
23536   uint64_t v_n = 0;
23537   uint32_t v_p0 = 0;
23538   uint32_t v_chunk_bits = 0;
23539   uint32_t v_chunk_count = 0;
23540 
23541   const uint8_t* iop_a_src = NULL;
23542   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23543   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23544   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23545   if (a_src) {
23546     io0_a_src = a_src->data.ptr;
23547     io1_a_src = io0_a_src + a_src->meta.ri;
23548     iop_a_src = io1_a_src;
23549     io2_a_src = io0_a_src + a_src->meta.wi;
23550   }
23551 
23552   v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
23553   v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
23554   if ((v_dst_bits_per_pixel & 7) != 0) {
23555     status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
23556     goto exit;
23557   }
23558   v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8)));
23559   v_dst_bytes_per_row = (((uint64_t)(self->private_impl.f_width)) * v_dst_bytes_per_pixel);
23560   v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8((self->private_data.f_scratch) + 1024, 1024));
23561   v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0);
23562   label__loop__continue:;
23563   while (true) {
23564     if (self->private_impl.f_dst_x == self->private_impl.f_width) {
23565       self->private_impl.f_dst_x = 0;
23566       self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc;
23567       if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
23568         goto label__loop__break;
23569       }
23570     }
23571     v_dst = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
23572     if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) {
23573       v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row);
23574     }
23575     v_i = (((uint64_t)(self->private_impl.f_dst_x)) * v_dst_bytes_per_pixel);
23576     if (v_i >= ((uint64_t)(v_dst.len))) {
23577       goto label__loop__continue;
23578     }
23579     v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_i);
23580     v_p0 = 0;
23581     if (self->private_impl.f_bits_per_pixel == 1) {
23582       v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 31) / 32);
23583       v_chunk_count = wuffs_base__u32__min(v_chunk_count, 16);
23584       while ((v_chunk_count > 0) && (((uint64_t)(io2_a_src - iop_a_src)) >= 4)) {
23585         v_chunk_bits = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
23586         iop_a_src += 4;
23587         self->private_data.f_scratch[(v_p0 + 0)] = ((uint8_t)((1 & (v_chunk_bits >> 31))));
23588         self->private_data.f_scratch[(v_p0 + 1)] = ((uint8_t)((1 & (v_chunk_bits >> 30))));
23589         self->private_data.f_scratch[(v_p0 + 2)] = ((uint8_t)((1 & (v_chunk_bits >> 29))));
23590         self->private_data.f_scratch[(v_p0 + 3)] = ((uint8_t)((1 & (v_chunk_bits >> 28))));
23591         self->private_data.f_scratch[(v_p0 + 4)] = ((uint8_t)((1 & (v_chunk_bits >> 27))));
23592         self->private_data.f_scratch[(v_p0 + 5)] = ((uint8_t)((1 & (v_chunk_bits >> 26))));
23593         self->private_data.f_scratch[(v_p0 + 6)] = ((uint8_t)((1 & (v_chunk_bits >> 25))));
23594         self->private_data.f_scratch[(v_p0 + 7)] = ((uint8_t)((1 & (v_chunk_bits >> 24))));
23595         self->private_data.f_scratch[(v_p0 + 8)] = ((uint8_t)((1 & (v_chunk_bits >> 23))));
23596         self->private_data.f_scratch[(v_p0 + 9)] = ((uint8_t)((1 & (v_chunk_bits >> 22))));
23597         self->private_data.f_scratch[(v_p0 + 10)] = ((uint8_t)((1 & (v_chunk_bits >> 21))));
23598         self->private_data.f_scratch[(v_p0 + 11)] = ((uint8_t)((1 & (v_chunk_bits >> 20))));
23599         self->private_data.f_scratch[(v_p0 + 12)] = ((uint8_t)((1 & (v_chunk_bits >> 19))));
23600         self->private_data.f_scratch[(v_p0 + 13)] = ((uint8_t)((1 & (v_chunk_bits >> 18))));
23601         self->private_data.f_scratch[(v_p0 + 14)] = ((uint8_t)((1 & (v_chunk_bits >> 17))));
23602         self->private_data.f_scratch[(v_p0 + 15)] = ((uint8_t)((1 & (v_chunk_bits >> 16))));
23603         self->private_data.f_scratch[(v_p0 + 16)] = ((uint8_t)((1 & (v_chunk_bits >> 15))));
23604         self->private_data.f_scratch[(v_p0 + 17)] = ((uint8_t)((1 & (v_chunk_bits >> 14))));
23605         self->private_data.f_scratch[(v_p0 + 18)] = ((uint8_t)((1 & (v_chunk_bits >> 13))));
23606         self->private_data.f_scratch[(v_p0 + 19)] = ((uint8_t)((1 & (v_chunk_bits >> 12))));
23607         self->private_data.f_scratch[(v_p0 + 20)] = ((uint8_t)((1 & (v_chunk_bits >> 11))));
23608         self->private_data.f_scratch[(v_p0 + 21)] = ((uint8_t)((1 & (v_chunk_bits >> 10))));
23609         self->private_data.f_scratch[(v_p0 + 22)] = ((uint8_t)((1 & (v_chunk_bits >> 9))));
23610         self->private_data.f_scratch[(v_p0 + 23)] = ((uint8_t)((1 & (v_chunk_bits >> 8))));
23611         self->private_data.f_scratch[(v_p0 + 24)] = ((uint8_t)((1 & (v_chunk_bits >> 7))));
23612         self->private_data.f_scratch[(v_p0 + 25)] = ((uint8_t)((1 & (v_chunk_bits >> 6))));
23613         self->private_data.f_scratch[(v_p0 + 26)] = ((uint8_t)((1 & (v_chunk_bits >> 5))));
23614         self->private_data.f_scratch[(v_p0 + 27)] = ((uint8_t)((1 & (v_chunk_bits >> 4))));
23615         self->private_data.f_scratch[(v_p0 + 28)] = ((uint8_t)((1 & (v_chunk_bits >> 3))));
23616         self->private_data.f_scratch[(v_p0 + 29)] = ((uint8_t)((1 & (v_chunk_bits >> 2))));
23617         self->private_data.f_scratch[(v_p0 + 30)] = ((uint8_t)((1 & (v_chunk_bits >> 1))));
23618         self->private_data.f_scratch[(v_p0 + 31)] = ((uint8_t)((1 & (v_chunk_bits >> 0))));
23619         v_p0 = ((v_p0 & 511) + 32);
23620         v_chunk_count -= 1;
23621       }
23622     } else if (self->private_impl.f_bits_per_pixel == 2) {
23623       v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 15) / 16);
23624       v_chunk_count = wuffs_base__u32__min(v_chunk_count, 32);
23625       while ((v_chunk_count > 0) && (((uint64_t)(io2_a_src - iop_a_src)) >= 4)) {
23626         v_chunk_bits = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
23627         iop_a_src += 4;
23628         self->private_data.f_scratch[(v_p0 + 0)] = ((uint8_t)((3 & (v_chunk_bits >> 30))));
23629         self->private_data.f_scratch[(v_p0 + 1)] = ((uint8_t)((3 & (v_chunk_bits >> 28))));
23630         self->private_data.f_scratch[(v_p0 + 2)] = ((uint8_t)((3 & (v_chunk_bits >> 26))));
23631         self->private_data.f_scratch[(v_p0 + 3)] = ((uint8_t)((3 & (v_chunk_bits >> 24))));
23632         self->private_data.f_scratch[(v_p0 + 4)] = ((uint8_t)((3 & (v_chunk_bits >> 22))));
23633         self->private_data.f_scratch[(v_p0 + 5)] = ((uint8_t)((3 & (v_chunk_bits >> 20))));
23634         self->private_data.f_scratch[(v_p0 + 6)] = ((uint8_t)((3 & (v_chunk_bits >> 18))));
23635         self->private_data.f_scratch[(v_p0 + 7)] = ((uint8_t)((3 & (v_chunk_bits >> 16))));
23636         self->private_data.f_scratch[(v_p0 + 8)] = ((uint8_t)((3 & (v_chunk_bits >> 14))));
23637         self->private_data.f_scratch[(v_p0 + 9)] = ((uint8_t)((3 & (v_chunk_bits >> 12))));
23638         self->private_data.f_scratch[(v_p0 + 10)] = ((uint8_t)((3 & (v_chunk_bits >> 10))));
23639         self->private_data.f_scratch[(v_p0 + 11)] = ((uint8_t)((3 & (v_chunk_bits >> 8))));
23640         self->private_data.f_scratch[(v_p0 + 12)] = ((uint8_t)((3 & (v_chunk_bits >> 6))));
23641         self->private_data.f_scratch[(v_p0 + 13)] = ((uint8_t)((3 & (v_chunk_bits >> 4))));
23642         self->private_data.f_scratch[(v_p0 + 14)] = ((uint8_t)((3 & (v_chunk_bits >> 2))));
23643         self->private_data.f_scratch[(v_p0 + 15)] = ((uint8_t)((3 & (v_chunk_bits >> 0))));
23644         v_p0 = ((v_p0 & 511) + 16);
23645         v_chunk_count -= 1;
23646       }
23647     } else if (self->private_impl.f_bits_per_pixel == 4) {
23648       v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 7) / 8);
23649       v_chunk_count = wuffs_base__u32__min(v_chunk_count, 64);
23650       while ((v_chunk_count > 0) && (((uint64_t)(io2_a_src - iop_a_src)) >= 4)) {
23651         v_chunk_bits = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
23652         iop_a_src += 4;
23653         self->private_data.f_scratch[(v_p0 + 0)] = ((uint8_t)((15 & (v_chunk_bits >> 28))));
23654         self->private_data.f_scratch[(v_p0 + 1)] = ((uint8_t)((15 & (v_chunk_bits >> 24))));
23655         self->private_data.f_scratch[(v_p0 + 2)] = ((uint8_t)((15 & (v_chunk_bits >> 20))));
23656         self->private_data.f_scratch[(v_p0 + 3)] = ((uint8_t)((15 & (v_chunk_bits >> 16))));
23657         self->private_data.f_scratch[(v_p0 + 4)] = ((uint8_t)((15 & (v_chunk_bits >> 12))));
23658         self->private_data.f_scratch[(v_p0 + 5)] = ((uint8_t)((15 & (v_chunk_bits >> 8))));
23659         self->private_data.f_scratch[(v_p0 + 6)] = ((uint8_t)((15 & (v_chunk_bits >> 4))));
23660         self->private_data.f_scratch[(v_p0 + 7)] = ((uint8_t)((15 & (v_chunk_bits >> 0))));
23661         v_p0 = ((v_p0 & 511) + 8);
23662         v_chunk_count -= 1;
23663       }
23664     }
23665     v_p0 = wuffs_base__u32__min(v_p0, wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x));
23666     v_n = wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, wuffs_base__slice_u8__subslice_j(wuffs_base__make_slice_u8(self->private_data.f_scratch, 2048), v_p0));
23667     if (v_n == 0) {
23668       status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
23669       goto ok;
23670     }
23671     wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)((v_n & 4294967295))));
23672   }
23673   label__loop__break:;
23674   status = wuffs_base__make_status(NULL);
23675   goto ok;
23676 
23677   ok:
23678   goto exit;
23679   exit:
23680   if (a_src) {
23681     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23682   }
23683 
23684   return status;
23685 }
23686 
23687 // -------- func bmp.decoder.frame_dirty_rect
23688 
23689 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
wuffs_bmp__decoder__frame_dirty_rect(const wuffs_bmp__decoder * self)23690 wuffs_bmp__decoder__frame_dirty_rect(
23691     const wuffs_bmp__decoder* self) {
23692   if (!self) {
23693     return wuffs_base__utility__empty_rect_ie_u32();
23694   }
23695   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
23696       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
23697     return wuffs_base__utility__empty_rect_ie_u32();
23698   }
23699 
23700   return wuffs_base__utility__make_rect_ie_u32(
23701       0,
23702       0,
23703       self->private_impl.f_width,
23704       self->private_impl.f_height);
23705 }
23706 
23707 // -------- func bmp.decoder.num_animation_loops
23708 
23709 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_bmp__decoder__num_animation_loops(const wuffs_bmp__decoder * self)23710 wuffs_bmp__decoder__num_animation_loops(
23711     const wuffs_bmp__decoder* self) {
23712   if (!self) {
23713     return 0;
23714   }
23715   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
23716       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
23717     return 0;
23718   }
23719 
23720   return 0;
23721 }
23722 
23723 // -------- func bmp.decoder.num_decoded_frame_configs
23724 
23725 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_bmp__decoder__num_decoded_frame_configs(const wuffs_bmp__decoder * self)23726 wuffs_bmp__decoder__num_decoded_frame_configs(
23727     const wuffs_bmp__decoder* self) {
23728   if (!self) {
23729     return 0;
23730   }
23731   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
23732       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
23733     return 0;
23734   }
23735 
23736   if (self->private_impl.f_call_sequence > 3) {
23737     return 1;
23738   }
23739   return 0;
23740 }
23741 
23742 // -------- func bmp.decoder.num_decoded_frames
23743 
23744 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_bmp__decoder__num_decoded_frames(const wuffs_bmp__decoder * self)23745 wuffs_bmp__decoder__num_decoded_frames(
23746     const wuffs_bmp__decoder* self) {
23747   if (!self) {
23748     return 0;
23749   }
23750   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
23751       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
23752     return 0;
23753   }
23754 
23755   if (self->private_impl.f_call_sequence > 4) {
23756     return 1;
23757   }
23758   return 0;
23759 }
23760 
23761 // -------- func bmp.decoder.restart_frame
23762 
23763 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)23764 wuffs_bmp__decoder__restart_frame(
23765     wuffs_bmp__decoder* self,
23766     uint64_t a_index,
23767     uint64_t a_io_position) {
23768   if (!self) {
23769     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
23770   }
23771   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
23772     return wuffs_base__make_status(
23773         (self->private_impl.magic == WUFFS_BASE__DISABLED)
23774         ? wuffs_base__error__disabled_by_previous_error
23775         : wuffs_base__error__initialize_not_called);
23776   }
23777 
23778   if (self->private_impl.f_call_sequence < 3) {
23779     return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
23780   }
23781   if (a_index != 0) {
23782     return wuffs_base__make_status(wuffs_base__error__bad_argument);
23783   }
23784   self->private_impl.f_call_sequence = 3;
23785   self->private_impl.f_frame_config_io_position = a_io_position;
23786   return wuffs_base__make_status(NULL);
23787 }
23788 
23789 // -------- func bmp.decoder.set_report_metadata
23790 
23791 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)23792 wuffs_bmp__decoder__set_report_metadata(
23793     wuffs_bmp__decoder* self,
23794     uint32_t a_fourcc,
23795     bool a_report) {
23796   return wuffs_base__make_empty_struct();
23797 }
23798 
23799 // -------- func bmp.decoder.tell_me_more
23800 
23801 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)23802 wuffs_bmp__decoder__tell_me_more(
23803     wuffs_bmp__decoder* self,
23804     wuffs_base__io_buffer* a_dst,
23805     wuffs_base__more_information* a_minfo,
23806     wuffs_base__io_buffer* a_src) {
23807   if (!self) {
23808     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
23809   }
23810   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
23811     return wuffs_base__make_status(
23812         (self->private_impl.magic == WUFFS_BASE__DISABLED)
23813         ? wuffs_base__error__disabled_by_previous_error
23814         : wuffs_base__error__initialize_not_called);
23815   }
23816   if (!a_dst || !a_src) {
23817     self->private_impl.magic = WUFFS_BASE__DISABLED;
23818     return wuffs_base__make_status(wuffs_base__error__bad_argument);
23819   }
23820   if ((self->private_impl.active_coroutine != 0) &&
23821       (self->private_impl.active_coroutine != 4)) {
23822     self->private_impl.magic = WUFFS_BASE__DISABLED;
23823     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
23824   }
23825   self->private_impl.active_coroutine = 0;
23826   wuffs_base__status status = wuffs_base__make_status(NULL);
23827 
23828   if (self->private_impl.f_io_redirect_fourcc <= 1) {
23829     status = wuffs_base__make_status(wuffs_base__error__no_more_information);
23830     goto exit;
23831   }
23832   if (a_minfo != NULL) {
23833     wuffs_base__more_information__set(a_minfo,
23834         1,
23835         self->private_impl.f_io_redirect_fourcc,
23836         0,
23837         self->private_impl.f_io_redirect_pos,
23838         18446744073709551615u);
23839   }
23840   self->private_impl.f_io_redirect_fourcc = 1;
23841 
23842   goto ok;
23843   ok:
23844   goto exit;
23845   exit:
23846   if (wuffs_base__status__is_error(&status)) {
23847     self->private_impl.magic = WUFFS_BASE__DISABLED;
23848   }
23849   return status;
23850 }
23851 
23852 // -------- func bmp.decoder.workbuf_len
23853 
23854 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_bmp__decoder__workbuf_len(const wuffs_bmp__decoder * self)23855 wuffs_bmp__decoder__workbuf_len(
23856     const wuffs_bmp__decoder* self) {
23857   if (!self) {
23858     return wuffs_base__utility__empty_range_ii_u64();
23859   }
23860   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
23861       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
23862     return wuffs_base__utility__empty_range_ii_u64();
23863   }
23864 
23865   return wuffs_base__utility__make_range_ii_u64(0, 0);
23866 }
23867 
23868 // -------- func bmp.decoder.read_palette
23869 
23870 static wuffs_base__status
wuffs_bmp__decoder__read_palette(wuffs_bmp__decoder * self,wuffs_base__io_buffer * a_src)23871 wuffs_bmp__decoder__read_palette(
23872     wuffs_bmp__decoder* self,
23873     wuffs_base__io_buffer* a_src) {
23874   wuffs_base__status status = wuffs_base__make_status(NULL);
23875 
23876   uint32_t v_i = 0;
23877   uint32_t v_argb = 0;
23878 
23879   const uint8_t* iop_a_src = NULL;
23880   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23881   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23882   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23883   if (a_src) {
23884     io0_a_src = a_src->data.ptr;
23885     io1_a_src = io0_a_src + a_src->meta.ri;
23886     iop_a_src = io1_a_src;
23887     io2_a_src = io0_a_src + a_src->meta.wi;
23888   }
23889 
23890   uint32_t coro_susp_point = self->private_impl.p_read_palette[0];
23891   if (coro_susp_point) {
23892     v_i = self->private_data.s_read_palette[0].v_i;
23893   }
23894   switch (coro_susp_point) {
23895     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
23896 
23897     if (self->private_impl.f_bitmap_info_len == 12) {
23898       while ((v_i < 256) && (self->private_impl.f_padding >= 3)) {
23899         self->private_impl.f_padding -= 3;
23900         {
23901           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
23902           uint32_t t_0;
23903           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) {
23904             t_0 = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src)));
23905             iop_a_src += 3;
23906           } else {
23907             self->private_data.s_read_palette[0].scratch = 0;
23908             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
23909             while (true) {
23910               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
23911                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
23912                 goto suspend;
23913               }
23914               uint64_t* scratch = &self->private_data.s_read_palette[0].scratch;
23915               uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
23916               *scratch <<= 8;
23917               *scratch >>= 8;
23918               *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
23919               if (num_bits_0 == 16) {
23920                 t_0 = ((uint32_t)(*scratch));
23921                 break;
23922               }
23923               num_bits_0 += 8;
23924               *scratch |= ((uint64_t)(num_bits_0)) << 56;
23925             }
23926           }
23927           v_argb = t_0;
23928         }
23929         v_argb |= 4278190080;
23930         self->private_data.f_src_palette[((4 * v_i) + 0)] = ((uint8_t)(((v_argb >> 0) & 255)));
23931         self->private_data.f_src_palette[((4 * v_i) + 1)] = ((uint8_t)(((v_argb >> 8) & 255)));
23932         self->private_data.f_src_palette[((4 * v_i) + 2)] = ((uint8_t)(((v_argb >> 16) & 255)));
23933         self->private_data.f_src_palette[((4 * v_i) + 3)] = ((uint8_t)(((v_argb >> 24) & 255)));
23934         v_i += 1;
23935       }
23936     } else {
23937       while ((v_i < 256) && (self->private_impl.f_padding >= 4)) {
23938         self->private_impl.f_padding -= 4;
23939         {
23940           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
23941           uint32_t t_1;
23942           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
23943             t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
23944             iop_a_src += 4;
23945           } else {
23946             self->private_data.s_read_palette[0].scratch = 0;
23947             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
23948             while (true) {
23949               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
23950                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
23951                 goto suspend;
23952               }
23953               uint64_t* scratch = &self->private_data.s_read_palette[0].scratch;
23954               uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
23955               *scratch <<= 8;
23956               *scratch >>= 8;
23957               *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
23958               if (num_bits_1 == 24) {
23959                 t_1 = ((uint32_t)(*scratch));
23960                 break;
23961               }
23962               num_bits_1 += 8;
23963               *scratch |= ((uint64_t)(num_bits_1)) << 56;
23964             }
23965           }
23966           v_argb = t_1;
23967         }
23968         v_argb |= 4278190080;
23969         self->private_data.f_src_palette[((4 * v_i) + 0)] = ((uint8_t)(((v_argb >> 0) & 255)));
23970         self->private_data.f_src_palette[((4 * v_i) + 1)] = ((uint8_t)(((v_argb >> 8) & 255)));
23971         self->private_data.f_src_palette[((4 * v_i) + 2)] = ((uint8_t)(((v_argb >> 16) & 255)));
23972         self->private_data.f_src_palette[((4 * v_i) + 3)] = ((uint8_t)(((v_argb >> 24) & 255)));
23973         v_i += 1;
23974       }
23975     }
23976     while (v_i < 256) {
23977       self->private_data.f_src_palette[((4 * v_i) + 0)] = 0;
23978       self->private_data.f_src_palette[((4 * v_i) + 1)] = 0;
23979       self->private_data.f_src_palette[((4 * v_i) + 2)] = 0;
23980       self->private_data.f_src_palette[((4 * v_i) + 3)] = 255;
23981       v_i += 1;
23982     }
23983 
23984     goto ok;
23985     ok:
23986     self->private_impl.p_read_palette[0] = 0;
23987     goto exit;
23988   }
23989 
23990   goto suspend;
23991   suspend:
23992   self->private_impl.p_read_palette[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
23993   self->private_data.s_read_palette[0].v_i = v_i;
23994 
23995   goto exit;
23996   exit:
23997   if (a_src) {
23998     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23999   }
24000 
24001   return status;
24002 }
24003 
24004 // -------- func bmp.decoder.process_masks
24005 
24006 static wuffs_base__status
wuffs_bmp__decoder__process_masks(wuffs_bmp__decoder * self)24007 wuffs_bmp__decoder__process_masks(
24008     wuffs_bmp__decoder* self) {
24009   wuffs_base__status status = wuffs_base__make_status(NULL);
24010 
24011   uint32_t v_i = 0;
24012   uint32_t v_mask = 0;
24013   uint32_t v_n = 0;
24014 
24015   while (v_i < 4) {
24016     v_mask = self->private_impl.f_channel_masks[v_i];
24017     if (v_mask != 0) {
24018       v_n = 0;
24019       while ((v_mask & 1) == 0) {
24020         v_n += 1;
24021         v_mask >>= 1;
24022       }
24023       self->private_impl.f_channel_shifts[v_i] = ((uint8_t)((v_n & 31)));
24024       v_n = 0;
24025       while ((v_mask & 1) == 1) {
24026         v_n += 1;
24027         v_mask >>= 1;
24028       }
24029       if ((v_mask != 0) || (v_n > 32)) {
24030         status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
24031         goto exit;
24032       }
24033       self->private_impl.f_channel_num_bits[v_i] = ((uint8_t)(v_n));
24034     } else if (v_i != 3) {
24035       status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
24036       goto exit;
24037     }
24038     v_i += 1;
24039   }
24040 
24041   goto ok;
24042   ok:
24043   goto exit;
24044   exit:
24045   return status;
24046 }
24047 
24048 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BMP)
24049 
24050 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CBOR)
24051 
24052 // ---------------- Status Codes Implementations
24053 
24054 const char wuffs_cbor__error__bad_input[] = "#cbor: bad input";
24055 const char wuffs_cbor__error__unsupported_recursion_depth[] = "#cbor: unsupported recursion depth";
24056 const char wuffs_cbor__error__internal_error_inconsistent_i_o[] = "#cbor: internal error: inconsistent I/O";
24057 const char wuffs_cbor__error__internal_error_inconsistent_token_length[] = "#cbor: internal error: inconsistent token length";
24058 
24059 // ---------------- Private Consts
24060 
24061 static const uint32_t
24062 WUFFS_CBOR__LITERALS[4] WUFFS_BASE__POTENTIALLY_UNUSED = {
24063   8388612, 8388616, 8388610, 8388609,
24064 };
24065 
24066 static const uint8_t
24067 WUFFS_CBOR__TOKEN_LENGTHS[32] WUFFS_BASE__POTENTIALLY_UNUSED = {
24068   1, 1, 1, 1, 1, 1, 1, 1,
24069   1, 1, 1, 1, 1, 1, 1, 1,
24070   1, 1, 1, 1, 1, 1, 1, 1,
24071   2, 3, 5, 9, 0, 0, 0, 1,
24072 };
24073 
24074 // ---------------- Private Initializer Prototypes
24075 
24076 // ---------------- Private Function Prototypes
24077 
24078 // ---------------- VTables
24079 
24080 const wuffs_base__token_decoder__func_ptrs
24081 wuffs_cbor__decoder__func_ptrs_for__wuffs_base__token_decoder = {
24082   (wuffs_base__status(*)(void*,
24083       wuffs_base__token_buffer*,
24084       wuffs_base__io_buffer*,
24085       wuffs_base__slice_u8))(&wuffs_cbor__decoder__decode_tokens),
24086   (wuffs_base__empty_struct(*)(void*,
24087       uint32_t,
24088       bool))(&wuffs_cbor__decoder__set_quirk_enabled),
24089   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_cbor__decoder__workbuf_len),
24090 };
24091 
24092 // ---------------- Initializer Implementations
24093 
24094 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)24095 wuffs_cbor__decoder__initialize(
24096     wuffs_cbor__decoder* self,
24097     size_t sizeof_star_self,
24098     uint64_t wuffs_version,
24099     uint32_t options){
24100   if (!self) {
24101     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
24102   }
24103   if (sizeof(*self) != sizeof_star_self) {
24104     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
24105   }
24106   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
24107       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
24108     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
24109   }
24110 
24111   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
24112     // The whole point of this if-check is to detect an uninitialized *self.
24113     // We disable the warning on GCC. Clang-5.0 does not have this warning.
24114 #if !defined(__clang__) && defined(__GNUC__)
24115 #pragma GCC diagnostic push
24116 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
24117 #endif
24118     if (self->private_impl.magic != 0) {
24119       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
24120     }
24121 #if !defined(__clang__) && defined(__GNUC__)
24122 #pragma GCC diagnostic pop
24123 #endif
24124   } else {
24125     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
24126       memset(self, 0, sizeof(*self));
24127       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
24128     } else {
24129       memset(&(self->private_impl), 0, sizeof(self->private_impl));
24130     }
24131   }
24132 
24133   self->private_impl.magic = WUFFS_BASE__MAGIC;
24134   self->private_impl.vtable_for__wuffs_base__token_decoder.vtable_name =
24135       wuffs_base__token_decoder__vtable_name;
24136   self->private_impl.vtable_for__wuffs_base__token_decoder.function_pointers =
24137       (const void*)(&wuffs_cbor__decoder__func_ptrs_for__wuffs_base__token_decoder);
24138   return wuffs_base__make_status(NULL);
24139 }
24140 
24141 wuffs_cbor__decoder*
wuffs_cbor__decoder__alloc()24142 wuffs_cbor__decoder__alloc() {
24143   wuffs_cbor__decoder* x =
24144       (wuffs_cbor__decoder*)(calloc(sizeof(wuffs_cbor__decoder), 1));
24145   if (!x) {
24146     return NULL;
24147   }
24148   if (wuffs_cbor__decoder__initialize(
24149       x, sizeof(wuffs_cbor__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
24150     free(x);
24151     return NULL;
24152   }
24153   return x;
24154 }
24155 
24156 size_t
sizeof__wuffs_cbor__decoder()24157 sizeof__wuffs_cbor__decoder() {
24158   return sizeof(wuffs_cbor__decoder);
24159 }
24160 
24161 // ---------------- Function Implementations
24162 
24163 // -------- func cbor.decoder.set_quirk_enabled
24164 
24165 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_cbor__decoder__set_quirk_enabled(wuffs_cbor__decoder * self,uint32_t a_quirk,bool a_enabled)24166 wuffs_cbor__decoder__set_quirk_enabled(
24167     wuffs_cbor__decoder* self,
24168     uint32_t a_quirk,
24169     bool a_enabled) {
24170   return wuffs_base__make_empty_struct();
24171 }
24172 
24173 // -------- func cbor.decoder.workbuf_len
24174 
24175 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_cbor__decoder__workbuf_len(const wuffs_cbor__decoder * self)24176 wuffs_cbor__decoder__workbuf_len(
24177     const wuffs_cbor__decoder* self) {
24178   if (!self) {
24179     return wuffs_base__utility__empty_range_ii_u64();
24180   }
24181   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
24182       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
24183     return wuffs_base__utility__empty_range_ii_u64();
24184   }
24185 
24186   return wuffs_base__utility__empty_range_ii_u64();
24187 }
24188 
24189 // -------- func cbor.decoder.decode_tokens
24190 
24191 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)24192 wuffs_cbor__decoder__decode_tokens(
24193     wuffs_cbor__decoder* self,
24194     wuffs_base__token_buffer* a_dst,
24195     wuffs_base__io_buffer* a_src,
24196     wuffs_base__slice_u8 a_workbuf) {
24197   if (!self) {
24198     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
24199   }
24200   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
24201     return wuffs_base__make_status(
24202         (self->private_impl.magic == WUFFS_BASE__DISABLED)
24203         ? wuffs_base__error__disabled_by_previous_error
24204         : wuffs_base__error__initialize_not_called);
24205   }
24206   if (!a_dst || !a_src) {
24207     self->private_impl.magic = WUFFS_BASE__DISABLED;
24208     return wuffs_base__make_status(wuffs_base__error__bad_argument);
24209   }
24210   if ((self->private_impl.active_coroutine != 0) &&
24211       (self->private_impl.active_coroutine != 1)) {
24212     self->private_impl.magic = WUFFS_BASE__DISABLED;
24213     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
24214   }
24215   self->private_impl.active_coroutine = 0;
24216   wuffs_base__status status = wuffs_base__make_status(NULL);
24217 
24218   uint64_t v_string_length = 0;
24219   uint64_t v_n64 = 0;
24220   uint32_t v_depth = 0;
24221   uint32_t v_stack_byte = 0;
24222   uint32_t v_stack_bit = 0;
24223   uint32_t v_stack_val = 0;
24224   uint32_t v_token_length = 0;
24225   uint32_t v_vminor = 0;
24226   uint32_t v_vminor_alt = 0;
24227   uint32_t v_continued = 0;
24228   uint8_t v_c = 0;
24229   uint8_t v_c_major = 0;
24230   uint8_t v_c_minor = 0;
24231   bool v_tagged = false;
24232   uint8_t v_indefinite_string_major_type = 0;
24233 
24234   wuffs_base__token* iop_a_dst = NULL;
24235   wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24236   wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24237   wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24238   if (a_dst) {
24239     io0_a_dst = a_dst->data.ptr;
24240     io1_a_dst = io0_a_dst + a_dst->meta.wi;
24241     iop_a_dst = io1_a_dst;
24242     io2_a_dst = io0_a_dst + a_dst->data.len;
24243     if (a_dst->meta.closed) {
24244       io2_a_dst = iop_a_dst;
24245     }
24246   }
24247   const uint8_t* iop_a_src = NULL;
24248   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24249   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24250   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24251   if (a_src) {
24252     io0_a_src = a_src->data.ptr;
24253     io1_a_src = io0_a_src + a_src->meta.ri;
24254     iop_a_src = io1_a_src;
24255     io2_a_src = io0_a_src + a_src->meta.wi;
24256   }
24257 
24258   uint32_t coro_susp_point = self->private_impl.p_decode_tokens[0];
24259   if (coro_susp_point) {
24260     v_string_length = self->private_data.s_decode_tokens[0].v_string_length;
24261     v_depth = self->private_data.s_decode_tokens[0].v_depth;
24262     v_token_length = self->private_data.s_decode_tokens[0].v_token_length;
24263     v_tagged = self->private_data.s_decode_tokens[0].v_tagged;
24264     v_indefinite_string_major_type = self->private_data.s_decode_tokens[0].v_indefinite_string_major_type;
24265   }
24266   switch (coro_susp_point) {
24267     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
24268 
24269     if (self->private_impl.f_end_of_data) {
24270       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
24271       goto ok;
24272     }
24273     label__outer__continue:;
24274     while (true) {
24275       while (true) {
24276         while (true) {
24277           if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 1) {
24278             status = wuffs_base__make_status(wuffs_base__suspension__short_write);
24279             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
24280             goto label__outer__continue;
24281           }
24282           if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
24283             if (a_src && a_src->meta.closed) {
24284               status = wuffs_base__make_status(wuffs_cbor__error__bad_input);
24285               goto exit;
24286             }
24287             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
24288             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
24289             goto label__outer__continue;
24290           }
24291           v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
24292           if ((v_indefinite_string_major_type != 0) && (v_indefinite_string_major_type != (v_c >> 5))) {
24293             if (v_c != 255) {
24294               status = wuffs_base__make_status(wuffs_cbor__error__bad_input);
24295               goto exit;
24296             }
24297             v_vminor = 4194560;
24298             if (v_indefinite_string_major_type == 3) {
24299               v_vminor |= 19;
24300             }
24301             v_indefinite_string_major_type = 0;
24302             iop_a_src += 1;
24303             *iop_a_dst++ = wuffs_base__make_token(
24304                 (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24305                 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24306             goto label__goto_parsed_a_leaf_value__break;
24307           }
24308           iop_a_src += 1;
24309           v_c_major = ((uint8_t)((v_c >> 5)));
24310           v_c_minor = (v_c & 31);
24311           if (v_c_minor < 24) {
24312             v_string_length = ((uint64_t)(v_c_minor));
24313           } else {
24314             while (true) {
24315               if (v_c_minor == 24) {
24316                 if (((uint64_t)(io2_a_src - iop_a_src)) >= 1) {
24317                   v_string_length = ((uint64_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src)));
24318                   iop_a_src += 1;
24319                   goto label__goto_have_string_length__break;
24320                 }
24321               } else if (v_c_minor == 25) {
24322                 if (((uint64_t)(io2_a_src - iop_a_src)) >= 2) {
24323                   v_string_length = ((uint64_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
24324                   iop_a_src += 2;
24325                   goto label__goto_have_string_length__break;
24326                 }
24327               } else if (v_c_minor == 26) {
24328                 if (((uint64_t)(io2_a_src - iop_a_src)) >= 4) {
24329                   v_string_length = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
24330                   iop_a_src += 4;
24331                   goto label__goto_have_string_length__break;
24332                 }
24333               } else if (v_c_minor == 27) {
24334                 if (((uint64_t)(io2_a_src - iop_a_src)) >= 8) {
24335                   v_string_length = wuffs_base__peek_u64be__no_bounds_check(iop_a_src);
24336                   iop_a_src += 8;
24337                   goto label__goto_have_string_length__break;
24338                 }
24339               } else {
24340                 v_string_length = 0;
24341                 goto label__goto_have_string_length__break;
24342               }
24343               if (iop_a_src > io1_a_src) {
24344                 iop_a_src--;
24345                 if (a_src && a_src->meta.closed) {
24346                   status = wuffs_base__make_status(wuffs_cbor__error__bad_input);
24347                   goto exit;
24348                 }
24349                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
24350                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
24351                 v_c_major = 0;
24352                 v_c_minor = 0;
24353                 goto label__outer__continue;
24354               }
24355               status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_i_o);
24356               goto exit;
24357             }
24358             label__goto_have_string_length__break:;
24359           }
24360           if (v_c_major == 0) {
24361             if (v_c_minor < 26) {
24362               *iop_a_dst++ = wuffs_base__make_token(
24363                   (((uint64_t)((14680064 | ((uint32_t)((v_string_length & 65535)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24364                   (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24365               goto label__goto_parsed_a_leaf_value__break;
24366             } else if (v_c_minor < 28) {
24367               *iop_a_dst++ = wuffs_base__make_token(
24368                   (((uint64_t)((14680064 | ((uint32_t)((v_string_length >> 46)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24369                   (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
24370                   (((uint64_t)(0)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24371               *iop_a_dst++ = wuffs_base__make_token(
24372                   (~(v_string_length & 70368744177663) << WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT) |
24373                   (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24374               goto label__goto_parsed_a_leaf_value__break;
24375             }
24376           } else if (v_c_major == 1) {
24377             if (v_c_minor < 26) {
24378               *iop_a_dst++ = wuffs_base__make_token(
24379                   (((uint64_t)((12582912 | (2097151 - ((uint32_t)((v_string_length & 65535))))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24380                   (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24381               goto label__goto_parsed_a_leaf_value__break;
24382             } else if (v_c_minor < 28) {
24383               if (v_string_length < 9223372036854775808u) {
24384                 *iop_a_dst++ = wuffs_base__make_token(
24385                     (((uint64_t)((12582912 | (2097151 - ((uint32_t)((v_string_length >> 46))))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24386                     (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
24387                     (((uint64_t)(0)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24388                 *iop_a_dst++ = wuffs_base__make_token(
24389                     (~((18446744073709551615u - v_string_length) & 70368744177663) << WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT) |
24390                     (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24391               } else {
24392                 *iop_a_dst++ = wuffs_base__make_token(
24393                     (((uint64_t)(787997)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) |
24394                     (((uint64_t)(16777216)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24395                     (((uint64_t)(9)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24396               }
24397               goto label__goto_parsed_a_leaf_value__break;
24398             }
24399           } else if (v_c_major == 2) {
24400             if (v_c_minor < 28) {
24401               if (v_string_length == 0) {
24402                 *iop_a_dst++ = wuffs_base__make_token(
24403                     (((uint64_t)(4194560)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24404                     (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24405                 goto label__goto_parsed_a_leaf_value__break;
24406               }
24407               *iop_a_dst++ = wuffs_base__make_token(
24408                   (((uint64_t)(4194560)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24409                   (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
24410                   (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24411             } else if (v_c_minor == 31) {
24412               if (v_indefinite_string_major_type != 0) {
24413                 goto label__goto_fail__break;
24414               }
24415               v_indefinite_string_major_type = 2;
24416               *iop_a_dst++ = wuffs_base__make_token(
24417                   (((uint64_t)(4194560)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24418                   (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
24419                   (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24420               goto label__outer__continue;
24421             } else {
24422               goto label__goto_fail__break;
24423             }
24424             label__0__continue:;
24425             while (true) {
24426               if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
24427                 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
24428                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
24429                 goto label__0__continue;
24430               }
24431               v_n64 = wuffs_base__u64__min(v_string_length, ((uint64_t)(io2_a_src - iop_a_src)));
24432               v_token_length = ((uint32_t)((v_n64 & 65535)));
24433               if (v_n64 > 65535) {
24434                 v_token_length = 65535;
24435               } else if (v_token_length <= 0) {
24436                 if (a_src && a_src->meta.closed) {
24437                   status = wuffs_base__make_status(wuffs_cbor__error__bad_input);
24438                   goto exit;
24439                 }
24440                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
24441                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
24442                 goto label__0__continue;
24443               }
24444               if (((uint64_t)(io2_a_src - iop_a_src)) < ((uint64_t)(v_token_length))) {
24445                 status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_token_length);
24446                 goto exit;
24447               }
24448               v_string_length -= ((uint64_t)(v_token_length));
24449               v_continued = 0;
24450               if ((v_string_length > 0) || (v_indefinite_string_major_type > 0)) {
24451                 v_continued = 1;
24452               }
24453               iop_a_src += v_token_length;
24454               *iop_a_dst++ = wuffs_base__make_token(
24455                   (((uint64_t)(4194816)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24456                   (((uint64_t)(v_continued)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
24457                   (((uint64_t)(v_token_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24458               if (v_string_length > 0) {
24459                 goto label__0__continue;
24460               } else if (v_indefinite_string_major_type > 0) {
24461                 goto label__outer__continue;
24462               }
24463               goto label__goto_parsed_a_leaf_value__break;
24464             }
24465           } else if (v_c_major == 3) {
24466             if (v_c_minor < 28) {
24467               if (v_string_length == 0) {
24468                 *iop_a_dst++ = wuffs_base__make_token(
24469                     (((uint64_t)(4194579)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24470                     (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24471                 goto label__goto_parsed_a_leaf_value__break;
24472               }
24473               *iop_a_dst++ = wuffs_base__make_token(
24474                   (((uint64_t)(4194579)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24475                   (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
24476                   (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24477             } else if (v_c_minor == 31) {
24478               if (v_indefinite_string_major_type != 0) {
24479                 goto label__goto_fail__break;
24480               }
24481               v_indefinite_string_major_type = 3;
24482               *iop_a_dst++ = wuffs_base__make_token(
24483                   (((uint64_t)(4194579)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24484                   (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
24485                   (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24486               goto label__outer__continue;
24487             } else {
24488               goto label__goto_fail__break;
24489             }
24490             label__1__continue:;
24491             while (true) {
24492               if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
24493                 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
24494                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
24495                 goto label__1__continue;
24496               }
24497               v_n64 = wuffs_base__u64__min(v_string_length, 65535);
24498               v_n64 = ((uint64_t)(wuffs_base__utf_8__longest_valid_prefix(iop_a_src,
24499                   ((size_t)(wuffs_base__u64__min(((uint64_t)(io2_a_src - iop_a_src)), v_n64))))));
24500               v_token_length = ((uint32_t)((v_n64 & 65535)));
24501               if (v_token_length <= 0) {
24502                 if ((a_src && a_src->meta.closed) || (((uint64_t)(io2_a_src - iop_a_src)) >= 4)) {
24503                   status = wuffs_base__make_status(wuffs_cbor__error__bad_input);
24504                   goto exit;
24505                 }
24506                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
24507                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7);
24508                 goto label__1__continue;
24509               }
24510               if (((uint64_t)(io2_a_src - iop_a_src)) < ((uint64_t)(v_token_length))) {
24511                 status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_token_length);
24512                 goto exit;
24513               }
24514               v_string_length -= ((uint64_t)(v_token_length));
24515               v_continued = 0;
24516               if ((v_string_length > 0) || (v_indefinite_string_major_type > 0)) {
24517                 v_continued = 1;
24518               }
24519               iop_a_src += v_token_length;
24520               *iop_a_dst++ = wuffs_base__make_token(
24521                   (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24522                   (((uint64_t)(v_continued)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
24523                   (((uint64_t)(v_token_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24524               if (v_string_length > 0) {
24525                 goto label__1__continue;
24526               } else if (v_indefinite_string_major_type > 0) {
24527                 goto label__outer__continue;
24528               }
24529               goto label__goto_parsed_a_leaf_value__break;
24530             }
24531           } else if (v_c_major == 4) {
24532             if (WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor] == 0) {
24533               goto label__goto_fail__break;
24534             } else if (v_depth >= 1024) {
24535               v_token_length = ((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor]));
24536               while ((v_token_length > 0) && (iop_a_src > io1_a_src)) {
24537                 iop_a_src--;
24538                 v_token_length -= 1;
24539               }
24540               status = wuffs_base__make_status(wuffs_cbor__error__unsupported_recursion_depth);
24541               goto exit;
24542             }
24543             v_vminor = 2105361;
24544             v_vminor_alt = 2101282;
24545             if (v_depth > 0) {
24546               v_stack_byte = ((v_depth - 1) / 16);
24547               v_stack_bit = (((v_depth - 1) & 15) * 2);
24548               if (0 == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1)) << v_stack_bit))) {
24549                 v_vminor = 2105377;
24550                 v_vminor_alt = 2105378;
24551               } else {
24552                 v_vminor = 2105409;
24553                 v_vminor_alt = 2113570;
24554               }
24555             }
24556             *iop_a_dst++ = wuffs_base__make_token(
24557                 (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24558                 (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24559             if (v_c_minor == 0) {
24560               *iop_a_dst++ = wuffs_base__make_token(
24561                   (((uint64_t)(v_vminor_alt)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24562                   (((uint64_t)(0)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24563               goto label__goto_parsed_a_leaf_value__break;
24564             }
24565             v_stack_byte = (v_depth / 16);
24566             v_stack_bit = ((v_depth & 15) * 2);
24567             self->private_data.f_stack[v_stack_byte] &= (4294967295 ^ (((uint32_t)(3)) << v_stack_bit));
24568             self->private_data.f_container_num_remaining[v_depth] = v_string_length;
24569             v_depth += 1;
24570             v_tagged = false;
24571             goto label__outer__continue;
24572           } else if (v_c_major == 5) {
24573             if (WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor] == 0) {
24574               goto label__goto_fail__break;
24575             } else if (v_depth >= 1024) {
24576               v_token_length = ((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor]));
24577               while ((v_token_length > 0) && (iop_a_src > io1_a_src)) {
24578                 iop_a_src--;
24579                 v_token_length -= 1;
24580               }
24581               status = wuffs_base__make_status(wuffs_cbor__error__unsupported_recursion_depth);
24582               goto exit;
24583             }
24584             v_vminor = 2113553;
24585             v_vminor_alt = 2101314;
24586             if (v_depth > 0) {
24587               v_stack_byte = ((v_depth - 1) / 16);
24588               v_stack_bit = (((v_depth - 1) & 15) * 2);
24589               if (0 == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1)) << v_stack_bit))) {
24590                 v_vminor = 2113569;
24591                 v_vminor_alt = 2105410;
24592               } else {
24593                 v_vminor = 2113601;
24594                 v_vminor_alt = 2113602;
24595               }
24596             }
24597             *iop_a_dst++ = wuffs_base__make_token(
24598                 (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24599                 (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24600             if (v_c_minor == 0) {
24601               *iop_a_dst++ = wuffs_base__make_token(
24602                   (((uint64_t)(v_vminor_alt)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24603                   (((uint64_t)(0)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24604               goto label__goto_parsed_a_leaf_value__break;
24605             }
24606             v_stack_byte = (v_depth / 16);
24607             v_stack_bit = ((v_depth & 15) * 2);
24608             self->private_data.f_stack[v_stack_byte] |= (((uint32_t)(3)) << v_stack_bit);
24609             self->private_data.f_container_num_remaining[v_depth] = v_string_length;
24610             v_depth += 1;
24611             v_tagged = false;
24612             goto label__outer__continue;
24613           } else if (v_c_major == 6) {
24614             if (v_c_minor >= 28) {
24615               goto label__goto_fail__break;
24616             }
24617             if (v_string_length < 262144) {
24618               *iop_a_dst++ = wuffs_base__make_token(
24619                   (((uint64_t)(787997)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) |
24620                   (((uint64_t)((4194304 | ((uint32_t)(v_string_length))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24621                   (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24622             } else {
24623               *iop_a_dst++ = wuffs_base__make_token(
24624                   (((uint64_t)(787997)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) |
24625                   (((uint64_t)((4194304 | ((uint32_t)((v_string_length >> 46)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24626                   (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
24627                   (((uint64_t)(0)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24628               *iop_a_dst++ = wuffs_base__make_token(
24629                   (~(v_string_length & 70368744177663) << WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT) |
24630                   (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24631             }
24632             v_tagged = true;
24633             goto label__outer__continue;
24634           } else if (v_c_major == 7) {
24635             if (v_c_minor < 20) {
24636               *iop_a_dst++ = wuffs_base__make_token(
24637                   (((uint64_t)(787997)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) |
24638                   (((uint64_t)((8388608 | ((uint32_t)((v_string_length & 255)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24639                   (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24640               goto label__goto_parsed_a_leaf_value__break;
24641             } else if (v_c_minor < 24) {
24642               *iop_a_dst++ = wuffs_base__make_token(
24643                   (((uint64_t)(WUFFS_CBOR__LITERALS[(v_c_minor & 3)])) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24644                   (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24645               goto label__goto_parsed_a_leaf_value__break;
24646             } else if (v_c_minor == 24) {
24647               if (v_string_length < 24) {
24648                 if ( ! (iop_a_src > io1_a_src)) {
24649                   status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_i_o);
24650                   goto exit;
24651                 }
24652                 iop_a_src--;
24653                 goto label__goto_fail__break;
24654               }
24655               *iop_a_dst++ = wuffs_base__make_token(
24656                   (((uint64_t)(787997)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) |
24657                   (((uint64_t)((8388608 | ((uint32_t)((v_string_length & 255)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24658                   (((uint64_t)(2)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24659               goto label__goto_parsed_a_leaf_value__break;
24660             } else if (v_c_minor < 28) {
24661               *iop_a_dst++ = wuffs_base__make_token(
24662                   (((uint64_t)(10490113)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24663                   (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24664               goto label__goto_parsed_a_leaf_value__break;
24665             } else if (v_c_minor == 31) {
24666               if (v_tagged || (v_depth <= 0)) {
24667                 goto label__goto_fail__break;
24668               }
24669               v_depth -= 1;
24670               if (self->private_data.f_container_num_remaining[v_depth] != 0) {
24671                 goto label__goto_fail__break;
24672               }
24673               v_stack_byte = (v_depth / 16);
24674               v_stack_bit = ((v_depth & 15) * 2);
24675               v_stack_val = (3 & (self->private_data.f_stack[v_stack_byte] >> v_stack_bit));
24676               if (v_stack_val == 1) {
24677                 goto label__goto_fail__break;
24678               }
24679               if (v_stack_val != 3) {
24680                 v_vminor_alt = 2097186;
24681               } else {
24682                 v_vminor_alt = 2097218;
24683               }
24684               if (v_depth <= 0) {
24685                 v_vminor_alt |= 4096;
24686               } else {
24687                 v_stack_byte = ((v_depth - 1) / 16);
24688                 v_stack_bit = (((v_depth - 1) & 15) * 2);
24689                 if (0 == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1)) << v_stack_bit))) {
24690                   v_vminor_alt |= 8192;
24691                 } else {
24692                   v_vminor_alt |= 16384;
24693                 }
24694               }
24695               *iop_a_dst++ = wuffs_base__make_token(
24696                   (((uint64_t)(v_vminor_alt)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24697                   (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24698               goto label__goto_parsed_a_leaf_value__break;
24699             }
24700           }
24701           goto label__goto_fail__break;
24702         }
24703         label__goto_fail__break:;
24704         if (iop_a_src > io1_a_src) {
24705           iop_a_src--;
24706           status = wuffs_base__make_status(wuffs_cbor__error__bad_input);
24707           goto exit;
24708         }
24709         status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_i_o);
24710         goto exit;
24711       }
24712       label__goto_parsed_a_leaf_value__break:;
24713       v_tagged = false;
24714       while (v_depth > 0) {
24715         v_stack_byte = ((v_depth - 1) / 16);
24716         v_stack_bit = (((v_depth - 1) & 15) * 2);
24717         self->private_data.f_stack[v_stack_byte] ^= (((uint32_t)(1)) << (v_stack_bit + 1));
24718         if (1 == (3 & (self->private_data.f_stack[v_stack_byte] >> v_stack_bit))) {
24719           goto label__outer__continue;
24720         }
24721         if (self->private_data.f_container_num_remaining[(v_depth - 1)] <= 0) {
24722           goto label__outer__continue;
24723         }
24724         self->private_data.f_container_num_remaining[(v_depth - 1)] -= 1;
24725         if (self->private_data.f_container_num_remaining[(v_depth - 1)] > 0) {
24726           goto label__outer__continue;
24727         }
24728         label__2__continue:;
24729         while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
24730           status = wuffs_base__make_status(wuffs_base__suspension__short_write);
24731           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8);
24732           goto label__2__continue;
24733         }
24734         v_depth -= 1;
24735         v_stack_byte = (v_depth / 16);
24736         v_stack_bit = ((v_depth & 15) * 2);
24737         if (0 == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1)) << v_stack_bit))) {
24738           v_vminor_alt = 2097186;
24739         } else {
24740           v_vminor_alt = 2097218;
24741         }
24742         if (v_depth <= 0) {
24743           v_vminor_alt |= 4096;
24744         } else {
24745           v_stack_byte = ((v_depth - 1) / 16);
24746           v_stack_bit = (((v_depth - 1) & 15) * 2);
24747           if (0 == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1)) << v_stack_bit))) {
24748             v_vminor_alt |= 8192;
24749           } else {
24750             v_vminor_alt |= 16384;
24751           }
24752         }
24753         *iop_a_dst++ = wuffs_base__make_token(
24754             (((uint64_t)(v_vminor_alt)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24755             (((uint64_t)(0)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24756       }
24757       goto label__outer__break;
24758     }
24759     label__outer__break:;
24760     self->private_impl.f_end_of_data = true;
24761 
24762     ok:
24763     self->private_impl.p_decode_tokens[0] = 0;
24764     goto exit;
24765   }
24766 
24767   goto suspend;
24768   suspend:
24769   self->private_impl.p_decode_tokens[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
24770   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
24771   self->private_data.s_decode_tokens[0].v_string_length = v_string_length;
24772   self->private_data.s_decode_tokens[0].v_depth = v_depth;
24773   self->private_data.s_decode_tokens[0].v_token_length = v_token_length;
24774   self->private_data.s_decode_tokens[0].v_tagged = v_tagged;
24775   self->private_data.s_decode_tokens[0].v_indefinite_string_major_type = v_indefinite_string_major_type;
24776 
24777   goto exit;
24778   exit:
24779   if (a_dst) {
24780     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
24781   }
24782   if (a_src) {
24783     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
24784   }
24785 
24786   if (wuffs_base__status__is_error(&status)) {
24787     self->private_impl.magic = WUFFS_BASE__DISABLED;
24788   }
24789   return status;
24790 }
24791 
24792 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CBOR)
24793 
24794 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CRC32)
24795 
24796 // ---------------- Status Codes Implementations
24797 
24798 // ---------------- Private Consts
24799 
24800 static const uint32_t
24801 WUFFS_CRC32__IEEE_TABLE[16][256] WUFFS_BASE__POTENTIALLY_UNUSED = {
24802   {
24803     0, 1996959894, 3993919788, 2567524794, 124634137, 1886057615, 3915621685, 2657392035,
24804     249268274, 2044508324, 3772115230, 2547177864, 162941995, 2125561021, 3887607047, 2428444049,
24805     498536548, 1789927666, 4089016648, 2227061214, 450548861, 1843258603, 4107580753, 2211677639,
24806     325883990, 1684777152, 4251122042, 2321926636, 335633487, 1661365465, 4195302755, 2366115317,
24807     997073096, 1281953886, 3579855332, 2724688242, 1006888145, 1258607687, 3524101629, 2768942443,
24808     901097722, 1119000684, 3686517206, 2898065728, 853044451, 1172266101, 3705015759, 2882616665,
24809     651767980, 1373503546, 3369554304, 3218104598, 565507253, 1454621731, 3485111705, 3099436303,
24810     671266974, 1594198024, 3322730930, 2970347812, 795835527, 1483230225, 3244367275, 3060149565,
24811     1994146192, 31158534, 2563907772, 4023717930, 1907459465, 112637215, 2680153253, 3904427059,
24812     2013776290, 251722036, 2517215374, 3775830040, 2137656763, 141376813, 2439277719, 3865271297,
24813     1802195444, 476864866, 2238001368, 4066508878, 1812370925, 453092731, 2181625025, 4111451223,
24814     1706088902, 314042704, 2344532202, 4240017532, 1658658271, 366619977, 2362670323, 4224994405,
24815     1303535960, 984961486, 2747007092, 3569037538, 1256170817, 1037604311, 2765210733, 3554079995,
24816     1131014506, 879679996, 2909243462, 3663771856, 1141124467, 855842277, 2852801631, 3708648649,
24817     1342533948, 654459306, 3188396048, 3373015174, 1466479909, 544179635, 3110523913, 3462522015,
24818     1591671054, 702138776, 2966460450, 3352799412, 1504918807, 783551873, 3082640443, 3233442989,
24819     3988292384, 2596254646, 62317068, 1957810842, 3939845945, 2647816111, 81470997, 1943803523,
24820     3814918930, 2489596804, 225274430, 2053790376, 3826175755, 2466906013, 167816743, 2097651377,
24821     4027552580, 2265490386, 503444072, 1762050814, 4150417245, 2154129355, 426522225, 1852507879,
24822     4275313526, 2312317920, 282753626, 1742555852, 4189708143, 2394877945, 397917763, 1622183637,
24823     3604390888, 2714866558, 953729732, 1340076626, 3518719985, 2797360999, 1068828381, 1219638859,
24824     3624741850, 2936675148, 906185462, 1090812512, 3747672003, 2825379669, 829329135, 1181335161,
24825     3412177804, 3160834842, 628085408, 1382605366, 3423369109, 3138078467, 570562233, 1426400815,
24826     3317316542, 2998733608, 733239954, 1555261956, 3268935591, 3050360625, 752459403, 1541320221,
24827     2607071920, 3965973030, 1969922972, 40735498, 2617837225, 3943577151, 1913087877, 83908371,
24828     2512341634, 3803740692, 2075208622, 213261112, 2463272603, 3855990285, 2094854071, 198958881,
24829     2262029012, 4057260610, 1759359992, 534414190, 2176718541, 4139329115, 1873836001, 414664567,
24830     2282248934, 4279200368, 1711684554, 285281116, 2405801727, 4167216745, 1634467795, 376229701,
24831     2685067896, 3608007406, 1308918612, 956543938, 2808555105, 3495958263, 1231636301, 1047427035,
24832     2932959818, 3654703836, 1088359270, 936918000, 2847714899, 3736837829, 1202900863, 817233897,
24833     3183342108, 3401237130, 1404277552, 615818150, 3134207493, 3453421203, 1423857449, 601450431,
24834     3009837614, 3294710456, 1567103746, 711928724, 3020668471, 3272380065, 1510334235, 755167117,
24835   }, {
24836     0, 421212481, 842424962, 724390851, 1684849924, 2105013317, 1448781702, 1329698503,
24837     3369699848, 3519200073, 4210026634, 3824474571, 2897563404, 3048111693, 2659397006, 2274893007,
24838     1254232657, 1406739216, 2029285587, 1643069842, 783210325, 934667796, 479770071, 92505238,
24839     2182846553, 2600511768, 2955803355, 2838940570, 3866582365, 4285295644, 3561045983, 3445231262,
24840     2508465314, 2359236067, 2813478432, 3198777185, 4058571174, 3908292839, 3286139684, 3670389349,
24841     1566420650, 1145479147, 1869335592, 1987116393, 959540142, 539646703, 185010476, 303839341,
24842     3745920755, 3327985586, 3983561841, 4100678960, 3140154359, 2721170102, 2300350837, 2416418868,
24843     396344571, 243568058, 631889529, 1018359608, 1945336319, 1793607870, 1103436669, 1490954812,
24844     4034481925, 3915546180, 3259968903, 3679722694, 2484439553, 2366552896, 2787371139, 3208174018,
24845     950060301, 565965900, 177645455, 328046286, 1556873225, 1171730760, 1861902987, 2011255754,
24846     3132841300, 2745199637, 2290958294, 2442530455, 3738671184, 3352078609, 3974232786, 4126854035,
24847     1919080284, 1803150877, 1079293406, 1498383519, 370020952, 253043481, 607678682, 1025720731,
24848     1711106983, 2095471334, 1472923941, 1322268772, 26324643, 411738082, 866634785, 717028704,
24849     2904875439, 3024081134, 2668790573, 2248782444, 3376948395, 3495106026, 4219356713, 3798300520,
24850     792689142, 908347575, 487136116, 68299317, 1263779058, 1380486579, 2036719216, 1618931505,
24851     3890672638, 4278043327, 3587215740, 3435896893, 2206873338, 2593195963, 2981909624, 2829542713,
24852     998479947, 580430090, 162921161, 279890824, 1609522511, 1190423566, 1842954189, 1958874764,
24853     4082766403, 3930137346, 3245109441, 3631694208, 2536953671, 2385372678, 2768287173, 3155920004,
24854     1900120602, 1750776667, 1131931800, 1517083097, 355290910, 204897887, 656092572, 1040194781,
24855     3113746450, 2692952403, 2343461520, 2461357009, 3723805974, 3304059991, 4022511508, 4141455061,
24856     2919742697, 3072101800, 2620513899, 2234183466, 3396041197, 3547351212, 4166851439, 3779471918,
24857     1725839073, 2143618976, 1424512099, 1307796770, 45282277, 464110244, 813994343, 698327078,
24858     3838160568, 4259225593, 3606301754, 3488152955, 2158586812, 2578602749, 2996767038, 2877569151,
24859     740041904, 889656817, 506086962, 120682355, 1215357364, 1366020341, 2051441462, 1667084919,
24860     3422213966, 3538019855, 4190942668, 3772220557, 2945847882, 3062702859, 2644537544, 2226864521,
24861     52649286, 439905287, 823476164, 672009861, 1733269570, 2119477507, 1434057408, 1281543041,
24862     2167981343, 2552493150, 3004082077, 2853541596, 3847487515, 4233048410, 3613549209, 3464057816,
24863     1239502615, 1358593622, 2077699477, 1657543892, 764250643, 882293586, 532408465, 111204816,
24864     1585378284, 1197851309, 1816695150, 1968414767, 974272232, 587794345, 136598634, 289367339,
24865     2527558116, 2411481253, 2760973158, 3179948583, 4073438432, 3956313505, 3237863010, 3655790371,
24866     347922877, 229101820, 646611775, 1066513022, 1892689081, 1774917112, 1122387515, 1543337850,
24867     3697634229, 3313392372, 3998419255, 4148705398, 3087642289, 2702352368, 2319436851, 2468674930,
24868   }, {
24869     0, 29518391, 59036782, 38190681, 118073564, 114017003, 76381362, 89069189,
24870     236147128, 265370511, 228034006, 206958561, 152762724, 148411219, 178138378, 190596925,
24871     472294256, 501532999, 530741022, 509615401, 456068012, 451764635, 413917122, 426358261,
24872     305525448, 334993663, 296822438, 275991697, 356276756, 352202787, 381193850, 393929805,
24873     944588512, 965684439, 1003065998, 973863097, 1061482044, 1049003019, 1019230802, 1023561829,
24874     912136024, 933002607, 903529270, 874031361, 827834244, 815125939, 852716522, 856752605,
24875     611050896, 631869351, 669987326, 640506825, 593644876, 580921211, 551983394, 556069653,
24876     712553512, 733666847, 704405574, 675154545, 762387700, 749958851, 787859610, 792175277,
24877     1889177024, 1901651959, 1931368878, 1927033753, 2006131996, 1985040171, 1947726194, 1976933189,
24878     2122964088, 2135668303, 2098006038, 2093965857, 2038461604, 2017599123, 2047123658, 2076625661,
24879     1824272048, 1836991623, 1866005214, 1861914857, 1807058540, 1786244187, 1748062722, 1777547317,
24880     1655668488, 1668093247, 1630251878, 1625932113, 1705433044, 1684323811, 1713505210, 1742760333,
24881     1222101792, 1226154263, 1263738702, 1251046777, 1339974652, 1310460363, 1281013650, 1301863845,
24882     1187289752, 1191637167, 1161842422, 1149379777, 1103966788, 1074747507, 1112139306, 1133218845,
24883     1425107024, 1429406311, 1467333694, 1454888457, 1408811148, 1379576507, 1350309090, 1371438805,
24884     1524775400, 1528845279, 1499917702, 1487177649, 1575719220, 1546255107, 1584350554, 1605185389,
24885     3778354048, 3774312887, 3803303918, 3816007129, 3862737756, 3892238699, 3854067506, 3833203973,
24886     4012263992, 4007927823, 3970080342, 3982554209, 3895452388, 3924658387, 3953866378, 3932773565,
24887     4245928176, 4241609415, 4271336606, 4283762345, 4196012076, 4225268251, 4187931714, 4166823541,
24888     4076923208, 4072833919, 4035198246, 4047918865, 4094247316, 4123732899, 4153251322, 4132437965,
24889     3648544096, 3636082519, 3673983246, 3678331705, 3732010428, 3753090955, 3723829714, 3694611429,
24890     3614117080, 3601426159, 3572488374, 3576541825, 3496125444, 3516976691, 3555094634, 3525581405,
24891     3311336976, 3298595879, 3336186494, 3340255305, 3260503756, 3281337595, 3251864226, 3222399125,
24892     3410866088, 3398419871, 3368647622, 3372945905, 3427010420, 3448139075, 3485520666, 3456284973,
24893     2444203584, 2423127159, 2452308526, 2481530905, 2527477404, 2539934891, 2502093554, 2497740997,
24894     2679949304, 2659102159, 2620920726, 2650438049, 2562027300, 2574714131, 2603727690, 2599670141,
24895     2374579504, 2353749767, 2383274334, 2412743529, 2323684844, 2336421851, 2298759554, 2294686645,
24896     2207933576, 2186809023, 2149495014, 2178734801, 2224278612, 2236720739, 2266437690, 2262135309,
24897     2850214048, 2820717207, 2858812622, 2879680249, 2934667388, 2938704459, 2909776914, 2897069605,
24898     2817622296, 2788420399, 2759153014, 2780249921, 2700618180, 2704950259, 2742877610, 2730399645,
24899     3049550800, 3020298727, 3057690558, 3078802825, 2999835404, 3004150075, 2974355298, 2961925461,
24900     3151438440, 3121956959, 3092510214, 3113327665, 3168701108, 3172786307, 3210370778, 3197646061,
24901   }, {
24902     0, 3099354981, 2852767883, 313896942, 2405603159, 937357362, 627793884, 2648127673,
24903     3316918511, 2097696650, 1874714724, 3607201537, 1255587768, 4067088605, 3772741427, 1482887254,
24904     1343838111, 3903140090, 4195393300, 1118632049, 3749429448, 1741137837, 1970407491, 3452858150,
24905     2511175536, 756094997, 1067759611, 2266550430, 449832999, 2725482306, 2965774508, 142231497,
24906     2687676222, 412010587, 171665333, 2995192016, 793786473, 2548850444, 2237264098, 1038456711,
24907     1703315409, 3711623348, 3482275674, 1999841343, 3940814982, 1381529571, 1089329165, 4166106984,
24908     4029413537, 1217896388, 1512189994, 3802027855, 2135519222, 3354724499, 3577784189, 1845280792,
24909     899665998, 2367928107, 2677414085, 657096608, 3137160985, 37822588, 284462994, 2823350519,
24910     2601801789, 598228824, 824021174, 2309093331, 343330666, 2898962447, 3195996129, 113467524,
24911     1587572946, 3860600759, 4104763481, 1276501820, 3519211397, 1769898208, 2076913422, 3279374443,
24912     3406630818, 1941006535, 1627703081, 3652755532, 1148164341, 4241751952, 3999682686, 1457141531,
24913     247015245, 3053797416, 2763059142, 470583459, 2178658330, 963106687, 735213713, 2473467892,
24914     992409347, 2207944806, 2435792776, 697522413, 3024379988, 217581361, 508405983, 2800865210,
24915     4271038444, 1177467017, 1419450215, 3962007554, 1911572667, 3377213406, 3690561584, 1665525589,
24916     1799331996, 3548628985, 3241568279, 2039091058, 3831314379, 1558270126, 1314193216, 4142438437,
24917     2928380019, 372764438, 75645176, 3158189981, 568925988, 2572515393, 2346768303, 861712586,
24918     3982079547, 1441124702, 1196457648, 4293663189, 1648042348, 3666298377, 3358779879, 1888390786,
24919     686661332, 2421291441, 2196002399, 978858298, 2811169155, 523464422, 226935048, 3040519789,
24920     3175145892, 100435649, 390670639, 2952089162, 841119475, 2325614998, 2553003640, 546822429,
24921     2029308235, 3225988654, 3539796416, 1782671013, 4153826844, 1328167289, 1570739863, 3844338162,
24922     1298864389, 4124540512, 3882013070, 1608431339, 3255406162, 2058742071, 1744848601, 3501990332,
24923     2296328682, 811816591, 584513889, 2590678532, 129869501, 3204563416, 2914283062, 352848211,
24924     494030490, 2781751807, 3078325777, 264757620, 2450577869, 715964072, 941166918, 2158327331,
24925     3636881013, 1618608400, 1926213374, 3396585883, 1470427426, 4011365959, 4255988137, 1158766284,
24926     1984818694, 3471935843, 3695453837, 1693991400, 4180638033, 1100160564, 1395044826, 3952793279,
24927     3019491049, 189112716, 435162722, 2706139399, 1016811966, 2217162459, 2526189877, 774831696,
24928     643086745, 2666061564, 2354934034, 887166583, 2838900430, 294275499, 54519365, 3145957664,
24929     3823145334, 1532818963, 1240029693, 4048895640, 1820460577, 3560857924, 3331051178, 2117577167,
24930     3598663992, 1858283101, 2088143283, 3301633750, 1495127663, 3785470218, 4078182116, 1269332353,
24931     332098007, 2876706482, 3116540252, 25085497, 2628386432, 605395429, 916469259, 2384220526,
24932     2254837415, 1054503362, 745528876, 2496903497, 151290352, 2981684885, 2735556987, 464596510,
24933     1137851976, 4218313005, 3923506883, 1365741990, 3434129695, 1946996346, 1723425172, 3724871409,
24934   }, {
24935     0, 1029712304, 2059424608, 1201699536, 4118849216, 3370159984, 2403399072, 2988497936,
24936     812665793, 219177585, 1253054625, 2010132753, 3320900865, 4170237105, 3207642721, 2186319825,
24937     1625331586, 1568718386, 438355170, 658566482, 2506109250, 2818578674, 4020265506, 3535817618,
24938     1351670851, 1844508147, 709922595, 389064339, 2769320579, 2557498163, 3754961379, 3803185235,
24939     3250663172, 4238411444, 3137436772, 2254525908, 876710340, 153198708, 1317132964, 1944187668,
24940     4054934725, 3436268917, 2339452837, 3054575125, 70369797, 961670069, 2129760613, 1133623509,
24941     2703341702, 2621542710, 3689016294, 3867263574, 1419845190, 1774270454, 778128678, 318858390,
24942     2438067015, 2888948471, 3952189479, 3606153623, 1691440519, 1504803895, 504432359, 594620247,
24943     1492342857, 1704161785, 573770537, 525542041, 2910060169, 2417219385, 3618876905, 3939730521,
24944     1753420680, 1440954936, 306397416, 790849880, 2634265928, 2690882808, 3888375336, 3668168600,
24945     940822475, 91481723, 1121164459, 2142483739, 3448989963, 4042473659, 3075684971, 2318603227,
24946     140739594, 889433530, 1923340138, 1338244826, 4259521226, 3229813626, 2267247018, 3124975642,
24947     2570221389, 2756861693, 3824297005, 3734113693, 1823658381, 1372780605, 376603373, 722643805,
24948     2839690380, 2485261628, 3548540908, 4007806556, 1556257356, 1638052860, 637716780, 459464860,
24949     4191346895, 3300051327, 2199040943, 3195181599, 206718479, 825388991, 1989285231, 1274166495,
24950     3382881038, 4106388158, 3009607790, 2382549470, 1008864718, 21111934, 1189240494, 2072147742,
24951     2984685714, 2357631266, 3408323570, 4131834434, 1147541074, 2030452706, 1051084082, 63335554,
24952     2174155603, 3170292451, 4216760371, 3325460867, 1947622803, 1232499747, 248909555, 867575619,
24953     3506841360, 3966111392, 2881909872, 2527485376, 612794832, 434546784, 1581699760, 1663499008,
24954     3782634705, 3692447073, 2612412337, 2799048193, 351717905, 697754529, 1849071985, 1398190273,
24955     1881644950, 1296545318, 182963446, 931652934, 2242328918, 3100053734, 4284967478, 3255255942,
24956     1079497815, 2100821479, 983009079, 133672583, 3050795671, 2293717799, 3474399735, 4067887175,
24957     281479188, 765927844, 1778867060, 1466397380, 3846680276, 3626469220, 2676489652, 2733102084,
24958     548881365, 500656741, 1517752501, 1729575173, 3577210133, 3898068133, 2952246901, 2459410373,
24959     3910527195, 3564487019, 2480257979, 2931134987, 479546907, 569730987, 1716854139, 1530213579,
24960     3647316762, 3825568426, 2745561210, 2663766474, 753206746, 293940330, 1445287610, 1799716618,
24961     2314567513, 3029685993, 4080348217, 3461678473, 2088098201, 1091956777, 112560889, 1003856713,
24962     3112514712, 2229607720, 3276105720, 4263857736, 1275433560, 1902492648, 918929720, 195422344,
24963     685033439, 364179055, 1377080511, 1869921551, 3713294623, 3761522863, 2811507327, 2599689167,
24964     413436958, 633644462, 1650777982, 1594160846, 3978570462, 3494118254, 2548332990, 2860797966,
24965     1211387997, 1968470509, 854852413, 261368461, 3182753437, 2161434413, 3346310653, 4195650637,
24966     2017729436, 1160000044, 42223868, 1071931724, 2378480988, 2963576044, 4144295484, 3395602316,
24967   }, {
24968     0, 3411858341, 1304994059, 2257875630, 2609988118, 1355649459, 3596215069, 486879416,
24969     3964895853, 655315400, 2711298918, 1791488195, 2009251963, 3164476382, 973758832, 4048990933,
24970     64357019, 3364540734, 1310630800, 2235723829, 2554806413, 1394316072, 3582976390, 517157411,
24971     4018503926, 618222419, 2722963965, 1762783832, 1947517664, 3209171269, 970744811, 4068520014,
24972     128714038, 3438335635, 1248109629, 2167961496, 2621261600, 1466012805, 3522553387, 447296910,
24973     3959392091, 547575038, 2788632144, 1835791861, 1886307661, 3140622056, 1034314822, 4143626211,
24974     75106221, 3475428360, 1236444838, 2196665603, 2682996155, 1421317662, 3525567664, 427767573,
24975     3895035328, 594892389, 2782995659, 1857943406, 1941489622, 3101955187, 1047553757, 4113347960,
24976     257428076, 3288652233, 1116777319, 2311878850, 2496219258, 1603640287, 3640781169, 308099796,
24977     3809183745, 676813732, 2932025610, 1704983215, 2023410199, 3016104370, 894593820, 4262377657,
24978     210634999, 3352484690, 1095150076, 2316991065, 2535410401, 1547934020, 3671583722, 294336591,
24979     3772615322, 729897279, 2903845777, 1716123700, 2068629644, 2953845545, 914647431, 4258839074,
24980     150212442, 3282623743, 1161604689, 2388688372, 2472889676, 1480171241, 3735940167, 368132066,
24981     3836185911, 805002898, 2842635324, 1647574937, 2134298401, 3026852996, 855535146, 4188192143,
24982     186781121, 3229539940, 1189784778, 2377547631, 2427670487, 1542429810, 3715886812, 371670393,
24983     3882979244, 741170185, 2864262823, 1642462466, 2095107514, 3082559007, 824732849, 4201955092,
24984     514856152, 3589064573, 1400419795, 2552522358, 2233554638, 1316849003, 3370776517, 62202976,
24985     4075001525, 968836368, 3207280574, 1954014235, 1769133219, 2720925446, 616199592, 4024870413,
24986     493229635, 3594175974, 1353627464, 2616354029, 2264355925, 1303087088, 3409966430, 6498043,
24987     4046820398, 979978123, 3170710821, 2007099008, 1789187640, 2717386141, 661419827, 3962610838,
24988     421269998, 3527459403, 1423225061, 2676515648, 2190300152, 1238466653, 3477467891, 68755798,
24989     4115633027, 1041448998, 3095868040, 1943789869, 1860096405, 2776760880, 588673182, 3897205563,
24990     449450869, 3516317904, 1459794558, 2623431131, 2170245475, 1242006214, 3432247400, 131015629,
24991     4137259288, 1036337853, 3142660115, 1879958454, 1829294862, 2790523051, 549483013, 3952910752,
24992     300424884, 3669282065, 1545650111, 2541513754, 2323209378, 1092980487, 3350330793, 216870412,
24993     4256931033, 921128828, 2960342482, 2066738807, 1714085583, 2910195050, 736264132, 3770592353,
24994     306060335, 3647131530, 1610005796, 2494197377, 2309971513, 1123257756, 3295149874, 255536279,
24995     4268596802, 892423655, 3013951305, 2029645036, 1711070292, 2929725425, 674528607, 3815288570,
24996     373562242, 3709388839, 1535949449, 2429577516, 2379569556, 1183418929, 3223189663, 188820282,
24997     4195850735, 827017802, 3084859620, 2089020225, 1636228089, 2866415708, 743340786, 3876759895,
24998     361896217, 3738094268, 1482340370, 2466671543, 2382584591, 1163888810, 3284924932, 144124321,
24999     4190215028, 849168593, 3020503679, 2136336858, 1649465698, 2836138695, 798521449, 3838094284,
25000   }, {
25001     0, 2792819636, 2543784233, 837294749, 4098827283, 1379413927, 1674589498, 3316072078,
25002     871321191, 2509784531, 2758827854, 34034938, 3349178996, 1641505216, 1346337629, 4131942633,
25003     1742642382, 3249117050, 4030828007, 1446413907, 2475800797, 904311657, 68069876, 2725880384,
25004     1412551337, 4064729373, 3283010432, 1708771380, 2692675258, 101317902, 937551763, 2442587175,
25005     3485284764, 1774858792, 1478633653, 4266992385, 1005723023, 2642744891, 2892827814, 169477906,
25006     4233263099, 1512406095, 1808623314, 3451546982, 136139752, 2926205020, 2676114113, 972376437,
25007     2825102674, 236236518, 1073525883, 2576072655, 1546420545, 4200303349, 3417542760, 1841601500,
25008     2609703733, 1039917185, 202635804, 2858742184, 1875103526, 3384067218, 4166835727, 1579931067,
25009     1141601657, 3799809741, 3549717584, 1977839588, 2957267306, 372464350, 668680259, 2175552503,
25010     2011446046, 3516084394, 3766168119, 1175200131, 2209029901, 635180217, 338955812, 2990736784,
25011     601221559, 2242044419, 3024812190, 306049834, 3617246628, 1911408144, 1074125965, 3866285881,
25012     272279504, 3058543716, 2275784441, 567459149, 3832906691, 1107462263, 1944752874, 3583875422,
25013     2343980261, 767641425, 472473036, 3126744696, 2147051766, 3649987394, 3899029983, 1309766251,
25014     3092841090, 506333494, 801510315, 2310084639, 1276520081, 3932237093, 3683203000, 2113813516,
25015     3966292011, 1243601823, 2079834370, 3716205238, 405271608, 3192979340, 2411259153, 701492901,
25016     3750207052, 2045810168, 1209569125, 4000285905, 734575199, 2378150379, 3159862134, 438345922,
25017     2283203314, 778166598, 529136603, 3120492655, 2086260449, 3660498261, 3955679176, 1303499900,
25018     3153699989, 495890209, 744928700, 2316418568, 1337360518, 3921775410, 3626602927, 2120129051,
25019     4022892092, 1237286280, 2018993941, 3726666913, 461853231, 3186645403, 2350400262, 711936178,
25020     3693557851, 2052076527, 1270360434, 3989775046, 677911624, 2384402428, 3220639073, 427820757,
25021     1202443118, 3789347034, 3493118535, 1984154099, 3018127229, 362020041, 612099668, 2181885408,
25022     1950653705, 3526596285, 3822816288, 1168934804, 2148251930, 645706414, 395618355, 2984485767,
25023     544559008, 2248295444, 3085590153, 295523645, 3560598451, 1917673479, 1134918298, 3855773998,
25024     328860103, 3052210803, 2214924526, 577903450, 3889505748, 1101147744, 1883911421, 3594338121,
25025     3424493451, 1785369663, 1535282850, 4260726038, 944946072, 2653270060, 2949491377, 163225861,
25026     4294103532, 1501944408, 1752023237, 3457862513, 196998655, 2915761739, 2619532502, 978710370,
25027     2881684293, 229902577, 1012666988, 2586515928, 1603020630, 4193987810, 3356702335, 1852063179,
25028     2553040162, 1046169238, 263412747, 2848217023, 1818454321, 3390333573, 4227627032, 1569420204,
25029     60859927, 2782375331, 2487203646, 843627658, 4159668740, 1368951216, 1617990445, 3322386585,
25030     810543216, 2520310724, 2815490393, 27783917, 3288386659, 1652017111, 1402985802, 4125677310,
25031     1685994201, 3255382381, 4091620336, 1435902020, 2419138250, 910562686, 128847843, 2715354199,
25032     1469150398, 4058414858, 3222168983, 1719234083, 2749255853, 94984985, 876691844, 2453031472,
25033   }, {
25034     0, 3433693342, 1109723005, 2391738339, 2219446010, 1222643300, 3329165703, 180685081,
25035     3555007413, 525277995, 2445286600, 1567235158, 1471092047, 2600801745, 361370162, 3642757804,
25036     2092642603, 2953916853, 1050555990, 4063508168, 4176560081, 878395215, 3134470316, 1987983410,
25037     2942184094, 1676945920, 3984272867, 567356797, 722740324, 3887998202, 1764827929, 2778407815,
25038     4185285206, 903635656, 3142804779, 2012833205, 2101111980, 2979425330, 1058630609, 4088621903,
25039     714308067, 3862526333, 1756790430, 2753330688, 2933487385, 1651734407, 3975966820, 542535930,
25040     2244825981, 1231508451, 3353891840, 188896414, 25648519, 3442302233, 1134713594, 2399689316,
25041     1445480648, 2592229462, 336416693, 3634843435, 3529655858, 516441772, 2420588879, 1559052753,
25042     698204909, 3845636723, 1807271312, 2803025166, 2916600855, 1635634313, 4025666410, 593021940,
25043     4202223960, 919787974, 3093159461, 1962401467, 2117261218, 2996361020, 1008193759, 4038971457,
25044     1428616134, 2576151384, 386135227, 3685348389, 3513580860, 499580322, 2471098945, 1608776415,
25045     2260985971, 1248454893, 3303468814, 139259792, 42591881, 3458459159, 1085071860, 2349261162,
25046     3505103035, 474062885, 2463016902, 1583654744, 1419882049, 2550902495, 377792828, 3660491170,
25047     51297038, 3483679632, 1093385331, 2374089965, 2269427188, 1273935210, 3311514249, 164344343,
25048     2890961296, 1627033870, 4000683757, 585078387, 672833386, 3836780532, 1782552599, 2794821769,
25049     2142603813, 3005188795, 1032883544, 4047146438, 4227826911, 928351297, 3118105506, 1970307900,
25050     1396409818, 2677114180, 287212199, 3719594553, 3614542624, 467372990, 2505346141, 1509854403,
25051     2162073199, 1282711281, 3271268626, 240228748, 76845205, 3359543307, 1186043880, 2317064054,
25052     796964081, 3811226735, 1839575948, 2702160658, 2882189835, 1734392469, 3924802934, 625327592,
25053     4234522436, 818917338, 3191908409, 1927981223, 2016387518, 3028656416, 973776579, 4137723485,
25054     2857232268, 1726474002, 3899187441, 616751215, 772270454, 3803048424, 1814228491, 2693328533,
25055     2041117753, 3036871847, 999160644, 4146592730, 4259508931, 826864221, 3217552830, 1936586016,
25056     3606501031, 442291769, 2496909786, 1484378436, 1388107869, 2652297411, 278519584, 3694387134,
25057     85183762, 3384397196, 1194773103, 2342308593, 2170143720, 1307820918, 3279733909, 265733131,
25058     2057717559, 3054258089, 948125770, 4096344276, 4276898253, 843467091, 3167309488, 1885556270,
25059     2839764098, 1709792284, 3949353983, 667704161, 755585656, 3785577190, 1865176325, 2743489947,
25060     102594076, 3401021058, 1144549729, 2291298815, 2186770662, 1325234296, 3228729243, 215514885,
25061     3589828009, 424832311, 2547870420, 1534552650, 1370645331, 2635621325, 328688686, 3745342640,
25062     2211456353, 1333405183, 3254067740, 224338562, 127544219, 3408931589, 1170156774, 2299866232,
25063     1345666772, 2627681866, 303053225, 3736746295, 3565105198, 416624816, 2522494803, 1525692365,
25064     4285207626, 868291796, 3176010551, 1910772649, 2065767088, 3079346734, 956571085, 4121828691,
25065     747507711, 3760459617, 1856702594, 2717976604, 2831417605, 1684930971, 3940615800, 642451174,
25066   },
25067   {
25068     0, 393942083, 787884166, 965557445, 1575768332, 1251427663, 1931114890, 1684106697,
25069     3151536664, 2896410203, 2502855326, 2186649309, 3862229780, 4048545623, 3368213394, 3753496529,
25070     2898281073, 3149616690, 2184604407, 2504883892, 4046197629, 3864463166, 3755621371, 3366006712,
25071     387506281, 6550570, 971950319, 781573292, 1257550181, 1569695014, 1677892067, 1937345952,
25072     2196865699, 2508887776, 2886183461, 3145514598, 3743273903, 3362179052, 4058774313, 3868258154,
25073     958996667, 777139448, 400492605, 10755198, 1690661303, 1941857780, 1244879153, 1565019506,
25074     775012562, 961205393, 13101140, 398261271, 1943900638, 1688634781, 1563146584, 1246801179,
25075     2515100362, 2190636681, 3139390028, 2892258831, 3355784134, 3749586821, 3874691904, 4052225795,
25076     3734110983, 3387496260, 4033096577, 3877584834, 2206093835, 2483373640, 2911402637, 3136515790,
25077     1699389727, 1915860316, 1270647193, 1556585946, 950464531, 803071056, 374397077, 19647702,
25078     1917993334, 1697207605, 1554278896, 1272937907, 800985210, 952435769, 21510396, 372452543,
25079     3381322606, 3740399405, 3883715560, 4027047851, 2489758306, 2199758369, 3130039012, 2917895847,
25080     1550025124, 1259902439, 1922410786, 1710144865, 26202280, 385139947, 796522542, 939715693,
25081     3887801276, 4039129087, 3377269562, 3728088953, 3126293168, 2905368307, 2493602358, 2212122229,
25082     4037264341, 3889747862, 3730172755, 3375300368, 2907673305, 3124004506, 2209987167, 2495786524,
25083     1266377165, 1543533966, 1703758155, 1928748296, 379007169, 32253058, 945887303, 790236164,
25084     1716846671, 1898845196, 1218652361, 1608006794, 1002000707, 750929152, 357530053, 36990342,
25085     3717046871, 3405166100, 4084959953, 3825245842, 2153902939, 2535122712, 2929187805, 3119304606,
25086     3398779454, 3723384445, 3831720632, 4078468859, 2541294386, 2147616625, 3113171892, 2935238647,
25087     1900929062, 1714877541, 1606142112, 1220599011, 748794154, 1004184937, 39295404, 355241455,
25088     3835986668, 4091516591, 3394415210, 3710500393, 3108557792, 2922629027, 2545875814, 2160455461,
25089     1601970420, 1208431799, 1904871538, 1727077425, 43020792, 367748539, 744905086, 991776061,
25090     1214562461, 1595921630, 1720903707, 1911159896, 361271697, 49513938, 998160663, 738569556,
25091     4089209477, 3838277318, 3712633347, 3392233024, 2924491657, 3106613194, 2158369551, 2547846988,
25092     3100050248, 2948339467, 2519804878, 2169126797, 3844821572, 4065347079, 3420289730, 3701894785,
25093     52404560, 342144275, 770279894, 982687125, 1593045084, 1233708063, 1879431386, 1736363161,
25094     336019769, 58479994, 988899775, 764050940, 1240141877, 1586496630, 1729968307, 1885744368,
25095     2950685473, 3097818978, 2166999975, 2522013668, 4063474221, 3846743662, 3703937707, 3418263272,
25096     976650731, 760059304, 348170605, 62635310, 1742393575, 1889649828, 1227683937, 1582820386,
25097     2179867635, 2526361520, 2937588597, 3093503798, 3691148031, 3413731004, 4076100217, 3851374138,
25098     2532754330, 2173556697, 3087067932, 2944139103, 3407516310, 3697379029, 3857496592, 4070026835,
25099     758014338, 978679233, 64506116, 346250567, 1891774606, 1740186829, 1580472328, 1229917259,
25100   }, {
25101     0, 4022496062, 83218493, 3946298115, 166436986, 3861498692, 220098631, 3806075769,
25102     332873972, 4229245898, 388141257, 4175494135, 440197262, 4127099824, 516501683, 4044053389,
25103     665747944, 3362581206, 593187285, 3432594155, 776282514, 3246869164, 716239279, 3312622225,
25104     880394524, 3686509090, 814485793, 3746462239, 1033003366, 3528460888, 963096923, 3601193573,
25105     1331495888, 2694801646, 1269355501, 2758457555, 1186374570, 2843003028, 1111716759, 2910918825,
25106     1552565028, 3007850522, 1484755737, 3082680359, 1432478558, 3131279456, 1368666979, 3193329757,
25107     1760789048, 2268195078, 1812353541, 2210675003, 1628971586, 2396670332, 1710092927, 2318375233,
25108     2066006732, 2498144754, 2144408305, 2417195471, 1926193846, 2634877320, 1983558283, 2583222709,
25109     2662991776, 1903717534, 2588923805, 1972223139, 2538711002, 2022952164, 2477029351, 2087066841,
25110     2372749140, 1655647338, 2308478825, 1717238871, 2223433518, 1799654416, 2155034387, 1873894445,
25111     3105130056, 1456926070, 3185661557, 1378041163, 2969511474, 1597852940, 3020617231, 1539874097,
25112     2864957116, 1157737858, 2922780289, 1106542015, 2737333958, 1290407416, 2816325371, 1210047941,
25113     3521578096, 1042640718, 3574781005, 986759027, 3624707082, 936300340, 3707335735, 859512585,
25114     3257943172, 770846650, 3334837433, 688390023, 3420185854, 605654976, 3475911875, 552361981,
25115     4132013464, 428600998, 4072428965, 494812827, 4288816610, 274747100, 4216845791, 345349857,
25116     3852387692, 173846098, 3781891409, 245988975, 3967116566, 62328360, 3900749099, 121822741,
25117     3859089665, 164061759, 3807435068, 221426178, 4025395579, 2933317, 3944446278, 81334904,
25118     4124199413, 437265099, 4045904328, 518386422, 4231653775, 335250097, 4174133682, 386814604,
25119     3249244393, 778691543, 3311294676, 714879978, 3359647891, 662848429, 3434477742, 595039120,
25120     3531393053, 1035903779, 3599308832, 961245982, 3684132967, 877986649, 3747788890, 815846244,
25121     2841119441, 1184522735, 2913852140, 1114616274, 2696129195, 1332855189, 2756082326, 1266946472,
25122     3129952805, 1431118107, 3195705880, 1371074854, 3009735263, 1554415969, 3079748194, 1481855324,
25123     2398522169, 1630855175, 2315475716, 1707159610, 2266835779, 1759461501, 2213084030, 1814728768,
25124     2636237773, 1927520499, 2580814832, 1981182158, 2496293815, 2064121993, 2420095882, 2147340468,
25125     2025787041, 2541577631, 2085281436, 2475210146, 1901375195, 2660681189, 1973518054, 2590184920,
25126     1801997909, 2225743211, 1872600680, 2153772374, 1652813359, 2369881361, 1719025170, 2310296876,
25127     1594986313, 2966676599, 1541693300, 3022402634, 1459236659, 3107472397, 1376780046, 3184366640,
25128     1288097725, 2734990467, 1211309952, 2817619134, 1160605639, 2867791097, 1104723962, 2920993988,
25129     937561457, 3626001999, 857201996, 3704993394, 1040821515, 3519792693, 989625654, 3577615880,
25130     607473029, 3421972155, 549494200, 3473077894, 769584639, 3256649409, 690699714, 3337180924,
25131     273452185, 4287555495, 347692196, 4219156378, 430386403, 4133832669, 491977950, 4069562336,
25132     60542061, 3965298515, 124656720, 3903616878, 175139863, 3853649705, 243645482, 3779581716,
25133   }, {
25134     0, 3247366080, 1483520449, 2581751297, 2967040898, 1901571138, 3904227907, 691737987,
25135     3133399365, 2068659845, 3803142276, 589399876, 169513671, 3415493895, 1383475974, 2482566342,
25136     2935407819, 1870142219, 4137319690, 924099274, 506443593, 3751897225, 1178799752, 2278412616,
25137     339027342, 3585866318, 1280941135, 2379694991, 2766951948, 1700956620, 4236308429, 1024339981,
25138     2258407383, 1192382487, 3740284438, 528411094, 910556245, 4157285269, 1848198548, 2946996820,
25139     1012887186, 4258378066, 1681119059, 2780629139, 2357599504, 1292419792, 3572147409, 358906641,
25140     678054684, 3924071644, 1879503581, 2978491677, 2561882270, 1497229150, 3235873119, 22109855,
25141     2460592729, 1395094937, 3401913240, 189516888, 577821147, 3825075739, 2048679962, 3146956762,
25142     3595049455, 398902831, 2384764974, 1336573934, 1720805997, 2803873197, 1056822188, 4285729900,
25143     1821112490, 2902796138, 887570795, 4117339819, 3696397096, 500978920, 2218668777, 1169222953,
25144     2025774372, 3106931428, 550659301, 3780950821, 3362238118, 166293862, 2416645991, 1367722151,
25145     3262987361, 66315169, 2584839584, 1537170016, 1923370979, 3005911075, 717813282, 3947244002,
25146     1356109368, 2438613496, 146288633, 3375820857, 3759007162, 562248314, 3093388411, 2045739963,
25147     3927406461, 731490493, 2994458300, 1945440636, 1523451135, 2604718911, 44219710, 3274466046,
25148     4263662323, 1068272947, 2790189874, 1740649714, 1325080945, 2406874801, 379033776, 3608758128,
25149     1155642294, 2238671990, 479005303, 3708016055, 4097359924, 901128180, 2891217397, 1843045941,
25150     2011248031, 3060787807, 797805662, 3993195422, 3342353949, 112630237, 2673147868, 1591353372,
25151     3441611994, 212601626, 2504944923, 1421914843, 2113644376, 3161815192, 630660761, 3826893145,
25152     3642224980, 412692116, 2172340373, 1089836885, 1775141590, 2822790422, 832715543, 4029474007,
25153     1674842129, 2723860433, 1001957840, 4197873168, 3540870035, 310623315, 2338445906, 1257178514,
25154     4051548744, 821257608, 2836464521, 1755307081, 1101318602, 2150241802, 432566283, 3628511179,
25155     1270766349, 2318435533, 332587724, 3529260300, 4217841807, 988411727, 2735444302, 1652903566,
25156     1602977411, 2651169091, 132630338, 3328776322, 4015131905, 786223809, 3074340032, 1991273216,
25157     3846741958, 616972294, 3173262855, 2091579847, 1435626564, 2485072772, 234706309, 3430124101,
25158     2712218736, 1613231024, 4190475697, 944458353, 292577266, 3506339890, 1226630707, 2291284467,
25159     459984181, 3672380149, 1124496628, 2189994804, 2880683703, 1782407543, 4091479926, 844224694,
25160     257943739, 3469817723, 1462980986, 2529005242, 3213269817, 2114471161, 3890881272, 644152632,
25161     3046902270, 1947391550, 3991973951, 746483711, 88439420, 3301680572, 1563018173, 2628197501,
25162     657826727, 3871046759, 2136545894, 3201811878, 2548879397, 1449267173, 3481299428, 235845156,
25163     2650161890, 1551408418, 3315268387, 68429027, 758067552, 3970035360, 1967360161, 3033356129,
25164     2311284588, 1213053100, 3517963949, 270598509, 958010606, 4170500910, 1635167535, 2700636911,
25165     855672361, 4069415401, 1802256360, 2866995240, 2212099499, 1113008747, 3686091882, 440112042,
25166   }, {
25167     0, 2611301487, 3963330207, 2006897392, 50740095, 2560849680, 4013794784, 1956178319,
25168     101480190, 2645113489, 3929532513, 1905435662, 84561281, 2662269422, 3912356638, 1922342769,
25169     202960380, 2545787283, 3760419683, 2072395532, 253679235, 2495322860, 3810871324, 2021655667,
25170     169122562, 2444351341, 3861841309, 2106214898, 152215677, 2461527058, 3844685538, 2123133581,
25171     405920760, 2207553431, 4094313831, 1873742088, 456646791, 2157096168, 4144791064, 1823027831,
25172     507358470, 2241388905, 4060492697, 1772322806, 490444409, 2258557462, 4043311334, 1789215881,
25173     338245124, 2408348267, 4161972379, 1672996084, 388959611, 2357870868, 4212429796, 1622269835,
25174     304431354, 2306870421, 4263435877, 1706791434, 287538053, 2324051946, 4246267162, 1723705717,
25175     811841520, 2881944479, 3696765295, 1207788800, 862293135, 2831204576, 3747484176, 1157324415,
25176     913293582, 2915732833, 3662962577, 1106318334, 896137841, 2932651550, 3646055662, 1123494017,
25177     1014716940, 2816349795, 3493905555, 1273334012, 1065181555, 2765630748, 3544645612, 1222882179,
25178     980888818, 2714919069, 3595350637, 1307180546, 963712909, 2731826146, 3578431762, 1324336509,
25179     676490248, 3019317351, 3295277719, 1607253752, 726947703, 2968591128, 3345992168, 1556776327,
25180     777919222, 3053147801, 3261432937, 1505806342, 760750473, 3070062054, 3244539670, 1522987897,
25181     608862708, 3220163995, 3362856811, 1406423812, 659339915, 3169449700, 3413582868, 1355966587,
25182     575076106, 3118709605, 3464325525, 1440228858, 557894773, 3135602714, 3447411434, 1457397381,
25183     1623683040, 4217512847, 2365387135, 391757072, 1673614495, 4167309552, 2415577600, 341804655,
25184     1724586270, 4251866481, 2331019137, 290835438, 1707942497, 4268256782, 2314648830, 307490961,
25185     1826587164, 4152020595, 2162433155, 457265388, 1876539747, 4101829900, 2212636668, 407333779,
25186     1792275682, 4051089549, 2263378557, 491595282, 1775619997, 4067460082, 2246988034, 508239213,
25187     2029433880, 3813931127, 2496473735, 258500328, 2079362919, 3763716872, 2546668024, 208559511,
25188     2130363110, 3848244873, 2462145657, 157552662, 2113730969, 3864638966, 2445764358, 174205801,
25189     1961777636, 4014675339, 2564147067, 57707284, 2011718299, 3964481268, 2614361092, 7778411,
25190     1927425818, 3913769845, 2665066885, 92077546, 1910772837, 3930150922, 2648673018, 108709525,
25191     1352980496, 3405878399, 3164554895, 658115296, 1403183983, 3355946752, 3214507504, 607924639,
25192     1453895406, 3440239233, 3130208369, 557218846, 1437504913, 3456883198, 3113552654, 573589345,
25193     1555838444, 3340335491, 2961681267, 723707676, 1606028947, 3290383100, 3011612684, 673504355,
25194     1521500946, 3239382909, 3062619533, 758026722, 1505130605, 3256038402, 3045975794, 774417053,
25195     1217725416, 3543158663, 2762906999, 1057739032, 1267939479, 3493229816, 2812847624, 1007544935,
25196     1318679830, 3577493881, 2728586121, 956803046, 1302285929, 3594125830, 2711933174, 973184153,
25197     1150152212, 3743982203, 2830528651, 856898788, 1200346475, 3694041348, 2880457716, 806684571,
25198     1115789546, 3643069573, 2931426933, 891243034, 1099408277, 3659722746, 2914794762, 907637093,
25199   }, {
25200     0, 3717650821, 1616688459, 3184159950, 3233376918, 489665299, 2699419613, 2104690264,
25201     1510200173, 2274691816, 979330598, 3888758691, 2595928571, 1194090622, 4209380528, 661706037,
25202     3020400346, 1771143007, 3562738577, 164481556, 1958661196, 2837976521, 350386439, 3379863682,
25203     3993269687, 865250354, 2388181244, 1406015865, 784146209, 4079732388, 1323412074, 2474079215,
25204     3011398645, 1860735600, 3542286014, 246687547, 1942430051, 2924607718, 328963112, 3456978349,
25205     3917322392, 887832861, 2300653011, 1421341782, 700772878, 4099025803, 1234716485, 2483986112,
25206     125431087, 3673109674, 1730500708, 3132326369, 3351283641, 441867836, 2812031730, 2047535991,
25207     1568292418, 2163009479, 1025936137, 3769651852, 2646824148, 1079348561, 4255113631, 537475098,
25208     3180171691, 1612400686, 3721471200, 4717925, 2100624189, 2694980280, 493375094, 3237910515,
25209     3884860102, 974691139, 2278750093, 1514417672, 657926224, 4204917205, 1198234907, 2600289438,
25210     160053105, 3558665972, 1775665722, 3024116671, 3375586791, 346391650, 2842683564, 1962488105,
25211     1401545756, 2384412057, 869618007, 3997403346, 2469432970, 1319524111, 4083956673, 788193860,
25212     250862174, 3546612699, 1856990997, 3006903952, 3461001416, 333211981, 2920678787, 1937824774,
25213     1425017139, 2305216694, 883735672, 3912918525, 2487837605, 1239398944, 4095071982, 696455019,
25214     3136584836, 1734518017, 3668494799, 121507914, 2051872274, 2816200599, 437363545, 3347544796,
25215     3774328809, 1029797484, 2158697122, 1564328743, 542033279, 4258798842, 1074950196, 2642717105,
25216     2691310871, 2113731730, 3224801372, 497043929, 1624461185, 3175454212, 9435850, 3709412175,
25217     4201248378, 671035391, 2587181873, 1201904308, 986750188, 3880142185, 1519135143, 2266689570,
25218     342721485, 3388693064, 1949382278, 2846355203, 3570723163, 155332830, 3028835344, 1763607957,
25219     1315852448, 2482538789, 775087595, 4087626862, 2396469814, 1396827059, 4002123645, 857560824,
25220     320106210, 3464673127, 1934154665, 2933785132, 3551331444, 238804465, 3018961215, 1852270778,
25221     1226292623, 2491507722, 692783300, 4108177729, 2309936921, 1412959900, 3924976210, 879016919,
25222     2803091512, 2055541181, 3343875443, 450471158, 1739236014, 3124525867, 133568485, 3663777376,
25223     4245691221, 545702608, 2639048222, 1088059291, 1034514883, 3762268230, 1576387720, 2153979149,
25224     501724348, 3228659001, 2109407735, 2687359090, 3713981994, 13109167, 3171052385, 1620357860,
25225     1206151121, 2591211092, 666423962, 4197321503, 2271022407, 1523307714, 3875649548, 982999433,
25226     2850034278, 1953942499, 3384583981, 338329256, 1767471344, 3033506165, 151375291, 3566408766,
25227     4091789579, 779425934, 2478797888, 1311354309, 861580189, 4006375960, 1392910038, 2391852883,
25228     2929327945, 1930372812, 3469036034, 324244359, 1847629279, 3015068762, 243015828, 3555391761,
25229     4103744548, 688715169, 2496043375, 1229996266, 874727090, 3920994103, 1417671673, 2313759356,
25230     446585235, 3339223062, 2059594968, 2807313757, 3660002053, 129100416, 3128657486, 1743609803,
25231     1084066558, 2634765179, 549535669, 4250396208, 2149900392, 1571961325, 3765982499, 1039043750,
25232   }, {
25233     0, 2635063670, 3782132909, 2086741467, 430739227, 2225303149, 4173482934, 1707977408,
25234     861478454, 2924937024, 3526875803, 1329085421, 720736557, 3086643291, 3415954816, 1452586230,
25235     1722956908, 4223524122, 2279405761, 450042295, 2132718455, 3792785921, 2658170842, 58693292,
25236     1441473114, 3370435372, 3028674295, 696911745, 1279765825, 3511176247, 2905172460, 807831706,
25237     3445913816, 1349228974, 738901109, 2969918723, 3569940419, 1237784245, 900084590, 2829701656,
25238     4265436910, 1664255896, 525574723, 2187084597, 3885099509, 2057177219, 117386584, 2616249390,
25239     2882946228, 920233410, 1253605401, 3619119471, 2994391983, 796207833, 1393823490, 3457937012,
25240     2559531650, 92322804, 2044829231, 3840835417, 2166609305, 472659183, 1615663412, 4249022530,
25241     1102706673, 3702920839, 2698457948, 1037619754, 1477802218, 3306854812, 3111894087, 611605809,
25242     1927342535, 4025419953, 2475568490, 243387420, 1800169180, 4131620778, 2317525617, 388842247,
25243     655084445, 3120835307, 3328511792, 1533734470, 1051149446, 2745738736, 3754524715, 1120297309,
25244     340972971, 2304586973, 4114354438, 1748234352, 234773168, 2431761350, 3968900637, 1906278251,
25245     2363330345, 299003487, 1840466820, 4038896370, 2507210802, 142532932, 1948239007, 3910149609,
25246     3213136159, 579563625, 1592415666, 3286611140, 2787646980, 992477042, 1195825833, 3662232543,
25247     3933188933, 2002801203, 184645608, 2517538462, 4089658462, 1858919720, 313391347, 2409765253,
25248     3644239219, 1144605701, 945318366, 2773977256, 3231326824, 1570095902, 569697989, 3170568115,
25249     2205413346, 511446676, 1646078799, 4279421497, 2598330617, 131105167, 2075239508, 3871229218,
25250     2955604436, 757403810, 1363424633, 3427521551, 2844163791, 881434553, 1223211618, 3588709140,
25251     3854685070, 2026779384, 78583587, 2577462869, 4235025557, 1633861091, 486774840, 2148301134,
25252     3600338360, 1268198606, 938871061, 2868504675, 3476308643, 1379640277, 777684494, 3008718712,
25253     1310168890, 3541595724, 2943964055, 846639841, 1471879201, 3400857943, 3067468940, 735723002,
25254     2102298892, 3762382970, 2619362721, 19901655, 1692534295, 4193118049, 2240594618, 411247564,
25255     681945942, 3047836192, 3385552891, 1422167693, 822682701, 2886124859, 3496468704, 1298661782,
25256     469546336, 2264093718, 4203901389, 1738379451, 38812283, 2673859341, 3812556502, 2117148576,
25257     3268024339, 1606809957, 598006974, 3198893512, 3680933640, 1181316734, 973624229, 2802299603,
25258     4052944421, 1822222163, 285065864, 2381456382, 3896478014, 1966106696, 156323219, 2489232613,
25259     2759337087, 964150537, 1159127250, 3625517476, 3184831332, 551242258, 1555722185, 3249901247,
25260     2535537225, 170842943, 1984954084, 3946848146, 2391651666, 327308324, 1877176831, 4075589769,
25261     263086283, 2460058045, 4005602406, 1942963472, 369291216, 2332888742, 4151061373, 1784924683,
25262     1022852861, 2717425547, 3717839440, 1083595558, 626782694, 3092517008, 3291821387, 1497027645,
25263     1763466407, 4094934481, 2289211402, 360544636, 1890636732, 3988730570, 2447251217, 215086695,
25264     1514488465, 3343557607, 3140191804, 639919946, 1139395978, 3739626748, 2726758695, 1065936977,
25265   }, {
25266     0, 3120290792, 2827399569, 293431929, 2323408227, 864534155, 586863858, 2600537882,
25267     3481914503, 1987188591, 1729068310, 3740575486, 1173727716, 4228805132, 3983743093, 1418249117,
25268     1147313999, 4254680231, 3974377182, 1428157750, 3458136620, 2011505092, 1721256893, 3747844181,
25269     2347455432, 839944224, 594403929, 2593536433, 26687147, 3094146371, 2836498234, 283794642,
25270     2294627998, 826205558, 541298447, 2578994407, 45702141, 3141697557, 2856315500, 331624836,
25271     1196225049, 4273416689, 4023010184, 1446090848, 3442513786, 1959480466, 1706436331, 3696098563,
25272     3433538001, 1968994873, 1679888448, 3722103720, 1188807858, 4280295258, 3999102243, 1470541515,
25273     53374294, 3134568126, 2879970503, 307431215, 2303854645, 816436189, 567589284, 2553242188,
25274     3405478781, 1929420949, 1652411116, 3682996484, 1082596894, 4185703926, 3892424591, 1375368295,
25275     91404282, 3163122706, 2918450795, 336584067, 2400113305, 922028401, 663249672, 2658384096,
25276     2392450098, 929185754, 639587747, 2682555979, 82149713, 3172883129, 2892181696, 362343208,
25277     1091578037, 4176212829, 3918960932, 1349337804, 3412872662, 1922537022, 1676344391, 3658557359,
25278     1111377379, 4224032267, 3937989746, 1396912026, 3359776896, 1908013928, 1623494929, 3644803833,
25279     2377615716, 877417100, 623982837, 2630542109, 130804743, 3190831087, 2941083030, 381060734,
25280     106748588, 3215393092, 2933549885, 388083925, 2350956495, 903570471, 614862430, 2640172470,
25281     3386185259, 1882115523, 1632872378, 3634920530, 1135178568, 4199721120, 3945775833, 1389631793,
25282     1317531835, 4152109907, 3858841898, 1610259138, 3304822232, 2097172016, 1820140617, 3582394273,
25283     2165193788, 955639764, 696815021, 2423477829, 192043359, 2995356343, 2750736590, 437203750,
25284     182808564, 3005133852, 2724453989, 462947725, 2157513367, 962777471, 673168134, 2447663342,
25285     3312231283, 2090301595, 1844056802, 3557935370, 1326499344, 4142603768, 3885397889, 1584245865,
25286     3326266917, 2142836173, 1858371508, 3611272284, 1279175494, 4123357358, 3837270743, 1564721471,
25287     164299426, 2955991370, 2706223923, 414607579, 2209834945, 978107433, 724686416, 2462715320,
25288     2183156074, 1004243586, 715579643, 2472360723, 140260361, 2980573153, 2698675608, 421617264,
25289     1302961645, 4099032581, 3845074044, 1557460884, 3352688782, 2116952934, 1867729183, 3601371895,
25290     2222754758, 1032278062, 754596439, 2499928511, 234942117, 3086693709, 2793824052, 528319708,
25291     1274365761, 4061043881, 3816027856, 1518873912, 3246989858, 2020800970, 1762628531, 3505670235,
25292     3223196809, 2045103969, 1754834200, 3512958704, 1247965674, 4086934018, 3806642299, 1528765331,
25293     261609486, 3060532198, 2802936223, 518697591, 2246819181, 1007707781, 762121468, 2492913428,
25294     213497176, 3041029808, 2755593417, 499441441, 2261110843, 1061030867, 776167850, 2545465922,
25295     3274734047, 2060165687, 1807140942, 3528266662, 1229724860, 4038575956, 3788156205, 1479636677,
25296     1222322711, 4045468159, 3764231046, 1504067694, 3265744756, 2069664924, 1780612837, 3554288909,
25297     2270357136, 1051278712, 802445057, 2519698665, 221152243, 3033880603, 2779263586, 475261322,
25298   }, {
25299     0, 2926088593, 2275419491, 701019378, 3560000647, 2052709654, 1402038756, 4261017717,
25300     1930665807, 3715829470, 4105419308, 1524313021, 2804077512, 155861593, 545453739, 2397726522,
25301     3861331614, 1213181711, 1636244477, 3488582252, 840331801, 2625561480, 3048626042, 467584747,
25302     2503254481, 995897408, 311723186, 3170637091, 1090907478, 4016929991, 3332753461, 1758288292,
25303     390036349, 3109546732, 2426363422, 1056427919, 3272488954, 1835443819, 1152258713, 3938878216,
25304     1680663602, 3393484195, 3817652561, 1306808512, 2954733749, 510998820, 935169494, 2580880455,
25305     4044899811, 1601229938, 1991794816, 3637571857, 623446372, 2336332021, 2726898695, 216120726,
25306     2181814956, 744704829, 95158223, 2881711710, 1446680107, 4166125498, 3516576584, 2146575065,
25307     780072698, 2148951915, 2849952665, 129384968, 4199529085, 1411853292, 2112855838, 3548843663,
25308     1567451573, 4077254692, 3670887638, 1957027143, 2304517426, 657765539, 251396177, 2694091200,
25309     3361327204, 1714510325, 1341779207, 3784408214, 476611811, 2986349938, 2613617024, 899690513,
25310     3142211371, 354600634, 1021997640, 2458051545, 1870338988, 3239283261, 3906682575, 1186180958,
25311     960597383, 2536053782, 3202459876, 277428597, 3983589632, 1125666961, 1792074851, 3300423154,
25312     1246892744, 3829039961, 3455203243, 1671079482, 2657312335, 806080478, 432241452, 3081497277,
25313     3748049689, 1896751752, 1489409658, 4138600427, 190316446, 2772397583, 2365053693, 580864876,
25314     2893360214, 35503559, 735381813, 2243795108, 2017747153, 3593269568, 4293150130, 1368183843,
25315     1560145396, 4069882981, 3680356503, 1966430470, 2295112051, 648294626, 258769936, 2701399425,
25316     804156091, 2173100842, 2823706584, 103204425, 4225711676, 1438101421, 2088704863, 3524758222,
25317     3134903146, 347226875, 1031468553, 2467456920, 1860935661, 3229814396, 3914054286, 1193487135,
25318     3385412645, 1738661300, 1315531078, 3758225623, 502792354, 3012596019, 2589468097, 875607120,
25319     1271043721, 3853125400, 3429020650, 1644831355, 2683558414, 832261023, 408158061, 3057348348,
25320     953223622, 2528745559, 3211865253, 286899508, 3974120769, 1116263632, 1799381026, 3307794867,
25321     2917509143, 59586950, 709201268, 2217549029, 2043995280, 3619452161, 4269064691, 1344032866,
25322     3740677976, 1889445577, 1498812987, 4148069290, 180845535, 2762992206, 2372361916, 588238637,
25323     1921194766, 3706423967, 4112727661, 1531686908, 2796705673, 148555288, 554857194, 2407195515,
25324     26248257, 2952271312, 2251333922, 676868275, 3584149702, 2076793175, 1375858085, 4234771508,
25325     2493785488, 986493953, 319029491, 3178008930, 1083533591, 4009621638, 3342158964, 1767759333,
25326     3887577823, 1239362382, 1612160956, 3464433197, 864482904, 2649647049, 3022443323, 441336490,
25327     1706844275, 3419730402, 3793503504, 1282724993, 2978819316, 535149925, 908921239, 2554697734,
25328     380632892, 3100077741, 2433735263, 1063734222, 3265180603, 1828069930, 1161729752, 3948283721,
25329     2207997677, 770953084, 71007118, 2857626143, 1470763626, 4190274555, 3490330377, 2120394392,
25330     4035494306, 1591758899, 1999168705, 3644880208, 616140069, 2328960180, 2736367686, 225524183,
25331   },
25332 };
25333 
25334 static const uint8_t
25335 WUFFS_CRC32__IEEE_X86_SSE42_K1K2[16] WUFFS_BASE__POTENTIALLY_UNUSED = {
25336   212, 43, 68, 84, 1, 0, 0, 0,
25337   150, 21, 228, 198, 1, 0, 0, 0,
25338 };
25339 
25340 static const uint8_t
25341 WUFFS_CRC32__IEEE_X86_SSE42_K3K4[16] WUFFS_BASE__POTENTIALLY_UNUSED = {
25342   208, 151, 25, 117, 1, 0, 0, 0,
25343   158, 0, 170, 204, 0, 0, 0, 0,
25344 };
25345 
25346 static const uint8_t
25347 WUFFS_CRC32__IEEE_X86_SSE42_K5ZZ[16] WUFFS_BASE__POTENTIALLY_UNUSED = {
25348   36, 97, 205, 99, 1, 0, 0, 0,
25349   0, 0, 0, 0, 0, 0, 0, 0,
25350 };
25351 
25352 static const uint8_t
25353 WUFFS_CRC32__IEEE_X86_SSE42_PXMU[16] WUFFS_BASE__POTENTIALLY_UNUSED = {
25354   65, 6, 113, 219, 1, 0, 0, 0,
25355   65, 22, 1, 247, 1, 0, 0, 0,
25356 };
25357 
25358 // ---------------- Private Initializer Prototypes
25359 
25360 // ---------------- Private Function Prototypes
25361 
25362 static wuffs_base__empty_struct
25363 wuffs_crc32__ieee_hasher__up(
25364     wuffs_crc32__ieee_hasher* self,
25365     wuffs_base__slice_u8 a_x);
25366 
25367 static wuffs_base__empty_struct
25368 wuffs_crc32__ieee_hasher__up__choosy_default(
25369     wuffs_crc32__ieee_hasher* self,
25370     wuffs_base__slice_u8 a_x);
25371 
25372 #if defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32)
25373 static wuffs_base__empty_struct
25374 wuffs_crc32__ieee_hasher__up_arm_crc32(
25375     wuffs_crc32__ieee_hasher* self,
25376     wuffs_base__slice_u8 a_x);
25377 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32)
25378 
25379 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
25380 static wuffs_base__empty_struct
25381 wuffs_crc32__ieee_hasher__up_x86_avx2(
25382     wuffs_crc32__ieee_hasher* self,
25383     wuffs_base__slice_u8 a_x);
25384 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
25385 
25386 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
25387 static wuffs_base__empty_struct
25388 wuffs_crc32__ieee_hasher__up_x86_sse42(
25389     wuffs_crc32__ieee_hasher* self,
25390     wuffs_base__slice_u8 a_x);
25391 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
25392 
25393 // ---------------- VTables
25394 
25395 const wuffs_base__hasher_u32__func_ptrs
25396 wuffs_crc32__ieee_hasher__func_ptrs_for__wuffs_base__hasher_u32 = {
25397   (wuffs_base__empty_struct(*)(void*,
25398       uint32_t,
25399       bool))(&wuffs_crc32__ieee_hasher__set_quirk_enabled),
25400   (uint32_t(*)(void*,
25401       wuffs_base__slice_u8))(&wuffs_crc32__ieee_hasher__update_u32),
25402 };
25403 
25404 // ---------------- Initializer Implementations
25405 
25406 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)25407 wuffs_crc32__ieee_hasher__initialize(
25408     wuffs_crc32__ieee_hasher* self,
25409     size_t sizeof_star_self,
25410     uint64_t wuffs_version,
25411     uint32_t options){
25412   if (!self) {
25413     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
25414   }
25415   if (sizeof(*self) != sizeof_star_self) {
25416     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
25417   }
25418   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
25419       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
25420     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
25421   }
25422 
25423   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
25424     // The whole point of this if-check is to detect an uninitialized *self.
25425     // We disable the warning on GCC. Clang-5.0 does not have this warning.
25426 #if !defined(__clang__) && defined(__GNUC__)
25427 #pragma GCC diagnostic push
25428 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
25429 #endif
25430     if (self->private_impl.magic != 0) {
25431       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
25432     }
25433 #if !defined(__clang__) && defined(__GNUC__)
25434 #pragma GCC diagnostic pop
25435 #endif
25436   } else {
25437     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
25438       memset(self, 0, sizeof(*self));
25439       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
25440     } else {
25441       memset(&(self->private_impl), 0, sizeof(self->private_impl));
25442     }
25443   }
25444 
25445   self->private_impl.choosy_up = &wuffs_crc32__ieee_hasher__up__choosy_default;
25446 
25447   self->private_impl.magic = WUFFS_BASE__MAGIC;
25448   self->private_impl.vtable_for__wuffs_base__hasher_u32.vtable_name =
25449       wuffs_base__hasher_u32__vtable_name;
25450   self->private_impl.vtable_for__wuffs_base__hasher_u32.function_pointers =
25451       (const void*)(&wuffs_crc32__ieee_hasher__func_ptrs_for__wuffs_base__hasher_u32);
25452   return wuffs_base__make_status(NULL);
25453 }
25454 
25455 wuffs_crc32__ieee_hasher*
wuffs_crc32__ieee_hasher__alloc()25456 wuffs_crc32__ieee_hasher__alloc() {
25457   wuffs_crc32__ieee_hasher* x =
25458       (wuffs_crc32__ieee_hasher*)(calloc(sizeof(wuffs_crc32__ieee_hasher), 1));
25459   if (!x) {
25460     return NULL;
25461   }
25462   if (wuffs_crc32__ieee_hasher__initialize(
25463       x, sizeof(wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
25464     free(x);
25465     return NULL;
25466   }
25467   return x;
25468 }
25469 
25470 size_t
sizeof__wuffs_crc32__ieee_hasher()25471 sizeof__wuffs_crc32__ieee_hasher() {
25472   return sizeof(wuffs_crc32__ieee_hasher);
25473 }
25474 
25475 // ---------------- Function Implementations
25476 
25477 // -------- func crc32.ieee_hasher.set_quirk_enabled
25478 
25479 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_crc32__ieee_hasher__set_quirk_enabled(wuffs_crc32__ieee_hasher * self,uint32_t a_quirk,bool a_enabled)25480 wuffs_crc32__ieee_hasher__set_quirk_enabled(
25481     wuffs_crc32__ieee_hasher* self,
25482     uint32_t a_quirk,
25483     bool a_enabled) {
25484   return wuffs_base__make_empty_struct();
25485 }
25486 
25487 // -------- func crc32.ieee_hasher.update_u32
25488 
25489 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_crc32__ieee_hasher__update_u32(wuffs_crc32__ieee_hasher * self,wuffs_base__slice_u8 a_x)25490 wuffs_crc32__ieee_hasher__update_u32(
25491     wuffs_crc32__ieee_hasher* self,
25492     wuffs_base__slice_u8 a_x) {
25493   if (!self) {
25494     return 0;
25495   }
25496   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
25497     return 0;
25498   }
25499 
25500   if (self->private_impl.f_state == 0) {
25501     self->private_impl.choosy_up = (
25502 #if defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32)
25503         wuffs_base__cpu_arch__have_arm_crc32() ? &wuffs_crc32__ieee_hasher__up_arm_crc32 :
25504 #endif
25505 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
25506         wuffs_base__cpu_arch__have_x86_avx2() ? &wuffs_crc32__ieee_hasher__up_x86_avx2 :
25507 #endif
25508 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
25509         wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_crc32__ieee_hasher__up_x86_sse42 :
25510 #endif
25511         self->private_impl.choosy_up);
25512   }
25513   wuffs_crc32__ieee_hasher__up(self, a_x);
25514   return self->private_impl.f_state;
25515 }
25516 
25517 // -------- func crc32.ieee_hasher.up
25518 
25519 static wuffs_base__empty_struct
wuffs_crc32__ieee_hasher__up(wuffs_crc32__ieee_hasher * self,wuffs_base__slice_u8 a_x)25520 wuffs_crc32__ieee_hasher__up(
25521     wuffs_crc32__ieee_hasher* self,
25522     wuffs_base__slice_u8 a_x) {
25523   return (*self->private_impl.choosy_up)(self, a_x);
25524 }
25525 
25526 static wuffs_base__empty_struct
wuffs_crc32__ieee_hasher__up__choosy_default(wuffs_crc32__ieee_hasher * self,wuffs_base__slice_u8 a_x)25527 wuffs_crc32__ieee_hasher__up__choosy_default(
25528     wuffs_crc32__ieee_hasher* self,
25529     wuffs_base__slice_u8 a_x) {
25530   uint32_t v_s = 0;
25531   wuffs_base__slice_u8 v_p = {0};
25532 
25533   v_s = (4294967295 ^ self->private_impl.f_state);
25534   {
25535     wuffs_base__slice_u8 i_slice_p = a_x;
25536     v_p.ptr = i_slice_p.ptr;
25537     v_p.len = 16;
25538     uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 32) * 32);
25539     while (v_p.ptr < i_end0_p) {
25540       v_s ^= ((((uint32_t)(v_p.ptr[0])) << 0) |
25541           (((uint32_t)(v_p.ptr[1])) << 8) |
25542           (((uint32_t)(v_p.ptr[2])) << 16) |
25543           (((uint32_t)(v_p.ptr[3])) << 24));
25544       v_s = (WUFFS_CRC32__IEEE_TABLE[0][v_p.ptr[15]] ^
25545           WUFFS_CRC32__IEEE_TABLE[1][v_p.ptr[14]] ^
25546           WUFFS_CRC32__IEEE_TABLE[2][v_p.ptr[13]] ^
25547           WUFFS_CRC32__IEEE_TABLE[3][v_p.ptr[12]] ^
25548           WUFFS_CRC32__IEEE_TABLE[4][v_p.ptr[11]] ^
25549           WUFFS_CRC32__IEEE_TABLE[5][v_p.ptr[10]] ^
25550           WUFFS_CRC32__IEEE_TABLE[6][v_p.ptr[9]] ^
25551           WUFFS_CRC32__IEEE_TABLE[7][v_p.ptr[8]] ^
25552           WUFFS_CRC32__IEEE_TABLE[8][v_p.ptr[7]] ^
25553           WUFFS_CRC32__IEEE_TABLE[9][v_p.ptr[6]] ^
25554           WUFFS_CRC32__IEEE_TABLE[10][v_p.ptr[5]] ^
25555           WUFFS_CRC32__IEEE_TABLE[11][v_p.ptr[4]] ^
25556           WUFFS_CRC32__IEEE_TABLE[12][(255 & (v_s >> 24))] ^
25557           WUFFS_CRC32__IEEE_TABLE[13][(255 & (v_s >> 16))] ^
25558           WUFFS_CRC32__IEEE_TABLE[14][(255 & (v_s >> 8))] ^
25559           WUFFS_CRC32__IEEE_TABLE[15][(255 & (v_s >> 0))]);
25560       v_p.ptr += 16;
25561       v_s ^= ((((uint32_t)(v_p.ptr[0])) << 0) |
25562           (((uint32_t)(v_p.ptr[1])) << 8) |
25563           (((uint32_t)(v_p.ptr[2])) << 16) |
25564           (((uint32_t)(v_p.ptr[3])) << 24));
25565       v_s = (WUFFS_CRC32__IEEE_TABLE[0][v_p.ptr[15]] ^
25566           WUFFS_CRC32__IEEE_TABLE[1][v_p.ptr[14]] ^
25567           WUFFS_CRC32__IEEE_TABLE[2][v_p.ptr[13]] ^
25568           WUFFS_CRC32__IEEE_TABLE[3][v_p.ptr[12]] ^
25569           WUFFS_CRC32__IEEE_TABLE[4][v_p.ptr[11]] ^
25570           WUFFS_CRC32__IEEE_TABLE[5][v_p.ptr[10]] ^
25571           WUFFS_CRC32__IEEE_TABLE[6][v_p.ptr[9]] ^
25572           WUFFS_CRC32__IEEE_TABLE[7][v_p.ptr[8]] ^
25573           WUFFS_CRC32__IEEE_TABLE[8][v_p.ptr[7]] ^
25574           WUFFS_CRC32__IEEE_TABLE[9][v_p.ptr[6]] ^
25575           WUFFS_CRC32__IEEE_TABLE[10][v_p.ptr[5]] ^
25576           WUFFS_CRC32__IEEE_TABLE[11][v_p.ptr[4]] ^
25577           WUFFS_CRC32__IEEE_TABLE[12][(255 & (v_s >> 24))] ^
25578           WUFFS_CRC32__IEEE_TABLE[13][(255 & (v_s >> 16))] ^
25579           WUFFS_CRC32__IEEE_TABLE[14][(255 & (v_s >> 8))] ^
25580           WUFFS_CRC32__IEEE_TABLE[15][(255 & (v_s >> 0))]);
25581       v_p.ptr += 16;
25582     }
25583     v_p.len = 16;
25584     uint8_t* i_end1_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 16) * 16);
25585     while (v_p.ptr < i_end1_p) {
25586       v_s ^= ((((uint32_t)(v_p.ptr[0])) << 0) |
25587           (((uint32_t)(v_p.ptr[1])) << 8) |
25588           (((uint32_t)(v_p.ptr[2])) << 16) |
25589           (((uint32_t)(v_p.ptr[3])) << 24));
25590       v_s = (WUFFS_CRC32__IEEE_TABLE[0][v_p.ptr[15]] ^
25591           WUFFS_CRC32__IEEE_TABLE[1][v_p.ptr[14]] ^
25592           WUFFS_CRC32__IEEE_TABLE[2][v_p.ptr[13]] ^
25593           WUFFS_CRC32__IEEE_TABLE[3][v_p.ptr[12]] ^
25594           WUFFS_CRC32__IEEE_TABLE[4][v_p.ptr[11]] ^
25595           WUFFS_CRC32__IEEE_TABLE[5][v_p.ptr[10]] ^
25596           WUFFS_CRC32__IEEE_TABLE[6][v_p.ptr[9]] ^
25597           WUFFS_CRC32__IEEE_TABLE[7][v_p.ptr[8]] ^
25598           WUFFS_CRC32__IEEE_TABLE[8][v_p.ptr[7]] ^
25599           WUFFS_CRC32__IEEE_TABLE[9][v_p.ptr[6]] ^
25600           WUFFS_CRC32__IEEE_TABLE[10][v_p.ptr[5]] ^
25601           WUFFS_CRC32__IEEE_TABLE[11][v_p.ptr[4]] ^
25602           WUFFS_CRC32__IEEE_TABLE[12][(255 & (v_s >> 24))] ^
25603           WUFFS_CRC32__IEEE_TABLE[13][(255 & (v_s >> 16))] ^
25604           WUFFS_CRC32__IEEE_TABLE[14][(255 & (v_s >> 8))] ^
25605           WUFFS_CRC32__IEEE_TABLE[15][(255 & (v_s >> 0))]);
25606       v_p.ptr += 16;
25607     }
25608     v_p.len = 1;
25609     uint8_t* i_end2_p = i_slice_p.ptr + i_slice_p.len;
25610     while (v_p.ptr < i_end2_p) {
25611       v_s = (WUFFS_CRC32__IEEE_TABLE[0][(((uint8_t)((v_s & 255))) ^ v_p.ptr[0])] ^ (v_s >> 8));
25612       v_p.ptr += 1;
25613     }
25614     v_p.len = 0;
25615   }
25616   self->private_impl.f_state = (4294967295 ^ v_s);
25617   return wuffs_base__make_empty_struct();
25618 }
25619 
25620 // ‼ WUFFS MULTI-FILE SECTION +arm_crc32
25621 // -------- func crc32.ieee_hasher.up_arm_crc32
25622 
25623 #if defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32)
25624 static wuffs_base__empty_struct
wuffs_crc32__ieee_hasher__up_arm_crc32(wuffs_crc32__ieee_hasher * self,wuffs_base__slice_u8 a_x)25625 wuffs_crc32__ieee_hasher__up_arm_crc32(
25626     wuffs_crc32__ieee_hasher* self,
25627     wuffs_base__slice_u8 a_x) {
25628   wuffs_base__slice_u8 v_p = {0};
25629   uint32_t v_s = 0;
25630 
25631   v_s = (4294967295 ^ self->private_impl.f_state);
25632   while ((((uint64_t)(a_x.len)) > 0) && ((15 & ((uint32_t)(0xFFF & (uintptr_t)(a_x.ptr)))) != 0)) {
25633     v_s = __crc32b(v_s, a_x.ptr[0]);
25634     a_x = wuffs_base__slice_u8__subslice_i(a_x, 1);
25635   }
25636   {
25637     wuffs_base__slice_u8 i_slice_p = a_x;
25638     v_p.ptr = i_slice_p.ptr;
25639     v_p.len = 8;
25640     uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 128) * 128);
25641     while (v_p.ptr < i_end0_p) {
25642       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
25643       v_p.ptr += 8;
25644       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
25645       v_p.ptr += 8;
25646       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
25647       v_p.ptr += 8;
25648       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
25649       v_p.ptr += 8;
25650       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
25651       v_p.ptr += 8;
25652       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
25653       v_p.ptr += 8;
25654       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
25655       v_p.ptr += 8;
25656       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
25657       v_p.ptr += 8;
25658       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
25659       v_p.ptr += 8;
25660       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
25661       v_p.ptr += 8;
25662       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
25663       v_p.ptr += 8;
25664       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
25665       v_p.ptr += 8;
25666       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
25667       v_p.ptr += 8;
25668       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
25669       v_p.ptr += 8;
25670       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
25671       v_p.ptr += 8;
25672       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
25673       v_p.ptr += 8;
25674     }
25675     v_p.len = 8;
25676     uint8_t* i_end1_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 8) * 8);
25677     while (v_p.ptr < i_end1_p) {
25678       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
25679       v_p.ptr += 8;
25680     }
25681     v_p.len = 1;
25682     uint8_t* i_end2_p = i_slice_p.ptr + i_slice_p.len;
25683     while (v_p.ptr < i_end2_p) {
25684       v_s = __crc32b(v_s, v_p.ptr[0]);
25685       v_p.ptr += 1;
25686     }
25687     v_p.len = 0;
25688   }
25689   self->private_impl.f_state = (4294967295 ^ v_s);
25690   return wuffs_base__make_empty_struct();
25691 }
25692 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32)
25693 // ‼ WUFFS MULTI-FILE SECTION -arm_crc32
25694 
25695 // ‼ WUFFS MULTI-FILE SECTION +x86_avx2
25696 // -------- func crc32.ieee_hasher.up_x86_avx2
25697 
25698 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
25699 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2")
25700 static wuffs_base__empty_struct
wuffs_crc32__ieee_hasher__up_x86_avx2(wuffs_crc32__ieee_hasher * self,wuffs_base__slice_u8 a_x)25701 wuffs_crc32__ieee_hasher__up_x86_avx2(
25702     wuffs_crc32__ieee_hasher* self,
25703     wuffs_base__slice_u8 a_x) {
25704   uint32_t v_s = 0;
25705   wuffs_base__slice_u8 v_p = {0};
25706   __m128i v_k = {0};
25707   __m128i v_x0 = {0};
25708   __m128i v_x1 = {0};
25709   __m128i v_x2 = {0};
25710   __m128i v_x3 = {0};
25711   __m128i v_y0 = {0};
25712   __m128i v_y1 = {0};
25713   __m128i v_y2 = {0};
25714   __m128i v_y3 = {0};
25715   uint64_t v_tail_index = 0;
25716 
25717   v_s = (4294967295 ^ self->private_impl.f_state);
25718   while ((((uint64_t)(a_x.len)) > 0) && ((15 & ((uint32_t)(0xFFF & (uintptr_t)(a_x.ptr)))) != 0)) {
25719     v_s = (WUFFS_CRC32__IEEE_TABLE[0][(((uint8_t)((v_s & 255))) ^ a_x.ptr[0])] ^ (v_s >> 8));
25720     a_x = wuffs_base__slice_u8__subslice_i(a_x, 1);
25721   }
25722   if (((uint64_t)(a_x.len)) < 64) {
25723     {
25724       wuffs_base__slice_u8 i_slice_p = a_x;
25725       v_p.ptr = i_slice_p.ptr;
25726       v_p.len = 1;
25727       uint8_t* i_end0_p = i_slice_p.ptr + i_slice_p.len;
25728       while (v_p.ptr < i_end0_p) {
25729         v_s = (WUFFS_CRC32__IEEE_TABLE[0][(((uint8_t)((v_s & 255))) ^ v_p.ptr[0])] ^ (v_s >> 8));
25730         v_p.ptr += 1;
25731       }
25732       v_p.len = 0;
25733     }
25734     self->private_impl.f_state = (4294967295 ^ v_s);
25735     return wuffs_base__make_empty_struct();
25736   }
25737   v_x0 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 0));
25738   v_x1 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 16));
25739   v_x2 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 32));
25740   v_x3 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 48));
25741   v_x0 = _mm_xor_si128(v_x0, _mm_cvtsi32_si128((int32_t)(v_s)));
25742   v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_K1K2));
25743   {
25744     wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, 64);
25745     v_p.ptr = i_slice_p.ptr;
25746     v_p.len = 64;
25747     uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 64) * 64);
25748     while (v_p.ptr < i_end0_p) {
25749       v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0));
25750       v_y1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(0));
25751       v_y2 = _mm_clmulepi64_si128(v_x2, v_k, (int32_t)(0));
25752       v_y3 = _mm_clmulepi64_si128(v_x3, v_k, (int32_t)(0));
25753       v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17));
25754       v_x1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(17));
25755       v_x2 = _mm_clmulepi64_si128(v_x2, v_k, (int32_t)(17));
25756       v_x3 = _mm_clmulepi64_si128(v_x3, v_k, (int32_t)(17));
25757       v_x0 = _mm_xor_si128(_mm_xor_si128(v_x0, v_y0), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 0)));
25758       v_x1 = _mm_xor_si128(_mm_xor_si128(v_x1, v_y1), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 16)));
25759       v_x2 = _mm_xor_si128(_mm_xor_si128(v_x2, v_y2), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 32)));
25760       v_x3 = _mm_xor_si128(_mm_xor_si128(v_x3, v_y3), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 48)));
25761       v_p.ptr += 64;
25762     }
25763     v_p.len = 0;
25764   }
25765   v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_K3K4));
25766   v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0));
25767   v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17));
25768   v_x0 = _mm_xor_si128(v_x0, v_x1);
25769   v_x0 = _mm_xor_si128(v_x0, v_y0);
25770   v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0));
25771   v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17));
25772   v_x0 = _mm_xor_si128(v_x0, v_x2);
25773   v_x0 = _mm_xor_si128(v_x0, v_y0);
25774   v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0));
25775   v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17));
25776   v_x0 = _mm_xor_si128(v_x0, v_x3);
25777   v_x0 = _mm_xor_si128(v_x0, v_y0);
25778   v_x1 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(16));
25779   v_x2 = _mm_set_epi32((int32_t)(0), (int32_t)(4294967295), (int32_t)(0), (int32_t)(4294967295));
25780   v_x0 = _mm_srli_si128(v_x0, (int32_t)(8));
25781   v_x0 = _mm_xor_si128(v_x0, v_x1);
25782   v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_K5ZZ));
25783   v_x1 = _mm_srli_si128(v_x0, (int32_t)(4));
25784   v_x0 = _mm_and_si128(v_x0, v_x2);
25785   v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0));
25786   v_x0 = _mm_xor_si128(v_x0, v_x1);
25787   v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_PXMU));
25788   v_x1 = _mm_and_si128(v_x0, v_x2);
25789   v_x1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(16));
25790   v_x1 = _mm_and_si128(v_x1, v_x2);
25791   v_x1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(0));
25792   v_x0 = _mm_xor_si128(v_x0, v_x1);
25793   v_s = ((uint32_t)(_mm_extract_epi32(v_x0, (int32_t)(1))));
25794   v_tail_index = (((uint64_t)(a_x.len)) & 18446744073709551552u);
25795   if (v_tail_index < ((uint64_t)(a_x.len))) {
25796     {
25797       wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, v_tail_index);
25798       v_p.ptr = i_slice_p.ptr;
25799       v_p.len = 1;
25800       uint8_t* i_end0_p = i_slice_p.ptr + i_slice_p.len;
25801       while (v_p.ptr < i_end0_p) {
25802         v_s = (WUFFS_CRC32__IEEE_TABLE[0][(((uint8_t)((v_s & 255))) ^ v_p.ptr[0])] ^ (v_s >> 8));
25803         v_p.ptr += 1;
25804       }
25805       v_p.len = 0;
25806     }
25807   }
25808   self->private_impl.f_state = (4294967295 ^ v_s);
25809   return wuffs_base__make_empty_struct();
25810 }
25811 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
25812 // ‼ WUFFS MULTI-FILE SECTION -x86_avx2
25813 
25814 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
25815 // -------- func crc32.ieee_hasher.up_x86_sse42
25816 
25817 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
25818 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
25819 static wuffs_base__empty_struct
wuffs_crc32__ieee_hasher__up_x86_sse42(wuffs_crc32__ieee_hasher * self,wuffs_base__slice_u8 a_x)25820 wuffs_crc32__ieee_hasher__up_x86_sse42(
25821     wuffs_crc32__ieee_hasher* self,
25822     wuffs_base__slice_u8 a_x) {
25823   uint32_t v_s = 0;
25824   wuffs_base__slice_u8 v_p = {0};
25825   __m128i v_k = {0};
25826   __m128i v_x0 = {0};
25827   __m128i v_x1 = {0};
25828   __m128i v_x2 = {0};
25829   __m128i v_x3 = {0};
25830   __m128i v_y0 = {0};
25831   __m128i v_y1 = {0};
25832   __m128i v_y2 = {0};
25833   __m128i v_y3 = {0};
25834   uint64_t v_tail_index = 0;
25835 
25836   v_s = (4294967295 ^ self->private_impl.f_state);
25837   while ((((uint64_t)(a_x.len)) > 0) && ((15 & ((uint32_t)(0xFFF & (uintptr_t)(a_x.ptr)))) != 0)) {
25838     v_s = (WUFFS_CRC32__IEEE_TABLE[0][(((uint8_t)((v_s & 255))) ^ a_x.ptr[0])] ^ (v_s >> 8));
25839     a_x = wuffs_base__slice_u8__subslice_i(a_x, 1);
25840   }
25841   if (((uint64_t)(a_x.len)) < 64) {
25842     {
25843       wuffs_base__slice_u8 i_slice_p = a_x;
25844       v_p.ptr = i_slice_p.ptr;
25845       v_p.len = 1;
25846       uint8_t* i_end0_p = i_slice_p.ptr + i_slice_p.len;
25847       while (v_p.ptr < i_end0_p) {
25848         v_s = (WUFFS_CRC32__IEEE_TABLE[0][(((uint8_t)((v_s & 255))) ^ v_p.ptr[0])] ^ (v_s >> 8));
25849         v_p.ptr += 1;
25850       }
25851       v_p.len = 0;
25852     }
25853     self->private_impl.f_state = (4294967295 ^ v_s);
25854     return wuffs_base__make_empty_struct();
25855   }
25856   v_x0 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 0));
25857   v_x1 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 16));
25858   v_x2 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 32));
25859   v_x3 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 48));
25860   v_x0 = _mm_xor_si128(v_x0, _mm_cvtsi32_si128((int32_t)(v_s)));
25861   v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_K1K2));
25862   {
25863     wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, 64);
25864     v_p.ptr = i_slice_p.ptr;
25865     v_p.len = 64;
25866     uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 64) * 64);
25867     while (v_p.ptr < i_end0_p) {
25868       v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0));
25869       v_y1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(0));
25870       v_y2 = _mm_clmulepi64_si128(v_x2, v_k, (int32_t)(0));
25871       v_y3 = _mm_clmulepi64_si128(v_x3, v_k, (int32_t)(0));
25872       v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17));
25873       v_x1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(17));
25874       v_x2 = _mm_clmulepi64_si128(v_x2, v_k, (int32_t)(17));
25875       v_x3 = _mm_clmulepi64_si128(v_x3, v_k, (int32_t)(17));
25876       v_x0 = _mm_xor_si128(_mm_xor_si128(v_x0, v_y0), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 0)));
25877       v_x1 = _mm_xor_si128(_mm_xor_si128(v_x1, v_y1), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 16)));
25878       v_x2 = _mm_xor_si128(_mm_xor_si128(v_x2, v_y2), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 32)));
25879       v_x3 = _mm_xor_si128(_mm_xor_si128(v_x3, v_y3), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 48)));
25880       v_p.ptr += 64;
25881     }
25882     v_p.len = 0;
25883   }
25884   v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_K3K4));
25885   v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0));
25886   v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17));
25887   v_x0 = _mm_xor_si128(v_x0, v_x1);
25888   v_x0 = _mm_xor_si128(v_x0, v_y0);
25889   v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0));
25890   v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17));
25891   v_x0 = _mm_xor_si128(v_x0, v_x2);
25892   v_x0 = _mm_xor_si128(v_x0, v_y0);
25893   v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0));
25894   v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17));
25895   v_x0 = _mm_xor_si128(v_x0, v_x3);
25896   v_x0 = _mm_xor_si128(v_x0, v_y0);
25897   v_x1 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(16));
25898   v_x2 = _mm_set_epi32((int32_t)(0), (int32_t)(4294967295), (int32_t)(0), (int32_t)(4294967295));
25899   v_x0 = _mm_srli_si128(v_x0, (int32_t)(8));
25900   v_x0 = _mm_xor_si128(v_x0, v_x1);
25901   v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_K5ZZ));
25902   v_x1 = _mm_srli_si128(v_x0, (int32_t)(4));
25903   v_x0 = _mm_and_si128(v_x0, v_x2);
25904   v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0));
25905   v_x0 = _mm_xor_si128(v_x0, v_x1);
25906   v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_PXMU));
25907   v_x1 = _mm_and_si128(v_x0, v_x2);
25908   v_x1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(16));
25909   v_x1 = _mm_and_si128(v_x1, v_x2);
25910   v_x1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(0));
25911   v_x0 = _mm_xor_si128(v_x0, v_x1);
25912   v_s = ((uint32_t)(_mm_extract_epi32(v_x0, (int32_t)(1))));
25913   v_tail_index = (((uint64_t)(a_x.len)) & 18446744073709551552u);
25914   if (v_tail_index < ((uint64_t)(a_x.len))) {
25915     {
25916       wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, v_tail_index);
25917       v_p.ptr = i_slice_p.ptr;
25918       v_p.len = 1;
25919       uint8_t* i_end0_p = i_slice_p.ptr + i_slice_p.len;
25920       while (v_p.ptr < i_end0_p) {
25921         v_s = (WUFFS_CRC32__IEEE_TABLE[0][(((uint8_t)((v_s & 255))) ^ v_p.ptr[0])] ^ (v_s >> 8));
25922         v_p.ptr += 1;
25923       }
25924       v_p.len = 0;
25925     }
25926   }
25927   self->private_impl.f_state = (4294967295 ^ v_s);
25928   return wuffs_base__make_empty_struct();
25929 }
25930 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
25931 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
25932 
25933 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CRC32)
25934 
25935 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__DEFLATE)
25936 
25937 // ---------------- Status Codes Implementations
25938 
25939 const char wuffs_deflate__error__bad_huffman_code_over_subscribed[] = "#deflate: bad Huffman code (over-subscribed)";
25940 const char wuffs_deflate__error__bad_huffman_code_under_subscribed[] = "#deflate: bad Huffman code (under-subscribed)";
25941 const char wuffs_deflate__error__bad_huffman_code_length_count[] = "#deflate: bad Huffman code length count";
25942 const char wuffs_deflate__error__bad_huffman_code_length_repetition[] = "#deflate: bad Huffman code length repetition";
25943 const char wuffs_deflate__error__bad_huffman_code[] = "#deflate: bad Huffman code";
25944 const char wuffs_deflate__error__bad_huffman_minimum_code_length[] = "#deflate: bad Huffman minimum code length";
25945 const char wuffs_deflate__error__bad_block[] = "#deflate: bad block";
25946 const char wuffs_deflate__error__bad_distance[] = "#deflate: bad distance";
25947 const char wuffs_deflate__error__bad_distance_code_count[] = "#deflate: bad distance code count";
25948 const char wuffs_deflate__error__bad_literal_length_code_count[] = "#deflate: bad literal/length code count";
25949 const char wuffs_deflate__error__inconsistent_stored_block_length[] = "#deflate: inconsistent stored block length";
25950 const char wuffs_deflate__error__missing_end_of_block_code[] = "#deflate: missing end-of-block code";
25951 const char wuffs_deflate__error__no_huffman_codes[] = "#deflate: no Huffman codes";
25952 const char wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state[] = "#deflate: internal error: inconsistent Huffman decoder state";
25953 const char wuffs_deflate__error__internal_error_inconsistent_i_o[] = "#deflate: internal error: inconsistent I/O";
25954 const char wuffs_deflate__error__internal_error_inconsistent_distance[] = "#deflate: internal error: inconsistent distance";
25955 const char wuffs_deflate__error__internal_error_inconsistent_n_bits[] = "#deflate: internal error: inconsistent n_bits";
25956 
25957 // ---------------- Private Consts
25958 
25959 static const uint8_t
25960 WUFFS_DEFLATE__CODE_ORDER[19] WUFFS_BASE__POTENTIALLY_UNUSED = {
25961   16, 17, 18, 0, 8, 7, 9, 6,
25962   10, 5, 11, 4, 12, 3, 13, 2,
25963   14, 1, 15,
25964 };
25965 
25966 static const uint8_t
25967 WUFFS_DEFLATE__REVERSE8[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
25968   0, 128, 64, 192, 32, 160, 96, 224,
25969   16, 144, 80, 208, 48, 176, 112, 240,
25970   8, 136, 72, 200, 40, 168, 104, 232,
25971   24, 152, 88, 216, 56, 184, 120, 248,
25972   4, 132, 68, 196, 36, 164, 100, 228,
25973   20, 148, 84, 212, 52, 180, 116, 244,
25974   12, 140, 76, 204, 44, 172, 108, 236,
25975   28, 156, 92, 220, 60, 188, 124, 252,
25976   2, 130, 66, 194, 34, 162, 98, 226,
25977   18, 146, 82, 210, 50, 178, 114, 242,
25978   10, 138, 74, 202, 42, 170, 106, 234,
25979   26, 154, 90, 218, 58, 186, 122, 250,
25980   6, 134, 70, 198, 38, 166, 102, 230,
25981   22, 150, 86, 214, 54, 182, 118, 246,
25982   14, 142, 78, 206, 46, 174, 110, 238,
25983   30, 158, 94, 222, 62, 190, 126, 254,
25984   1, 129, 65, 193, 33, 161, 97, 225,
25985   17, 145, 81, 209, 49, 177, 113, 241,
25986   9, 137, 73, 201, 41, 169, 105, 233,
25987   25, 153, 89, 217, 57, 185, 121, 249,
25988   5, 133, 69, 197, 37, 165, 101, 229,
25989   21, 149, 85, 213, 53, 181, 117, 245,
25990   13, 141, 77, 205, 45, 173, 109, 237,
25991   29, 157, 93, 221, 61, 189, 125, 253,
25992   3, 131, 67, 195, 35, 163, 99, 227,
25993   19, 147, 83, 211, 51, 179, 115, 243,
25994   11, 139, 75, 203, 43, 171, 107, 235,
25995   27, 155, 91, 219, 59, 187, 123, 251,
25996   7, 135, 71, 199, 39, 167, 103, 231,
25997   23, 151, 87, 215, 55, 183, 119, 247,
25998   15, 143, 79, 207, 47, 175, 111, 239,
25999   31, 159, 95, 223, 63, 191, 127, 255,
26000 };
26001 
26002 static const uint32_t
26003 WUFFS_DEFLATE__LCODE_MAGIC_NUMBERS[32] WUFFS_BASE__POTENTIALLY_UNUSED = {
26004   1073741824, 1073742080, 1073742336, 1073742592, 1073742848, 1073743104, 1073743360, 1073743616,
26005   1073743888, 1073744400, 1073744912, 1073745424, 1073745952, 1073746976, 1073748000, 1073749024,
26006   1073750064, 1073752112, 1073754160, 1073756208, 1073758272, 1073762368, 1073766464, 1073770560,
26007   1073774672, 1073782864, 1073791056, 1073799248, 1073807104, 134217728, 134217728, 134217728,
26008 };
26009 
26010 static const uint32_t
26011 WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[32] WUFFS_BASE__POTENTIALLY_UNUSED = {
26012   1073741824, 1073742080, 1073742336, 1073742592, 1073742864, 1073743376, 1073743904, 1073744928,
26013   1073745968, 1073748016, 1073750080, 1073754176, 1073758288, 1073766480, 1073774688, 1073791072,
26014   1073807472, 1073840240, 1073873024, 1073938560, 1074004112, 1074135184, 1074266272, 1074528416,
26015   1074790576, 1075314864, 1075839168, 1076887744, 1077936336, 1080033488, 134217728, 134217728,
26016 };
26017 
26018 #define WUFFS_DEFLATE__HUFFS_TABLE_SIZE 1024
26019 
26020 #define WUFFS_DEFLATE__HUFFS_TABLE_MASK 1023
26021 
26022 // ---------------- Private Initializer Prototypes
26023 
26024 // ---------------- Private Function Prototypes
26025 
26026 static wuffs_base__status
26027 wuffs_deflate__decoder__decode_blocks(
26028     wuffs_deflate__decoder* self,
26029     wuffs_base__io_buffer* a_dst,
26030     wuffs_base__io_buffer* a_src);
26031 
26032 static wuffs_base__status
26033 wuffs_deflate__decoder__decode_uncompressed(
26034     wuffs_deflate__decoder* self,
26035     wuffs_base__io_buffer* a_dst,
26036     wuffs_base__io_buffer* a_src);
26037 
26038 static wuffs_base__status
26039 wuffs_deflate__decoder__init_fixed_huffman(
26040     wuffs_deflate__decoder* self);
26041 
26042 static wuffs_base__status
26043 wuffs_deflate__decoder__init_dynamic_huffman(
26044     wuffs_deflate__decoder* self,
26045     wuffs_base__io_buffer* a_src);
26046 
26047 static wuffs_base__status
26048 wuffs_deflate__decoder__init_huff(
26049     wuffs_deflate__decoder* self,
26050     uint32_t a_which,
26051     uint32_t a_n_codes0,
26052     uint32_t a_n_codes1,
26053     uint32_t a_base_symbol);
26054 
26055 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
26056 static wuffs_base__status
26057 wuffs_deflate__decoder__decode_huffman_bmi2(
26058     wuffs_deflate__decoder* self,
26059     wuffs_base__io_buffer* a_dst,
26060     wuffs_base__io_buffer* a_src);
26061 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
26062 
26063 static wuffs_base__status
26064 wuffs_deflate__decoder__decode_huffman_fast32(
26065     wuffs_deflate__decoder* self,
26066     wuffs_base__io_buffer* a_dst,
26067     wuffs_base__io_buffer* a_src);
26068 
26069 static wuffs_base__status
26070 wuffs_deflate__decoder__decode_huffman_fast64(
26071     wuffs_deflate__decoder* self,
26072     wuffs_base__io_buffer* a_dst,
26073     wuffs_base__io_buffer* a_src);
26074 
26075 static wuffs_base__status
26076 wuffs_deflate__decoder__decode_huffman_fast64__choosy_default(
26077     wuffs_deflate__decoder* self,
26078     wuffs_base__io_buffer* a_dst,
26079     wuffs_base__io_buffer* a_src);
26080 
26081 static wuffs_base__status
26082 wuffs_deflate__decoder__decode_huffman_slow(
26083     wuffs_deflate__decoder* self,
26084     wuffs_base__io_buffer* a_dst,
26085     wuffs_base__io_buffer* a_src);
26086 
26087 // ---------------- VTables
26088 
26089 const wuffs_base__io_transformer__func_ptrs
26090 wuffs_deflate__decoder__func_ptrs_for__wuffs_base__io_transformer = {
26091   (wuffs_base__empty_struct(*)(void*,
26092       uint32_t,
26093       bool))(&wuffs_deflate__decoder__set_quirk_enabled),
26094   (wuffs_base__status(*)(void*,
26095       wuffs_base__io_buffer*,
26096       wuffs_base__io_buffer*,
26097       wuffs_base__slice_u8))(&wuffs_deflate__decoder__transform_io),
26098   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_deflate__decoder__workbuf_len),
26099 };
26100 
26101 // ---------------- Initializer Implementations
26102 
26103 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)26104 wuffs_deflate__decoder__initialize(
26105     wuffs_deflate__decoder* self,
26106     size_t sizeof_star_self,
26107     uint64_t wuffs_version,
26108     uint32_t options){
26109   if (!self) {
26110     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
26111   }
26112   if (sizeof(*self) != sizeof_star_self) {
26113     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
26114   }
26115   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
26116       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
26117     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
26118   }
26119 
26120   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
26121     // The whole point of this if-check is to detect an uninitialized *self.
26122     // We disable the warning on GCC. Clang-5.0 does not have this warning.
26123 #if !defined(__clang__) && defined(__GNUC__)
26124 #pragma GCC diagnostic push
26125 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
26126 #endif
26127     if (self->private_impl.magic != 0) {
26128       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
26129     }
26130 #if !defined(__clang__) && defined(__GNUC__)
26131 #pragma GCC diagnostic pop
26132 #endif
26133   } else {
26134     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
26135       memset(self, 0, sizeof(*self));
26136       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
26137     } else {
26138       memset(&(self->private_impl), 0, sizeof(self->private_impl));
26139     }
26140   }
26141 
26142   self->private_impl.choosy_decode_huffman_fast64 = &wuffs_deflate__decoder__decode_huffman_fast64__choosy_default;
26143 
26144   self->private_impl.magic = WUFFS_BASE__MAGIC;
26145   self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name =
26146       wuffs_base__io_transformer__vtable_name;
26147   self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers =
26148       (const void*)(&wuffs_deflate__decoder__func_ptrs_for__wuffs_base__io_transformer);
26149   return wuffs_base__make_status(NULL);
26150 }
26151 
26152 wuffs_deflate__decoder*
wuffs_deflate__decoder__alloc()26153 wuffs_deflate__decoder__alloc() {
26154   wuffs_deflate__decoder* x =
26155       (wuffs_deflate__decoder*)(calloc(sizeof(wuffs_deflate__decoder), 1));
26156   if (!x) {
26157     return NULL;
26158   }
26159   if (wuffs_deflate__decoder__initialize(
26160       x, sizeof(wuffs_deflate__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
26161     free(x);
26162     return NULL;
26163   }
26164   return x;
26165 }
26166 
26167 size_t
sizeof__wuffs_deflate__decoder()26168 sizeof__wuffs_deflate__decoder() {
26169   return sizeof(wuffs_deflate__decoder);
26170 }
26171 
26172 // ---------------- Function Implementations
26173 
26174 // -------- func deflate.decoder.add_history
26175 
26176 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_deflate__decoder__add_history(wuffs_deflate__decoder * self,wuffs_base__slice_u8 a_hist)26177 wuffs_deflate__decoder__add_history(
26178     wuffs_deflate__decoder* self,
26179     wuffs_base__slice_u8 a_hist) {
26180   if (!self) {
26181     return wuffs_base__make_empty_struct();
26182   }
26183   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
26184     return wuffs_base__make_empty_struct();
26185   }
26186 
26187   wuffs_base__slice_u8 v_s = {0};
26188   uint64_t v_n_copied = 0;
26189   uint32_t v_already_full = 0;
26190 
26191   v_s = a_hist;
26192   if (((uint64_t)(v_s.len)) >= 32768) {
26193     v_s = wuffs_base__slice_u8__suffix(v_s, 32768);
26194     wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8(self->private_data.f_history, 32768), v_s);
26195     self->private_impl.f_history_index = 32768;
26196   } else {
26197     v_n_copied = wuffs_base__slice_u8__copy_from_slice(wuffs_base__slice_u8__subslice_i(wuffs_base__make_slice_u8(self->private_data.f_history, 32768), (self->private_impl.f_history_index & 32767)), v_s);
26198     if (v_n_copied < ((uint64_t)(v_s.len))) {
26199       v_s = wuffs_base__slice_u8__subslice_i(v_s, v_n_copied);
26200       v_n_copied = wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8(self->private_data.f_history, 32768), v_s);
26201       self->private_impl.f_history_index = (((uint32_t)((v_n_copied & 32767))) + 32768);
26202     } else {
26203       v_already_full = 0;
26204       if (self->private_impl.f_history_index >= 32768) {
26205         v_already_full = 32768;
26206       }
26207       self->private_impl.f_history_index = ((self->private_impl.f_history_index & 32767) + ((uint32_t)((v_n_copied & 32767))) + v_already_full);
26208     }
26209   }
26210   wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8((self->private_data.f_history) + 32768, 257), wuffs_base__make_slice_u8(self->private_data.f_history, 33025));
26211   return wuffs_base__make_empty_struct();
26212 }
26213 
26214 // -------- func deflate.decoder.set_quirk_enabled
26215 
26216 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_deflate__decoder__set_quirk_enabled(wuffs_deflate__decoder * self,uint32_t a_quirk,bool a_enabled)26217 wuffs_deflate__decoder__set_quirk_enabled(
26218     wuffs_deflate__decoder* self,
26219     uint32_t a_quirk,
26220     bool a_enabled) {
26221   return wuffs_base__make_empty_struct();
26222 }
26223 
26224 // -------- func deflate.decoder.workbuf_len
26225 
26226 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_deflate__decoder__workbuf_len(const wuffs_deflate__decoder * self)26227 wuffs_deflate__decoder__workbuf_len(
26228     const wuffs_deflate__decoder* self) {
26229   if (!self) {
26230     return wuffs_base__utility__empty_range_ii_u64();
26231   }
26232   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
26233       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
26234     return wuffs_base__utility__empty_range_ii_u64();
26235   }
26236 
26237   return wuffs_base__utility__make_range_ii_u64(1, 1);
26238 }
26239 
26240 // -------- func deflate.decoder.transform_io
26241 
26242 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)26243 wuffs_deflate__decoder__transform_io(
26244     wuffs_deflate__decoder* self,
26245     wuffs_base__io_buffer* a_dst,
26246     wuffs_base__io_buffer* a_src,
26247     wuffs_base__slice_u8 a_workbuf) {
26248   if (!self) {
26249     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
26250   }
26251   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
26252     return wuffs_base__make_status(
26253         (self->private_impl.magic == WUFFS_BASE__DISABLED)
26254         ? wuffs_base__error__disabled_by_previous_error
26255         : wuffs_base__error__initialize_not_called);
26256   }
26257   if (!a_dst || !a_src) {
26258     self->private_impl.magic = WUFFS_BASE__DISABLED;
26259     return wuffs_base__make_status(wuffs_base__error__bad_argument);
26260   }
26261   if ((self->private_impl.active_coroutine != 0) &&
26262       (self->private_impl.active_coroutine != 1)) {
26263     self->private_impl.magic = WUFFS_BASE__DISABLED;
26264     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
26265   }
26266   self->private_impl.active_coroutine = 0;
26267   wuffs_base__status status = wuffs_base__make_status(NULL);
26268 
26269   uint64_t v_mark = 0;
26270   wuffs_base__status v_status = wuffs_base__make_status(NULL);
26271 
26272   uint8_t* iop_a_dst = NULL;
26273   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
26274   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
26275   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
26276   if (a_dst) {
26277     io0_a_dst = a_dst->data.ptr;
26278     io1_a_dst = io0_a_dst + a_dst->meta.wi;
26279     iop_a_dst = io1_a_dst;
26280     io2_a_dst = io0_a_dst + a_dst->data.len;
26281     if (a_dst->meta.closed) {
26282       io2_a_dst = iop_a_dst;
26283     }
26284   }
26285 
26286   uint32_t coro_susp_point = self->private_impl.p_transform_io[0];
26287   switch (coro_susp_point) {
26288     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
26289 
26290     self->private_impl.choosy_decode_huffman_fast64 = (
26291 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
26292         wuffs_base__cpu_arch__have_x86_bmi2() ? &wuffs_deflate__decoder__decode_huffman_bmi2 :
26293 #endif
26294         self->private_impl.choosy_decode_huffman_fast64);
26295     while (true) {
26296       v_mark = ((uint64_t)(iop_a_dst - io0_a_dst));
26297       {
26298         if (a_dst) {
26299           a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
26300         }
26301         wuffs_base__status t_0 = wuffs_deflate__decoder__decode_blocks(self, a_dst, a_src);
26302         v_status = t_0;
26303         if (a_dst) {
26304           iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
26305         }
26306       }
26307       if ( ! wuffs_base__status__is_suspension(&v_status)) {
26308         status = v_status;
26309         if (wuffs_base__status__is_error(&status)) {
26310           goto exit;
26311         } else if (wuffs_base__status__is_suspension(&status)) {
26312           status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
26313           goto exit;
26314         }
26315         goto ok;
26316       }
26317       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))));
26318       wuffs_deflate__decoder__add_history(self, wuffs_base__io__since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst));
26319       status = v_status;
26320       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
26321     }
26322 
26323     ok:
26324     self->private_impl.p_transform_io[0] = 0;
26325     goto exit;
26326   }
26327 
26328   goto suspend;
26329   suspend:
26330   self->private_impl.p_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
26331   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
26332 
26333   goto exit;
26334   exit:
26335   if (a_dst) {
26336     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
26337   }
26338 
26339   if (wuffs_base__status__is_error(&status)) {
26340     self->private_impl.magic = WUFFS_BASE__DISABLED;
26341   }
26342   return status;
26343 }
26344 
26345 // -------- func deflate.decoder.decode_blocks
26346 
26347 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)26348 wuffs_deflate__decoder__decode_blocks(
26349     wuffs_deflate__decoder* self,
26350     wuffs_base__io_buffer* a_dst,
26351     wuffs_base__io_buffer* a_src) {
26352   wuffs_base__status status = wuffs_base__make_status(NULL);
26353 
26354   uint32_t v_final = 0;
26355   uint32_t v_b0 = 0;
26356   uint32_t v_type = 0;
26357   wuffs_base__status v_status = wuffs_base__make_status(NULL);
26358 
26359   const uint8_t* iop_a_src = NULL;
26360   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
26361   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
26362   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
26363   if (a_src) {
26364     io0_a_src = a_src->data.ptr;
26365     io1_a_src = io0_a_src + a_src->meta.ri;
26366     iop_a_src = io1_a_src;
26367     io2_a_src = io0_a_src + a_src->meta.wi;
26368   }
26369 
26370   uint32_t coro_susp_point = self->private_impl.p_decode_blocks[0];
26371   if (coro_susp_point) {
26372     v_final = self->private_data.s_decode_blocks[0].v_final;
26373   }
26374   switch (coro_susp_point) {
26375     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
26376 
26377     label__outer__continue:;
26378     while (v_final == 0) {
26379       while (self->private_impl.f_n_bits < 3) {
26380         {
26381           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
26382           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
26383             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
26384             goto suspend;
26385           }
26386           uint32_t t_0 = *iop_a_src++;
26387           v_b0 = t_0;
26388         }
26389         self->private_impl.f_bits |= (v_b0 << (self->private_impl.f_n_bits & 3));
26390         self->private_impl.f_n_bits = ((self->private_impl.f_n_bits & 3) + 8);
26391       }
26392       v_final = (self->private_impl.f_bits & 1);
26393       v_type = ((self->private_impl.f_bits >> 1) & 3);
26394       self->private_impl.f_bits >>= 3;
26395       self->private_impl.f_n_bits -= 3;
26396       if (v_type == 0) {
26397         if (a_src) {
26398           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
26399         }
26400         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
26401         status = wuffs_deflate__decoder__decode_uncompressed(self, a_dst, a_src);
26402         if (a_src) {
26403           iop_a_src = a_src->data.ptr + a_src->meta.ri;
26404         }
26405         if (status.repr) {
26406           goto suspend;
26407         }
26408         goto label__outer__continue;
26409       } else if (v_type == 1) {
26410         v_status = wuffs_deflate__decoder__init_fixed_huffman(self);
26411         if ( ! wuffs_base__status__is_ok(&v_status)) {
26412           status = v_status;
26413           if (wuffs_base__status__is_error(&status)) {
26414             goto exit;
26415           } else if (wuffs_base__status__is_suspension(&status)) {
26416             status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
26417             goto exit;
26418           }
26419           goto ok;
26420         }
26421       } else if (v_type == 2) {
26422         if (a_src) {
26423           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
26424         }
26425         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
26426         status = wuffs_deflate__decoder__init_dynamic_huffman(self, a_src);
26427         if (a_src) {
26428           iop_a_src = a_src->data.ptr + a_src->meta.ri;
26429         }
26430         if (status.repr) {
26431           goto suspend;
26432         }
26433       } else {
26434         status = wuffs_base__make_status(wuffs_deflate__error__bad_block);
26435         goto exit;
26436       }
26437       self->private_impl.f_end_of_block = false;
26438       while (true) {
26439         if (sizeof(void*) == 4) {
26440           if (a_src) {
26441             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
26442           }
26443           v_status = wuffs_deflate__decoder__decode_huffman_fast32(self, a_dst, a_src);
26444           if (a_src) {
26445             iop_a_src = a_src->data.ptr + a_src->meta.ri;
26446           }
26447         } else {
26448           if (a_src) {
26449             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
26450           }
26451           v_status = wuffs_deflate__decoder__decode_huffman_fast64(self, a_dst, a_src);
26452           if (a_src) {
26453             iop_a_src = a_src->data.ptr + a_src->meta.ri;
26454           }
26455         }
26456         if (wuffs_base__status__is_error(&v_status)) {
26457           status = v_status;
26458           goto exit;
26459         }
26460         if (self->private_impl.f_end_of_block) {
26461           goto label__outer__continue;
26462         }
26463         if (a_src) {
26464           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
26465         }
26466         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
26467         status = wuffs_deflate__decoder__decode_huffman_slow(self, a_dst, a_src);
26468         if (a_src) {
26469           iop_a_src = a_src->data.ptr + a_src->meta.ri;
26470         }
26471         if (status.repr) {
26472           goto suspend;
26473         }
26474         if (self->private_impl.f_end_of_block) {
26475           goto label__outer__continue;
26476         }
26477       }
26478     }
26479 
26480     ok:
26481     self->private_impl.p_decode_blocks[0] = 0;
26482     goto exit;
26483   }
26484 
26485   goto suspend;
26486   suspend:
26487   self->private_impl.p_decode_blocks[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
26488   self->private_data.s_decode_blocks[0].v_final = v_final;
26489 
26490   goto exit;
26491   exit:
26492   if (a_src) {
26493     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
26494   }
26495 
26496   return status;
26497 }
26498 
26499 // -------- func deflate.decoder.decode_uncompressed
26500 
26501 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)26502 wuffs_deflate__decoder__decode_uncompressed(
26503     wuffs_deflate__decoder* self,
26504     wuffs_base__io_buffer* a_dst,
26505     wuffs_base__io_buffer* a_src) {
26506   wuffs_base__status status = wuffs_base__make_status(NULL);
26507 
26508   uint32_t v_length = 0;
26509   uint32_t v_n_copied = 0;
26510 
26511   uint8_t* iop_a_dst = NULL;
26512   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
26513   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
26514   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
26515   if (a_dst) {
26516     io0_a_dst = a_dst->data.ptr;
26517     io1_a_dst = io0_a_dst + a_dst->meta.wi;
26518     iop_a_dst = io1_a_dst;
26519     io2_a_dst = io0_a_dst + a_dst->data.len;
26520     if (a_dst->meta.closed) {
26521       io2_a_dst = iop_a_dst;
26522     }
26523   }
26524   const uint8_t* iop_a_src = NULL;
26525   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
26526   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
26527   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
26528   if (a_src) {
26529     io0_a_src = a_src->data.ptr;
26530     io1_a_src = io0_a_src + a_src->meta.ri;
26531     iop_a_src = io1_a_src;
26532     io2_a_src = io0_a_src + a_src->meta.wi;
26533   }
26534 
26535   uint32_t coro_susp_point = self->private_impl.p_decode_uncompressed[0];
26536   if (coro_susp_point) {
26537     v_length = self->private_data.s_decode_uncompressed[0].v_length;
26538   }
26539   switch (coro_susp_point) {
26540     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
26541 
26542     if ((self->private_impl.f_n_bits >= 8) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7)) != 0)) {
26543       status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
26544       goto exit;
26545     }
26546     self->private_impl.f_n_bits = 0;
26547     self->private_impl.f_bits = 0;
26548     {
26549       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
26550       uint32_t t_0;
26551       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
26552         t_0 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
26553         iop_a_src += 4;
26554       } else {
26555         self->private_data.s_decode_uncompressed[0].scratch = 0;
26556         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
26557         while (true) {
26558           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
26559             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
26560             goto suspend;
26561           }
26562           uint64_t* scratch = &self->private_data.s_decode_uncompressed[0].scratch;
26563           uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
26564           *scratch <<= 8;
26565           *scratch >>= 8;
26566           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
26567           if (num_bits_0 == 24) {
26568             t_0 = ((uint32_t)(*scratch));
26569             break;
26570           }
26571           num_bits_0 += 8;
26572           *scratch |= ((uint64_t)(num_bits_0)) << 56;
26573         }
26574       }
26575       v_length = t_0;
26576     }
26577     if ((((v_length) & 0xFFFF) + ((v_length) >> (32 - (16)))) != 65535) {
26578       status = wuffs_base__make_status(wuffs_deflate__error__inconsistent_stored_block_length);
26579       goto exit;
26580     }
26581     v_length = ((v_length) & 0xFFFF);
26582     while (true) {
26583       v_n_copied = wuffs_base__io_writer__limited_copy_u32_from_reader(
26584           &iop_a_dst, io2_a_dst,v_length, &iop_a_src, io2_a_src);
26585       if (v_length <= v_n_copied) {
26586         status = wuffs_base__make_status(NULL);
26587         goto ok;
26588       }
26589       v_length -= v_n_copied;
26590       if (((uint64_t)(io2_a_dst - iop_a_dst)) == 0) {
26591         status = wuffs_base__make_status(wuffs_base__suspension__short_write);
26592         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
26593       } else {
26594         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
26595         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
26596       }
26597     }
26598 
26599     ok:
26600     self->private_impl.p_decode_uncompressed[0] = 0;
26601     goto exit;
26602   }
26603 
26604   goto suspend;
26605   suspend:
26606   self->private_impl.p_decode_uncompressed[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
26607   self->private_data.s_decode_uncompressed[0].v_length = v_length;
26608 
26609   goto exit;
26610   exit:
26611   if (a_dst) {
26612     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
26613   }
26614   if (a_src) {
26615     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
26616   }
26617 
26618   return status;
26619 }
26620 
26621 // -------- func deflate.decoder.init_fixed_huffman
26622 
26623 static wuffs_base__status
wuffs_deflate__decoder__init_fixed_huffman(wuffs_deflate__decoder * self)26624 wuffs_deflate__decoder__init_fixed_huffman(
26625     wuffs_deflate__decoder* self) {
26626   uint32_t v_i = 0;
26627   wuffs_base__status v_status = wuffs_base__make_status(NULL);
26628 
26629   while (v_i < 144) {
26630     self->private_data.f_code_lengths[v_i] = 8;
26631     v_i += 1;
26632   }
26633   while (v_i < 256) {
26634     self->private_data.f_code_lengths[v_i] = 9;
26635     v_i += 1;
26636   }
26637   while (v_i < 280) {
26638     self->private_data.f_code_lengths[v_i] = 7;
26639     v_i += 1;
26640   }
26641   while (v_i < 288) {
26642     self->private_data.f_code_lengths[v_i] = 8;
26643     v_i += 1;
26644   }
26645   while (v_i < 320) {
26646     self->private_data.f_code_lengths[v_i] = 5;
26647     v_i += 1;
26648   }
26649   v_status = wuffs_deflate__decoder__init_huff(self,
26650       0,
26651       0,
26652       288,
26653       257);
26654   if (wuffs_base__status__is_error(&v_status)) {
26655     return v_status;
26656   }
26657   v_status = wuffs_deflate__decoder__init_huff(self,
26658       1,
26659       288,
26660       320,
26661       0);
26662   if (wuffs_base__status__is_error(&v_status)) {
26663     return v_status;
26664   }
26665   return wuffs_base__make_status(NULL);
26666 }
26667 
26668 // -------- func deflate.decoder.init_dynamic_huffman
26669 
26670 static wuffs_base__status
wuffs_deflate__decoder__init_dynamic_huffman(wuffs_deflate__decoder * self,wuffs_base__io_buffer * a_src)26671 wuffs_deflate__decoder__init_dynamic_huffman(
26672     wuffs_deflate__decoder* self,
26673     wuffs_base__io_buffer* a_src) {
26674   wuffs_base__status status = wuffs_base__make_status(NULL);
26675 
26676   uint32_t v_bits = 0;
26677   uint32_t v_n_bits = 0;
26678   uint32_t v_b0 = 0;
26679   uint32_t v_n_lit = 0;
26680   uint32_t v_n_dist = 0;
26681   uint32_t v_n_clen = 0;
26682   uint32_t v_i = 0;
26683   uint32_t v_b1 = 0;
26684   wuffs_base__status v_status = wuffs_base__make_status(NULL);
26685   uint32_t v_mask = 0;
26686   uint32_t v_table_entry = 0;
26687   uint32_t v_table_entry_n_bits = 0;
26688   uint32_t v_b2 = 0;
26689   uint32_t v_n_extra_bits = 0;
26690   uint8_t v_rep_symbol = 0;
26691   uint32_t v_rep_count = 0;
26692   uint32_t v_b3 = 0;
26693 
26694   const uint8_t* iop_a_src = NULL;
26695   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
26696   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
26697   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
26698   if (a_src) {
26699     io0_a_src = a_src->data.ptr;
26700     io1_a_src = io0_a_src + a_src->meta.ri;
26701     iop_a_src = io1_a_src;
26702     io2_a_src = io0_a_src + a_src->meta.wi;
26703   }
26704 
26705   uint32_t coro_susp_point = self->private_impl.p_init_dynamic_huffman[0];
26706   if (coro_susp_point) {
26707     v_bits = self->private_data.s_init_dynamic_huffman[0].v_bits;
26708     v_n_bits = self->private_data.s_init_dynamic_huffman[0].v_n_bits;
26709     v_n_lit = self->private_data.s_init_dynamic_huffman[0].v_n_lit;
26710     v_n_dist = self->private_data.s_init_dynamic_huffman[0].v_n_dist;
26711     v_n_clen = self->private_data.s_init_dynamic_huffman[0].v_n_clen;
26712     v_i = self->private_data.s_init_dynamic_huffman[0].v_i;
26713     v_mask = self->private_data.s_init_dynamic_huffman[0].v_mask;
26714     v_table_entry = self->private_data.s_init_dynamic_huffman[0].v_table_entry;
26715     v_n_extra_bits = self->private_data.s_init_dynamic_huffman[0].v_n_extra_bits;
26716     v_rep_symbol = self->private_data.s_init_dynamic_huffman[0].v_rep_symbol;
26717     v_rep_count = self->private_data.s_init_dynamic_huffman[0].v_rep_count;
26718   }
26719   switch (coro_susp_point) {
26720     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
26721 
26722     v_bits = self->private_impl.f_bits;
26723     v_n_bits = self->private_impl.f_n_bits;
26724     while (v_n_bits < 14) {
26725       {
26726         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
26727         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
26728           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
26729           goto suspend;
26730         }
26731         uint32_t t_0 = *iop_a_src++;
26732         v_b0 = t_0;
26733       }
26734       v_bits |= (v_b0 << v_n_bits);
26735       v_n_bits += 8;
26736     }
26737     v_n_lit = (((v_bits) & 0x1F) + 257);
26738     if (v_n_lit > 286) {
26739       status = wuffs_base__make_status(wuffs_deflate__error__bad_literal_length_code_count);
26740       goto exit;
26741     }
26742     v_bits >>= 5;
26743     v_n_dist = (((v_bits) & 0x1F) + 1);
26744     if (v_n_dist > 30) {
26745       status = wuffs_base__make_status(wuffs_deflate__error__bad_distance_code_count);
26746       goto exit;
26747     }
26748     v_bits >>= 5;
26749     v_n_clen = (((v_bits) & 0xF) + 4);
26750     v_bits >>= 4;
26751     v_n_bits -= 14;
26752     v_i = 0;
26753     while (v_i < v_n_clen) {
26754       while (v_n_bits < 3) {
26755         {
26756           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
26757           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
26758             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
26759             goto suspend;
26760           }
26761           uint32_t t_1 = *iop_a_src++;
26762           v_b1 = t_1;
26763         }
26764         v_bits |= (v_b1 << v_n_bits);
26765         v_n_bits += 8;
26766       }
26767       self->private_data.f_code_lengths[WUFFS_DEFLATE__CODE_ORDER[v_i]] = ((uint8_t)((v_bits & 7)));
26768       v_bits >>= 3;
26769       v_n_bits -= 3;
26770       v_i += 1;
26771     }
26772     while (v_i < 19) {
26773       self->private_data.f_code_lengths[WUFFS_DEFLATE__CODE_ORDER[v_i]] = 0;
26774       v_i += 1;
26775     }
26776     v_status = wuffs_deflate__decoder__init_huff(self,
26777         0,
26778         0,
26779         19,
26780         4095);
26781     if (wuffs_base__status__is_error(&v_status)) {
26782       status = v_status;
26783       goto exit;
26784     }
26785     v_mask = ((((uint32_t)(1)) << self->private_impl.f_n_huffs_bits[0]) - 1);
26786     v_i = 0;
26787     label__0__continue:;
26788     while (v_i < (v_n_lit + v_n_dist)) {
26789       while (true) {
26790         v_table_entry = self->private_data.f_huffs[0][(v_bits & v_mask)];
26791         v_table_entry_n_bits = (v_table_entry & 15);
26792         if (v_n_bits >= v_table_entry_n_bits) {
26793           v_bits >>= v_table_entry_n_bits;
26794           v_n_bits -= v_table_entry_n_bits;
26795           goto label__1__break;
26796         }
26797         {
26798           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
26799           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
26800             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
26801             goto suspend;
26802           }
26803           uint32_t t_2 = *iop_a_src++;
26804           v_b2 = t_2;
26805         }
26806         v_bits |= (v_b2 << v_n_bits);
26807         v_n_bits += 8;
26808       }
26809       label__1__break:;
26810       if ((v_table_entry >> 24) != 128) {
26811         status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
26812         goto exit;
26813       }
26814       v_table_entry = ((v_table_entry >> 8) & 255);
26815       if (v_table_entry < 16) {
26816         self->private_data.f_code_lengths[v_i] = ((uint8_t)(v_table_entry));
26817         v_i += 1;
26818         goto label__0__continue;
26819       }
26820       v_n_extra_bits = 0;
26821       v_rep_symbol = 0;
26822       v_rep_count = 0;
26823       if (v_table_entry == 16) {
26824         v_n_extra_bits = 2;
26825         if (v_i <= 0) {
26826           status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_length_repetition);
26827           goto exit;
26828         }
26829         v_rep_symbol = (self->private_data.f_code_lengths[(v_i - 1)] & 15);
26830         v_rep_count = 3;
26831       } else if (v_table_entry == 17) {
26832         v_n_extra_bits = 3;
26833         v_rep_symbol = 0;
26834         v_rep_count = 3;
26835       } else if (v_table_entry == 18) {
26836         v_n_extra_bits = 7;
26837         v_rep_symbol = 0;
26838         v_rep_count = 11;
26839       } else {
26840         status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
26841         goto exit;
26842       }
26843       while (v_n_bits < v_n_extra_bits) {
26844         {
26845           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
26846           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
26847             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
26848             goto suspend;
26849           }
26850           uint32_t t_3 = *iop_a_src++;
26851           v_b3 = t_3;
26852         }
26853         v_bits |= (v_b3 << v_n_bits);
26854         v_n_bits += 8;
26855       }
26856       v_rep_count += ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_n_extra_bits));
26857       v_bits >>= v_n_extra_bits;
26858       v_n_bits -= v_n_extra_bits;
26859       while (v_rep_count > 0) {
26860         if (v_i >= (v_n_lit + v_n_dist)) {
26861           status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_length_count);
26862           goto exit;
26863         }
26864         self->private_data.f_code_lengths[v_i] = v_rep_symbol;
26865         v_i += 1;
26866         v_rep_count -= 1;
26867       }
26868     }
26869     if (v_i != (v_n_lit + v_n_dist)) {
26870       status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_length_count);
26871       goto exit;
26872     }
26873     if (self->private_data.f_code_lengths[256] == 0) {
26874       status = wuffs_base__make_status(wuffs_deflate__error__missing_end_of_block_code);
26875       goto exit;
26876     }
26877     v_status = wuffs_deflate__decoder__init_huff(self,
26878         0,
26879         0,
26880         v_n_lit,
26881         257);
26882     if (wuffs_base__status__is_error(&v_status)) {
26883       status = v_status;
26884       goto exit;
26885     }
26886     v_status = wuffs_deflate__decoder__init_huff(self,
26887         1,
26888         v_n_lit,
26889         (v_n_lit + v_n_dist),
26890         0);
26891     if (wuffs_base__status__is_error(&v_status)) {
26892       status = v_status;
26893       goto exit;
26894     }
26895     self->private_impl.f_bits = v_bits;
26896     self->private_impl.f_n_bits = v_n_bits;
26897 
26898     goto ok;
26899     ok:
26900     self->private_impl.p_init_dynamic_huffman[0] = 0;
26901     goto exit;
26902   }
26903 
26904   goto suspend;
26905   suspend:
26906   self->private_impl.p_init_dynamic_huffman[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
26907   self->private_data.s_init_dynamic_huffman[0].v_bits = v_bits;
26908   self->private_data.s_init_dynamic_huffman[0].v_n_bits = v_n_bits;
26909   self->private_data.s_init_dynamic_huffman[0].v_n_lit = v_n_lit;
26910   self->private_data.s_init_dynamic_huffman[0].v_n_dist = v_n_dist;
26911   self->private_data.s_init_dynamic_huffman[0].v_n_clen = v_n_clen;
26912   self->private_data.s_init_dynamic_huffman[0].v_i = v_i;
26913   self->private_data.s_init_dynamic_huffman[0].v_mask = v_mask;
26914   self->private_data.s_init_dynamic_huffman[0].v_table_entry = v_table_entry;
26915   self->private_data.s_init_dynamic_huffman[0].v_n_extra_bits = v_n_extra_bits;
26916   self->private_data.s_init_dynamic_huffman[0].v_rep_symbol = v_rep_symbol;
26917   self->private_data.s_init_dynamic_huffman[0].v_rep_count = v_rep_count;
26918 
26919   goto exit;
26920   exit:
26921   if (a_src) {
26922     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
26923   }
26924 
26925   return status;
26926 }
26927 
26928 // -------- func deflate.decoder.init_huff
26929 
26930 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)26931 wuffs_deflate__decoder__init_huff(
26932     wuffs_deflate__decoder* self,
26933     uint32_t a_which,
26934     uint32_t a_n_codes0,
26935     uint32_t a_n_codes1,
26936     uint32_t a_base_symbol) {
26937   uint16_t v_counts[16] = {0};
26938   uint32_t v_i = 0;
26939   uint32_t v_remaining = 0;
26940   uint16_t v_offsets[16] = {0};
26941   uint32_t v_n_symbols = 0;
26942   uint32_t v_count = 0;
26943   uint16_t v_symbols[320] = {0};
26944   uint32_t v_min_cl = 0;
26945   uint32_t v_max_cl = 0;
26946   uint32_t v_initial_high_bits = 0;
26947   uint32_t v_prev_cl = 0;
26948   uint32_t v_prev_redirect_key = 0;
26949   uint32_t v_top = 0;
26950   uint32_t v_next_top = 0;
26951   uint32_t v_code = 0;
26952   uint32_t v_key = 0;
26953   uint32_t v_value = 0;
26954   uint32_t v_cl = 0;
26955   uint32_t v_redirect_key = 0;
26956   uint32_t v_j = 0;
26957   uint32_t v_reversed_key = 0;
26958   uint32_t v_symbol = 0;
26959   uint32_t v_high_bits = 0;
26960   uint32_t v_delta = 0;
26961 
26962   v_i = a_n_codes0;
26963   while (v_i < a_n_codes1) {
26964     if (v_counts[(self->private_data.f_code_lengths[v_i] & 15)] >= 320) {
26965       return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
26966     }
26967 #if defined(__GNUC__)
26968 #pragma GCC diagnostic push
26969 #pragma GCC diagnostic ignored "-Wconversion"
26970 #endif
26971     v_counts[(self->private_data.f_code_lengths[v_i] & 15)] += 1;
26972 #if defined(__GNUC__)
26973 #pragma GCC diagnostic pop
26974 #endif
26975     v_i += 1;
26976   }
26977   if ((((uint32_t)(v_counts[0])) + a_n_codes0) == a_n_codes1) {
26978     return wuffs_base__make_status(wuffs_deflate__error__no_huffman_codes);
26979   }
26980   v_remaining = 1;
26981   v_i = 1;
26982   while (v_i <= 15) {
26983     if (v_remaining > 1073741824) {
26984       return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
26985     }
26986     v_remaining <<= 1;
26987     if (v_remaining < ((uint32_t)(v_counts[v_i]))) {
26988       return wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_over_subscribed);
26989     }
26990     v_remaining -= ((uint32_t)(v_counts[v_i]));
26991     v_i += 1;
26992   }
26993   if (v_remaining != 0) {
26994     if ((a_which == 1) &&
26995         (v_counts[1] == 1) &&
26996         (self->private_data.f_code_lengths[a_n_codes0] == 1) &&
26997         ((((uint32_t)(v_counts[0])) + a_n_codes0 + 1) == a_n_codes1)) {
26998       self->private_impl.f_n_huffs_bits[1] = 1;
26999       self->private_data.f_huffs[1][0] = (WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[0] | 1);
27000       self->private_data.f_huffs[1][1] = (WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[31] | 1);
27001       return wuffs_base__make_status(NULL);
27002     }
27003     return wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_under_subscribed);
27004   }
27005   v_i = 1;
27006   while (v_i <= 15) {
27007     v_offsets[v_i] = ((uint16_t)(v_n_symbols));
27008     v_count = ((uint32_t)(v_counts[v_i]));
27009     if (v_n_symbols > (320 - v_count)) {
27010       return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27011     }
27012     v_n_symbols = (v_n_symbols + v_count);
27013     v_i += 1;
27014   }
27015   if (v_n_symbols > 288) {
27016     return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27017   }
27018   v_i = a_n_codes0;
27019   while (v_i < a_n_codes1) {
27020     if (v_i < a_n_codes0) {
27021       return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27022     }
27023     if (self->private_data.f_code_lengths[v_i] != 0) {
27024       if (v_offsets[(self->private_data.f_code_lengths[v_i] & 15)] >= 320) {
27025         return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27026       }
27027       v_symbols[v_offsets[(self->private_data.f_code_lengths[v_i] & 15)]] = ((uint16_t)((v_i - a_n_codes0)));
27028 #if defined(__GNUC__)
27029 #pragma GCC diagnostic push
27030 #pragma GCC diagnostic ignored "-Wconversion"
27031 #endif
27032       v_offsets[(self->private_data.f_code_lengths[v_i] & 15)] += 1;
27033 #if defined(__GNUC__)
27034 #pragma GCC diagnostic pop
27035 #endif
27036     }
27037     v_i += 1;
27038   }
27039   v_min_cl = 1;
27040   while (true) {
27041     if (v_counts[v_min_cl] != 0) {
27042       goto label__0__break;
27043     }
27044     if (v_min_cl >= 9) {
27045       return wuffs_base__make_status(wuffs_deflate__error__bad_huffman_minimum_code_length);
27046     }
27047     v_min_cl += 1;
27048   }
27049   label__0__break:;
27050   v_max_cl = 15;
27051   while (true) {
27052     if (v_counts[v_max_cl] != 0) {
27053       goto label__1__break;
27054     }
27055     if (v_max_cl <= 1) {
27056       return wuffs_base__make_status(wuffs_deflate__error__no_huffman_codes);
27057     }
27058     v_max_cl -= 1;
27059   }
27060   label__1__break:;
27061   if (v_max_cl <= 9) {
27062     self->private_impl.f_n_huffs_bits[a_which] = v_max_cl;
27063   } else {
27064     self->private_impl.f_n_huffs_bits[a_which] = 9;
27065   }
27066   v_i = 0;
27067   if ((v_n_symbols != ((uint32_t)(v_offsets[v_max_cl]))) || (v_n_symbols != ((uint32_t)(v_offsets[15])))) {
27068     return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27069   }
27070   if ((a_n_codes0 + ((uint32_t)(v_symbols[0]))) >= 320) {
27071     return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27072   }
27073   v_initial_high_bits = 512;
27074   if (v_max_cl < 9) {
27075     v_initial_high_bits = (((uint32_t)(1)) << v_max_cl);
27076   }
27077   v_prev_cl = ((uint32_t)((self->private_data.f_code_lengths[(a_n_codes0 + ((uint32_t)(v_symbols[0])))] & 15)));
27078   v_prev_redirect_key = 4294967295;
27079   v_top = 0;
27080   v_next_top = 512;
27081   v_code = 0;
27082   v_key = 0;
27083   v_value = 0;
27084   while (true) {
27085     if ((a_n_codes0 + ((uint32_t)(v_symbols[v_i]))) >= 320) {
27086       return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27087     }
27088     v_cl = ((uint32_t)((self->private_data.f_code_lengths[(a_n_codes0 + ((uint32_t)(v_symbols[v_i])))] & 15)));
27089     if (v_cl > v_prev_cl) {
27090       v_code <<= (v_cl - v_prev_cl);
27091       if (v_code >= 32768) {
27092         return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27093       }
27094     }
27095     v_prev_cl = v_cl;
27096     v_key = v_code;
27097     if (v_cl > 9) {
27098       v_cl -= 9;
27099       v_redirect_key = ((v_key >> v_cl) & 511);
27100       v_key = ((v_key) & WUFFS_BASE__LOW_BITS_MASK__U32(v_cl));
27101       if (v_prev_redirect_key != v_redirect_key) {
27102         v_prev_redirect_key = v_redirect_key;
27103         v_remaining = (((uint32_t)(1)) << v_cl);
27104         v_j = v_prev_cl;
27105         while (v_j <= 15) {
27106           if (v_remaining <= ((uint32_t)(v_counts[v_j]))) {
27107             goto label__2__break;
27108           }
27109           v_remaining -= ((uint32_t)(v_counts[v_j]));
27110           if (v_remaining > 1073741824) {
27111             return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27112           }
27113           v_remaining <<= 1;
27114           v_j += 1;
27115         }
27116         label__2__break:;
27117         if ((v_j <= 9) || (15 < v_j)) {
27118           return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27119         }
27120         v_j -= 9;
27121         v_initial_high_bits = (((uint32_t)(1)) << v_j);
27122         v_top = v_next_top;
27123         if ((v_top + (((uint32_t)(1)) << v_j)) > 1024) {
27124           return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27125         }
27126         v_next_top = (v_top + (((uint32_t)(1)) << v_j));
27127         v_redirect_key = (((uint32_t)(WUFFS_DEFLATE__REVERSE8[(v_redirect_key >> 1)])) | ((v_redirect_key & 1) << 8));
27128         self->private_data.f_huffs[a_which][v_redirect_key] = (268435465 | (v_top << 8) | (v_j << 4));
27129       }
27130     }
27131     if ((v_key >= 512) || (v_counts[v_prev_cl] <= 0)) {
27132       return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27133     }
27134 #if defined(__GNUC__)
27135 #pragma GCC diagnostic push
27136 #pragma GCC diagnostic ignored "-Wconversion"
27137 #endif
27138     v_counts[v_prev_cl] -= 1;
27139 #if defined(__GNUC__)
27140 #pragma GCC diagnostic pop
27141 #endif
27142     v_reversed_key = (((uint32_t)(WUFFS_DEFLATE__REVERSE8[(v_key >> 1)])) | ((v_key & 1) << 8));
27143     v_reversed_key >>= (9 - v_cl);
27144     v_symbol = ((uint32_t)(v_symbols[v_i]));
27145     if (v_symbol == 256) {
27146       v_value = (536870912 | v_cl);
27147     } else if ((v_symbol < 256) && (a_which == 0)) {
27148       v_value = (2147483648 | (v_symbol << 8) | v_cl);
27149     } else if (v_symbol >= a_base_symbol) {
27150       v_symbol -= a_base_symbol;
27151       if (a_which == 0) {
27152         v_value = (WUFFS_DEFLATE__LCODE_MAGIC_NUMBERS[(v_symbol & 31)] | v_cl);
27153       } else {
27154         v_value = (WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[(v_symbol & 31)] | v_cl);
27155       }
27156     } else {
27157       return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27158     }
27159     v_high_bits = v_initial_high_bits;
27160     v_delta = (((uint32_t)(1)) << v_cl);
27161     while (v_high_bits >= v_delta) {
27162       v_high_bits -= v_delta;
27163       if ((v_top + ((v_high_bits | v_reversed_key) & 511)) >= 1024) {
27164         return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27165       }
27166       self->private_data.f_huffs[a_which][(v_top + ((v_high_bits | v_reversed_key) & 511))] = v_value;
27167     }
27168     v_i += 1;
27169     if (v_i >= v_n_symbols) {
27170       goto label__3__break;
27171     }
27172     v_code += 1;
27173     if (v_code >= 32768) {
27174       return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27175     }
27176   }
27177   label__3__break:;
27178   return wuffs_base__make_status(NULL);
27179 }
27180 
27181 // ‼ WUFFS MULTI-FILE SECTION +x86_bmi2
27182 // -------- func deflate.decoder.decode_huffman_bmi2
27183 
27184 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
27185 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("bmi2")
27186 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)27187 wuffs_deflate__decoder__decode_huffman_bmi2(
27188     wuffs_deflate__decoder* self,
27189     wuffs_base__io_buffer* a_dst,
27190     wuffs_base__io_buffer* a_src) {
27191   wuffs_base__status status = wuffs_base__make_status(NULL);
27192 
27193   uint64_t v_bits = 0;
27194   uint32_t v_n_bits = 0;
27195   uint32_t v_table_entry = 0;
27196   uint32_t v_table_entry_n_bits = 0;
27197   uint64_t v_lmask = 0;
27198   uint64_t v_dmask = 0;
27199   uint32_t v_redir_top = 0;
27200   uint32_t v_redir_mask = 0;
27201   uint32_t v_length = 0;
27202   uint32_t v_dist_minus_1 = 0;
27203   uint32_t v_hlen = 0;
27204   uint32_t v_hdist = 0;
27205   uint32_t v_hdist_adjustment = 0;
27206 
27207   uint8_t* iop_a_dst = NULL;
27208   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27209   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27210   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27211   if (a_dst) {
27212     io0_a_dst = a_dst->data.ptr;
27213     io1_a_dst = io0_a_dst + a_dst->meta.wi;
27214     iop_a_dst = io1_a_dst;
27215     io2_a_dst = io0_a_dst + a_dst->data.len;
27216     if (a_dst->meta.closed) {
27217       io2_a_dst = iop_a_dst;
27218     }
27219   }
27220   const uint8_t* iop_a_src = NULL;
27221   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27222   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27223   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27224   if (a_src) {
27225     io0_a_src = a_src->data.ptr;
27226     io1_a_src = io0_a_src + a_src->meta.ri;
27227     iop_a_src = io1_a_src;
27228     io2_a_src = io0_a_src + a_src->meta.wi;
27229   }
27230 
27231   if ((self->private_impl.f_n_bits >= 8) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7)) != 0)) {
27232     status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
27233     goto exit;
27234   }
27235   v_bits = ((uint64_t)(self->private_impl.f_bits));
27236   v_n_bits = self->private_impl.f_n_bits;
27237   v_lmask = ((((uint64_t)(1)) << self->private_impl.f_n_huffs_bits[0]) - 1);
27238   v_dmask = ((((uint64_t)(1)) << self->private_impl.f_n_huffs_bits[1]) - 1);
27239   if (self->private_impl.f_transformed_history_count < (a_dst ? a_dst->meta.pos : 0)) {
27240     status = wuffs_base__make_status(wuffs_base__error__bad_i_o_position);
27241     goto exit;
27242   }
27243   v_hdist_adjustment = ((uint32_t)(((self->private_impl.f_transformed_history_count - (a_dst ? a_dst->meta.pos : 0)) & 4294967295)));
27244   label__loop__continue:;
27245   while ((((uint64_t)(io2_a_dst - iop_a_dst)) >= 266) && (((uint64_t)(io2_a_src - iop_a_src)) >= 8)) {
27246     v_bits |= ((uint64_t)(wuffs_base__peek_u64le__no_bounds_check(iop_a_src) << (v_n_bits & 63)));
27247     iop_a_src += ((63 - (v_n_bits & 63)) >> 3);
27248     v_n_bits |= 56;
27249     v_table_entry = self->private_data.f_huffs[0][(v_bits & v_lmask)];
27250     v_table_entry_n_bits = (v_table_entry & 15);
27251     v_bits >>= v_table_entry_n_bits;
27252     v_n_bits -= v_table_entry_n_bits;
27253     if ((v_table_entry >> 31) != 0) {
27254       (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)(((v_table_entry >> 8) & 255)))), iop_a_dst += 1);
27255       goto label__loop__continue;
27256     } else if ((v_table_entry >> 30) != 0) {
27257     } else if ((v_table_entry >> 29) != 0) {
27258       self->private_impl.f_end_of_block = true;
27259       goto label__loop__break;
27260     } else if ((v_table_entry >> 28) != 0) {
27261       v_redir_top = ((v_table_entry >> 8) & 65535);
27262       v_redir_mask = ((((uint32_t)(1)) << ((v_table_entry >> 4) & 15)) - 1);
27263       v_table_entry = self->private_data.f_huffs[0][((v_redir_top + (((uint32_t)((v_bits & 4294967295))) & v_redir_mask)) & 1023)];
27264       v_table_entry_n_bits = (v_table_entry & 15);
27265       v_bits >>= v_table_entry_n_bits;
27266       v_n_bits -= v_table_entry_n_bits;
27267       if ((v_table_entry >> 31) != 0) {
27268         (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)(((v_table_entry >> 8) & 255)))), iop_a_dst += 1);
27269         goto label__loop__continue;
27270       } else if ((v_table_entry >> 30) != 0) {
27271       } else if ((v_table_entry >> 29) != 0) {
27272         self->private_impl.f_end_of_block = true;
27273         goto label__loop__break;
27274       } else if ((v_table_entry >> 28) != 0) {
27275         status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27276         goto exit;
27277       } else if ((v_table_entry >> 27) != 0) {
27278         status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
27279         goto exit;
27280       } else {
27281         status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27282         goto exit;
27283       }
27284     } else if ((v_table_entry >> 27) != 0) {
27285       status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
27286       goto exit;
27287     } else {
27288       status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27289       goto exit;
27290     }
27291     v_length = (((v_table_entry >> 8) & 255) + 3);
27292     v_table_entry_n_bits = ((v_table_entry >> 4) & 15);
27293     if (v_table_entry_n_bits > 0) {
27294       v_length = (((v_length + 253 + ((uint32_t)(((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U64(v_table_entry_n_bits))))) & 255) + 3);
27295       v_bits >>= v_table_entry_n_bits;
27296       v_n_bits -= v_table_entry_n_bits;
27297     }
27298     v_table_entry = self->private_data.f_huffs[1][(v_bits & v_dmask)];
27299     v_table_entry_n_bits = (v_table_entry & 15);
27300     v_bits >>= v_table_entry_n_bits;
27301     v_n_bits -= v_table_entry_n_bits;
27302     if ((v_table_entry >> 28) == 1) {
27303       v_redir_top = ((v_table_entry >> 8) & 65535);
27304       v_redir_mask = ((((uint32_t)(1)) << ((v_table_entry >> 4) & 15)) - 1);
27305       v_table_entry = self->private_data.f_huffs[1][((v_redir_top + (((uint32_t)((v_bits & 4294967295))) & v_redir_mask)) & 1023)];
27306       v_table_entry_n_bits = (v_table_entry & 15);
27307       v_bits >>= v_table_entry_n_bits;
27308       v_n_bits -= v_table_entry_n_bits;
27309     }
27310     if ((v_table_entry >> 24) != 64) {
27311       if ((v_table_entry >> 24) == 8) {
27312         status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
27313         goto exit;
27314       }
27315       status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27316       goto exit;
27317     }
27318     v_dist_minus_1 = ((v_table_entry >> 8) & 32767);
27319     v_table_entry_n_bits = ((v_table_entry >> 4) & 15);
27320     v_dist_minus_1 = ((v_dist_minus_1 + ((uint32_t)(((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U64(v_table_entry_n_bits))))) & 32767);
27321     v_bits >>= v_table_entry_n_bits;
27322     v_n_bits -= v_table_entry_n_bits;
27323     while (true) {
27324       if (((uint64_t)((v_dist_minus_1 + 1))) > ((uint64_t)(iop_a_dst - io0_a_dst))) {
27325         v_hlen = 0;
27326         v_hdist = ((uint32_t)((((uint64_t)((v_dist_minus_1 + 1))) - ((uint64_t)(iop_a_dst - io0_a_dst)))));
27327         if (v_length > v_hdist) {
27328           v_length -= v_hdist;
27329           v_hlen = v_hdist;
27330         } else {
27331           v_hlen = v_length;
27332           v_length = 0;
27333         }
27334         v_hdist += v_hdist_adjustment;
27335         if (self->private_impl.f_history_index < v_hdist) {
27336           status = wuffs_base__make_status(wuffs_deflate__error__bad_distance);
27337           goto exit;
27338         }
27339         v_hdist = (self->private_impl.f_history_index - v_hdist);
27340         wuffs_base__io_writer__limited_copy_u32_from_slice(
27341             &iop_a_dst, io2_a_dst,v_hlen, wuffs_base__slice_u8__subslice_i(wuffs_base__make_slice_u8(self->private_data.f_history, 33025), (v_hdist & 32767)));
27342         if (v_length == 0) {
27343           goto label__loop__continue;
27344         }
27345         if ((((uint64_t)((v_dist_minus_1 + 1))) > ((uint64_t)(iop_a_dst - io0_a_dst))) || (((uint64_t)(v_length)) > ((uint64_t)(io2_a_dst - iop_a_dst))) || (((uint64_t)((v_length + 8))) > ((uint64_t)(io2_a_dst - iop_a_dst)))) {
27346           status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_distance);
27347           goto exit;
27348         }
27349       }
27350       if ((v_dist_minus_1 + 1) >= 8) {
27351         wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast(
27352             &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1));
27353       } else if ((v_dist_minus_1 + 1) == 1) {
27354         wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast(
27355             &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1));
27356       } else {
27357         wuffs_base__io_writer__limited_copy_u32_from_history_fast(
27358             &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1));
27359       }
27360       goto label__0__break;
27361     }
27362     label__0__break:;
27363   }
27364   label__loop__break:;
27365   if (v_n_bits > 63) {
27366     status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
27367     goto exit;
27368   }
27369   while (v_n_bits >= 8) {
27370     v_n_bits -= 8;
27371     if (iop_a_src > io1_a_src) {
27372       iop_a_src--;
27373     } else {
27374       status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_i_o);
27375       goto exit;
27376     }
27377   }
27378   self->private_impl.f_bits = ((uint32_t)((v_bits & ((((uint64_t)(1)) << v_n_bits) - 1))));
27379   self->private_impl.f_n_bits = v_n_bits;
27380   if ((self->private_impl.f_n_bits >= 8) || ((self->private_impl.f_bits >> self->private_impl.f_n_bits) != 0)) {
27381     status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
27382     goto exit;
27383   }
27384   goto exit;
27385   exit:
27386   if (a_dst) {
27387     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
27388   }
27389   if (a_src) {
27390     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
27391   }
27392 
27393   return status;
27394 }
27395 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
27396 // ‼ WUFFS MULTI-FILE SECTION -x86_bmi2
27397 
27398 // -------- func deflate.decoder.decode_huffman_fast32
27399 
27400 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)27401 wuffs_deflate__decoder__decode_huffman_fast32(
27402     wuffs_deflate__decoder* self,
27403     wuffs_base__io_buffer* a_dst,
27404     wuffs_base__io_buffer* a_src) {
27405   wuffs_base__status status = wuffs_base__make_status(NULL);
27406 
27407   uint32_t v_bits = 0;
27408   uint32_t v_n_bits = 0;
27409   uint32_t v_table_entry = 0;
27410   uint32_t v_table_entry_n_bits = 0;
27411   uint32_t v_lmask = 0;
27412   uint32_t v_dmask = 0;
27413   uint32_t v_redir_top = 0;
27414   uint32_t v_redir_mask = 0;
27415   uint32_t v_length = 0;
27416   uint32_t v_dist_minus_1 = 0;
27417   uint32_t v_hlen = 0;
27418   uint32_t v_hdist = 0;
27419   uint32_t v_hdist_adjustment = 0;
27420 
27421   uint8_t* iop_a_dst = NULL;
27422   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27423   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27424   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27425   if (a_dst) {
27426     io0_a_dst = a_dst->data.ptr;
27427     io1_a_dst = io0_a_dst + a_dst->meta.wi;
27428     iop_a_dst = io1_a_dst;
27429     io2_a_dst = io0_a_dst + a_dst->data.len;
27430     if (a_dst->meta.closed) {
27431       io2_a_dst = iop_a_dst;
27432     }
27433   }
27434   const uint8_t* iop_a_src = NULL;
27435   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27436   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27437   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27438   if (a_src) {
27439     io0_a_src = a_src->data.ptr;
27440     io1_a_src = io0_a_src + a_src->meta.ri;
27441     iop_a_src = io1_a_src;
27442     io2_a_src = io0_a_src + a_src->meta.wi;
27443   }
27444 
27445   if ((self->private_impl.f_n_bits >= 8) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7)) != 0)) {
27446     status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
27447     goto exit;
27448   }
27449   v_bits = self->private_impl.f_bits;
27450   v_n_bits = self->private_impl.f_n_bits;
27451   v_lmask = ((((uint32_t)(1)) << self->private_impl.f_n_huffs_bits[0]) - 1);
27452   v_dmask = ((((uint32_t)(1)) << self->private_impl.f_n_huffs_bits[1]) - 1);
27453   if (self->private_impl.f_transformed_history_count < (a_dst ? a_dst->meta.pos : 0)) {
27454     status = wuffs_base__make_status(wuffs_base__error__bad_i_o_position);
27455     goto exit;
27456   }
27457   v_hdist_adjustment = ((uint32_t)(((self->private_impl.f_transformed_history_count - (a_dst ? a_dst->meta.pos : 0)) & 4294967295)));
27458   label__loop__continue:;
27459   while ((((uint64_t)(io2_a_dst - iop_a_dst)) >= 266) && (((uint64_t)(io2_a_src - iop_a_src)) >= 12)) {
27460     if (v_n_bits < 15) {
27461       v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
27462       iop_a_src += 1;
27463       v_n_bits += 8;
27464       v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
27465       iop_a_src += 1;
27466       v_n_bits += 8;
27467     } else {
27468     }
27469     v_table_entry = self->private_data.f_huffs[0][(v_bits & v_lmask)];
27470     v_table_entry_n_bits = (v_table_entry & 15);
27471     v_bits >>= v_table_entry_n_bits;
27472     v_n_bits -= v_table_entry_n_bits;
27473     if ((v_table_entry >> 31) != 0) {
27474       (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)(((v_table_entry >> 8) & 255)))), iop_a_dst += 1);
27475       goto label__loop__continue;
27476     } else if ((v_table_entry >> 30) != 0) {
27477     } else if ((v_table_entry >> 29) != 0) {
27478       self->private_impl.f_end_of_block = true;
27479       goto label__loop__break;
27480     } else if ((v_table_entry >> 28) != 0) {
27481       if (v_n_bits < 15) {
27482         v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
27483         iop_a_src += 1;
27484         v_n_bits += 8;
27485         v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
27486         iop_a_src += 1;
27487         v_n_bits += 8;
27488       } else {
27489       }
27490       v_redir_top = ((v_table_entry >> 8) & 65535);
27491       v_redir_mask = ((((uint32_t)(1)) << ((v_table_entry >> 4) & 15)) - 1);
27492       v_table_entry = self->private_data.f_huffs[0][((v_redir_top + (v_bits & v_redir_mask)) & 1023)];
27493       v_table_entry_n_bits = (v_table_entry & 15);
27494       v_bits >>= v_table_entry_n_bits;
27495       v_n_bits -= v_table_entry_n_bits;
27496       if ((v_table_entry >> 31) != 0) {
27497         (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)(((v_table_entry >> 8) & 255)))), iop_a_dst += 1);
27498         goto label__loop__continue;
27499       } else if ((v_table_entry >> 30) != 0) {
27500       } else if ((v_table_entry >> 29) != 0) {
27501         self->private_impl.f_end_of_block = true;
27502         goto label__loop__break;
27503       } else if ((v_table_entry >> 28) != 0) {
27504         status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27505         goto exit;
27506       } else if ((v_table_entry >> 27) != 0) {
27507         status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
27508         goto exit;
27509       } else {
27510         status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27511         goto exit;
27512       }
27513     } else if ((v_table_entry >> 27) != 0) {
27514       status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
27515       goto exit;
27516     } else {
27517       status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27518       goto exit;
27519     }
27520     v_length = (((v_table_entry >> 8) & 255) + 3);
27521     v_table_entry_n_bits = ((v_table_entry >> 4) & 15);
27522     if (v_table_entry_n_bits > 0) {
27523       if (v_n_bits < 15) {
27524         v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
27525         iop_a_src += 1;
27526         v_n_bits += 8;
27527         v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
27528         iop_a_src += 1;
27529         v_n_bits += 8;
27530       } else {
27531       }
27532       v_length = (((v_length + 253 + ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_table_entry_n_bits))) & 255) + 3);
27533       v_bits >>= v_table_entry_n_bits;
27534       v_n_bits -= v_table_entry_n_bits;
27535     } else {
27536     }
27537     if (v_n_bits < 15) {
27538       v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
27539       iop_a_src += 1;
27540       v_n_bits += 8;
27541       v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
27542       iop_a_src += 1;
27543       v_n_bits += 8;
27544     } else {
27545     }
27546     v_table_entry = self->private_data.f_huffs[1][(v_bits & v_dmask)];
27547     v_table_entry_n_bits = (v_table_entry & 15);
27548     v_bits >>= v_table_entry_n_bits;
27549     v_n_bits -= v_table_entry_n_bits;
27550     if ((v_table_entry >> 28) == 1) {
27551       if (v_n_bits < 15) {
27552         v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
27553         iop_a_src += 1;
27554         v_n_bits += 8;
27555         v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
27556         iop_a_src += 1;
27557         v_n_bits += 8;
27558       } else {
27559       }
27560       v_redir_top = ((v_table_entry >> 8) & 65535);
27561       v_redir_mask = ((((uint32_t)(1)) << ((v_table_entry >> 4) & 15)) - 1);
27562       v_table_entry = self->private_data.f_huffs[1][((v_redir_top + (v_bits & v_redir_mask)) & 1023)];
27563       v_table_entry_n_bits = (v_table_entry & 15);
27564       v_bits >>= v_table_entry_n_bits;
27565       v_n_bits -= v_table_entry_n_bits;
27566     } else {
27567     }
27568     if ((v_table_entry >> 24) != 64) {
27569       if ((v_table_entry >> 24) == 8) {
27570         status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
27571         goto exit;
27572       }
27573       status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27574       goto exit;
27575     }
27576     v_dist_minus_1 = ((v_table_entry >> 8) & 32767);
27577     v_table_entry_n_bits = ((v_table_entry >> 4) & 15);
27578     if (v_n_bits < v_table_entry_n_bits) {
27579       v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
27580       iop_a_src += 1;
27581       v_n_bits += 8;
27582       v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
27583       iop_a_src += 1;
27584       v_n_bits += 8;
27585     }
27586     v_dist_minus_1 = ((v_dist_minus_1 + ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_table_entry_n_bits))) & 32767);
27587     v_bits >>= v_table_entry_n_bits;
27588     v_n_bits -= v_table_entry_n_bits;
27589     while (true) {
27590       if (((uint64_t)((v_dist_minus_1 + 1))) > ((uint64_t)(iop_a_dst - io0_a_dst))) {
27591         v_hlen = 0;
27592         v_hdist = ((uint32_t)((((uint64_t)((v_dist_minus_1 + 1))) - ((uint64_t)(iop_a_dst - io0_a_dst)))));
27593         if (v_length > v_hdist) {
27594           v_length -= v_hdist;
27595           v_hlen = v_hdist;
27596         } else {
27597           v_hlen = v_length;
27598           v_length = 0;
27599         }
27600         v_hdist += v_hdist_adjustment;
27601         if (self->private_impl.f_history_index < v_hdist) {
27602           status = wuffs_base__make_status(wuffs_deflate__error__bad_distance);
27603           goto exit;
27604         }
27605         v_hdist = (self->private_impl.f_history_index - v_hdist);
27606         wuffs_base__io_writer__limited_copy_u32_from_slice(
27607             &iop_a_dst, io2_a_dst,v_hlen, wuffs_base__slice_u8__subslice_i(wuffs_base__make_slice_u8(self->private_data.f_history, 33025), (v_hdist & 32767)));
27608         if (v_length == 0) {
27609           goto label__loop__continue;
27610         }
27611         if ((((uint64_t)((v_dist_minus_1 + 1))) > ((uint64_t)(iop_a_dst - io0_a_dst))) || (((uint64_t)(v_length)) > ((uint64_t)(io2_a_dst - iop_a_dst))) || (((uint64_t)((v_length + 8))) > ((uint64_t)(io2_a_dst - iop_a_dst)))) {
27612           status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_distance);
27613           goto exit;
27614         }
27615       }
27616       if ((v_dist_minus_1 + 1) >= 8) {
27617         wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast(
27618             &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1));
27619       } else {
27620         wuffs_base__io_writer__limited_copy_u32_from_history_fast(
27621             &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1));
27622       }
27623       goto label__0__break;
27624     }
27625     label__0__break:;
27626   }
27627   label__loop__break:;
27628   while (v_n_bits >= 8) {
27629     v_n_bits -= 8;
27630     if (iop_a_src > io1_a_src) {
27631       iop_a_src--;
27632     } else {
27633       status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_i_o);
27634       goto exit;
27635     }
27636   }
27637   self->private_impl.f_bits = (v_bits & ((((uint32_t)(1)) << v_n_bits) - 1));
27638   self->private_impl.f_n_bits = v_n_bits;
27639   if ((self->private_impl.f_n_bits >= 8) || ((self->private_impl.f_bits >> self->private_impl.f_n_bits) != 0)) {
27640     status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
27641     goto exit;
27642   }
27643   goto exit;
27644   exit:
27645   if (a_dst) {
27646     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
27647   }
27648   if (a_src) {
27649     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
27650   }
27651 
27652   return status;
27653 }
27654 
27655 // -------- func deflate.decoder.decode_huffman_fast64
27656 
27657 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)27658 wuffs_deflate__decoder__decode_huffman_fast64(
27659     wuffs_deflate__decoder* self,
27660     wuffs_base__io_buffer* a_dst,
27661     wuffs_base__io_buffer* a_src) {
27662   return (*self->private_impl.choosy_decode_huffman_fast64)(self, a_dst, a_src);
27663 }
27664 
27665 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)27666 wuffs_deflate__decoder__decode_huffman_fast64__choosy_default(
27667     wuffs_deflate__decoder* self,
27668     wuffs_base__io_buffer* a_dst,
27669     wuffs_base__io_buffer* a_src) {
27670   wuffs_base__status status = wuffs_base__make_status(NULL);
27671 
27672   uint64_t v_bits = 0;
27673   uint32_t v_n_bits = 0;
27674   uint32_t v_table_entry = 0;
27675   uint32_t v_table_entry_n_bits = 0;
27676   uint64_t v_lmask = 0;
27677   uint64_t v_dmask = 0;
27678   uint32_t v_redir_top = 0;
27679   uint32_t v_redir_mask = 0;
27680   uint32_t v_length = 0;
27681   uint32_t v_dist_minus_1 = 0;
27682   uint32_t v_hlen = 0;
27683   uint32_t v_hdist = 0;
27684   uint32_t v_hdist_adjustment = 0;
27685 
27686   uint8_t* iop_a_dst = NULL;
27687   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27688   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27689   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27690   if (a_dst) {
27691     io0_a_dst = a_dst->data.ptr;
27692     io1_a_dst = io0_a_dst + a_dst->meta.wi;
27693     iop_a_dst = io1_a_dst;
27694     io2_a_dst = io0_a_dst + a_dst->data.len;
27695     if (a_dst->meta.closed) {
27696       io2_a_dst = iop_a_dst;
27697     }
27698   }
27699   const uint8_t* iop_a_src = NULL;
27700   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27701   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27702   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27703   if (a_src) {
27704     io0_a_src = a_src->data.ptr;
27705     io1_a_src = io0_a_src + a_src->meta.ri;
27706     iop_a_src = io1_a_src;
27707     io2_a_src = io0_a_src + a_src->meta.wi;
27708   }
27709 
27710   if ((self->private_impl.f_n_bits >= 8) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7)) != 0)) {
27711     status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
27712     goto exit;
27713   }
27714   v_bits = ((uint64_t)(self->private_impl.f_bits));
27715   v_n_bits = self->private_impl.f_n_bits;
27716   v_lmask = ((((uint64_t)(1)) << self->private_impl.f_n_huffs_bits[0]) - 1);
27717   v_dmask = ((((uint64_t)(1)) << self->private_impl.f_n_huffs_bits[1]) - 1);
27718   if (self->private_impl.f_transformed_history_count < (a_dst ? a_dst->meta.pos : 0)) {
27719     status = wuffs_base__make_status(wuffs_base__error__bad_i_o_position);
27720     goto exit;
27721   }
27722   v_hdist_adjustment = ((uint32_t)(((self->private_impl.f_transformed_history_count - (a_dst ? a_dst->meta.pos : 0)) & 4294967295)));
27723   label__loop__continue:;
27724   while ((((uint64_t)(io2_a_dst - iop_a_dst)) >= 266) && (((uint64_t)(io2_a_src - iop_a_src)) >= 8)) {
27725     v_bits |= ((uint64_t)(wuffs_base__peek_u64le__no_bounds_check(iop_a_src) << (v_n_bits & 63)));
27726     iop_a_src += ((63 - (v_n_bits & 63)) >> 3);
27727     v_n_bits |= 56;
27728     v_table_entry = self->private_data.f_huffs[0][(v_bits & v_lmask)];
27729     v_table_entry_n_bits = (v_table_entry & 15);
27730     v_bits >>= v_table_entry_n_bits;
27731     v_n_bits -= v_table_entry_n_bits;
27732     if ((v_table_entry >> 31) != 0) {
27733       (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)(((v_table_entry >> 8) & 255)))), iop_a_dst += 1);
27734       goto label__loop__continue;
27735     } else if ((v_table_entry >> 30) != 0) {
27736     } else if ((v_table_entry >> 29) != 0) {
27737       self->private_impl.f_end_of_block = true;
27738       goto label__loop__break;
27739     } else if ((v_table_entry >> 28) != 0) {
27740       v_redir_top = ((v_table_entry >> 8) & 65535);
27741       v_redir_mask = ((((uint32_t)(1)) << ((v_table_entry >> 4) & 15)) - 1);
27742       v_table_entry = self->private_data.f_huffs[0][((v_redir_top + (((uint32_t)((v_bits & 4294967295))) & v_redir_mask)) & 1023)];
27743       v_table_entry_n_bits = (v_table_entry & 15);
27744       v_bits >>= v_table_entry_n_bits;
27745       v_n_bits -= v_table_entry_n_bits;
27746       if ((v_table_entry >> 31) != 0) {
27747         (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)(((v_table_entry >> 8) & 255)))), iop_a_dst += 1);
27748         goto label__loop__continue;
27749       } else if ((v_table_entry >> 30) != 0) {
27750       } else if ((v_table_entry >> 29) != 0) {
27751         self->private_impl.f_end_of_block = true;
27752         goto label__loop__break;
27753       } else if ((v_table_entry >> 28) != 0) {
27754         status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27755         goto exit;
27756       } else if ((v_table_entry >> 27) != 0) {
27757         status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
27758         goto exit;
27759       } else {
27760         status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27761         goto exit;
27762       }
27763     } else if ((v_table_entry >> 27) != 0) {
27764       status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
27765       goto exit;
27766     } else {
27767       status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27768       goto exit;
27769     }
27770     v_length = (((v_table_entry >> 8) & 255) + 3);
27771     v_table_entry_n_bits = ((v_table_entry >> 4) & 15);
27772     if (v_table_entry_n_bits > 0) {
27773       v_length = (((v_length + 253 + ((uint32_t)(((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U64(v_table_entry_n_bits))))) & 255) + 3);
27774       v_bits >>= v_table_entry_n_bits;
27775       v_n_bits -= v_table_entry_n_bits;
27776     }
27777     v_table_entry = self->private_data.f_huffs[1][(v_bits & v_dmask)];
27778     v_table_entry_n_bits = (v_table_entry & 15);
27779     v_bits >>= v_table_entry_n_bits;
27780     v_n_bits -= v_table_entry_n_bits;
27781     if ((v_table_entry >> 28) == 1) {
27782       v_redir_top = ((v_table_entry >> 8) & 65535);
27783       v_redir_mask = ((((uint32_t)(1)) << ((v_table_entry >> 4) & 15)) - 1);
27784       v_table_entry = self->private_data.f_huffs[1][((v_redir_top + (((uint32_t)((v_bits & 4294967295))) & v_redir_mask)) & 1023)];
27785       v_table_entry_n_bits = (v_table_entry & 15);
27786       v_bits >>= v_table_entry_n_bits;
27787       v_n_bits -= v_table_entry_n_bits;
27788     }
27789     if ((v_table_entry >> 24) != 64) {
27790       if ((v_table_entry >> 24) == 8) {
27791         status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
27792         goto exit;
27793       }
27794       status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27795       goto exit;
27796     }
27797     v_dist_minus_1 = ((v_table_entry >> 8) & 32767);
27798     v_table_entry_n_bits = ((v_table_entry >> 4) & 15);
27799     v_dist_minus_1 = ((v_dist_minus_1 + ((uint32_t)(((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U64(v_table_entry_n_bits))))) & 32767);
27800     v_bits >>= v_table_entry_n_bits;
27801     v_n_bits -= v_table_entry_n_bits;
27802     while (true) {
27803       if (((uint64_t)((v_dist_minus_1 + 1))) > ((uint64_t)(iop_a_dst - io0_a_dst))) {
27804         v_hlen = 0;
27805         v_hdist = ((uint32_t)((((uint64_t)((v_dist_minus_1 + 1))) - ((uint64_t)(iop_a_dst - io0_a_dst)))));
27806         if (v_length > v_hdist) {
27807           v_length -= v_hdist;
27808           v_hlen = v_hdist;
27809         } else {
27810           v_hlen = v_length;
27811           v_length = 0;
27812         }
27813         v_hdist += v_hdist_adjustment;
27814         if (self->private_impl.f_history_index < v_hdist) {
27815           status = wuffs_base__make_status(wuffs_deflate__error__bad_distance);
27816           goto exit;
27817         }
27818         v_hdist = (self->private_impl.f_history_index - v_hdist);
27819         wuffs_base__io_writer__limited_copy_u32_from_slice(
27820             &iop_a_dst, io2_a_dst,v_hlen, wuffs_base__slice_u8__subslice_i(wuffs_base__make_slice_u8(self->private_data.f_history, 33025), (v_hdist & 32767)));
27821         if (v_length == 0) {
27822           goto label__loop__continue;
27823         }
27824         if ((((uint64_t)((v_dist_minus_1 + 1))) > ((uint64_t)(iop_a_dst - io0_a_dst))) || (((uint64_t)(v_length)) > ((uint64_t)(io2_a_dst - iop_a_dst))) || (((uint64_t)((v_length + 8))) > ((uint64_t)(io2_a_dst - iop_a_dst)))) {
27825           status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_distance);
27826           goto exit;
27827         }
27828       }
27829       if ((v_dist_minus_1 + 1) >= 8) {
27830         wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast(
27831             &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1));
27832       } else if ((v_dist_minus_1 + 1) == 1) {
27833         wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast(
27834             &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1));
27835       } else {
27836         wuffs_base__io_writer__limited_copy_u32_from_history_fast(
27837             &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1));
27838       }
27839       goto label__0__break;
27840     }
27841     label__0__break:;
27842   }
27843   label__loop__break:;
27844   if (v_n_bits > 63) {
27845     status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
27846     goto exit;
27847   }
27848   while (v_n_bits >= 8) {
27849     v_n_bits -= 8;
27850     if (iop_a_src > io1_a_src) {
27851       iop_a_src--;
27852     } else {
27853       status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_i_o);
27854       goto exit;
27855     }
27856   }
27857   self->private_impl.f_bits = ((uint32_t)((v_bits & ((((uint64_t)(1)) << v_n_bits) - 1))));
27858   self->private_impl.f_n_bits = v_n_bits;
27859   if ((self->private_impl.f_n_bits >= 8) || ((self->private_impl.f_bits >> self->private_impl.f_n_bits) != 0)) {
27860     status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
27861     goto exit;
27862   }
27863   goto exit;
27864   exit:
27865   if (a_dst) {
27866     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
27867   }
27868   if (a_src) {
27869     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
27870   }
27871 
27872   return status;
27873 }
27874 
27875 // -------- func deflate.decoder.decode_huffman_slow
27876 
27877 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)27878 wuffs_deflate__decoder__decode_huffman_slow(
27879     wuffs_deflate__decoder* self,
27880     wuffs_base__io_buffer* a_dst,
27881     wuffs_base__io_buffer* a_src) {
27882   wuffs_base__status status = wuffs_base__make_status(NULL);
27883 
27884   uint32_t v_bits = 0;
27885   uint32_t v_n_bits = 0;
27886   uint32_t v_table_entry = 0;
27887   uint32_t v_table_entry_n_bits = 0;
27888   uint32_t v_lmask = 0;
27889   uint32_t v_dmask = 0;
27890   uint32_t v_b0 = 0;
27891   uint32_t v_redir_top = 0;
27892   uint32_t v_redir_mask = 0;
27893   uint32_t v_b1 = 0;
27894   uint32_t v_length = 0;
27895   uint32_t v_b2 = 0;
27896   uint32_t v_b3 = 0;
27897   uint32_t v_b4 = 0;
27898   uint32_t v_dist_minus_1 = 0;
27899   uint32_t v_b5 = 0;
27900   uint32_t v_n_copied = 0;
27901   uint32_t v_hlen = 0;
27902   uint32_t v_hdist = 0;
27903 
27904   uint8_t* iop_a_dst = NULL;
27905   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27906   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27907   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27908   if (a_dst) {
27909     io0_a_dst = a_dst->data.ptr;
27910     io1_a_dst = io0_a_dst + a_dst->meta.wi;
27911     iop_a_dst = io1_a_dst;
27912     io2_a_dst = io0_a_dst + a_dst->data.len;
27913     if (a_dst->meta.closed) {
27914       io2_a_dst = iop_a_dst;
27915     }
27916   }
27917   const uint8_t* iop_a_src = NULL;
27918   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27919   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27920   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27921   if (a_src) {
27922     io0_a_src = a_src->data.ptr;
27923     io1_a_src = io0_a_src + a_src->meta.ri;
27924     iop_a_src = io1_a_src;
27925     io2_a_src = io0_a_src + a_src->meta.wi;
27926   }
27927 
27928   uint32_t coro_susp_point = self->private_impl.p_decode_huffman_slow[0];
27929   if (coro_susp_point) {
27930     v_bits = self->private_data.s_decode_huffman_slow[0].v_bits;
27931     v_n_bits = self->private_data.s_decode_huffman_slow[0].v_n_bits;
27932     v_table_entry = self->private_data.s_decode_huffman_slow[0].v_table_entry;
27933     v_table_entry_n_bits = self->private_data.s_decode_huffman_slow[0].v_table_entry_n_bits;
27934     v_lmask = self->private_data.s_decode_huffman_slow[0].v_lmask;
27935     v_dmask = self->private_data.s_decode_huffman_slow[0].v_dmask;
27936     v_redir_top = self->private_data.s_decode_huffman_slow[0].v_redir_top;
27937     v_redir_mask = self->private_data.s_decode_huffman_slow[0].v_redir_mask;
27938     v_length = self->private_data.s_decode_huffman_slow[0].v_length;
27939     v_dist_minus_1 = self->private_data.s_decode_huffman_slow[0].v_dist_minus_1;
27940     v_hlen = self->private_data.s_decode_huffman_slow[0].v_hlen;
27941     v_hdist = self->private_data.s_decode_huffman_slow[0].v_hdist;
27942   }
27943   switch (coro_susp_point) {
27944     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
27945 
27946     if ((self->private_impl.f_n_bits >= 8) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7)) != 0)) {
27947       status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
27948       goto exit;
27949     }
27950     v_bits = self->private_impl.f_bits;
27951     v_n_bits = self->private_impl.f_n_bits;
27952     v_lmask = ((((uint32_t)(1)) << self->private_impl.f_n_huffs_bits[0]) - 1);
27953     v_dmask = ((((uint32_t)(1)) << self->private_impl.f_n_huffs_bits[1]) - 1);
27954     label__loop__continue:;
27955     while ( ! (self->private_impl.p_decode_huffman_slow[0] != 0)) {
27956       while (true) {
27957         v_table_entry = self->private_data.f_huffs[0][(v_bits & v_lmask)];
27958         v_table_entry_n_bits = (v_table_entry & 15);
27959         if (v_n_bits >= v_table_entry_n_bits) {
27960           v_bits >>= v_table_entry_n_bits;
27961           v_n_bits -= v_table_entry_n_bits;
27962           goto label__0__break;
27963         }
27964         {
27965           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
27966           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
27967             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
27968             goto suspend;
27969           }
27970           uint32_t t_0 = *iop_a_src++;
27971           v_b0 = t_0;
27972         }
27973         v_bits |= (v_b0 << v_n_bits);
27974         v_n_bits += 8;
27975       }
27976       label__0__break:;
27977       if ((v_table_entry >> 31) != 0) {
27978         self->private_data.s_decode_huffman_slow[0].scratch = ((uint8_t)(((v_table_entry >> 8) & 255)));
27979         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
27980         if (iop_a_dst == io2_a_dst) {
27981           status = wuffs_base__make_status(wuffs_base__suspension__short_write);
27982           goto suspend;
27983         }
27984         *iop_a_dst++ = ((uint8_t)(self->private_data.s_decode_huffman_slow[0].scratch));
27985         goto label__loop__continue;
27986       } else if ((v_table_entry >> 30) != 0) {
27987       } else if ((v_table_entry >> 29) != 0) {
27988         self->private_impl.f_end_of_block = true;
27989         goto label__loop__break;
27990       } else if ((v_table_entry >> 28) != 0) {
27991         v_redir_top = ((v_table_entry >> 8) & 65535);
27992         v_redir_mask = ((((uint32_t)(1)) << ((v_table_entry >> 4) & 15)) - 1);
27993         while (true) {
27994           v_table_entry = self->private_data.f_huffs[0][((v_redir_top + (v_bits & v_redir_mask)) & 1023)];
27995           v_table_entry_n_bits = (v_table_entry & 15);
27996           if (v_n_bits >= v_table_entry_n_bits) {
27997             v_bits >>= v_table_entry_n_bits;
27998             v_n_bits -= v_table_entry_n_bits;
27999             goto label__1__break;
28000           }
28001           {
28002             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
28003             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
28004               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28005               goto suspend;
28006             }
28007             uint32_t t_1 = *iop_a_src++;
28008             v_b1 = t_1;
28009           }
28010           v_bits |= (v_b1 << v_n_bits);
28011           v_n_bits += 8;
28012         }
28013         label__1__break:;
28014         if ((v_table_entry >> 31) != 0) {
28015           self->private_data.s_decode_huffman_slow[0].scratch = ((uint8_t)(((v_table_entry >> 8) & 255)));
28016           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
28017           if (iop_a_dst == io2_a_dst) {
28018             status = wuffs_base__make_status(wuffs_base__suspension__short_write);
28019             goto suspend;
28020           }
28021           *iop_a_dst++ = ((uint8_t)(self->private_data.s_decode_huffman_slow[0].scratch));
28022           goto label__loop__continue;
28023         } else if ((v_table_entry >> 30) != 0) {
28024         } else if ((v_table_entry >> 29) != 0) {
28025           self->private_impl.f_end_of_block = true;
28026           goto label__loop__break;
28027         } else if ((v_table_entry >> 28) != 0) {
28028           status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
28029           goto exit;
28030         } else if ((v_table_entry >> 27) != 0) {
28031           status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
28032           goto exit;
28033         } else {
28034           status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
28035           goto exit;
28036         }
28037       } else if ((v_table_entry >> 27) != 0) {
28038         status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
28039         goto exit;
28040       } else {
28041         status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
28042         goto exit;
28043       }
28044       v_length = (((v_table_entry >> 8) & 255) + 3);
28045       v_table_entry_n_bits = ((v_table_entry >> 4) & 15);
28046       if (v_table_entry_n_bits > 0) {
28047         while (v_n_bits < v_table_entry_n_bits) {
28048           {
28049             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
28050             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
28051               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28052               goto suspend;
28053             }
28054             uint32_t t_2 = *iop_a_src++;
28055             v_b2 = t_2;
28056           }
28057           v_bits |= (v_b2 << v_n_bits);
28058           v_n_bits += 8;
28059         }
28060         v_length = (((v_length + 253 + ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_table_entry_n_bits))) & 255) + 3);
28061         v_bits >>= v_table_entry_n_bits;
28062         v_n_bits -= v_table_entry_n_bits;
28063       }
28064       while (true) {
28065         v_table_entry = self->private_data.f_huffs[1][(v_bits & v_dmask)];
28066         v_table_entry_n_bits = (v_table_entry & 15);
28067         if (v_n_bits >= v_table_entry_n_bits) {
28068           v_bits >>= v_table_entry_n_bits;
28069           v_n_bits -= v_table_entry_n_bits;
28070           goto label__2__break;
28071         }
28072         {
28073           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
28074           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
28075             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28076             goto suspend;
28077           }
28078           uint32_t t_3 = *iop_a_src++;
28079           v_b3 = t_3;
28080         }
28081         v_bits |= (v_b3 << v_n_bits);
28082         v_n_bits += 8;
28083       }
28084       label__2__break:;
28085       if ((v_table_entry >> 28) == 1) {
28086         v_redir_top = ((v_table_entry >> 8) & 65535);
28087         v_redir_mask = ((((uint32_t)(1)) << ((v_table_entry >> 4) & 15)) - 1);
28088         while (true) {
28089           v_table_entry = self->private_data.f_huffs[1][((v_redir_top + (v_bits & v_redir_mask)) & 1023)];
28090           v_table_entry_n_bits = (v_table_entry & 15);
28091           if (v_n_bits >= v_table_entry_n_bits) {
28092             v_bits >>= v_table_entry_n_bits;
28093             v_n_bits -= v_table_entry_n_bits;
28094             goto label__3__break;
28095           }
28096           {
28097             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
28098             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
28099               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28100               goto suspend;
28101             }
28102             uint32_t t_4 = *iop_a_src++;
28103             v_b4 = t_4;
28104           }
28105           v_bits |= (v_b4 << v_n_bits);
28106           v_n_bits += 8;
28107         }
28108         label__3__break:;
28109       }
28110       if ((v_table_entry >> 24) != 64) {
28111         if ((v_table_entry >> 24) == 8) {
28112           status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
28113           goto exit;
28114         }
28115         status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
28116         goto exit;
28117       }
28118       v_dist_minus_1 = ((v_table_entry >> 8) & 32767);
28119       v_table_entry_n_bits = ((v_table_entry >> 4) & 15);
28120       if (v_table_entry_n_bits > 0) {
28121         while (v_n_bits < v_table_entry_n_bits) {
28122           {
28123             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
28124             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
28125               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28126               goto suspend;
28127             }
28128             uint32_t t_5 = *iop_a_src++;
28129             v_b5 = t_5;
28130           }
28131           v_bits |= (v_b5 << v_n_bits);
28132           v_n_bits += 8;
28133         }
28134         v_dist_minus_1 = ((v_dist_minus_1 + ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_table_entry_n_bits))) & 32767);
28135         v_bits >>= v_table_entry_n_bits;
28136         v_n_bits -= v_table_entry_n_bits;
28137       }
28138       while (true) {
28139         if (((uint64_t)((v_dist_minus_1 + 1))) > ((uint64_t)(iop_a_dst - io0_a_dst))) {
28140           v_hdist = ((uint32_t)((((uint64_t)((v_dist_minus_1 + 1))) - ((uint64_t)(iop_a_dst - io0_a_dst)))));
28141           if (v_length > v_hdist) {
28142             v_length -= v_hdist;
28143             v_hlen = v_hdist;
28144           } else {
28145             v_hlen = v_length;
28146             v_length = 0;
28147           }
28148           v_hdist += ((uint32_t)((((uint64_t)(self->private_impl.f_transformed_history_count - (a_dst ? a_dst->meta.pos : 0))) & 4294967295)));
28149           if (self->private_impl.f_history_index < v_hdist) {
28150             status = wuffs_base__make_status(wuffs_deflate__error__bad_distance);
28151             goto exit;
28152           }
28153           v_hdist = (self->private_impl.f_history_index - v_hdist);
28154           while (true) {
28155             v_n_copied = wuffs_base__io_writer__limited_copy_u32_from_slice(
28156                 &iop_a_dst, io2_a_dst,v_hlen, wuffs_base__slice_u8__subslice_i(wuffs_base__make_slice_u8(self->private_data.f_history, 32768), (v_hdist & 32767)));
28157             if (v_hlen <= v_n_copied) {
28158               v_hlen = 0;
28159               goto label__4__break;
28160             }
28161             if (v_n_copied > 0) {
28162               v_hlen -= v_n_copied;
28163               v_hdist = (((uint32_t)(v_hdist + v_n_copied)) & 32767);
28164               if (v_hdist == 0) {
28165                 goto label__4__break;
28166               }
28167             }
28168             status = wuffs_base__make_status(wuffs_base__suspension__short_write);
28169             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9);
28170           }
28171           label__4__break:;
28172           if (v_hlen > 0) {
28173             while (true) {
28174               v_n_copied = wuffs_base__io_writer__limited_copy_u32_from_slice(
28175                   &iop_a_dst, io2_a_dst,v_hlen, wuffs_base__slice_u8__subslice_i(wuffs_base__make_slice_u8(self->private_data.f_history, 32768), (v_hdist & 32767)));
28176               if (v_hlen <= v_n_copied) {
28177                 v_hlen = 0;
28178                 goto label__5__break;
28179               }
28180               v_hlen -= v_n_copied;
28181               v_hdist += v_n_copied;
28182               status = wuffs_base__make_status(wuffs_base__suspension__short_write);
28183               WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10);
28184             }
28185             label__5__break:;
28186           }
28187           if (v_length == 0) {
28188             goto label__loop__continue;
28189           }
28190         }
28191         v_n_copied = wuffs_base__io_writer__limited_copy_u32_from_history(
28192             &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1));
28193         if (v_length <= v_n_copied) {
28194           v_length = 0;
28195           goto label__6__break;
28196         }
28197         v_length -= v_n_copied;
28198         status = wuffs_base__make_status(wuffs_base__suspension__short_write);
28199         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(11);
28200       }
28201       label__6__break:;
28202     }
28203     label__loop__break:;
28204     self->private_impl.f_bits = v_bits;
28205     self->private_impl.f_n_bits = v_n_bits;
28206     if ((self->private_impl.f_n_bits >= 8) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7)) != 0)) {
28207       status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
28208       goto exit;
28209     }
28210 
28211     ok:
28212     self->private_impl.p_decode_huffman_slow[0] = 0;
28213     goto exit;
28214   }
28215 
28216   goto suspend;
28217   suspend:
28218   self->private_impl.p_decode_huffman_slow[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
28219   self->private_data.s_decode_huffman_slow[0].v_bits = v_bits;
28220   self->private_data.s_decode_huffman_slow[0].v_n_bits = v_n_bits;
28221   self->private_data.s_decode_huffman_slow[0].v_table_entry = v_table_entry;
28222   self->private_data.s_decode_huffman_slow[0].v_table_entry_n_bits = v_table_entry_n_bits;
28223   self->private_data.s_decode_huffman_slow[0].v_lmask = v_lmask;
28224   self->private_data.s_decode_huffman_slow[0].v_dmask = v_dmask;
28225   self->private_data.s_decode_huffman_slow[0].v_redir_top = v_redir_top;
28226   self->private_data.s_decode_huffman_slow[0].v_redir_mask = v_redir_mask;
28227   self->private_data.s_decode_huffman_slow[0].v_length = v_length;
28228   self->private_data.s_decode_huffman_slow[0].v_dist_minus_1 = v_dist_minus_1;
28229   self->private_data.s_decode_huffman_slow[0].v_hlen = v_hlen;
28230   self->private_data.s_decode_huffman_slow[0].v_hdist = v_hdist;
28231 
28232   goto exit;
28233   exit:
28234   if (a_dst) {
28235     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
28236   }
28237   if (a_src) {
28238     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
28239   }
28240 
28241   return status;
28242 }
28243 
28244 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__DEFLATE)
28245 
28246 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZW)
28247 
28248 // ---------------- Status Codes Implementations
28249 
28250 const char wuffs_lzw__error__bad_code[] = "#lzw: bad code";
28251 const char wuffs_lzw__error__internal_error_inconsistent_i_o[] = "#lzw: internal error: inconsistent I/O";
28252 
28253 // ---------------- Private Consts
28254 
28255 // ---------------- Private Initializer Prototypes
28256 
28257 // ---------------- Private Function Prototypes
28258 
28259 static wuffs_base__empty_struct
28260 wuffs_lzw__decoder__read_from(
28261     wuffs_lzw__decoder* self,
28262     wuffs_base__io_buffer* a_src);
28263 
28264 static wuffs_base__status
28265 wuffs_lzw__decoder__write_to(
28266     wuffs_lzw__decoder* self,
28267     wuffs_base__io_buffer* a_dst);
28268 
28269 // ---------------- VTables
28270 
28271 const wuffs_base__io_transformer__func_ptrs
28272 wuffs_lzw__decoder__func_ptrs_for__wuffs_base__io_transformer = {
28273   (wuffs_base__empty_struct(*)(void*,
28274       uint32_t,
28275       bool))(&wuffs_lzw__decoder__set_quirk_enabled),
28276   (wuffs_base__status(*)(void*,
28277       wuffs_base__io_buffer*,
28278       wuffs_base__io_buffer*,
28279       wuffs_base__slice_u8))(&wuffs_lzw__decoder__transform_io),
28280   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_lzw__decoder__workbuf_len),
28281 };
28282 
28283 // ---------------- Initializer Implementations
28284 
28285 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)28286 wuffs_lzw__decoder__initialize(
28287     wuffs_lzw__decoder* self,
28288     size_t sizeof_star_self,
28289     uint64_t wuffs_version,
28290     uint32_t options){
28291   if (!self) {
28292     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
28293   }
28294   if (sizeof(*self) != sizeof_star_self) {
28295     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
28296   }
28297   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
28298       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
28299     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
28300   }
28301 
28302   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
28303     // The whole point of this if-check is to detect an uninitialized *self.
28304     // We disable the warning on GCC. Clang-5.0 does not have this warning.
28305 #if !defined(__clang__) && defined(__GNUC__)
28306 #pragma GCC diagnostic push
28307 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
28308 #endif
28309     if (self->private_impl.magic != 0) {
28310       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
28311     }
28312 #if !defined(__clang__) && defined(__GNUC__)
28313 #pragma GCC diagnostic pop
28314 #endif
28315   } else {
28316     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
28317       memset(self, 0, sizeof(*self));
28318       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
28319     } else {
28320       memset(&(self->private_impl), 0, sizeof(self->private_impl));
28321     }
28322   }
28323 
28324   self->private_impl.magic = WUFFS_BASE__MAGIC;
28325   self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name =
28326       wuffs_base__io_transformer__vtable_name;
28327   self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers =
28328       (const void*)(&wuffs_lzw__decoder__func_ptrs_for__wuffs_base__io_transformer);
28329   return wuffs_base__make_status(NULL);
28330 }
28331 
28332 wuffs_lzw__decoder*
wuffs_lzw__decoder__alloc()28333 wuffs_lzw__decoder__alloc() {
28334   wuffs_lzw__decoder* x =
28335       (wuffs_lzw__decoder*)(calloc(sizeof(wuffs_lzw__decoder), 1));
28336   if (!x) {
28337     return NULL;
28338   }
28339   if (wuffs_lzw__decoder__initialize(
28340       x, sizeof(wuffs_lzw__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
28341     free(x);
28342     return NULL;
28343   }
28344   return x;
28345 }
28346 
28347 size_t
sizeof__wuffs_lzw__decoder()28348 sizeof__wuffs_lzw__decoder() {
28349   return sizeof(wuffs_lzw__decoder);
28350 }
28351 
28352 // ---------------- Function Implementations
28353 
28354 // -------- func lzw.decoder.set_quirk_enabled
28355 
28356 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_lzw__decoder__set_quirk_enabled(wuffs_lzw__decoder * self,uint32_t a_quirk,bool a_enabled)28357 wuffs_lzw__decoder__set_quirk_enabled(
28358     wuffs_lzw__decoder* self,
28359     uint32_t a_quirk,
28360     bool a_enabled) {
28361   return wuffs_base__make_empty_struct();
28362 }
28363 
28364 // -------- func lzw.decoder.set_literal_width
28365 
28366 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_lzw__decoder__set_literal_width(wuffs_lzw__decoder * self,uint32_t a_lw)28367 wuffs_lzw__decoder__set_literal_width(
28368     wuffs_lzw__decoder* self,
28369     uint32_t a_lw) {
28370   if (!self) {
28371     return wuffs_base__make_empty_struct();
28372   }
28373   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
28374     return wuffs_base__make_empty_struct();
28375   }
28376   if (a_lw > 8) {
28377     self->private_impl.magic = WUFFS_BASE__DISABLED;
28378     return wuffs_base__make_empty_struct();
28379   }
28380 
28381   self->private_impl.f_set_literal_width_arg = (a_lw + 1);
28382   return wuffs_base__make_empty_struct();
28383 }
28384 
28385 // -------- func lzw.decoder.workbuf_len
28386 
28387 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_lzw__decoder__workbuf_len(const wuffs_lzw__decoder * self)28388 wuffs_lzw__decoder__workbuf_len(
28389     const wuffs_lzw__decoder* self) {
28390   if (!self) {
28391     return wuffs_base__utility__empty_range_ii_u64();
28392   }
28393   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
28394       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
28395     return wuffs_base__utility__empty_range_ii_u64();
28396   }
28397 
28398   return wuffs_base__utility__make_range_ii_u64(0, 0);
28399 }
28400 
28401 // -------- func lzw.decoder.transform_io
28402 
28403 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)28404 wuffs_lzw__decoder__transform_io(
28405     wuffs_lzw__decoder* self,
28406     wuffs_base__io_buffer* a_dst,
28407     wuffs_base__io_buffer* a_src,
28408     wuffs_base__slice_u8 a_workbuf) {
28409   if (!self) {
28410     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
28411   }
28412   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
28413     return wuffs_base__make_status(
28414         (self->private_impl.magic == WUFFS_BASE__DISABLED)
28415         ? wuffs_base__error__disabled_by_previous_error
28416         : wuffs_base__error__initialize_not_called);
28417   }
28418   if (!a_dst || !a_src) {
28419     self->private_impl.magic = WUFFS_BASE__DISABLED;
28420     return wuffs_base__make_status(wuffs_base__error__bad_argument);
28421   }
28422   if ((self->private_impl.active_coroutine != 0) &&
28423       (self->private_impl.active_coroutine != 1)) {
28424     self->private_impl.magic = WUFFS_BASE__DISABLED;
28425     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
28426   }
28427   self->private_impl.active_coroutine = 0;
28428   wuffs_base__status status = wuffs_base__make_status(NULL);
28429 
28430   uint32_t v_i = 0;
28431 
28432   uint32_t coro_susp_point = self->private_impl.p_transform_io[0];
28433   switch (coro_susp_point) {
28434     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
28435 
28436     self->private_impl.f_literal_width = 8;
28437     if (self->private_impl.f_set_literal_width_arg > 0) {
28438       self->private_impl.f_literal_width = (self->private_impl.f_set_literal_width_arg - 1);
28439     }
28440     self->private_impl.f_clear_code = (((uint32_t)(1)) << self->private_impl.f_literal_width);
28441     self->private_impl.f_end_code = (self->private_impl.f_clear_code + 1);
28442     self->private_impl.f_save_code = self->private_impl.f_end_code;
28443     self->private_impl.f_prev_code = self->private_impl.f_end_code;
28444     self->private_impl.f_width = (self->private_impl.f_literal_width + 1);
28445     self->private_impl.f_bits = 0;
28446     self->private_impl.f_n_bits = 0;
28447     self->private_impl.f_output_ri = 0;
28448     self->private_impl.f_output_wi = 0;
28449     v_i = 0;
28450     while (v_i < self->private_impl.f_clear_code) {
28451       self->private_data.f_lm1s[v_i] = 0;
28452       self->private_data.f_suffixes[v_i][0] = ((uint8_t)(v_i));
28453       v_i += 1;
28454     }
28455     label__0__continue:;
28456     while (true) {
28457       wuffs_lzw__decoder__read_from(self, a_src);
28458       if (self->private_impl.f_output_wi > 0) {
28459         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
28460         status = wuffs_lzw__decoder__write_to(self, a_dst);
28461         if (status.repr) {
28462           goto suspend;
28463         }
28464       }
28465       if (self->private_impl.f_read_from_return_value == 0) {
28466         goto label__0__break;
28467       } else if (self->private_impl.f_read_from_return_value == 1) {
28468         goto label__0__continue;
28469       } else if (self->private_impl.f_read_from_return_value == 2) {
28470         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28471         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
28472       } else if (self->private_impl.f_read_from_return_value == 3) {
28473         status = wuffs_base__make_status(wuffs_lzw__error__bad_code);
28474         goto exit;
28475       } else {
28476         status = wuffs_base__make_status(wuffs_lzw__error__internal_error_inconsistent_i_o);
28477         goto exit;
28478       }
28479     }
28480     label__0__break:;
28481 
28482     ok:
28483     self->private_impl.p_transform_io[0] = 0;
28484     goto exit;
28485   }
28486 
28487   goto suspend;
28488   suspend:
28489   self->private_impl.p_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
28490   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
28491 
28492   goto exit;
28493   exit:
28494   if (wuffs_base__status__is_error(&status)) {
28495     self->private_impl.magic = WUFFS_BASE__DISABLED;
28496   }
28497   return status;
28498 }
28499 
28500 // -------- func lzw.decoder.read_from
28501 
28502 static wuffs_base__empty_struct
wuffs_lzw__decoder__read_from(wuffs_lzw__decoder * self,wuffs_base__io_buffer * a_src)28503 wuffs_lzw__decoder__read_from(
28504     wuffs_lzw__decoder* self,
28505     wuffs_base__io_buffer* a_src) {
28506   uint32_t v_clear_code = 0;
28507   uint32_t v_end_code = 0;
28508   uint32_t v_save_code = 0;
28509   uint32_t v_prev_code = 0;
28510   uint32_t v_width = 0;
28511   uint32_t v_bits = 0;
28512   uint32_t v_n_bits = 0;
28513   uint32_t v_output_wi = 0;
28514   uint32_t v_code = 0;
28515   uint32_t v_c = 0;
28516   uint32_t v_o = 0;
28517   uint32_t v_steps = 0;
28518   uint8_t v_first_byte = 0;
28519   uint16_t v_lm1_b = 0;
28520   uint16_t v_lm1_a = 0;
28521 
28522   const uint8_t* iop_a_src = NULL;
28523   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
28524   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
28525   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
28526   if (a_src) {
28527     io0_a_src = a_src->data.ptr;
28528     io1_a_src = io0_a_src + a_src->meta.ri;
28529     iop_a_src = io1_a_src;
28530     io2_a_src = io0_a_src + a_src->meta.wi;
28531   }
28532 
28533   v_clear_code = self->private_impl.f_clear_code;
28534   v_end_code = self->private_impl.f_end_code;
28535   v_save_code = self->private_impl.f_save_code;
28536   v_prev_code = self->private_impl.f_prev_code;
28537   v_width = self->private_impl.f_width;
28538   v_bits = self->private_impl.f_bits;
28539   v_n_bits = self->private_impl.f_n_bits;
28540   v_output_wi = self->private_impl.f_output_wi;
28541   while (true) {
28542     if (v_n_bits < v_width) {
28543       if (((uint64_t)(io2_a_src - iop_a_src)) >= 4) {
28544         v_bits |= ((uint32_t)(wuffs_base__peek_u32le__no_bounds_check(iop_a_src) << v_n_bits));
28545         iop_a_src += ((31 - v_n_bits) >> 3);
28546         v_n_bits |= 24;
28547       } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
28548         self->private_impl.f_read_from_return_value = 2;
28549         goto label__0__break;
28550       } else {
28551         v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
28552         iop_a_src += 1;
28553         v_n_bits += 8;
28554         if (v_n_bits >= v_width) {
28555         } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
28556           self->private_impl.f_read_from_return_value = 2;
28557           goto label__0__break;
28558         } else {
28559           v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
28560           iop_a_src += 1;
28561           v_n_bits += 8;
28562           if (v_n_bits < v_width) {
28563             self->private_impl.f_read_from_return_value = 4;
28564             goto label__0__break;
28565           }
28566         }
28567       }
28568     }
28569     v_code = ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_width));
28570     v_bits >>= v_width;
28571     v_n_bits -= v_width;
28572     if (v_code < v_clear_code) {
28573       self->private_data.f_output[v_output_wi] = ((uint8_t)(v_code));
28574       v_output_wi = ((v_output_wi + 1) & 8191);
28575       if (v_save_code <= 4095) {
28576         v_lm1_a = (((uint16_t)(self->private_data.f_lm1s[v_prev_code] + 1)) & 4095);
28577         self->private_data.f_lm1s[v_save_code] = v_lm1_a;
28578         if ((v_lm1_a % 8) != 0) {
28579           self->private_impl.f_prefixes[v_save_code] = self->private_impl.f_prefixes[v_prev_code];
28580           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]));
28581           self->private_data.f_suffixes[v_save_code][(v_lm1_a % 8)] = ((uint8_t)(v_code));
28582         } else {
28583           self->private_impl.f_prefixes[v_save_code] = ((uint16_t)(v_prev_code));
28584           self->private_data.f_suffixes[v_save_code][0] = ((uint8_t)(v_code));
28585         }
28586         v_save_code += 1;
28587         if (v_width < 12) {
28588           v_width += (1 & (v_save_code >> v_width));
28589         }
28590         v_prev_code = v_code;
28591       }
28592     } else if (v_code <= v_end_code) {
28593       if (v_code == v_end_code) {
28594         self->private_impl.f_read_from_return_value = 0;
28595         goto label__0__break;
28596       }
28597       v_save_code = v_end_code;
28598       v_prev_code = v_end_code;
28599       v_width = (self->private_impl.f_literal_width + 1);
28600     } else if (v_code <= v_save_code) {
28601       v_c = v_code;
28602       if (v_code == v_save_code) {
28603         v_c = v_prev_code;
28604       }
28605       v_o = ((v_output_wi + (((uint32_t)(self->private_data.f_lm1s[v_c])) & 4294967288)) & 8191);
28606       v_output_wi = ((v_output_wi + 1 + ((uint32_t)(self->private_data.f_lm1s[v_c]))) & 8191);
28607       v_steps = (((uint32_t)(self->private_data.f_lm1s[v_c])) >> 3);
28608       while (true) {
28609         memcpy((self->private_data.f_output)+(v_o), (self->private_data.f_suffixes[v_c]), 8);
28610         if (v_steps <= 0) {
28611           goto label__1__break;
28612         }
28613         v_steps -= 1;
28614         v_o = (((uint32_t)(v_o - 8)) & 8191);
28615         v_c = ((uint32_t)(self->private_impl.f_prefixes[v_c]));
28616       }
28617       label__1__break:;
28618       v_first_byte = self->private_data.f_suffixes[v_c][0];
28619       if (v_code == v_save_code) {
28620         self->private_data.f_output[v_output_wi] = v_first_byte;
28621         v_output_wi = ((v_output_wi + 1) & 8191);
28622       }
28623       if (v_save_code <= 4095) {
28624         v_lm1_b = (((uint16_t)(self->private_data.f_lm1s[v_prev_code] + 1)) & 4095);
28625         self->private_data.f_lm1s[v_save_code] = v_lm1_b;
28626         if ((v_lm1_b % 8) != 0) {
28627           self->private_impl.f_prefixes[v_save_code] = self->private_impl.f_prefixes[v_prev_code];
28628           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]));
28629           self->private_data.f_suffixes[v_save_code][(v_lm1_b % 8)] = v_first_byte;
28630         } else {
28631           self->private_impl.f_prefixes[v_save_code] = ((uint16_t)(v_prev_code));
28632           self->private_data.f_suffixes[v_save_code][0] = ((uint8_t)(v_first_byte));
28633         }
28634         v_save_code += 1;
28635         if (v_width < 12) {
28636           v_width += (1 & (v_save_code >> v_width));
28637         }
28638         v_prev_code = v_code;
28639       }
28640     } else {
28641       self->private_impl.f_read_from_return_value = 3;
28642       goto label__0__break;
28643     }
28644     if (v_output_wi > 4095) {
28645       self->private_impl.f_read_from_return_value = 1;
28646       goto label__0__break;
28647     }
28648   }
28649   label__0__break:;
28650   if (self->private_impl.f_read_from_return_value != 2) {
28651     while (v_n_bits >= 8) {
28652       v_n_bits -= 8;
28653       if (iop_a_src > io1_a_src) {
28654         iop_a_src--;
28655       } else {
28656         self->private_impl.f_read_from_return_value = 4;
28657         goto label__2__break;
28658       }
28659     }
28660     label__2__break:;
28661   }
28662   self->private_impl.f_save_code = v_save_code;
28663   self->private_impl.f_prev_code = v_prev_code;
28664   self->private_impl.f_width = v_width;
28665   self->private_impl.f_bits = v_bits;
28666   self->private_impl.f_n_bits = v_n_bits;
28667   self->private_impl.f_output_wi = v_output_wi;
28668   if (a_src) {
28669     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
28670   }
28671 
28672   return wuffs_base__make_empty_struct();
28673 }
28674 
28675 // -------- func lzw.decoder.write_to
28676 
28677 static wuffs_base__status
wuffs_lzw__decoder__write_to(wuffs_lzw__decoder * self,wuffs_base__io_buffer * a_dst)28678 wuffs_lzw__decoder__write_to(
28679     wuffs_lzw__decoder* self,
28680     wuffs_base__io_buffer* a_dst) {
28681   wuffs_base__status status = wuffs_base__make_status(NULL);
28682 
28683   wuffs_base__slice_u8 v_s = {0};
28684   uint64_t v_n = 0;
28685 
28686   uint8_t* iop_a_dst = NULL;
28687   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
28688   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
28689   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
28690   if (a_dst) {
28691     io0_a_dst = a_dst->data.ptr;
28692     io1_a_dst = io0_a_dst + a_dst->meta.wi;
28693     iop_a_dst = io1_a_dst;
28694     io2_a_dst = io0_a_dst + a_dst->data.len;
28695     if (a_dst->meta.closed) {
28696       io2_a_dst = iop_a_dst;
28697     }
28698   }
28699 
28700   uint32_t coro_susp_point = self->private_impl.p_write_to[0];
28701   switch (coro_susp_point) {
28702     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
28703 
28704     while (self->private_impl.f_output_wi > 0) {
28705       if (self->private_impl.f_output_ri > self->private_impl.f_output_wi) {
28706         status = wuffs_base__make_status(wuffs_lzw__error__internal_error_inconsistent_i_o);
28707         goto exit;
28708       }
28709       v_s = wuffs_base__slice_u8__subslice_ij(wuffs_base__make_slice_u8(self->private_data.f_output,
28710           8199),
28711           self->private_impl.f_output_ri,
28712           self->private_impl.f_output_wi);
28713       v_n = wuffs_base__io_writer__copy_from_slice(&iop_a_dst, io2_a_dst,v_s);
28714       if (v_n == ((uint64_t)(v_s.len))) {
28715         self->private_impl.f_output_ri = 0;
28716         self->private_impl.f_output_wi = 0;
28717         status = wuffs_base__make_status(NULL);
28718         goto ok;
28719       }
28720       self->private_impl.f_output_ri = (((uint32_t)(self->private_impl.f_output_ri + ((uint32_t)((v_n & 4294967295))))) & 8191);
28721       status = wuffs_base__make_status(wuffs_base__suspension__short_write);
28722       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
28723     }
28724 
28725     ok:
28726     self->private_impl.p_write_to[0] = 0;
28727     goto exit;
28728   }
28729 
28730   goto suspend;
28731   suspend:
28732   self->private_impl.p_write_to[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
28733 
28734   goto exit;
28735   exit:
28736   if (a_dst) {
28737     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
28738   }
28739 
28740   return status;
28741 }
28742 
28743 // -------- func lzw.decoder.flush
28744 
28745 WUFFS_BASE__MAYBE_STATIC wuffs_base__slice_u8
wuffs_lzw__decoder__flush(wuffs_lzw__decoder * self)28746 wuffs_lzw__decoder__flush(
28747     wuffs_lzw__decoder* self) {
28748   if (!self) {
28749     return wuffs_base__make_slice_u8(NULL, 0);
28750   }
28751   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
28752     return wuffs_base__make_slice_u8(NULL, 0);
28753   }
28754 
28755   wuffs_base__slice_u8 v_s = {0};
28756 
28757   if (self->private_impl.f_output_ri <= self->private_impl.f_output_wi) {
28758     v_s = wuffs_base__slice_u8__subslice_ij(wuffs_base__make_slice_u8(self->private_data.f_output,
28759         8199),
28760         self->private_impl.f_output_ri,
28761         self->private_impl.f_output_wi);
28762   }
28763   self->private_impl.f_output_ri = 0;
28764   self->private_impl.f_output_wi = 0;
28765   return v_s;
28766 }
28767 
28768 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZW)
28769 
28770 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GIF)
28771 
28772 // ---------------- Status Codes Implementations
28773 
28774 const char wuffs_gif__error__bad_extension_label[] = "#gif: bad extension label";
28775 const char wuffs_gif__error__bad_frame_size[] = "#gif: bad frame size";
28776 const char wuffs_gif__error__bad_graphic_control[] = "#gif: bad graphic control";
28777 const char wuffs_gif__error__bad_header[] = "#gif: bad header";
28778 const char wuffs_gif__error__bad_literal_width[] = "#gif: bad literal width";
28779 const char wuffs_gif__error__bad_palette[] = "#gif: bad palette";
28780 const char wuffs_gif__error__internal_error_inconsistent_ri_wi[] = "#gif: internal error: inconsistent ri/wi";
28781 
28782 // ---------------- Private Consts
28783 
28784 static const uint32_t
28785 WUFFS_GIF__INTERLACE_START[5] WUFFS_BASE__POTENTIALLY_UNUSED = {
28786   4294967295, 1, 2, 4, 0,
28787 };
28788 
28789 static const uint8_t
28790 WUFFS_GIF__INTERLACE_DELTA[5] WUFFS_BASE__POTENTIALLY_UNUSED = {
28791   1, 2, 4, 8, 8,
28792 };
28793 
28794 static const uint8_t
28795 WUFFS_GIF__INTERLACE_COUNT[5] WUFFS_BASE__POTENTIALLY_UNUSED = {
28796   0, 1, 2, 4, 8,
28797 };
28798 
28799 static const uint8_t
28800 WUFFS_GIF__ANIMEXTS1DOT0[11] WUFFS_BASE__POTENTIALLY_UNUSED = {
28801   65, 78, 73, 77, 69, 88, 84, 83,
28802   49, 46, 48,
28803 };
28804 
28805 static const uint8_t
28806 WUFFS_GIF__NETSCAPE2DOT0[11] WUFFS_BASE__POTENTIALLY_UNUSED = {
28807   78, 69, 84, 83, 67, 65, 80, 69,
28808   50, 46, 48,
28809 };
28810 
28811 static const uint8_t
28812 WUFFS_GIF__ICCRGBG1012[11] WUFFS_BASE__POTENTIALLY_UNUSED = {
28813   73, 67, 67, 82, 71, 66, 71, 49,
28814   48, 49, 50,
28815 };
28816 
28817 static const uint8_t
28818 WUFFS_GIF__XMPDATAXMP[11] WUFFS_BASE__POTENTIALLY_UNUSED = {
28819   88, 77, 80, 32, 68, 97, 116, 97,
28820   88, 77, 80,
28821 };
28822 
28823 #define WUFFS_GIF__QUIRKS_BASE 1041635328
28824 
28825 #define WUFFS_GIF__QUIRKS_COUNT 7
28826 
28827 // ---------------- Private Initializer Prototypes
28828 
28829 // ---------------- Private Function Prototypes
28830 
28831 static wuffs_base__status
28832 wuffs_gif__decoder__skip_frame(
28833     wuffs_gif__decoder* self,
28834     wuffs_base__io_buffer* a_src);
28835 
28836 static wuffs_base__empty_struct
28837 wuffs_gif__decoder__reset_gc(
28838     wuffs_gif__decoder* self);
28839 
28840 static wuffs_base__status
28841 wuffs_gif__decoder__decode_up_to_id_part1(
28842     wuffs_gif__decoder* self,
28843     wuffs_base__io_buffer* a_src);
28844 
28845 static wuffs_base__status
28846 wuffs_gif__decoder__decode_header(
28847     wuffs_gif__decoder* self,
28848     wuffs_base__io_buffer* a_src);
28849 
28850 static wuffs_base__status
28851 wuffs_gif__decoder__decode_lsd(
28852     wuffs_gif__decoder* self,
28853     wuffs_base__io_buffer* a_src);
28854 
28855 static wuffs_base__status
28856 wuffs_gif__decoder__decode_extension(
28857     wuffs_gif__decoder* self,
28858     wuffs_base__io_buffer* a_src);
28859 
28860 static wuffs_base__status
28861 wuffs_gif__decoder__skip_blocks(
28862     wuffs_gif__decoder* self,
28863     wuffs_base__io_buffer* a_src);
28864 
28865 static wuffs_base__status
28866 wuffs_gif__decoder__decode_ae(
28867     wuffs_gif__decoder* self,
28868     wuffs_base__io_buffer* a_src);
28869 
28870 static wuffs_base__status
28871 wuffs_gif__decoder__decode_gc(
28872     wuffs_gif__decoder* self,
28873     wuffs_base__io_buffer* a_src);
28874 
28875 static wuffs_base__status
28876 wuffs_gif__decoder__decode_id_part0(
28877     wuffs_gif__decoder* self,
28878     wuffs_base__io_buffer* a_src);
28879 
28880 static wuffs_base__status
28881 wuffs_gif__decoder__decode_id_part1(
28882     wuffs_gif__decoder* self,
28883     wuffs_base__pixel_buffer* a_dst,
28884     wuffs_base__io_buffer* a_src,
28885     wuffs_base__pixel_blend a_blend);
28886 
28887 static wuffs_base__status
28888 wuffs_gif__decoder__decode_id_part2(
28889     wuffs_gif__decoder* self,
28890     wuffs_base__pixel_buffer* a_dst,
28891     wuffs_base__io_buffer* a_src,
28892     wuffs_base__slice_u8 a_workbuf);
28893 
28894 static wuffs_base__status
28895 wuffs_gif__decoder__copy_to_image_buffer(
28896     wuffs_gif__decoder* self,
28897     wuffs_base__pixel_buffer* a_pb,
28898     wuffs_base__slice_u8 a_src);
28899 
28900 // ---------------- VTables
28901 
28902 const wuffs_base__image_decoder__func_ptrs
28903 wuffs_gif__decoder__func_ptrs_for__wuffs_base__image_decoder = {
28904   (wuffs_base__status(*)(void*,
28905       wuffs_base__pixel_buffer*,
28906       wuffs_base__io_buffer*,
28907       wuffs_base__pixel_blend,
28908       wuffs_base__slice_u8,
28909       wuffs_base__decode_frame_options*))(&wuffs_gif__decoder__decode_frame),
28910   (wuffs_base__status(*)(void*,
28911       wuffs_base__frame_config*,
28912       wuffs_base__io_buffer*))(&wuffs_gif__decoder__decode_frame_config),
28913   (wuffs_base__status(*)(void*,
28914       wuffs_base__image_config*,
28915       wuffs_base__io_buffer*))(&wuffs_gif__decoder__decode_image_config),
28916   (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_gif__decoder__frame_dirty_rect),
28917   (uint32_t(*)(const void*))(&wuffs_gif__decoder__num_animation_loops),
28918   (uint64_t(*)(const void*))(&wuffs_gif__decoder__num_decoded_frame_configs),
28919   (uint64_t(*)(const void*))(&wuffs_gif__decoder__num_decoded_frames),
28920   (wuffs_base__status(*)(void*,
28921       uint64_t,
28922       uint64_t))(&wuffs_gif__decoder__restart_frame),
28923   (wuffs_base__empty_struct(*)(void*,
28924       uint32_t,
28925       bool))(&wuffs_gif__decoder__set_quirk_enabled),
28926   (wuffs_base__empty_struct(*)(void*,
28927       uint32_t,
28928       bool))(&wuffs_gif__decoder__set_report_metadata),
28929   (wuffs_base__status(*)(void*,
28930       wuffs_base__io_buffer*,
28931       wuffs_base__more_information*,
28932       wuffs_base__io_buffer*))(&wuffs_gif__decoder__tell_me_more),
28933   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_gif__decoder__workbuf_len),
28934 };
28935 
28936 // ---------------- Initializer Implementations
28937 
28938 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)28939 wuffs_gif__decoder__initialize(
28940     wuffs_gif__decoder* self,
28941     size_t sizeof_star_self,
28942     uint64_t wuffs_version,
28943     uint32_t options){
28944   if (!self) {
28945     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
28946   }
28947   if (sizeof(*self) != sizeof_star_self) {
28948     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
28949   }
28950   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
28951       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
28952     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
28953   }
28954 
28955   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
28956     // The whole point of this if-check is to detect an uninitialized *self.
28957     // We disable the warning on GCC. Clang-5.0 does not have this warning.
28958 #if !defined(__clang__) && defined(__GNUC__)
28959 #pragma GCC diagnostic push
28960 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
28961 #endif
28962     if (self->private_impl.magic != 0) {
28963       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
28964     }
28965 #if !defined(__clang__) && defined(__GNUC__)
28966 #pragma GCC diagnostic pop
28967 #endif
28968   } else {
28969     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
28970       memset(self, 0, sizeof(*self));
28971       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
28972     } else {
28973       memset(&(self->private_impl), 0, sizeof(self->private_impl));
28974     }
28975   }
28976 
28977   {
28978     wuffs_base__status z = wuffs_lzw__decoder__initialize(
28979         &self->private_data.f_lzw, sizeof(self->private_data.f_lzw), WUFFS_VERSION, options);
28980     if (z.repr) {
28981       return z;
28982     }
28983   }
28984   self->private_impl.magic = WUFFS_BASE__MAGIC;
28985   self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
28986       wuffs_base__image_decoder__vtable_name;
28987   self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
28988       (const void*)(&wuffs_gif__decoder__func_ptrs_for__wuffs_base__image_decoder);
28989   return wuffs_base__make_status(NULL);
28990 }
28991 
28992 wuffs_gif__decoder*
wuffs_gif__decoder__alloc()28993 wuffs_gif__decoder__alloc() {
28994   wuffs_gif__decoder* x =
28995       (wuffs_gif__decoder*)(calloc(sizeof(wuffs_gif__decoder), 1));
28996   if (!x) {
28997     return NULL;
28998   }
28999   if (wuffs_gif__decoder__initialize(
29000       x, sizeof(wuffs_gif__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
29001     free(x);
29002     return NULL;
29003   }
29004   return x;
29005 }
29006 
29007 size_t
sizeof__wuffs_gif__decoder()29008 sizeof__wuffs_gif__decoder() {
29009   return sizeof(wuffs_gif__decoder);
29010 }
29011 
29012 // ---------------- Function Implementations
29013 
29014 // -------- func gif.decoder.set_quirk_enabled
29015 
29016 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_gif__decoder__set_quirk_enabled(wuffs_gif__decoder * self,uint32_t a_quirk,bool a_enabled)29017 wuffs_gif__decoder__set_quirk_enabled(
29018     wuffs_gif__decoder* self,
29019     uint32_t a_quirk,
29020     bool a_enabled) {
29021   if (!self) {
29022     return wuffs_base__make_empty_struct();
29023   }
29024   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
29025     return wuffs_base__make_empty_struct();
29026   }
29027 
29028   if ((self->private_impl.f_call_sequence == 0) && (a_quirk >= 1041635328)) {
29029     a_quirk -= 1041635328;
29030     if (a_quirk < 7) {
29031       self->private_impl.f_quirks[a_quirk] = a_enabled;
29032     }
29033   }
29034   return wuffs_base__make_empty_struct();
29035 }
29036 
29037 // -------- func gif.decoder.decode_image_config
29038 
29039 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)29040 wuffs_gif__decoder__decode_image_config(
29041     wuffs_gif__decoder* self,
29042     wuffs_base__image_config* a_dst,
29043     wuffs_base__io_buffer* a_src) {
29044   if (!self) {
29045     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
29046   }
29047   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
29048     return wuffs_base__make_status(
29049         (self->private_impl.magic == WUFFS_BASE__DISABLED)
29050         ? wuffs_base__error__disabled_by_previous_error
29051         : wuffs_base__error__initialize_not_called);
29052   }
29053   if (!a_src) {
29054     self->private_impl.magic = WUFFS_BASE__DISABLED;
29055     return wuffs_base__make_status(wuffs_base__error__bad_argument);
29056   }
29057   if ((self->private_impl.active_coroutine != 0) &&
29058       (self->private_impl.active_coroutine != 1)) {
29059     self->private_impl.magic = WUFFS_BASE__DISABLED;
29060     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
29061   }
29062   self->private_impl.active_coroutine = 0;
29063   wuffs_base__status status = wuffs_base__make_status(NULL);
29064 
29065   bool v_ffio = false;
29066 
29067   uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
29068   switch (coro_susp_point) {
29069     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
29070 
29071     if (self->private_impl.f_call_sequence == 0) {
29072       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
29073       status = wuffs_gif__decoder__decode_header(self, a_src);
29074       if (status.repr) {
29075         goto suspend;
29076       }
29077       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
29078       status = wuffs_gif__decoder__decode_lsd(self, a_src);
29079       if (status.repr) {
29080         goto suspend;
29081       }
29082     } else if (self->private_impl.f_call_sequence != 2) {
29083       status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
29084       goto exit;
29085     }
29086     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
29087     status = wuffs_gif__decoder__decode_up_to_id_part1(self, a_src);
29088     if (status.repr) {
29089       goto suspend;
29090     }
29091     v_ffio =  ! self->private_impl.f_gc_has_transparent_index;
29092     if ( ! self->private_impl.f_quirks[2]) {
29093       v_ffio = (v_ffio &&
29094           (self->private_impl.f_frame_rect_x0 == 0) &&
29095           (self->private_impl.f_frame_rect_y0 == 0) &&
29096           (self->private_impl.f_frame_rect_x1 == self->private_impl.f_width) &&
29097           (self->private_impl.f_frame_rect_y1 == self->private_impl.f_height));
29098     } else if (v_ffio) {
29099       self->private_impl.f_black_color_u32_argb_premul = 4278190080;
29100     }
29101     if (self->private_impl.f_background_color_u32_argb_premul == 77) {
29102       self->private_impl.f_background_color_u32_argb_premul = self->private_impl.f_black_color_u32_argb_premul;
29103     }
29104     if (a_dst != NULL) {
29105       wuffs_base__image_config__set(
29106           a_dst,
29107           2198077448,
29108           0,
29109           self->private_impl.f_width,
29110           self->private_impl.f_height,
29111           self->private_impl.f_frame_config_io_position,
29112           v_ffio);
29113     }
29114     self->private_impl.f_call_sequence = 3;
29115 
29116     goto ok;
29117     ok:
29118     self->private_impl.p_decode_image_config[0] = 0;
29119     goto exit;
29120   }
29121 
29122   goto suspend;
29123   suspend:
29124   self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
29125   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
29126 
29127   goto exit;
29128   exit:
29129   if (wuffs_base__status__is_error(&status)) {
29130     self->private_impl.magic = WUFFS_BASE__DISABLED;
29131   }
29132   return status;
29133 }
29134 
29135 // -------- func gif.decoder.set_report_metadata
29136 
29137 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)29138 wuffs_gif__decoder__set_report_metadata(
29139     wuffs_gif__decoder* self,
29140     uint32_t a_fourcc,
29141     bool a_report) {
29142   if (!self) {
29143     return wuffs_base__make_empty_struct();
29144   }
29145   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
29146     return wuffs_base__make_empty_struct();
29147   }
29148 
29149   if (a_fourcc == 1229144912) {
29150     self->private_impl.f_report_metadata_iccp = a_report;
29151   } else if (a_fourcc == 1481461792) {
29152     self->private_impl.f_report_metadata_xmp = a_report;
29153   }
29154   return wuffs_base__make_empty_struct();
29155 }
29156 
29157 // -------- func gif.decoder.tell_me_more
29158 
29159 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)29160 wuffs_gif__decoder__tell_me_more(
29161     wuffs_gif__decoder* self,
29162     wuffs_base__io_buffer* a_dst,
29163     wuffs_base__more_information* a_minfo,
29164     wuffs_base__io_buffer* a_src) {
29165   if (!self) {
29166     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
29167   }
29168   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
29169     return wuffs_base__make_status(
29170         (self->private_impl.magic == WUFFS_BASE__DISABLED)
29171         ? wuffs_base__error__disabled_by_previous_error
29172         : wuffs_base__error__initialize_not_called);
29173   }
29174   if (!a_dst || !a_src) {
29175     self->private_impl.magic = WUFFS_BASE__DISABLED;
29176     return wuffs_base__make_status(wuffs_base__error__bad_argument);
29177   }
29178   if ((self->private_impl.active_coroutine != 0) &&
29179       (self->private_impl.active_coroutine != 2)) {
29180     self->private_impl.magic = WUFFS_BASE__DISABLED;
29181     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
29182   }
29183   self->private_impl.active_coroutine = 0;
29184   wuffs_base__status status = wuffs_base__make_status(NULL);
29185 
29186   uint64_t v_chunk_length = 0;
29187 
29188   const uint8_t* iop_a_src = NULL;
29189   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29190   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29191   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29192   if (a_src) {
29193     io0_a_src = a_src->data.ptr;
29194     io1_a_src = io0_a_src + a_src->meta.ri;
29195     iop_a_src = io1_a_src;
29196     io2_a_src = io0_a_src + a_src->meta.wi;
29197   }
29198 
29199   uint32_t coro_susp_point = self->private_impl.p_tell_me_more[0];
29200   switch (coro_susp_point) {
29201     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
29202 
29203     if (self->private_impl.f_call_sequence != 1) {
29204       status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
29205       goto exit;
29206     }
29207     if (self->private_impl.f_metadata_fourcc == 0) {
29208       status = wuffs_base__make_status(wuffs_base__error__no_more_information);
29209       goto exit;
29210     }
29211     while (true) {
29212       label__0__continue:;
29213       while (true) {
29214         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) {
29215           if (a_minfo != NULL) {
29216             wuffs_base__more_information__set(a_minfo,
29217                 2,
29218                 0,
29219                 self->private_impl.f_metadata_io_position,
29220                 0,
29221                 0);
29222           }
29223           status = wuffs_base__make_status(wuffs_base__suspension__mispositioned_read);
29224           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
29225           goto label__0__continue;
29226         }
29227         if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
29228           if (a_minfo != NULL) {
29229             wuffs_base__more_information__set(a_minfo,
29230                 0,
29231                 0,
29232                 0,
29233                 0,
29234                 0);
29235           }
29236           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
29237           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
29238           goto label__0__continue;
29239         }
29240         goto label__0__break;
29241       }
29242       label__0__break:;
29243       v_chunk_length = ((uint64_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src)));
29244       if (v_chunk_length <= 0) {
29245         iop_a_src += 1;
29246         goto label__1__break;
29247       }
29248       if (self->private_impl.f_metadata_fourcc == 1481461792) {
29249         v_chunk_length += 1;
29250       } else {
29251         iop_a_src += 1;
29252       }
29253       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);
29254       if (a_minfo != NULL) {
29255         wuffs_base__more_information__set(a_minfo,
29256             3,
29257             self->private_impl.f_metadata_fourcc,
29258             0,
29259             wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))),
29260             self->private_impl.f_metadata_io_position);
29261       }
29262       status = wuffs_base__make_status(wuffs_base__suspension__even_more_information);
29263       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
29264     }
29265     label__1__break:;
29266     if (a_minfo != NULL) {
29267       wuffs_base__more_information__set(a_minfo,
29268           3,
29269           self->private_impl.f_metadata_fourcc,
29270           0,
29271           self->private_impl.f_metadata_io_position,
29272           self->private_impl.f_metadata_io_position);
29273     }
29274     self->private_impl.f_call_sequence = 2;
29275     self->private_impl.f_metadata_fourcc = 0;
29276     self->private_impl.f_metadata_io_position = 0;
29277     status = wuffs_base__make_status(NULL);
29278     goto ok;
29279 
29280     ok:
29281     self->private_impl.p_tell_me_more[0] = 0;
29282     goto exit;
29283   }
29284 
29285   goto suspend;
29286   suspend:
29287   self->private_impl.p_tell_me_more[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
29288   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
29289 
29290   goto exit;
29291   exit:
29292   if (a_src) {
29293     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
29294   }
29295 
29296   if (wuffs_base__status__is_error(&status)) {
29297     self->private_impl.magic = WUFFS_BASE__DISABLED;
29298   }
29299   return status;
29300 }
29301 
29302 // -------- func gif.decoder.num_animation_loops
29303 
29304 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_gif__decoder__num_animation_loops(const wuffs_gif__decoder * self)29305 wuffs_gif__decoder__num_animation_loops(
29306     const wuffs_gif__decoder* self) {
29307   if (!self) {
29308     return 0;
29309   }
29310   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
29311       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
29312     return 0;
29313   }
29314 
29315   if (self->private_impl.f_seen_num_animation_loops_value) {
29316     return self->private_impl.f_num_animation_loops_value;
29317   }
29318   return 1;
29319 }
29320 
29321 // -------- func gif.decoder.num_decoded_frame_configs
29322 
29323 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_gif__decoder__num_decoded_frame_configs(const wuffs_gif__decoder * self)29324 wuffs_gif__decoder__num_decoded_frame_configs(
29325     const wuffs_gif__decoder* self) {
29326   if (!self) {
29327     return 0;
29328   }
29329   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
29330       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
29331     return 0;
29332   }
29333 
29334   return self->private_impl.f_num_decoded_frame_configs_value;
29335 }
29336 
29337 // -------- func gif.decoder.num_decoded_frames
29338 
29339 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_gif__decoder__num_decoded_frames(const wuffs_gif__decoder * self)29340 wuffs_gif__decoder__num_decoded_frames(
29341     const wuffs_gif__decoder* self) {
29342   if (!self) {
29343     return 0;
29344   }
29345   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
29346       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
29347     return 0;
29348   }
29349 
29350   return self->private_impl.f_num_decoded_frames_value;
29351 }
29352 
29353 // -------- func gif.decoder.frame_dirty_rect
29354 
29355 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
wuffs_gif__decoder__frame_dirty_rect(const wuffs_gif__decoder * self)29356 wuffs_gif__decoder__frame_dirty_rect(
29357     const wuffs_gif__decoder* self) {
29358   if (!self) {
29359     return wuffs_base__utility__empty_rect_ie_u32();
29360   }
29361   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
29362       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
29363     return wuffs_base__utility__empty_rect_ie_u32();
29364   }
29365 
29366   return wuffs_base__utility__make_rect_ie_u32(
29367       wuffs_base__u32__min(self->private_impl.f_frame_rect_x0, self->private_impl.f_width),
29368       wuffs_base__u32__min(self->private_impl.f_frame_rect_y0, self->private_impl.f_height),
29369       wuffs_base__u32__min(self->private_impl.f_frame_rect_x1, self->private_impl.f_width),
29370       wuffs_base__u32__min(self->private_impl.f_dirty_max_excl_y, self->private_impl.f_height));
29371 }
29372 
29373 // -------- func gif.decoder.workbuf_len
29374 
29375 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_gif__decoder__workbuf_len(const wuffs_gif__decoder * self)29376 wuffs_gif__decoder__workbuf_len(
29377     const wuffs_gif__decoder* self) {
29378   if (!self) {
29379     return wuffs_base__utility__empty_range_ii_u64();
29380   }
29381   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
29382       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
29383     return wuffs_base__utility__empty_range_ii_u64();
29384   }
29385 
29386   return wuffs_base__utility__make_range_ii_u64(0, 0);
29387 }
29388 
29389 // -------- func gif.decoder.restart_frame
29390 
29391 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)29392 wuffs_gif__decoder__restart_frame(
29393     wuffs_gif__decoder* self,
29394     uint64_t a_index,
29395     uint64_t a_io_position) {
29396   if (!self) {
29397     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
29398   }
29399   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
29400     return wuffs_base__make_status(
29401         (self->private_impl.magic == WUFFS_BASE__DISABLED)
29402         ? wuffs_base__error__disabled_by_previous_error
29403         : wuffs_base__error__initialize_not_called);
29404   }
29405 
29406   if (self->private_impl.f_call_sequence < 3) {
29407     return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
29408   }
29409   self->private_impl.f_delayed_num_decoded_frames = false;
29410   self->private_impl.f_end_of_data = false;
29411   self->private_impl.f_restarted = true;
29412   self->private_impl.f_frame_config_io_position = a_io_position;
29413   self->private_impl.f_num_decoded_frame_configs_value = a_index;
29414   self->private_impl.f_num_decoded_frames_value = a_index;
29415   wuffs_gif__decoder__reset_gc(self);
29416   return wuffs_base__make_status(NULL);
29417 }
29418 
29419 // -------- func gif.decoder.decode_frame_config
29420 
29421 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)29422 wuffs_gif__decoder__decode_frame_config(
29423     wuffs_gif__decoder* self,
29424     wuffs_base__frame_config* a_dst,
29425     wuffs_base__io_buffer* a_src) {
29426   if (!self) {
29427     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
29428   }
29429   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
29430     return wuffs_base__make_status(
29431         (self->private_impl.magic == WUFFS_BASE__DISABLED)
29432         ? wuffs_base__error__disabled_by_previous_error
29433         : wuffs_base__error__initialize_not_called);
29434   }
29435   if (!a_src) {
29436     self->private_impl.magic = WUFFS_BASE__DISABLED;
29437     return wuffs_base__make_status(wuffs_base__error__bad_argument);
29438   }
29439   if ((self->private_impl.active_coroutine != 0) &&
29440       (self->private_impl.active_coroutine != 3)) {
29441     self->private_impl.magic = WUFFS_BASE__DISABLED;
29442     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
29443   }
29444   self->private_impl.active_coroutine = 0;
29445   wuffs_base__status status = wuffs_base__make_status(NULL);
29446 
29447   uint32_t v_background_color = 0;
29448   uint8_t v_flags = 0;
29449 
29450   const uint8_t* iop_a_src = NULL;
29451   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29452   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29453   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29454   if (a_src) {
29455     io0_a_src = a_src->data.ptr;
29456     io1_a_src = io0_a_src + a_src->meta.ri;
29457     iop_a_src = io1_a_src;
29458     io2_a_src = io0_a_src + a_src->meta.wi;
29459   }
29460 
29461   uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
29462   if (coro_susp_point) {
29463     v_background_color = self->private_data.s_decode_frame_config[0].v_background_color;
29464   }
29465   switch (coro_susp_point) {
29466     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
29467 
29468     self->private_impl.f_ignore_metadata = true;
29469     self->private_impl.f_dirty_max_excl_y = 0;
29470     if ( ! self->private_impl.f_end_of_data) {
29471       if (self->private_impl.f_call_sequence == 0) {
29472         if (a_src) {
29473           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
29474         }
29475         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
29476         status = wuffs_gif__decoder__decode_image_config(self, NULL, a_src);
29477         if (a_src) {
29478           iop_a_src = a_src->data.ptr + a_src->meta.ri;
29479         }
29480         if (status.repr) {
29481           goto suspend;
29482         }
29483       } else if (self->private_impl.f_call_sequence != 3) {
29484         if (self->private_impl.f_call_sequence == 4) {
29485           if (a_src) {
29486             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
29487           }
29488           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
29489           status = wuffs_gif__decoder__skip_frame(self, a_src);
29490           if (a_src) {
29491             iop_a_src = a_src->data.ptr + a_src->meta.ri;
29492           }
29493           if (status.repr) {
29494             goto suspend;
29495           }
29496         }
29497         if (a_src) {
29498           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
29499         }
29500         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
29501         status = wuffs_gif__decoder__decode_up_to_id_part1(self, a_src);
29502         if (a_src) {
29503           iop_a_src = a_src->data.ptr + a_src->meta.ri;
29504         }
29505         if (status.repr) {
29506           goto suspend;
29507         }
29508       }
29509     }
29510     if (self->private_impl.f_end_of_data) {
29511       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
29512       goto ok;
29513     }
29514     v_background_color = self->private_impl.f_black_color_u32_argb_premul;
29515     if ( ! self->private_impl.f_gc_has_transparent_index) {
29516       v_background_color = self->private_impl.f_background_color_u32_argb_premul;
29517       if (self->private_impl.f_quirks[1] && (self->private_impl.f_num_decoded_frame_configs_value == 0)) {
29518         while (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
29519           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
29520           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
29521         }
29522         v_flags = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
29523         if ((v_flags & 128) != 0) {
29524           v_background_color = self->private_impl.f_black_color_u32_argb_premul;
29525         }
29526       }
29527     }
29528     if (a_dst != NULL) {
29529       wuffs_base__frame_config__set(
29530           a_dst,
29531           wuffs_base__utility__make_rect_ie_u32(
29532           wuffs_base__u32__min(self->private_impl.f_frame_rect_x0, self->private_impl.f_width),
29533           wuffs_base__u32__min(self->private_impl.f_frame_rect_y0, self->private_impl.f_height),
29534           wuffs_base__u32__min(self->private_impl.f_frame_rect_x1, self->private_impl.f_width),
29535           wuffs_base__u32__min(self->private_impl.f_frame_rect_y1, self->private_impl.f_height)),
29536           ((wuffs_base__flicks)(self->private_impl.f_gc_duration)),
29537           self->private_impl.f_num_decoded_frame_configs_value,
29538           self->private_impl.f_frame_config_io_position,
29539           self->private_impl.f_gc_disposal,
29540           ! self->private_impl.f_gc_has_transparent_index,
29541           false,
29542           v_background_color);
29543     }
29544     wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frame_configs_value, 1);
29545     self->private_impl.f_call_sequence = 4;
29546 
29547     ok:
29548     self->private_impl.p_decode_frame_config[0] = 0;
29549     goto exit;
29550   }
29551 
29552   goto suspend;
29553   suspend:
29554   self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
29555   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
29556   self->private_data.s_decode_frame_config[0].v_background_color = v_background_color;
29557 
29558   goto exit;
29559   exit:
29560   if (a_src) {
29561     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
29562   }
29563 
29564   if (wuffs_base__status__is_error(&status)) {
29565     self->private_impl.magic = WUFFS_BASE__DISABLED;
29566   }
29567   return status;
29568 }
29569 
29570 // -------- func gif.decoder.skip_frame
29571 
29572 static wuffs_base__status
wuffs_gif__decoder__skip_frame(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)29573 wuffs_gif__decoder__skip_frame(
29574     wuffs_gif__decoder* self,
29575     wuffs_base__io_buffer* a_src) {
29576   wuffs_base__status status = wuffs_base__make_status(NULL);
29577 
29578   uint8_t v_flags = 0;
29579   uint8_t v_lw = 0;
29580 
29581   const uint8_t* iop_a_src = NULL;
29582   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29583   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29584   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29585   if (a_src) {
29586     io0_a_src = a_src->data.ptr;
29587     io1_a_src = io0_a_src + a_src->meta.ri;
29588     iop_a_src = io1_a_src;
29589     io2_a_src = io0_a_src + a_src->meta.wi;
29590   }
29591 
29592   uint32_t coro_susp_point = self->private_impl.p_skip_frame[0];
29593   switch (coro_susp_point) {
29594     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
29595 
29596     {
29597       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
29598       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
29599         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
29600         goto suspend;
29601       }
29602       uint8_t t_0 = *iop_a_src++;
29603       v_flags = t_0;
29604     }
29605     if ((v_flags & 128) != 0) {
29606       self->private_data.s_skip_frame[0].scratch = (((uint32_t)(3)) << (1 + (v_flags & 7)));
29607       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
29608       if (self->private_data.s_skip_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
29609         self->private_data.s_skip_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
29610         iop_a_src = io2_a_src;
29611         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
29612         goto suspend;
29613       }
29614       iop_a_src += self->private_data.s_skip_frame[0].scratch;
29615     }
29616     {
29617       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
29618       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
29619         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
29620         goto suspend;
29621       }
29622       uint8_t t_1 = *iop_a_src++;
29623       v_lw = t_1;
29624     }
29625     if (v_lw > 8) {
29626       status = wuffs_base__make_status(wuffs_gif__error__bad_literal_width);
29627       goto exit;
29628     }
29629     if (a_src) {
29630       a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
29631     }
29632     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
29633     status = wuffs_gif__decoder__skip_blocks(self, a_src);
29634     if (a_src) {
29635       iop_a_src = a_src->data.ptr + a_src->meta.ri;
29636     }
29637     if (status.repr) {
29638       goto suspend;
29639     }
29640     if (self->private_impl.f_quirks[0]) {
29641       self->private_impl.f_delayed_num_decoded_frames = true;
29642     } else {
29643       wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1);
29644     }
29645     wuffs_gif__decoder__reset_gc(self);
29646 
29647     goto ok;
29648     ok:
29649     self->private_impl.p_skip_frame[0] = 0;
29650     goto exit;
29651   }
29652 
29653   goto suspend;
29654   suspend:
29655   self->private_impl.p_skip_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
29656 
29657   goto exit;
29658   exit:
29659   if (a_src) {
29660     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
29661   }
29662 
29663   return status;
29664 }
29665 
29666 // -------- func gif.decoder.decode_frame
29667 
29668 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)29669 wuffs_gif__decoder__decode_frame(
29670     wuffs_gif__decoder* self,
29671     wuffs_base__pixel_buffer* a_dst,
29672     wuffs_base__io_buffer* a_src,
29673     wuffs_base__pixel_blend a_blend,
29674     wuffs_base__slice_u8 a_workbuf,
29675     wuffs_base__decode_frame_options* a_opts) {
29676   if (!self) {
29677     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
29678   }
29679   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
29680     return wuffs_base__make_status(
29681         (self->private_impl.magic == WUFFS_BASE__DISABLED)
29682         ? wuffs_base__error__disabled_by_previous_error
29683         : wuffs_base__error__initialize_not_called);
29684   }
29685   if (!a_dst || !a_src) {
29686     self->private_impl.magic = WUFFS_BASE__DISABLED;
29687     return wuffs_base__make_status(wuffs_base__error__bad_argument);
29688   }
29689   if ((self->private_impl.active_coroutine != 0) &&
29690       (self->private_impl.active_coroutine != 4)) {
29691     self->private_impl.magic = WUFFS_BASE__DISABLED;
29692     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
29693   }
29694   self->private_impl.active_coroutine = 0;
29695   wuffs_base__status status = wuffs_base__make_status(NULL);
29696 
29697   uint32_t coro_susp_point = self->private_impl.p_decode_frame[0];
29698   switch (coro_susp_point) {
29699     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
29700 
29701     self->private_impl.f_ignore_metadata = true;
29702     if (self->private_impl.f_call_sequence != 4) {
29703       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
29704       status = wuffs_gif__decoder__decode_frame_config(self, NULL, a_src);
29705       if (status.repr) {
29706         goto suspend;
29707       }
29708     }
29709     if (self->private_impl.f_quirks[5] && ((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))) {
29710       status = wuffs_base__make_status(wuffs_gif__error__bad_frame_size);
29711       goto exit;
29712     }
29713     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
29714     status = wuffs_gif__decoder__decode_id_part1(self, a_dst, a_src, a_blend);
29715     if (status.repr) {
29716       goto suspend;
29717     }
29718     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
29719     status = wuffs_gif__decoder__decode_id_part2(self, a_dst, a_src, a_workbuf);
29720     if (status.repr) {
29721       goto suspend;
29722     }
29723     wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1);
29724     wuffs_gif__decoder__reset_gc(self);
29725 
29726     goto ok;
29727     ok:
29728     self->private_impl.p_decode_frame[0] = 0;
29729     goto exit;
29730   }
29731 
29732   goto suspend;
29733   suspend:
29734   self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
29735   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 4 : 0;
29736 
29737   goto exit;
29738   exit:
29739   if (wuffs_base__status__is_error(&status)) {
29740     self->private_impl.magic = WUFFS_BASE__DISABLED;
29741   }
29742   return status;
29743 }
29744 
29745 // -------- func gif.decoder.reset_gc
29746 
29747 static wuffs_base__empty_struct
wuffs_gif__decoder__reset_gc(wuffs_gif__decoder * self)29748 wuffs_gif__decoder__reset_gc(
29749     wuffs_gif__decoder* self) {
29750   self->private_impl.f_call_sequence = 5;
29751   self->private_impl.f_gc_has_transparent_index = false;
29752   self->private_impl.f_gc_transparent_index = 0;
29753   self->private_impl.f_gc_disposal = 0;
29754   self->private_impl.f_gc_duration = 0;
29755   return wuffs_base__make_empty_struct();
29756 }
29757 
29758 // -------- func gif.decoder.decode_up_to_id_part1
29759 
29760 static wuffs_base__status
wuffs_gif__decoder__decode_up_to_id_part1(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)29761 wuffs_gif__decoder__decode_up_to_id_part1(
29762     wuffs_gif__decoder* self,
29763     wuffs_base__io_buffer* a_src) {
29764   wuffs_base__status status = wuffs_base__make_status(NULL);
29765 
29766   uint8_t v_block_type = 0;
29767 
29768   const uint8_t* iop_a_src = NULL;
29769   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29770   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29771   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29772   if (a_src) {
29773     io0_a_src = a_src->data.ptr;
29774     io1_a_src = io0_a_src + a_src->meta.ri;
29775     iop_a_src = io1_a_src;
29776     io2_a_src = io0_a_src + a_src->meta.wi;
29777   }
29778 
29779   uint32_t coro_susp_point = self->private_impl.p_decode_up_to_id_part1[0];
29780   switch (coro_susp_point) {
29781     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
29782 
29783     if ( ! self->private_impl.f_restarted) {
29784       if (self->private_impl.f_call_sequence != 2) {
29785         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)));
29786       }
29787     } else 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)))) {
29788       status = wuffs_base__make_status(wuffs_base__error__bad_restart);
29789       goto exit;
29790     } else {
29791       self->private_impl.f_restarted = false;
29792     }
29793     while (true) {
29794       {
29795         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
29796         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
29797           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
29798           goto suspend;
29799         }
29800         uint8_t t_0 = *iop_a_src++;
29801         v_block_type = t_0;
29802       }
29803       if (v_block_type == 33) {
29804         if (a_src) {
29805           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
29806         }
29807         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
29808         status = wuffs_gif__decoder__decode_extension(self, a_src);
29809         if (a_src) {
29810           iop_a_src = a_src->data.ptr + a_src->meta.ri;
29811         }
29812         if (status.repr) {
29813           goto suspend;
29814         }
29815       } else if (v_block_type == 44) {
29816         if (self->private_impl.f_delayed_num_decoded_frames) {
29817           self->private_impl.f_delayed_num_decoded_frames = false;
29818           wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1);
29819         }
29820         if (a_src) {
29821           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
29822         }
29823         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
29824         status = wuffs_gif__decoder__decode_id_part0(self, a_src);
29825         if (a_src) {
29826           iop_a_src = a_src->data.ptr + a_src->meta.ri;
29827         }
29828         if (status.repr) {
29829           goto suspend;
29830         }
29831         goto label__0__break;
29832       } else {
29833         if (self->private_impl.f_delayed_num_decoded_frames) {
29834           self->private_impl.f_delayed_num_decoded_frames = false;
29835           wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1);
29836         }
29837         self->private_impl.f_end_of_data = true;
29838         goto label__0__break;
29839       }
29840     }
29841     label__0__break:;
29842 
29843     goto ok;
29844     ok:
29845     self->private_impl.p_decode_up_to_id_part1[0] = 0;
29846     goto exit;
29847   }
29848 
29849   goto suspend;
29850   suspend:
29851   self->private_impl.p_decode_up_to_id_part1[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
29852 
29853   goto exit;
29854   exit:
29855   if (a_src) {
29856     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
29857   }
29858 
29859   return status;
29860 }
29861 
29862 // -------- func gif.decoder.decode_header
29863 
29864 static wuffs_base__status
wuffs_gif__decoder__decode_header(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)29865 wuffs_gif__decoder__decode_header(
29866     wuffs_gif__decoder* self,
29867     wuffs_base__io_buffer* a_src) {
29868   wuffs_base__status status = wuffs_base__make_status(NULL);
29869 
29870   uint8_t v_c[6] = {0};
29871   uint32_t v_i = 0;
29872 
29873   const uint8_t* iop_a_src = NULL;
29874   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29875   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29876   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29877   if (a_src) {
29878     io0_a_src = a_src->data.ptr;
29879     io1_a_src = io0_a_src + a_src->meta.ri;
29880     iop_a_src = io1_a_src;
29881     io2_a_src = io0_a_src + a_src->meta.wi;
29882   }
29883 
29884   uint32_t coro_susp_point = self->private_impl.p_decode_header[0];
29885   if (coro_susp_point) {
29886     memcpy(v_c, self->private_data.s_decode_header[0].v_c, sizeof(v_c));
29887     v_i = self->private_data.s_decode_header[0].v_i;
29888   }
29889   switch (coro_susp_point) {
29890     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
29891 
29892     while (v_i < 6) {
29893       {
29894         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
29895         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
29896           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
29897           goto suspend;
29898         }
29899         uint8_t t_0 = *iop_a_src++;
29900         v_c[v_i] = t_0;
29901       }
29902       v_i += 1;
29903     }
29904     if ((v_c[0] != 71) ||
29905         (v_c[1] != 73) ||
29906         (v_c[2] != 70) ||
29907         (v_c[3] != 56) ||
29908         ((v_c[4] != 55) && (v_c[4] != 57)) ||
29909         (v_c[5] != 97)) {
29910       status = wuffs_base__make_status(wuffs_gif__error__bad_header);
29911       goto exit;
29912     }
29913 
29914     goto ok;
29915     ok:
29916     self->private_impl.p_decode_header[0] = 0;
29917     goto exit;
29918   }
29919 
29920   goto suspend;
29921   suspend:
29922   self->private_impl.p_decode_header[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
29923   memcpy(self->private_data.s_decode_header[0].v_c, v_c, sizeof(v_c));
29924   self->private_data.s_decode_header[0].v_i = v_i;
29925 
29926   goto exit;
29927   exit:
29928   if (a_src) {
29929     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
29930   }
29931 
29932   return status;
29933 }
29934 
29935 // -------- func gif.decoder.decode_lsd
29936 
29937 static wuffs_base__status
wuffs_gif__decoder__decode_lsd(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)29938 wuffs_gif__decoder__decode_lsd(
29939     wuffs_gif__decoder* self,
29940     wuffs_base__io_buffer* a_src) {
29941   wuffs_base__status status = wuffs_base__make_status(NULL);
29942 
29943   uint8_t v_flags = 0;
29944   uint8_t v_background_color_index = 0;
29945   uint32_t v_num_palette_entries = 0;
29946   uint32_t v_i = 0;
29947   uint32_t v_j = 0;
29948   uint32_t v_argb = 0;
29949 
29950   const uint8_t* iop_a_src = NULL;
29951   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29952   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29953   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29954   if (a_src) {
29955     io0_a_src = a_src->data.ptr;
29956     io1_a_src = io0_a_src + a_src->meta.ri;
29957     iop_a_src = io1_a_src;
29958     io2_a_src = io0_a_src + a_src->meta.wi;
29959   }
29960 
29961   uint32_t coro_susp_point = self->private_impl.p_decode_lsd[0];
29962   if (coro_susp_point) {
29963     v_flags = self->private_data.s_decode_lsd[0].v_flags;
29964     v_background_color_index = self->private_data.s_decode_lsd[0].v_background_color_index;
29965     v_num_palette_entries = self->private_data.s_decode_lsd[0].v_num_palette_entries;
29966     v_i = self->private_data.s_decode_lsd[0].v_i;
29967   }
29968   switch (coro_susp_point) {
29969     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
29970 
29971     {
29972       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
29973       uint32_t t_0;
29974       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
29975         t_0 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
29976         iop_a_src += 2;
29977       } else {
29978         self->private_data.s_decode_lsd[0].scratch = 0;
29979         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
29980         while (true) {
29981           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
29982             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
29983             goto suspend;
29984           }
29985           uint64_t* scratch = &self->private_data.s_decode_lsd[0].scratch;
29986           uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
29987           *scratch <<= 8;
29988           *scratch >>= 8;
29989           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
29990           if (num_bits_0 == 8) {
29991             t_0 = ((uint32_t)(*scratch));
29992             break;
29993           }
29994           num_bits_0 += 8;
29995           *scratch |= ((uint64_t)(num_bits_0)) << 56;
29996         }
29997       }
29998       self->private_impl.f_width = t_0;
29999     }
30000     {
30001       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
30002       uint32_t t_1;
30003       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
30004         t_1 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
30005         iop_a_src += 2;
30006       } else {
30007         self->private_data.s_decode_lsd[0].scratch = 0;
30008         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
30009         while (true) {
30010           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30011             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30012             goto suspend;
30013           }
30014           uint64_t* scratch = &self->private_data.s_decode_lsd[0].scratch;
30015           uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
30016           *scratch <<= 8;
30017           *scratch >>= 8;
30018           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
30019           if (num_bits_1 == 8) {
30020             t_1 = ((uint32_t)(*scratch));
30021             break;
30022           }
30023           num_bits_1 += 8;
30024           *scratch |= ((uint64_t)(num_bits_1)) << 56;
30025         }
30026       }
30027       self->private_impl.f_height = t_1;
30028     }
30029     {
30030       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
30031       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30032         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30033         goto suspend;
30034       }
30035       uint8_t t_2 = *iop_a_src++;
30036       v_flags = t_2;
30037     }
30038     {
30039       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
30040       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30041         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30042         goto suspend;
30043       }
30044       uint8_t t_3 = *iop_a_src++;
30045       v_background_color_index = t_3;
30046     }
30047     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
30048     if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30049       status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30050       goto suspend;
30051     }
30052     iop_a_src++;
30053     v_i = 0;
30054     self->private_impl.f_has_global_palette = ((v_flags & 128) != 0);
30055     if (self->private_impl.f_has_global_palette) {
30056       v_num_palette_entries = (((uint32_t)(1)) << (1 + (v_flags & 7)));
30057       while (v_i < v_num_palette_entries) {
30058         {
30059           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
30060           uint32_t t_4;
30061           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) {
30062             t_4 = ((uint32_t)(wuffs_base__peek_u24be__no_bounds_check(iop_a_src)));
30063             iop_a_src += 3;
30064           } else {
30065             self->private_data.s_decode_lsd[0].scratch = 0;
30066             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
30067             while (true) {
30068               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30069                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30070                 goto suspend;
30071               }
30072               uint64_t* scratch = &self->private_data.s_decode_lsd[0].scratch;
30073               uint32_t num_bits_4 = ((uint32_t)(*scratch & 0xFF));
30074               *scratch >>= 8;
30075               *scratch <<= 8;
30076               *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_4);
30077               if (num_bits_4 == 16) {
30078                 t_4 = ((uint32_t)(*scratch >> 40));
30079                 break;
30080               }
30081               num_bits_4 += 8;
30082               *scratch |= ((uint64_t)(num_bits_4));
30083             }
30084           }
30085           v_argb = t_4;
30086         }
30087         v_argb |= 4278190080;
30088         self->private_data.f_palettes[0][((4 * v_i) + 0)] = ((uint8_t)(((v_argb >> 0) & 255)));
30089         self->private_data.f_palettes[0][((4 * v_i) + 1)] = ((uint8_t)(((v_argb >> 8) & 255)));
30090         self->private_data.f_palettes[0][((4 * v_i) + 2)] = ((uint8_t)(((v_argb >> 16) & 255)));
30091         self->private_data.f_palettes[0][((4 * v_i) + 3)] = ((uint8_t)(((v_argb >> 24) & 255)));
30092         v_i += 1;
30093       }
30094       if (self->private_impl.f_quirks[2]) {
30095         if ((v_background_color_index != 0) && (((uint32_t)(v_background_color_index)) < v_num_palette_entries)) {
30096           v_j = (4 * ((uint32_t)(v_background_color_index)));
30097           self->private_impl.f_background_color_u32_argb_premul = ((((uint32_t)(self->private_data.f_palettes[0][(v_j + 0)])) << 0) |
30098               (((uint32_t)(self->private_data.f_palettes[0][(v_j + 1)])) << 8) |
30099               (((uint32_t)(self->private_data.f_palettes[0][(v_j + 2)])) << 16) |
30100               (((uint32_t)(self->private_data.f_palettes[0][(v_j + 3)])) << 24));
30101         } else {
30102           self->private_impl.f_background_color_u32_argb_premul = 77;
30103         }
30104       }
30105     }
30106     while (v_i < 256) {
30107       self->private_data.f_palettes[0][((4 * v_i) + 0)] = 0;
30108       self->private_data.f_palettes[0][((4 * v_i) + 1)] = 0;
30109       self->private_data.f_palettes[0][((4 * v_i) + 2)] = 0;
30110       self->private_data.f_palettes[0][((4 * v_i) + 3)] = 255;
30111       v_i += 1;
30112     }
30113 
30114     goto ok;
30115     ok:
30116     self->private_impl.p_decode_lsd[0] = 0;
30117     goto exit;
30118   }
30119 
30120   goto suspend;
30121   suspend:
30122   self->private_impl.p_decode_lsd[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
30123   self->private_data.s_decode_lsd[0].v_flags = v_flags;
30124   self->private_data.s_decode_lsd[0].v_background_color_index = v_background_color_index;
30125   self->private_data.s_decode_lsd[0].v_num_palette_entries = v_num_palette_entries;
30126   self->private_data.s_decode_lsd[0].v_i = v_i;
30127 
30128   goto exit;
30129   exit:
30130   if (a_src) {
30131     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30132   }
30133 
30134   return status;
30135 }
30136 
30137 // -------- func gif.decoder.decode_extension
30138 
30139 static wuffs_base__status
wuffs_gif__decoder__decode_extension(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)30140 wuffs_gif__decoder__decode_extension(
30141     wuffs_gif__decoder* self,
30142     wuffs_base__io_buffer* a_src) {
30143   wuffs_base__status status = wuffs_base__make_status(NULL);
30144 
30145   uint8_t v_label = 0;
30146 
30147   const uint8_t* iop_a_src = NULL;
30148   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30149   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30150   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30151   if (a_src) {
30152     io0_a_src = a_src->data.ptr;
30153     io1_a_src = io0_a_src + a_src->meta.ri;
30154     iop_a_src = io1_a_src;
30155     io2_a_src = io0_a_src + a_src->meta.wi;
30156   }
30157 
30158   uint32_t coro_susp_point = self->private_impl.p_decode_extension[0];
30159   switch (coro_susp_point) {
30160     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
30161 
30162     {
30163       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
30164       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30165         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30166         goto suspend;
30167       }
30168       uint8_t t_0 = *iop_a_src++;
30169       v_label = t_0;
30170     }
30171     if (v_label == 249) {
30172       if (a_src) {
30173         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30174       }
30175       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
30176       status = wuffs_gif__decoder__decode_gc(self, a_src);
30177       if (a_src) {
30178         iop_a_src = a_src->data.ptr + a_src->meta.ri;
30179       }
30180       if (status.repr) {
30181         goto suspend;
30182       }
30183       status = wuffs_base__make_status(NULL);
30184       goto ok;
30185     } else if (v_label == 255) {
30186       if (a_src) {
30187         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30188       }
30189       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
30190       status = wuffs_gif__decoder__decode_ae(self, a_src);
30191       if (a_src) {
30192         iop_a_src = a_src->data.ptr + a_src->meta.ri;
30193       }
30194       if (status.repr) {
30195         goto suspend;
30196       }
30197       status = wuffs_base__make_status(NULL);
30198       goto ok;
30199     }
30200     if (a_src) {
30201       a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30202     }
30203     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
30204     status = wuffs_gif__decoder__skip_blocks(self, a_src);
30205     if (a_src) {
30206       iop_a_src = a_src->data.ptr + a_src->meta.ri;
30207     }
30208     if (status.repr) {
30209       goto suspend;
30210     }
30211 
30212     ok:
30213     self->private_impl.p_decode_extension[0] = 0;
30214     goto exit;
30215   }
30216 
30217   goto suspend;
30218   suspend:
30219   self->private_impl.p_decode_extension[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
30220 
30221   goto exit;
30222   exit:
30223   if (a_src) {
30224     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30225   }
30226 
30227   return status;
30228 }
30229 
30230 // -------- func gif.decoder.skip_blocks
30231 
30232 static wuffs_base__status
wuffs_gif__decoder__skip_blocks(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)30233 wuffs_gif__decoder__skip_blocks(
30234     wuffs_gif__decoder* self,
30235     wuffs_base__io_buffer* a_src) {
30236   wuffs_base__status status = wuffs_base__make_status(NULL);
30237 
30238   uint8_t v_block_size = 0;
30239 
30240   const uint8_t* iop_a_src = NULL;
30241   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30242   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30243   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30244   if (a_src) {
30245     io0_a_src = a_src->data.ptr;
30246     io1_a_src = io0_a_src + a_src->meta.ri;
30247     iop_a_src = io1_a_src;
30248     io2_a_src = io0_a_src + a_src->meta.wi;
30249   }
30250 
30251   uint32_t coro_susp_point = self->private_impl.p_skip_blocks[0];
30252   switch (coro_susp_point) {
30253     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
30254 
30255     while (true) {
30256       {
30257         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
30258         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30259           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30260           goto suspend;
30261         }
30262         uint8_t t_0 = *iop_a_src++;
30263         v_block_size = t_0;
30264       }
30265       if (v_block_size == 0) {
30266         status = wuffs_base__make_status(NULL);
30267         goto ok;
30268       }
30269       self->private_data.s_skip_blocks[0].scratch = ((uint32_t)(v_block_size));
30270       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
30271       if (self->private_data.s_skip_blocks[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
30272         self->private_data.s_skip_blocks[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
30273         iop_a_src = io2_a_src;
30274         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30275         goto suspend;
30276       }
30277       iop_a_src += self->private_data.s_skip_blocks[0].scratch;
30278     }
30279 
30280     ok:
30281     self->private_impl.p_skip_blocks[0] = 0;
30282     goto exit;
30283   }
30284 
30285   goto suspend;
30286   suspend:
30287   self->private_impl.p_skip_blocks[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
30288 
30289   goto exit;
30290   exit:
30291   if (a_src) {
30292     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30293   }
30294 
30295   return status;
30296 }
30297 
30298 // -------- func gif.decoder.decode_ae
30299 
30300 static wuffs_base__status
wuffs_gif__decoder__decode_ae(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)30301 wuffs_gif__decoder__decode_ae(
30302     wuffs_gif__decoder* self,
30303     wuffs_base__io_buffer* a_src) {
30304   wuffs_base__status status = wuffs_base__make_status(NULL);
30305 
30306   uint8_t v_c = 0;
30307   uint8_t v_block_size = 0;
30308   bool v_is_animexts = false;
30309   bool v_is_netscape = false;
30310   bool v_is_iccp = false;
30311   bool v_is_xmp = false;
30312 
30313   const uint8_t* iop_a_src = NULL;
30314   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30315   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30316   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30317   if (a_src) {
30318     io0_a_src = a_src->data.ptr;
30319     io1_a_src = io0_a_src + a_src->meta.ri;
30320     iop_a_src = io1_a_src;
30321     io2_a_src = io0_a_src + a_src->meta.wi;
30322   }
30323 
30324   uint32_t coro_susp_point = self->private_impl.p_decode_ae[0];
30325   if (coro_susp_point) {
30326     v_block_size = self->private_data.s_decode_ae[0].v_block_size;
30327     v_is_animexts = self->private_data.s_decode_ae[0].v_is_animexts;
30328     v_is_netscape = self->private_data.s_decode_ae[0].v_is_netscape;
30329     v_is_iccp = self->private_data.s_decode_ae[0].v_is_iccp;
30330     v_is_xmp = self->private_data.s_decode_ae[0].v_is_xmp;
30331   }
30332   switch (coro_susp_point) {
30333     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
30334 
30335     while (true) {
30336       if (self->private_impl.f_metadata_fourcc != 0) {
30337         status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
30338         goto ok;
30339       }
30340       {
30341         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
30342         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30343           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30344           goto suspend;
30345         }
30346         uint8_t t_0 = *iop_a_src++;
30347         v_block_size = t_0;
30348       }
30349       if (v_block_size == 0) {
30350         status = wuffs_base__make_status(NULL);
30351         goto ok;
30352       }
30353       if (v_block_size != 11) {
30354         self->private_data.s_decode_ae[0].scratch = ((uint32_t)(v_block_size));
30355         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
30356         if (self->private_data.s_decode_ae[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
30357           self->private_data.s_decode_ae[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
30358           iop_a_src = io2_a_src;
30359           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30360           goto suspend;
30361         }
30362         iop_a_src += self->private_data.s_decode_ae[0].scratch;
30363         goto label__goto_done__break;
30364       }
30365       v_is_animexts = true;
30366       v_is_netscape = true;
30367       v_is_iccp = true;
30368       v_is_xmp = true;
30369       v_block_size = 0;
30370       while (v_block_size < 11) {
30371         {
30372           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
30373           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30374             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30375             goto suspend;
30376           }
30377           uint8_t t_1 = *iop_a_src++;
30378           v_c = t_1;
30379         }
30380         v_is_animexts = (v_is_animexts && (v_c == WUFFS_GIF__ANIMEXTS1DOT0[v_block_size]));
30381         v_is_netscape = (v_is_netscape && (v_c == WUFFS_GIF__NETSCAPE2DOT0[v_block_size]));
30382         v_is_iccp = (v_is_iccp && (v_c == WUFFS_GIF__ICCRGBG1012[v_block_size]));
30383         v_is_xmp = (v_is_xmp && (v_c == WUFFS_GIF__XMPDATAXMP[v_block_size]));
30384 #if defined(__GNUC__)
30385 #pragma GCC diagnostic push
30386 #pragma GCC diagnostic ignored "-Wconversion"
30387 #endif
30388         v_block_size += 1;
30389 #if defined(__GNUC__)
30390 #pragma GCC diagnostic pop
30391 #endif
30392       }
30393       if (v_is_animexts || v_is_netscape) {
30394         {
30395           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
30396           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30397             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30398             goto suspend;
30399           }
30400           uint8_t t_2 = *iop_a_src++;
30401           v_block_size = t_2;
30402         }
30403         if (v_block_size != 3) {
30404           self->private_data.s_decode_ae[0].scratch = ((uint32_t)(v_block_size));
30405           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
30406           if (self->private_data.s_decode_ae[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
30407             self->private_data.s_decode_ae[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
30408             iop_a_src = io2_a_src;
30409             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30410             goto suspend;
30411           }
30412           iop_a_src += self->private_data.s_decode_ae[0].scratch;
30413           goto label__goto_done__break;
30414         }
30415         {
30416           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
30417           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30418             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30419             goto suspend;
30420           }
30421           uint8_t t_3 = *iop_a_src++;
30422           v_c = t_3;
30423         }
30424         if (v_c != 1) {
30425           self->private_data.s_decode_ae[0].scratch = 2;
30426           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
30427           if (self->private_data.s_decode_ae[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
30428             self->private_data.s_decode_ae[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
30429             iop_a_src = io2_a_src;
30430             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30431             goto suspend;
30432           }
30433           iop_a_src += self->private_data.s_decode_ae[0].scratch;
30434           goto label__goto_done__break;
30435         }
30436         {
30437           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
30438           uint32_t t_4;
30439           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
30440             t_4 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
30441             iop_a_src += 2;
30442           } else {
30443             self->private_data.s_decode_ae[0].scratch = 0;
30444             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
30445             while (true) {
30446               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30447                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30448                 goto suspend;
30449               }
30450               uint64_t* scratch = &self->private_data.s_decode_ae[0].scratch;
30451               uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
30452               *scratch <<= 8;
30453               *scratch >>= 8;
30454               *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
30455               if (num_bits_4 == 8) {
30456                 t_4 = ((uint32_t)(*scratch));
30457                 break;
30458               }
30459               num_bits_4 += 8;
30460               *scratch |= ((uint64_t)(num_bits_4)) << 56;
30461             }
30462           }
30463           self->private_impl.f_num_animation_loops_value = t_4;
30464         }
30465         self->private_impl.f_seen_num_animation_loops_value = true;
30466         if ((0 < self->private_impl.f_num_animation_loops_value) && (self->private_impl.f_num_animation_loops_value <= 65535)) {
30467           self->private_impl.f_num_animation_loops_value += 1;
30468         }
30469       } else if (self->private_impl.f_ignore_metadata) {
30470       } else if (v_is_iccp && self->private_impl.f_report_metadata_iccp) {
30471         self->private_impl.f_metadata_fourcc = 1229144912;
30472         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)));
30473         self->private_impl.f_call_sequence = 1;
30474         status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
30475         goto ok;
30476       } else if (v_is_xmp && self->private_impl.f_report_metadata_xmp) {
30477         self->private_impl.f_metadata_fourcc = 1481461792;
30478         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)));
30479         self->private_impl.f_call_sequence = 1;
30480         status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
30481         goto ok;
30482       }
30483       goto label__goto_done__break;
30484     }
30485     label__goto_done__break:;
30486     if (a_src) {
30487       a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30488     }
30489     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
30490     status = wuffs_gif__decoder__skip_blocks(self, a_src);
30491     if (a_src) {
30492       iop_a_src = a_src->data.ptr + a_src->meta.ri;
30493     }
30494     if (status.repr) {
30495       goto suspend;
30496     }
30497 
30498     ok:
30499     self->private_impl.p_decode_ae[0] = 0;
30500     goto exit;
30501   }
30502 
30503   goto suspend;
30504   suspend:
30505   self->private_impl.p_decode_ae[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
30506   self->private_data.s_decode_ae[0].v_block_size = v_block_size;
30507   self->private_data.s_decode_ae[0].v_is_animexts = v_is_animexts;
30508   self->private_data.s_decode_ae[0].v_is_netscape = v_is_netscape;
30509   self->private_data.s_decode_ae[0].v_is_iccp = v_is_iccp;
30510   self->private_data.s_decode_ae[0].v_is_xmp = v_is_xmp;
30511 
30512   goto exit;
30513   exit:
30514   if (a_src) {
30515     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30516   }
30517 
30518   return status;
30519 }
30520 
30521 // -------- func gif.decoder.decode_gc
30522 
30523 static wuffs_base__status
wuffs_gif__decoder__decode_gc(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)30524 wuffs_gif__decoder__decode_gc(
30525     wuffs_gif__decoder* self,
30526     wuffs_base__io_buffer* a_src) {
30527   wuffs_base__status status = wuffs_base__make_status(NULL);
30528 
30529   uint8_t v_c = 0;
30530   uint8_t v_flags = 0;
30531   uint16_t v_gc_duration_centiseconds = 0;
30532 
30533   const uint8_t* iop_a_src = NULL;
30534   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30535   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30536   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30537   if (a_src) {
30538     io0_a_src = a_src->data.ptr;
30539     io1_a_src = io0_a_src + a_src->meta.ri;
30540     iop_a_src = io1_a_src;
30541     io2_a_src = io0_a_src + a_src->meta.wi;
30542   }
30543 
30544   uint32_t coro_susp_point = self->private_impl.p_decode_gc[0];
30545   switch (coro_susp_point) {
30546     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
30547 
30548     {
30549       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
30550       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30551         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30552         goto suspend;
30553       }
30554       uint8_t t_0 = *iop_a_src++;
30555       v_c = t_0;
30556     }
30557     if (v_c != 4) {
30558       status = wuffs_base__make_status(wuffs_gif__error__bad_graphic_control);
30559       goto exit;
30560     }
30561     {
30562       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
30563       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30564         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30565         goto suspend;
30566       }
30567       uint8_t t_1 = *iop_a_src++;
30568       v_flags = t_1;
30569     }
30570     self->private_impl.f_gc_has_transparent_index = ((v_flags & 1) != 0);
30571     v_flags = ((v_flags >> 2) & 7);
30572     if (v_flags == 2) {
30573       self->private_impl.f_gc_disposal = 1;
30574     } else if ((v_flags == 3) || (v_flags == 4)) {
30575       self->private_impl.f_gc_disposal = 2;
30576     } else {
30577       self->private_impl.f_gc_disposal = 0;
30578     }
30579     {
30580       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
30581       uint16_t t_2;
30582       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
30583         t_2 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src);
30584         iop_a_src += 2;
30585       } else {
30586         self->private_data.s_decode_gc[0].scratch = 0;
30587         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
30588         while (true) {
30589           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30590             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30591             goto suspend;
30592           }
30593           uint64_t* scratch = &self->private_data.s_decode_gc[0].scratch;
30594           uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
30595           *scratch <<= 8;
30596           *scratch >>= 8;
30597           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
30598           if (num_bits_2 == 8) {
30599             t_2 = ((uint16_t)(*scratch));
30600             break;
30601           }
30602           num_bits_2 += 8;
30603           *scratch |= ((uint64_t)(num_bits_2)) << 56;
30604         }
30605       }
30606       v_gc_duration_centiseconds = t_2;
30607     }
30608     self->private_impl.f_gc_duration = (((uint64_t)(v_gc_duration_centiseconds)) * 7056000);
30609     {
30610       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
30611       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30612         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30613         goto suspend;
30614       }
30615       uint8_t t_3 = *iop_a_src++;
30616       self->private_impl.f_gc_transparent_index = t_3;
30617     }
30618     {
30619       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
30620       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30621         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30622         goto suspend;
30623       }
30624       uint8_t t_4 = *iop_a_src++;
30625       v_c = t_4;
30626     }
30627     if (v_c != 0) {
30628       status = wuffs_base__make_status(wuffs_gif__error__bad_graphic_control);
30629       goto exit;
30630     }
30631 
30632     goto ok;
30633     ok:
30634     self->private_impl.p_decode_gc[0] = 0;
30635     goto exit;
30636   }
30637 
30638   goto suspend;
30639   suspend:
30640   self->private_impl.p_decode_gc[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
30641 
30642   goto exit;
30643   exit:
30644   if (a_src) {
30645     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30646   }
30647 
30648   return status;
30649 }
30650 
30651 // -------- func gif.decoder.decode_id_part0
30652 
30653 static wuffs_base__status
wuffs_gif__decoder__decode_id_part0(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)30654 wuffs_gif__decoder__decode_id_part0(
30655     wuffs_gif__decoder* self,
30656     wuffs_base__io_buffer* a_src) {
30657   wuffs_base__status status = wuffs_base__make_status(NULL);
30658 
30659   const uint8_t* iop_a_src = NULL;
30660   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30661   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30662   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30663   if (a_src) {
30664     io0_a_src = a_src->data.ptr;
30665     io1_a_src = io0_a_src + a_src->meta.ri;
30666     iop_a_src = io1_a_src;
30667     io2_a_src = io0_a_src + a_src->meta.wi;
30668   }
30669 
30670   uint32_t coro_susp_point = self->private_impl.p_decode_id_part0[0];
30671   switch (coro_susp_point) {
30672     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
30673 
30674     {
30675       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
30676       uint32_t t_0;
30677       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
30678         t_0 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
30679         iop_a_src += 2;
30680       } else {
30681         self->private_data.s_decode_id_part0[0].scratch = 0;
30682         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
30683         while (true) {
30684           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30685             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30686             goto suspend;
30687           }
30688           uint64_t* scratch = &self->private_data.s_decode_id_part0[0].scratch;
30689           uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
30690           *scratch <<= 8;
30691           *scratch >>= 8;
30692           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
30693           if (num_bits_0 == 8) {
30694             t_0 = ((uint32_t)(*scratch));
30695             break;
30696           }
30697           num_bits_0 += 8;
30698           *scratch |= ((uint64_t)(num_bits_0)) << 56;
30699         }
30700       }
30701       self->private_impl.f_frame_rect_x0 = t_0;
30702     }
30703     {
30704       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
30705       uint32_t t_1;
30706       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
30707         t_1 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
30708         iop_a_src += 2;
30709       } else {
30710         self->private_data.s_decode_id_part0[0].scratch = 0;
30711         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
30712         while (true) {
30713           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30714             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30715             goto suspend;
30716           }
30717           uint64_t* scratch = &self->private_data.s_decode_id_part0[0].scratch;
30718           uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
30719           *scratch <<= 8;
30720           *scratch >>= 8;
30721           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
30722           if (num_bits_1 == 8) {
30723             t_1 = ((uint32_t)(*scratch));
30724             break;
30725           }
30726           num_bits_1 += 8;
30727           *scratch |= ((uint64_t)(num_bits_1)) << 56;
30728         }
30729       }
30730       self->private_impl.f_frame_rect_y0 = t_1;
30731     }
30732     {
30733       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
30734       uint32_t t_2;
30735       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
30736         t_2 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
30737         iop_a_src += 2;
30738       } else {
30739         self->private_data.s_decode_id_part0[0].scratch = 0;
30740         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
30741         while (true) {
30742           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30743             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30744             goto suspend;
30745           }
30746           uint64_t* scratch = &self->private_data.s_decode_id_part0[0].scratch;
30747           uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
30748           *scratch <<= 8;
30749           *scratch >>= 8;
30750           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
30751           if (num_bits_2 == 8) {
30752             t_2 = ((uint32_t)(*scratch));
30753             break;
30754           }
30755           num_bits_2 += 8;
30756           *scratch |= ((uint64_t)(num_bits_2)) << 56;
30757         }
30758       }
30759       self->private_impl.f_frame_rect_x1 = t_2;
30760     }
30761     self->private_impl.f_frame_rect_x1 += self->private_impl.f_frame_rect_x0;
30762     {
30763       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
30764       uint32_t t_3;
30765       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
30766         t_3 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
30767         iop_a_src += 2;
30768       } else {
30769         self->private_data.s_decode_id_part0[0].scratch = 0;
30770         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
30771         while (true) {
30772           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30773             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30774             goto suspend;
30775           }
30776           uint64_t* scratch = &self->private_data.s_decode_id_part0[0].scratch;
30777           uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56));
30778           *scratch <<= 8;
30779           *scratch >>= 8;
30780           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3;
30781           if (num_bits_3 == 8) {
30782             t_3 = ((uint32_t)(*scratch));
30783             break;
30784           }
30785           num_bits_3 += 8;
30786           *scratch |= ((uint64_t)(num_bits_3)) << 56;
30787         }
30788       }
30789       self->private_impl.f_frame_rect_y1 = t_3;
30790     }
30791     self->private_impl.f_frame_rect_y1 += self->private_impl.f_frame_rect_y0;
30792     self->private_impl.f_dst_x = self->private_impl.f_frame_rect_x0;
30793     self->private_impl.f_dst_y = self->private_impl.f_frame_rect_y0;
30794     if ((self->private_impl.f_call_sequence == 0) &&  ! self->private_impl.f_quirks[4]) {
30795       self->private_impl.f_width = wuffs_base__u32__max(self->private_impl.f_width, self->private_impl.f_frame_rect_x1);
30796       self->private_impl.f_height = wuffs_base__u32__max(self->private_impl.f_height, self->private_impl.f_frame_rect_y1);
30797     }
30798 
30799     goto ok;
30800     ok:
30801     self->private_impl.p_decode_id_part0[0] = 0;
30802     goto exit;
30803   }
30804 
30805   goto suspend;
30806   suspend:
30807   self->private_impl.p_decode_id_part0[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
30808 
30809   goto exit;
30810   exit:
30811   if (a_src) {
30812     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30813   }
30814 
30815   return status;
30816 }
30817 
30818 // -------- func gif.decoder.decode_id_part1
30819 
30820 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)30821 wuffs_gif__decoder__decode_id_part1(
30822     wuffs_gif__decoder* self,
30823     wuffs_base__pixel_buffer* a_dst,
30824     wuffs_base__io_buffer* a_src,
30825     wuffs_base__pixel_blend a_blend) {
30826   wuffs_base__status status = wuffs_base__make_status(NULL);
30827 
30828   uint8_t v_flags = 0;
30829   uint8_t v_which_palette = 0;
30830   uint32_t v_num_palette_entries = 0;
30831   uint32_t v_i = 0;
30832   uint32_t v_argb = 0;
30833   wuffs_base__status v_status = wuffs_base__make_status(NULL);
30834   uint8_t v_lw = 0;
30835 
30836   const uint8_t* iop_a_src = NULL;
30837   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30838   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30839   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30840   if (a_src) {
30841     io0_a_src = a_src->data.ptr;
30842     io1_a_src = io0_a_src + a_src->meta.ri;
30843     iop_a_src = io1_a_src;
30844     io2_a_src = io0_a_src + a_src->meta.wi;
30845   }
30846 
30847   uint32_t coro_susp_point = self->private_impl.p_decode_id_part1[0];
30848   if (coro_susp_point) {
30849     v_which_palette = self->private_data.s_decode_id_part1[0].v_which_palette;
30850     v_num_palette_entries = self->private_data.s_decode_id_part1[0].v_num_palette_entries;
30851     v_i = self->private_data.s_decode_id_part1[0].v_i;
30852   }
30853   switch (coro_susp_point) {
30854     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
30855 
30856     {
30857       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
30858       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30859         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30860         goto suspend;
30861       }
30862       uint8_t t_0 = *iop_a_src++;
30863       v_flags = t_0;
30864     }
30865     if ((v_flags & 64) != 0) {
30866       self->private_impl.f_interlace = 4;
30867     } else {
30868       self->private_impl.f_interlace = 0;
30869     }
30870     v_which_palette = 1;
30871     if ((v_flags & 128) != 0) {
30872       v_num_palette_entries = (((uint32_t)(1)) << (1 + (v_flags & 7)));
30873       v_i = 0;
30874       while (v_i < v_num_palette_entries) {
30875         {
30876           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
30877           uint32_t t_1;
30878           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) {
30879             t_1 = ((uint32_t)(wuffs_base__peek_u24be__no_bounds_check(iop_a_src)));
30880             iop_a_src += 3;
30881           } else {
30882             self->private_data.s_decode_id_part1[0].scratch = 0;
30883             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
30884             while (true) {
30885               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30886                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30887                 goto suspend;
30888               }
30889               uint64_t* scratch = &self->private_data.s_decode_id_part1[0].scratch;
30890               uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFF));
30891               *scratch >>= 8;
30892               *scratch <<= 8;
30893               *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
30894               if (num_bits_1 == 16) {
30895                 t_1 = ((uint32_t)(*scratch >> 40));
30896                 break;
30897               }
30898               num_bits_1 += 8;
30899               *scratch |= ((uint64_t)(num_bits_1));
30900             }
30901           }
30902           v_argb = t_1;
30903         }
30904         v_argb |= 4278190080;
30905         self->private_data.f_palettes[1][((4 * v_i) + 0)] = ((uint8_t)(((v_argb >> 0) & 255)));
30906         self->private_data.f_palettes[1][((4 * v_i) + 1)] = ((uint8_t)(((v_argb >> 8) & 255)));
30907         self->private_data.f_palettes[1][((4 * v_i) + 2)] = ((uint8_t)(((v_argb >> 16) & 255)));
30908         self->private_data.f_palettes[1][((4 * v_i) + 3)] = ((uint8_t)(((v_argb >> 24) & 255)));
30909         v_i += 1;
30910       }
30911       while (v_i < 256) {
30912         self->private_data.f_palettes[1][((4 * v_i) + 0)] = 0;
30913         self->private_data.f_palettes[1][((4 * v_i) + 1)] = 0;
30914         self->private_data.f_palettes[1][((4 * v_i) + 2)] = 0;
30915         self->private_data.f_palettes[1][((4 * v_i) + 3)] = 255;
30916         v_i += 1;
30917       }
30918     } else if (self->private_impl.f_quirks[6] &&  ! self->private_impl.f_has_global_palette) {
30919       status = wuffs_base__make_status(wuffs_gif__error__bad_palette);
30920       goto exit;
30921     } else if (self->private_impl.f_gc_has_transparent_index) {
30922       wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8(self->private_data.f_palettes[1], 1024), wuffs_base__make_slice_u8(self->private_data.f_palettes[0], 1024));
30923     } else {
30924       v_which_palette = 0;
30925     }
30926     if (self->private_impl.f_gc_has_transparent_index) {
30927       self->private_data.f_palettes[1][((4 * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 0)] = 0;
30928       self->private_data.f_palettes[1][((4 * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 1)] = 0;
30929       self->private_data.f_palettes[1][((4 * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 2)] = 0;
30930       self->private_data.f_palettes[1][((4 * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 3)] = 0;
30931     }
30932     v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
30933         wuffs_base__pixel_buffer__pixel_format(a_dst),
30934         wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)),
30935         wuffs_base__utility__make_pixel_format(2198077448),
30936         wuffs_base__make_slice_u8(self->private_data.f_palettes[v_which_palette], 1024),
30937         a_blend);
30938     if ( ! wuffs_base__status__is_ok(&v_status)) {
30939       status = v_status;
30940       if (wuffs_base__status__is_error(&status)) {
30941         goto exit;
30942       } else if (wuffs_base__status__is_suspension(&status)) {
30943         status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
30944         goto exit;
30945       }
30946       goto ok;
30947     }
30948     if (self->private_impl.f_previous_lzw_decode_ended_abruptly) {
30949       wuffs_base__ignore_status(wuffs_lzw__decoder__initialize(&self->private_data.f_lzw,
30950           sizeof (wuffs_lzw__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
30951     }
30952     {
30953       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
30954       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30955         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30956         goto suspend;
30957       }
30958       uint8_t t_2 = *iop_a_src++;
30959       v_lw = t_2;
30960     }
30961     if (v_lw > 8) {
30962       status = wuffs_base__make_status(wuffs_gif__error__bad_literal_width);
30963       goto exit;
30964     }
30965     wuffs_lzw__decoder__set_literal_width(&self->private_data.f_lzw, ((uint32_t)(v_lw)));
30966     self->private_impl.f_previous_lzw_decode_ended_abruptly = true;
30967 
30968     ok:
30969     self->private_impl.p_decode_id_part1[0] = 0;
30970     goto exit;
30971   }
30972 
30973   goto suspend;
30974   suspend:
30975   self->private_impl.p_decode_id_part1[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
30976   self->private_data.s_decode_id_part1[0].v_which_palette = v_which_palette;
30977   self->private_data.s_decode_id_part1[0].v_num_palette_entries = v_num_palette_entries;
30978   self->private_data.s_decode_id_part1[0].v_i = v_i;
30979 
30980   goto exit;
30981   exit:
30982   if (a_src) {
30983     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30984   }
30985 
30986   return status;
30987 }
30988 
30989 // -------- func gif.decoder.decode_id_part2
30990 
30991 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)30992 wuffs_gif__decoder__decode_id_part2(
30993     wuffs_gif__decoder* self,
30994     wuffs_base__pixel_buffer* a_dst,
30995     wuffs_base__io_buffer* a_src,
30996     wuffs_base__slice_u8 a_workbuf) {
30997   wuffs_base__io_buffer empty_io_buffer = wuffs_base__empty_io_buffer();
30998 
30999   wuffs_base__status status = wuffs_base__make_status(NULL);
31000 
31001   uint64_t v_block_size = 0;
31002   bool v_need_block_size = false;
31003   uint32_t v_n_copied = 0;
31004   uint64_t v_n_compressed = 0;
31005   wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer();
31006   wuffs_base__io_buffer* v_r = &u_r;
31007   const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31008   const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31009   const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31010   const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31011   uint64_t v_mark = 0;
31012   wuffs_base__status v_lzw_status = wuffs_base__make_status(NULL);
31013   wuffs_base__status v_copy_status = wuffs_base__make_status(NULL);
31014   wuffs_base__slice_u8 v_uncompressed = {0};
31015 
31016   const uint8_t* iop_a_src = NULL;
31017   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31018   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31019   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31020   if (a_src) {
31021     io0_a_src = a_src->data.ptr;
31022     io1_a_src = io0_a_src + a_src->meta.ri;
31023     iop_a_src = io1_a_src;
31024     io2_a_src = io0_a_src + a_src->meta.wi;
31025   }
31026 
31027   uint32_t coro_susp_point = self->private_impl.p_decode_id_part2[0];
31028   if (coro_susp_point) {
31029     v_block_size = self->private_data.s_decode_id_part2[0].v_block_size;
31030     v_need_block_size = self->private_data.s_decode_id_part2[0].v_need_block_size;
31031     v_lzw_status = self->private_data.s_decode_id_part2[0].v_lzw_status;
31032   }
31033   switch (coro_susp_point) {
31034     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
31035 
31036     v_need_block_size = true;
31037     label__outer__continue:;
31038     while (true) {
31039       if (v_need_block_size) {
31040         v_need_block_size = false;
31041         {
31042           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
31043           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31044             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31045             goto suspend;
31046           }
31047           uint64_t t_0 = *iop_a_src++;
31048           v_block_size = t_0;
31049         }
31050       }
31051       if (v_block_size == 0) {
31052         goto label__outer__break;
31053       }
31054       while (((uint64_t)(io2_a_src - iop_a_src)) == 0) {
31055         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31056         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
31057       }
31058       if (self->private_impl.f_compressed_ri == self->private_impl.f_compressed_wi) {
31059         self->private_impl.f_compressed_ri = 0;
31060         self->private_impl.f_compressed_wi = 0;
31061       }
31062       while (self->private_impl.f_compressed_wi <= 3841) {
31063         v_n_compressed = wuffs_base__u64__min(v_block_size, ((uint64_t)(io2_a_src - iop_a_src)));
31064         if (v_n_compressed <= 0) {
31065           goto label__0__break;
31066         }
31067         v_n_copied = wuffs_base__io_reader__limited_copy_u32_to_slice(
31068             &iop_a_src, io2_a_src,((uint32_t)((v_n_compressed & 4294967295))), wuffs_base__slice_u8__subslice_i(wuffs_base__make_slice_u8(self->private_data.f_compressed, 4096), self->private_impl.f_compressed_wi));
31069         wuffs_base__u64__sat_add_indirect(&self->private_impl.f_compressed_wi, ((uint64_t)(v_n_copied)));
31070         wuffs_base__u64__sat_sub_indirect(&v_block_size, ((uint64_t)(v_n_copied)));
31071         if (v_block_size > 0) {
31072           goto label__0__break;
31073         }
31074         if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
31075           v_need_block_size = true;
31076           goto label__0__break;
31077         }
31078         v_block_size = ((uint64_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src)));
31079         iop_a_src += 1;
31080       }
31081       label__0__break:;
31082       label__inner__continue:;
31083       while (true) {
31084         if ((self->private_impl.f_compressed_ri > self->private_impl.f_compressed_wi) || (self->private_impl.f_compressed_wi > 4096)) {
31085           status = wuffs_base__make_status(wuffs_gif__error__internal_error_inconsistent_ri_wi);
31086           goto exit;
31087         }
31088         {
31089           wuffs_base__io_buffer* o_0_v_r = v_r;
31090           const uint8_t *o_0_iop_v_r = iop_v_r;
31091           const uint8_t *o_0_io0_v_r = io0_v_r;
31092           const uint8_t *o_0_io1_v_r = io1_v_r;
31093           const uint8_t *o_0_io2_v_r = io2_v_r;
31094           v_r = wuffs_base__io_reader__set(
31095               &u_r,
31096               &iop_v_r,
31097               &io0_v_r,
31098               &io1_v_r,
31099               &io2_v_r,
31100               wuffs_base__slice_u8__subslice_ij(wuffs_base__make_slice_u8(self->private_data.f_compressed,
31101               4096),
31102               self->private_impl.f_compressed_ri,
31103               self->private_impl.f_compressed_wi),
31104               0);
31105           v_mark = ((uint64_t)(iop_v_r - io0_v_r));
31106           {
31107             u_r.meta.ri = ((size_t)(iop_v_r - u_r.data.ptr));
31108             wuffs_base__status t_1 = wuffs_lzw__decoder__transform_io(&self->private_data.f_lzw, &empty_io_buffer, v_r, wuffs_base__utility__empty_slice_u8());
31109             v_lzw_status = t_1;
31110             iop_v_r = u_r.data.ptr + u_r.meta.ri;
31111           }
31112           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))));
31113           v_r = o_0_v_r;
31114           iop_v_r = o_0_iop_v_r;
31115           io0_v_r = o_0_io0_v_r;
31116           io1_v_r = o_0_io1_v_r;
31117           io2_v_r = o_0_io2_v_r;
31118         }
31119         v_uncompressed = wuffs_lzw__decoder__flush(&self->private_data.f_lzw);
31120         if (((uint64_t)(v_uncompressed.len)) > 0) {
31121           v_copy_status = wuffs_gif__decoder__copy_to_image_buffer(self, a_dst, v_uncompressed);
31122           if (wuffs_base__status__is_error(&v_copy_status)) {
31123             status = v_copy_status;
31124             goto exit;
31125           }
31126         }
31127         if (wuffs_base__status__is_ok(&v_lzw_status)) {
31128           self->private_impl.f_previous_lzw_decode_ended_abruptly = false;
31129           if (v_need_block_size || (v_block_size > 0)) {
31130             self->private_data.s_decode_id_part2[0].scratch = ((uint32_t)(v_block_size));
31131             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
31132             if (self->private_data.s_decode_id_part2[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
31133               self->private_data.s_decode_id_part2[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
31134               iop_a_src = io2_a_src;
31135               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31136               goto suspend;
31137             }
31138             iop_a_src += self->private_data.s_decode_id_part2[0].scratch;
31139             if (a_src) {
31140               a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
31141             }
31142             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
31143             status = wuffs_gif__decoder__skip_blocks(self, a_src);
31144             if (a_src) {
31145               iop_a_src = a_src->data.ptr + a_src->meta.ri;
31146             }
31147             if (status.repr) {
31148               goto suspend;
31149             }
31150           }
31151           goto label__outer__break;
31152         } else if (v_lzw_status.repr == wuffs_base__suspension__short_read) {
31153           goto label__outer__continue;
31154         } else if (v_lzw_status.repr == wuffs_base__suspension__short_write) {
31155           goto label__inner__continue;
31156         }
31157         status = v_lzw_status;
31158         if (wuffs_base__status__is_error(&status)) {
31159           goto exit;
31160         } else if (wuffs_base__status__is_suspension(&status)) {
31161           status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
31162           goto exit;
31163         }
31164         goto ok;
31165       }
31166     }
31167     label__outer__break:;
31168     self->private_impl.f_compressed_ri = 0;
31169     self->private_impl.f_compressed_wi = 0;
31170     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)) {
31171       status = wuffs_base__make_status(wuffs_base__error__not_enough_data);
31172       goto exit;
31173     }
31174 
31175     ok:
31176     self->private_impl.p_decode_id_part2[0] = 0;
31177     goto exit;
31178   }
31179 
31180   goto suspend;
31181   suspend:
31182   self->private_impl.p_decode_id_part2[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
31183   self->private_data.s_decode_id_part2[0].v_block_size = v_block_size;
31184   self->private_data.s_decode_id_part2[0].v_need_block_size = v_need_block_size;
31185   self->private_data.s_decode_id_part2[0].v_lzw_status = v_lzw_status;
31186 
31187   goto exit;
31188   exit:
31189   if (a_src) {
31190     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
31191   }
31192 
31193   return status;
31194 }
31195 
31196 // -------- func gif.decoder.copy_to_image_buffer
31197 
31198 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)31199 wuffs_gif__decoder__copy_to_image_buffer(
31200     wuffs_gif__decoder* self,
31201     wuffs_base__pixel_buffer* a_pb,
31202     wuffs_base__slice_u8 a_src) {
31203   wuffs_base__slice_u8 v_dst = {0};
31204   wuffs_base__slice_u8 v_src = {0};
31205   uint64_t v_width_in_bytes = 0;
31206   uint64_t v_n = 0;
31207   uint64_t v_src_ri = 0;
31208   wuffs_base__pixel_format v_pixfmt = {0};
31209   uint32_t v_bytes_per_pixel = 0;
31210   uint32_t v_bits_per_pixel = 0;
31211   wuffs_base__table_u8 v_tab = {0};
31212   uint64_t v_i = 0;
31213   uint64_t v_j = 0;
31214   uint32_t v_replicate_y0 = 0;
31215   uint32_t v_replicate_y1 = 0;
31216   wuffs_base__slice_u8 v_replicate_dst = {0};
31217   wuffs_base__slice_u8 v_replicate_src = {0};
31218 
31219   v_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_pb);
31220   v_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_pixfmt);
31221   if ((v_bits_per_pixel & 7) != 0) {
31222     return wuffs_base__make_status(wuffs_base__error__unsupported_option);
31223   }
31224   v_bytes_per_pixel = (v_bits_per_pixel >> 3);
31225   v_width_in_bytes = (((uint64_t)(self->private_impl.f_width)) * ((uint64_t)(v_bytes_per_pixel)));
31226   v_tab = wuffs_base__pixel_buffer__plane(a_pb, 0);
31227   label__0__continue:;
31228   while (v_src_ri < ((uint64_t)(a_src.len))) {
31229     v_src = wuffs_base__slice_u8__subslice_i(a_src, v_src_ri);
31230     if (self->private_impl.f_dst_y >= self->private_impl.f_frame_rect_y1) {
31231       if (self->private_impl.f_quirks[3]) {
31232         return wuffs_base__make_status(NULL);
31233       }
31234       return wuffs_base__make_status(wuffs_base__error__too_much_data);
31235     }
31236     v_dst = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
31237     if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
31238       v_dst = wuffs_base__slice_u8__subslice_j(v_dst, 0);
31239     } else if (v_width_in_bytes < ((uint64_t)(v_dst.len))) {
31240       v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_width_in_bytes);
31241     }
31242     v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_bytes_per_pixel)));
31243     if (v_i < ((uint64_t)(v_dst.len))) {
31244       v_j = (((uint64_t)(self->private_impl.f_frame_rect_x1)) * ((uint64_t)(v_bytes_per_pixel)));
31245       if ((v_i <= v_j) && (v_j <= ((uint64_t)(v_dst.len)))) {
31246         v_dst = wuffs_base__slice_u8__subslice_ij(v_dst, v_i, v_j);
31247       } else {
31248         v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_i);
31249       }
31250       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);
31251       wuffs_base__u64__sat_add_indirect(&v_src_ri, v_n);
31252       wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)((v_n & 4294967295))));
31253       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, 1));
31254     }
31255     if (self->private_impl.f_frame_rect_x1 <= self->private_impl.f_dst_x) {
31256       self->private_impl.f_dst_x = self->private_impl.f_frame_rect_x0;
31257       if (self->private_impl.f_interlace == 0) {
31258         wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_y, 1);
31259         goto label__0__continue;
31260       }
31261       if ((self->private_impl.f_num_decoded_frames_value == 0) &&  ! self->private_impl.f_gc_has_transparent_index && (self->private_impl.f_interlace > 1)) {
31262         v_replicate_src = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
31263         v_replicate_y0 = wuffs_base__u32__sat_add(self->private_impl.f_dst_y, 1);
31264         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])));
31265         v_replicate_y1 = wuffs_base__u32__min(v_replicate_y1, self->private_impl.f_frame_rect_y1);
31266         while (v_replicate_y0 < v_replicate_y1) {
31267           v_replicate_dst = wuffs_base__table_u8__row_u32(v_tab, v_replicate_y0);
31268           wuffs_base__slice_u8__copy_from_slice(v_replicate_dst, v_replicate_src);
31269           v_replicate_y0 += 1;
31270         }
31271         self->private_impl.f_dirty_max_excl_y = wuffs_base__u32__max(self->private_impl.f_dirty_max_excl_y, v_replicate_y1);
31272       }
31273       wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_y, ((uint32_t)(WUFFS_GIF__INTERLACE_DELTA[self->private_impl.f_interlace])));
31274       while ((self->private_impl.f_interlace > 0) && (self->private_impl.f_dst_y >= self->private_impl.f_frame_rect_y1)) {
31275 #if defined(__GNUC__)
31276 #pragma GCC diagnostic push
31277 #pragma GCC diagnostic ignored "-Wconversion"
31278 #endif
31279         self->private_impl.f_interlace -= 1;
31280 #if defined(__GNUC__)
31281 #pragma GCC diagnostic pop
31282 #endif
31283         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]);
31284       }
31285       goto label__0__continue;
31286     }
31287     if (((uint64_t)(a_src.len)) == v_src_ri) {
31288       goto label__0__break;
31289     } else if (((uint64_t)(a_src.len)) < v_src_ri) {
31290       return wuffs_base__make_status(wuffs_gif__error__internal_error_inconsistent_ri_wi);
31291     }
31292     v_n = ((uint64_t)((self->private_impl.f_frame_rect_x1 - self->private_impl.f_dst_x)));
31293     v_n = wuffs_base__u64__min(v_n, (((uint64_t)(a_src.len)) - v_src_ri));
31294     wuffs_base__u64__sat_add_indirect(&v_src_ri, v_n);
31295     wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)((v_n & 4294967295))));
31296     if (self->private_impl.f_frame_rect_x1 <= self->private_impl.f_dst_x) {
31297       self->private_impl.f_dst_x = self->private_impl.f_frame_rect_x0;
31298       wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_y, ((uint32_t)(WUFFS_GIF__INTERLACE_DELTA[self->private_impl.f_interlace])));
31299       while ((self->private_impl.f_interlace > 0) && (self->private_impl.f_dst_y >= self->private_impl.f_frame_rect_y1)) {
31300 #if defined(__GNUC__)
31301 #pragma GCC diagnostic push
31302 #pragma GCC diagnostic ignored "-Wconversion"
31303 #endif
31304         self->private_impl.f_interlace -= 1;
31305 #if defined(__GNUC__)
31306 #pragma GCC diagnostic pop
31307 #endif
31308         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]);
31309       }
31310       goto label__0__continue;
31311     }
31312     if (v_src_ri != ((uint64_t)(a_src.len))) {
31313       return wuffs_base__make_status(wuffs_gif__error__internal_error_inconsistent_ri_wi);
31314     }
31315     goto label__0__break;
31316   }
31317   label__0__break:;
31318   return wuffs_base__make_status(NULL);
31319 }
31320 
31321 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GIF)
31322 
31323 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GZIP)
31324 
31325 // ---------------- Status Codes Implementations
31326 
31327 const char wuffs_gzip__error__bad_checksum[] = "#gzip: bad checksum";
31328 const char wuffs_gzip__error__bad_compression_method[] = "#gzip: bad compression method";
31329 const char wuffs_gzip__error__bad_encoding_flags[] = "#gzip: bad encoding flags";
31330 const char wuffs_gzip__error__bad_header[] = "#gzip: bad header";
31331 
31332 // ---------------- Private Consts
31333 
31334 // ---------------- Private Initializer Prototypes
31335 
31336 // ---------------- Private Function Prototypes
31337 
31338 // ---------------- VTables
31339 
31340 const wuffs_base__io_transformer__func_ptrs
31341 wuffs_gzip__decoder__func_ptrs_for__wuffs_base__io_transformer = {
31342   (wuffs_base__empty_struct(*)(void*,
31343       uint32_t,
31344       bool))(&wuffs_gzip__decoder__set_quirk_enabled),
31345   (wuffs_base__status(*)(void*,
31346       wuffs_base__io_buffer*,
31347       wuffs_base__io_buffer*,
31348       wuffs_base__slice_u8))(&wuffs_gzip__decoder__transform_io),
31349   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_gzip__decoder__workbuf_len),
31350 };
31351 
31352 // ---------------- Initializer Implementations
31353 
31354 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)31355 wuffs_gzip__decoder__initialize(
31356     wuffs_gzip__decoder* self,
31357     size_t sizeof_star_self,
31358     uint64_t wuffs_version,
31359     uint32_t options){
31360   if (!self) {
31361     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
31362   }
31363   if (sizeof(*self) != sizeof_star_self) {
31364     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
31365   }
31366   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
31367       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
31368     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
31369   }
31370 
31371   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
31372     // The whole point of this if-check is to detect an uninitialized *self.
31373     // We disable the warning on GCC. Clang-5.0 does not have this warning.
31374 #if !defined(__clang__) && defined(__GNUC__)
31375 #pragma GCC diagnostic push
31376 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
31377 #endif
31378     if (self->private_impl.magic != 0) {
31379       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
31380     }
31381 #if !defined(__clang__) && defined(__GNUC__)
31382 #pragma GCC diagnostic pop
31383 #endif
31384   } else {
31385     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
31386       memset(self, 0, sizeof(*self));
31387       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
31388     } else {
31389       memset(&(self->private_impl), 0, sizeof(self->private_impl));
31390     }
31391   }
31392 
31393   {
31394     wuffs_base__status z = wuffs_crc32__ieee_hasher__initialize(
31395         &self->private_data.f_checksum, sizeof(self->private_data.f_checksum), WUFFS_VERSION, options);
31396     if (z.repr) {
31397       return z;
31398     }
31399   }
31400   {
31401     wuffs_base__status z = wuffs_deflate__decoder__initialize(
31402         &self->private_data.f_flate, sizeof(self->private_data.f_flate), WUFFS_VERSION, options);
31403     if (z.repr) {
31404       return z;
31405     }
31406   }
31407   self->private_impl.magic = WUFFS_BASE__MAGIC;
31408   self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name =
31409       wuffs_base__io_transformer__vtable_name;
31410   self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers =
31411       (const void*)(&wuffs_gzip__decoder__func_ptrs_for__wuffs_base__io_transformer);
31412   return wuffs_base__make_status(NULL);
31413 }
31414 
31415 wuffs_gzip__decoder*
wuffs_gzip__decoder__alloc()31416 wuffs_gzip__decoder__alloc() {
31417   wuffs_gzip__decoder* x =
31418       (wuffs_gzip__decoder*)(calloc(sizeof(wuffs_gzip__decoder), 1));
31419   if (!x) {
31420     return NULL;
31421   }
31422   if (wuffs_gzip__decoder__initialize(
31423       x, sizeof(wuffs_gzip__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
31424     free(x);
31425     return NULL;
31426   }
31427   return x;
31428 }
31429 
31430 size_t
sizeof__wuffs_gzip__decoder()31431 sizeof__wuffs_gzip__decoder() {
31432   return sizeof(wuffs_gzip__decoder);
31433 }
31434 
31435 // ---------------- Function Implementations
31436 
31437 // -------- func gzip.decoder.set_quirk_enabled
31438 
31439 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_gzip__decoder__set_quirk_enabled(wuffs_gzip__decoder * self,uint32_t a_quirk,bool a_enabled)31440 wuffs_gzip__decoder__set_quirk_enabled(
31441     wuffs_gzip__decoder* self,
31442     uint32_t a_quirk,
31443     bool a_enabled) {
31444   if (!self) {
31445     return wuffs_base__make_empty_struct();
31446   }
31447   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
31448     return wuffs_base__make_empty_struct();
31449   }
31450 
31451   if (a_quirk == 1) {
31452     self->private_impl.f_ignore_checksum = a_enabled;
31453   }
31454   return wuffs_base__make_empty_struct();
31455 }
31456 
31457 // -------- func gzip.decoder.workbuf_len
31458 
31459 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_gzip__decoder__workbuf_len(const wuffs_gzip__decoder * self)31460 wuffs_gzip__decoder__workbuf_len(
31461     const wuffs_gzip__decoder* self) {
31462   if (!self) {
31463     return wuffs_base__utility__empty_range_ii_u64();
31464   }
31465   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
31466       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
31467     return wuffs_base__utility__empty_range_ii_u64();
31468   }
31469 
31470   return wuffs_base__utility__make_range_ii_u64(1, 1);
31471 }
31472 
31473 // -------- func gzip.decoder.transform_io
31474 
31475 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)31476 wuffs_gzip__decoder__transform_io(
31477     wuffs_gzip__decoder* self,
31478     wuffs_base__io_buffer* a_dst,
31479     wuffs_base__io_buffer* a_src,
31480     wuffs_base__slice_u8 a_workbuf) {
31481   if (!self) {
31482     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
31483   }
31484   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
31485     return wuffs_base__make_status(
31486         (self->private_impl.magic == WUFFS_BASE__DISABLED)
31487         ? wuffs_base__error__disabled_by_previous_error
31488         : wuffs_base__error__initialize_not_called);
31489   }
31490   if (!a_dst || !a_src) {
31491     self->private_impl.magic = WUFFS_BASE__DISABLED;
31492     return wuffs_base__make_status(wuffs_base__error__bad_argument);
31493   }
31494   if ((self->private_impl.active_coroutine != 0) &&
31495       (self->private_impl.active_coroutine != 1)) {
31496     self->private_impl.magic = WUFFS_BASE__DISABLED;
31497     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
31498   }
31499   self->private_impl.active_coroutine = 0;
31500   wuffs_base__status status = wuffs_base__make_status(NULL);
31501 
31502   uint8_t v_c = 0;
31503   uint8_t v_flags = 0;
31504   uint16_t v_xlen = 0;
31505   uint64_t v_mark = 0;
31506   uint32_t v_checksum_got = 0;
31507   uint32_t v_decoded_length_got = 0;
31508   wuffs_base__status v_status = wuffs_base__make_status(NULL);
31509   uint32_t v_checksum_want = 0;
31510   uint32_t v_decoded_length_want = 0;
31511 
31512   uint8_t* iop_a_dst = NULL;
31513   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31514   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31515   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31516   if (a_dst) {
31517     io0_a_dst = a_dst->data.ptr;
31518     io1_a_dst = io0_a_dst + a_dst->meta.wi;
31519     iop_a_dst = io1_a_dst;
31520     io2_a_dst = io0_a_dst + a_dst->data.len;
31521     if (a_dst->meta.closed) {
31522       io2_a_dst = iop_a_dst;
31523     }
31524   }
31525   const uint8_t* iop_a_src = NULL;
31526   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31527   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31528   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31529   if (a_src) {
31530     io0_a_src = a_src->data.ptr;
31531     io1_a_src = io0_a_src + a_src->meta.ri;
31532     iop_a_src = io1_a_src;
31533     io2_a_src = io0_a_src + a_src->meta.wi;
31534   }
31535 
31536   uint32_t coro_susp_point = self->private_impl.p_transform_io[0];
31537   if (coro_susp_point) {
31538     v_flags = self->private_data.s_transform_io[0].v_flags;
31539     v_checksum_got = self->private_data.s_transform_io[0].v_checksum_got;
31540     v_decoded_length_got = self->private_data.s_transform_io[0].v_decoded_length_got;
31541     v_checksum_want = self->private_data.s_transform_io[0].v_checksum_want;
31542   }
31543   switch (coro_susp_point) {
31544     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
31545 
31546     {
31547       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
31548       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31549         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31550         goto suspend;
31551       }
31552       uint8_t t_0 = *iop_a_src++;
31553       v_c = t_0;
31554     }
31555     if (v_c != 31) {
31556       status = wuffs_base__make_status(wuffs_gzip__error__bad_header);
31557       goto exit;
31558     }
31559     {
31560       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
31561       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31562         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31563         goto suspend;
31564       }
31565       uint8_t t_1 = *iop_a_src++;
31566       v_c = t_1;
31567     }
31568     if (v_c != 139) {
31569       status = wuffs_base__make_status(wuffs_gzip__error__bad_header);
31570       goto exit;
31571     }
31572     {
31573       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
31574       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31575         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31576         goto suspend;
31577       }
31578       uint8_t t_2 = *iop_a_src++;
31579       v_c = t_2;
31580     }
31581     if (v_c != 8) {
31582       status = wuffs_base__make_status(wuffs_gzip__error__bad_compression_method);
31583       goto exit;
31584     }
31585     {
31586       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
31587       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31588         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31589         goto suspend;
31590       }
31591       uint8_t t_3 = *iop_a_src++;
31592       v_flags = t_3;
31593     }
31594     self->private_data.s_transform_io[0].scratch = 6;
31595     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
31596     if (self->private_data.s_transform_io[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
31597       self->private_data.s_transform_io[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
31598       iop_a_src = io2_a_src;
31599       status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31600       goto suspend;
31601     }
31602     iop_a_src += self->private_data.s_transform_io[0].scratch;
31603     if ((v_flags & 4) != 0) {
31604       {
31605         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
31606         uint16_t t_4;
31607         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
31608           t_4 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src);
31609           iop_a_src += 2;
31610         } else {
31611           self->private_data.s_transform_io[0].scratch = 0;
31612           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
31613           while (true) {
31614             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31615               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31616               goto suspend;
31617             }
31618             uint64_t* scratch = &self->private_data.s_transform_io[0].scratch;
31619             uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
31620             *scratch <<= 8;
31621             *scratch >>= 8;
31622             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
31623             if (num_bits_4 == 8) {
31624               t_4 = ((uint16_t)(*scratch));
31625               break;
31626             }
31627             num_bits_4 += 8;
31628             *scratch |= ((uint64_t)(num_bits_4)) << 56;
31629           }
31630         }
31631         v_xlen = t_4;
31632       }
31633       self->private_data.s_transform_io[0].scratch = ((uint32_t)(v_xlen));
31634       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
31635       if (self->private_data.s_transform_io[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
31636         self->private_data.s_transform_io[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
31637         iop_a_src = io2_a_src;
31638         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31639         goto suspend;
31640       }
31641       iop_a_src += self->private_data.s_transform_io[0].scratch;
31642     }
31643     if ((v_flags & 8) != 0) {
31644       while (true) {
31645         {
31646           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
31647           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31648             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31649             goto suspend;
31650           }
31651           uint8_t t_5 = *iop_a_src++;
31652           v_c = t_5;
31653         }
31654         if (v_c == 0) {
31655           goto label__0__break;
31656         }
31657       }
31658       label__0__break:;
31659     }
31660     if ((v_flags & 16) != 0) {
31661       while (true) {
31662         {
31663           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
31664           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31665             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31666             goto suspend;
31667           }
31668           uint8_t t_6 = *iop_a_src++;
31669           v_c = t_6;
31670         }
31671         if (v_c == 0) {
31672           goto label__1__break;
31673         }
31674       }
31675       label__1__break:;
31676     }
31677     if ((v_flags & 2) != 0) {
31678       self->private_data.s_transform_io[0].scratch = 2;
31679       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
31680       if (self->private_data.s_transform_io[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
31681         self->private_data.s_transform_io[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
31682         iop_a_src = io2_a_src;
31683         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31684         goto suspend;
31685       }
31686       iop_a_src += self->private_data.s_transform_io[0].scratch;
31687     }
31688     if ((v_flags & 224) != 0) {
31689       status = wuffs_base__make_status(wuffs_gzip__error__bad_encoding_flags);
31690       goto exit;
31691     }
31692     while (true) {
31693       v_mark = ((uint64_t)(iop_a_dst - io0_a_dst));
31694       {
31695         if (a_dst) {
31696           a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
31697         }
31698         if (a_src) {
31699           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
31700         }
31701         wuffs_base__status t_7 = wuffs_deflate__decoder__transform_io(&self->private_data.f_flate, a_dst, a_src, a_workbuf);
31702         v_status = t_7;
31703         if (a_dst) {
31704           iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
31705         }
31706         if (a_src) {
31707           iop_a_src = a_src->data.ptr + a_src->meta.ri;
31708         }
31709       }
31710       if ( ! self->private_impl.f_ignore_checksum) {
31711         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));
31712         v_decoded_length_got += ((uint32_t)((wuffs_base__io__count_since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst))) & 4294967295)));
31713       }
31714       if (wuffs_base__status__is_ok(&v_status)) {
31715         goto label__2__break;
31716       }
31717       status = v_status;
31718       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(12);
31719     }
31720     label__2__break:;
31721     {
31722       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
31723       uint32_t t_8;
31724       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
31725         t_8 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
31726         iop_a_src += 4;
31727       } else {
31728         self->private_data.s_transform_io[0].scratch = 0;
31729         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
31730         while (true) {
31731           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31732             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31733             goto suspend;
31734           }
31735           uint64_t* scratch = &self->private_data.s_transform_io[0].scratch;
31736           uint32_t num_bits_8 = ((uint32_t)(*scratch >> 56));
31737           *scratch <<= 8;
31738           *scratch >>= 8;
31739           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_8;
31740           if (num_bits_8 == 24) {
31741             t_8 = ((uint32_t)(*scratch));
31742             break;
31743           }
31744           num_bits_8 += 8;
31745           *scratch |= ((uint64_t)(num_bits_8)) << 56;
31746         }
31747       }
31748       v_checksum_want = t_8;
31749     }
31750     {
31751       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
31752       uint32_t t_9;
31753       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
31754         t_9 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
31755         iop_a_src += 4;
31756       } else {
31757         self->private_data.s_transform_io[0].scratch = 0;
31758         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
31759         while (true) {
31760           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31761             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31762             goto suspend;
31763           }
31764           uint64_t* scratch = &self->private_data.s_transform_io[0].scratch;
31765           uint32_t num_bits_9 = ((uint32_t)(*scratch >> 56));
31766           *scratch <<= 8;
31767           *scratch >>= 8;
31768           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_9;
31769           if (num_bits_9 == 24) {
31770             t_9 = ((uint32_t)(*scratch));
31771             break;
31772           }
31773           num_bits_9 += 8;
31774           *scratch |= ((uint64_t)(num_bits_9)) << 56;
31775         }
31776       }
31777       v_decoded_length_want = t_9;
31778     }
31779     if ( ! self->private_impl.f_ignore_checksum && ((v_checksum_got != v_checksum_want) || (v_decoded_length_got != v_decoded_length_want))) {
31780       status = wuffs_base__make_status(wuffs_gzip__error__bad_checksum);
31781       goto exit;
31782     }
31783 
31784     ok:
31785     self->private_impl.p_transform_io[0] = 0;
31786     goto exit;
31787   }
31788 
31789   goto suspend;
31790   suspend:
31791   self->private_impl.p_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
31792   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
31793   self->private_data.s_transform_io[0].v_flags = v_flags;
31794   self->private_data.s_transform_io[0].v_checksum_got = v_checksum_got;
31795   self->private_data.s_transform_io[0].v_decoded_length_got = v_decoded_length_got;
31796   self->private_data.s_transform_io[0].v_checksum_want = v_checksum_want;
31797 
31798   goto exit;
31799   exit:
31800   if (a_dst) {
31801     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
31802   }
31803   if (a_src) {
31804     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
31805   }
31806 
31807   if (wuffs_base__status__is_error(&status)) {
31808     self->private_impl.magic = WUFFS_BASE__DISABLED;
31809   }
31810   return status;
31811 }
31812 
31813 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GZIP)
31814 
31815 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JSON)
31816 
31817 // ---------------- Status Codes Implementations
31818 
31819 const char wuffs_json__error__bad_c0_control_code[] = "#json: bad C0 control code";
31820 const char wuffs_json__error__bad_utf_8[] = "#json: bad UTF-8";
31821 const char wuffs_json__error__bad_backslash_escape[] = "#json: bad backslash-escape";
31822 const char wuffs_json__error__bad_input[] = "#json: bad input";
31823 const char wuffs_json__error__bad_new_line_in_a_string[] = "#json: bad new-line in a string";
31824 const char wuffs_json__error__bad_quirk_combination[] = "#json: bad quirk combination";
31825 const char wuffs_json__error__unsupported_number_length[] = "#json: unsupported number length";
31826 const char wuffs_json__error__unsupported_recursion_depth[] = "#json: unsupported recursion depth";
31827 const char wuffs_json__error__internal_error_inconsistent_i_o[] = "#json: internal error: inconsistent I/O";
31828 
31829 // ---------------- Private Consts
31830 
31831 #define WUFFS_JSON__DECODER_NUMBER_LENGTH_MAX_INCL 99
31832 
31833 static const uint8_t
31834 WUFFS_JSON__LUT_BACKSLASHES[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
31835   0, 0, 0, 0, 0, 0, 0, 0,
31836   0, 0, 3, 0, 0, 0, 0, 0,
31837   0, 0, 0, 0, 0, 0, 0, 0,
31838   0, 0, 0, 0, 0, 0, 0, 0,
31839   0, 0, 162, 0, 0, 0, 0, 5,
31840   0, 0, 0, 0, 0, 0, 0, 175,
31841   7, 0, 0, 0, 0, 0, 0, 0,
31842   0, 0, 0, 0, 0, 0, 0, 4,
31843   0, 0, 0, 0, 0, 0, 0, 0,
31844   0, 0, 0, 0, 0, 0, 0, 0,
31845   0, 0, 0, 0, 0, 0, 0, 0,
31846   0, 0, 0, 0, 220, 0, 0, 0,
31847   0, 1, 136, 0, 0, 2, 140, 0,
31848   0, 0, 0, 0, 0, 0, 138, 0,
31849   0, 0, 141, 0, 137, 0, 6, 0,
31850   0, 0, 0, 0, 0, 0, 0, 0,
31851   0, 0, 0, 0, 0, 0, 0, 0,
31852   0, 0, 0, 0, 0, 0, 0, 0,
31853   0, 0, 0, 0, 0, 0, 0, 0,
31854   0, 0, 0, 0, 0, 0, 0, 0,
31855   0, 0, 0, 0, 0, 0, 0, 0,
31856   0, 0, 0, 0, 0, 0, 0, 0,
31857   0, 0, 0, 0, 0, 0, 0, 0,
31858   0, 0, 0, 0, 0, 0, 0, 0,
31859   0, 0, 0, 0, 0, 0, 0, 0,
31860   0, 0, 0, 0, 0, 0, 0, 0,
31861   0, 0, 0, 0, 0, 0, 0, 0,
31862   0, 0, 0, 0, 0, 0, 0, 0,
31863   0, 0, 0, 0, 0, 0, 0, 0,
31864   0, 0, 0, 0, 0, 0, 0, 0,
31865   0, 0, 0, 0, 0, 0, 0, 0,
31866   0, 0, 0, 0, 0, 0, 0, 0,
31867 };
31868 
31869 static const uint8_t
31870 WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_QUIRKS[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
31871   0, 1, 3, 4, 5, 6, 7, 10,
31872 };
31873 
31874 static const uint8_t
31875 WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_CHARS[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
31876   0, 7, 27, 10, 63, 39, 11, 0,
31877 };
31878 
31879 static const uint8_t
31880 WUFFS_JSON__LUT_CHARS[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
31881   128, 129, 130, 131, 132, 133, 134, 135,
31882   136, 137, 138, 139, 140, 141, 142, 143,
31883   144, 145, 146, 147, 148, 149, 150, 151,
31884   152, 153, 154, 155, 156, 157, 158, 159,
31885   0, 0, 1, 0, 0, 0, 0, 0,
31886   0, 0, 0, 0, 0, 0, 0, 0,
31887   0, 0, 0, 0, 0, 0, 0, 0,
31888   0, 0, 0, 0, 0, 0, 0, 0,
31889   0, 0, 0, 0, 0, 0, 0, 0,
31890   0, 0, 0, 0, 0, 0, 0, 0,
31891   0, 0, 0, 0, 0, 0, 0, 0,
31892   0, 0, 0, 0, 2, 0, 0, 0,
31893   0, 0, 0, 0, 0, 0, 0, 0,
31894   0, 0, 0, 0, 0, 0, 0, 0,
31895   0, 0, 0, 0, 0, 0, 0, 0,
31896   0, 0, 0, 0, 0, 0, 0, 0,
31897   16, 16, 16, 16, 16, 16, 16, 16,
31898   16, 16, 16, 16, 16, 16, 16, 16,
31899   16, 16, 16, 16, 16, 16, 16, 16,
31900   16, 16, 16, 16, 16, 16, 16, 16,
31901   16, 16, 16, 16, 16, 16, 16, 16,
31902   16, 16, 16, 16, 16, 16, 16, 16,
31903   16, 16, 16, 16, 16, 16, 16, 16,
31904   16, 16, 16, 16, 16, 16, 16, 16,
31905   32, 32, 3, 3, 3, 3, 3, 3,
31906   3, 3, 3, 3, 3, 3, 3, 3,
31907   3, 3, 3, 3, 3, 3, 3, 3,
31908   3, 3, 3, 3, 3, 3, 3, 3,
31909   4, 4, 4, 4, 4, 4, 4, 4,
31910   4, 4, 4, 4, 4, 4, 4, 4,
31911   5, 5, 5, 5, 5, 32, 32, 32,
31912   32, 32, 32, 32, 32, 32, 32, 32,
31913 };
31914 
31915 #define WUFFS_JSON__CLASS_WHITESPACE 0
31916 
31917 #define WUFFS_JSON__CLASS_STRING 1
31918 
31919 #define WUFFS_JSON__CLASS_COMMA 2
31920 
31921 #define WUFFS_JSON__CLASS_COLON 3
31922 
31923 #define WUFFS_JSON__CLASS_NUMBER 4
31924 
31925 #define WUFFS_JSON__CLASS_OPEN_CURLY_BRACE 5
31926 
31927 #define WUFFS_JSON__CLASS_CLOSE_CURLY_BRACE 6
31928 
31929 #define WUFFS_JSON__CLASS_OPEN_SQUARE_BRACKET 7
31930 
31931 #define WUFFS_JSON__CLASS_CLOSE_SQUARE_BRACKET 8
31932 
31933 #define WUFFS_JSON__CLASS_FALSE 9
31934 
31935 #define WUFFS_JSON__CLASS_TRUE 10
31936 
31937 #define WUFFS_JSON__CLASS_NULL_NAN_INF 11
31938 
31939 #define WUFFS_JSON__CLASS_COMMENT 12
31940 
31941 #define WUFFS_JSON__EXPECT_VALUE 7858
31942 
31943 #define WUFFS_JSON__EXPECT_NON_STRING_VALUE 7856
31944 
31945 #define WUFFS_JSON__EXPECT_STRING 4098
31946 
31947 #define WUFFS_JSON__EXPECT_COMMA 4100
31948 
31949 #define WUFFS_JSON__EXPECT_COLON 4104
31950 
31951 #define WUFFS_JSON__EXPECT_NUMBER 4112
31952 
31953 #define WUFFS_JSON__EXPECT_CLOSE_CURLY_BRACE 4160
31954 
31955 #define WUFFS_JSON__EXPECT_CLOSE_SQUARE_BRACKET 4352
31956 
31957 static const uint8_t
31958 WUFFS_JSON__LUT_CLASSES[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
31959   15, 15, 15, 15, 15, 15, 15, 15,
31960   15, 0, 0, 15, 15, 0, 15, 15,
31961   15, 15, 15, 15, 15, 15, 15, 15,
31962   15, 15, 15, 15, 15, 15, 15, 15,
31963   0, 15, 1, 15, 15, 15, 15, 15,
31964   15, 15, 15, 11, 2, 4, 15, 12,
31965   4, 4, 4, 4, 4, 4, 4, 4,
31966   4, 4, 3, 15, 15, 15, 15, 15,
31967   15, 15, 15, 15, 15, 15, 15, 15,
31968   15, 11, 15, 15, 15, 15, 11, 15,
31969   15, 15, 15, 15, 15, 15, 15, 15,
31970   15, 15, 15, 7, 15, 8, 15, 15,
31971   15, 15, 15, 15, 15, 15, 9, 15,
31972   15, 11, 15, 15, 15, 15, 11, 15,
31973   15, 15, 15, 15, 10, 15, 15, 15,
31974   15, 15, 15, 5, 15, 6, 15, 15,
31975   15, 15, 15, 15, 15, 15, 15, 15,
31976   15, 15, 15, 15, 15, 15, 15, 15,
31977   15, 15, 15, 15, 15, 15, 15, 15,
31978   15, 15, 15, 15, 15, 15, 15, 15,
31979   15, 15, 15, 15, 15, 15, 15, 15,
31980   15, 15, 15, 15, 15, 15, 15, 15,
31981   15, 15, 15, 15, 15, 15, 15, 15,
31982   15, 15, 15, 15, 15, 15, 15, 15,
31983   15, 15, 15, 15, 15, 15, 15, 15,
31984   15, 15, 15, 15, 15, 15, 15, 15,
31985   15, 15, 15, 15, 15, 15, 15, 15,
31986   15, 15, 15, 15, 15, 15, 15, 15,
31987   15, 15, 15, 15, 15, 15, 15, 15,
31988   15, 15, 15, 15, 15, 15, 15, 15,
31989   15, 15, 15, 15, 15, 15, 15, 15,
31990   15, 15, 15, 15, 15, 15, 15, 15,
31991 };
31992 
31993 static const uint8_t
31994 WUFFS_JSON__LUT_DECIMAL_DIGITS[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
31995   0, 0, 0, 0, 0, 0, 0, 0,
31996   0, 0, 0, 0, 0, 0, 0, 0,
31997   0, 0, 0, 0, 0, 0, 0, 0,
31998   0, 0, 0, 0, 0, 0, 0, 0,
31999   0, 0, 0, 0, 0, 0, 0, 0,
32000   0, 0, 0, 0, 0, 0, 0, 0,
32001   128, 129, 130, 131, 132, 133, 134, 135,
32002   136, 137, 0, 0, 0, 0, 0, 0,
32003   0, 0, 0, 0, 0, 0, 0, 0,
32004   0, 0, 0, 0, 0, 0, 0, 0,
32005   0, 0, 0, 0, 0, 0, 0, 0,
32006   0, 0, 0, 0, 0, 0, 0, 0,
32007   0, 0, 0, 0, 0, 0, 0, 0,
32008   0, 0, 0, 0, 0, 0, 0, 0,
32009   0, 0, 0, 0, 0, 0, 0, 0,
32010   0, 0, 0, 0, 0, 0, 0, 0,
32011   0, 0, 0, 0, 0, 0, 0, 0,
32012   0, 0, 0, 0, 0, 0, 0, 0,
32013   0, 0, 0, 0, 0, 0, 0, 0,
32014   0, 0, 0, 0, 0, 0, 0, 0,
32015   0, 0, 0, 0, 0, 0, 0, 0,
32016   0, 0, 0, 0, 0, 0, 0, 0,
32017   0, 0, 0, 0, 0, 0, 0, 0,
32018   0, 0, 0, 0, 0, 0, 0, 0,
32019   0, 0, 0, 0, 0, 0, 0, 0,
32020   0, 0, 0, 0, 0, 0, 0, 0,
32021   0, 0, 0, 0, 0, 0, 0, 0,
32022   0, 0, 0, 0, 0, 0, 0, 0,
32023   0, 0, 0, 0, 0, 0, 0, 0,
32024   0, 0, 0, 0, 0, 0, 0, 0,
32025   0, 0, 0, 0, 0, 0, 0, 0,
32026   0, 0, 0, 0, 0, 0, 0, 0,
32027 };
32028 
32029 static const uint8_t
32030 WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
32031   0, 0, 0, 0, 0, 0, 0, 0,
32032   0, 0, 0, 0, 0, 0, 0, 0,
32033   0, 0, 0, 0, 0, 0, 0, 0,
32034   0, 0, 0, 0, 0, 0, 0, 0,
32035   0, 0, 0, 0, 0, 0, 0, 0,
32036   0, 0, 0, 0, 0, 0, 0, 0,
32037   128, 129, 130, 131, 132, 133, 134, 135,
32038   136, 137, 0, 0, 0, 0, 0, 0,
32039   0, 138, 139, 140, 141, 142, 143, 0,
32040   0, 0, 0, 0, 0, 0, 0, 0,
32041   0, 0, 0, 0, 0, 0, 0, 0,
32042   0, 0, 0, 0, 0, 0, 0, 0,
32043   0, 138, 139, 140, 141, 142, 143, 0,
32044   0, 0, 0, 0, 0, 0, 0, 0,
32045   0, 0, 0, 0, 0, 0, 0, 0,
32046   0, 0, 0, 0, 0, 0, 0, 0,
32047   0, 0, 0, 0, 0, 0, 0, 0,
32048   0, 0, 0, 0, 0, 0, 0, 0,
32049   0, 0, 0, 0, 0, 0, 0, 0,
32050   0, 0, 0, 0, 0, 0, 0, 0,
32051   0, 0, 0, 0, 0, 0, 0, 0,
32052   0, 0, 0, 0, 0, 0, 0, 0,
32053   0, 0, 0, 0, 0, 0, 0, 0,
32054   0, 0, 0, 0, 0, 0, 0, 0,
32055   0, 0, 0, 0, 0, 0, 0, 0,
32056   0, 0, 0, 0, 0, 0, 0, 0,
32057   0, 0, 0, 0, 0, 0, 0, 0,
32058   0, 0, 0, 0, 0, 0, 0, 0,
32059   0, 0, 0, 0, 0, 0, 0, 0,
32060   0, 0, 0, 0, 0, 0, 0, 0,
32061   0, 0, 0, 0, 0, 0, 0, 0,
32062   0, 0, 0, 0, 0, 0, 0, 0,
32063 };
32064 
32065 #define WUFFS_JSON__QUIRKS_BASE 1225364480
32066 
32067 #define WUFFS_JSON__QUIRKS_COUNT 21
32068 
32069 // ---------------- Private Initializer Prototypes
32070 
32071 // ---------------- Private Function Prototypes
32072 
32073 static uint32_t
32074 wuffs_json__decoder__decode_number(
32075     wuffs_json__decoder* self,
32076     wuffs_base__io_buffer* a_src);
32077 
32078 static uint32_t
32079 wuffs_json__decoder__decode_digits(
32080     wuffs_json__decoder* self,
32081     wuffs_base__io_buffer* a_src,
32082     uint32_t a_n);
32083 
32084 static wuffs_base__status
32085 wuffs_json__decoder__decode_leading(
32086     wuffs_json__decoder* self,
32087     wuffs_base__token_buffer* a_dst,
32088     wuffs_base__io_buffer* a_src);
32089 
32090 static wuffs_base__status
32091 wuffs_json__decoder__decode_comment(
32092     wuffs_json__decoder* self,
32093     wuffs_base__token_buffer* a_dst,
32094     wuffs_base__io_buffer* a_src);
32095 
32096 static wuffs_base__status
32097 wuffs_json__decoder__decode_inf_nan(
32098     wuffs_json__decoder* self,
32099     wuffs_base__token_buffer* a_dst,
32100     wuffs_base__io_buffer* a_src);
32101 
32102 static wuffs_base__status
32103 wuffs_json__decoder__decode_trailer(
32104     wuffs_json__decoder* self,
32105     wuffs_base__token_buffer* a_dst,
32106     wuffs_base__io_buffer* a_src);
32107 
32108 // ---------------- VTables
32109 
32110 const wuffs_base__token_decoder__func_ptrs
32111 wuffs_json__decoder__func_ptrs_for__wuffs_base__token_decoder = {
32112   (wuffs_base__status(*)(void*,
32113       wuffs_base__token_buffer*,
32114       wuffs_base__io_buffer*,
32115       wuffs_base__slice_u8))(&wuffs_json__decoder__decode_tokens),
32116   (wuffs_base__empty_struct(*)(void*,
32117       uint32_t,
32118       bool))(&wuffs_json__decoder__set_quirk_enabled),
32119   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_json__decoder__workbuf_len),
32120 };
32121 
32122 // ---------------- Initializer Implementations
32123 
32124 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)32125 wuffs_json__decoder__initialize(
32126     wuffs_json__decoder* self,
32127     size_t sizeof_star_self,
32128     uint64_t wuffs_version,
32129     uint32_t options){
32130   if (!self) {
32131     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
32132   }
32133   if (sizeof(*self) != sizeof_star_self) {
32134     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
32135   }
32136   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
32137       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
32138     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
32139   }
32140 
32141   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
32142     // The whole point of this if-check is to detect an uninitialized *self.
32143     // We disable the warning on GCC. Clang-5.0 does not have this warning.
32144 #if !defined(__clang__) && defined(__GNUC__)
32145 #pragma GCC diagnostic push
32146 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
32147 #endif
32148     if (self->private_impl.magic != 0) {
32149       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
32150     }
32151 #if !defined(__clang__) && defined(__GNUC__)
32152 #pragma GCC diagnostic pop
32153 #endif
32154   } else {
32155     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
32156       memset(self, 0, sizeof(*self));
32157       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
32158     } else {
32159       memset(&(self->private_impl), 0, sizeof(self->private_impl));
32160     }
32161   }
32162 
32163   self->private_impl.magic = WUFFS_BASE__MAGIC;
32164   self->private_impl.vtable_for__wuffs_base__token_decoder.vtable_name =
32165       wuffs_base__token_decoder__vtable_name;
32166   self->private_impl.vtable_for__wuffs_base__token_decoder.function_pointers =
32167       (const void*)(&wuffs_json__decoder__func_ptrs_for__wuffs_base__token_decoder);
32168   return wuffs_base__make_status(NULL);
32169 }
32170 
32171 wuffs_json__decoder*
wuffs_json__decoder__alloc()32172 wuffs_json__decoder__alloc() {
32173   wuffs_json__decoder* x =
32174       (wuffs_json__decoder*)(calloc(sizeof(wuffs_json__decoder), 1));
32175   if (!x) {
32176     return NULL;
32177   }
32178   if (wuffs_json__decoder__initialize(
32179       x, sizeof(wuffs_json__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
32180     free(x);
32181     return NULL;
32182   }
32183   return x;
32184 }
32185 
32186 size_t
sizeof__wuffs_json__decoder()32187 sizeof__wuffs_json__decoder() {
32188   return sizeof(wuffs_json__decoder);
32189 }
32190 
32191 // ---------------- Function Implementations
32192 
32193 // -------- func json.decoder.set_quirk_enabled
32194 
32195 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_json__decoder__set_quirk_enabled(wuffs_json__decoder * self,uint32_t a_quirk,bool a_enabled)32196 wuffs_json__decoder__set_quirk_enabled(
32197     wuffs_json__decoder* self,
32198     uint32_t a_quirk,
32199     bool a_enabled) {
32200   if (!self) {
32201     return wuffs_base__make_empty_struct();
32202   }
32203   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
32204     return wuffs_base__make_empty_struct();
32205   }
32206 
32207   if (a_quirk >= 1225364480) {
32208     a_quirk -= 1225364480;
32209     if (a_quirk < 21) {
32210       self->private_impl.f_quirks[a_quirk] = a_enabled;
32211     }
32212   }
32213   return wuffs_base__make_empty_struct();
32214 }
32215 
32216 // -------- func json.decoder.workbuf_len
32217 
32218 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_json__decoder__workbuf_len(const wuffs_json__decoder * self)32219 wuffs_json__decoder__workbuf_len(
32220     const wuffs_json__decoder* self) {
32221   if (!self) {
32222     return wuffs_base__utility__empty_range_ii_u64();
32223   }
32224   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
32225       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
32226     return wuffs_base__utility__empty_range_ii_u64();
32227   }
32228 
32229   return wuffs_base__utility__empty_range_ii_u64();
32230 }
32231 
32232 // -------- func json.decoder.decode_tokens
32233 
32234 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)32235 wuffs_json__decoder__decode_tokens(
32236     wuffs_json__decoder* self,
32237     wuffs_base__token_buffer* a_dst,
32238     wuffs_base__io_buffer* a_src,
32239     wuffs_base__slice_u8 a_workbuf) {
32240   if (!self) {
32241     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
32242   }
32243   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
32244     return wuffs_base__make_status(
32245         (self->private_impl.magic == WUFFS_BASE__DISABLED)
32246         ? wuffs_base__error__disabled_by_previous_error
32247         : wuffs_base__error__initialize_not_called);
32248   }
32249   if (!a_dst || !a_src) {
32250     self->private_impl.magic = WUFFS_BASE__DISABLED;
32251     return wuffs_base__make_status(wuffs_base__error__bad_argument);
32252   }
32253   if ((self->private_impl.active_coroutine != 0) &&
32254       (self->private_impl.active_coroutine != 1)) {
32255     self->private_impl.magic = WUFFS_BASE__DISABLED;
32256     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
32257   }
32258   self->private_impl.active_coroutine = 0;
32259   wuffs_base__status status = wuffs_base__make_status(NULL);
32260 
32261   uint32_t v_vminor = 0;
32262   uint32_t v_number_length = 0;
32263   uint32_t v_number_status = 0;
32264   uint32_t v_string_length = 0;
32265   uint32_t v_whitespace_length = 0;
32266   uint32_t v_depth = 0;
32267   uint32_t v_stack_byte = 0;
32268   uint32_t v_stack_bit = 0;
32269   uint32_t v_match = 0;
32270   uint32_t v_c4 = 0;
32271   uint8_t v_c = 0;
32272   uint8_t v_backslash = 0;
32273   uint8_t v_char = 0;
32274   uint8_t v_class = 0;
32275   uint32_t v_multi_byte_utf8 = 0;
32276   uint8_t v_backslash_x_ok = 0;
32277   uint8_t v_backslash_x_value = 0;
32278   uint32_t v_backslash_x_string = 0;
32279   uint8_t v_uni4_ok = 0;
32280   uint64_t v_uni4_string = 0;
32281   uint32_t v_uni4_value = 0;
32282   uint32_t v_uni4_high_surrogate = 0;
32283   uint8_t v_uni8_ok = 0;
32284   uint64_t v_uni8_string = 0;
32285   uint32_t v_uni8_value = 0;
32286   uint32_t v_expect = 0;
32287   uint32_t v_expect_after_value = 0;
32288 
32289   wuffs_base__token* iop_a_dst = NULL;
32290   wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32291   wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32292   wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32293   if (a_dst) {
32294     io0_a_dst = a_dst->data.ptr;
32295     io1_a_dst = io0_a_dst + a_dst->meta.wi;
32296     iop_a_dst = io1_a_dst;
32297     io2_a_dst = io0_a_dst + a_dst->data.len;
32298     if (a_dst->meta.closed) {
32299       io2_a_dst = iop_a_dst;
32300     }
32301   }
32302   const uint8_t* iop_a_src = NULL;
32303   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32304   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32305   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32306   if (a_src) {
32307     io0_a_src = a_src->data.ptr;
32308     io1_a_src = io0_a_src + a_src->meta.ri;
32309     iop_a_src = io1_a_src;
32310     io2_a_src = io0_a_src + a_src->meta.wi;
32311   }
32312 
32313   uint32_t coro_susp_point = self->private_impl.p_decode_tokens[0];
32314   if (coro_susp_point) {
32315     v_depth = self->private_data.s_decode_tokens[0].v_depth;
32316     v_expect = self->private_data.s_decode_tokens[0].v_expect;
32317     v_expect_after_value = self->private_data.s_decode_tokens[0].v_expect_after_value;
32318   }
32319   switch (coro_susp_point) {
32320     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
32321 
32322     if (self->private_impl.f_end_of_data) {
32323       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
32324       goto ok;
32325     }
32326     if (self->private_impl.f_quirks[18]) {
32327       if (self->private_impl.f_quirks[11] || self->private_impl.f_quirks[12] || self->private_impl.f_quirks[17]) {
32328         status = wuffs_base__make_status(wuffs_json__error__bad_quirk_combination);
32329         goto exit;
32330       }
32331     }
32332     if (self->private_impl.f_quirks[15] || self->private_impl.f_quirks[16]) {
32333       if (a_dst) {
32334         a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
32335       }
32336       if (a_src) {
32337         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
32338       }
32339       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
32340       status = wuffs_json__decoder__decode_leading(self, a_dst, a_src);
32341       if (a_dst) {
32342         iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
32343       }
32344       if (a_src) {
32345         iop_a_src = a_src->data.ptr + a_src->meta.ri;
32346       }
32347       if (status.repr) {
32348         goto suspend;
32349       }
32350     }
32351     v_expect = 7858;
32352     label__outer__continue:;
32353     while (true) {
32354       while (true) {
32355         if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
32356           status = wuffs_base__make_status(wuffs_base__suspension__short_write);
32357           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
32358           goto label__outer__continue;
32359         }
32360         v_whitespace_length = 0;
32361         v_c = 0;
32362         v_class = 0;
32363         while (true) {
32364           if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
32365             if (v_whitespace_length > 0) {
32366               *iop_a_dst++ = wuffs_base__make_token(
32367                   (((uint64_t)(0)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32368                   (((uint64_t)(v_whitespace_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32369               v_whitespace_length = 0;
32370             }
32371             if (a_src && a_src->meta.closed) {
32372               status = wuffs_base__make_status(wuffs_json__error__bad_input);
32373               goto exit;
32374             }
32375             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32376             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
32377             v_whitespace_length = 0;
32378             goto label__outer__continue;
32379           }
32380           v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
32381           v_class = WUFFS_JSON__LUT_CLASSES[v_c];
32382           if (v_class != 0) {
32383             goto label__ws__break;
32384           }
32385           iop_a_src += 1;
32386           if (v_whitespace_length >= 65534) {
32387             *iop_a_dst++ = wuffs_base__make_token(
32388                 (((uint64_t)(0)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32389                 (((uint64_t)(65535)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32390             v_whitespace_length = 0;
32391             goto label__outer__continue;
32392           }
32393           v_whitespace_length += 1;
32394         }
32395         label__ws__break:;
32396         if (v_whitespace_length > 0) {
32397           *iop_a_dst++ = wuffs_base__make_token(
32398               (((uint64_t)(0)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32399               (((uint64_t)(v_whitespace_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32400           v_whitespace_length = 0;
32401           if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
32402             goto label__outer__continue;
32403           }
32404         }
32405         if (0 == (v_expect & (((uint32_t)(1)) << v_class))) {
32406           status = wuffs_base__make_status(wuffs_json__error__bad_input);
32407           goto exit;
32408         }
32409         if (v_class == 1) {
32410           *iop_a_dst++ = wuffs_base__make_token(
32411               (((uint64_t)(4194579)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32412               (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32413               (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32414           iop_a_src += 1;
32415           label__string_loop_outer__continue:;
32416           while (true) {
32417             if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
32418               status = wuffs_base__make_status(wuffs_base__suspension__short_write);
32419               WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
32420               goto label__string_loop_outer__continue;
32421             }
32422             v_string_length = 0;
32423             label__string_loop_inner__continue:;
32424             while (true) {
32425               if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
32426                 if (v_string_length > 0) {
32427                   *iop_a_dst++ = wuffs_base__make_token(
32428                       (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32429                       (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32430                       (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32431                   v_string_length = 0;
32432                 }
32433                 if (a_src && a_src->meta.closed) {
32434                   status = wuffs_base__make_status(wuffs_json__error__bad_input);
32435                   goto exit;
32436                 }
32437                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32438                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
32439                 v_string_length = 0;
32440                 goto label__string_loop_outer__continue;
32441               }
32442               while (((uint64_t)(io2_a_src - iop_a_src)) > 4) {
32443                 v_c4 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
32444                 if (0 != (WUFFS_JSON__LUT_CHARS[(255 & (v_c4 >> 0))] |
32445                     WUFFS_JSON__LUT_CHARS[(255 & (v_c4 >> 8))] |
32446                     WUFFS_JSON__LUT_CHARS[(255 & (v_c4 >> 16))] |
32447                     WUFFS_JSON__LUT_CHARS[(255 & (v_c4 >> 24))])) {
32448                   goto label__0__break;
32449                 }
32450                 iop_a_src += 4;
32451                 if (v_string_length > 65527) {
32452                   *iop_a_dst++ = wuffs_base__make_token(
32453                       (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32454                       (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32455                       (((uint64_t)((v_string_length + 4))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32456                   v_string_length = 0;
32457                   goto label__string_loop_outer__continue;
32458                 }
32459                 v_string_length += 4;
32460               }
32461               label__0__break:;
32462               v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
32463               v_char = WUFFS_JSON__LUT_CHARS[v_c];
32464               if (v_char == 0) {
32465                 iop_a_src += 1;
32466                 if (v_string_length >= 65531) {
32467                   *iop_a_dst++ = wuffs_base__make_token(
32468                       (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32469                       (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32470                       (((uint64_t)(65532)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32471                   v_string_length = 0;
32472                   goto label__string_loop_outer__continue;
32473                 }
32474                 v_string_length += 1;
32475                 goto label__string_loop_inner__continue;
32476               } else if (v_char == 1) {
32477                 if (v_string_length != 0) {
32478                   *iop_a_dst++ = wuffs_base__make_token(
32479                       (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32480                       (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32481                       (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32482                   v_string_length = 0;
32483                 }
32484                 goto label__string_loop_outer__break;
32485               } else if (v_char == 2) {
32486                 if (v_string_length > 0) {
32487                   *iop_a_dst++ = wuffs_base__make_token(
32488                       (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32489                       (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32490                       (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32491                   v_string_length = 0;
32492                   if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
32493                     goto label__string_loop_outer__continue;
32494                   }
32495                 }
32496                 if (((uint64_t)(io2_a_src - iop_a_src)) < 2) {
32497                   if (a_src && a_src->meta.closed) {
32498                     status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
32499                     goto exit;
32500                   }
32501                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32502                   WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
32503                   v_string_length = 0;
32504                   v_char = 0;
32505                   goto label__string_loop_outer__continue;
32506                 }
32507                 v_c = ((uint8_t)((wuffs_base__peek_u16le__no_bounds_check(iop_a_src) >> 8)));
32508                 v_backslash = WUFFS_JSON__LUT_BACKSLASHES[v_c];
32509                 if ((v_backslash & 128) != 0) {
32510                   iop_a_src += 2;
32511                   *iop_a_dst++ = wuffs_base__make_token(
32512                       (((uint64_t)((6291456 | ((uint32_t)((v_backslash & 127)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32513                       (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32514                       (((uint64_t)(2)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32515                   goto label__string_loop_outer__continue;
32516                 } else if (v_backslash != 0) {
32517                   if (self->private_impl.f_quirks[WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_QUIRKS[(v_backslash & 7)]]) {
32518                     iop_a_src += 2;
32519                     *iop_a_dst++ = wuffs_base__make_token(
32520                         (((uint64_t)((6291456 | ((uint32_t)(WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_CHARS[(v_backslash & 7)]))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32521                         (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32522                         (((uint64_t)(2)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32523                     goto label__string_loop_outer__continue;
32524                   }
32525                 } else if (v_c == 117) {
32526                   if (((uint64_t)(io2_a_src - iop_a_src)) < 6) {
32527                     if (a_src && a_src->meta.closed) {
32528                       status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
32529                       goto exit;
32530                     }
32531                     status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32532                     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7);
32533                     v_string_length = 0;
32534                     v_char = 0;
32535                     goto label__string_loop_outer__continue;
32536                   }
32537                   v_uni4_string = (((uint64_t)(wuffs_base__peek_u48le__no_bounds_check(iop_a_src))) >> 16);
32538                   v_uni4_value = 0;
32539                   v_uni4_ok = 128;
32540                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni4_string >> 0))];
32541                   v_uni4_ok &= v_c;
32542                   v_uni4_value |= (((uint32_t)((v_c & 15))) << 12);
32543                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni4_string >> 8))];
32544                   v_uni4_ok &= v_c;
32545                   v_uni4_value |= (((uint32_t)((v_c & 15))) << 8);
32546                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni4_string >> 16))];
32547                   v_uni4_ok &= v_c;
32548                   v_uni4_value |= (((uint32_t)((v_c & 15))) << 4);
32549                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni4_string >> 24))];
32550                   v_uni4_ok &= v_c;
32551                   v_uni4_value |= (((uint32_t)((v_c & 15))) << 0);
32552                   if (v_uni4_ok == 0) {
32553                   } else if ((v_uni4_value < 55296) || (57343 < v_uni4_value)) {
32554                     iop_a_src += 6;
32555                     *iop_a_dst++ = wuffs_base__make_token(
32556                         (((uint64_t)((6291456 | v_uni4_value))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32557                         (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32558                         (((uint64_t)(6)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32559                     goto label__string_loop_outer__continue;
32560                   } else if (v_uni4_value >= 56320) {
32561                   } else {
32562                     if (((uint64_t)(io2_a_src - iop_a_src)) < 12) {
32563                       if (a_src && a_src->meta.closed) {
32564                         if (self->private_impl.f_quirks[20]) {
32565                           iop_a_src += 6;
32566                           *iop_a_dst++ = wuffs_base__make_token(
32567                               (((uint64_t)(6356989)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32568                               (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32569                               (((uint64_t)(6)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32570                           goto label__string_loop_outer__continue;
32571                         }
32572                         status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
32573                         goto exit;
32574                       }
32575                       status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32576                       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8);
32577                       v_string_length = 0;
32578                       v_uni4_value = 0;
32579                       v_char = 0;
32580                       goto label__string_loop_outer__continue;
32581                     }
32582                     v_uni4_string = (wuffs_base__peek_u64le__no_bounds_check(iop_a_src + 4) >> 16);
32583                     if (((255 & (v_uni4_string >> 0)) != 92) || ((255 & (v_uni4_string >> 8)) != 117)) {
32584                       v_uni4_high_surrogate = 0;
32585                       v_uni4_value = 0;
32586                       v_uni4_ok = 0;
32587                     } else {
32588                       v_uni4_high_surrogate = (65536 + ((v_uni4_value - 55296) << 10));
32589                       v_uni4_value = 0;
32590                       v_uni4_ok = 128;
32591                       v_uni4_string >>= 16;
32592                       v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni4_string >> 0))];
32593                       v_uni4_ok &= v_c;
32594                       v_uni4_value |= (((uint32_t)((v_c & 15))) << 12);
32595                       v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni4_string >> 8))];
32596                       v_uni4_ok &= v_c;
32597                       v_uni4_value |= (((uint32_t)((v_c & 15))) << 8);
32598                       v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni4_string >> 16))];
32599                       v_uni4_ok &= v_c;
32600                       v_uni4_value |= (((uint32_t)((v_c & 15))) << 4);
32601                       v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni4_string >> 24))];
32602                       v_uni4_ok &= v_c;
32603                       v_uni4_value |= (((uint32_t)((v_c & 15))) << 0);
32604                     }
32605                     if ((v_uni4_ok != 0) && (56320 <= v_uni4_value) && (v_uni4_value <= 57343)) {
32606                       v_uni4_value -= 56320;
32607                       iop_a_src += 12;
32608                       *iop_a_dst++ = wuffs_base__make_token(
32609                           (((uint64_t)((6291456 | v_uni4_high_surrogate | v_uni4_value))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32610                           (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32611                           (((uint64_t)(12)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32612                       goto label__string_loop_outer__continue;
32613                     }
32614                   }
32615                   if (self->private_impl.f_quirks[20]) {
32616                     if (((uint64_t)(io2_a_src - iop_a_src)) < 6) {
32617                       status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o);
32618                       goto exit;
32619                     }
32620                     iop_a_src += 6;
32621                     *iop_a_dst++ = wuffs_base__make_token(
32622                         (((uint64_t)(6356989)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32623                         (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32624                         (((uint64_t)(6)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32625                     goto label__string_loop_outer__continue;
32626                   }
32627                 } else if ((v_c == 85) && self->private_impl.f_quirks[2]) {
32628                   if (((uint64_t)(io2_a_src - iop_a_src)) < 10) {
32629                     if (a_src && a_src->meta.closed) {
32630                       status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
32631                       goto exit;
32632                     }
32633                     status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32634                     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9);
32635                     v_string_length = 0;
32636                     v_char = 0;
32637                     goto label__string_loop_outer__continue;
32638                   }
32639                   v_uni8_string = wuffs_base__peek_u64le__no_bounds_check(iop_a_src + 2);
32640                   v_uni8_value = 0;
32641                   v_uni8_ok = 128;
32642                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni8_string >> 0))];
32643                   v_uni8_ok &= v_c;
32644                   v_uni8_value |= (((uint32_t)((v_c & 15))) << 28);
32645                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni8_string >> 8))];
32646                   v_uni8_ok &= v_c;
32647                   v_uni8_value |= (((uint32_t)((v_c & 15))) << 24);
32648                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni8_string >> 16))];
32649                   v_uni8_ok &= v_c;
32650                   v_uni8_value |= (((uint32_t)((v_c & 15))) << 20);
32651                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni8_string >> 24))];
32652                   v_uni8_ok &= v_c;
32653                   v_uni8_value |= (((uint32_t)((v_c & 15))) << 16);
32654                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni8_string >> 32))];
32655                   v_uni8_ok &= v_c;
32656                   v_uni8_value |= (((uint32_t)((v_c & 15))) << 12);
32657                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni8_string >> 40))];
32658                   v_uni8_ok &= v_c;
32659                   v_uni8_value |= (((uint32_t)((v_c & 15))) << 8);
32660                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni8_string >> 48))];
32661                   v_uni8_ok &= v_c;
32662                   v_uni8_value |= (((uint32_t)((v_c & 15))) << 4);
32663                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni8_string >> 56))];
32664                   v_uni8_ok &= v_c;
32665                   v_uni8_value |= (((uint32_t)((v_c & 15))) << 0);
32666                   if (v_uni8_ok == 0) {
32667                   } else if ((v_uni8_value < 55296) || ((57343 < v_uni8_value) && (v_uni8_value <= 1114111))) {
32668                     iop_a_src += 10;
32669                     *iop_a_dst++ = wuffs_base__make_token(
32670                         (((uint64_t)((6291456 | (v_uni8_value & 2097151)))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32671                         (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32672                         (((uint64_t)(10)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32673                     goto label__string_loop_outer__continue;
32674                   } else if (self->private_impl.f_quirks[20]) {
32675                     iop_a_src += 10;
32676                     *iop_a_dst++ = wuffs_base__make_token(
32677                         (((uint64_t)(6356989)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32678                         (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32679                         (((uint64_t)(10)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32680                     goto label__string_loop_outer__continue;
32681                   }
32682                 } else if ((v_c == 120) && self->private_impl.f_quirks[9]) {
32683                   if (((uint64_t)(io2_a_src - iop_a_src)) < 4) {
32684                     if (a_src && a_src->meta.closed) {
32685                       status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
32686                       goto exit;
32687                     }
32688                     status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32689                     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10);
32690                     v_string_length = 0;
32691                     v_char = 0;
32692                     goto label__string_loop_outer__continue;
32693                   }
32694                   v_backslash_x_string = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
32695                   v_backslash_x_ok = 128;
32696                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_backslash_x_string >> 16))];
32697                   v_backslash_x_ok &= v_c;
32698                   v_backslash_x_value = ((uint8_t)(((v_c & 15) << 4)));
32699                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_backslash_x_string >> 24))];
32700                   v_backslash_x_ok &= v_c;
32701                   v_backslash_x_value = ((uint8_t)((v_backslash_x_value | (v_c & 15))));
32702                   if ((v_backslash_x_ok == 0) || ((v_backslash_x_string & 65535) != 30812)) {
32703                     status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
32704                     goto exit;
32705                   }
32706                   iop_a_src += 4;
32707                   *iop_a_dst++ = wuffs_base__make_token(
32708                       (((uint64_t)((6291456 | ((uint32_t)(v_backslash_x_value))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32709                       (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32710                       (((uint64_t)(4)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32711                   goto label__string_loop_outer__continue;
32712                 }
32713                 status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
32714                 goto exit;
32715               } else if (v_char == 3) {
32716                 if (((uint64_t)(io2_a_src - iop_a_src)) < 2) {
32717                   if (v_string_length > 0) {
32718                     *iop_a_dst++ = wuffs_base__make_token(
32719                         (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32720                         (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32721                         (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32722                     v_string_length = 0;
32723                     if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
32724                       goto label__string_loop_outer__continue;
32725                     }
32726                   }
32727                   if (a_src && a_src->meta.closed) {
32728                     if (self->private_impl.f_quirks[20]) {
32729                       *iop_a_dst++ = wuffs_base__make_token(
32730                           (((uint64_t)(6356989)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32731                           (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32732                           (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32733                       iop_a_src += 1;
32734                       goto label__string_loop_outer__continue;
32735                     }
32736                     status = wuffs_base__make_status(wuffs_json__error__bad_utf_8);
32737                     goto exit;
32738                   }
32739                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32740                   WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(11);
32741                   v_string_length = 0;
32742                   v_char = 0;
32743                   goto label__string_loop_outer__continue;
32744                 }
32745                 v_multi_byte_utf8 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
32746                 if ((v_multi_byte_utf8 & 49152) == 32768) {
32747                   v_multi_byte_utf8 = ((1984 & ((uint32_t)(v_multi_byte_utf8 << 6))) | (63 & (v_multi_byte_utf8 >> 8)));
32748                   iop_a_src += 2;
32749                   if (v_string_length >= 65528) {
32750                     *iop_a_dst++ = wuffs_base__make_token(
32751                         (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32752                         (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32753                         (((uint64_t)((v_string_length + 2))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32754                     v_string_length = 0;
32755                     goto label__string_loop_outer__continue;
32756                   }
32757                   v_string_length += 2;
32758                   goto label__string_loop_inner__continue;
32759                 }
32760               } else if (v_char == 4) {
32761                 if (((uint64_t)(io2_a_src - iop_a_src)) < 3) {
32762                   if (v_string_length > 0) {
32763                     *iop_a_dst++ = wuffs_base__make_token(
32764                         (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32765                         (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32766                         (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32767                     v_string_length = 0;
32768                     if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
32769                       goto label__string_loop_outer__continue;
32770                     }
32771                   }
32772                   if (a_src && a_src->meta.closed) {
32773                     if (self->private_impl.f_quirks[20]) {
32774                       *iop_a_dst++ = wuffs_base__make_token(
32775                           (((uint64_t)(6356989)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32776                           (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32777                           (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32778                       iop_a_src += 1;
32779                       goto label__string_loop_outer__continue;
32780                     }
32781                     status = wuffs_base__make_status(wuffs_json__error__bad_utf_8);
32782                     goto exit;
32783                   }
32784                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32785                   WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(12);
32786                   v_string_length = 0;
32787                   v_char = 0;
32788                   goto label__string_loop_outer__continue;
32789                 }
32790                 v_multi_byte_utf8 = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src)));
32791                 if ((v_multi_byte_utf8 & 12632064) == 8421376) {
32792                   v_multi_byte_utf8 = ((61440 & ((uint32_t)(v_multi_byte_utf8 << 12))) | (4032 & (v_multi_byte_utf8 >> 2)) | (63 & (v_multi_byte_utf8 >> 16)));
32793                   if ((2047 < v_multi_byte_utf8) && ((v_multi_byte_utf8 < 55296) || (57343 < v_multi_byte_utf8))) {
32794                     iop_a_src += 3;
32795                     if (v_string_length >= 65528) {
32796                       *iop_a_dst++ = wuffs_base__make_token(
32797                           (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32798                           (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32799                           (((uint64_t)((v_string_length + 3))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32800                       v_string_length = 0;
32801                       goto label__string_loop_outer__continue;
32802                     }
32803                     v_string_length += 3;
32804                     goto label__string_loop_inner__continue;
32805                   }
32806                 }
32807               } else if (v_char == 5) {
32808                 if (((uint64_t)(io2_a_src - iop_a_src)) < 4) {
32809                   if (v_string_length > 0) {
32810                     *iop_a_dst++ = wuffs_base__make_token(
32811                         (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32812                         (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32813                         (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32814                     v_string_length = 0;
32815                     if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
32816                       goto label__string_loop_outer__continue;
32817                     }
32818                   }
32819                   if (a_src && a_src->meta.closed) {
32820                     if (self->private_impl.f_quirks[20]) {
32821                       *iop_a_dst++ = wuffs_base__make_token(
32822                           (((uint64_t)(6356989)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32823                           (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32824                           (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32825                       iop_a_src += 1;
32826                       goto label__string_loop_outer__continue;
32827                     }
32828                     status = wuffs_base__make_status(wuffs_json__error__bad_utf_8);
32829                     goto exit;
32830                   }
32831                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32832                   WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(13);
32833                   v_string_length = 0;
32834                   v_char = 0;
32835                   goto label__string_loop_outer__continue;
32836                 }
32837                 v_multi_byte_utf8 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
32838                 if ((v_multi_byte_utf8 & 3233857536) == 2155905024) {
32839                   v_multi_byte_utf8 = ((1835008 & ((uint32_t)(v_multi_byte_utf8 << 18))) |
32840                       (258048 & ((uint32_t)(v_multi_byte_utf8 << 4))) |
32841                       (4032 & (v_multi_byte_utf8 >> 10)) |
32842                       (63 & (v_multi_byte_utf8 >> 24)));
32843                   if ((65535 < v_multi_byte_utf8) && (v_multi_byte_utf8 <= 1114111)) {
32844                     iop_a_src += 4;
32845                     if (v_string_length >= 65528) {
32846                       *iop_a_dst++ = wuffs_base__make_token(
32847                           (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32848                           (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32849                           (((uint64_t)((v_string_length + 4))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32850                       v_string_length = 0;
32851                       goto label__string_loop_outer__continue;
32852                     }
32853                     v_string_length += 4;
32854                     goto label__string_loop_inner__continue;
32855                   }
32856                 }
32857               }
32858               if (v_string_length > 0) {
32859                 *iop_a_dst++ = wuffs_base__make_token(
32860                     (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32861                     (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32862                     (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32863                 v_string_length = 0;
32864                 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
32865                   goto label__string_loop_outer__continue;
32866                 }
32867               }
32868               if ((v_char & 128) != 0) {
32869                 if (self->private_impl.f_quirks[0]) {
32870                   *iop_a_dst++ = wuffs_base__make_token(
32871                       (((uint64_t)((6291456 | ((uint32_t)((v_char & 127)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32872                       (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32873                       (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32874                   iop_a_src += 1;
32875                   goto label__string_loop_outer__continue;
32876                 }
32877                 if (v_char == 138) {
32878                   status = wuffs_base__make_status(wuffs_json__error__bad_new_line_in_a_string);
32879                   goto exit;
32880                 }
32881                 status = wuffs_base__make_status(wuffs_json__error__bad_c0_control_code);
32882                 goto exit;
32883               }
32884               if (self->private_impl.f_quirks[20]) {
32885                 *iop_a_dst++ = wuffs_base__make_token(
32886                     (((uint64_t)(6356989)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32887                     (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32888                     (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32889                 iop_a_src += 1;
32890                 goto label__string_loop_outer__continue;
32891               }
32892               status = wuffs_base__make_status(wuffs_json__error__bad_utf_8);
32893               goto exit;
32894             }
32895           }
32896           label__string_loop_outer__break:;
32897           label__1__continue:;
32898           while (true) {
32899             if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
32900               if (a_src && a_src->meta.closed) {
32901                 status = wuffs_base__make_status(wuffs_json__error__bad_input);
32902                 goto exit;
32903               }
32904               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32905               WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(14);
32906               goto label__1__continue;
32907             }
32908             if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
32909               status = wuffs_base__make_status(wuffs_base__suspension__short_write);
32910               WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(15);
32911               goto label__1__continue;
32912             }
32913             iop_a_src += 1;
32914             *iop_a_dst++ = wuffs_base__make_token(
32915                 (((uint64_t)(4194579)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32916                 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32917             goto label__1__break;
32918           }
32919           label__1__break:;
32920           if (0 == (v_expect & (((uint32_t)(1)) << 4))) {
32921             v_expect = 4104;
32922             goto label__outer__continue;
32923           }
32924           goto label__goto_parsed_a_leaf_value__break;
32925         } else if (v_class == 2) {
32926           iop_a_src += 1;
32927           *iop_a_dst++ = wuffs_base__make_token(
32928               (((uint64_t)(1)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32929               (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32930           if (0 == (v_expect & (((uint32_t)(1)) << 8))) {
32931             if (self->private_impl.f_quirks[13]) {
32932               v_expect = 4162;
32933             } else {
32934               v_expect = 4098;
32935             }
32936           } else {
32937             if (self->private_impl.f_quirks[13]) {
32938               v_expect = 8114;
32939             } else {
32940               v_expect = 7858;
32941             }
32942           }
32943           goto label__outer__continue;
32944         } else if (v_class == 3) {
32945           iop_a_src += 1;
32946           *iop_a_dst++ = wuffs_base__make_token(
32947               (((uint64_t)(1)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32948               (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32949           v_expect = 7858;
32950           goto label__outer__continue;
32951         } else if (v_class == 4) {
32952           while (true) {
32953             if (a_src) {
32954               a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
32955             }
32956             v_number_length = wuffs_json__decoder__decode_number(self, a_src);
32957             if (a_src) {
32958               iop_a_src = a_src->data.ptr + a_src->meta.ri;
32959             }
32960             v_number_status = (v_number_length >> 8);
32961             v_vminor = 10486787;
32962             if ((v_number_length & 128) != 0) {
32963               v_vminor = 10486785;
32964             }
32965             v_number_length = (v_number_length & 127);
32966             if (v_number_status == 0) {
32967               *iop_a_dst++ = wuffs_base__make_token(
32968                   (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32969                   (((uint64_t)(v_number_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32970               goto label__2__break;
32971             }
32972             while (v_number_length > 0) {
32973               v_number_length -= 1;
32974               if (iop_a_src > io1_a_src) {
32975                 iop_a_src--;
32976               } else {
32977                 status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o);
32978                 goto exit;
32979               }
32980             }
32981             if (v_number_status == 1) {
32982               if (self->private_impl.f_quirks[14]) {
32983                 if (a_dst) {
32984                   a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
32985                 }
32986                 if (a_src) {
32987                   a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
32988                 }
32989                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
32990                 status = wuffs_json__decoder__decode_inf_nan(self, a_dst, a_src);
32991                 if (a_dst) {
32992                   iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
32993                 }
32994                 if (a_src) {
32995                   iop_a_src = a_src->data.ptr + a_src->meta.ri;
32996                 }
32997                 if (status.repr) {
32998                   goto suspend;
32999                 }
33000                 goto label__2__break;
33001               }
33002               status = wuffs_base__make_status(wuffs_json__error__bad_input);
33003               goto exit;
33004             } else if (v_number_status == 2) {
33005               status = wuffs_base__make_status(wuffs_json__error__unsupported_number_length);
33006               goto exit;
33007             } else {
33008               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33009               WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(17);
33010               while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
33011                 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
33012                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(18);
33013               }
33014             }
33015           }
33016           label__2__break:;
33017           goto label__goto_parsed_a_leaf_value__break;
33018         } else if (v_class == 5) {
33019           v_vminor = 2113553;
33020           if (v_depth == 0) {
33021           } else if (0 != (v_expect_after_value & (((uint32_t)(1)) << 6))) {
33022             v_vminor = 2113601;
33023           } else {
33024             v_vminor = 2113569;
33025           }
33026           if (v_depth >= 1024) {
33027             status = wuffs_base__make_status(wuffs_json__error__unsupported_recursion_depth);
33028             goto exit;
33029           }
33030           v_stack_byte = (v_depth / 32);
33031           v_stack_bit = (v_depth & 31);
33032           self->private_data.f_stack[v_stack_byte] |= (((uint32_t)(1)) << v_stack_bit);
33033           v_depth += 1;
33034           iop_a_src += 1;
33035           *iop_a_dst++ = wuffs_base__make_token(
33036               (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33037               (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33038           v_expect = 4162;
33039           v_expect_after_value = 4164;
33040           goto label__outer__continue;
33041         } else if (v_class == 6) {
33042           iop_a_src += 1;
33043           if (v_depth <= 1) {
33044             *iop_a_dst++ = wuffs_base__make_token(
33045                 (((uint64_t)(2101314)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33046                 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33047             goto label__outer__break;
33048           }
33049           v_depth -= 1;
33050           v_stack_byte = ((v_depth - 1) / 32);
33051           v_stack_bit = ((v_depth - 1) & 31);
33052           if (0 == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1)) << v_stack_bit))) {
33053             *iop_a_dst++ = wuffs_base__make_token(
33054                 (((uint64_t)(2105410)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33055                 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33056             v_expect = 4356;
33057             v_expect_after_value = 4356;
33058           } else {
33059             *iop_a_dst++ = wuffs_base__make_token(
33060                 (((uint64_t)(2113602)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33061                 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33062             v_expect = 4164;
33063             v_expect_after_value = 4164;
33064           }
33065           goto label__outer__continue;
33066         } else if (v_class == 7) {
33067           v_vminor = 2105361;
33068           if (v_depth == 0) {
33069           } else if (0 != (v_expect_after_value & (((uint32_t)(1)) << 6))) {
33070             v_vminor = 2105409;
33071           } else {
33072             v_vminor = 2105377;
33073           }
33074           if (v_depth >= 1024) {
33075             status = wuffs_base__make_status(wuffs_json__error__unsupported_recursion_depth);
33076             goto exit;
33077           }
33078           v_stack_byte = (v_depth / 32);
33079           v_stack_bit = (v_depth & 31);
33080           self->private_data.f_stack[v_stack_byte] &= (4294967295 ^ (((uint32_t)(1)) << v_stack_bit));
33081           v_depth += 1;
33082           iop_a_src += 1;
33083           *iop_a_dst++ = wuffs_base__make_token(
33084               (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33085               (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33086           v_expect = 8114;
33087           v_expect_after_value = 4356;
33088           goto label__outer__continue;
33089         } else if (v_class == 8) {
33090           iop_a_src += 1;
33091           if (v_depth <= 1) {
33092             *iop_a_dst++ = wuffs_base__make_token(
33093                 (((uint64_t)(2101282)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33094                 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33095             goto label__outer__break;
33096           }
33097           v_depth -= 1;
33098           v_stack_byte = ((v_depth - 1) / 32);
33099           v_stack_bit = ((v_depth - 1) & 31);
33100           if (0 == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1)) << v_stack_bit))) {
33101             *iop_a_dst++ = wuffs_base__make_token(
33102                 (((uint64_t)(2105378)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33103                 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33104             v_expect = 4356;
33105             v_expect_after_value = 4356;
33106           } else {
33107             *iop_a_dst++ = wuffs_base__make_token(
33108                 (((uint64_t)(2113570)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33109                 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33110             v_expect = 4164;
33111             v_expect_after_value = 4164;
33112           }
33113           goto label__outer__continue;
33114         } else if (v_class == 9) {
33115           v_match = wuffs_base__io_reader__match7(iop_a_src, io2_a_src, a_src,111546413966853);
33116           if (v_match == 0) {
33117             *iop_a_dst++ = wuffs_base__make_token(
33118                 (((uint64_t)(8388612)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33119                 (((uint64_t)(5)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33120             if (((uint64_t)(io2_a_src - iop_a_src)) < 5) {
33121               status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o);
33122               goto exit;
33123             }
33124             iop_a_src += 5;
33125             goto label__goto_parsed_a_leaf_value__break;
33126           } else if (v_match == 1) {
33127             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33128             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(19);
33129             goto label__outer__continue;
33130           }
33131         } else if (v_class == 10) {
33132           v_match = wuffs_base__io_reader__match7(iop_a_src, io2_a_src, a_src,435762131972);
33133           if (v_match == 0) {
33134             *iop_a_dst++ = wuffs_base__make_token(
33135                 (((uint64_t)(8388616)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33136                 (((uint64_t)(4)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33137             if (((uint64_t)(io2_a_src - iop_a_src)) < 4) {
33138               status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o);
33139               goto exit;
33140             }
33141             iop_a_src += 4;
33142             goto label__goto_parsed_a_leaf_value__break;
33143           } else if (v_match == 1) {
33144             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33145             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(20);
33146             goto label__outer__continue;
33147           }
33148         } else if (v_class == 11) {
33149           v_match = wuffs_base__io_reader__match7(iop_a_src, io2_a_src, a_src,465676103172);
33150           if (v_match == 0) {
33151             *iop_a_dst++ = wuffs_base__make_token(
33152                 (((uint64_t)(8388610)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33153                 (((uint64_t)(4)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33154             if (((uint64_t)(io2_a_src - iop_a_src)) < 4) {
33155               status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o);
33156               goto exit;
33157             }
33158             iop_a_src += 4;
33159             goto label__goto_parsed_a_leaf_value__break;
33160           } else if (v_match == 1) {
33161             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33162             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(21);
33163             goto label__outer__continue;
33164           }
33165           if (self->private_impl.f_quirks[14]) {
33166             if (a_dst) {
33167               a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
33168             }
33169             if (a_src) {
33170               a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33171             }
33172             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(22);
33173             status = wuffs_json__decoder__decode_inf_nan(self, a_dst, a_src);
33174             if (a_dst) {
33175               iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
33176             }
33177             if (a_src) {
33178               iop_a_src = a_src->data.ptr + a_src->meta.ri;
33179             }
33180             if (status.repr) {
33181               goto suspend;
33182             }
33183             goto label__goto_parsed_a_leaf_value__break;
33184           }
33185         } else if (v_class == 12) {
33186           if (self->private_impl.f_quirks[11] || self->private_impl.f_quirks[12]) {
33187             if (a_dst) {
33188               a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
33189             }
33190             if (a_src) {
33191               a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33192             }
33193             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(23);
33194             status = wuffs_json__decoder__decode_comment(self, a_dst, a_src);
33195             if (a_dst) {
33196               iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
33197             }
33198             if (a_src) {
33199               iop_a_src = a_src->data.ptr + a_src->meta.ri;
33200             }
33201             if (status.repr) {
33202               goto suspend;
33203             }
33204             if (self->private_impl.f_comment_type > 0) {
33205               goto label__outer__continue;
33206             }
33207           }
33208         }
33209         status = wuffs_base__make_status(wuffs_json__error__bad_input);
33210         goto exit;
33211       }
33212       label__goto_parsed_a_leaf_value__break:;
33213       if (v_depth == 0) {
33214         goto label__outer__break;
33215       }
33216       v_expect = v_expect_after_value;
33217     }
33218     label__outer__break:;
33219     if (self->private_impl.f_quirks[17] || self->private_impl.f_quirks[18]) {
33220       if (a_dst) {
33221         a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
33222       }
33223       if (a_src) {
33224         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33225       }
33226       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(24);
33227       status = wuffs_json__decoder__decode_trailer(self, a_dst, a_src);
33228       if (a_dst) {
33229         iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
33230       }
33231       if (a_src) {
33232         iop_a_src = a_src->data.ptr + a_src->meta.ri;
33233       }
33234       if (status.repr) {
33235         goto suspend;
33236       }
33237     }
33238     self->private_impl.f_end_of_data = true;
33239 
33240     ok:
33241     self->private_impl.p_decode_tokens[0] = 0;
33242     goto exit;
33243   }
33244 
33245   goto suspend;
33246   suspend:
33247   self->private_impl.p_decode_tokens[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
33248   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
33249   self->private_data.s_decode_tokens[0].v_depth = v_depth;
33250   self->private_data.s_decode_tokens[0].v_expect = v_expect;
33251   self->private_data.s_decode_tokens[0].v_expect_after_value = v_expect_after_value;
33252 
33253   goto exit;
33254   exit:
33255   if (a_dst) {
33256     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
33257   }
33258   if (a_src) {
33259     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33260   }
33261 
33262   if (wuffs_base__status__is_error(&status)) {
33263     self->private_impl.magic = WUFFS_BASE__DISABLED;
33264   }
33265   return status;
33266 }
33267 
33268 // -------- func json.decoder.decode_number
33269 
33270 static uint32_t
wuffs_json__decoder__decode_number(wuffs_json__decoder * self,wuffs_base__io_buffer * a_src)33271 wuffs_json__decoder__decode_number(
33272     wuffs_json__decoder* self,
33273     wuffs_base__io_buffer* a_src) {
33274   uint8_t v_c = 0;
33275   uint32_t v_n = 0;
33276   uint32_t v_floating_point = 0;
33277 
33278   const uint8_t* iop_a_src = NULL;
33279   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33280   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33281   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33282   if (a_src) {
33283     io0_a_src = a_src->data.ptr;
33284     io1_a_src = io0_a_src + a_src->meta.ri;
33285     iop_a_src = io1_a_src;
33286     io2_a_src = io0_a_src + a_src->meta.wi;
33287   }
33288 
33289   while (true) {
33290     v_n = 0;
33291     if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
33292       if ( ! (a_src && a_src->meta.closed)) {
33293         v_n |= 768;
33294       }
33295       goto label__goto_done__break;
33296     }
33297     v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
33298     if (v_c != 45) {
33299     } else {
33300       v_n += 1;
33301       iop_a_src += 1;
33302       if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
33303         if ( ! (a_src && a_src->meta.closed)) {
33304           v_n |= 768;
33305         }
33306         v_n |= 256;
33307         goto label__goto_done__break;
33308       }
33309       v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
33310     }
33311     if (v_c == 48) {
33312       v_n += 1;
33313       iop_a_src += 1;
33314     } else {
33315       if (a_src) {
33316         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33317       }
33318       v_n = wuffs_json__decoder__decode_digits(self, a_src, v_n);
33319       if (a_src) {
33320         iop_a_src = a_src->data.ptr + a_src->meta.ri;
33321       }
33322       if (v_n > 99) {
33323         goto label__goto_done__break;
33324       }
33325     }
33326     if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
33327       if ( ! (a_src && a_src->meta.closed)) {
33328         v_n |= 768;
33329       }
33330       goto label__goto_done__break;
33331     }
33332     v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
33333     if (v_c != 46) {
33334     } else {
33335       if (v_n >= 99) {
33336         v_n |= 512;
33337         goto label__goto_done__break;
33338       }
33339       v_n += 1;
33340       iop_a_src += 1;
33341       v_floating_point = 128;
33342       if (a_src) {
33343         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33344       }
33345       v_n = wuffs_json__decoder__decode_digits(self, a_src, v_n);
33346       if (a_src) {
33347         iop_a_src = a_src->data.ptr + a_src->meta.ri;
33348       }
33349       if (v_n > 99) {
33350         goto label__goto_done__break;
33351       }
33352       if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
33353         if ( ! (a_src && a_src->meta.closed)) {
33354           v_n |= 768;
33355         }
33356         goto label__goto_done__break;
33357       }
33358       v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
33359     }
33360     if ((v_c != 69) && (v_c != 101)) {
33361       goto label__goto_done__break;
33362     }
33363     if (v_n >= 99) {
33364       v_n |= 512;
33365       goto label__goto_done__break;
33366     }
33367     v_n += 1;
33368     iop_a_src += 1;
33369     v_floating_point = 128;
33370     if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
33371       if ( ! (a_src && a_src->meta.closed)) {
33372         v_n |= 768;
33373       }
33374       v_n |= 256;
33375       goto label__goto_done__break;
33376     }
33377     v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
33378     if ((v_c != 43) && (v_c != 45)) {
33379     } else {
33380       if (v_n >= 99) {
33381         v_n |= 512;
33382         goto label__goto_done__break;
33383       }
33384       v_n += 1;
33385       iop_a_src += 1;
33386     }
33387     if (a_src) {
33388       a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33389     }
33390     v_n = wuffs_json__decoder__decode_digits(self, a_src, v_n);
33391     if (a_src) {
33392       iop_a_src = a_src->data.ptr + a_src->meta.ri;
33393     }
33394     goto label__goto_done__break;
33395   }
33396   label__goto_done__break:;
33397   if (a_src) {
33398     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33399   }
33400   return (v_n | v_floating_point);
33401 }
33402 
33403 // -------- func json.decoder.decode_digits
33404 
33405 static uint32_t
wuffs_json__decoder__decode_digits(wuffs_json__decoder * self,wuffs_base__io_buffer * a_src,uint32_t a_n)33406 wuffs_json__decoder__decode_digits(
33407     wuffs_json__decoder* self,
33408     wuffs_base__io_buffer* a_src,
33409     uint32_t a_n) {
33410   uint8_t v_c = 0;
33411   uint32_t v_n = 0;
33412 
33413   const uint8_t* iop_a_src = NULL;
33414   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33415   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33416   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33417   if (a_src) {
33418     io0_a_src = a_src->data.ptr;
33419     io1_a_src = io0_a_src + a_src->meta.ri;
33420     iop_a_src = io1_a_src;
33421     io2_a_src = io0_a_src + a_src->meta.wi;
33422   }
33423 
33424   v_n = a_n;
33425   while (true) {
33426     if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
33427       if ( ! (a_src && a_src->meta.closed)) {
33428         v_n |= 768;
33429       }
33430       goto label__0__break;
33431     }
33432     v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
33433     if (0 == WUFFS_JSON__LUT_DECIMAL_DIGITS[v_c]) {
33434       goto label__0__break;
33435     }
33436     if (v_n >= 99) {
33437       v_n |= 512;
33438       goto label__0__break;
33439     }
33440     v_n += 1;
33441     iop_a_src += 1;
33442   }
33443   label__0__break:;
33444   if (v_n == a_n) {
33445     v_n |= 256;
33446   }
33447   if (a_src) {
33448     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33449   }
33450   return v_n;
33451 }
33452 
33453 // -------- func json.decoder.decode_leading
33454 
33455 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)33456 wuffs_json__decoder__decode_leading(
33457     wuffs_json__decoder* self,
33458     wuffs_base__token_buffer* a_dst,
33459     wuffs_base__io_buffer* a_src) {
33460   wuffs_base__status status = wuffs_base__make_status(NULL);
33461 
33462   uint8_t v_c = 0;
33463   uint32_t v_u = 0;
33464 
33465   wuffs_base__token* iop_a_dst = NULL;
33466   wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33467   wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33468   wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33469   if (a_dst) {
33470     io0_a_dst = a_dst->data.ptr;
33471     io1_a_dst = io0_a_dst + a_dst->meta.wi;
33472     iop_a_dst = io1_a_dst;
33473     io2_a_dst = io0_a_dst + a_dst->data.len;
33474     if (a_dst->meta.closed) {
33475       io2_a_dst = iop_a_dst;
33476     }
33477   }
33478   const uint8_t* iop_a_src = NULL;
33479   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33480   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33481   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33482   if (a_src) {
33483     io0_a_src = a_src->data.ptr;
33484     io1_a_src = io0_a_src + a_src->meta.ri;
33485     iop_a_src = io1_a_src;
33486     io2_a_src = io0_a_src + a_src->meta.wi;
33487   }
33488 
33489   uint32_t coro_susp_point = self->private_impl.p_decode_leading[0];
33490   switch (coro_susp_point) {
33491     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
33492 
33493     self->private_impl.f_allow_leading_ars = self->private_impl.f_quirks[15];
33494     self->private_impl.f_allow_leading_ubom = self->private_impl.f_quirks[16];
33495     label__0__continue:;
33496     while (self->private_impl.f_allow_leading_ars || self->private_impl.f_allow_leading_ubom) {
33497       if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
33498         status = wuffs_base__make_status(wuffs_base__suspension__short_write);
33499         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
33500         goto label__0__continue;
33501       }
33502       if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
33503         if (a_src && a_src->meta.closed) {
33504           goto label__0__break;
33505         }
33506         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33507         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
33508         goto label__0__continue;
33509       }
33510       v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
33511       if ((v_c == 30) && self->private_impl.f_allow_leading_ars) {
33512         self->private_impl.f_allow_leading_ars = false;
33513         iop_a_src += 1;
33514         *iop_a_dst++ = wuffs_base__make_token(
33515             (((uint64_t)(0)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33516             (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33517         goto label__0__continue;
33518       } else if ((v_c == 239) && self->private_impl.f_allow_leading_ubom) {
33519         if (((uint64_t)(io2_a_src - iop_a_src)) < 3) {
33520           if (a_src && a_src->meta.closed) {
33521             goto label__0__break;
33522           }
33523           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33524           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
33525           goto label__0__continue;
33526         }
33527         v_u = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src)));
33528         if (v_u == 12565487) {
33529           self->private_impl.f_allow_leading_ubom = false;
33530           iop_a_src += 3;
33531           *iop_a_dst++ = wuffs_base__make_token(
33532               (((uint64_t)(0)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33533               (((uint64_t)(3)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33534           goto label__0__continue;
33535         }
33536       }
33537       goto label__0__break;
33538     }
33539     label__0__break:;
33540 
33541     ok:
33542     self->private_impl.p_decode_leading[0] = 0;
33543     goto exit;
33544   }
33545 
33546   goto suspend;
33547   suspend:
33548   self->private_impl.p_decode_leading[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
33549 
33550   goto exit;
33551   exit:
33552   if (a_dst) {
33553     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
33554   }
33555   if (a_src) {
33556     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33557   }
33558 
33559   return status;
33560 }
33561 
33562 // -------- func json.decoder.decode_comment
33563 
33564 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)33565 wuffs_json__decoder__decode_comment(
33566     wuffs_json__decoder* self,
33567     wuffs_base__token_buffer* a_dst,
33568     wuffs_base__io_buffer* a_src) {
33569   wuffs_base__status status = wuffs_base__make_status(NULL);
33570 
33571   uint8_t v_c = 0;
33572   uint16_t v_c2 = 0;
33573   uint32_t v_length = 0;
33574 
33575   wuffs_base__token* iop_a_dst = NULL;
33576   wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33577   wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33578   wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33579   if (a_dst) {
33580     io0_a_dst = a_dst->data.ptr;
33581     io1_a_dst = io0_a_dst + a_dst->meta.wi;
33582     iop_a_dst = io1_a_dst;
33583     io2_a_dst = io0_a_dst + a_dst->data.len;
33584     if (a_dst->meta.closed) {
33585       io2_a_dst = iop_a_dst;
33586     }
33587   }
33588   const uint8_t* iop_a_src = NULL;
33589   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33590   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33591   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33592   if (a_src) {
33593     io0_a_src = a_src->data.ptr;
33594     io1_a_src = io0_a_src + a_src->meta.ri;
33595     iop_a_src = io1_a_src;
33596     io2_a_src = io0_a_src + a_src->meta.wi;
33597   }
33598 
33599   uint32_t coro_susp_point = self->private_impl.p_decode_comment[0];
33600   switch (coro_susp_point) {
33601     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
33602 
33603     self->private_impl.f_comment_type = 0;
33604     label__0__continue:;
33605     while ((((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) || (((uint64_t)(io2_a_src - iop_a_src)) <= 1)) {
33606       if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
33607         status = wuffs_base__make_status(wuffs_base__suspension__short_write);
33608         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
33609         goto label__0__continue;
33610       }
33611       if (a_src && a_src->meta.closed) {
33612         status = wuffs_base__make_status(NULL);
33613         goto ok;
33614       }
33615       status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33616       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
33617     }
33618     v_c2 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src);
33619     if ((v_c2 == 10799) && self->private_impl.f_quirks[11]) {
33620       iop_a_src += 2;
33621       v_length = 2;
33622       label__comment_block__continue:;
33623       while (true) {
33624         if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
33625           status = wuffs_base__make_status(wuffs_base__suspension__short_write);
33626           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
33627           v_length = 0;
33628           goto label__comment_block__continue;
33629         }
33630         while (true) {
33631           if (((uint64_t)(io2_a_src - iop_a_src)) <= 1) {
33632             if (v_length > 0) {
33633               *iop_a_dst++ = wuffs_base__make_token(
33634                   (((uint64_t)(2)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33635                   (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33636                   (((uint64_t)(v_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33637             }
33638             if (a_src && a_src->meta.closed) {
33639               status = wuffs_base__make_status(wuffs_json__error__bad_input);
33640               goto exit;
33641             }
33642             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33643             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
33644             v_length = 0;
33645             goto label__comment_block__continue;
33646           }
33647           v_c2 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src);
33648           if (v_c2 == 12074) {
33649             iop_a_src += 2;
33650             *iop_a_dst++ = wuffs_base__make_token(
33651                 (((uint64_t)(2)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33652                 (((uint64_t)((v_length + 2))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33653             self->private_impl.f_comment_type = 1;
33654             status = wuffs_base__make_status(NULL);
33655             goto ok;
33656           }
33657           iop_a_src += 1;
33658           if (v_length >= 65533) {
33659             *iop_a_dst++ = wuffs_base__make_token(
33660                 (((uint64_t)(2)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33661                 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33662                 (((uint64_t)((v_length + 1))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33663             v_length = 0;
33664             goto label__comment_block__continue;
33665           }
33666           v_length += 1;
33667         }
33668       }
33669     } else if ((v_c2 == 12079) && self->private_impl.f_quirks[12]) {
33670       iop_a_src += 2;
33671       v_length = 2;
33672       label__comment_line__continue:;
33673       while (true) {
33674         if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
33675           status = wuffs_base__make_status(wuffs_base__suspension__short_write);
33676           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
33677           v_length = 0;
33678           goto label__comment_line__continue;
33679         }
33680         while (true) {
33681           if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
33682             if (a_src && a_src->meta.closed) {
33683               *iop_a_dst++ = wuffs_base__make_token(
33684                   (((uint64_t)(4)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33685                   (((uint64_t)(v_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33686               self->private_impl.f_comment_type = 2;
33687               status = wuffs_base__make_status(NULL);
33688               goto ok;
33689             } else if (v_length > 0) {
33690               *iop_a_dst++ = wuffs_base__make_token(
33691                   (((uint64_t)(4)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33692                   (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33693                   (((uint64_t)(v_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33694             }
33695             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33696             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
33697             v_length = 0;
33698             goto label__comment_line__continue;
33699           }
33700           v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
33701           if (v_c == 10) {
33702             *iop_a_dst++ = wuffs_base__make_token(
33703                 (((uint64_t)(4)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33704                 (((uint64_t)(v_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33705             self->private_impl.f_comment_type = 2;
33706             status = wuffs_base__make_status(NULL);
33707             goto ok;
33708           }
33709           iop_a_src += 1;
33710           if (v_length >= 65533) {
33711             *iop_a_dst++ = wuffs_base__make_token(
33712                 (((uint64_t)(4)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33713                 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33714                 (((uint64_t)((v_length + 1))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33715             v_length = 0;
33716             goto label__comment_line__continue;
33717           }
33718           v_length += 1;
33719         }
33720       }
33721     }
33722 
33723     ok:
33724     self->private_impl.p_decode_comment[0] = 0;
33725     goto exit;
33726   }
33727 
33728   goto suspend;
33729   suspend:
33730   self->private_impl.p_decode_comment[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
33731 
33732   goto exit;
33733   exit:
33734   if (a_dst) {
33735     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
33736   }
33737   if (a_src) {
33738     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33739   }
33740 
33741   return status;
33742 }
33743 
33744 // -------- func json.decoder.decode_inf_nan
33745 
33746 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)33747 wuffs_json__decoder__decode_inf_nan(
33748     wuffs_json__decoder* self,
33749     wuffs_base__token_buffer* a_dst,
33750     wuffs_base__io_buffer* a_src) {
33751   wuffs_base__status status = wuffs_base__make_status(NULL);
33752 
33753   uint32_t v_c4 = 0;
33754   uint32_t v_neg = 0;
33755 
33756   wuffs_base__token* iop_a_dst = NULL;
33757   wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33758   wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33759   wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33760   if (a_dst) {
33761     io0_a_dst = a_dst->data.ptr;
33762     io1_a_dst = io0_a_dst + a_dst->meta.wi;
33763     iop_a_dst = io1_a_dst;
33764     io2_a_dst = io0_a_dst + a_dst->data.len;
33765     if (a_dst->meta.closed) {
33766       io2_a_dst = iop_a_dst;
33767     }
33768   }
33769   const uint8_t* iop_a_src = NULL;
33770   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33771   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33772   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33773   if (a_src) {
33774     io0_a_src = a_src->data.ptr;
33775     io1_a_src = io0_a_src + a_src->meta.ri;
33776     iop_a_src = io1_a_src;
33777     io2_a_src = io0_a_src + a_src->meta.wi;
33778   }
33779 
33780   uint32_t coro_susp_point = self->private_impl.p_decode_inf_nan[0];
33781   if (coro_susp_point) {
33782     v_neg = self->private_data.s_decode_inf_nan[0].v_neg;
33783   }
33784   switch (coro_susp_point) {
33785     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
33786 
33787     label__0__continue:;
33788     while (true) {
33789       if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
33790         status = wuffs_base__make_status(wuffs_base__suspension__short_write);
33791         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
33792         goto label__0__continue;
33793       }
33794       if (((uint64_t)(io2_a_src - iop_a_src)) <= 2) {
33795         if (a_src && a_src->meta.closed) {
33796           status = wuffs_base__make_status(wuffs_json__error__bad_input);
33797           goto exit;
33798         }
33799         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33800         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
33801         goto label__0__continue;
33802       }
33803       v_c4 = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src)));
33804       if ((v_c4 | 2105376) == 6712937) {
33805         if (((uint64_t)(io2_a_src - iop_a_src)) > 7) {
33806           if ((wuffs_base__peek_u64le__no_bounds_check(iop_a_src) | 2314885530818453536) == 8751735898823356009) {
33807             *iop_a_dst++ = wuffs_base__make_token(
33808                 (((uint64_t)(10485792)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33809                 (((uint64_t)(8)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33810             iop_a_src += 8;
33811             status = wuffs_base__make_status(NULL);
33812             goto ok;
33813           }
33814         } else if ( ! (a_src && a_src->meta.closed)) {
33815           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33816           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
33817           goto label__0__continue;
33818         }
33819         *iop_a_dst++ = wuffs_base__make_token(
33820             (((uint64_t)(10485792)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33821             (((uint64_t)(3)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33822         iop_a_src += 3;
33823         status = wuffs_base__make_status(NULL);
33824         goto ok;
33825       } else if ((v_c4 | 2105376) == 7233902) {
33826         *iop_a_dst++ = wuffs_base__make_token(
33827             (((uint64_t)(10485888)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33828             (((uint64_t)(3)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33829         iop_a_src += 3;
33830         status = wuffs_base__make_status(NULL);
33831         goto ok;
33832       } else if ((v_c4 & 255) == 43) {
33833         v_neg = 0;
33834       } else if ((v_c4 & 255) == 45) {
33835         v_neg = 1;
33836       } else {
33837         status = wuffs_base__make_status(wuffs_json__error__bad_input);
33838         goto exit;
33839       }
33840       if (((uint64_t)(io2_a_src - iop_a_src)) <= 3) {
33841         if (a_src && a_src->meta.closed) {
33842           status = wuffs_base__make_status(wuffs_json__error__bad_input);
33843           goto exit;
33844         }
33845         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33846         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
33847         goto label__0__continue;
33848       }
33849       v_c4 = (wuffs_base__peek_u32le__no_bounds_check(iop_a_src) >> 8);
33850       if ((v_c4 | 2105376) == 6712937) {
33851         if (((uint64_t)(io2_a_src - iop_a_src)) > 8) {
33852           if ((wuffs_base__peek_u64le__no_bounds_check(iop_a_src + 1) | 2314885530818453536) == 8751735898823356009) {
33853             *iop_a_dst++ = wuffs_base__make_token(
33854                 (((uint64_t)((10485760 | (((uint32_t)(32)) >> v_neg)))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33855                 (((uint64_t)(9)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33856             iop_a_src += 9;
33857             status = wuffs_base__make_status(NULL);
33858             goto ok;
33859           }
33860         } else if ( ! (a_src && a_src->meta.closed)) {
33861           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33862           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
33863           goto label__0__continue;
33864         }
33865         *iop_a_dst++ = wuffs_base__make_token(
33866             (((uint64_t)((10485760 | (((uint32_t)(32)) >> v_neg)))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33867             (((uint64_t)(4)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33868         iop_a_src += 4;
33869         status = wuffs_base__make_status(NULL);
33870         goto ok;
33871       } else if ((v_c4 | 2105376) == 7233902) {
33872         *iop_a_dst++ = wuffs_base__make_token(
33873             (((uint64_t)((10485760 | (((uint32_t)(128)) >> v_neg)))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33874             (((uint64_t)(4)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33875         iop_a_src += 4;
33876         status = wuffs_base__make_status(NULL);
33877         goto ok;
33878       }
33879       status = wuffs_base__make_status(wuffs_json__error__bad_input);
33880       goto exit;
33881     }
33882 
33883     ok:
33884     self->private_impl.p_decode_inf_nan[0] = 0;
33885     goto exit;
33886   }
33887 
33888   goto suspend;
33889   suspend:
33890   self->private_impl.p_decode_inf_nan[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
33891   self->private_data.s_decode_inf_nan[0].v_neg = v_neg;
33892 
33893   goto exit;
33894   exit:
33895   if (a_dst) {
33896     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
33897   }
33898   if (a_src) {
33899     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33900   }
33901 
33902   return status;
33903 }
33904 
33905 // -------- func json.decoder.decode_trailer
33906 
33907 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)33908 wuffs_json__decoder__decode_trailer(
33909     wuffs_json__decoder* self,
33910     wuffs_base__token_buffer* a_dst,
33911     wuffs_base__io_buffer* a_src) {
33912   wuffs_base__status status = wuffs_base__make_status(NULL);
33913 
33914   uint8_t v_c = 0;
33915   uint32_t v_whitespace_length = 0;
33916 
33917   wuffs_base__token* iop_a_dst = NULL;
33918   wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33919   wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33920   wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33921   if (a_dst) {
33922     io0_a_dst = a_dst->data.ptr;
33923     io1_a_dst = io0_a_dst + a_dst->meta.wi;
33924     iop_a_dst = io1_a_dst;
33925     io2_a_dst = io0_a_dst + a_dst->data.len;
33926     if (a_dst->meta.closed) {
33927       io2_a_dst = iop_a_dst;
33928     }
33929   }
33930   const uint8_t* iop_a_src = NULL;
33931   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33932   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33933   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33934   if (a_src) {
33935     io0_a_src = a_src->data.ptr;
33936     io1_a_src = io0_a_src + a_src->meta.ri;
33937     iop_a_src = io1_a_src;
33938     io2_a_src = io0_a_src + a_src->meta.wi;
33939   }
33940 
33941   uint32_t coro_susp_point = self->private_impl.p_decode_trailer[0];
33942   switch (coro_susp_point) {
33943     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
33944 
33945     if (self->private_impl.f_quirks[18]) {
33946       self->private_impl.f_trailer_stop = 10;
33947     } else {
33948       self->private_impl.f_trailer_stop = 0;
33949     }
33950     label__outer__continue:;
33951     while (true) {
33952       if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
33953         status = wuffs_base__make_status(wuffs_base__suspension__short_write);
33954         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
33955         v_whitespace_length = 0;
33956         goto label__outer__continue;
33957       }
33958       while (true) {
33959         if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
33960           if (v_whitespace_length > 0) {
33961             *iop_a_dst++ = wuffs_base__make_token(
33962                 (((uint64_t)(0)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33963                 (((uint64_t)(v_whitespace_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33964             v_whitespace_length = 0;
33965           }
33966           if (a_src && a_src->meta.closed) {
33967             goto label__outer__break;
33968           }
33969           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33970           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
33971           v_whitespace_length = 0;
33972           goto label__outer__continue;
33973         }
33974         v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
33975         if (WUFFS_JSON__LUT_CLASSES[v_c] != 0) {
33976           if (v_whitespace_length > 0) {
33977             *iop_a_dst++ = wuffs_base__make_token(
33978                 (((uint64_t)(0)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33979                 (((uint64_t)(v_whitespace_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33980             v_whitespace_length = 0;
33981           }
33982           if (self->private_impl.f_trailer_stop > 0) {
33983             status = wuffs_base__make_status(wuffs_json__error__bad_input);
33984             goto exit;
33985           }
33986           if (a_dst) {
33987             a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
33988           }
33989           if (a_src) {
33990             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33991           }
33992           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
33993           status = wuffs_json__decoder__decode_comment(self, a_dst, a_src);
33994           if (a_dst) {
33995             iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
33996           }
33997           if (a_src) {
33998             iop_a_src = a_src->data.ptr + a_src->meta.ri;
33999           }
34000           if (status.repr) {
34001             goto suspend;
34002           }
34003           v_c = 0;
34004           v_whitespace_length = 0;
34005           if (self->private_impl.f_comment_type > 0) {
34006             goto label__outer__continue;
34007           }
34008           status = wuffs_base__make_status(NULL);
34009           goto ok;
34010         }
34011         iop_a_src += 1;
34012         if ((v_whitespace_length >= 65534) || (v_c == self->private_impl.f_trailer_stop)) {
34013           *iop_a_dst++ = wuffs_base__make_token(
34014               (((uint64_t)(0)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
34015               (((uint64_t)((v_whitespace_length + 1))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
34016           v_whitespace_length = 0;
34017           if (v_c == self->private_impl.f_trailer_stop) {
34018             status = wuffs_base__make_status(NULL);
34019             goto ok;
34020           }
34021           goto label__outer__continue;
34022         }
34023         v_whitespace_length += 1;
34024       }
34025     }
34026     label__outer__break:;
34027 
34028     ok:
34029     self->private_impl.p_decode_trailer[0] = 0;
34030     goto exit;
34031   }
34032 
34033   goto suspend;
34034   suspend:
34035   self->private_impl.p_decode_trailer[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
34036 
34037   goto exit;
34038   exit:
34039   if (a_dst) {
34040     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
34041   }
34042   if (a_src) {
34043     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
34044   }
34045 
34046   return status;
34047 }
34048 
34049 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JSON)
34050 
34051 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NIE)
34052 
34053 // ---------------- Status Codes Implementations
34054 
34055 const char wuffs_nie__error__bad_header[] = "#nie: bad header";
34056 const char wuffs_nie__error__unsupported_nie_file[] = "#nie: unsupported NIE file";
34057 const char wuffs_nie__note__internal_note_short_read[] = "@nie: internal note: short read";
34058 
34059 // ---------------- Private Consts
34060 
34061 // ---------------- Private Initializer Prototypes
34062 
34063 // ---------------- Private Function Prototypes
34064 
34065 static wuffs_base__status
34066 wuffs_nie__decoder__swizzle(
34067     wuffs_nie__decoder* self,
34068     wuffs_base__pixel_buffer* a_dst,
34069     wuffs_base__io_buffer* a_src);
34070 
34071 // ---------------- VTables
34072 
34073 const wuffs_base__image_decoder__func_ptrs
34074 wuffs_nie__decoder__func_ptrs_for__wuffs_base__image_decoder = {
34075   (wuffs_base__status(*)(void*,
34076       wuffs_base__pixel_buffer*,
34077       wuffs_base__io_buffer*,
34078       wuffs_base__pixel_blend,
34079       wuffs_base__slice_u8,
34080       wuffs_base__decode_frame_options*))(&wuffs_nie__decoder__decode_frame),
34081   (wuffs_base__status(*)(void*,
34082       wuffs_base__frame_config*,
34083       wuffs_base__io_buffer*))(&wuffs_nie__decoder__decode_frame_config),
34084   (wuffs_base__status(*)(void*,
34085       wuffs_base__image_config*,
34086       wuffs_base__io_buffer*))(&wuffs_nie__decoder__decode_image_config),
34087   (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_nie__decoder__frame_dirty_rect),
34088   (uint32_t(*)(const void*))(&wuffs_nie__decoder__num_animation_loops),
34089   (uint64_t(*)(const void*))(&wuffs_nie__decoder__num_decoded_frame_configs),
34090   (uint64_t(*)(const void*))(&wuffs_nie__decoder__num_decoded_frames),
34091   (wuffs_base__status(*)(void*,
34092       uint64_t,
34093       uint64_t))(&wuffs_nie__decoder__restart_frame),
34094   (wuffs_base__empty_struct(*)(void*,
34095       uint32_t,
34096       bool))(&wuffs_nie__decoder__set_quirk_enabled),
34097   (wuffs_base__empty_struct(*)(void*,
34098       uint32_t,
34099       bool))(&wuffs_nie__decoder__set_report_metadata),
34100   (wuffs_base__status(*)(void*,
34101       wuffs_base__io_buffer*,
34102       wuffs_base__more_information*,
34103       wuffs_base__io_buffer*))(&wuffs_nie__decoder__tell_me_more),
34104   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_nie__decoder__workbuf_len),
34105 };
34106 
34107 // ---------------- Initializer Implementations
34108 
34109 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)34110 wuffs_nie__decoder__initialize(
34111     wuffs_nie__decoder* self,
34112     size_t sizeof_star_self,
34113     uint64_t wuffs_version,
34114     uint32_t options){
34115   if (!self) {
34116     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
34117   }
34118   if (sizeof(*self) != sizeof_star_self) {
34119     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
34120   }
34121   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
34122       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
34123     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
34124   }
34125 
34126   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
34127     // The whole point of this if-check is to detect an uninitialized *self.
34128     // We disable the warning on GCC. Clang-5.0 does not have this warning.
34129 #if !defined(__clang__) && defined(__GNUC__)
34130 #pragma GCC diagnostic push
34131 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
34132 #endif
34133     if (self->private_impl.magic != 0) {
34134       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
34135     }
34136 #if !defined(__clang__) && defined(__GNUC__)
34137 #pragma GCC diagnostic pop
34138 #endif
34139   } else {
34140     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
34141       memset(self, 0, sizeof(*self));
34142       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
34143     } else {
34144       memset(&(self->private_impl), 0, sizeof(self->private_impl));
34145     }
34146   }
34147 
34148   self->private_impl.magic = WUFFS_BASE__MAGIC;
34149   self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
34150       wuffs_base__image_decoder__vtable_name;
34151   self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
34152       (const void*)(&wuffs_nie__decoder__func_ptrs_for__wuffs_base__image_decoder);
34153   return wuffs_base__make_status(NULL);
34154 }
34155 
34156 wuffs_nie__decoder*
wuffs_nie__decoder__alloc()34157 wuffs_nie__decoder__alloc() {
34158   wuffs_nie__decoder* x =
34159       (wuffs_nie__decoder*)(calloc(sizeof(wuffs_nie__decoder), 1));
34160   if (!x) {
34161     return NULL;
34162   }
34163   if (wuffs_nie__decoder__initialize(
34164       x, sizeof(wuffs_nie__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
34165     free(x);
34166     return NULL;
34167   }
34168   return x;
34169 }
34170 
34171 size_t
sizeof__wuffs_nie__decoder()34172 sizeof__wuffs_nie__decoder() {
34173   return sizeof(wuffs_nie__decoder);
34174 }
34175 
34176 // ---------------- Function Implementations
34177 
34178 // -------- func nie.decoder.set_quirk_enabled
34179 
34180 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_nie__decoder__set_quirk_enabled(wuffs_nie__decoder * self,uint32_t a_quirk,bool a_enabled)34181 wuffs_nie__decoder__set_quirk_enabled(
34182     wuffs_nie__decoder* self,
34183     uint32_t a_quirk,
34184     bool a_enabled) {
34185   return wuffs_base__make_empty_struct();
34186 }
34187 
34188 // -------- func nie.decoder.decode_image_config
34189 
34190 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)34191 wuffs_nie__decoder__decode_image_config(
34192     wuffs_nie__decoder* self,
34193     wuffs_base__image_config* a_dst,
34194     wuffs_base__io_buffer* a_src) {
34195   if (!self) {
34196     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
34197   }
34198   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
34199     return wuffs_base__make_status(
34200         (self->private_impl.magic == WUFFS_BASE__DISABLED)
34201         ? wuffs_base__error__disabled_by_previous_error
34202         : wuffs_base__error__initialize_not_called);
34203   }
34204   if (!a_src) {
34205     self->private_impl.magic = WUFFS_BASE__DISABLED;
34206     return wuffs_base__make_status(wuffs_base__error__bad_argument);
34207   }
34208   if ((self->private_impl.active_coroutine != 0) &&
34209       (self->private_impl.active_coroutine != 1)) {
34210     self->private_impl.magic = WUFFS_BASE__DISABLED;
34211     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
34212   }
34213   self->private_impl.active_coroutine = 0;
34214   wuffs_base__status status = wuffs_base__make_status(NULL);
34215 
34216   uint32_t v_a = 0;
34217 
34218   const uint8_t* iop_a_src = NULL;
34219   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34220   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34221   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34222   if (a_src) {
34223     io0_a_src = a_src->data.ptr;
34224     io1_a_src = io0_a_src + a_src->meta.ri;
34225     iop_a_src = io1_a_src;
34226     io2_a_src = io0_a_src + a_src->meta.wi;
34227   }
34228 
34229   uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
34230   switch (coro_susp_point) {
34231     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
34232 
34233     if (self->private_impl.f_call_sequence != 0) {
34234       status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
34235       goto exit;
34236     }
34237     {
34238       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
34239       uint32_t t_0;
34240       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
34241         t_0 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
34242         iop_a_src += 4;
34243       } else {
34244         self->private_data.s_decode_image_config[0].scratch = 0;
34245         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
34246         while (true) {
34247           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
34248             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34249             goto suspend;
34250           }
34251           uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
34252           uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
34253           *scratch <<= 8;
34254           *scratch >>= 8;
34255           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
34256           if (num_bits_0 == 24) {
34257             t_0 = ((uint32_t)(*scratch));
34258             break;
34259           }
34260           num_bits_0 += 8;
34261           *scratch |= ((uint64_t)(num_bits_0)) << 56;
34262         }
34263       }
34264       v_a = t_0;
34265     }
34266     if (v_a != 1169146734) {
34267       status = wuffs_base__make_status(wuffs_nie__error__bad_header);
34268       goto exit;
34269     }
34270     {
34271       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
34272       uint32_t t_1;
34273       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
34274         t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
34275         iop_a_src += 4;
34276       } else {
34277         self->private_data.s_decode_image_config[0].scratch = 0;
34278         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
34279         while (true) {
34280           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
34281             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34282             goto suspend;
34283           }
34284           uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
34285           uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
34286           *scratch <<= 8;
34287           *scratch >>= 8;
34288           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
34289           if (num_bits_1 == 24) {
34290             t_1 = ((uint32_t)(*scratch));
34291             break;
34292           }
34293           num_bits_1 += 8;
34294           *scratch |= ((uint64_t)(num_bits_1)) << 56;
34295         }
34296       }
34297       v_a = t_1;
34298     }
34299     if (v_a == 879649535) {
34300       self->private_impl.f_pixfmt = 2164295816;
34301     } else if (v_a == 946758399) {
34302       self->private_impl.f_pixfmt = 2164308923;
34303     } else if (v_a == 879780607) {
34304       status = wuffs_base__make_status(wuffs_nie__error__unsupported_nie_file);
34305       goto exit;
34306     } else if (v_a == 946889471) {
34307       status = wuffs_base__make_status(wuffs_nie__error__unsupported_nie_file);
34308       goto exit;
34309     } else {
34310       status = wuffs_base__make_status(wuffs_nie__error__bad_header);
34311       goto exit;
34312     }
34313     {
34314       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
34315       uint32_t t_2;
34316       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
34317         t_2 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
34318         iop_a_src += 4;
34319       } else {
34320         self->private_data.s_decode_image_config[0].scratch = 0;
34321         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
34322         while (true) {
34323           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
34324             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34325             goto suspend;
34326           }
34327           uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
34328           uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
34329           *scratch <<= 8;
34330           *scratch >>= 8;
34331           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
34332           if (num_bits_2 == 24) {
34333             t_2 = ((uint32_t)(*scratch));
34334             break;
34335           }
34336           num_bits_2 += 8;
34337           *scratch |= ((uint64_t)(num_bits_2)) << 56;
34338         }
34339       }
34340       v_a = t_2;
34341     }
34342     if (v_a >= 2147483648) {
34343       status = wuffs_base__make_status(wuffs_nie__error__bad_header);
34344       goto exit;
34345     }
34346     self->private_impl.f_width = v_a;
34347     {
34348       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
34349       uint32_t t_3;
34350       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
34351         t_3 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
34352         iop_a_src += 4;
34353       } else {
34354         self->private_data.s_decode_image_config[0].scratch = 0;
34355         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
34356         while (true) {
34357           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
34358             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34359             goto suspend;
34360           }
34361           uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
34362           uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56));
34363           *scratch <<= 8;
34364           *scratch >>= 8;
34365           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3;
34366           if (num_bits_3 == 24) {
34367             t_3 = ((uint32_t)(*scratch));
34368             break;
34369           }
34370           num_bits_3 += 8;
34371           *scratch |= ((uint64_t)(num_bits_3)) << 56;
34372         }
34373       }
34374       v_a = t_3;
34375     }
34376     if (v_a >= 2147483648) {
34377       status = wuffs_base__make_status(wuffs_nie__error__bad_header);
34378       goto exit;
34379     }
34380     self->private_impl.f_height = v_a;
34381     if (a_dst != NULL) {
34382       wuffs_base__image_config__set(
34383           a_dst,
34384           self->private_impl.f_pixfmt,
34385           0,
34386           self->private_impl.f_width,
34387           self->private_impl.f_height,
34388           16,
34389           false);
34390     }
34391     self->private_impl.f_call_sequence = 3;
34392 
34393     goto ok;
34394     ok:
34395     self->private_impl.p_decode_image_config[0] = 0;
34396     goto exit;
34397   }
34398 
34399   goto suspend;
34400   suspend:
34401   self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
34402   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
34403 
34404   goto exit;
34405   exit:
34406   if (a_src) {
34407     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
34408   }
34409 
34410   if (wuffs_base__status__is_error(&status)) {
34411     self->private_impl.magic = WUFFS_BASE__DISABLED;
34412   }
34413   return status;
34414 }
34415 
34416 // -------- func nie.decoder.decode_frame_config
34417 
34418 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)34419 wuffs_nie__decoder__decode_frame_config(
34420     wuffs_nie__decoder* self,
34421     wuffs_base__frame_config* a_dst,
34422     wuffs_base__io_buffer* a_src) {
34423   if (!self) {
34424     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
34425   }
34426   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
34427     return wuffs_base__make_status(
34428         (self->private_impl.magic == WUFFS_BASE__DISABLED)
34429         ? wuffs_base__error__disabled_by_previous_error
34430         : wuffs_base__error__initialize_not_called);
34431   }
34432   if (!a_src) {
34433     self->private_impl.magic = WUFFS_BASE__DISABLED;
34434     return wuffs_base__make_status(wuffs_base__error__bad_argument);
34435   }
34436   if ((self->private_impl.active_coroutine != 0) &&
34437       (self->private_impl.active_coroutine != 2)) {
34438     self->private_impl.magic = WUFFS_BASE__DISABLED;
34439     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
34440   }
34441   self->private_impl.active_coroutine = 0;
34442   wuffs_base__status status = wuffs_base__make_status(NULL);
34443 
34444   const uint8_t* iop_a_src = NULL;
34445   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34446   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34447   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34448   if (a_src) {
34449     io0_a_src = a_src->data.ptr;
34450     io1_a_src = io0_a_src + a_src->meta.ri;
34451     iop_a_src = io1_a_src;
34452     io2_a_src = io0_a_src + a_src->meta.wi;
34453   }
34454 
34455   uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
34456   switch (coro_susp_point) {
34457     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
34458 
34459     if (self->private_impl.f_call_sequence < 3) {
34460       if (a_src) {
34461         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
34462       }
34463       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
34464       status = wuffs_nie__decoder__decode_image_config(self, NULL, a_src);
34465       if (a_src) {
34466         iop_a_src = a_src->data.ptr + a_src->meta.ri;
34467       }
34468       if (status.repr) {
34469         goto suspend;
34470       }
34471     } else if (self->private_impl.f_call_sequence == 3) {
34472       if (16 != wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)))) {
34473         status = wuffs_base__make_status(wuffs_base__error__bad_restart);
34474         goto exit;
34475       }
34476     } else if (self->private_impl.f_call_sequence == 4) {
34477       self->private_impl.f_call_sequence = 255;
34478       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
34479       goto ok;
34480     } else {
34481       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
34482       goto ok;
34483     }
34484     if (a_dst != NULL) {
34485       wuffs_base__frame_config__set(
34486           a_dst,
34487           wuffs_base__utility__make_rect_ie_u32(
34488           0,
34489           0,
34490           self->private_impl.f_width,
34491           self->private_impl.f_height),
34492           ((wuffs_base__flicks)(0)),
34493           0,
34494           16,
34495           0,
34496           false,
34497           false,
34498           0);
34499     }
34500     self->private_impl.f_call_sequence = 4;
34501 
34502     ok:
34503     self->private_impl.p_decode_frame_config[0] = 0;
34504     goto exit;
34505   }
34506 
34507   goto suspend;
34508   suspend:
34509   self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
34510   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
34511 
34512   goto exit;
34513   exit:
34514   if (a_src) {
34515     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
34516   }
34517 
34518   if (wuffs_base__status__is_error(&status)) {
34519     self->private_impl.magic = WUFFS_BASE__DISABLED;
34520   }
34521   return status;
34522 }
34523 
34524 // -------- func nie.decoder.decode_frame
34525 
34526 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)34527 wuffs_nie__decoder__decode_frame(
34528     wuffs_nie__decoder* self,
34529     wuffs_base__pixel_buffer* a_dst,
34530     wuffs_base__io_buffer* a_src,
34531     wuffs_base__pixel_blend a_blend,
34532     wuffs_base__slice_u8 a_workbuf,
34533     wuffs_base__decode_frame_options* a_opts) {
34534   if (!self) {
34535     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
34536   }
34537   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
34538     return wuffs_base__make_status(
34539         (self->private_impl.magic == WUFFS_BASE__DISABLED)
34540         ? wuffs_base__error__disabled_by_previous_error
34541         : wuffs_base__error__initialize_not_called);
34542   }
34543   if (!a_dst || !a_src) {
34544     self->private_impl.magic = WUFFS_BASE__DISABLED;
34545     return wuffs_base__make_status(wuffs_base__error__bad_argument);
34546   }
34547   if ((self->private_impl.active_coroutine != 0) &&
34548       (self->private_impl.active_coroutine != 3)) {
34549     self->private_impl.magic = WUFFS_BASE__DISABLED;
34550     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
34551   }
34552   self->private_impl.active_coroutine = 0;
34553   wuffs_base__status status = wuffs_base__make_status(NULL);
34554 
34555   wuffs_base__status v_status = wuffs_base__make_status(NULL);
34556 
34557   uint32_t coro_susp_point = self->private_impl.p_decode_frame[0];
34558   switch (coro_susp_point) {
34559     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
34560 
34561     if (self->private_impl.f_call_sequence < 4) {
34562       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
34563       status = wuffs_nie__decoder__decode_frame_config(self, NULL, a_src);
34564       if (status.repr) {
34565         goto suspend;
34566       }
34567     } else if (self->private_impl.f_call_sequence == 4) {
34568     } else {
34569       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
34570       goto ok;
34571     }
34572     self->private_impl.f_dst_x = 0;
34573     self->private_impl.f_dst_y = 0;
34574     v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
34575         wuffs_base__pixel_buffer__pixel_format(a_dst),
34576         wuffs_base__pixel_buffer__palette(a_dst),
34577         wuffs_base__utility__make_pixel_format(self->private_impl.f_pixfmt),
34578         wuffs_base__utility__empty_slice_u8(),
34579         a_blend);
34580     if ( ! wuffs_base__status__is_ok(&v_status)) {
34581       status = v_status;
34582       if (wuffs_base__status__is_error(&status)) {
34583         goto exit;
34584       } else if (wuffs_base__status__is_suspension(&status)) {
34585         status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
34586         goto exit;
34587       }
34588       goto ok;
34589     }
34590     while (true) {
34591       v_status = wuffs_nie__decoder__swizzle(self, a_dst, a_src);
34592       if (wuffs_base__status__is_ok(&v_status)) {
34593         goto label__0__break;
34594       } else if (v_status.repr != wuffs_nie__note__internal_note_short_read) {
34595         status = v_status;
34596         if (wuffs_base__status__is_error(&status)) {
34597           goto exit;
34598         } else if (wuffs_base__status__is_suspension(&status)) {
34599           status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
34600           goto exit;
34601         }
34602         goto ok;
34603       }
34604       status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34605       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
34606     }
34607     label__0__break:;
34608     self->private_impl.f_call_sequence = 255;
34609 
34610     ok:
34611     self->private_impl.p_decode_frame[0] = 0;
34612     goto exit;
34613   }
34614 
34615   goto suspend;
34616   suspend:
34617   self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
34618   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
34619 
34620   goto exit;
34621   exit:
34622   if (wuffs_base__status__is_error(&status)) {
34623     self->private_impl.magic = WUFFS_BASE__DISABLED;
34624   }
34625   return status;
34626 }
34627 
34628 // -------- func nie.decoder.swizzle
34629 
34630 static wuffs_base__status
wuffs_nie__decoder__swizzle(wuffs_nie__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src)34631 wuffs_nie__decoder__swizzle(
34632     wuffs_nie__decoder* self,
34633     wuffs_base__pixel_buffer* a_dst,
34634     wuffs_base__io_buffer* a_src) {
34635   wuffs_base__status status = wuffs_base__make_status(NULL);
34636 
34637   wuffs_base__pixel_format v_dst_pixfmt = {0};
34638   uint32_t v_dst_bits_per_pixel = 0;
34639   uint64_t v_dst_bytes_per_pixel = 0;
34640   uint64_t v_dst_bytes_per_row = 0;
34641   wuffs_base__table_u8 v_tab = {0};
34642   wuffs_base__slice_u8 v_dst = {0};
34643   uint64_t v_i = 0;
34644   uint64_t v_n = 0;
34645 
34646   const uint8_t* iop_a_src = NULL;
34647   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34648   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34649   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34650   if (a_src) {
34651     io0_a_src = a_src->data.ptr;
34652     io1_a_src = io0_a_src + a_src->meta.ri;
34653     iop_a_src = io1_a_src;
34654     io2_a_src = io0_a_src + a_src->meta.wi;
34655   }
34656 
34657   v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
34658   v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
34659   if ((v_dst_bits_per_pixel & 7) != 0) {
34660     status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
34661     goto exit;
34662   }
34663   v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8)));
34664   v_dst_bytes_per_row = (((uint64_t)(self->private_impl.f_width)) * v_dst_bytes_per_pixel);
34665   v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0);
34666   label__0__continue:;
34667   while (true) {
34668     if (self->private_impl.f_dst_x == self->private_impl.f_width) {
34669       self->private_impl.f_dst_x = 0;
34670       self->private_impl.f_dst_y += 1;
34671       if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
34672         goto label__0__break;
34673       }
34674     }
34675     v_dst = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
34676     if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) {
34677       v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row);
34678     }
34679     v_i = (((uint64_t)(self->private_impl.f_dst_x)) * v_dst_bytes_per_pixel);
34680     if (v_i >= ((uint64_t)(v_dst.len))) {
34681       goto label__0__continue;
34682     }
34683     v_n = wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(
34684         &self->private_impl.f_swizzler,
34685         wuffs_base__slice_u8__subslice_i(v_dst, v_i),
34686         wuffs_base__pixel_buffer__palette(a_dst),
34687         &iop_a_src,
34688         io2_a_src);
34689     if (v_n == 0) {
34690       status = wuffs_base__make_status(wuffs_nie__note__internal_note_short_read);
34691       goto ok;
34692     }
34693     wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)((v_n & 4294967295))));
34694   }
34695   label__0__break:;
34696   status = wuffs_base__make_status(NULL);
34697   goto ok;
34698 
34699   ok:
34700   goto exit;
34701   exit:
34702   if (a_src) {
34703     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
34704   }
34705 
34706   return status;
34707 }
34708 
34709 // -------- func nie.decoder.frame_dirty_rect
34710 
34711 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
wuffs_nie__decoder__frame_dirty_rect(const wuffs_nie__decoder * self)34712 wuffs_nie__decoder__frame_dirty_rect(
34713     const wuffs_nie__decoder* self) {
34714   if (!self) {
34715     return wuffs_base__utility__empty_rect_ie_u32();
34716   }
34717   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
34718       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
34719     return wuffs_base__utility__empty_rect_ie_u32();
34720   }
34721 
34722   return wuffs_base__utility__make_rect_ie_u32(
34723       0,
34724       0,
34725       self->private_impl.f_width,
34726       self->private_impl.f_height);
34727 }
34728 
34729 // -------- func nie.decoder.num_animation_loops
34730 
34731 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_nie__decoder__num_animation_loops(const wuffs_nie__decoder * self)34732 wuffs_nie__decoder__num_animation_loops(
34733     const wuffs_nie__decoder* self) {
34734   if (!self) {
34735     return 0;
34736   }
34737   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
34738       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
34739     return 0;
34740   }
34741 
34742   return 0;
34743 }
34744 
34745 // -------- func nie.decoder.num_decoded_frame_configs
34746 
34747 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_nie__decoder__num_decoded_frame_configs(const wuffs_nie__decoder * self)34748 wuffs_nie__decoder__num_decoded_frame_configs(
34749     const wuffs_nie__decoder* self) {
34750   if (!self) {
34751     return 0;
34752   }
34753   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
34754       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
34755     return 0;
34756   }
34757 
34758   if (self->private_impl.f_call_sequence > 3) {
34759     return 1;
34760   }
34761   return 0;
34762 }
34763 
34764 // -------- func nie.decoder.num_decoded_frames
34765 
34766 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_nie__decoder__num_decoded_frames(const wuffs_nie__decoder * self)34767 wuffs_nie__decoder__num_decoded_frames(
34768     const wuffs_nie__decoder* self) {
34769   if (!self) {
34770     return 0;
34771   }
34772   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
34773       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
34774     return 0;
34775   }
34776 
34777   if (self->private_impl.f_call_sequence > 4) {
34778     return 1;
34779   }
34780   return 0;
34781 }
34782 
34783 // -------- func nie.decoder.restart_frame
34784 
34785 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)34786 wuffs_nie__decoder__restart_frame(
34787     wuffs_nie__decoder* self,
34788     uint64_t a_index,
34789     uint64_t a_io_position) {
34790   if (!self) {
34791     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
34792   }
34793   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
34794     return wuffs_base__make_status(
34795         (self->private_impl.magic == WUFFS_BASE__DISABLED)
34796         ? wuffs_base__error__disabled_by_previous_error
34797         : wuffs_base__error__initialize_not_called);
34798   }
34799 
34800   if (self->private_impl.f_call_sequence < 3) {
34801     return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
34802   }
34803   if ((a_index != 0) || (a_io_position != 16)) {
34804     return wuffs_base__make_status(wuffs_base__error__bad_argument);
34805   }
34806   self->private_impl.f_call_sequence = 3;
34807   return wuffs_base__make_status(NULL);
34808 }
34809 
34810 // -------- func nie.decoder.set_report_metadata
34811 
34812 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)34813 wuffs_nie__decoder__set_report_metadata(
34814     wuffs_nie__decoder* self,
34815     uint32_t a_fourcc,
34816     bool a_report) {
34817   return wuffs_base__make_empty_struct();
34818 }
34819 
34820 // -------- func nie.decoder.tell_me_more
34821 
34822 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)34823 wuffs_nie__decoder__tell_me_more(
34824     wuffs_nie__decoder* self,
34825     wuffs_base__io_buffer* a_dst,
34826     wuffs_base__more_information* a_minfo,
34827     wuffs_base__io_buffer* a_src) {
34828   if (!self) {
34829     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
34830   }
34831   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
34832     return wuffs_base__make_status(
34833         (self->private_impl.magic == WUFFS_BASE__DISABLED)
34834         ? wuffs_base__error__disabled_by_previous_error
34835         : wuffs_base__error__initialize_not_called);
34836   }
34837   if (!a_dst || !a_src) {
34838     self->private_impl.magic = WUFFS_BASE__DISABLED;
34839     return wuffs_base__make_status(wuffs_base__error__bad_argument);
34840   }
34841   if ((self->private_impl.active_coroutine != 0) &&
34842       (self->private_impl.active_coroutine != 4)) {
34843     self->private_impl.magic = WUFFS_BASE__DISABLED;
34844     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
34845   }
34846   self->private_impl.active_coroutine = 0;
34847   wuffs_base__status status = wuffs_base__make_status(NULL);
34848 
34849   status = wuffs_base__make_status(wuffs_base__error__no_more_information);
34850   goto exit;
34851 
34852   goto ok;
34853   ok:
34854   goto exit;
34855   exit:
34856   if (wuffs_base__status__is_error(&status)) {
34857     self->private_impl.magic = WUFFS_BASE__DISABLED;
34858   }
34859   return status;
34860 }
34861 
34862 // -------- func nie.decoder.workbuf_len
34863 
34864 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_nie__decoder__workbuf_len(const wuffs_nie__decoder * self)34865 wuffs_nie__decoder__workbuf_len(
34866     const wuffs_nie__decoder* self) {
34867   if (!self) {
34868     return wuffs_base__utility__empty_range_ii_u64();
34869   }
34870   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
34871       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
34872     return wuffs_base__utility__empty_range_ii_u64();
34873   }
34874 
34875   return wuffs_base__utility__make_range_ii_u64(0, 0);
34876 }
34877 
34878 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NIE)
34879 
34880 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ZLIB)
34881 
34882 // ---------------- Status Codes Implementations
34883 
34884 const char wuffs_zlib__note__dictionary_required[] = "@zlib: dictionary required";
34885 const char wuffs_zlib__error__bad_checksum[] = "#zlib: bad checksum";
34886 const char wuffs_zlib__error__bad_compression_method[] = "#zlib: bad compression method";
34887 const char wuffs_zlib__error__bad_compression_window_size[] = "#zlib: bad compression window size";
34888 const char wuffs_zlib__error__bad_parity_check[] = "#zlib: bad parity check";
34889 const char wuffs_zlib__error__incorrect_dictionary[] = "#zlib: incorrect dictionary";
34890 
34891 // ---------------- Private Consts
34892 
34893 // ---------------- Private Initializer Prototypes
34894 
34895 // ---------------- Private Function Prototypes
34896 
34897 // ---------------- VTables
34898 
34899 const wuffs_base__io_transformer__func_ptrs
34900 wuffs_zlib__decoder__func_ptrs_for__wuffs_base__io_transformer = {
34901   (wuffs_base__empty_struct(*)(void*,
34902       uint32_t,
34903       bool))(&wuffs_zlib__decoder__set_quirk_enabled),
34904   (wuffs_base__status(*)(void*,
34905       wuffs_base__io_buffer*,
34906       wuffs_base__io_buffer*,
34907       wuffs_base__slice_u8))(&wuffs_zlib__decoder__transform_io),
34908   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_zlib__decoder__workbuf_len),
34909 };
34910 
34911 // ---------------- Initializer Implementations
34912 
34913 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)34914 wuffs_zlib__decoder__initialize(
34915     wuffs_zlib__decoder* self,
34916     size_t sizeof_star_self,
34917     uint64_t wuffs_version,
34918     uint32_t options){
34919   if (!self) {
34920     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
34921   }
34922   if (sizeof(*self) != sizeof_star_self) {
34923     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
34924   }
34925   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
34926       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
34927     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
34928   }
34929 
34930   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
34931     // The whole point of this if-check is to detect an uninitialized *self.
34932     // We disable the warning on GCC. Clang-5.0 does not have this warning.
34933 #if !defined(__clang__) && defined(__GNUC__)
34934 #pragma GCC diagnostic push
34935 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
34936 #endif
34937     if (self->private_impl.magic != 0) {
34938       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
34939     }
34940 #if !defined(__clang__) && defined(__GNUC__)
34941 #pragma GCC diagnostic pop
34942 #endif
34943   } else {
34944     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
34945       memset(self, 0, sizeof(*self));
34946       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
34947     } else {
34948       memset(&(self->private_impl), 0, sizeof(self->private_impl));
34949     }
34950   }
34951 
34952   {
34953     wuffs_base__status z = wuffs_adler32__hasher__initialize(
34954         &self->private_data.f_checksum, sizeof(self->private_data.f_checksum), WUFFS_VERSION, options);
34955     if (z.repr) {
34956       return z;
34957     }
34958   }
34959   {
34960     wuffs_base__status z = wuffs_adler32__hasher__initialize(
34961         &self->private_data.f_dict_id_hasher, sizeof(self->private_data.f_dict_id_hasher), WUFFS_VERSION, options);
34962     if (z.repr) {
34963       return z;
34964     }
34965   }
34966   {
34967     wuffs_base__status z = wuffs_deflate__decoder__initialize(
34968         &self->private_data.f_flate, sizeof(self->private_data.f_flate), WUFFS_VERSION, options);
34969     if (z.repr) {
34970       return z;
34971     }
34972   }
34973   self->private_impl.magic = WUFFS_BASE__MAGIC;
34974   self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name =
34975       wuffs_base__io_transformer__vtable_name;
34976   self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers =
34977       (const void*)(&wuffs_zlib__decoder__func_ptrs_for__wuffs_base__io_transformer);
34978   return wuffs_base__make_status(NULL);
34979 }
34980 
34981 wuffs_zlib__decoder*
wuffs_zlib__decoder__alloc()34982 wuffs_zlib__decoder__alloc() {
34983   wuffs_zlib__decoder* x =
34984       (wuffs_zlib__decoder*)(calloc(sizeof(wuffs_zlib__decoder), 1));
34985   if (!x) {
34986     return NULL;
34987   }
34988   if (wuffs_zlib__decoder__initialize(
34989       x, sizeof(wuffs_zlib__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
34990     free(x);
34991     return NULL;
34992   }
34993   return x;
34994 }
34995 
34996 size_t
sizeof__wuffs_zlib__decoder()34997 sizeof__wuffs_zlib__decoder() {
34998   return sizeof(wuffs_zlib__decoder);
34999 }
35000 
35001 // ---------------- Function Implementations
35002 
35003 // -------- func zlib.decoder.dictionary_id
35004 
35005 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_zlib__decoder__dictionary_id(const wuffs_zlib__decoder * self)35006 wuffs_zlib__decoder__dictionary_id(
35007     const wuffs_zlib__decoder* self) {
35008   if (!self) {
35009     return 0;
35010   }
35011   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
35012       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
35013     return 0;
35014   }
35015 
35016   return self->private_impl.f_dict_id_want;
35017 }
35018 
35019 // -------- func zlib.decoder.add_dictionary
35020 
35021 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_zlib__decoder__add_dictionary(wuffs_zlib__decoder * self,wuffs_base__slice_u8 a_dict)35022 wuffs_zlib__decoder__add_dictionary(
35023     wuffs_zlib__decoder* self,
35024     wuffs_base__slice_u8 a_dict) {
35025   if (!self) {
35026     return wuffs_base__make_empty_struct();
35027   }
35028   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
35029     return wuffs_base__make_empty_struct();
35030   }
35031 
35032   if (self->private_impl.f_header_complete) {
35033     self->private_impl.f_bad_call_sequence = true;
35034   } else {
35035     self->private_impl.f_dict_id_got = wuffs_adler32__hasher__update_u32(&self->private_data.f_dict_id_hasher, a_dict);
35036     wuffs_deflate__decoder__add_history(&self->private_data.f_flate, a_dict);
35037   }
35038   self->private_impl.f_got_dictionary = true;
35039   return wuffs_base__make_empty_struct();
35040 }
35041 
35042 // -------- func zlib.decoder.set_quirk_enabled
35043 
35044 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_zlib__decoder__set_quirk_enabled(wuffs_zlib__decoder * self,uint32_t a_quirk,bool a_enabled)35045 wuffs_zlib__decoder__set_quirk_enabled(
35046     wuffs_zlib__decoder* self,
35047     uint32_t a_quirk,
35048     bool a_enabled) {
35049   if (!self) {
35050     return wuffs_base__make_empty_struct();
35051   }
35052   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
35053     return wuffs_base__make_empty_struct();
35054   }
35055 
35056   if (a_quirk == 1) {
35057     self->private_impl.f_ignore_checksum = a_enabled;
35058   }
35059   return wuffs_base__make_empty_struct();
35060 }
35061 
35062 // -------- func zlib.decoder.workbuf_len
35063 
35064 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_zlib__decoder__workbuf_len(const wuffs_zlib__decoder * self)35065 wuffs_zlib__decoder__workbuf_len(
35066     const wuffs_zlib__decoder* self) {
35067   if (!self) {
35068     return wuffs_base__utility__empty_range_ii_u64();
35069   }
35070   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
35071       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
35072     return wuffs_base__utility__empty_range_ii_u64();
35073   }
35074 
35075   return wuffs_base__utility__make_range_ii_u64(1, 1);
35076 }
35077 
35078 // -------- func zlib.decoder.transform_io
35079 
35080 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)35081 wuffs_zlib__decoder__transform_io(
35082     wuffs_zlib__decoder* self,
35083     wuffs_base__io_buffer* a_dst,
35084     wuffs_base__io_buffer* a_src,
35085     wuffs_base__slice_u8 a_workbuf) {
35086   if (!self) {
35087     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
35088   }
35089   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
35090     return wuffs_base__make_status(
35091         (self->private_impl.magic == WUFFS_BASE__DISABLED)
35092         ? wuffs_base__error__disabled_by_previous_error
35093         : wuffs_base__error__initialize_not_called);
35094   }
35095   if (!a_dst || !a_src) {
35096     self->private_impl.magic = WUFFS_BASE__DISABLED;
35097     return wuffs_base__make_status(wuffs_base__error__bad_argument);
35098   }
35099   if ((self->private_impl.active_coroutine != 0) &&
35100       (self->private_impl.active_coroutine != 1)) {
35101     self->private_impl.magic = WUFFS_BASE__DISABLED;
35102     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
35103   }
35104   self->private_impl.active_coroutine = 0;
35105   wuffs_base__status status = wuffs_base__make_status(NULL);
35106 
35107   uint16_t v_x = 0;
35108   uint32_t v_checksum_got = 0;
35109   wuffs_base__status v_status = wuffs_base__make_status(NULL);
35110   uint32_t v_checksum_want = 0;
35111   uint64_t v_mark = 0;
35112 
35113   uint8_t* iop_a_dst = NULL;
35114   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35115   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35116   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35117   if (a_dst) {
35118     io0_a_dst = a_dst->data.ptr;
35119     io1_a_dst = io0_a_dst + a_dst->meta.wi;
35120     iop_a_dst = io1_a_dst;
35121     io2_a_dst = io0_a_dst + a_dst->data.len;
35122     if (a_dst->meta.closed) {
35123       io2_a_dst = iop_a_dst;
35124     }
35125   }
35126   const uint8_t* iop_a_src = NULL;
35127   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35128   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35129   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35130   if (a_src) {
35131     io0_a_src = a_src->data.ptr;
35132     io1_a_src = io0_a_src + a_src->meta.ri;
35133     iop_a_src = io1_a_src;
35134     io2_a_src = io0_a_src + a_src->meta.wi;
35135   }
35136 
35137   uint32_t coro_susp_point = self->private_impl.p_transform_io[0];
35138   if (coro_susp_point) {
35139     v_checksum_got = self->private_data.s_transform_io[0].v_checksum_got;
35140   }
35141   switch (coro_susp_point) {
35142     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
35143 
35144     if (self->private_impl.f_bad_call_sequence) {
35145       status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
35146       goto exit;
35147     } else if ( ! self->private_impl.f_want_dictionary) {
35148       {
35149         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
35150         uint16_t t_0;
35151         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
35152           t_0 = wuffs_base__peek_u16be__no_bounds_check(iop_a_src);
35153           iop_a_src += 2;
35154         } else {
35155           self->private_data.s_transform_io[0].scratch = 0;
35156           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
35157           while (true) {
35158             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
35159               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
35160               goto suspend;
35161             }
35162             uint64_t* scratch = &self->private_data.s_transform_io[0].scratch;
35163             uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFF));
35164             *scratch >>= 8;
35165             *scratch <<= 8;
35166             *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
35167             if (num_bits_0 == 8) {
35168               t_0 = ((uint16_t)(*scratch >> 48));
35169               break;
35170             }
35171             num_bits_0 += 8;
35172             *scratch |= ((uint64_t)(num_bits_0));
35173           }
35174         }
35175         v_x = t_0;
35176       }
35177       if (((v_x >> 8) & 15) != 8) {
35178         status = wuffs_base__make_status(wuffs_zlib__error__bad_compression_method);
35179         goto exit;
35180       }
35181       if ((v_x >> 12) > 7) {
35182         status = wuffs_base__make_status(wuffs_zlib__error__bad_compression_window_size);
35183         goto exit;
35184       }
35185       if ((v_x % 31) != 0) {
35186         status = wuffs_base__make_status(wuffs_zlib__error__bad_parity_check);
35187         goto exit;
35188       }
35189       self->private_impl.f_want_dictionary = ((v_x & 32) != 0);
35190       if (self->private_impl.f_want_dictionary) {
35191         self->private_impl.f_dict_id_got = 1;
35192         {
35193           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
35194           uint32_t t_1;
35195           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
35196             t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
35197             iop_a_src += 4;
35198           } else {
35199             self->private_data.s_transform_io[0].scratch = 0;
35200             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
35201             while (true) {
35202               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
35203                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
35204                 goto suspend;
35205               }
35206               uint64_t* scratch = &self->private_data.s_transform_io[0].scratch;
35207               uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFF));
35208               *scratch >>= 8;
35209               *scratch <<= 8;
35210               *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
35211               if (num_bits_1 == 24) {
35212                 t_1 = ((uint32_t)(*scratch >> 32));
35213                 break;
35214               }
35215               num_bits_1 += 8;
35216               *scratch |= ((uint64_t)(num_bits_1));
35217             }
35218           }
35219           self->private_impl.f_dict_id_want = t_1;
35220         }
35221         status = wuffs_base__make_status(wuffs_zlib__note__dictionary_required);
35222         goto ok;
35223       } else if (self->private_impl.f_got_dictionary) {
35224         status = wuffs_base__make_status(wuffs_zlib__error__incorrect_dictionary);
35225         goto exit;
35226       }
35227     } else if (self->private_impl.f_dict_id_got != self->private_impl.f_dict_id_want) {
35228       if (self->private_impl.f_got_dictionary) {
35229         status = wuffs_base__make_status(wuffs_zlib__error__incorrect_dictionary);
35230         goto exit;
35231       }
35232       status = wuffs_base__make_status(wuffs_zlib__note__dictionary_required);
35233       goto ok;
35234     }
35235     self->private_impl.f_header_complete = true;
35236     while (true) {
35237       v_mark = ((uint64_t)(iop_a_dst - io0_a_dst));
35238       {
35239         if (a_dst) {
35240           a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
35241         }
35242         if (a_src) {
35243           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
35244         }
35245         wuffs_base__status t_2 = wuffs_deflate__decoder__transform_io(&self->private_data.f_flate, a_dst, a_src, a_workbuf);
35246         v_status = t_2;
35247         if (a_dst) {
35248           iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
35249         }
35250         if (a_src) {
35251           iop_a_src = a_src->data.ptr + a_src->meta.ri;
35252         }
35253       }
35254       if ( ! self->private_impl.f_ignore_checksum) {
35255         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));
35256       }
35257       if (wuffs_base__status__is_ok(&v_status)) {
35258         goto label__0__break;
35259       }
35260       status = v_status;
35261       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
35262     }
35263     label__0__break:;
35264     {
35265       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
35266       uint32_t t_3;
35267       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
35268         t_3 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
35269         iop_a_src += 4;
35270       } else {
35271         self->private_data.s_transform_io[0].scratch = 0;
35272         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
35273         while (true) {
35274           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
35275             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
35276             goto suspend;
35277           }
35278           uint64_t* scratch = &self->private_data.s_transform_io[0].scratch;
35279           uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFF));
35280           *scratch >>= 8;
35281           *scratch <<= 8;
35282           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3);
35283           if (num_bits_3 == 24) {
35284             t_3 = ((uint32_t)(*scratch >> 32));
35285             break;
35286           }
35287           num_bits_3 += 8;
35288           *scratch |= ((uint64_t)(num_bits_3));
35289         }
35290       }
35291       v_checksum_want = t_3;
35292     }
35293     if ( ! self->private_impl.f_ignore_checksum && (v_checksum_got != v_checksum_want)) {
35294       status = wuffs_base__make_status(wuffs_zlib__error__bad_checksum);
35295       goto exit;
35296     }
35297 
35298     ok:
35299     self->private_impl.p_transform_io[0] = 0;
35300     goto exit;
35301   }
35302 
35303   goto suspend;
35304   suspend:
35305   self->private_impl.p_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
35306   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
35307   self->private_data.s_transform_io[0].v_checksum_got = v_checksum_got;
35308 
35309   goto exit;
35310   exit:
35311   if (a_dst) {
35312     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
35313   }
35314   if (a_src) {
35315     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
35316   }
35317 
35318   if (wuffs_base__status__is_error(&status)) {
35319     self->private_impl.magic = WUFFS_BASE__DISABLED;
35320   }
35321   return status;
35322 }
35323 
35324 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ZLIB)
35325 
35326 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__PNG)
35327 
35328 // ---------------- Status Codes Implementations
35329 
35330 const char wuffs_png__error__bad_animation_sequence_number[] = "#png: bad animation sequence number";
35331 const char wuffs_png__error__bad_checksum[] = "#png: bad checksum";
35332 const char wuffs_png__error__bad_chunk[] = "#png: bad chunk";
35333 const char wuffs_png__error__bad_filter[] = "#png: bad filter";
35334 const char wuffs_png__error__bad_header[] = "#png: bad header";
35335 const char wuffs_png__error__bad_text_chunk_not_latin_1[] = "#png: bad text chunk (not Latin-1)";
35336 const char wuffs_png__error__missing_palette[] = "#png: missing palette";
35337 const char wuffs_png__error__unsupported_png_compression_method[] = "#png: unsupported PNG compression method";
35338 const char wuffs_png__error__unsupported_png_file[] = "#png: unsupported PNG file";
35339 const char wuffs_png__error__internal_error_inconsistent_i_o[] = "#png: internal error: inconsistent I/O";
35340 const char wuffs_png__error__internal_error_inconsistent_chunk_type[] = "#png: internal error: inconsistent chunk type";
35341 const char wuffs_png__error__internal_error_inconsistent_frame_bounds[] = "#png: internal error: inconsistent frame bounds";
35342 const char wuffs_png__error__internal_error_inconsistent_workbuf_length[] = "#png: internal error: inconsistent workbuf length";
35343 const char wuffs_png__error__internal_error_zlib_decoder_did_not_exhaust_its_input[] = "#png: internal error: zlib decoder did not exhaust its input";
35344 
35345 // ---------------- Private Consts
35346 
35347 #define WUFFS_PNG__ANCILLARY_BIT 32
35348 
35349 static const uint8_t
35350 WUFFS_PNG__INTERLACING[8][6] WUFFS_BASE__POTENTIALLY_UNUSED = {
35351   {
35352     0, 0, 0, 0, 0, 0,
35353   }, {
35354     3, 7, 0, 3, 7, 0,
35355   }, {
35356     3, 3, 4, 3, 7, 0,
35357   }, {
35358     2, 3, 0, 3, 3, 4,
35359   }, {
35360     2, 1, 2, 2, 3, 0,
35361   }, {
35362     1, 1, 0, 2, 1, 2,
35363   }, {
35364     1, 0, 1, 1, 1, 0,
35365   }, {
35366     0, 0, 0, 1, 0, 1,
35367   },
35368 };
35369 
35370 static const uint8_t
35371 WUFFS_PNG__LOW_BIT_DEPTH_MULTIPLIERS[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
35372   0, 255, 85, 0, 17, 0, 0, 0,
35373 };
35374 
35375 static const uint8_t
35376 WUFFS_PNG__LOW_BIT_DEPTH_NUM_PACKS[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
35377   0, 8, 4, 0, 2, 0, 0, 0,
35378 };
35379 
35380 static const uint8_t
35381 WUFFS_PNG__NUM_CHANNELS[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
35382   1, 0, 3, 1, 2, 0, 4, 0,
35383 };
35384 
35385 static const uint16_t
35386 WUFFS_PNG__LATIN_1[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
35387   0, 0, 0, 0, 0, 0, 0, 0,
35388   0, 0, 0, 0, 0, 0, 0, 0,
35389   0, 0, 0, 0, 0, 0, 0, 0,
35390   0, 0, 0, 0, 0, 0, 0, 0,
35391   32, 33, 34, 35, 36, 37, 38, 39,
35392   40, 41, 42, 43, 44, 45, 46, 47,
35393   48, 49, 50, 51, 52, 53, 54, 55,
35394   56, 57, 58, 59, 60, 61, 62, 63,
35395   64, 65, 66, 67, 68, 69, 70, 71,
35396   72, 73, 74, 75, 76, 77, 78, 79,
35397   80, 81, 82, 83, 84, 85, 86, 87,
35398   88, 89, 90, 91, 92, 93, 94, 95,
35399   96, 97, 98, 99, 100, 101, 102, 103,
35400   104, 105, 106, 107, 108, 109, 110, 111,
35401   112, 113, 114, 115, 116, 117, 118, 119,
35402   120, 121, 122, 123, 124, 125, 126, 0,
35403   0, 0, 0, 0, 0, 0, 0, 0,
35404   0, 0, 0, 0, 0, 0, 0, 0,
35405   0, 0, 0, 0, 0, 0, 0, 0,
35406   0, 0, 0, 0, 0, 0, 0, 0,
35407   0, 41410, 41666, 41922, 42178, 42434, 42690, 42946,
35408   43202, 43458, 43714, 43970, 44226, 44482, 44738, 44994,
35409   45250, 45506, 45762, 46018, 46274, 46530, 46786, 47042,
35410   47298, 47554, 47810, 48066, 48322, 48578, 48834, 49090,
35411   32963, 33219, 33475, 33731, 33987, 34243, 34499, 34755,
35412   35011, 35267, 35523, 35779, 36035, 36291, 36547, 36803,
35413   37059, 37315, 37571, 37827, 38083, 38339, 38595, 38851,
35414   39107, 39363, 39619, 39875, 40131, 40387, 40643, 40899,
35415   41155, 41411, 41667, 41923, 42179, 42435, 42691, 42947,
35416   43203, 43459, 43715, 43971, 44227, 44483, 44739, 44995,
35417   45251, 45507, 45763, 46019, 46275, 46531, 46787, 47043,
35418   47299, 47555, 47811, 48067, 48323, 48579, 48835, 49091,
35419 };
35420 
35421 // ---------------- Private Initializer Prototypes
35422 
35423 // ---------------- Private Function Prototypes
35424 
35425 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
35426 static wuffs_base__empty_struct
35427 wuffs_png__decoder__filter_1_distance_4_arm_neon(
35428     wuffs_png__decoder* self,
35429     wuffs_base__slice_u8 a_curr);
35430 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
35431 
35432 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
35433 static wuffs_base__empty_struct
35434 wuffs_png__decoder__filter_3_distance_4_arm_neon(
35435     wuffs_png__decoder* self,
35436     wuffs_base__slice_u8 a_curr,
35437     wuffs_base__slice_u8 a_prev);
35438 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
35439 
35440 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
35441 static wuffs_base__empty_struct
35442 wuffs_png__decoder__filter_4_distance_3_arm_neon(
35443     wuffs_png__decoder* self,
35444     wuffs_base__slice_u8 a_curr,
35445     wuffs_base__slice_u8 a_prev);
35446 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
35447 
35448 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
35449 static wuffs_base__empty_struct
35450 wuffs_png__decoder__filter_4_distance_4_arm_neon(
35451     wuffs_png__decoder* self,
35452     wuffs_base__slice_u8 a_curr,
35453     wuffs_base__slice_u8 a_prev);
35454 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
35455 
35456 static wuffs_base__empty_struct
35457 wuffs_png__decoder__filter_1(
35458     wuffs_png__decoder* self,
35459     wuffs_base__slice_u8 a_curr);
35460 
35461 static wuffs_base__empty_struct
35462 wuffs_png__decoder__filter_1__choosy_default(
35463     wuffs_png__decoder* self,
35464     wuffs_base__slice_u8 a_curr);
35465 
35466 static wuffs_base__empty_struct
35467 wuffs_png__decoder__filter_1_distance_3_fallback(
35468     wuffs_png__decoder* self,
35469     wuffs_base__slice_u8 a_curr);
35470 
35471 static wuffs_base__empty_struct
35472 wuffs_png__decoder__filter_1_distance_4_fallback(
35473     wuffs_png__decoder* self,
35474     wuffs_base__slice_u8 a_curr);
35475 
35476 static wuffs_base__empty_struct
35477 wuffs_png__decoder__filter_2(
35478     wuffs_png__decoder* self,
35479     wuffs_base__slice_u8 a_curr,
35480     wuffs_base__slice_u8 a_prev);
35481 
35482 static wuffs_base__empty_struct
35483 wuffs_png__decoder__filter_3(
35484     wuffs_png__decoder* self,
35485     wuffs_base__slice_u8 a_curr,
35486     wuffs_base__slice_u8 a_prev);
35487 
35488 static wuffs_base__empty_struct
35489 wuffs_png__decoder__filter_3__choosy_default(
35490     wuffs_png__decoder* self,
35491     wuffs_base__slice_u8 a_curr,
35492     wuffs_base__slice_u8 a_prev);
35493 
35494 static wuffs_base__empty_struct
35495 wuffs_png__decoder__filter_3_distance_3_fallback(
35496     wuffs_png__decoder* self,
35497     wuffs_base__slice_u8 a_curr,
35498     wuffs_base__slice_u8 a_prev);
35499 
35500 static wuffs_base__empty_struct
35501 wuffs_png__decoder__filter_3_distance_4_fallback(
35502     wuffs_png__decoder* self,
35503     wuffs_base__slice_u8 a_curr,
35504     wuffs_base__slice_u8 a_prev);
35505 
35506 static wuffs_base__empty_struct
35507 wuffs_png__decoder__filter_4(
35508     wuffs_png__decoder* self,
35509     wuffs_base__slice_u8 a_curr,
35510     wuffs_base__slice_u8 a_prev);
35511 
35512 static wuffs_base__empty_struct
35513 wuffs_png__decoder__filter_4__choosy_default(
35514     wuffs_png__decoder* self,
35515     wuffs_base__slice_u8 a_curr,
35516     wuffs_base__slice_u8 a_prev);
35517 
35518 static wuffs_base__empty_struct
35519 wuffs_png__decoder__filter_4_distance_3_fallback(
35520     wuffs_png__decoder* self,
35521     wuffs_base__slice_u8 a_curr,
35522     wuffs_base__slice_u8 a_prev);
35523 
35524 static wuffs_base__empty_struct
35525 wuffs_png__decoder__filter_4_distance_4_fallback(
35526     wuffs_png__decoder* self,
35527     wuffs_base__slice_u8 a_curr,
35528     wuffs_base__slice_u8 a_prev);
35529 
35530 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
35531 static wuffs_base__empty_struct
35532 wuffs_png__decoder__filter_1_distance_4_x86_sse42(
35533     wuffs_png__decoder* self,
35534     wuffs_base__slice_u8 a_curr);
35535 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
35536 
35537 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
35538 static wuffs_base__empty_struct
35539 wuffs_png__decoder__filter_3_distance_4_x86_sse42(
35540     wuffs_png__decoder* self,
35541     wuffs_base__slice_u8 a_curr,
35542     wuffs_base__slice_u8 a_prev);
35543 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
35544 
35545 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
35546 static wuffs_base__empty_struct
35547 wuffs_png__decoder__filter_4_distance_3_x86_sse42(
35548     wuffs_png__decoder* self,
35549     wuffs_base__slice_u8 a_curr,
35550     wuffs_base__slice_u8 a_prev);
35551 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
35552 
35553 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
35554 static wuffs_base__empty_struct
35555 wuffs_png__decoder__filter_4_distance_4_x86_sse42(
35556     wuffs_png__decoder* self,
35557     wuffs_base__slice_u8 a_curr,
35558     wuffs_base__slice_u8 a_prev);
35559 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
35560 
35561 static wuffs_base__status
35562 wuffs_png__decoder__decode_ihdr(
35563     wuffs_png__decoder* self,
35564     wuffs_base__io_buffer* a_src);
35565 
35566 static wuffs_base__empty_struct
35567 wuffs_png__decoder__assign_filter_distance(
35568     wuffs_png__decoder* self);
35569 
35570 static uint64_t
35571 wuffs_png__decoder__calculate_bytes_per_row(
35572     const wuffs_png__decoder* self,
35573     uint32_t a_width);
35574 
35575 static wuffs_base__empty_struct
35576 wuffs_png__decoder__choose_filter_implementations(
35577     wuffs_png__decoder* self);
35578 
35579 static wuffs_base__status
35580 wuffs_png__decoder__decode_other_chunk(
35581     wuffs_png__decoder* self,
35582     wuffs_base__io_buffer* a_src);
35583 
35584 static wuffs_base__status
35585 wuffs_png__decoder__decode_actl(
35586     wuffs_png__decoder* self,
35587     wuffs_base__io_buffer* a_src);
35588 
35589 static wuffs_base__status
35590 wuffs_png__decoder__decode_chrm(
35591     wuffs_png__decoder* self,
35592     wuffs_base__io_buffer* a_src);
35593 
35594 static wuffs_base__status
35595 wuffs_png__decoder__decode_fctl(
35596     wuffs_png__decoder* self,
35597     wuffs_base__io_buffer* a_src);
35598 
35599 static wuffs_base__status
35600 wuffs_png__decoder__decode_gama(
35601     wuffs_png__decoder* self,
35602     wuffs_base__io_buffer* a_src);
35603 
35604 static wuffs_base__status
35605 wuffs_png__decoder__decode_iccp(
35606     wuffs_png__decoder* self,
35607     wuffs_base__io_buffer* a_src);
35608 
35609 static wuffs_base__status
35610 wuffs_png__decoder__decode_plte(
35611     wuffs_png__decoder* self,
35612     wuffs_base__io_buffer* a_src);
35613 
35614 static wuffs_base__status
35615 wuffs_png__decoder__decode_srgb(
35616     wuffs_png__decoder* self,
35617     wuffs_base__io_buffer* a_src);
35618 
35619 static wuffs_base__status
35620 wuffs_png__decoder__decode_trns(
35621     wuffs_png__decoder* self,
35622     wuffs_base__io_buffer* a_src);
35623 
35624 static wuffs_base__status
35625 wuffs_png__decoder__skip_frame(
35626     wuffs_png__decoder* self,
35627     wuffs_base__io_buffer* a_src);
35628 
35629 static wuffs_base__status
35630 wuffs_png__decoder__decode_pass(
35631     wuffs_png__decoder* self,
35632     wuffs_base__io_buffer* a_src,
35633     wuffs_base__slice_u8 a_workbuf);
35634 
35635 static wuffs_base__status
35636 wuffs_png__decoder__filter_and_swizzle(
35637     wuffs_png__decoder* self,
35638     wuffs_base__pixel_buffer* a_dst,
35639     wuffs_base__slice_u8 a_workbuf);
35640 
35641 static wuffs_base__status
35642 wuffs_png__decoder__filter_and_swizzle__choosy_default(
35643     wuffs_png__decoder* self,
35644     wuffs_base__pixel_buffer* a_dst,
35645     wuffs_base__slice_u8 a_workbuf);
35646 
35647 static wuffs_base__status
35648 wuffs_png__decoder__filter_and_swizzle_tricky(
35649     wuffs_png__decoder* self,
35650     wuffs_base__pixel_buffer* a_dst,
35651     wuffs_base__slice_u8 a_workbuf);
35652 
35653 // ---------------- VTables
35654 
35655 const wuffs_base__image_decoder__func_ptrs
35656 wuffs_png__decoder__func_ptrs_for__wuffs_base__image_decoder = {
35657   (wuffs_base__status(*)(void*,
35658       wuffs_base__pixel_buffer*,
35659       wuffs_base__io_buffer*,
35660       wuffs_base__pixel_blend,
35661       wuffs_base__slice_u8,
35662       wuffs_base__decode_frame_options*))(&wuffs_png__decoder__decode_frame),
35663   (wuffs_base__status(*)(void*,
35664       wuffs_base__frame_config*,
35665       wuffs_base__io_buffer*))(&wuffs_png__decoder__decode_frame_config),
35666   (wuffs_base__status(*)(void*,
35667       wuffs_base__image_config*,
35668       wuffs_base__io_buffer*))(&wuffs_png__decoder__decode_image_config),
35669   (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_png__decoder__frame_dirty_rect),
35670   (uint32_t(*)(const void*))(&wuffs_png__decoder__num_animation_loops),
35671   (uint64_t(*)(const void*))(&wuffs_png__decoder__num_decoded_frame_configs),
35672   (uint64_t(*)(const void*))(&wuffs_png__decoder__num_decoded_frames),
35673   (wuffs_base__status(*)(void*,
35674       uint64_t,
35675       uint64_t))(&wuffs_png__decoder__restart_frame),
35676   (wuffs_base__empty_struct(*)(void*,
35677       uint32_t,
35678       bool))(&wuffs_png__decoder__set_quirk_enabled),
35679   (wuffs_base__empty_struct(*)(void*,
35680       uint32_t,
35681       bool))(&wuffs_png__decoder__set_report_metadata),
35682   (wuffs_base__status(*)(void*,
35683       wuffs_base__io_buffer*,
35684       wuffs_base__more_information*,
35685       wuffs_base__io_buffer*))(&wuffs_png__decoder__tell_me_more),
35686   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_png__decoder__workbuf_len),
35687 };
35688 
35689 // ---------------- Initializer Implementations
35690 
35691 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)35692 wuffs_png__decoder__initialize(
35693     wuffs_png__decoder* self,
35694     size_t sizeof_star_self,
35695     uint64_t wuffs_version,
35696     uint32_t options){
35697   if (!self) {
35698     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
35699   }
35700   if (sizeof(*self) != sizeof_star_self) {
35701     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
35702   }
35703   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
35704       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
35705     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
35706   }
35707 
35708   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
35709     // The whole point of this if-check is to detect an uninitialized *self.
35710     // We disable the warning on GCC. Clang-5.0 does not have this warning.
35711 #if !defined(__clang__) && defined(__GNUC__)
35712 #pragma GCC diagnostic push
35713 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
35714 #endif
35715     if (self->private_impl.magic != 0) {
35716       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
35717     }
35718 #if !defined(__clang__) && defined(__GNUC__)
35719 #pragma GCC diagnostic pop
35720 #endif
35721   } else {
35722     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
35723       memset(self, 0, sizeof(*self));
35724       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
35725     } else {
35726       memset(&(self->private_impl), 0, sizeof(self->private_impl));
35727     }
35728   }
35729 
35730   self->private_impl.choosy_filter_1 = &wuffs_png__decoder__filter_1__choosy_default;
35731   self->private_impl.choosy_filter_3 = &wuffs_png__decoder__filter_3__choosy_default;
35732   self->private_impl.choosy_filter_4 = &wuffs_png__decoder__filter_4__choosy_default;
35733   self->private_impl.choosy_filter_and_swizzle = &wuffs_png__decoder__filter_and_swizzle__choosy_default;
35734 
35735   {
35736     wuffs_base__status z = wuffs_crc32__ieee_hasher__initialize(
35737         &self->private_data.f_crc32, sizeof(self->private_data.f_crc32), WUFFS_VERSION, options);
35738     if (z.repr) {
35739       return z;
35740     }
35741   }
35742   {
35743     wuffs_base__status z = wuffs_zlib__decoder__initialize(
35744         &self->private_data.f_zlib, sizeof(self->private_data.f_zlib), WUFFS_VERSION, options);
35745     if (z.repr) {
35746       return z;
35747     }
35748   }
35749   self->private_impl.magic = WUFFS_BASE__MAGIC;
35750   self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
35751       wuffs_base__image_decoder__vtable_name;
35752   self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
35753       (const void*)(&wuffs_png__decoder__func_ptrs_for__wuffs_base__image_decoder);
35754   return wuffs_base__make_status(NULL);
35755 }
35756 
35757 wuffs_png__decoder*
wuffs_png__decoder__alloc()35758 wuffs_png__decoder__alloc() {
35759   wuffs_png__decoder* x =
35760       (wuffs_png__decoder*)(calloc(sizeof(wuffs_png__decoder), 1));
35761   if (!x) {
35762     return NULL;
35763   }
35764   if (wuffs_png__decoder__initialize(
35765       x, sizeof(wuffs_png__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
35766     free(x);
35767     return NULL;
35768   }
35769   return x;
35770 }
35771 
35772 size_t
sizeof__wuffs_png__decoder()35773 sizeof__wuffs_png__decoder() {
35774   return sizeof(wuffs_png__decoder);
35775 }
35776 
35777 // ---------------- Function Implementations
35778 
35779 // ‼ WUFFS MULTI-FILE SECTION +arm_neon
35780 // -------- func png.decoder.filter_1_distance_4_arm_neon
35781 
35782 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
35783 static wuffs_base__empty_struct
wuffs_png__decoder__filter_1_distance_4_arm_neon(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr)35784 wuffs_png__decoder__filter_1_distance_4_arm_neon(
35785     wuffs_png__decoder* self,
35786     wuffs_base__slice_u8 a_curr) {
35787   wuffs_base__slice_u8 v_curr = {0};
35788   uint8x8_t v_fa = {0};
35789   uint8x8_t v_fx = {0};
35790 
35791   {
35792     wuffs_base__slice_u8 i_slice_curr = a_curr;
35793     v_curr.ptr = i_slice_curr.ptr;
35794     v_curr.len = 4;
35795     uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
35796     while (v_curr.ptr < i_end0_curr) {
35797       v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
35798       v_fx = vadd_u8(v_fx, v_fa);
35799       wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
35800       v_fa = v_fx;
35801       v_curr.ptr += 4;
35802       v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
35803       v_fx = vadd_u8(v_fx, v_fa);
35804       wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
35805       v_fa = v_fx;
35806       v_curr.ptr += 4;
35807     }
35808     v_curr.len = 4;
35809     uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
35810     while (v_curr.ptr < i_end1_curr) {
35811       v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
35812       v_fx = vadd_u8(v_fx, v_fa);
35813       wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
35814       v_fa = v_fx;
35815       v_curr.ptr += 4;
35816     }
35817     v_curr.len = 0;
35818   }
35819   return wuffs_base__make_empty_struct();
35820 }
35821 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
35822 // ‼ WUFFS MULTI-FILE SECTION -arm_neon
35823 
35824 // ‼ WUFFS MULTI-FILE SECTION +arm_neon
35825 // -------- func png.decoder.filter_3_distance_4_arm_neon
35826 
35827 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
35828 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)35829 wuffs_png__decoder__filter_3_distance_4_arm_neon(
35830     wuffs_png__decoder* self,
35831     wuffs_base__slice_u8 a_curr,
35832     wuffs_base__slice_u8 a_prev) {
35833   wuffs_base__slice_u8 v_curr = {0};
35834   wuffs_base__slice_u8 v_prev = {0};
35835   uint8x8_t v_fa = {0};
35836   uint8x8_t v_fb = {0};
35837   uint8x8_t v_fx = {0};
35838 
35839   if (((uint64_t)(a_prev.len)) == 0) {
35840     {
35841       wuffs_base__slice_u8 i_slice_curr = a_curr;
35842       v_curr.ptr = i_slice_curr.ptr;
35843       v_curr.len = 4;
35844       uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
35845       while (v_curr.ptr < i_end0_curr) {
35846         v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
35847         v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb));
35848         wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
35849         v_fa = v_fx;
35850         v_curr.ptr += 4;
35851         v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
35852         v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb));
35853         wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
35854         v_fa = v_fx;
35855         v_curr.ptr += 4;
35856       }
35857       v_curr.len = 4;
35858       uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
35859       while (v_curr.ptr < i_end1_curr) {
35860         v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
35861         v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb));
35862         wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
35863         v_fa = v_fx;
35864         v_curr.ptr += 4;
35865       }
35866       v_curr.len = 0;
35867     }
35868   } else {
35869     {
35870       wuffs_base__slice_u8 i_slice_curr = a_curr;
35871       v_curr.ptr = i_slice_curr.ptr;
35872       wuffs_base__slice_u8 i_slice_prev = a_prev;
35873       v_prev.ptr = i_slice_prev.ptr;
35874       i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
35875       v_curr.len = 4;
35876       v_prev.len = 4;
35877       uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
35878       while (v_curr.ptr < i_end0_curr) {
35879         v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
35880         v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
35881         v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb));
35882         wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
35883         v_fa = v_fx;
35884         v_curr.ptr += 4;
35885         v_prev.ptr += 4;
35886         v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
35887         v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
35888         v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb));
35889         wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
35890         v_fa = v_fx;
35891         v_curr.ptr += 4;
35892         v_prev.ptr += 4;
35893       }
35894       v_curr.len = 4;
35895       v_prev.len = 4;
35896       uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
35897       while (v_curr.ptr < i_end1_curr) {
35898         v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
35899         v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
35900         v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb));
35901         wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
35902         v_fa = v_fx;
35903         v_curr.ptr += 4;
35904         v_prev.ptr += 4;
35905       }
35906       v_curr.len = 0;
35907       v_prev.len = 0;
35908     }
35909   }
35910   return wuffs_base__make_empty_struct();
35911 }
35912 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
35913 // ‼ WUFFS MULTI-FILE SECTION -arm_neon
35914 
35915 // ‼ WUFFS MULTI-FILE SECTION +arm_neon
35916 // -------- func png.decoder.filter_4_distance_3_arm_neon
35917 
35918 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
35919 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)35920 wuffs_png__decoder__filter_4_distance_3_arm_neon(
35921     wuffs_png__decoder* self,
35922     wuffs_base__slice_u8 a_curr,
35923     wuffs_base__slice_u8 a_prev) {
35924   wuffs_base__slice_u8 v_curr = {0};
35925   wuffs_base__slice_u8 v_prev = {0};
35926   uint8x8_t v_fa = {0};
35927   uint8x8_t v_fb = {0};
35928   uint8x8_t v_fc = {0};
35929   uint8x8_t v_fx = {0};
35930   uint16x8_t v_fafb = {0};
35931   uint16x8_t v_fcfc = {0};
35932   uint16x8_t v_pa = {0};
35933   uint16x8_t v_pb = {0};
35934   uint16x8_t v_pc = {0};
35935   uint16x8_t v_cmpab = {0};
35936   uint16x8_t v_cmpac = {0};
35937   uint8x8_t v_picka = {0};
35938   uint8x8_t v_pickb = {0};
35939 
35940   {
35941     wuffs_base__slice_u8 i_slice_curr = a_curr;
35942     v_curr.ptr = i_slice_curr.ptr;
35943     wuffs_base__slice_u8 i_slice_prev = a_prev;
35944     v_prev.ptr = i_slice_prev.ptr;
35945     i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
35946     v_curr.len = 4;
35947     v_prev.len = 4;
35948     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);
35949     while (v_curr.ptr < i_end0_curr) {
35950       v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
35951       v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
35952       v_fafb = vaddl_u8(v_fa, v_fb);
35953       v_fcfc = vaddl_u8(v_fc, v_fc);
35954       v_pa = vabdl_u8(v_fb, v_fc);
35955       v_pb = vabdl_u8(v_fa, v_fc);
35956       v_pc = vabdq_u16(v_fafb, v_fcfc);
35957       v_cmpab = vcleq_u16(v_pa, v_pb);
35958       v_cmpac = vcleq_u16(v_pa, v_pc);
35959       v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
35960       v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
35961       v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
35962       wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
35963       v_fc = v_fb;
35964       v_fa = v_fx;
35965       v_curr.ptr += 3;
35966       v_prev.ptr += 3;
35967       v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
35968       v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
35969       v_fafb = vaddl_u8(v_fa, v_fb);
35970       v_fcfc = vaddl_u8(v_fc, v_fc);
35971       v_pa = vabdl_u8(v_fb, v_fc);
35972       v_pb = vabdl_u8(v_fa, v_fc);
35973       v_pc = vabdq_u16(v_fafb, v_fcfc);
35974       v_cmpab = vcleq_u16(v_pa, v_pb);
35975       v_cmpac = vcleq_u16(v_pa, v_pc);
35976       v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
35977       v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
35978       v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
35979       wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
35980       v_fc = v_fb;
35981       v_fa = v_fx;
35982       v_curr.ptr += 3;
35983       v_prev.ptr += 3;
35984     }
35985     v_curr.len = 4;
35986     v_prev.len = 4;
35987     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);
35988     while (v_curr.ptr < i_end1_curr) {
35989       v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
35990       v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
35991       v_fafb = vaddl_u8(v_fa, v_fb);
35992       v_fcfc = vaddl_u8(v_fc, v_fc);
35993       v_pa = vabdl_u8(v_fb, v_fc);
35994       v_pb = vabdl_u8(v_fa, v_fc);
35995       v_pc = vabdq_u16(v_fafb, v_fcfc);
35996       v_cmpab = vcleq_u16(v_pa, v_pb);
35997       v_cmpac = vcleq_u16(v_pa, v_pc);
35998       v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
35999       v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
36000       v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
36001       wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
36002       v_fc = v_fb;
36003       v_fa = v_fx;
36004       v_curr.ptr += 3;
36005       v_prev.ptr += 3;
36006     }
36007     v_curr.len = 3;
36008     v_prev.len = 3;
36009     uint8_t* i_end2_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3);
36010     while (v_curr.ptr < i_end2_curr) {
36011       v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u24le__no_bounds_check(v_prev.ptr)));
36012       v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u24le__no_bounds_check(v_curr.ptr)));
36013       v_fafb = vaddl_u8(v_fa, v_fb);
36014       v_fcfc = vaddl_u8(v_fc, v_fc);
36015       v_pa = vabdl_u8(v_fb, v_fc);
36016       v_pb = vabdl_u8(v_fa, v_fc);
36017       v_pc = vabdq_u16(v_fafb, v_fcfc);
36018       v_cmpab = vcleq_u16(v_pa, v_pb);
36019       v_cmpac = vcleq_u16(v_pa, v_pc);
36020       v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
36021       v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
36022       v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
36023       wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
36024       v_curr.ptr += 3;
36025       v_prev.ptr += 3;
36026     }
36027     v_curr.len = 0;
36028     v_prev.len = 0;
36029   }
36030   return wuffs_base__make_empty_struct();
36031 }
36032 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
36033 // ‼ WUFFS MULTI-FILE SECTION -arm_neon
36034 
36035 // ‼ WUFFS MULTI-FILE SECTION +arm_neon
36036 // -------- func png.decoder.filter_4_distance_4_arm_neon
36037 
36038 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
36039 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)36040 wuffs_png__decoder__filter_4_distance_4_arm_neon(
36041     wuffs_png__decoder* self,
36042     wuffs_base__slice_u8 a_curr,
36043     wuffs_base__slice_u8 a_prev) {
36044   wuffs_base__slice_u8 v_curr = {0};
36045   wuffs_base__slice_u8 v_prev = {0};
36046   uint8x8_t v_fa = {0};
36047   uint8x8_t v_fb = {0};
36048   uint8x8_t v_fc = {0};
36049   uint8x8_t v_fx = {0};
36050   uint16x8_t v_fafb = {0};
36051   uint16x8_t v_fcfc = {0};
36052   uint16x8_t v_pa = {0};
36053   uint16x8_t v_pb = {0};
36054   uint16x8_t v_pc = {0};
36055   uint16x8_t v_cmpab = {0};
36056   uint16x8_t v_cmpac = {0};
36057   uint8x8_t v_picka = {0};
36058   uint8x8_t v_pickb = {0};
36059 
36060   {
36061     wuffs_base__slice_u8 i_slice_curr = a_curr;
36062     v_curr.ptr = i_slice_curr.ptr;
36063     wuffs_base__slice_u8 i_slice_prev = a_prev;
36064     v_prev.ptr = i_slice_prev.ptr;
36065     i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
36066     v_curr.len = 4;
36067     v_prev.len = 4;
36068     uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
36069     while (v_curr.ptr < i_end0_curr) {
36070       v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
36071       v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36072       v_fafb = vaddl_u8(v_fa, v_fb);
36073       v_fcfc = vaddl_u8(v_fc, v_fc);
36074       v_pa = vabdl_u8(v_fb, v_fc);
36075       v_pb = vabdl_u8(v_fa, v_fc);
36076       v_pc = vabdq_u16(v_fafb, v_fcfc);
36077       v_cmpab = vcleq_u16(v_pa, v_pb);
36078       v_cmpac = vcleq_u16(v_pa, v_pc);
36079       v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
36080       v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
36081       v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
36082       wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
36083       v_fc = v_fb;
36084       v_fa = v_fx;
36085       v_curr.ptr += 4;
36086       v_prev.ptr += 4;
36087       v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
36088       v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36089       v_fafb = vaddl_u8(v_fa, v_fb);
36090       v_fcfc = vaddl_u8(v_fc, v_fc);
36091       v_pa = vabdl_u8(v_fb, v_fc);
36092       v_pb = vabdl_u8(v_fa, v_fc);
36093       v_pc = vabdq_u16(v_fafb, v_fcfc);
36094       v_cmpab = vcleq_u16(v_pa, v_pb);
36095       v_cmpac = vcleq_u16(v_pa, v_pc);
36096       v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
36097       v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
36098       v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
36099       wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
36100       v_fc = v_fb;
36101       v_fa = v_fx;
36102       v_curr.ptr += 4;
36103       v_prev.ptr += 4;
36104     }
36105     v_curr.len = 4;
36106     v_prev.len = 4;
36107     uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
36108     while (v_curr.ptr < i_end1_curr) {
36109       v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
36110       v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36111       v_fafb = vaddl_u8(v_fa, v_fb);
36112       v_fcfc = vaddl_u8(v_fc, v_fc);
36113       v_pa = vabdl_u8(v_fb, v_fc);
36114       v_pb = vabdl_u8(v_fa, v_fc);
36115       v_pc = vabdq_u16(v_fafb, v_fcfc);
36116       v_cmpab = vcleq_u16(v_pa, v_pb);
36117       v_cmpac = vcleq_u16(v_pa, v_pc);
36118       v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
36119       v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
36120       v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
36121       wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
36122       v_fc = v_fb;
36123       v_fa = v_fx;
36124       v_curr.ptr += 4;
36125       v_prev.ptr += 4;
36126     }
36127     v_curr.len = 0;
36128     v_prev.len = 0;
36129   }
36130   return wuffs_base__make_empty_struct();
36131 }
36132 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
36133 // ‼ WUFFS MULTI-FILE SECTION -arm_neon
36134 
36135 // -------- func png.decoder.filter_1
36136 
36137 static wuffs_base__empty_struct
wuffs_png__decoder__filter_1(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr)36138 wuffs_png__decoder__filter_1(
36139     wuffs_png__decoder* self,
36140     wuffs_base__slice_u8 a_curr) {
36141   return (*self->private_impl.choosy_filter_1)(self, a_curr);
36142 }
36143 
36144 static wuffs_base__empty_struct
wuffs_png__decoder__filter_1__choosy_default(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr)36145 wuffs_png__decoder__filter_1__choosy_default(
36146     wuffs_png__decoder* self,
36147     wuffs_base__slice_u8 a_curr) {
36148   uint64_t v_filter_distance = 0;
36149   uint8_t v_fa = 0;
36150   uint64_t v_i_start = 0;
36151   uint64_t v_i = 0;
36152 
36153   v_filter_distance = ((uint64_t)(self->private_impl.f_filter_distance));
36154   v_i_start = 0;
36155   while (v_i_start < v_filter_distance) {
36156     v_fa = 0;
36157     v_i = v_i_start;
36158     while (v_i < ((uint64_t)(a_curr.len))) {
36159       a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + v_fa));
36160       v_fa = a_curr.ptr[v_i];
36161       v_i += v_filter_distance;
36162     }
36163     v_i_start += 1;
36164   }
36165   return wuffs_base__make_empty_struct();
36166 }
36167 
36168 // -------- func png.decoder.filter_1_distance_3_fallback
36169 
36170 static wuffs_base__empty_struct
wuffs_png__decoder__filter_1_distance_3_fallback(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr)36171 wuffs_png__decoder__filter_1_distance_3_fallback(
36172     wuffs_png__decoder* self,
36173     wuffs_base__slice_u8 a_curr) {
36174   wuffs_base__slice_u8 v_curr = {0};
36175   uint8_t v_fa0 = 0;
36176   uint8_t v_fa1 = 0;
36177   uint8_t v_fa2 = 0;
36178 
36179   {
36180     wuffs_base__slice_u8 i_slice_curr = a_curr;
36181     v_curr.ptr = i_slice_curr.ptr;
36182     v_curr.len = 3;
36183     uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 6) * 6);
36184     while (v_curr.ptr < i_end0_curr) {
36185       v_fa0 = ((uint8_t)(v_fa0 + v_curr.ptr[0]));
36186       v_curr.ptr[0] = v_fa0;
36187       v_fa1 = ((uint8_t)(v_fa1 + v_curr.ptr[1]));
36188       v_curr.ptr[1] = v_fa1;
36189       v_fa2 = ((uint8_t)(v_fa2 + v_curr.ptr[2]));
36190       v_curr.ptr[2] = v_fa2;
36191       v_curr.ptr += 3;
36192       v_fa0 = ((uint8_t)(v_fa0 + v_curr.ptr[0]));
36193       v_curr.ptr[0] = v_fa0;
36194       v_fa1 = ((uint8_t)(v_fa1 + v_curr.ptr[1]));
36195       v_curr.ptr[1] = v_fa1;
36196       v_fa2 = ((uint8_t)(v_fa2 + v_curr.ptr[2]));
36197       v_curr.ptr[2] = v_fa2;
36198       v_curr.ptr += 3;
36199     }
36200     v_curr.len = 3;
36201     uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3);
36202     while (v_curr.ptr < i_end1_curr) {
36203       v_fa0 = ((uint8_t)(v_fa0 + v_curr.ptr[0]));
36204       v_curr.ptr[0] = v_fa0;
36205       v_fa1 = ((uint8_t)(v_fa1 + v_curr.ptr[1]));
36206       v_curr.ptr[1] = v_fa1;
36207       v_fa2 = ((uint8_t)(v_fa2 + v_curr.ptr[2]));
36208       v_curr.ptr[2] = v_fa2;
36209       v_curr.ptr += 3;
36210     }
36211     v_curr.len = 0;
36212   }
36213   return wuffs_base__make_empty_struct();
36214 }
36215 
36216 // -------- func png.decoder.filter_1_distance_4_fallback
36217 
36218 static wuffs_base__empty_struct
wuffs_png__decoder__filter_1_distance_4_fallback(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr)36219 wuffs_png__decoder__filter_1_distance_4_fallback(
36220     wuffs_png__decoder* self,
36221     wuffs_base__slice_u8 a_curr) {
36222   wuffs_base__slice_u8 v_curr = {0};
36223   uint8_t v_fa0 = 0;
36224   uint8_t v_fa1 = 0;
36225   uint8_t v_fa2 = 0;
36226   uint8_t v_fa3 = 0;
36227 
36228   {
36229     wuffs_base__slice_u8 i_slice_curr = a_curr;
36230     v_curr.ptr = i_slice_curr.ptr;
36231     v_curr.len = 4;
36232     uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
36233     while (v_curr.ptr < i_end0_curr) {
36234       v_fa0 = ((uint8_t)(v_fa0 + v_curr.ptr[0]));
36235       v_curr.ptr[0] = v_fa0;
36236       v_fa1 = ((uint8_t)(v_fa1 + v_curr.ptr[1]));
36237       v_curr.ptr[1] = v_fa1;
36238       v_fa2 = ((uint8_t)(v_fa2 + v_curr.ptr[2]));
36239       v_curr.ptr[2] = v_fa2;
36240       v_fa3 = ((uint8_t)(v_fa3 + v_curr.ptr[3]));
36241       v_curr.ptr[3] = v_fa3;
36242       v_curr.ptr += 4;
36243     }
36244     v_curr.len = 0;
36245   }
36246   return wuffs_base__make_empty_struct();
36247 }
36248 
36249 // -------- func png.decoder.filter_2
36250 
36251 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)36252 wuffs_png__decoder__filter_2(
36253     wuffs_png__decoder* self,
36254     wuffs_base__slice_u8 a_curr,
36255     wuffs_base__slice_u8 a_prev) {
36256   uint64_t v_n = 0;
36257   uint64_t v_i = 0;
36258 
36259   v_n = wuffs_base__u64__min(((uint64_t)(a_curr.len)), ((uint64_t)(a_prev.len)));
36260   v_i = 0;
36261   while (v_i < v_n) {
36262     a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + a_prev.ptr[v_i]));
36263     v_i += 1;
36264   }
36265   return wuffs_base__make_empty_struct();
36266 }
36267 
36268 // -------- func png.decoder.filter_3
36269 
36270 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)36271 wuffs_png__decoder__filter_3(
36272     wuffs_png__decoder* self,
36273     wuffs_base__slice_u8 a_curr,
36274     wuffs_base__slice_u8 a_prev) {
36275   return (*self->private_impl.choosy_filter_3)(self, a_curr, a_prev);
36276 }
36277 
36278 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)36279 wuffs_png__decoder__filter_3__choosy_default(
36280     wuffs_png__decoder* self,
36281     wuffs_base__slice_u8 a_curr,
36282     wuffs_base__slice_u8 a_prev) {
36283   uint64_t v_filter_distance = 0;
36284   uint64_t v_n = 0;
36285   uint64_t v_i = 0;
36286 
36287   v_filter_distance = ((uint64_t)(self->private_impl.f_filter_distance));
36288   if (((uint64_t)(a_prev.len)) == 0) {
36289     v_i = v_filter_distance;
36290     while (v_i < ((uint64_t)(a_curr.len))) {
36291       a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + (a_curr.ptr[(v_i - v_filter_distance)] / 2)));
36292       v_i += 1;
36293     }
36294   } else {
36295     v_n = wuffs_base__u64__min(((uint64_t)(a_curr.len)), ((uint64_t)(a_prev.len)));
36296     v_i = 0;
36297     while ((v_i < v_n) && (v_i < v_filter_distance)) {
36298       a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + (a_prev.ptr[v_i] / 2)));
36299       v_i += 1;
36300     }
36301     v_i = v_filter_distance;
36302     while (v_i < v_n) {
36303       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]))) / 2)))));
36304       v_i += 1;
36305     }
36306   }
36307   return wuffs_base__make_empty_struct();
36308 }
36309 
36310 // -------- func png.decoder.filter_3_distance_3_fallback
36311 
36312 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)36313 wuffs_png__decoder__filter_3_distance_3_fallback(
36314     wuffs_png__decoder* self,
36315     wuffs_base__slice_u8 a_curr,
36316     wuffs_base__slice_u8 a_prev) {
36317   wuffs_base__slice_u8 v_curr = {0};
36318   wuffs_base__slice_u8 v_prev = {0};
36319   uint8_t v_fa0 = 0;
36320   uint8_t v_fa1 = 0;
36321   uint8_t v_fa2 = 0;
36322 
36323   if (((uint64_t)(a_prev.len)) == 0) {
36324     {
36325       wuffs_base__slice_u8 i_slice_curr = a_curr;
36326       v_curr.ptr = i_slice_curr.ptr;
36327       v_curr.len = 3;
36328       uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 6) * 6);
36329       while (v_curr.ptr < i_end0_curr) {
36330         v_fa0 = ((uint8_t)((v_fa0 / 2) + v_curr.ptr[0]));
36331         v_curr.ptr[0] = v_fa0;
36332         v_fa1 = ((uint8_t)((v_fa1 / 2) + v_curr.ptr[1]));
36333         v_curr.ptr[1] = v_fa1;
36334         v_fa2 = ((uint8_t)((v_fa2 / 2) + v_curr.ptr[2]));
36335         v_curr.ptr[2] = v_fa2;
36336         v_curr.ptr += 3;
36337         v_fa0 = ((uint8_t)((v_fa0 / 2) + v_curr.ptr[0]));
36338         v_curr.ptr[0] = v_fa0;
36339         v_fa1 = ((uint8_t)((v_fa1 / 2) + v_curr.ptr[1]));
36340         v_curr.ptr[1] = v_fa1;
36341         v_fa2 = ((uint8_t)((v_fa2 / 2) + v_curr.ptr[2]));
36342         v_curr.ptr[2] = v_fa2;
36343         v_curr.ptr += 3;
36344       }
36345       v_curr.len = 3;
36346       uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3);
36347       while (v_curr.ptr < i_end1_curr) {
36348         v_fa0 = ((uint8_t)((v_fa0 / 2) + v_curr.ptr[0]));
36349         v_curr.ptr[0] = v_fa0;
36350         v_fa1 = ((uint8_t)((v_fa1 / 2) + v_curr.ptr[1]));
36351         v_curr.ptr[1] = v_fa1;
36352         v_fa2 = ((uint8_t)((v_fa2 / 2) + v_curr.ptr[2]));
36353         v_curr.ptr[2] = v_fa2;
36354         v_curr.ptr += 3;
36355       }
36356       v_curr.len = 0;
36357     }
36358   } else {
36359     {
36360       wuffs_base__slice_u8 i_slice_curr = a_curr;
36361       v_curr.ptr = i_slice_curr.ptr;
36362       wuffs_base__slice_u8 i_slice_prev = a_prev;
36363       v_prev.ptr = i_slice_prev.ptr;
36364       i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
36365       v_curr.len = 3;
36366       v_prev.len = 3;
36367       uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 6) * 6);
36368       while (v_curr.ptr < i_end0_curr) {
36369         v_fa0 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa0)) + ((uint32_t)(v_prev.ptr[0]))) / 2))) + v_curr.ptr[0]));
36370         v_curr.ptr[0] = v_fa0;
36371         v_fa1 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa1)) + ((uint32_t)(v_prev.ptr[1]))) / 2))) + v_curr.ptr[1]));
36372         v_curr.ptr[1] = v_fa1;
36373         v_fa2 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa2)) + ((uint32_t)(v_prev.ptr[2]))) / 2))) + v_curr.ptr[2]));
36374         v_curr.ptr[2] = v_fa2;
36375         v_curr.ptr += 3;
36376         v_prev.ptr += 3;
36377         v_fa0 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa0)) + ((uint32_t)(v_prev.ptr[0]))) / 2))) + v_curr.ptr[0]));
36378         v_curr.ptr[0] = v_fa0;
36379         v_fa1 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa1)) + ((uint32_t)(v_prev.ptr[1]))) / 2))) + v_curr.ptr[1]));
36380         v_curr.ptr[1] = v_fa1;
36381         v_fa2 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa2)) + ((uint32_t)(v_prev.ptr[2]))) / 2))) + v_curr.ptr[2]));
36382         v_curr.ptr[2] = v_fa2;
36383         v_curr.ptr += 3;
36384         v_prev.ptr += 3;
36385       }
36386       v_curr.len = 3;
36387       v_prev.len = 3;
36388       uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3);
36389       while (v_curr.ptr < i_end1_curr) {
36390         v_fa0 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa0)) + ((uint32_t)(v_prev.ptr[0]))) / 2))) + v_curr.ptr[0]));
36391         v_curr.ptr[0] = v_fa0;
36392         v_fa1 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa1)) + ((uint32_t)(v_prev.ptr[1]))) / 2))) + v_curr.ptr[1]));
36393         v_curr.ptr[1] = v_fa1;
36394         v_fa2 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa2)) + ((uint32_t)(v_prev.ptr[2]))) / 2))) + v_curr.ptr[2]));
36395         v_curr.ptr[2] = v_fa2;
36396         v_curr.ptr += 3;
36397         v_prev.ptr += 3;
36398       }
36399       v_curr.len = 0;
36400       v_prev.len = 0;
36401     }
36402   }
36403   return wuffs_base__make_empty_struct();
36404 }
36405 
36406 // -------- func png.decoder.filter_3_distance_4_fallback
36407 
36408 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)36409 wuffs_png__decoder__filter_3_distance_4_fallback(
36410     wuffs_png__decoder* self,
36411     wuffs_base__slice_u8 a_curr,
36412     wuffs_base__slice_u8 a_prev) {
36413   wuffs_base__slice_u8 v_curr = {0};
36414   wuffs_base__slice_u8 v_prev = {0};
36415   uint8_t v_fa0 = 0;
36416   uint8_t v_fa1 = 0;
36417   uint8_t v_fa2 = 0;
36418   uint8_t v_fa3 = 0;
36419 
36420   if (((uint64_t)(a_prev.len)) == 0) {
36421     {
36422       wuffs_base__slice_u8 i_slice_curr = a_curr;
36423       v_curr.ptr = i_slice_curr.ptr;
36424       v_curr.len = 4;
36425       uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
36426       while (v_curr.ptr < i_end0_curr) {
36427         v_fa0 = ((uint8_t)((v_fa0 / 2) + v_curr.ptr[0]));
36428         v_curr.ptr[0] = v_fa0;
36429         v_fa1 = ((uint8_t)((v_fa1 / 2) + v_curr.ptr[1]));
36430         v_curr.ptr[1] = v_fa1;
36431         v_fa2 = ((uint8_t)((v_fa2 / 2) + v_curr.ptr[2]));
36432         v_curr.ptr[2] = v_fa2;
36433         v_fa3 = ((uint8_t)((v_fa3 / 2) + v_curr.ptr[3]));
36434         v_curr.ptr[3] = v_fa3;
36435         v_curr.ptr += 4;
36436       }
36437       v_curr.len = 0;
36438     }
36439   } else {
36440     {
36441       wuffs_base__slice_u8 i_slice_curr = a_curr;
36442       v_curr.ptr = i_slice_curr.ptr;
36443       wuffs_base__slice_u8 i_slice_prev = a_prev;
36444       v_prev.ptr = i_slice_prev.ptr;
36445       i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
36446       v_curr.len = 4;
36447       v_prev.len = 4;
36448       uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
36449       while (v_curr.ptr < i_end0_curr) {
36450         v_fa0 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa0)) + ((uint32_t)(v_prev.ptr[0]))) / 2))) + v_curr.ptr[0]));
36451         v_curr.ptr[0] = v_fa0;
36452         v_fa1 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa1)) + ((uint32_t)(v_prev.ptr[1]))) / 2))) + v_curr.ptr[1]));
36453         v_curr.ptr[1] = v_fa1;
36454         v_fa2 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa2)) + ((uint32_t)(v_prev.ptr[2]))) / 2))) + v_curr.ptr[2]));
36455         v_curr.ptr[2] = v_fa2;
36456         v_fa3 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa3)) + ((uint32_t)(v_prev.ptr[3]))) / 2))) + v_curr.ptr[3]));
36457         v_curr.ptr[3] = v_fa3;
36458         v_curr.ptr += 4;
36459         v_prev.ptr += 4;
36460       }
36461       v_curr.len = 0;
36462       v_prev.len = 0;
36463     }
36464   }
36465   return wuffs_base__make_empty_struct();
36466 }
36467 
36468 // -------- func png.decoder.filter_4
36469 
36470 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)36471 wuffs_png__decoder__filter_4(
36472     wuffs_png__decoder* self,
36473     wuffs_base__slice_u8 a_curr,
36474     wuffs_base__slice_u8 a_prev) {
36475   return (*self->private_impl.choosy_filter_4)(self, a_curr, a_prev);
36476 }
36477 
36478 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)36479 wuffs_png__decoder__filter_4__choosy_default(
36480     wuffs_png__decoder* self,
36481     wuffs_base__slice_u8 a_curr,
36482     wuffs_base__slice_u8 a_prev) {
36483   uint64_t v_filter_distance = 0;
36484   uint64_t v_n = 0;
36485   uint64_t v_i = 0;
36486   uint32_t v_fa = 0;
36487   uint32_t v_fb = 0;
36488   uint32_t v_fc = 0;
36489   uint32_t v_pp = 0;
36490   uint32_t v_pa = 0;
36491   uint32_t v_pb = 0;
36492   uint32_t v_pc = 0;
36493 
36494   v_filter_distance = ((uint64_t)(self->private_impl.f_filter_distance));
36495   v_n = wuffs_base__u64__min(((uint64_t)(a_curr.len)), ((uint64_t)(a_prev.len)));
36496   v_i = 0;
36497   while ((v_i < v_n) && (v_i < v_filter_distance)) {
36498     a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + a_prev.ptr[v_i]));
36499     v_i += 1;
36500   }
36501   v_i = v_filter_distance;
36502   while (v_i < v_n) {
36503     v_fa = ((uint32_t)(a_curr.ptr[(v_i - v_filter_distance)]));
36504     v_fb = ((uint32_t)(a_prev.ptr[v_i]));
36505     v_fc = ((uint32_t)(a_prev.ptr[(v_i - v_filter_distance)]));
36506     v_pp = ((uint32_t)(((uint32_t)(v_fa + v_fb)) - v_fc));
36507     v_pa = ((uint32_t)(v_pp - v_fa));
36508     if (v_pa >= 2147483648) {
36509       v_pa = ((uint32_t)(0 - v_pa));
36510     }
36511     v_pb = ((uint32_t)(v_pp - v_fb));
36512     if (v_pb >= 2147483648) {
36513       v_pb = ((uint32_t)(0 - v_pb));
36514     }
36515     v_pc = ((uint32_t)(v_pp - v_fc));
36516     if (v_pc >= 2147483648) {
36517       v_pc = ((uint32_t)(0 - v_pc));
36518     }
36519     if ((v_pa <= v_pb) && (v_pa <= v_pc)) {
36520     } else if (v_pb <= v_pc) {
36521       v_fa = v_fb;
36522     } else {
36523       v_fa = v_fc;
36524     }
36525     a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + ((uint8_t)((v_fa & 255)))));
36526     v_i += 1;
36527   }
36528   return wuffs_base__make_empty_struct();
36529 }
36530 
36531 // -------- func png.decoder.filter_4_distance_3_fallback
36532 
36533 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)36534 wuffs_png__decoder__filter_4_distance_3_fallback(
36535     wuffs_png__decoder* self,
36536     wuffs_base__slice_u8 a_curr,
36537     wuffs_base__slice_u8 a_prev) {
36538   wuffs_base__slice_u8 v_curr = {0};
36539   wuffs_base__slice_u8 v_prev = {0};
36540   uint32_t v_fa0 = 0;
36541   uint32_t v_fa1 = 0;
36542   uint32_t v_fa2 = 0;
36543   uint32_t v_fb0 = 0;
36544   uint32_t v_fb1 = 0;
36545   uint32_t v_fb2 = 0;
36546   uint32_t v_fc0 = 0;
36547   uint32_t v_fc1 = 0;
36548   uint32_t v_fc2 = 0;
36549   uint32_t v_pp0 = 0;
36550   uint32_t v_pp1 = 0;
36551   uint32_t v_pp2 = 0;
36552   uint32_t v_pa0 = 0;
36553   uint32_t v_pa1 = 0;
36554   uint32_t v_pa2 = 0;
36555   uint32_t v_pb0 = 0;
36556   uint32_t v_pb1 = 0;
36557   uint32_t v_pb2 = 0;
36558   uint32_t v_pc0 = 0;
36559   uint32_t v_pc1 = 0;
36560   uint32_t v_pc2 = 0;
36561 
36562   {
36563     wuffs_base__slice_u8 i_slice_curr = a_curr;
36564     v_curr.ptr = i_slice_curr.ptr;
36565     wuffs_base__slice_u8 i_slice_prev = a_prev;
36566     v_prev.ptr = i_slice_prev.ptr;
36567     i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
36568     v_curr.len = 3;
36569     v_prev.len = 3;
36570     uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3);
36571     while (v_curr.ptr < i_end0_curr) {
36572       v_fb0 = ((uint32_t)(v_prev.ptr[0]));
36573       v_pp0 = ((uint32_t)(((uint32_t)(v_fa0 + v_fb0)) - v_fc0));
36574       v_pa0 = ((uint32_t)(v_pp0 - v_fa0));
36575       if (v_pa0 >= 2147483648) {
36576         v_pa0 = ((uint32_t)(0 - v_pa0));
36577       }
36578       v_pb0 = ((uint32_t)(v_pp0 - v_fb0));
36579       if (v_pb0 >= 2147483648) {
36580         v_pb0 = ((uint32_t)(0 - v_pb0));
36581       }
36582       v_pc0 = ((uint32_t)(v_pp0 - v_fc0));
36583       if (v_pc0 >= 2147483648) {
36584         v_pc0 = ((uint32_t)(0 - v_pc0));
36585       }
36586       if ((v_pa0 <= v_pb0) && (v_pa0 <= v_pc0)) {
36587       } else if (v_pb0 <= v_pc0) {
36588         v_fa0 = v_fb0;
36589       } else {
36590         v_fa0 = v_fc0;
36591       }
36592       v_curr.ptr[0] = ((uint8_t)(v_curr.ptr[0] + ((uint8_t)((v_fa0 & 255)))));
36593       v_fa0 = ((uint32_t)(v_curr.ptr[0]));
36594       v_fc0 = v_fb0;
36595       v_fb1 = ((uint32_t)(v_prev.ptr[1]));
36596       v_pp1 = ((uint32_t)(((uint32_t)(v_fa1 + v_fb1)) - v_fc1));
36597       v_pa1 = ((uint32_t)(v_pp1 - v_fa1));
36598       if (v_pa1 >= 2147483648) {
36599         v_pa1 = ((uint32_t)(0 - v_pa1));
36600       }
36601       v_pb1 = ((uint32_t)(v_pp1 - v_fb1));
36602       if (v_pb1 >= 2147483648) {
36603         v_pb1 = ((uint32_t)(0 - v_pb1));
36604       }
36605       v_pc1 = ((uint32_t)(v_pp1 - v_fc1));
36606       if (v_pc1 >= 2147483648) {
36607         v_pc1 = ((uint32_t)(0 - v_pc1));
36608       }
36609       if ((v_pa1 <= v_pb1) && (v_pa1 <= v_pc1)) {
36610       } else if (v_pb1 <= v_pc1) {
36611         v_fa1 = v_fb1;
36612       } else {
36613         v_fa1 = v_fc1;
36614       }
36615       v_curr.ptr[1] = ((uint8_t)(v_curr.ptr[1] + ((uint8_t)((v_fa1 & 255)))));
36616       v_fa1 = ((uint32_t)(v_curr.ptr[1]));
36617       v_fc1 = v_fb1;
36618       v_fb2 = ((uint32_t)(v_prev.ptr[2]));
36619       v_pp2 = ((uint32_t)(((uint32_t)(v_fa2 + v_fb2)) - v_fc2));
36620       v_pa2 = ((uint32_t)(v_pp2 - v_fa2));
36621       if (v_pa2 >= 2147483648) {
36622         v_pa2 = ((uint32_t)(0 - v_pa2));
36623       }
36624       v_pb2 = ((uint32_t)(v_pp2 - v_fb2));
36625       if (v_pb2 >= 2147483648) {
36626         v_pb2 = ((uint32_t)(0 - v_pb2));
36627       }
36628       v_pc2 = ((uint32_t)(v_pp2 - v_fc2));
36629       if (v_pc2 >= 2147483648) {
36630         v_pc2 = ((uint32_t)(0 - v_pc2));
36631       }
36632       if ((v_pa2 <= v_pb2) && (v_pa2 <= v_pc2)) {
36633       } else if (v_pb2 <= v_pc2) {
36634         v_fa2 = v_fb2;
36635       } else {
36636         v_fa2 = v_fc2;
36637       }
36638       v_curr.ptr[2] = ((uint8_t)(v_curr.ptr[2] + ((uint8_t)((v_fa2 & 255)))));
36639       v_fa2 = ((uint32_t)(v_curr.ptr[2]));
36640       v_fc2 = v_fb2;
36641       v_curr.ptr += 3;
36642       v_prev.ptr += 3;
36643     }
36644     v_curr.len = 0;
36645     v_prev.len = 0;
36646   }
36647   return wuffs_base__make_empty_struct();
36648 }
36649 
36650 // -------- func png.decoder.filter_4_distance_4_fallback
36651 
36652 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)36653 wuffs_png__decoder__filter_4_distance_4_fallback(
36654     wuffs_png__decoder* self,
36655     wuffs_base__slice_u8 a_curr,
36656     wuffs_base__slice_u8 a_prev) {
36657   wuffs_base__slice_u8 v_curr = {0};
36658   wuffs_base__slice_u8 v_prev = {0};
36659   uint32_t v_fa0 = 0;
36660   uint32_t v_fa1 = 0;
36661   uint32_t v_fa2 = 0;
36662   uint32_t v_fa3 = 0;
36663   uint32_t v_fb0 = 0;
36664   uint32_t v_fb1 = 0;
36665   uint32_t v_fb2 = 0;
36666   uint32_t v_fb3 = 0;
36667   uint32_t v_fc0 = 0;
36668   uint32_t v_fc1 = 0;
36669   uint32_t v_fc2 = 0;
36670   uint32_t v_fc3 = 0;
36671   uint32_t v_pp0 = 0;
36672   uint32_t v_pp1 = 0;
36673   uint32_t v_pp2 = 0;
36674   uint32_t v_pp3 = 0;
36675   uint32_t v_pa0 = 0;
36676   uint32_t v_pa1 = 0;
36677   uint32_t v_pa2 = 0;
36678   uint32_t v_pa3 = 0;
36679   uint32_t v_pb0 = 0;
36680   uint32_t v_pb1 = 0;
36681   uint32_t v_pb2 = 0;
36682   uint32_t v_pb3 = 0;
36683   uint32_t v_pc0 = 0;
36684   uint32_t v_pc1 = 0;
36685   uint32_t v_pc2 = 0;
36686   uint32_t v_pc3 = 0;
36687 
36688   {
36689     wuffs_base__slice_u8 i_slice_curr = a_curr;
36690     v_curr.ptr = i_slice_curr.ptr;
36691     wuffs_base__slice_u8 i_slice_prev = a_prev;
36692     v_prev.ptr = i_slice_prev.ptr;
36693     i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
36694     v_curr.len = 4;
36695     v_prev.len = 4;
36696     uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
36697     while (v_curr.ptr < i_end0_curr) {
36698       v_fb0 = ((uint32_t)(v_prev.ptr[0]));
36699       v_pp0 = ((uint32_t)(((uint32_t)(v_fa0 + v_fb0)) - v_fc0));
36700       v_pa0 = ((uint32_t)(v_pp0 - v_fa0));
36701       if (v_pa0 >= 2147483648) {
36702         v_pa0 = ((uint32_t)(0 - v_pa0));
36703       }
36704       v_pb0 = ((uint32_t)(v_pp0 - v_fb0));
36705       if (v_pb0 >= 2147483648) {
36706         v_pb0 = ((uint32_t)(0 - v_pb0));
36707       }
36708       v_pc0 = ((uint32_t)(v_pp0 - v_fc0));
36709       if (v_pc0 >= 2147483648) {
36710         v_pc0 = ((uint32_t)(0 - v_pc0));
36711       }
36712       if ((v_pa0 <= v_pb0) && (v_pa0 <= v_pc0)) {
36713       } else if (v_pb0 <= v_pc0) {
36714         v_fa0 = v_fb0;
36715       } else {
36716         v_fa0 = v_fc0;
36717       }
36718       v_curr.ptr[0] = ((uint8_t)(v_curr.ptr[0] + ((uint8_t)((v_fa0 & 255)))));
36719       v_fa0 = ((uint32_t)(v_curr.ptr[0]));
36720       v_fc0 = v_fb0;
36721       v_fb1 = ((uint32_t)(v_prev.ptr[1]));
36722       v_pp1 = ((uint32_t)(((uint32_t)(v_fa1 + v_fb1)) - v_fc1));
36723       v_pa1 = ((uint32_t)(v_pp1 - v_fa1));
36724       if (v_pa1 >= 2147483648) {
36725         v_pa1 = ((uint32_t)(0 - v_pa1));
36726       }
36727       v_pb1 = ((uint32_t)(v_pp1 - v_fb1));
36728       if (v_pb1 >= 2147483648) {
36729         v_pb1 = ((uint32_t)(0 - v_pb1));
36730       }
36731       v_pc1 = ((uint32_t)(v_pp1 - v_fc1));
36732       if (v_pc1 >= 2147483648) {
36733         v_pc1 = ((uint32_t)(0 - v_pc1));
36734       }
36735       if ((v_pa1 <= v_pb1) && (v_pa1 <= v_pc1)) {
36736       } else if (v_pb1 <= v_pc1) {
36737         v_fa1 = v_fb1;
36738       } else {
36739         v_fa1 = v_fc1;
36740       }
36741       v_curr.ptr[1] = ((uint8_t)(v_curr.ptr[1] + ((uint8_t)((v_fa1 & 255)))));
36742       v_fa1 = ((uint32_t)(v_curr.ptr[1]));
36743       v_fc1 = v_fb1;
36744       v_fb2 = ((uint32_t)(v_prev.ptr[2]));
36745       v_pp2 = ((uint32_t)(((uint32_t)(v_fa2 + v_fb2)) - v_fc2));
36746       v_pa2 = ((uint32_t)(v_pp2 - v_fa2));
36747       if (v_pa2 >= 2147483648) {
36748         v_pa2 = ((uint32_t)(0 - v_pa2));
36749       }
36750       v_pb2 = ((uint32_t)(v_pp2 - v_fb2));
36751       if (v_pb2 >= 2147483648) {
36752         v_pb2 = ((uint32_t)(0 - v_pb2));
36753       }
36754       v_pc2 = ((uint32_t)(v_pp2 - v_fc2));
36755       if (v_pc2 >= 2147483648) {
36756         v_pc2 = ((uint32_t)(0 - v_pc2));
36757       }
36758       if ((v_pa2 <= v_pb2) && (v_pa2 <= v_pc2)) {
36759       } else if (v_pb2 <= v_pc2) {
36760         v_fa2 = v_fb2;
36761       } else {
36762         v_fa2 = v_fc2;
36763       }
36764       v_curr.ptr[2] = ((uint8_t)(v_curr.ptr[2] + ((uint8_t)((v_fa2 & 255)))));
36765       v_fa2 = ((uint32_t)(v_curr.ptr[2]));
36766       v_fc2 = v_fb2;
36767       v_fb3 = ((uint32_t)(v_prev.ptr[3]));
36768       v_pp3 = ((uint32_t)(((uint32_t)(v_fa3 + v_fb3)) - v_fc3));
36769       v_pa3 = ((uint32_t)(v_pp3 - v_fa3));
36770       if (v_pa3 >= 2147483648) {
36771         v_pa3 = ((uint32_t)(0 - v_pa3));
36772       }
36773       v_pb3 = ((uint32_t)(v_pp3 - v_fb3));
36774       if (v_pb3 >= 2147483648) {
36775         v_pb3 = ((uint32_t)(0 - v_pb3));
36776       }
36777       v_pc3 = ((uint32_t)(v_pp3 - v_fc3));
36778       if (v_pc3 >= 2147483648) {
36779         v_pc3 = ((uint32_t)(0 - v_pc3));
36780       }
36781       if ((v_pa3 <= v_pb3) && (v_pa3 <= v_pc3)) {
36782       } else if (v_pb3 <= v_pc3) {
36783         v_fa3 = v_fb3;
36784       } else {
36785         v_fa3 = v_fc3;
36786       }
36787       v_curr.ptr[3] = ((uint8_t)(v_curr.ptr[3] + ((uint8_t)((v_fa3 & 255)))));
36788       v_fa3 = ((uint32_t)(v_curr.ptr[3]));
36789       v_fc3 = v_fb3;
36790       v_curr.ptr += 4;
36791       v_prev.ptr += 4;
36792     }
36793     v_curr.len = 0;
36794     v_prev.len = 0;
36795   }
36796   return wuffs_base__make_empty_struct();
36797 }
36798 
36799 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
36800 // -------- func png.decoder.filter_1_distance_4_x86_sse42
36801 
36802 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
36803 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
36804 static wuffs_base__empty_struct
wuffs_png__decoder__filter_1_distance_4_x86_sse42(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr)36805 wuffs_png__decoder__filter_1_distance_4_x86_sse42(
36806     wuffs_png__decoder* self,
36807     wuffs_base__slice_u8 a_curr) {
36808   wuffs_base__slice_u8 v_curr = {0};
36809   __m128i v_x128 = {0};
36810   __m128i v_a128 = {0};
36811 
36812   {
36813     wuffs_base__slice_u8 i_slice_curr = a_curr;
36814     v_curr.ptr = i_slice_curr.ptr;
36815     v_curr.len = 4;
36816     uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
36817     while (v_curr.ptr < i_end0_curr) {
36818       v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36819       v_x128 = _mm_add_epi8(v_x128, v_a128);
36820       v_a128 = v_x128;
36821       wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
36822       v_curr.ptr += 4;
36823       v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36824       v_x128 = _mm_add_epi8(v_x128, v_a128);
36825       v_a128 = v_x128;
36826       wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
36827       v_curr.ptr += 4;
36828     }
36829     v_curr.len = 4;
36830     uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
36831     while (v_curr.ptr < i_end1_curr) {
36832       v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36833       v_x128 = _mm_add_epi8(v_x128, v_a128);
36834       v_a128 = v_x128;
36835       wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
36836       v_curr.ptr += 4;
36837     }
36838     v_curr.len = 0;
36839   }
36840   return wuffs_base__make_empty_struct();
36841 }
36842 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
36843 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
36844 
36845 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
36846 // -------- func png.decoder.filter_3_distance_4_x86_sse42
36847 
36848 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
36849 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
36850 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)36851 wuffs_png__decoder__filter_3_distance_4_x86_sse42(
36852     wuffs_png__decoder* self,
36853     wuffs_base__slice_u8 a_curr,
36854     wuffs_base__slice_u8 a_prev) {
36855   wuffs_base__slice_u8 v_curr = {0};
36856   wuffs_base__slice_u8 v_prev = {0};
36857   __m128i v_x128 = {0};
36858   __m128i v_a128 = {0};
36859   __m128i v_b128 = {0};
36860   __m128i v_p128 = {0};
36861   __m128i v_k128 = {0};
36862 
36863   if (((uint64_t)(a_prev.len)) == 0) {
36864     v_k128 = _mm_set1_epi8((int8_t)(254));
36865     {
36866       wuffs_base__slice_u8 i_slice_curr = a_curr;
36867       v_curr.ptr = i_slice_curr.ptr;
36868       v_curr.len = 4;
36869       uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
36870       while (v_curr.ptr < i_end0_curr) {
36871         v_p128 = _mm_avg_epu8(_mm_and_si128(v_a128, v_k128), v_b128);
36872         v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36873         v_x128 = _mm_add_epi8(v_x128, v_p128);
36874         v_a128 = v_x128;
36875         wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
36876         v_curr.ptr += 4;
36877         v_p128 = _mm_avg_epu8(_mm_and_si128(v_a128, v_k128), v_b128);
36878         v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36879         v_x128 = _mm_add_epi8(v_x128, v_p128);
36880         v_a128 = v_x128;
36881         wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
36882         v_curr.ptr += 4;
36883       }
36884       v_curr.len = 4;
36885       uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
36886       while (v_curr.ptr < i_end1_curr) {
36887         v_p128 = _mm_avg_epu8(_mm_and_si128(v_a128, v_k128), v_b128);
36888         v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36889         v_x128 = _mm_add_epi8(v_x128, v_p128);
36890         v_a128 = v_x128;
36891         wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
36892         v_curr.ptr += 4;
36893       }
36894       v_curr.len = 0;
36895     }
36896   } else {
36897     v_k128 = _mm_set1_epi8((int8_t)(1));
36898     {
36899       wuffs_base__slice_u8 i_slice_curr = a_curr;
36900       v_curr.ptr = i_slice_curr.ptr;
36901       wuffs_base__slice_u8 i_slice_prev = a_prev;
36902       v_prev.ptr = i_slice_prev.ptr;
36903       i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
36904       v_curr.len = 4;
36905       v_prev.len = 4;
36906       uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
36907       while (v_curr.ptr < i_end0_curr) {
36908         v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
36909         v_p128 = _mm_avg_epu8(v_a128, v_b128);
36910         v_p128 = _mm_sub_epi8(v_p128, _mm_and_si128(v_k128, _mm_xor_si128(v_a128, v_b128)));
36911         v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36912         v_x128 = _mm_add_epi8(v_x128, v_p128);
36913         v_a128 = v_x128;
36914         wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
36915         v_curr.ptr += 4;
36916         v_prev.ptr += 4;
36917         v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
36918         v_p128 = _mm_avg_epu8(v_a128, v_b128);
36919         v_p128 = _mm_sub_epi8(v_p128, _mm_and_si128(v_k128, _mm_xor_si128(v_a128, v_b128)));
36920         v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36921         v_x128 = _mm_add_epi8(v_x128, v_p128);
36922         v_a128 = v_x128;
36923         wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
36924         v_curr.ptr += 4;
36925         v_prev.ptr += 4;
36926       }
36927       v_curr.len = 4;
36928       v_prev.len = 4;
36929       uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
36930       while (v_curr.ptr < i_end1_curr) {
36931         v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
36932         v_p128 = _mm_avg_epu8(v_a128, v_b128);
36933         v_p128 = _mm_sub_epi8(v_p128, _mm_and_si128(v_k128, _mm_xor_si128(v_a128, v_b128)));
36934         v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36935         v_x128 = _mm_add_epi8(v_x128, v_p128);
36936         v_a128 = v_x128;
36937         wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
36938         v_curr.ptr += 4;
36939         v_prev.ptr += 4;
36940       }
36941       v_curr.len = 0;
36942       v_prev.len = 0;
36943     }
36944   }
36945   return wuffs_base__make_empty_struct();
36946 }
36947 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
36948 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
36949 
36950 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
36951 // -------- func png.decoder.filter_4_distance_3_x86_sse42
36952 
36953 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
36954 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
36955 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)36956 wuffs_png__decoder__filter_4_distance_3_x86_sse42(
36957     wuffs_png__decoder* self,
36958     wuffs_base__slice_u8 a_curr,
36959     wuffs_base__slice_u8 a_prev) {
36960   wuffs_base__slice_u8 v_curr = {0};
36961   wuffs_base__slice_u8 v_prev = {0};
36962   __m128i v_x128 = {0};
36963   __m128i v_a128 = {0};
36964   __m128i v_b128 = {0};
36965   __m128i v_c128 = {0};
36966   __m128i v_p128 = {0};
36967   __m128i v_pa128 = {0};
36968   __m128i v_pb128 = {0};
36969   __m128i v_pc128 = {0};
36970   __m128i v_smallest128 = {0};
36971   __m128i v_z128 = {0};
36972 
36973   {
36974     wuffs_base__slice_u8 i_slice_curr = a_curr;
36975     v_curr.ptr = i_slice_curr.ptr;
36976     wuffs_base__slice_u8 i_slice_prev = a_prev;
36977     v_prev.ptr = i_slice_prev.ptr;
36978     i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
36979     v_curr.len = 4;
36980     v_prev.len = 4;
36981     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);
36982     while (v_curr.ptr < i_end0_curr) {
36983       v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
36984       v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
36985       v_pa128 = _mm_sub_epi16(v_b128, v_c128);
36986       v_pb128 = _mm_sub_epi16(v_a128, v_c128);
36987       v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
36988       v_pa128 = _mm_abs_epi16(v_pa128);
36989       v_pb128 = _mm_abs_epi16(v_pb128);
36990       v_pc128 = _mm_abs_epi16(v_pc128);
36991       v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
36992       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));
36993       v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36994       v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
36995       v_x128 = _mm_add_epi8(v_x128, v_p128);
36996       v_a128 = v_x128;
36997       v_c128 = v_b128;
36998       v_x128 = _mm_packus_epi16(v_x128, v_x128);
36999       wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37000       v_curr.ptr += 3;
37001       v_prev.ptr += 3;
37002       v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
37003       v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
37004       v_pa128 = _mm_sub_epi16(v_b128, v_c128);
37005       v_pb128 = _mm_sub_epi16(v_a128, v_c128);
37006       v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
37007       v_pa128 = _mm_abs_epi16(v_pa128);
37008       v_pb128 = _mm_abs_epi16(v_pb128);
37009       v_pc128 = _mm_abs_epi16(v_pc128);
37010       v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
37011       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));
37012       v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
37013       v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
37014       v_x128 = _mm_add_epi8(v_x128, v_p128);
37015       v_a128 = v_x128;
37016       v_c128 = v_b128;
37017       v_x128 = _mm_packus_epi16(v_x128, v_x128);
37018       wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37019       v_curr.ptr += 3;
37020       v_prev.ptr += 3;
37021     }
37022     v_curr.len = 4;
37023     v_prev.len = 4;
37024     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);
37025     while (v_curr.ptr < i_end1_curr) {
37026       v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
37027       v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
37028       v_pa128 = _mm_sub_epi16(v_b128, v_c128);
37029       v_pb128 = _mm_sub_epi16(v_a128, v_c128);
37030       v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
37031       v_pa128 = _mm_abs_epi16(v_pa128);
37032       v_pb128 = _mm_abs_epi16(v_pb128);
37033       v_pc128 = _mm_abs_epi16(v_pc128);
37034       v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
37035       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));
37036       v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
37037       v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
37038       v_x128 = _mm_add_epi8(v_x128, v_p128);
37039       v_a128 = v_x128;
37040       v_c128 = v_b128;
37041       v_x128 = _mm_packus_epi16(v_x128, v_x128);
37042       wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37043       v_curr.ptr += 3;
37044       v_prev.ptr += 3;
37045     }
37046     v_curr.len = 3;
37047     v_prev.len = 3;
37048     uint8_t* i_end2_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3);
37049     while (v_curr.ptr < i_end2_curr) {
37050       v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u24le__no_bounds_check(v_prev.ptr)));
37051       v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
37052       v_pa128 = _mm_sub_epi16(v_b128, v_c128);
37053       v_pb128 = _mm_sub_epi16(v_a128, v_c128);
37054       v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
37055       v_pa128 = _mm_abs_epi16(v_pa128);
37056       v_pb128 = _mm_abs_epi16(v_pb128);
37057       v_pc128 = _mm_abs_epi16(v_pc128);
37058       v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
37059       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));
37060       v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u24le__no_bounds_check(v_curr.ptr)));
37061       v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
37062       v_x128 = _mm_add_epi8(v_x128, v_p128);
37063       v_x128 = _mm_packus_epi16(v_x128, v_x128);
37064       wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37065       v_curr.ptr += 3;
37066       v_prev.ptr += 3;
37067     }
37068     v_curr.len = 0;
37069     v_prev.len = 0;
37070   }
37071   return wuffs_base__make_empty_struct();
37072 }
37073 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
37074 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
37075 
37076 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
37077 // -------- func png.decoder.filter_4_distance_4_x86_sse42
37078 
37079 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
37080 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
37081 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)37082 wuffs_png__decoder__filter_4_distance_4_x86_sse42(
37083     wuffs_png__decoder* self,
37084     wuffs_base__slice_u8 a_curr,
37085     wuffs_base__slice_u8 a_prev) {
37086   wuffs_base__slice_u8 v_curr = {0};
37087   wuffs_base__slice_u8 v_prev = {0};
37088   __m128i v_x128 = {0};
37089   __m128i v_a128 = {0};
37090   __m128i v_b128 = {0};
37091   __m128i v_c128 = {0};
37092   __m128i v_p128 = {0};
37093   __m128i v_pa128 = {0};
37094   __m128i v_pb128 = {0};
37095   __m128i v_pc128 = {0};
37096   __m128i v_smallest128 = {0};
37097   __m128i v_z128 = {0};
37098 
37099   {
37100     wuffs_base__slice_u8 i_slice_curr = a_curr;
37101     v_curr.ptr = i_slice_curr.ptr;
37102     wuffs_base__slice_u8 i_slice_prev = a_prev;
37103     v_prev.ptr = i_slice_prev.ptr;
37104     i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
37105     v_curr.len = 4;
37106     v_prev.len = 4;
37107     uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
37108     while (v_curr.ptr < i_end0_curr) {
37109       v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
37110       v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
37111       v_pa128 = _mm_sub_epi16(v_b128, v_c128);
37112       v_pb128 = _mm_sub_epi16(v_a128, v_c128);
37113       v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
37114       v_pa128 = _mm_abs_epi16(v_pa128);
37115       v_pb128 = _mm_abs_epi16(v_pb128);
37116       v_pc128 = _mm_abs_epi16(v_pc128);
37117       v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
37118       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));
37119       v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
37120       v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
37121       v_x128 = _mm_add_epi8(v_x128, v_p128);
37122       v_a128 = v_x128;
37123       v_c128 = v_b128;
37124       v_x128 = _mm_packus_epi16(v_x128, v_x128);
37125       wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37126       v_curr.ptr += 4;
37127       v_prev.ptr += 4;
37128       v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
37129       v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
37130       v_pa128 = _mm_sub_epi16(v_b128, v_c128);
37131       v_pb128 = _mm_sub_epi16(v_a128, v_c128);
37132       v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
37133       v_pa128 = _mm_abs_epi16(v_pa128);
37134       v_pb128 = _mm_abs_epi16(v_pb128);
37135       v_pc128 = _mm_abs_epi16(v_pc128);
37136       v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
37137       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));
37138       v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
37139       v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
37140       v_x128 = _mm_add_epi8(v_x128, v_p128);
37141       v_a128 = v_x128;
37142       v_c128 = v_b128;
37143       v_x128 = _mm_packus_epi16(v_x128, v_x128);
37144       wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37145       v_curr.ptr += 4;
37146       v_prev.ptr += 4;
37147     }
37148     v_curr.len = 4;
37149     v_prev.len = 4;
37150     uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
37151     while (v_curr.ptr < i_end1_curr) {
37152       v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
37153       v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
37154       v_pa128 = _mm_sub_epi16(v_b128, v_c128);
37155       v_pb128 = _mm_sub_epi16(v_a128, v_c128);
37156       v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
37157       v_pa128 = _mm_abs_epi16(v_pa128);
37158       v_pb128 = _mm_abs_epi16(v_pb128);
37159       v_pc128 = _mm_abs_epi16(v_pc128);
37160       v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
37161       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));
37162       v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
37163       v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
37164       v_x128 = _mm_add_epi8(v_x128, v_p128);
37165       v_a128 = v_x128;
37166       v_c128 = v_b128;
37167       v_x128 = _mm_packus_epi16(v_x128, v_x128);
37168       wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37169       v_curr.ptr += 4;
37170       v_prev.ptr += 4;
37171     }
37172     v_curr.len = 0;
37173     v_prev.len = 0;
37174   }
37175   return wuffs_base__make_empty_struct();
37176 }
37177 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
37178 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
37179 
37180 // -------- func png.decoder.set_quirk_enabled
37181 
37182 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_png__decoder__set_quirk_enabled(wuffs_png__decoder * self,uint32_t a_quirk,bool a_enabled)37183 wuffs_png__decoder__set_quirk_enabled(
37184     wuffs_png__decoder* self,
37185     uint32_t a_quirk,
37186     bool a_enabled) {
37187   if (!self) {
37188     return wuffs_base__make_empty_struct();
37189   }
37190   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
37191     return wuffs_base__make_empty_struct();
37192   }
37193 
37194   if (a_quirk == 1) {
37195     self->private_impl.f_ignore_checksum = a_enabled;
37196     wuffs_zlib__decoder__set_quirk_enabled(&self->private_data.f_zlib, a_quirk, a_enabled);
37197   }
37198   return wuffs_base__make_empty_struct();
37199 }
37200 
37201 // -------- func png.decoder.decode_image_config
37202 
37203 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)37204 wuffs_png__decoder__decode_image_config(
37205     wuffs_png__decoder* self,
37206     wuffs_base__image_config* a_dst,
37207     wuffs_base__io_buffer* a_src) {
37208   if (!self) {
37209     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
37210   }
37211   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
37212     return wuffs_base__make_status(
37213         (self->private_impl.magic == WUFFS_BASE__DISABLED)
37214         ? wuffs_base__error__disabled_by_previous_error
37215         : wuffs_base__error__initialize_not_called);
37216   }
37217   if (!a_src) {
37218     self->private_impl.magic = WUFFS_BASE__DISABLED;
37219     return wuffs_base__make_status(wuffs_base__error__bad_argument);
37220   }
37221   if ((self->private_impl.active_coroutine != 0) &&
37222       (self->private_impl.active_coroutine != 1)) {
37223     self->private_impl.magic = WUFFS_BASE__DISABLED;
37224     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
37225   }
37226   self->private_impl.active_coroutine = 0;
37227   wuffs_base__status status = wuffs_base__make_status(NULL);
37228 
37229   uint64_t v_magic = 0;
37230   uint64_t v_mark = 0;
37231   uint32_t v_checksum_have = 0;
37232   uint32_t v_checksum_want = 0;
37233   wuffs_base__status v_status = wuffs_base__make_status(NULL);
37234 
37235   const uint8_t* iop_a_src = NULL;
37236   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
37237   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
37238   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
37239   if (a_src) {
37240     io0_a_src = a_src->data.ptr;
37241     io1_a_src = io0_a_src + a_src->meta.ri;
37242     iop_a_src = io1_a_src;
37243     io2_a_src = io0_a_src + a_src->meta.wi;
37244   }
37245 
37246   uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
37247   if (coro_susp_point) {
37248     v_checksum_have = self->private_data.s_decode_image_config[0].v_checksum_have;
37249   }
37250   switch (coro_susp_point) {
37251     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
37252 
37253     if (self->private_impl.f_call_sequence == 2) {
37254       if (self->private_impl.f_metadata_fourcc != 0) {
37255         self->private_impl.f_call_sequence = 1;
37256         status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
37257         goto ok;
37258       }
37259     } else if (self->private_impl.f_call_sequence != 0) {
37260       status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
37261       goto exit;
37262     } else {
37263       {
37264         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
37265         uint64_t t_0;
37266         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 8)) {
37267           t_0 = wuffs_base__peek_u64le__no_bounds_check(iop_a_src);
37268           iop_a_src += 8;
37269         } else {
37270           self->private_data.s_decode_image_config[0].scratch = 0;
37271           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
37272           while (true) {
37273             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
37274               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
37275               goto suspend;
37276             }
37277             uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
37278             uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
37279             *scratch <<= 8;
37280             *scratch >>= 8;
37281             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
37282             if (num_bits_0 == 56) {
37283               t_0 = ((uint64_t)(*scratch));
37284               break;
37285             }
37286             num_bits_0 += 8;
37287             *scratch |= ((uint64_t)(num_bits_0)) << 56;
37288           }
37289         }
37290         v_magic = t_0;
37291       }
37292       if (v_magic != 727905341920923785) {
37293         status = wuffs_base__make_status(wuffs_png__error__bad_header);
37294         goto exit;
37295       }
37296       {
37297         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
37298         uint64_t t_1;
37299         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 8)) {
37300           t_1 = wuffs_base__peek_u64le__no_bounds_check(iop_a_src);
37301           iop_a_src += 8;
37302         } else {
37303           self->private_data.s_decode_image_config[0].scratch = 0;
37304           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
37305           while (true) {
37306             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
37307               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
37308               goto suspend;
37309             }
37310             uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
37311             uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
37312             *scratch <<= 8;
37313             *scratch >>= 8;
37314             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
37315             if (num_bits_1 == 56) {
37316               t_1 = ((uint64_t)(*scratch));
37317               break;
37318             }
37319             num_bits_1 += 8;
37320             *scratch |= ((uint64_t)(num_bits_1)) << 56;
37321           }
37322         }
37323         v_magic = t_1;
37324       }
37325       if (v_magic != 5927942488114331648) {
37326         status = wuffs_base__make_status(wuffs_png__error__bad_header);
37327         goto exit;
37328       }
37329       self->private_impl.f_chunk_type_array[0] = 73;
37330       self->private_impl.f_chunk_type_array[1] = 72;
37331       self->private_impl.f_chunk_type_array[2] = 68;
37332       self->private_impl.f_chunk_type_array[3] = 82;
37333       wuffs_base__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32,
37334           sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
37335       wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__make_slice_u8(self->private_impl.f_chunk_type_array, 4));
37336       while (true) {
37337         v_mark = ((uint64_t)(iop_a_src - io0_a_src));
37338         {
37339           if (a_src) {
37340             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
37341           }
37342           wuffs_base__status t_2 = wuffs_png__decoder__decode_ihdr(self, a_src);
37343           v_status = t_2;
37344           if (a_src) {
37345             iop_a_src = a_src->data.ptr + a_src->meta.ri;
37346           }
37347         }
37348         if ( ! self->private_impl.f_ignore_checksum) {
37349           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));
37350         }
37351         if (wuffs_base__status__is_ok(&v_status)) {
37352           goto label__0__break;
37353         }
37354         status = v_status;
37355         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
37356       }
37357       label__0__break:;
37358       {
37359         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
37360         uint32_t t_3;
37361         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
37362           t_3 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
37363           iop_a_src += 4;
37364         } else {
37365           self->private_data.s_decode_image_config[0].scratch = 0;
37366           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
37367           while (true) {
37368             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
37369               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
37370               goto suspend;
37371             }
37372             uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
37373             uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFF));
37374             *scratch >>= 8;
37375             *scratch <<= 8;
37376             *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3);
37377             if (num_bits_3 == 24) {
37378               t_3 = ((uint32_t)(*scratch >> 32));
37379               break;
37380             }
37381             num_bits_3 += 8;
37382             *scratch |= ((uint64_t)(num_bits_3));
37383           }
37384         }
37385         v_checksum_want = t_3;
37386       }
37387       if ( ! self->private_impl.f_ignore_checksum && (v_checksum_have != v_checksum_want)) {
37388         status = wuffs_base__make_status(wuffs_png__error__bad_checksum);
37389         goto exit;
37390       }
37391     }
37392     while (true) {
37393       while (((uint64_t)(io2_a_src - iop_a_src)) < 8) {
37394         if (a_src && a_src->meta.closed) {
37395           status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
37396           goto exit;
37397         }
37398         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
37399         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8);
37400       }
37401       self->private_impl.f_chunk_length = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
37402       self->private_impl.f_chunk_type = ((uint32_t)((wuffs_base__peek_u64le__no_bounds_check(iop_a_src) >> 32)));
37403       if (self->private_impl.f_chunk_type == 1413563465) {
37404         if ( ! self->private_impl.f_seen_actl || self->private_impl.f_seen_fctl) {
37405           goto label__1__break;
37406         }
37407         self->private_impl.f_seen_idat = true;
37408       } else if (self->private_impl.f_chunk_type == 1413571686) {
37409         if (self->private_impl.f_seen_idat && self->private_impl.f_seen_fctl) {
37410           goto label__1__break;
37411         }
37412         status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
37413         goto exit;
37414       }
37415       iop_a_src += 8;
37416       if ( ! self->private_impl.f_ignore_checksum && ((self->private_impl.f_chunk_type & 32) == 0)) {
37417         self->private_impl.f_chunk_type_array[0] = ((uint8_t)(((self->private_impl.f_chunk_type >> 0) & 255)));
37418         self->private_impl.f_chunk_type_array[1] = ((uint8_t)(((self->private_impl.f_chunk_type >> 8) & 255)));
37419         self->private_impl.f_chunk_type_array[2] = ((uint8_t)(((self->private_impl.f_chunk_type >> 16) & 255)));
37420         self->private_impl.f_chunk_type_array[3] = ((uint8_t)(((self->private_impl.f_chunk_type >> 24) & 255)));
37421         wuffs_base__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32,
37422             sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
37423         wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__make_slice_u8(self->private_impl.f_chunk_type_array, 4));
37424       }
37425       while (true) {
37426         v_mark = ((uint64_t)(iop_a_src - io0_a_src));
37427         {
37428           if (a_src) {
37429             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
37430           }
37431           wuffs_base__status t_4 = wuffs_png__decoder__decode_other_chunk(self, a_src);
37432           v_status = t_4;
37433           if (a_src) {
37434             iop_a_src = a_src->data.ptr + a_src->meta.ri;
37435           }
37436         }
37437         if ( ! self->private_impl.f_ignore_checksum && ((self->private_impl.f_chunk_type & 32) == 0)) {
37438           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));
37439         }
37440         if (wuffs_base__status__is_ok(&v_status)) {
37441           goto label__2__break;
37442         }
37443         status = v_status;
37444         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9);
37445       }
37446       label__2__break:;
37447       if (self->private_impl.f_metadata_fourcc != 0) {
37448         self->private_impl.f_call_sequence = 1;
37449         status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
37450         goto ok;
37451       }
37452       {
37453         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
37454         uint32_t t_5;
37455         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
37456           t_5 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
37457           iop_a_src += 4;
37458         } else {
37459           self->private_data.s_decode_image_config[0].scratch = 0;
37460           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
37461           while (true) {
37462             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
37463               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
37464               goto suspend;
37465             }
37466             uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
37467             uint32_t num_bits_5 = ((uint32_t)(*scratch & 0xFF));
37468             *scratch >>= 8;
37469             *scratch <<= 8;
37470             *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_5);
37471             if (num_bits_5 == 24) {
37472               t_5 = ((uint32_t)(*scratch >> 32));
37473               break;
37474             }
37475             num_bits_5 += 8;
37476             *scratch |= ((uint64_t)(num_bits_5));
37477           }
37478         }
37479         v_checksum_want = t_5;
37480       }
37481       if ( ! self->private_impl.f_ignore_checksum && ((self->private_impl.f_chunk_type & 32) == 0) && (v_checksum_have != v_checksum_want)) {
37482         status = wuffs_base__make_status(wuffs_png__error__bad_checksum);
37483         goto exit;
37484       }
37485     }
37486     label__1__break:;
37487     if ((self->private_impl.f_color_type == 3) &&  ! self->private_impl.f_seen_plte) {
37488       status = wuffs_base__make_status(wuffs_png__error__missing_palette);
37489       goto exit;
37490     }
37491     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)));
37492     self->private_impl.f_first_config_io_position = self->private_impl.f_frame_config_io_position;
37493     if (a_dst != NULL) {
37494       wuffs_base__image_config__set(
37495           a_dst,
37496           self->private_impl.f_dst_pixfmt,
37497           0,
37498           self->private_impl.f_width,
37499           self->private_impl.f_height,
37500           self->private_impl.f_first_config_io_position,
37501           ((self->private_impl.f_color_type <= 3) &&  ! self->private_impl.f_seen_trns));
37502     }
37503     if ( ! self->private_impl.f_seen_actl) {
37504       self->private_impl.f_num_animation_frames_value = 1;
37505       self->private_impl.f_first_rect_x0 = 0;
37506       self->private_impl.f_first_rect_y0 = 0;
37507       self->private_impl.f_first_rect_x1 = self->private_impl.f_width;
37508       self->private_impl.f_first_rect_y1 = self->private_impl.f_height;
37509       self->private_impl.f_first_duration = 0;
37510       self->private_impl.f_first_disposal = 0;
37511       self->private_impl.f_first_overwrite_instead_of_blend = false;
37512     }
37513     self->private_impl.f_call_sequence = 3;
37514 
37515     ok:
37516     self->private_impl.p_decode_image_config[0] = 0;
37517     goto exit;
37518   }
37519 
37520   goto suspend;
37521   suspend:
37522   self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
37523   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
37524   self->private_data.s_decode_image_config[0].v_checksum_have = v_checksum_have;
37525 
37526   goto exit;
37527   exit:
37528   if (a_src) {
37529     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
37530   }
37531 
37532   if (wuffs_base__status__is_error(&status)) {
37533     self->private_impl.magic = WUFFS_BASE__DISABLED;
37534   }
37535   return status;
37536 }
37537 
37538 // -------- func png.decoder.decode_ihdr
37539 
37540 static wuffs_base__status
wuffs_png__decoder__decode_ihdr(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)37541 wuffs_png__decoder__decode_ihdr(
37542     wuffs_png__decoder* self,
37543     wuffs_base__io_buffer* a_src) {
37544   wuffs_base__status status = wuffs_base__make_status(NULL);
37545 
37546   uint32_t v_a32 = 0;
37547   uint8_t v_a8 = 0;
37548 
37549   const uint8_t* iop_a_src = NULL;
37550   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
37551   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
37552   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
37553   if (a_src) {
37554     io0_a_src = a_src->data.ptr;
37555     io1_a_src = io0_a_src + a_src->meta.ri;
37556     iop_a_src = io1_a_src;
37557     io2_a_src = io0_a_src + a_src->meta.wi;
37558   }
37559 
37560   uint32_t coro_susp_point = self->private_impl.p_decode_ihdr[0];
37561   switch (coro_susp_point) {
37562     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
37563 
37564     {
37565       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
37566       uint32_t t_0;
37567       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
37568         t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
37569         iop_a_src += 4;
37570       } else {
37571         self->private_data.s_decode_ihdr[0].scratch = 0;
37572         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
37573         while (true) {
37574           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
37575             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
37576             goto suspend;
37577           }
37578           uint64_t* scratch = &self->private_data.s_decode_ihdr[0].scratch;
37579           uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFF));
37580           *scratch >>= 8;
37581           *scratch <<= 8;
37582           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
37583           if (num_bits_0 == 24) {
37584             t_0 = ((uint32_t)(*scratch >> 32));
37585             break;
37586           }
37587           num_bits_0 += 8;
37588           *scratch |= ((uint64_t)(num_bits_0));
37589         }
37590       }
37591       v_a32 = t_0;
37592     }
37593     if ((v_a32 == 0) || (v_a32 >= 2147483648)) {
37594       status = wuffs_base__make_status(wuffs_png__error__bad_header);
37595       goto exit;
37596     } else if (v_a32 >= 16777216) {
37597       status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file);
37598       goto exit;
37599     }
37600     self->private_impl.f_width = v_a32;
37601     {
37602       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
37603       uint32_t t_1;
37604       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
37605         t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
37606         iop_a_src += 4;
37607       } else {
37608         self->private_data.s_decode_ihdr[0].scratch = 0;
37609         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
37610         while (true) {
37611           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
37612             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
37613             goto suspend;
37614           }
37615           uint64_t* scratch = &self->private_data.s_decode_ihdr[0].scratch;
37616           uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFF));
37617           *scratch >>= 8;
37618           *scratch <<= 8;
37619           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
37620           if (num_bits_1 == 24) {
37621             t_1 = ((uint32_t)(*scratch >> 32));
37622             break;
37623           }
37624           num_bits_1 += 8;
37625           *scratch |= ((uint64_t)(num_bits_1));
37626         }
37627       }
37628       v_a32 = t_1;
37629     }
37630     if ((v_a32 == 0) || (v_a32 >= 2147483648)) {
37631       status = wuffs_base__make_status(wuffs_png__error__bad_header);
37632       goto exit;
37633     } else if (v_a32 >= 16777216) {
37634       status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file);
37635       goto exit;
37636     }
37637     self->private_impl.f_height = v_a32;
37638     {
37639       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
37640       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
37641         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
37642         goto suspend;
37643       }
37644       uint8_t t_2 = *iop_a_src++;
37645       v_a8 = t_2;
37646     }
37647     if (v_a8 > 16) {
37648       status = wuffs_base__make_status(wuffs_png__error__bad_header);
37649       goto exit;
37650     }
37651     self->private_impl.f_depth = v_a8;
37652     {
37653       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
37654       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
37655         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
37656         goto suspend;
37657       }
37658       uint8_t t_3 = *iop_a_src++;
37659       v_a8 = t_3;
37660     }
37661     if ((v_a8 == 1) || (v_a8 == 5) || (v_a8 > 6)) {
37662       status = wuffs_base__make_status(wuffs_png__error__bad_header);
37663       goto exit;
37664     }
37665     self->private_impl.f_color_type = v_a8;
37666     {
37667       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
37668       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
37669         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
37670         goto suspend;
37671       }
37672       uint8_t t_4 = *iop_a_src++;
37673       v_a8 = t_4;
37674     }
37675     if (v_a8 != 0) {
37676       status = wuffs_base__make_status(wuffs_png__error__unsupported_png_compression_method);
37677       goto exit;
37678     }
37679     {
37680       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
37681       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
37682         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
37683         goto suspend;
37684       }
37685       uint8_t t_5 = *iop_a_src++;
37686       v_a8 = t_5;
37687     }
37688     if (v_a8 != 0) {
37689       status = wuffs_base__make_status(wuffs_png__error__bad_header);
37690       goto exit;
37691     }
37692     {
37693       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
37694       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
37695         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
37696         goto suspend;
37697       }
37698       uint8_t t_6 = *iop_a_src++;
37699       v_a8 = t_6;
37700     }
37701     if (v_a8 == 0) {
37702       self->private_impl.f_interlace_pass = 0;
37703     } else if (v_a8 == 1) {
37704       self->private_impl.f_interlace_pass = 1;
37705       self->private_impl.choosy_filter_and_swizzle = (
37706           &wuffs_png__decoder__filter_and_swizzle_tricky);
37707     } else {
37708       status = wuffs_base__make_status(wuffs_png__error__bad_header);
37709       goto exit;
37710     }
37711     self->private_impl.f_filter_distance = 0;
37712     wuffs_png__decoder__assign_filter_distance(self);
37713     if (self->private_impl.f_filter_distance == 0) {
37714       status = wuffs_base__make_status(wuffs_png__error__bad_header);
37715       goto exit;
37716     }
37717     self->private_impl.f_overall_workbuf_length = (((uint64_t)(self->private_impl.f_height)) * (1 + wuffs_png__decoder__calculate_bytes_per_row(self, self->private_impl.f_width)));
37718     wuffs_png__decoder__choose_filter_implementations(self);
37719 
37720     goto ok;
37721     ok:
37722     self->private_impl.p_decode_ihdr[0] = 0;
37723     goto exit;
37724   }
37725 
37726   goto suspend;
37727   suspend:
37728   self->private_impl.p_decode_ihdr[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
37729 
37730   goto exit;
37731   exit:
37732   if (a_src) {
37733     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
37734   }
37735 
37736   return status;
37737 }
37738 
37739 // -------- func png.decoder.assign_filter_distance
37740 
37741 static wuffs_base__empty_struct
wuffs_png__decoder__assign_filter_distance(wuffs_png__decoder * self)37742 wuffs_png__decoder__assign_filter_distance(
37743     wuffs_png__decoder* self) {
37744   if (self->private_impl.f_depth < 8) {
37745     if ((self->private_impl.f_depth != 1) && (self->private_impl.f_depth != 2) && (self->private_impl.f_depth != 4)) {
37746       return wuffs_base__make_empty_struct();
37747     } else if (self->private_impl.f_color_type == 0) {
37748       self->private_impl.f_dst_pixfmt = 536870920;
37749       self->private_impl.f_src_pixfmt = 536870920;
37750     } else if (self->private_impl.f_color_type == 3) {
37751       self->private_impl.f_dst_pixfmt = 2198077448;
37752       self->private_impl.f_src_pixfmt = 2198077448;
37753     } else {
37754       return wuffs_base__make_empty_struct();
37755     }
37756     self->private_impl.f_filter_distance = 1;
37757     self->private_impl.choosy_filter_and_swizzle = (
37758         &wuffs_png__decoder__filter_and_swizzle_tricky);
37759   } else if (self->private_impl.f_color_type == 0) {
37760     if (self->private_impl.f_depth == 8) {
37761       self->private_impl.f_dst_pixfmt = 536870920;
37762       self->private_impl.f_src_pixfmt = 536870920;
37763       self->private_impl.f_filter_distance = 1;
37764     } else if (self->private_impl.f_depth == 16) {
37765       self->private_impl.f_dst_pixfmt = 536870923;
37766       self->private_impl.f_src_pixfmt = 537919499;
37767       self->private_impl.f_filter_distance = 2;
37768     }
37769   } else if (self->private_impl.f_color_type == 2) {
37770     if (self->private_impl.f_depth == 8) {
37771       self->private_impl.f_dst_pixfmt = 2147485832;
37772       self->private_impl.f_src_pixfmt = 2684356744;
37773       self->private_impl.f_filter_distance = 3;
37774     } else if (self->private_impl.f_depth == 16) {
37775       self->private_impl.f_dst_pixfmt = 2164308923;
37776       self->private_impl.f_src_pixfmt = 2164308923;
37777       self->private_impl.f_filter_distance = 6;
37778       self->private_impl.choosy_filter_and_swizzle = (
37779           &wuffs_png__decoder__filter_and_swizzle_tricky);
37780     }
37781   } else if (self->private_impl.f_color_type == 3) {
37782     if (self->private_impl.f_depth == 8) {
37783       self->private_impl.f_dst_pixfmt = 2198077448;
37784       self->private_impl.f_src_pixfmt = 2198077448;
37785       self->private_impl.f_filter_distance = 1;
37786     }
37787   } else if (self->private_impl.f_color_type == 4) {
37788     if (self->private_impl.f_depth == 8) {
37789       self->private_impl.f_dst_pixfmt = 2164295816;
37790       self->private_impl.f_src_pixfmt = 2164295816;
37791       self->private_impl.f_filter_distance = 2;
37792       self->private_impl.choosy_filter_and_swizzle = (
37793           &wuffs_png__decoder__filter_and_swizzle_tricky);
37794     } else if (self->private_impl.f_depth == 16) {
37795       self->private_impl.f_dst_pixfmt = 2164308923;
37796       self->private_impl.f_src_pixfmt = 2164308923;
37797       self->private_impl.f_filter_distance = 4;
37798       self->private_impl.choosy_filter_and_swizzle = (
37799           &wuffs_png__decoder__filter_and_swizzle_tricky);
37800     }
37801   } else if (self->private_impl.f_color_type == 6) {
37802     if (self->private_impl.f_depth == 8) {
37803       self->private_impl.f_dst_pixfmt = 2164295816;
37804       self->private_impl.f_src_pixfmt = 2701166728;
37805       self->private_impl.f_filter_distance = 4;
37806     } else if (self->private_impl.f_depth == 16) {
37807       self->private_impl.f_dst_pixfmt = 2164308923;
37808       self->private_impl.f_src_pixfmt = 2164308923;
37809       self->private_impl.f_filter_distance = 8;
37810       self->private_impl.choosy_filter_and_swizzle = (
37811           &wuffs_png__decoder__filter_and_swizzle_tricky);
37812     }
37813   }
37814   return wuffs_base__make_empty_struct();
37815 }
37816 
37817 // -------- func png.decoder.calculate_bytes_per_row
37818 
37819 static uint64_t
wuffs_png__decoder__calculate_bytes_per_row(const wuffs_png__decoder * self,uint32_t a_width)37820 wuffs_png__decoder__calculate_bytes_per_row(
37821     const wuffs_png__decoder* self,
37822     uint32_t a_width) {
37823   uint64_t v_bytes_per_channel = 0;
37824 
37825   if (self->private_impl.f_depth == 1) {
37826     return ((uint64_t)(((a_width + 7) / 8)));
37827   } else if (self->private_impl.f_depth == 2) {
37828     return ((uint64_t)(((a_width + 3) / 4)));
37829   } else if (self->private_impl.f_depth == 4) {
37830     return ((uint64_t)(((a_width + 1) / 2)));
37831   }
37832   v_bytes_per_channel = ((uint64_t)((self->private_impl.f_depth >> 3)));
37833   return (((uint64_t)(a_width)) * v_bytes_per_channel * ((uint64_t)(WUFFS_PNG__NUM_CHANNELS[self->private_impl.f_color_type])));
37834 }
37835 
37836 // -------- func png.decoder.choose_filter_implementations
37837 
37838 static wuffs_base__empty_struct
wuffs_png__decoder__choose_filter_implementations(wuffs_png__decoder * self)37839 wuffs_png__decoder__choose_filter_implementations(
37840     wuffs_png__decoder* self) {
37841   if (self->private_impl.f_filter_distance == 3) {
37842     self->private_impl.choosy_filter_1 = (
37843         &wuffs_png__decoder__filter_1_distance_3_fallback);
37844     self->private_impl.choosy_filter_3 = (
37845         &wuffs_png__decoder__filter_3_distance_3_fallback);
37846     self->private_impl.choosy_filter_4 = (
37847 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
37848         wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_png__decoder__filter_4_distance_3_arm_neon :
37849 #endif
37850 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
37851         wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_png__decoder__filter_4_distance_3_x86_sse42 :
37852 #endif
37853         &wuffs_png__decoder__filter_4_distance_3_fallback);
37854   } else if (self->private_impl.f_filter_distance == 4) {
37855     self->private_impl.choosy_filter_1 = (
37856 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
37857         wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_png__decoder__filter_1_distance_4_arm_neon :
37858 #endif
37859 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
37860         wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_png__decoder__filter_1_distance_4_x86_sse42 :
37861 #endif
37862         &wuffs_png__decoder__filter_1_distance_4_fallback);
37863     self->private_impl.choosy_filter_3 = (
37864 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
37865         wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_png__decoder__filter_3_distance_4_arm_neon :
37866 #endif
37867 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
37868         wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_png__decoder__filter_3_distance_4_x86_sse42 :
37869 #endif
37870         &wuffs_png__decoder__filter_3_distance_4_fallback);
37871     self->private_impl.choosy_filter_4 = (
37872 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
37873         wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_png__decoder__filter_4_distance_4_arm_neon :
37874 #endif
37875 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
37876         wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_png__decoder__filter_4_distance_4_x86_sse42 :
37877 #endif
37878         &wuffs_png__decoder__filter_4_distance_4_fallback);
37879   }
37880   return wuffs_base__make_empty_struct();
37881 }
37882 
37883 // -------- func png.decoder.decode_other_chunk
37884 
37885 static wuffs_base__status
wuffs_png__decoder__decode_other_chunk(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)37886 wuffs_png__decoder__decode_other_chunk(
37887     wuffs_png__decoder* self,
37888     wuffs_base__io_buffer* a_src) {
37889   wuffs_base__status status = wuffs_base__make_status(NULL);
37890 
37891   const uint8_t* iop_a_src = NULL;
37892   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
37893   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
37894   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
37895   if (a_src) {
37896     io0_a_src = a_src->data.ptr;
37897     io1_a_src = io0_a_src + a_src->meta.ri;
37898     iop_a_src = io1_a_src;
37899     io2_a_src = io0_a_src + a_src->meta.wi;
37900   }
37901 
37902   uint32_t coro_susp_point = self->private_impl.p_decode_other_chunk[0];
37903   switch (coro_susp_point) {
37904     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
37905 
37906     if (self->private_impl.f_chunk_type == 1163152464) {
37907       if (self->private_impl.f_seen_plte || (self->private_impl.f_color_type != 3)) {
37908         status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
37909         goto exit;
37910       }
37911       if (a_src) {
37912         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
37913       }
37914       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
37915       status = wuffs_png__decoder__decode_plte(self, a_src);
37916       if (a_src) {
37917         iop_a_src = a_src->data.ptr + a_src->meta.ri;
37918       }
37919       if (status.repr) {
37920         goto suspend;
37921       }
37922       self->private_impl.f_seen_plte = true;
37923     } else if ((self->private_impl.f_chunk_type & 32) == 0) {
37924       if (self->private_impl.f_chunk_type != 1413563465) {
37925         status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
37926         goto exit;
37927       }
37928     } else if (self->private_impl.f_chunk_type == 1280598881) {
37929       if (self->private_impl.f_seen_actl) {
37930         status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
37931         goto exit;
37932       }
37933       if (a_src) {
37934         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
37935       }
37936       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
37937       status = wuffs_png__decoder__decode_actl(self, a_src);
37938       if (a_src) {
37939         iop_a_src = a_src->data.ptr + a_src->meta.ri;
37940       }
37941       if (status.repr) {
37942         goto suspend;
37943       }
37944       self->private_impl.f_seen_actl = true;
37945     } else if (self->private_impl.f_chunk_type == 1297238115) {
37946       if (self->private_impl.f_report_metadata_chrm) {
37947         if (self->private_impl.f_seen_chrm) {
37948           status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
37949           goto exit;
37950         }
37951         if (a_src) {
37952           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
37953         }
37954         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
37955         status = wuffs_png__decoder__decode_chrm(self, a_src);
37956         if (a_src) {
37957           iop_a_src = a_src->data.ptr + a_src->meta.ri;
37958         }
37959         if (status.repr) {
37960           goto suspend;
37961         }
37962         self->private_impl.f_seen_chrm = true;
37963       }
37964     } else if (self->private_impl.f_chunk_type == 1280598886) {
37965       if (self->private_impl.f_seen_fctl) {
37966         status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
37967         goto exit;
37968       }
37969       if (a_src) {
37970         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
37971       }
37972       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
37973       status = wuffs_png__decoder__decode_fctl(self, a_src);
37974       if (a_src) {
37975         iop_a_src = a_src->data.ptr + a_src->meta.ri;
37976       }
37977       if (status.repr) {
37978         goto suspend;
37979       }
37980       self->private_impl.f_seen_fctl = true;
37981     } else if (self->private_impl.f_chunk_type == 1095582055) {
37982       if (self->private_impl.f_report_metadata_gama) {
37983         if (self->private_impl.f_seen_gama) {
37984           status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
37985           goto exit;
37986         }
37987         if (a_src) {
37988           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
37989         }
37990         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
37991         status = wuffs_png__decoder__decode_gama(self, a_src);
37992         if (a_src) {
37993           iop_a_src = a_src->data.ptr + a_src->meta.ri;
37994         }
37995         if (status.repr) {
37996           goto suspend;
37997         }
37998         self->private_impl.f_seen_gama = true;
37999       }
38000     } else if (self->private_impl.f_chunk_type == 1346585449) {
38001       if (self->private_impl.f_report_metadata_iccp) {
38002         if (self->private_impl.f_seen_iccp) {
38003           status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38004           goto exit;
38005         }
38006         if (a_src) {
38007           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38008         }
38009         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
38010         status = wuffs_png__decoder__decode_iccp(self, a_src);
38011         if (a_src) {
38012           iop_a_src = a_src->data.ptr + a_src->meta.ri;
38013         }
38014         if (status.repr) {
38015           goto suspend;
38016         }
38017         self->private_impl.f_seen_iccp = true;
38018       }
38019     } else if (self->private_impl.f_chunk_type == 1111970419) {
38020       if (self->private_impl.f_report_metadata_srgb) {
38021         if (self->private_impl.f_seen_srgb) {
38022           status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38023           goto exit;
38024         }
38025         if (a_src) {
38026           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38027         }
38028         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
38029         status = wuffs_png__decoder__decode_srgb(self, a_src);
38030         if (a_src) {
38031           iop_a_src = a_src->data.ptr + a_src->meta.ri;
38032         }
38033         if (status.repr) {
38034           goto suspend;
38035         }
38036         self->private_impl.f_seen_srgb = true;
38037       }
38038     } else if (self->private_impl.f_chunk_type == 1397641844) {
38039       if (self->private_impl.f_seen_trns || (self->private_impl.f_color_type > 3) || ((self->private_impl.f_color_type == 3) &&  ! self->private_impl.f_seen_plte)) {
38040         status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38041         goto exit;
38042       }
38043       if (a_src) {
38044         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38045       }
38046       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
38047       status = wuffs_png__decoder__decode_trns(self, a_src);
38048       if (a_src) {
38049         iop_a_src = a_src->data.ptr + a_src->meta.ri;
38050       }
38051       if (status.repr) {
38052         goto suspend;
38053       }
38054       self->private_impl.f_seen_trns = true;
38055     } else if ((self->private_impl.f_chunk_type == 1951945833) || (self->private_impl.f_chunk_type == 1951942004) || (self->private_impl.f_chunk_type == 1951945850)) {
38056       if (self->private_impl.f_report_metadata_kvp) {
38057         self->private_impl.f_metadata_flavor = 4;
38058         self->private_impl.f_metadata_fourcc = 1263947851;
38059         self->private_impl.f_metadata_x = 0;
38060         self->private_impl.f_metadata_y = 0;
38061         self->private_impl.f_metadata_z = 0;
38062       }
38063     }
38064     if (self->private_impl.f_metadata_fourcc == 0) {
38065       self->private_data.s_decode_other_chunk[0].scratch = self->private_impl.f_chunk_length;
38066       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
38067       if (self->private_data.s_decode_other_chunk[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
38068         self->private_data.s_decode_other_chunk[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
38069         iop_a_src = io2_a_src;
38070         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38071         goto suspend;
38072       }
38073       iop_a_src += self->private_data.s_decode_other_chunk[0].scratch;
38074     }
38075 
38076     goto ok;
38077     ok:
38078     self->private_impl.p_decode_other_chunk[0] = 0;
38079     goto exit;
38080   }
38081 
38082   goto suspend;
38083   suspend:
38084   self->private_impl.p_decode_other_chunk[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
38085 
38086   goto exit;
38087   exit:
38088   if (a_src) {
38089     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38090   }
38091 
38092   return status;
38093 }
38094 
38095 // -------- func png.decoder.decode_actl
38096 
38097 static wuffs_base__status
wuffs_png__decoder__decode_actl(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)38098 wuffs_png__decoder__decode_actl(
38099     wuffs_png__decoder* self,
38100     wuffs_base__io_buffer* a_src) {
38101   wuffs_base__status status = wuffs_base__make_status(NULL);
38102 
38103   const uint8_t* iop_a_src = NULL;
38104   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38105   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38106   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38107   if (a_src) {
38108     io0_a_src = a_src->data.ptr;
38109     io1_a_src = io0_a_src + a_src->meta.ri;
38110     iop_a_src = io1_a_src;
38111     io2_a_src = io0_a_src + a_src->meta.wi;
38112   }
38113 
38114   uint32_t coro_susp_point = self->private_impl.p_decode_actl[0];
38115   switch (coro_susp_point) {
38116     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
38117 
38118     if (self->private_impl.f_chunk_length != 8) {
38119       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38120       goto exit;
38121     } else if (self->private_impl.f_interlace_pass > 0) {
38122       status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file);
38123       goto exit;
38124     }
38125     self->private_impl.f_chunk_length = 0;
38126     {
38127       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
38128       uint32_t t_0;
38129       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38130         t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
38131         iop_a_src += 4;
38132       } else {
38133         self->private_data.s_decode_actl[0].scratch = 0;
38134         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
38135         while (true) {
38136           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38137             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38138             goto suspend;
38139           }
38140           uint64_t* scratch = &self->private_data.s_decode_actl[0].scratch;
38141           uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFF));
38142           *scratch >>= 8;
38143           *scratch <<= 8;
38144           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
38145           if (num_bits_0 == 24) {
38146             t_0 = ((uint32_t)(*scratch >> 32));
38147             break;
38148           }
38149           num_bits_0 += 8;
38150           *scratch |= ((uint64_t)(num_bits_0));
38151         }
38152       }
38153       self->private_impl.f_num_animation_frames_value = t_0;
38154     }
38155     if (self->private_impl.f_num_animation_frames_value == 0) {
38156       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38157       goto exit;
38158     }
38159     {
38160       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
38161       uint32_t t_1;
38162       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38163         t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
38164         iop_a_src += 4;
38165       } else {
38166         self->private_data.s_decode_actl[0].scratch = 0;
38167         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
38168         while (true) {
38169           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38170             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38171             goto suspend;
38172           }
38173           uint64_t* scratch = &self->private_data.s_decode_actl[0].scratch;
38174           uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFF));
38175           *scratch >>= 8;
38176           *scratch <<= 8;
38177           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
38178           if (num_bits_1 == 24) {
38179             t_1 = ((uint32_t)(*scratch >> 32));
38180             break;
38181           }
38182           num_bits_1 += 8;
38183           *scratch |= ((uint64_t)(num_bits_1));
38184         }
38185       }
38186       self->private_impl.f_num_animation_loops_value = t_1;
38187     }
38188 
38189     goto ok;
38190     ok:
38191     self->private_impl.p_decode_actl[0] = 0;
38192     goto exit;
38193   }
38194 
38195   goto suspend;
38196   suspend:
38197   self->private_impl.p_decode_actl[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
38198 
38199   goto exit;
38200   exit:
38201   if (a_src) {
38202     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38203   }
38204 
38205   return status;
38206 }
38207 
38208 // -------- func png.decoder.decode_chrm
38209 
38210 static wuffs_base__status
wuffs_png__decoder__decode_chrm(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)38211 wuffs_png__decoder__decode_chrm(
38212     wuffs_png__decoder* self,
38213     wuffs_base__io_buffer* a_src) {
38214   wuffs_base__status status = wuffs_base__make_status(NULL);
38215 
38216   uint64_t v_u = 0;
38217 
38218   const uint8_t* iop_a_src = NULL;
38219   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38220   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38221   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38222   if (a_src) {
38223     io0_a_src = a_src->data.ptr;
38224     io1_a_src = io0_a_src + a_src->meta.ri;
38225     iop_a_src = io1_a_src;
38226     io2_a_src = io0_a_src + a_src->meta.wi;
38227   }
38228 
38229   uint32_t coro_susp_point = self->private_impl.p_decode_chrm[0];
38230   switch (coro_susp_point) {
38231     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
38232 
38233     if (self->private_impl.f_chunk_length != 32) {
38234       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38235       goto exit;
38236     }
38237     self->private_impl.f_chunk_length = 0;
38238     self->private_impl.f_metadata_flavor = 5;
38239     self->private_impl.f_metadata_fourcc = 1128813133;
38240     self->private_impl.f_metadata_x = 0;
38241     self->private_impl.f_metadata_y = 0;
38242     self->private_impl.f_metadata_z = 0;
38243     {
38244       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
38245       uint64_t t_0;
38246       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38247         t_0 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
38248         iop_a_src += 4;
38249       } else {
38250         self->private_data.s_decode_chrm[0].scratch = 0;
38251         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
38252         while (true) {
38253           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38254             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38255             goto suspend;
38256           }
38257           uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
38258           uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFF));
38259           *scratch >>= 8;
38260           *scratch <<= 8;
38261           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
38262           if (num_bits_0 == 24) {
38263             t_0 = ((uint64_t)(*scratch >> 32));
38264             break;
38265           }
38266           num_bits_0 += 8;
38267           *scratch |= ((uint64_t)(num_bits_0));
38268         }
38269       }
38270       v_u = t_0;
38271     }
38272     self->private_impl.f_metadata_x |= ((16777215 & v_u) << 0);
38273     {
38274       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
38275       uint64_t t_1;
38276       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38277         t_1 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
38278         iop_a_src += 4;
38279       } else {
38280         self->private_data.s_decode_chrm[0].scratch = 0;
38281         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
38282         while (true) {
38283           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38284             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38285             goto suspend;
38286           }
38287           uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
38288           uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFF));
38289           *scratch >>= 8;
38290           *scratch <<= 8;
38291           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
38292           if (num_bits_1 == 24) {
38293             t_1 = ((uint64_t)(*scratch >> 32));
38294             break;
38295           }
38296           num_bits_1 += 8;
38297           *scratch |= ((uint64_t)(num_bits_1));
38298         }
38299       }
38300       v_u = t_1;
38301     }
38302     self->private_impl.f_metadata_x |= ((16777215 & v_u) << 24);
38303     {
38304       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
38305       uint64_t t_2;
38306       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38307         t_2 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
38308         iop_a_src += 4;
38309       } else {
38310         self->private_data.s_decode_chrm[0].scratch = 0;
38311         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
38312         while (true) {
38313           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38314             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38315             goto suspend;
38316           }
38317           uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
38318           uint32_t num_bits_2 = ((uint32_t)(*scratch & 0xFF));
38319           *scratch >>= 8;
38320           *scratch <<= 8;
38321           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_2);
38322           if (num_bits_2 == 24) {
38323             t_2 = ((uint64_t)(*scratch >> 32));
38324             break;
38325           }
38326           num_bits_2 += 8;
38327           *scratch |= ((uint64_t)(num_bits_2));
38328         }
38329       }
38330       v_u = t_2;
38331     }
38332     self->private_impl.f_metadata_x |= ((uint64_t)((16777215 & v_u) << 48));
38333     self->private_impl.f_metadata_y |= ((16777215 & v_u) >> 16);
38334     {
38335       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
38336       uint64_t t_3;
38337       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38338         t_3 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
38339         iop_a_src += 4;
38340       } else {
38341         self->private_data.s_decode_chrm[0].scratch = 0;
38342         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
38343         while (true) {
38344           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38345             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38346             goto suspend;
38347           }
38348           uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
38349           uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFF));
38350           *scratch >>= 8;
38351           *scratch <<= 8;
38352           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3);
38353           if (num_bits_3 == 24) {
38354             t_3 = ((uint64_t)(*scratch >> 32));
38355             break;
38356           }
38357           num_bits_3 += 8;
38358           *scratch |= ((uint64_t)(num_bits_3));
38359         }
38360       }
38361       v_u = t_3;
38362     }
38363     self->private_impl.f_metadata_y |= ((16777215 & v_u) << 8);
38364     {
38365       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
38366       uint64_t t_4;
38367       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38368         t_4 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
38369         iop_a_src += 4;
38370       } else {
38371         self->private_data.s_decode_chrm[0].scratch = 0;
38372         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
38373         while (true) {
38374           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38375             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38376             goto suspend;
38377           }
38378           uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
38379           uint32_t num_bits_4 = ((uint32_t)(*scratch & 0xFF));
38380           *scratch >>= 8;
38381           *scratch <<= 8;
38382           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_4);
38383           if (num_bits_4 == 24) {
38384             t_4 = ((uint64_t)(*scratch >> 32));
38385             break;
38386           }
38387           num_bits_4 += 8;
38388           *scratch |= ((uint64_t)(num_bits_4));
38389         }
38390       }
38391       v_u = t_4;
38392     }
38393     self->private_impl.f_metadata_y |= ((16777215 & v_u) << 32);
38394     {
38395       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
38396       uint64_t t_5;
38397       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38398         t_5 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
38399         iop_a_src += 4;
38400       } else {
38401         self->private_data.s_decode_chrm[0].scratch = 0;
38402         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
38403         while (true) {
38404           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38405             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38406             goto suspend;
38407           }
38408           uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
38409           uint32_t num_bits_5 = ((uint32_t)(*scratch & 0xFF));
38410           *scratch >>= 8;
38411           *scratch <<= 8;
38412           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_5);
38413           if (num_bits_5 == 24) {
38414             t_5 = ((uint64_t)(*scratch >> 32));
38415             break;
38416           }
38417           num_bits_5 += 8;
38418           *scratch |= ((uint64_t)(num_bits_5));
38419         }
38420       }
38421       v_u = t_5;
38422     }
38423     self->private_impl.f_metadata_y |= ((uint64_t)((16777215 & v_u) << 56));
38424     self->private_impl.f_metadata_z |= ((16777215 & v_u) >> 8);
38425     {
38426       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
38427       uint64_t t_6;
38428       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38429         t_6 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
38430         iop_a_src += 4;
38431       } else {
38432         self->private_data.s_decode_chrm[0].scratch = 0;
38433         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
38434         while (true) {
38435           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38436             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38437             goto suspend;
38438           }
38439           uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
38440           uint32_t num_bits_6 = ((uint32_t)(*scratch & 0xFF));
38441           *scratch >>= 8;
38442           *scratch <<= 8;
38443           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_6);
38444           if (num_bits_6 == 24) {
38445             t_6 = ((uint64_t)(*scratch >> 32));
38446             break;
38447           }
38448           num_bits_6 += 8;
38449           *scratch |= ((uint64_t)(num_bits_6));
38450         }
38451       }
38452       v_u = t_6;
38453     }
38454     self->private_impl.f_metadata_z |= ((16777215 & v_u) << 16);
38455     {
38456       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
38457       uint64_t t_7;
38458       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38459         t_7 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
38460         iop_a_src += 4;
38461       } else {
38462         self->private_data.s_decode_chrm[0].scratch = 0;
38463         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
38464         while (true) {
38465           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38466             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38467             goto suspend;
38468           }
38469           uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
38470           uint32_t num_bits_7 = ((uint32_t)(*scratch & 0xFF));
38471           *scratch >>= 8;
38472           *scratch <<= 8;
38473           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_7);
38474           if (num_bits_7 == 24) {
38475             t_7 = ((uint64_t)(*scratch >> 32));
38476             break;
38477           }
38478           num_bits_7 += 8;
38479           *scratch |= ((uint64_t)(num_bits_7));
38480         }
38481       }
38482       v_u = t_7;
38483     }
38484     self->private_impl.f_metadata_z |= ((16777215 & v_u) << 40);
38485 
38486     goto ok;
38487     ok:
38488     self->private_impl.p_decode_chrm[0] = 0;
38489     goto exit;
38490   }
38491 
38492   goto suspend;
38493   suspend:
38494   self->private_impl.p_decode_chrm[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
38495 
38496   goto exit;
38497   exit:
38498   if (a_src) {
38499     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38500   }
38501 
38502   return status;
38503 }
38504 
38505 // -------- func png.decoder.decode_fctl
38506 
38507 static wuffs_base__status
wuffs_png__decoder__decode_fctl(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)38508 wuffs_png__decoder__decode_fctl(
38509     wuffs_png__decoder* self,
38510     wuffs_base__io_buffer* a_src) {
38511   wuffs_base__status status = wuffs_base__make_status(NULL);
38512 
38513   uint32_t v_x0 = 0;
38514   uint32_t v_y0 = 0;
38515   uint32_t v_x1 = 0;
38516   uint32_t v_y1 = 0;
38517 
38518   const uint8_t* iop_a_src = NULL;
38519   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38520   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38521   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38522   if (a_src) {
38523     io0_a_src = a_src->data.ptr;
38524     io1_a_src = io0_a_src + a_src->meta.ri;
38525     iop_a_src = io1_a_src;
38526     io2_a_src = io0_a_src + a_src->meta.wi;
38527   }
38528 
38529   uint32_t coro_susp_point = self->private_impl.p_decode_fctl[0];
38530   if (coro_susp_point) {
38531     v_x0 = self->private_data.s_decode_fctl[0].v_x0;
38532     v_x1 = self->private_data.s_decode_fctl[0].v_x1;
38533     v_y1 = self->private_data.s_decode_fctl[0].v_y1;
38534   }
38535   switch (coro_susp_point) {
38536     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
38537 
38538     if (self->private_impl.f_chunk_length != 26) {
38539       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38540       goto exit;
38541     }
38542     self->private_impl.f_chunk_length = 0;
38543     {
38544       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
38545       uint32_t t_0;
38546       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38547         t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
38548         iop_a_src += 4;
38549       } else {
38550         self->private_data.s_decode_fctl[0].scratch = 0;
38551         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
38552         while (true) {
38553           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38554             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38555             goto suspend;
38556           }
38557           uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch;
38558           uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFF));
38559           *scratch >>= 8;
38560           *scratch <<= 8;
38561           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
38562           if (num_bits_0 == 24) {
38563             t_0 = ((uint32_t)(*scratch >> 32));
38564             break;
38565           }
38566           num_bits_0 += 8;
38567           *scratch |= ((uint64_t)(num_bits_0));
38568         }
38569       }
38570       v_x0 = t_0;
38571     }
38572     if (v_x0 != self->private_impl.f_next_animation_seq_num) {
38573       status = wuffs_base__make_status(wuffs_png__error__bad_animation_sequence_number);
38574       goto exit;
38575     } else if (self->private_impl.f_next_animation_seq_num >= 4294967295) {
38576       status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file);
38577       goto exit;
38578     }
38579     self->private_impl.f_next_animation_seq_num += 1;
38580     {
38581       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
38582       uint32_t t_1;
38583       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38584         t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
38585         iop_a_src += 4;
38586       } else {
38587         self->private_data.s_decode_fctl[0].scratch = 0;
38588         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
38589         while (true) {
38590           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38591             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38592             goto suspend;
38593           }
38594           uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch;
38595           uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFF));
38596           *scratch >>= 8;
38597           *scratch <<= 8;
38598           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
38599           if (num_bits_1 == 24) {
38600             t_1 = ((uint32_t)(*scratch >> 32));
38601             break;
38602           }
38603           num_bits_1 += 8;
38604           *scratch |= ((uint64_t)(num_bits_1));
38605         }
38606       }
38607       v_x1 = t_1;
38608     }
38609     {
38610       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
38611       uint32_t t_2;
38612       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38613         t_2 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
38614         iop_a_src += 4;
38615       } else {
38616         self->private_data.s_decode_fctl[0].scratch = 0;
38617         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
38618         while (true) {
38619           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38620             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38621             goto suspend;
38622           }
38623           uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch;
38624           uint32_t num_bits_2 = ((uint32_t)(*scratch & 0xFF));
38625           *scratch >>= 8;
38626           *scratch <<= 8;
38627           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_2);
38628           if (num_bits_2 == 24) {
38629             t_2 = ((uint32_t)(*scratch >> 32));
38630             break;
38631           }
38632           num_bits_2 += 8;
38633           *scratch |= ((uint64_t)(num_bits_2));
38634         }
38635       }
38636       v_y1 = t_2;
38637     }
38638     {
38639       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
38640       uint32_t t_3;
38641       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38642         t_3 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
38643         iop_a_src += 4;
38644       } else {
38645         self->private_data.s_decode_fctl[0].scratch = 0;
38646         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
38647         while (true) {
38648           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38649             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38650             goto suspend;
38651           }
38652           uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch;
38653           uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFF));
38654           *scratch >>= 8;
38655           *scratch <<= 8;
38656           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3);
38657           if (num_bits_3 == 24) {
38658             t_3 = ((uint32_t)(*scratch >> 32));
38659             break;
38660           }
38661           num_bits_3 += 8;
38662           *scratch |= ((uint64_t)(num_bits_3));
38663         }
38664       }
38665       v_x0 = t_3;
38666     }
38667     {
38668       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
38669       uint32_t t_4;
38670       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38671         t_4 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
38672         iop_a_src += 4;
38673       } else {
38674         self->private_data.s_decode_fctl[0].scratch = 0;
38675         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
38676         while (true) {
38677           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38678             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38679             goto suspend;
38680           }
38681           uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch;
38682           uint32_t num_bits_4 = ((uint32_t)(*scratch & 0xFF));
38683           *scratch >>= 8;
38684           *scratch <<= 8;
38685           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_4);
38686           if (num_bits_4 == 24) {
38687             t_4 = ((uint32_t)(*scratch >> 32));
38688             break;
38689           }
38690           num_bits_4 += 8;
38691           *scratch |= ((uint64_t)(num_bits_4));
38692         }
38693       }
38694       v_y0 = t_4;
38695     }
38696     v_x1 += v_x0;
38697     v_y1 += v_y0;
38698     if ((v_x0 >= v_x1) ||
38699         (v_x0 > self->private_impl.f_width) ||
38700         (v_x1 > self->private_impl.f_width) ||
38701         (v_y0 >= v_y1) ||
38702         (v_y0 > self->private_impl.f_height) ||
38703         (v_y1 > self->private_impl.f_height)) {
38704       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38705       goto exit;
38706     }
38707     self->private_impl.f_frame_rect_x0 = v_x0;
38708     self->private_impl.f_frame_rect_y0 = v_y0;
38709     self->private_impl.f_frame_rect_x1 = v_x1;
38710     self->private_impl.f_frame_rect_y1 = v_y1;
38711     {
38712       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
38713       uint32_t t_5;
38714       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
38715         t_5 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
38716         iop_a_src += 2;
38717       } else {
38718         self->private_data.s_decode_fctl[0].scratch = 0;
38719         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
38720         while (true) {
38721           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38722             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38723             goto suspend;
38724           }
38725           uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch;
38726           uint32_t num_bits_5 = ((uint32_t)(*scratch & 0xFF));
38727           *scratch >>= 8;
38728           *scratch <<= 8;
38729           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_5);
38730           if (num_bits_5 == 8) {
38731             t_5 = ((uint32_t)(*scratch >> 48));
38732             break;
38733           }
38734           num_bits_5 += 8;
38735           *scratch |= ((uint64_t)(num_bits_5));
38736         }
38737       }
38738       v_x0 = t_5;
38739     }
38740     {
38741       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
38742       uint32_t t_6;
38743       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
38744         t_6 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
38745         iop_a_src += 2;
38746       } else {
38747         self->private_data.s_decode_fctl[0].scratch = 0;
38748         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
38749         while (true) {
38750           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38751             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38752             goto suspend;
38753           }
38754           uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch;
38755           uint32_t num_bits_6 = ((uint32_t)(*scratch & 0xFF));
38756           *scratch >>= 8;
38757           *scratch <<= 8;
38758           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_6);
38759           if (num_bits_6 == 8) {
38760             t_6 = ((uint32_t)(*scratch >> 48));
38761             break;
38762           }
38763           num_bits_6 += 8;
38764           *scratch |= ((uint64_t)(num_bits_6));
38765         }
38766       }
38767       v_x1 = t_6;
38768     }
38769     if (v_x1 <= 0) {
38770       self->private_impl.f_frame_duration = (((uint64_t)(v_x0)) * 7056000);
38771     } else {
38772       self->private_impl.f_frame_duration = ((((uint64_t)(v_x0)) * 705600000) / ((uint64_t)(v_x1)));
38773     }
38774     {
38775       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
38776       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38777         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38778         goto suspend;
38779       }
38780       uint32_t t_7 = *iop_a_src++;
38781       v_x0 = t_7;
38782     }
38783     if (v_x0 == 0) {
38784       self->private_impl.f_frame_disposal = 0;
38785     } else if (v_x0 == 1) {
38786       self->private_impl.f_frame_disposal = 1;
38787     } else if (v_x0 == 2) {
38788       self->private_impl.f_frame_disposal = 2;
38789     } else {
38790       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38791       goto exit;
38792     }
38793     {
38794       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
38795       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38796         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38797         goto suspend;
38798       }
38799       uint32_t t_8 = *iop_a_src++;
38800       v_x0 = t_8;
38801     }
38802     if (v_x0 == 0) {
38803       self->private_impl.f_frame_overwrite_instead_of_blend = true;
38804     } else if (v_x0 == 1) {
38805       self->private_impl.f_frame_overwrite_instead_of_blend = false;
38806     } else {
38807       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38808       goto exit;
38809     }
38810     if (self->private_impl.f_num_decoded_frame_configs_value == 0) {
38811       self->private_impl.f_first_rect_x0 = self->private_impl.f_frame_rect_x0;
38812       self->private_impl.f_first_rect_y0 = self->private_impl.f_frame_rect_y0;
38813       self->private_impl.f_first_rect_x1 = self->private_impl.f_frame_rect_x1;
38814       self->private_impl.f_first_rect_y1 = self->private_impl.f_frame_rect_y1;
38815       self->private_impl.f_first_duration = self->private_impl.f_frame_duration;
38816       self->private_impl.f_first_disposal = self->private_impl.f_frame_disposal;
38817       self->private_impl.f_first_overwrite_instead_of_blend = self->private_impl.f_frame_overwrite_instead_of_blend;
38818     }
38819 
38820     goto ok;
38821     ok:
38822     self->private_impl.p_decode_fctl[0] = 0;
38823     goto exit;
38824   }
38825 
38826   goto suspend;
38827   suspend:
38828   self->private_impl.p_decode_fctl[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
38829   self->private_data.s_decode_fctl[0].v_x0 = v_x0;
38830   self->private_data.s_decode_fctl[0].v_x1 = v_x1;
38831   self->private_data.s_decode_fctl[0].v_y1 = v_y1;
38832 
38833   goto exit;
38834   exit:
38835   if (a_src) {
38836     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38837   }
38838 
38839   return status;
38840 }
38841 
38842 // -------- func png.decoder.decode_gama
38843 
38844 static wuffs_base__status
wuffs_png__decoder__decode_gama(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)38845 wuffs_png__decoder__decode_gama(
38846     wuffs_png__decoder* self,
38847     wuffs_base__io_buffer* a_src) {
38848   wuffs_base__status status = wuffs_base__make_status(NULL);
38849 
38850   const uint8_t* iop_a_src = NULL;
38851   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38852   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38853   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38854   if (a_src) {
38855     io0_a_src = a_src->data.ptr;
38856     io1_a_src = io0_a_src + a_src->meta.ri;
38857     iop_a_src = io1_a_src;
38858     io2_a_src = io0_a_src + a_src->meta.wi;
38859   }
38860 
38861   uint32_t coro_susp_point = self->private_impl.p_decode_gama[0];
38862   switch (coro_susp_point) {
38863     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
38864 
38865     if (self->private_impl.f_chunk_length != 4) {
38866       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38867       goto exit;
38868     }
38869     self->private_impl.f_chunk_length = 0;
38870     self->private_impl.f_metadata_flavor = 5;
38871     self->private_impl.f_metadata_fourcc = 1195461953;
38872     {
38873       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
38874       uint64_t t_0;
38875       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38876         t_0 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
38877         iop_a_src += 4;
38878       } else {
38879         self->private_data.s_decode_gama[0].scratch = 0;
38880         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
38881         while (true) {
38882           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38883             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38884             goto suspend;
38885           }
38886           uint64_t* scratch = &self->private_data.s_decode_gama[0].scratch;
38887           uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFF));
38888           *scratch >>= 8;
38889           *scratch <<= 8;
38890           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
38891           if (num_bits_0 == 24) {
38892             t_0 = ((uint64_t)(*scratch >> 32));
38893             break;
38894           }
38895           num_bits_0 += 8;
38896           *scratch |= ((uint64_t)(num_bits_0));
38897         }
38898       }
38899       self->private_impl.f_metadata_x = t_0;
38900     }
38901     self->private_impl.f_metadata_y = 0;
38902     self->private_impl.f_metadata_z = 0;
38903 
38904     goto ok;
38905     ok:
38906     self->private_impl.p_decode_gama[0] = 0;
38907     goto exit;
38908   }
38909 
38910   goto suspend;
38911   suspend:
38912   self->private_impl.p_decode_gama[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
38913 
38914   goto exit;
38915   exit:
38916   if (a_src) {
38917     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38918   }
38919 
38920   return status;
38921 }
38922 
38923 // -------- func png.decoder.decode_iccp
38924 
38925 static wuffs_base__status
wuffs_png__decoder__decode_iccp(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)38926 wuffs_png__decoder__decode_iccp(
38927     wuffs_png__decoder* self,
38928     wuffs_base__io_buffer* a_src) {
38929   wuffs_base__status status = wuffs_base__make_status(NULL);
38930 
38931   uint8_t v_c = 0;
38932 
38933   const uint8_t* iop_a_src = NULL;
38934   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38935   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38936   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38937   if (a_src) {
38938     io0_a_src = a_src->data.ptr;
38939     io1_a_src = io0_a_src + a_src->meta.ri;
38940     iop_a_src = io1_a_src;
38941     io2_a_src = io0_a_src + a_src->meta.wi;
38942   }
38943 
38944   uint32_t coro_susp_point = self->private_impl.p_decode_iccp[0];
38945   switch (coro_susp_point) {
38946     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
38947 
38948     while (true) {
38949       if (self->private_impl.f_chunk_length <= 0) {
38950         status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38951         goto exit;
38952       }
38953       self->private_impl.f_chunk_length -= 1;
38954       {
38955         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
38956         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38957           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38958           goto suspend;
38959         }
38960         uint8_t t_0 = *iop_a_src++;
38961         v_c = t_0;
38962       }
38963       if (v_c == 0) {
38964         goto label__0__break;
38965       }
38966     }
38967     label__0__break:;
38968     if (self->private_impl.f_chunk_length <= 0) {
38969       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38970       goto exit;
38971     }
38972     self->private_impl.f_chunk_length -= 1;
38973     {
38974       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
38975       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38976         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38977         goto suspend;
38978       }
38979       uint8_t t_1 = *iop_a_src++;
38980       v_c = t_1;
38981     }
38982     if (v_c != 0) {
38983       status = wuffs_base__make_status(wuffs_png__error__unsupported_png_compression_method);
38984       goto exit;
38985     }
38986     self->private_impl.f_metadata_is_zlib_compressed = true;
38987     self->private_impl.f_metadata_flavor = 4;
38988     self->private_impl.f_metadata_fourcc = 1229144912;
38989     self->private_impl.f_metadata_x = 0;
38990     self->private_impl.f_metadata_y = 0;
38991     self->private_impl.f_metadata_z = 0;
38992 
38993     goto ok;
38994     ok:
38995     self->private_impl.p_decode_iccp[0] = 0;
38996     goto exit;
38997   }
38998 
38999   goto suspend;
39000   suspend:
39001   self->private_impl.p_decode_iccp[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
39002 
39003   goto exit;
39004   exit:
39005   if (a_src) {
39006     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
39007   }
39008 
39009   return status;
39010 }
39011 
39012 // -------- func png.decoder.decode_plte
39013 
39014 static wuffs_base__status
wuffs_png__decoder__decode_plte(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)39015 wuffs_png__decoder__decode_plte(
39016     wuffs_png__decoder* self,
39017     wuffs_base__io_buffer* a_src) {
39018   wuffs_base__status status = wuffs_base__make_status(NULL);
39019 
39020   uint32_t v_num_entries = 0;
39021   uint32_t v_i = 0;
39022   uint32_t v_argb = 0;
39023 
39024   const uint8_t* iop_a_src = NULL;
39025   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39026   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39027   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39028   if (a_src) {
39029     io0_a_src = a_src->data.ptr;
39030     io1_a_src = io0_a_src + a_src->meta.ri;
39031     iop_a_src = io1_a_src;
39032     io2_a_src = io0_a_src + a_src->meta.wi;
39033   }
39034 
39035   uint32_t coro_susp_point = self->private_impl.p_decode_plte[0];
39036   if (coro_susp_point) {
39037     v_num_entries = self->private_data.s_decode_plte[0].v_num_entries;
39038     v_i = self->private_data.s_decode_plte[0].v_i;
39039   }
39040   switch (coro_susp_point) {
39041     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
39042 
39043     if ((self->private_impl.f_chunk_length > 768) || ((self->private_impl.f_chunk_length % 3) != 0)) {
39044       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39045       goto exit;
39046     }
39047     v_num_entries = (((uint32_t)(self->private_impl.f_chunk_length)) / 3);
39048     self->private_impl.f_chunk_length = 0;
39049     while (v_i < v_num_entries) {
39050       {
39051         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
39052         uint32_t t_0;
39053         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) {
39054           t_0 = ((uint32_t)(wuffs_base__peek_u24be__no_bounds_check(iop_a_src)));
39055           iop_a_src += 3;
39056         } else {
39057           self->private_data.s_decode_plte[0].scratch = 0;
39058           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
39059           while (true) {
39060             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39061               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39062               goto suspend;
39063             }
39064             uint64_t* scratch = &self->private_data.s_decode_plte[0].scratch;
39065             uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFF));
39066             *scratch >>= 8;
39067             *scratch <<= 8;
39068             *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
39069             if (num_bits_0 == 16) {
39070               t_0 = ((uint32_t)(*scratch >> 40));
39071               break;
39072             }
39073             num_bits_0 += 8;
39074             *scratch |= ((uint64_t)(num_bits_0));
39075           }
39076         }
39077         v_argb = t_0;
39078       }
39079       v_argb |= 4278190080;
39080       self->private_data.f_src_palette[((4 * v_i) + 0)] = ((uint8_t)(((v_argb >> 0) & 255)));
39081       self->private_data.f_src_palette[((4 * v_i) + 1)] = ((uint8_t)(((v_argb >> 8) & 255)));
39082       self->private_data.f_src_palette[((4 * v_i) + 2)] = ((uint8_t)(((v_argb >> 16) & 255)));
39083       self->private_data.f_src_palette[((4 * v_i) + 3)] = ((uint8_t)(((v_argb >> 24) & 255)));
39084       v_i += 1;
39085     }
39086     while (v_i < 256) {
39087       self->private_data.f_src_palette[((4 * v_i) + 0)] = 0;
39088       self->private_data.f_src_palette[((4 * v_i) + 1)] = 0;
39089       self->private_data.f_src_palette[((4 * v_i) + 2)] = 0;
39090       self->private_data.f_src_palette[((4 * v_i) + 3)] = 255;
39091       v_i += 1;
39092     }
39093 
39094     goto ok;
39095     ok:
39096     self->private_impl.p_decode_plte[0] = 0;
39097     goto exit;
39098   }
39099 
39100   goto suspend;
39101   suspend:
39102   self->private_impl.p_decode_plte[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
39103   self->private_data.s_decode_plte[0].v_num_entries = v_num_entries;
39104   self->private_data.s_decode_plte[0].v_i = v_i;
39105 
39106   goto exit;
39107   exit:
39108   if (a_src) {
39109     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
39110   }
39111 
39112   return status;
39113 }
39114 
39115 // -------- func png.decoder.decode_srgb
39116 
39117 static wuffs_base__status
wuffs_png__decoder__decode_srgb(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)39118 wuffs_png__decoder__decode_srgb(
39119     wuffs_png__decoder* self,
39120     wuffs_base__io_buffer* a_src) {
39121   wuffs_base__status status = wuffs_base__make_status(NULL);
39122 
39123   const uint8_t* iop_a_src = NULL;
39124   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39125   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39126   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39127   if (a_src) {
39128     io0_a_src = a_src->data.ptr;
39129     io1_a_src = io0_a_src + a_src->meta.ri;
39130     iop_a_src = io1_a_src;
39131     io2_a_src = io0_a_src + a_src->meta.wi;
39132   }
39133 
39134   uint32_t coro_susp_point = self->private_impl.p_decode_srgb[0];
39135   switch (coro_susp_point) {
39136     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
39137 
39138     if (self->private_impl.f_chunk_length != 1) {
39139       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39140       goto exit;
39141     }
39142     self->private_impl.f_chunk_length = 0;
39143     self->private_impl.f_metadata_flavor = 5;
39144     self->private_impl.f_metadata_fourcc = 1397901122;
39145     {
39146       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
39147       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39148         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39149         goto suspend;
39150       }
39151       uint64_t t_0 = *iop_a_src++;
39152       self->private_impl.f_metadata_x = t_0;
39153     }
39154     self->private_impl.f_metadata_y = 0;
39155     self->private_impl.f_metadata_z = 0;
39156 
39157     goto ok;
39158     ok:
39159     self->private_impl.p_decode_srgb[0] = 0;
39160     goto exit;
39161   }
39162 
39163   goto suspend;
39164   suspend:
39165   self->private_impl.p_decode_srgb[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
39166 
39167   goto exit;
39168   exit:
39169   if (a_src) {
39170     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
39171   }
39172 
39173   return status;
39174 }
39175 
39176 // -------- func png.decoder.decode_trns
39177 
39178 static wuffs_base__status
wuffs_png__decoder__decode_trns(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)39179 wuffs_png__decoder__decode_trns(
39180     wuffs_png__decoder* self,
39181     wuffs_base__io_buffer* a_src) {
39182   wuffs_base__status status = wuffs_base__make_status(NULL);
39183 
39184   uint32_t v_i = 0;
39185   uint32_t v_n = 0;
39186   uint64_t v_u = 0;
39187 
39188   const uint8_t* iop_a_src = NULL;
39189   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39190   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39191   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39192   if (a_src) {
39193     io0_a_src = a_src->data.ptr;
39194     io1_a_src = io0_a_src + a_src->meta.ri;
39195     iop_a_src = io1_a_src;
39196     io2_a_src = io0_a_src + a_src->meta.wi;
39197   }
39198 
39199   uint32_t coro_susp_point = self->private_impl.p_decode_trns[0];
39200   if (coro_susp_point) {
39201     v_i = self->private_data.s_decode_trns[0].v_i;
39202     v_n = self->private_data.s_decode_trns[0].v_n;
39203   }
39204   switch (coro_susp_point) {
39205     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
39206 
39207     if (self->private_impl.f_color_type == 0) {
39208       self->private_impl.choosy_filter_and_swizzle = (
39209           &wuffs_png__decoder__filter_and_swizzle_tricky);
39210       if (self->private_impl.f_depth <= 8) {
39211         self->private_impl.f_dst_pixfmt = 2164295816;
39212         self->private_impl.f_src_pixfmt = 2164295816;
39213       } else {
39214         self->private_impl.f_dst_pixfmt = 2164308923;
39215         self->private_impl.f_src_pixfmt = 2164308923;
39216       }
39217       if (self->private_impl.f_chunk_length != 2) {
39218         status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39219         goto exit;
39220       }
39221       self->private_impl.f_chunk_length = 0;
39222       {
39223         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
39224         uint64_t t_0;
39225         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
39226           t_0 = ((uint64_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
39227           iop_a_src += 2;
39228         } else {
39229           self->private_data.s_decode_trns[0].scratch = 0;
39230           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
39231           while (true) {
39232             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39233               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39234               goto suspend;
39235             }
39236             uint64_t* scratch = &self->private_data.s_decode_trns[0].scratch;
39237             uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFF));
39238             *scratch >>= 8;
39239             *scratch <<= 8;
39240             *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
39241             if (num_bits_0 == 8) {
39242               t_0 = ((uint64_t)(*scratch >> 48));
39243               break;
39244             }
39245             num_bits_0 += 8;
39246             *scratch |= ((uint64_t)(num_bits_0));
39247           }
39248         }
39249         v_u = t_0;
39250       }
39251       if (self->private_impl.f_depth <= 1) {
39252         self->private_impl.f_remap_transparency = (((v_u & 1) * 16777215) | 4278190080);
39253       } else if (self->private_impl.f_depth <= 2) {
39254         self->private_impl.f_remap_transparency = (((v_u & 3) * 5592405) | 4278190080);
39255       } else if (self->private_impl.f_depth <= 4) {
39256         self->private_impl.f_remap_transparency = (((v_u & 15) * 1118481) | 4278190080);
39257       } else if (self->private_impl.f_depth <= 8) {
39258         self->private_impl.f_remap_transparency = (((v_u & 255) * 65793) | 4278190080);
39259       } else {
39260         self->private_impl.f_remap_transparency = ((v_u * 4295032833) | 18446462598732840960u);
39261       }
39262     } else if (self->private_impl.f_color_type == 2) {
39263       self->private_impl.choosy_filter_and_swizzle = (
39264           &wuffs_png__decoder__filter_and_swizzle_tricky);
39265       if (self->private_impl.f_depth <= 8) {
39266         self->private_impl.f_dst_pixfmt = 2164295816;
39267         self->private_impl.f_src_pixfmt = 2164295816;
39268       } else {
39269         self->private_impl.f_dst_pixfmt = 2164308923;
39270         self->private_impl.f_src_pixfmt = 2164308923;
39271       }
39272       if (self->private_impl.f_chunk_length != 6) {
39273         status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39274         goto exit;
39275       }
39276       self->private_impl.f_chunk_length = 0;
39277       {
39278         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
39279         uint64_t t_1;
39280         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 6)) {
39281           t_1 = ((uint64_t)(wuffs_base__peek_u48be__no_bounds_check(iop_a_src)));
39282           iop_a_src += 6;
39283         } else {
39284           self->private_data.s_decode_trns[0].scratch = 0;
39285           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
39286           while (true) {
39287             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39288               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39289               goto suspend;
39290             }
39291             uint64_t* scratch = &self->private_data.s_decode_trns[0].scratch;
39292             uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFF));
39293             *scratch >>= 8;
39294             *scratch <<= 8;
39295             *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
39296             if (num_bits_1 == 40) {
39297               t_1 = ((uint64_t)(*scratch >> 16));
39298               break;
39299             }
39300             num_bits_1 += 8;
39301             *scratch |= ((uint64_t)(num_bits_1));
39302           }
39303         }
39304         v_u = t_1;
39305       }
39306       if (self->private_impl.f_depth <= 8) {
39307         self->private_impl.f_remap_transparency = ((255 & (v_u >> 0)) |
39308             (65280 & (v_u >> 8)) |
39309             (16711680 & (v_u >> 16)) |
39310             4278190080);
39311       } else {
39312         self->private_impl.f_remap_transparency = (v_u | 18446462598732840960u);
39313       }
39314     } else if (self->private_impl.f_color_type == 3) {
39315       self->private_impl.f_dst_pixfmt = 2164523016;
39316       self->private_impl.f_src_pixfmt = 2164523016;
39317       if (self->private_impl.f_chunk_length > 256) {
39318         status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39319         goto exit;
39320       }
39321       v_n = ((uint32_t)(self->private_impl.f_chunk_length));
39322       self->private_impl.f_chunk_length = 0;
39323       while (v_i < v_n) {
39324         {
39325           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
39326           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39327             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39328             goto suspend;
39329           }
39330           uint8_t t_2 = *iop_a_src++;
39331           self->private_data.f_src_palette[((4 * v_i) + 3)] = t_2;
39332         }
39333         v_i += 1;
39334       }
39335     } else {
39336       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39337       goto exit;
39338     }
39339 
39340     goto ok;
39341     ok:
39342     self->private_impl.p_decode_trns[0] = 0;
39343     goto exit;
39344   }
39345 
39346   goto suspend;
39347   suspend:
39348   self->private_impl.p_decode_trns[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
39349   self->private_data.s_decode_trns[0].v_i = v_i;
39350   self->private_data.s_decode_trns[0].v_n = v_n;
39351 
39352   goto exit;
39353   exit:
39354   if (a_src) {
39355     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
39356   }
39357 
39358   return status;
39359 }
39360 
39361 // -------- func png.decoder.decode_frame_config
39362 
39363 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)39364 wuffs_png__decoder__decode_frame_config(
39365     wuffs_png__decoder* self,
39366     wuffs_base__frame_config* a_dst,
39367     wuffs_base__io_buffer* a_src) {
39368   if (!self) {
39369     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
39370   }
39371   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
39372     return wuffs_base__make_status(
39373         (self->private_impl.magic == WUFFS_BASE__DISABLED)
39374         ? wuffs_base__error__disabled_by_previous_error
39375         : wuffs_base__error__initialize_not_called);
39376   }
39377   if (!a_src) {
39378     self->private_impl.magic = WUFFS_BASE__DISABLED;
39379     return wuffs_base__make_status(wuffs_base__error__bad_argument);
39380   }
39381   if ((self->private_impl.active_coroutine != 0) &&
39382       (self->private_impl.active_coroutine != 2)) {
39383     self->private_impl.magic = WUFFS_BASE__DISABLED;
39384     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
39385   }
39386   self->private_impl.active_coroutine = 0;
39387   wuffs_base__status status = wuffs_base__make_status(NULL);
39388 
39389   const uint8_t* iop_a_src = NULL;
39390   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39391   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39392   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39393   if (a_src) {
39394     io0_a_src = a_src->data.ptr;
39395     io1_a_src = io0_a_src + a_src->meta.ri;
39396     iop_a_src = io1_a_src;
39397     io2_a_src = io0_a_src + a_src->meta.wi;
39398   }
39399 
39400   uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
39401   switch (coro_susp_point) {
39402     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
39403 
39404     if (self->private_impl.f_call_sequence == 255) {
39405       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
39406       goto ok;
39407     } else if (self->private_impl.f_call_sequence < 3) {
39408       if (a_src) {
39409         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
39410       }
39411       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
39412       status = wuffs_png__decoder__decode_image_config(self, NULL, a_src);
39413       if (a_src) {
39414         iop_a_src = a_src->data.ptr + a_src->meta.ri;
39415       }
39416       if (status.repr) {
39417         goto suspend;
39418       }
39419     } else if (self->private_impl.f_call_sequence == 3) {
39420       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)))) {
39421         status = wuffs_base__make_status(wuffs_base__error__bad_restart);
39422         goto exit;
39423       }
39424     } else if (self->private_impl.f_call_sequence == 4) {
39425       if (a_src) {
39426         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
39427       }
39428       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
39429       status = wuffs_png__decoder__skip_frame(self, a_src);
39430       if (a_src) {
39431         iop_a_src = a_src->data.ptr + a_src->meta.ri;
39432       }
39433       if (status.repr) {
39434         goto suspend;
39435       }
39436       if (self->private_impl.f_call_sequence == 255) {
39437         status = wuffs_base__make_status(wuffs_base__note__end_of_data);
39438         goto ok;
39439       }
39440     }
39441     if (self->private_impl.f_num_decoded_frame_configs_value == 0) {
39442       self->private_impl.f_frame_rect_x0 = self->private_impl.f_first_rect_x0;
39443       self->private_impl.f_frame_rect_y0 = self->private_impl.f_first_rect_y0;
39444       self->private_impl.f_frame_rect_x1 = self->private_impl.f_first_rect_x1;
39445       self->private_impl.f_frame_rect_y1 = self->private_impl.f_first_rect_y1;
39446       self->private_impl.f_frame_config_io_position = self->private_impl.f_first_config_io_position;
39447       self->private_impl.f_frame_duration = self->private_impl.f_first_duration;
39448       self->private_impl.f_frame_disposal = self->private_impl.f_first_disposal;
39449       self->private_impl.f_frame_overwrite_instead_of_blend = self->private_impl.f_first_overwrite_instead_of_blend;
39450     } else {
39451       while (true) {
39452         {
39453           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
39454           uint32_t t_0;
39455           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
39456             t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
39457             iop_a_src += 4;
39458           } else {
39459             self->private_data.s_decode_frame_config[0].scratch = 0;
39460             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
39461             while (true) {
39462               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39463                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39464                 goto suspend;
39465               }
39466               uint64_t* scratch = &self->private_data.s_decode_frame_config[0].scratch;
39467               uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFF));
39468               *scratch >>= 8;
39469               *scratch <<= 8;
39470               *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
39471               if (num_bits_0 == 24) {
39472                 t_0 = ((uint32_t)(*scratch >> 32));
39473                 break;
39474               }
39475               num_bits_0 += 8;
39476               *scratch |= ((uint64_t)(num_bits_0));
39477             }
39478           }
39479           self->private_impl.f_chunk_length = t_0;
39480         }
39481         {
39482           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
39483           uint32_t t_1;
39484           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
39485             t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
39486             iop_a_src += 4;
39487           } else {
39488             self->private_data.s_decode_frame_config[0].scratch = 0;
39489             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
39490             while (true) {
39491               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39492                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39493                 goto suspend;
39494               }
39495               uint64_t* scratch = &self->private_data.s_decode_frame_config[0].scratch;
39496               uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
39497               *scratch <<= 8;
39498               *scratch >>= 8;
39499               *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
39500               if (num_bits_1 == 24) {
39501                 t_1 = ((uint32_t)(*scratch));
39502                 break;
39503               }
39504               num_bits_1 += 8;
39505               *scratch |= ((uint64_t)(num_bits_1)) << 56;
39506             }
39507           }
39508           self->private_impl.f_chunk_type = t_1;
39509         }
39510         if (self->private_impl.f_chunk_type == 1413571686) {
39511           status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39512           goto exit;
39513         } else if (self->private_impl.f_chunk_type == 1280598886) {
39514           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))) - 8));
39515           if (a_src) {
39516             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
39517           }
39518           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
39519           status = wuffs_png__decoder__decode_fctl(self, a_src);
39520           if (a_src) {
39521             iop_a_src = a_src->data.ptr + a_src->meta.ri;
39522           }
39523           if (status.repr) {
39524             goto suspend;
39525           }
39526           self->private_data.s_decode_frame_config[0].scratch = 4;
39527           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
39528           if (self->private_data.s_decode_frame_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
39529             self->private_data.s_decode_frame_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
39530             iop_a_src = io2_a_src;
39531             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39532             goto suspend;
39533           }
39534           iop_a_src += self->private_data.s_decode_frame_config[0].scratch;
39535           goto label__0__break;
39536         }
39537         self->private_data.s_decode_frame_config[0].scratch = (((uint64_t)(self->private_impl.f_chunk_length)) + 4);
39538         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
39539         if (self->private_data.s_decode_frame_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
39540           self->private_data.s_decode_frame_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
39541           iop_a_src = io2_a_src;
39542           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39543           goto suspend;
39544         }
39545         iop_a_src += self->private_data.s_decode_frame_config[0].scratch;
39546         self->private_impl.f_chunk_length = 0;
39547       }
39548       label__0__break:;
39549     }
39550     if (a_dst != NULL) {
39551       wuffs_base__frame_config__set(
39552           a_dst,
39553           wuffs_base__utility__make_rect_ie_u32(
39554           self->private_impl.f_frame_rect_x0,
39555           self->private_impl.f_frame_rect_y0,
39556           self->private_impl.f_frame_rect_x1,
39557           self->private_impl.f_frame_rect_y1),
39558           ((wuffs_base__flicks)(self->private_impl.f_frame_duration)),
39559           ((uint64_t)(self->private_impl.f_num_decoded_frame_configs_value)),
39560           self->private_impl.f_frame_config_io_position,
39561           self->private_impl.f_frame_disposal,
39562           ((self->private_impl.f_color_type <= 3) &&  ! self->private_impl.f_seen_trns),
39563           self->private_impl.f_frame_overwrite_instead_of_blend,
39564           0);
39565     }
39566     wuffs_base__u32__sat_add_indirect(&self->private_impl.f_num_decoded_frame_configs_value, 1);
39567     self->private_impl.f_call_sequence = 4;
39568 
39569     ok:
39570     self->private_impl.p_decode_frame_config[0] = 0;
39571     goto exit;
39572   }
39573 
39574   goto suspend;
39575   suspend:
39576   self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
39577   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
39578 
39579   goto exit;
39580   exit:
39581   if (a_src) {
39582     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
39583   }
39584 
39585   if (wuffs_base__status__is_error(&status)) {
39586     self->private_impl.magic = WUFFS_BASE__DISABLED;
39587   }
39588   return status;
39589 }
39590 
39591 // -------- func png.decoder.skip_frame
39592 
39593 static wuffs_base__status
wuffs_png__decoder__skip_frame(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)39594 wuffs_png__decoder__skip_frame(
39595     wuffs_png__decoder* self,
39596     wuffs_base__io_buffer* a_src) {
39597   wuffs_base__status status = wuffs_base__make_status(NULL);
39598 
39599   uint32_t v_seq_num = 0;
39600 
39601   const uint8_t* iop_a_src = NULL;
39602   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39603   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39604   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39605   if (a_src) {
39606     io0_a_src = a_src->data.ptr;
39607     io1_a_src = io0_a_src + a_src->meta.ri;
39608     iop_a_src = io1_a_src;
39609     io2_a_src = io0_a_src + a_src->meta.wi;
39610   }
39611 
39612   uint32_t coro_susp_point = self->private_impl.p_skip_frame[0];
39613   switch (coro_susp_point) {
39614     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
39615 
39616     self->private_impl.f_chunk_type_array[0] = 0;
39617     self->private_impl.f_chunk_type_array[1] = 0;
39618     self->private_impl.f_chunk_type_array[2] = 0;
39619     self->private_impl.f_chunk_type_array[3] = 0;
39620     label__0__continue:;
39621     while (true) {
39622       while (((uint64_t)(io2_a_src - iop_a_src)) < 8) {
39623         if (a_src && a_src->meta.closed) {
39624           status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39625           goto exit;
39626         }
39627         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39628         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
39629       }
39630       self->private_impl.f_chunk_length = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
39631       self->private_impl.f_chunk_type = ((uint32_t)((wuffs_base__peek_u64le__no_bounds_check(iop_a_src) >> 32)));
39632       if (self->private_impl.f_chunk_type == 1413563465) {
39633         if (self->private_impl.f_chunk_type_array[0] == 102) {
39634           status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39635           goto exit;
39636         }
39637         self->private_impl.f_chunk_type_array[0] = 73;
39638         self->private_impl.f_chunk_type_array[1] = 68;
39639         self->private_impl.f_chunk_type_array[2] = 65;
39640         self->private_impl.f_chunk_type_array[3] = 84;
39641       } else if (self->private_impl.f_chunk_type == 1413571686) {
39642         if (self->private_impl.f_chunk_type_array[0] == 73) {
39643           status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39644           goto exit;
39645         }
39646         self->private_impl.f_chunk_type_array[0] = 102;
39647         self->private_impl.f_chunk_type_array[1] = 100;
39648         self->private_impl.f_chunk_type_array[2] = 65;
39649         self->private_impl.f_chunk_type_array[3] = 84;
39650         if (self->private_impl.f_chunk_length < 4) {
39651           status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39652           goto exit;
39653         }
39654         self->private_impl.f_chunk_length -= 4;
39655         iop_a_src += 8;
39656         {
39657           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
39658           uint32_t t_0;
39659           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
39660             t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
39661             iop_a_src += 4;
39662           } else {
39663             self->private_data.s_skip_frame[0].scratch = 0;
39664             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
39665             while (true) {
39666               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39667                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39668                 goto suspend;
39669               }
39670               uint64_t* scratch = &self->private_data.s_skip_frame[0].scratch;
39671               uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFF));
39672               *scratch >>= 8;
39673               *scratch <<= 8;
39674               *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
39675               if (num_bits_0 == 24) {
39676                 t_0 = ((uint32_t)(*scratch >> 32));
39677                 break;
39678               }
39679               num_bits_0 += 8;
39680               *scratch |= ((uint64_t)(num_bits_0));
39681             }
39682           }
39683           v_seq_num = t_0;
39684         }
39685         if (v_seq_num != self->private_impl.f_next_animation_seq_num) {
39686           status = wuffs_base__make_status(wuffs_png__error__bad_animation_sequence_number);
39687           goto exit;
39688         } else if (self->private_impl.f_next_animation_seq_num >= 4294967295) {
39689           status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file);
39690           goto exit;
39691         }
39692         self->private_impl.f_next_animation_seq_num += 1;
39693         self->private_data.s_skip_frame[0].scratch = (((uint64_t)(self->private_impl.f_chunk_length)) + 4);
39694         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
39695         if (self->private_data.s_skip_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
39696           self->private_data.s_skip_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
39697           iop_a_src = io2_a_src;
39698           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39699           goto suspend;
39700         }
39701         iop_a_src += self->private_data.s_skip_frame[0].scratch;
39702         self->private_impl.f_chunk_length = 0;
39703         goto label__0__continue;
39704       } else if (self->private_impl.f_chunk_type_array[0] != 0) {
39705         goto label__0__break;
39706       } else if (self->private_impl.f_chunk_type == 1280598886) {
39707         status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39708         goto exit;
39709       }
39710       self->private_data.s_skip_frame[0].scratch = (((uint64_t)(self->private_impl.f_chunk_length)) + 12);
39711       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
39712       if (self->private_data.s_skip_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
39713         self->private_data.s_skip_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
39714         iop_a_src = io2_a_src;
39715         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39716         goto suspend;
39717       }
39718       iop_a_src += self->private_data.s_skip_frame[0].scratch;
39719       self->private_impl.f_chunk_length = 0;
39720     }
39721     label__0__break:;
39722     wuffs_base__u32__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1);
39723     if (self->private_impl.f_num_decoded_frames_value < self->private_impl.f_num_animation_frames_value) {
39724       self->private_impl.f_call_sequence = 5;
39725     } else {
39726       self->private_impl.f_call_sequence = 255;
39727     }
39728 
39729     ok:
39730     self->private_impl.p_skip_frame[0] = 0;
39731     goto exit;
39732   }
39733 
39734   goto suspend;
39735   suspend:
39736   self->private_impl.p_skip_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
39737 
39738   goto exit;
39739   exit:
39740   if (a_src) {
39741     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
39742   }
39743 
39744   return status;
39745 }
39746 
39747 // -------- func png.decoder.decode_frame
39748 
39749 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)39750 wuffs_png__decoder__decode_frame(
39751     wuffs_png__decoder* self,
39752     wuffs_base__pixel_buffer* a_dst,
39753     wuffs_base__io_buffer* a_src,
39754     wuffs_base__pixel_blend a_blend,
39755     wuffs_base__slice_u8 a_workbuf,
39756     wuffs_base__decode_frame_options* a_opts) {
39757   if (!self) {
39758     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
39759   }
39760   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
39761     return wuffs_base__make_status(
39762         (self->private_impl.magic == WUFFS_BASE__DISABLED)
39763         ? wuffs_base__error__disabled_by_previous_error
39764         : wuffs_base__error__initialize_not_called);
39765   }
39766   if (!a_dst || !a_src) {
39767     self->private_impl.magic = WUFFS_BASE__DISABLED;
39768     return wuffs_base__make_status(wuffs_base__error__bad_argument);
39769   }
39770   if ((self->private_impl.active_coroutine != 0) &&
39771       (self->private_impl.active_coroutine != 3)) {
39772     self->private_impl.magic = WUFFS_BASE__DISABLED;
39773     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
39774   }
39775   self->private_impl.active_coroutine = 0;
39776   wuffs_base__status status = wuffs_base__make_status(NULL);
39777 
39778   uint32_t v_seq_num = 0;
39779   wuffs_base__status v_status = wuffs_base__make_status(NULL);
39780   uint32_t v_pass_width = 0;
39781   uint32_t v_pass_height = 0;
39782 
39783   const uint8_t* iop_a_src = NULL;
39784   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39785   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39786   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39787   if (a_src) {
39788     io0_a_src = a_src->data.ptr;
39789     io1_a_src = io0_a_src + a_src->meta.ri;
39790     iop_a_src = io1_a_src;
39791     io2_a_src = io0_a_src + a_src->meta.wi;
39792   }
39793 
39794   uint32_t coro_susp_point = self->private_impl.p_decode_frame[0];
39795   switch (coro_susp_point) {
39796     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
39797 
39798     if (self->private_impl.f_call_sequence == 255) {
39799       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
39800       goto ok;
39801     } else if (self->private_impl.f_call_sequence != 4) {
39802       if (a_src) {
39803         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
39804       }
39805       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
39806       status = wuffs_png__decoder__decode_frame_config(self, NULL, a_src);
39807       if (a_src) {
39808         iop_a_src = a_src->data.ptr + a_src->meta.ri;
39809       }
39810       if (status.repr) {
39811         goto suspend;
39812       }
39813     }
39814     while (true) {
39815       while (((uint64_t)(io2_a_src - iop_a_src)) < 8) {
39816         if (a_src && a_src->meta.closed) {
39817           status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39818           goto exit;
39819         }
39820         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39821         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
39822       }
39823       self->private_impl.f_chunk_length = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
39824       self->private_impl.f_chunk_type = ((uint32_t)((wuffs_base__peek_u64le__no_bounds_check(iop_a_src) >> 32)));
39825       if (self->private_impl.f_chunk_type == 1413563465) {
39826         self->private_impl.f_chunk_type_array[0] = 73;
39827         self->private_impl.f_chunk_type_array[1] = 68;
39828         self->private_impl.f_chunk_type_array[2] = 65;
39829         self->private_impl.f_chunk_type_array[3] = 84;
39830         iop_a_src += 8;
39831         if ( ! self->private_impl.f_ignore_checksum) {
39832           wuffs_base__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32,
39833               sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
39834           wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__make_slice_u8(self->private_impl.f_chunk_type_array, 4));
39835         }
39836         goto label__0__break;
39837       } else if (self->private_impl.f_chunk_type == 1413571686) {
39838         self->private_impl.f_chunk_type_array[0] = 102;
39839         self->private_impl.f_chunk_type_array[1] = 100;
39840         self->private_impl.f_chunk_type_array[2] = 65;
39841         self->private_impl.f_chunk_type_array[3] = 84;
39842         if (self->private_impl.f_chunk_length < 4) {
39843           status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39844           goto exit;
39845         }
39846         self->private_impl.f_chunk_length -= 4;
39847         iop_a_src += 8;
39848         {
39849           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
39850           uint32_t t_0;
39851           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
39852             t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
39853             iop_a_src += 4;
39854           } else {
39855             self->private_data.s_decode_frame[0].scratch = 0;
39856             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
39857             while (true) {
39858               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39859                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39860                 goto suspend;
39861               }
39862               uint64_t* scratch = &self->private_data.s_decode_frame[0].scratch;
39863               uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFF));
39864               *scratch >>= 8;
39865               *scratch <<= 8;
39866               *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
39867               if (num_bits_0 == 24) {
39868                 t_0 = ((uint32_t)(*scratch >> 32));
39869                 break;
39870               }
39871               num_bits_0 += 8;
39872               *scratch |= ((uint64_t)(num_bits_0));
39873             }
39874           }
39875           v_seq_num = t_0;
39876         }
39877         if (v_seq_num != self->private_impl.f_next_animation_seq_num) {
39878           status = wuffs_base__make_status(wuffs_png__error__bad_animation_sequence_number);
39879           goto exit;
39880         } else if (self->private_impl.f_next_animation_seq_num >= 4294967295) {
39881           status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file);
39882           goto exit;
39883         }
39884         self->private_impl.f_next_animation_seq_num += 1;
39885         goto label__0__break;
39886       } else if (self->private_impl.f_chunk_type == 1280598886) {
39887         status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39888         goto exit;
39889       }
39890       self->private_data.s_decode_frame[0].scratch = (((uint64_t)(self->private_impl.f_chunk_length)) + 12);
39891       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
39892       if (self->private_data.s_decode_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
39893         self->private_data.s_decode_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
39894         iop_a_src = io2_a_src;
39895         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39896         goto suspend;
39897       }
39898       iop_a_src += self->private_data.s_decode_frame[0].scratch;
39899       self->private_impl.f_chunk_length = 0;
39900     }
39901     label__0__break:;
39902     if (self->private_impl.f_zlib_is_dirty) {
39903       wuffs_base__ignore_status(wuffs_zlib__decoder__initialize(&self->private_data.f_zlib,
39904           sizeof (wuffs_zlib__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
39905       if (self->private_impl.f_ignore_checksum) {
39906         wuffs_zlib__decoder__set_quirk_enabled(&self->private_data.f_zlib, 1, true);
39907       }
39908     }
39909     self->private_impl.f_zlib_is_dirty = true;
39910     v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
39911         wuffs_base__pixel_buffer__pixel_format(a_dst),
39912         wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)),
39913         wuffs_base__utility__make_pixel_format(self->private_impl.f_src_pixfmt),
39914         wuffs_base__make_slice_u8(self->private_data.f_src_palette, 1024),
39915         a_blend);
39916     if ( ! wuffs_base__status__is_ok(&v_status)) {
39917       status = v_status;
39918       if (wuffs_base__status__is_error(&status)) {
39919         goto exit;
39920       } else if (wuffs_base__status__is_suspension(&status)) {
39921         status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
39922         goto exit;
39923       }
39924       goto ok;
39925     }
39926     self->private_impl.f_workbuf_hist_pos_base = 0;
39927     while (true) {
39928       if (self->private_impl.f_chunk_type_array[0] == 73) {
39929         v_pass_width = (16777215 & ((((uint32_t)(WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][1])) + self->private_impl.f_width) >> WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][0]));
39930         v_pass_height = (16777215 & ((((uint32_t)(WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][4])) + self->private_impl.f_height) >> WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][3]));
39931       } else {
39932         v_pass_width = (16777215 & ((uint32_t)(self->private_impl.f_frame_rect_x1 - self->private_impl.f_frame_rect_x0)));
39933         v_pass_height = (16777215 & ((uint32_t)(self->private_impl.f_frame_rect_y1 - self->private_impl.f_frame_rect_y0)));
39934       }
39935       if ((v_pass_width > 0) && (v_pass_height > 0)) {
39936         self->private_impl.f_pass_bytes_per_row = wuffs_png__decoder__calculate_bytes_per_row(self, v_pass_width);
39937         self->private_impl.f_pass_workbuf_length = (((uint64_t)(v_pass_height)) * (1 + self->private_impl.f_pass_bytes_per_row));
39938         if (a_src) {
39939           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
39940         }
39941         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
39942         status = wuffs_png__decoder__decode_pass(self, a_src, a_workbuf);
39943         if (a_src) {
39944           iop_a_src = a_src->data.ptr + a_src->meta.ri;
39945         }
39946         if (status.repr) {
39947           goto suspend;
39948         }
39949         v_status = wuffs_png__decoder__filter_and_swizzle(self, a_dst, a_workbuf);
39950         if ( ! wuffs_base__status__is_ok(&v_status)) {
39951           status = v_status;
39952           if (wuffs_base__status__is_error(&status)) {
39953             goto exit;
39954           } else if (wuffs_base__status__is_suspension(&status)) {
39955             status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
39956             goto exit;
39957           }
39958           goto ok;
39959         }
39960         self->private_impl.f_workbuf_hist_pos_base += self->private_impl.f_pass_workbuf_length;
39961       }
39962       if ((self->private_impl.f_interlace_pass == 0) || (self->private_impl.f_interlace_pass >= 7)) {
39963         goto label__1__break;
39964       }
39965 #if defined(__GNUC__)
39966 #pragma GCC diagnostic push
39967 #pragma GCC diagnostic ignored "-Wconversion"
39968 #endif
39969       self->private_impl.f_interlace_pass += 1;
39970 #if defined(__GNUC__)
39971 #pragma GCC diagnostic pop
39972 #endif
39973     }
39974     label__1__break:;
39975     wuffs_base__u32__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1);
39976     if (self->private_impl.f_num_decoded_frames_value < self->private_impl.f_num_animation_frames_value) {
39977       self->private_impl.f_call_sequence = 5;
39978     } else {
39979       self->private_impl.f_call_sequence = 255;
39980     }
39981 
39982     ok:
39983     self->private_impl.p_decode_frame[0] = 0;
39984     goto exit;
39985   }
39986 
39987   goto suspend;
39988   suspend:
39989   self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
39990   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
39991 
39992   goto exit;
39993   exit:
39994   if (a_src) {
39995     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
39996   }
39997 
39998   if (wuffs_base__status__is_error(&status)) {
39999     self->private_impl.magic = WUFFS_BASE__DISABLED;
40000   }
40001   return status;
40002 }
40003 
40004 // -------- func png.decoder.decode_pass
40005 
40006 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)40007 wuffs_png__decoder__decode_pass(
40008     wuffs_png__decoder* self,
40009     wuffs_base__io_buffer* a_src,
40010     wuffs_base__slice_u8 a_workbuf) {
40011   wuffs_base__status status = wuffs_base__make_status(NULL);
40012 
40013   wuffs_base__io_buffer u_w = wuffs_base__empty_io_buffer();
40014   wuffs_base__io_buffer* v_w = &u_w;
40015   uint8_t* iop_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40016   uint8_t* io0_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40017   uint8_t* io1_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40018   uint8_t* io2_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40019   uint64_t v_w_mark = 0;
40020   uint64_t v_r_mark = 0;
40021   wuffs_base__status v_zlib_status = wuffs_base__make_status(NULL);
40022   uint32_t v_checksum_have = 0;
40023   uint32_t v_checksum_want = 0;
40024   uint32_t v_seq_num = 0;
40025 
40026   const uint8_t* iop_a_src = NULL;
40027   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40028   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40029   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40030   if (a_src) {
40031     io0_a_src = a_src->data.ptr;
40032     io1_a_src = io0_a_src + a_src->meta.ri;
40033     iop_a_src = io1_a_src;
40034     io2_a_src = io0_a_src + a_src->meta.wi;
40035   }
40036 
40037   uint32_t coro_susp_point = self->private_impl.p_decode_pass[0];
40038   switch (coro_susp_point) {
40039     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
40040 
40041     self->private_impl.f_workbuf_wi = 0;
40042     label__0__continue:;
40043     while (true) {
40044       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)))) {
40045         status = wuffs_base__make_status(wuffs_base__error__bad_workbuf_length);
40046         goto exit;
40047       }
40048       {
40049         wuffs_base__io_buffer* o_0_v_w = v_w;
40050         uint8_t *o_0_iop_v_w = iop_v_w;
40051         uint8_t *o_0_io0_v_w = io0_v_w;
40052         uint8_t *o_0_io1_v_w = io1_v_w;
40053         uint8_t *o_0_io2_v_w = io2_v_w;
40054         v_w = wuffs_base__io_writer__set(
40055             &u_w,
40056             &iop_v_w,
40057             &io0_v_w,
40058             &io1_v_w,
40059             &io2_v_w,
40060             wuffs_base__slice_u8__subslice_ij(a_workbuf,
40061             self->private_impl.f_workbuf_wi,
40062             self->private_impl.f_pass_workbuf_length),
40063             ((uint64_t)(self->private_impl.f_workbuf_hist_pos_base + self->private_impl.f_workbuf_wi)));
40064         {
40065           const uint8_t *o_1_io2_a_src = io2_a_src;
40066           wuffs_base__io_reader__limit(&io2_a_src, iop_a_src,
40067               ((uint64_t)(self->private_impl.f_chunk_length)));
40068           if (a_src) {
40069             a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
40070           }
40071           v_w_mark = ((uint64_t)(iop_v_w - io0_v_w));
40072           v_r_mark = ((uint64_t)(iop_a_src - io0_a_src));
40073           {
40074             u_w.meta.wi = ((size_t)(iop_v_w - u_w.data.ptr));
40075             if (a_src) {
40076               a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
40077             }
40078             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());
40079             v_zlib_status = t_0;
40080             iop_v_w = u_w.data.ptr + u_w.meta.wi;
40081             if (a_src) {
40082               iop_a_src = a_src->data.ptr + a_src->meta.ri;
40083             }
40084           }
40085           if ( ! self->private_impl.f_ignore_checksum) {
40086             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));
40087           }
40088           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))) & 4294967295))));
40089           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))));
40090           io2_a_src = o_1_io2_a_src;
40091           if (a_src) {
40092             a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
40093           }
40094         }
40095         v_w = o_0_v_w;
40096         iop_v_w = o_0_iop_v_w;
40097         io0_v_w = o_0_io0_v_w;
40098         io1_v_w = o_0_io1_v_w;
40099         io2_v_w = o_0_io2_v_w;
40100       }
40101       if (wuffs_base__status__is_ok(&v_zlib_status)) {
40102         if (self->private_impl.f_chunk_length > 0) {
40103           status = wuffs_base__make_status(wuffs_base__error__too_much_data);
40104           goto exit;
40105         }
40106         {
40107           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
40108           uint32_t t_1;
40109           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
40110             t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
40111             iop_a_src += 4;
40112           } else {
40113             self->private_data.s_decode_pass[0].scratch = 0;
40114             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
40115             while (true) {
40116               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
40117                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40118                 goto suspend;
40119               }
40120               uint64_t* scratch = &self->private_data.s_decode_pass[0].scratch;
40121               uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFF));
40122               *scratch >>= 8;
40123               *scratch <<= 8;
40124               *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
40125               if (num_bits_1 == 24) {
40126                 t_1 = ((uint32_t)(*scratch >> 32));
40127                 break;
40128               }
40129               num_bits_1 += 8;
40130               *scratch |= ((uint64_t)(num_bits_1));
40131             }
40132           }
40133           v_checksum_want = t_1;
40134         }
40135         if ( ! self->private_impl.f_ignore_checksum && (self->private_impl.f_chunk_type_array[0] == 73)) {
40136           v_checksum_have = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__utility__empty_slice_u8());
40137           if (v_checksum_have != v_checksum_want) {
40138             status = wuffs_base__make_status(wuffs_png__error__bad_checksum);
40139             goto exit;
40140           }
40141         }
40142         goto label__0__break;
40143       } else if (v_zlib_status.repr == wuffs_base__suspension__short_write) {
40144         if ((1 <= self->private_impl.f_interlace_pass) && (self->private_impl.f_interlace_pass <= 6)) {
40145           goto label__0__break;
40146         }
40147         status = wuffs_base__make_status(wuffs_base__error__too_much_data);
40148         goto exit;
40149       } else if (v_zlib_status.repr != wuffs_base__suspension__short_read) {
40150         status = v_zlib_status;
40151         if (wuffs_base__status__is_error(&status)) {
40152           goto exit;
40153         } else if (wuffs_base__status__is_suspension(&status)) {
40154           status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
40155           goto exit;
40156         }
40157         goto ok;
40158       } else if (self->private_impl.f_chunk_length == 0) {
40159         {
40160           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
40161           uint32_t t_2;
40162           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
40163             t_2 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
40164             iop_a_src += 4;
40165           } else {
40166             self->private_data.s_decode_pass[0].scratch = 0;
40167             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
40168             while (true) {
40169               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
40170                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40171                 goto suspend;
40172               }
40173               uint64_t* scratch = &self->private_data.s_decode_pass[0].scratch;
40174               uint32_t num_bits_2 = ((uint32_t)(*scratch & 0xFF));
40175               *scratch >>= 8;
40176               *scratch <<= 8;
40177               *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_2);
40178               if (num_bits_2 == 24) {
40179                 t_2 = ((uint32_t)(*scratch >> 32));
40180                 break;
40181               }
40182               num_bits_2 += 8;
40183               *scratch |= ((uint64_t)(num_bits_2));
40184             }
40185           }
40186           v_checksum_want = t_2;
40187         }
40188         if ( ! self->private_impl.f_ignore_checksum && (self->private_impl.f_chunk_type_array[0] == 73)) {
40189           v_checksum_have = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__utility__empty_slice_u8());
40190           if (v_checksum_have != v_checksum_want) {
40191             status = wuffs_base__make_status(wuffs_png__error__bad_checksum);
40192             goto exit;
40193           }
40194         }
40195         {
40196           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
40197           uint32_t t_3;
40198           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
40199             t_3 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
40200             iop_a_src += 4;
40201           } else {
40202             self->private_data.s_decode_pass[0].scratch = 0;
40203             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
40204             while (true) {
40205               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
40206                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40207                 goto suspend;
40208               }
40209               uint64_t* scratch = &self->private_data.s_decode_pass[0].scratch;
40210               uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFF));
40211               *scratch >>= 8;
40212               *scratch <<= 8;
40213               *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3);
40214               if (num_bits_3 == 24) {
40215                 t_3 = ((uint32_t)(*scratch >> 32));
40216                 break;
40217               }
40218               num_bits_3 += 8;
40219               *scratch |= ((uint64_t)(num_bits_3));
40220             }
40221           }
40222           self->private_impl.f_chunk_length = t_3;
40223         }
40224         {
40225           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
40226           uint32_t t_4;
40227           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
40228             t_4 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
40229             iop_a_src += 4;
40230           } else {
40231             self->private_data.s_decode_pass[0].scratch = 0;
40232             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
40233             while (true) {
40234               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
40235                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40236                 goto suspend;
40237               }
40238               uint64_t* scratch = &self->private_data.s_decode_pass[0].scratch;
40239               uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
40240               *scratch <<= 8;
40241               *scratch >>= 8;
40242               *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
40243               if (num_bits_4 == 24) {
40244                 t_4 = ((uint32_t)(*scratch));
40245                 break;
40246               }
40247               num_bits_4 += 8;
40248               *scratch |= ((uint64_t)(num_bits_4)) << 56;
40249             }
40250           }
40251           self->private_impl.f_chunk_type = t_4;
40252         }
40253         if (self->private_impl.f_chunk_type_array[0] == 73) {
40254           if (self->private_impl.f_chunk_type != 1413563465) {
40255             status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
40256             goto exit;
40257           }
40258           if ( ! self->private_impl.f_ignore_checksum) {
40259             wuffs_base__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32,
40260                 sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
40261             wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__make_slice_u8(self->private_impl.f_chunk_type_array, 4));
40262           }
40263         } else {
40264           if ((self->private_impl.f_chunk_type != 1413571686) || (self->private_impl.f_chunk_length < 4)) {
40265             status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
40266             goto exit;
40267           }
40268           self->private_impl.f_chunk_length -= 4;
40269           {
40270             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
40271             uint32_t t_5;
40272             if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
40273               t_5 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
40274               iop_a_src += 4;
40275             } else {
40276               self->private_data.s_decode_pass[0].scratch = 0;
40277               WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
40278               while (true) {
40279                 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
40280                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40281                   goto suspend;
40282                 }
40283                 uint64_t* scratch = &self->private_data.s_decode_pass[0].scratch;
40284                 uint32_t num_bits_5 = ((uint32_t)(*scratch & 0xFF));
40285                 *scratch >>= 8;
40286                 *scratch <<= 8;
40287                 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_5);
40288                 if (num_bits_5 == 24) {
40289                   t_5 = ((uint32_t)(*scratch >> 32));
40290                   break;
40291                 }
40292                 num_bits_5 += 8;
40293                 *scratch |= ((uint64_t)(num_bits_5));
40294               }
40295             }
40296             v_seq_num = t_5;
40297           }
40298           if (v_seq_num != self->private_impl.f_next_animation_seq_num) {
40299             status = wuffs_base__make_status(wuffs_png__error__bad_animation_sequence_number);
40300             goto exit;
40301           } else if (self->private_impl.f_next_animation_seq_num >= 4294967295) {
40302             status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file);
40303             goto exit;
40304           }
40305           self->private_impl.f_next_animation_seq_num += 1;
40306         }
40307         goto label__0__continue;
40308       } else if (((uint64_t)(io2_a_src - iop_a_src)) > 0) {
40309         status = wuffs_base__make_status(wuffs_png__error__internal_error_zlib_decoder_did_not_exhaust_its_input);
40310         goto exit;
40311       }
40312       status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40313       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(11);
40314     }
40315     label__0__break:;
40316     if (self->private_impl.f_workbuf_wi != self->private_impl.f_pass_workbuf_length) {
40317       status = wuffs_base__make_status(wuffs_base__error__not_enough_data);
40318       goto exit;
40319     } else if (0 < ((uint64_t)(a_workbuf.len))) {
40320       if (a_workbuf.ptr[0] == 4) {
40321         a_workbuf.ptr[0] = 1;
40322       }
40323     }
40324 
40325     ok:
40326     self->private_impl.p_decode_pass[0] = 0;
40327     goto exit;
40328   }
40329 
40330   goto suspend;
40331   suspend:
40332   self->private_impl.p_decode_pass[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
40333 
40334   goto exit;
40335   exit:
40336   if (a_src) {
40337     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
40338   }
40339 
40340   return status;
40341 }
40342 
40343 // -------- func png.decoder.frame_dirty_rect
40344 
40345 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
wuffs_png__decoder__frame_dirty_rect(const wuffs_png__decoder * self)40346 wuffs_png__decoder__frame_dirty_rect(
40347     const wuffs_png__decoder* self) {
40348   if (!self) {
40349     return wuffs_base__utility__empty_rect_ie_u32();
40350   }
40351   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
40352       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
40353     return wuffs_base__utility__empty_rect_ie_u32();
40354   }
40355 
40356   return wuffs_base__utility__make_rect_ie_u32(
40357       self->private_impl.f_frame_rect_x0,
40358       self->private_impl.f_frame_rect_y0,
40359       self->private_impl.f_frame_rect_x1,
40360       self->private_impl.f_frame_rect_y1);
40361 }
40362 
40363 // -------- func png.decoder.num_animation_loops
40364 
40365 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_png__decoder__num_animation_loops(const wuffs_png__decoder * self)40366 wuffs_png__decoder__num_animation_loops(
40367     const wuffs_png__decoder* self) {
40368   if (!self) {
40369     return 0;
40370   }
40371   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
40372       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
40373     return 0;
40374   }
40375 
40376   return self->private_impl.f_num_animation_loops_value;
40377 }
40378 
40379 // -------- func png.decoder.num_decoded_frame_configs
40380 
40381 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_png__decoder__num_decoded_frame_configs(const wuffs_png__decoder * self)40382 wuffs_png__decoder__num_decoded_frame_configs(
40383     const wuffs_png__decoder* self) {
40384   if (!self) {
40385     return 0;
40386   }
40387   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
40388       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
40389     return 0;
40390   }
40391 
40392   return ((uint64_t)(self->private_impl.f_num_decoded_frame_configs_value));
40393 }
40394 
40395 // -------- func png.decoder.num_decoded_frames
40396 
40397 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_png__decoder__num_decoded_frames(const wuffs_png__decoder * self)40398 wuffs_png__decoder__num_decoded_frames(
40399     const wuffs_png__decoder* self) {
40400   if (!self) {
40401     return 0;
40402   }
40403   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
40404       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
40405     return 0;
40406   }
40407 
40408   return ((uint64_t)(self->private_impl.f_num_decoded_frames_value));
40409 }
40410 
40411 // -------- func png.decoder.restart_frame
40412 
40413 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)40414 wuffs_png__decoder__restart_frame(
40415     wuffs_png__decoder* self,
40416     uint64_t a_index,
40417     uint64_t a_io_position) {
40418   if (!self) {
40419     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
40420   }
40421   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
40422     return wuffs_base__make_status(
40423         (self->private_impl.magic == WUFFS_BASE__DISABLED)
40424         ? wuffs_base__error__disabled_by_previous_error
40425         : wuffs_base__error__initialize_not_called);
40426   }
40427 
40428   if (self->private_impl.f_call_sequence < 3) {
40429     return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
40430   } else if ((a_index >= ((uint64_t)(self->private_impl.f_num_animation_frames_value))) || ((a_index == 0) && (a_io_position != self->private_impl.f_first_config_io_position))) {
40431     return wuffs_base__make_status(wuffs_base__error__bad_argument);
40432   }
40433   self->private_impl.f_call_sequence = 3;
40434   if (self->private_impl.f_interlace_pass >= 1) {
40435     self->private_impl.f_interlace_pass = 1;
40436   }
40437   self->private_impl.f_frame_config_io_position = a_io_position;
40438   self->private_impl.f_num_decoded_frame_configs_value = ((uint32_t)((a_index & 4294967295)));
40439   self->private_impl.f_num_decoded_frames_value = self->private_impl.f_num_decoded_frame_configs_value;
40440   return wuffs_base__make_status(NULL);
40441 }
40442 
40443 // -------- func png.decoder.set_report_metadata
40444 
40445 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)40446 wuffs_png__decoder__set_report_metadata(
40447     wuffs_png__decoder* self,
40448     uint32_t a_fourcc,
40449     bool a_report) {
40450   if (!self) {
40451     return wuffs_base__make_empty_struct();
40452   }
40453   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
40454     return wuffs_base__make_empty_struct();
40455   }
40456 
40457   if (a_fourcc == 1128813133) {
40458     self->private_impl.f_report_metadata_chrm = a_report;
40459   } else if (a_fourcc == 1195461953) {
40460     self->private_impl.f_report_metadata_gama = a_report;
40461   } else if (a_fourcc == 1229144912) {
40462     self->private_impl.f_report_metadata_iccp = a_report;
40463   } else if (a_fourcc == 1263947808) {
40464     self->private_impl.f_report_metadata_kvp = a_report;
40465   } else if (a_fourcc == 1397901122) {
40466     self->private_impl.f_report_metadata_srgb = a_report;
40467   }
40468   return wuffs_base__make_empty_struct();
40469 }
40470 
40471 // -------- func png.decoder.tell_me_more
40472 
40473 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)40474 wuffs_png__decoder__tell_me_more(
40475     wuffs_png__decoder* self,
40476     wuffs_base__io_buffer* a_dst,
40477     wuffs_base__more_information* a_minfo,
40478     wuffs_base__io_buffer* a_src) {
40479   if (!self) {
40480     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
40481   }
40482   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
40483     return wuffs_base__make_status(
40484         (self->private_impl.magic == WUFFS_BASE__DISABLED)
40485         ? wuffs_base__error__disabled_by_previous_error
40486         : wuffs_base__error__initialize_not_called);
40487   }
40488   if (!a_dst || !a_src) {
40489     self->private_impl.magic = WUFFS_BASE__DISABLED;
40490     return wuffs_base__make_status(wuffs_base__error__bad_argument);
40491   }
40492   if ((self->private_impl.active_coroutine != 0) &&
40493       (self->private_impl.active_coroutine != 4)) {
40494     self->private_impl.magic = WUFFS_BASE__DISABLED;
40495     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
40496   }
40497   self->private_impl.active_coroutine = 0;
40498   wuffs_base__status status = wuffs_base__make_status(NULL);
40499 
40500   uint8_t v_c = 0;
40501   uint16_t v_c2 = 0;
40502   wuffs_base__io_buffer u_w = wuffs_base__empty_io_buffer();
40503   wuffs_base__io_buffer* v_w = &u_w;
40504   uint8_t* iop_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40505   uint8_t* io0_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40506   uint8_t* io1_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40507   uint8_t* io2_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40508   uint64_t v_num_written = 0;
40509   uint64_t v_w_mark = 0;
40510   uint64_t v_r_mark = 0;
40511   wuffs_base__status v_zlib_status = wuffs_base__make_status(NULL);
40512 
40513   uint8_t* iop_a_dst = NULL;
40514   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40515   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40516   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40517   if (a_dst) {
40518     io0_a_dst = a_dst->data.ptr;
40519     io1_a_dst = io0_a_dst + a_dst->meta.wi;
40520     iop_a_dst = io1_a_dst;
40521     io2_a_dst = io0_a_dst + a_dst->data.len;
40522     if (a_dst->meta.closed) {
40523       io2_a_dst = iop_a_dst;
40524     }
40525   }
40526   const uint8_t* iop_a_src = NULL;
40527   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40528   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40529   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40530   if (a_src) {
40531     io0_a_src = a_src->data.ptr;
40532     io1_a_src = io0_a_src + a_src->meta.ri;
40533     iop_a_src = io1_a_src;
40534     io2_a_src = io0_a_src + a_src->meta.wi;
40535   }
40536 
40537   uint32_t coro_susp_point = self->private_impl.p_tell_me_more[0];
40538   if (coro_susp_point) {
40539     v_zlib_status = self->private_data.s_tell_me_more[0].v_zlib_status;
40540   }
40541   switch (coro_susp_point) {
40542     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
40543 
40544     if (self->private_impl.f_call_sequence != 1) {
40545       status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
40546       goto exit;
40547     }
40548     if (self->private_impl.f_metadata_fourcc == 0) {
40549       status = wuffs_base__make_status(wuffs_base__error__no_more_information);
40550       goto exit;
40551     }
40552     if (self->private_impl.f_metadata_is_zlib_compressed) {
40553       if (self->private_impl.f_zlib_is_dirty) {
40554         wuffs_base__ignore_status(wuffs_zlib__decoder__initialize(&self->private_data.f_zlib,
40555             sizeof (wuffs_zlib__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
40556         if (self->private_impl.f_ignore_checksum) {
40557           wuffs_zlib__decoder__set_quirk_enabled(&self->private_data.f_zlib, 1, true);
40558         }
40559       }
40560       self->private_impl.f_zlib_is_dirty = true;
40561       self->private_impl.f_ztxt_hist_pos = 0;
40562     }
40563     label__loop__continue:;
40564     while (true) {
40565       if (a_minfo != NULL) {
40566         wuffs_base__more_information__set(a_minfo,
40567             self->private_impl.f_metadata_flavor,
40568             self->private_impl.f_metadata_fourcc,
40569             self->private_impl.f_metadata_x,
40570             self->private_impl.f_metadata_y,
40571             self->private_impl.f_metadata_z);
40572       }
40573       if (self->private_impl.f_metadata_flavor != 4) {
40574         goto label__loop__break;
40575       }
40576       if (self->private_impl.f_metadata_is_zlib_compressed) {
40577         if (self->private_impl.f_chunk_type == 1346585449) {
40578           {
40579             const uint8_t *o_0_io2_a_src = io2_a_src;
40580             wuffs_base__io_reader__limit(&io2_a_src, iop_a_src,
40581                 ((uint64_t)(self->private_impl.f_chunk_length)));
40582             if (a_src) {
40583               a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
40584             }
40585             v_r_mark = ((uint64_t)(iop_a_src - io0_a_src));
40586             {
40587               if (a_dst) {
40588                 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
40589               }
40590               if (a_src) {
40591                 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
40592               }
40593               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());
40594               v_zlib_status = t_0;
40595               if (a_dst) {
40596                 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
40597               }
40598               if (a_src) {
40599                 iop_a_src = a_src->data.ptr + a_src->meta.ri;
40600               }
40601             }
40602             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))) & 4294967295))));
40603             io2_a_src = o_0_io2_a_src;
40604             if (a_src) {
40605               a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
40606             }
40607           }
40608           if (wuffs_base__status__is_ok(&v_zlib_status)) {
40609             self->private_impl.f_metadata_is_zlib_compressed = false;
40610             goto label__loop__break;
40611           } else if ( ! wuffs_base__status__is_suspension(&v_zlib_status)) {
40612             status = v_zlib_status;
40613             if (wuffs_base__status__is_error(&status)) {
40614               goto exit;
40615             } else if (wuffs_base__status__is_suspension(&status)) {
40616               status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
40617               goto exit;
40618             }
40619             goto ok;
40620           }
40621           status = v_zlib_status;
40622           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
40623         } else if (self->private_impl.f_chunk_type == 1951945833) {
40624           {
40625             const uint8_t *o_1_io2_a_src = io2_a_src;
40626             wuffs_base__io_reader__limit(&io2_a_src, iop_a_src,
40627                 ((uint64_t)(self->private_impl.f_chunk_length)));
40628             if (a_src) {
40629               a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
40630             }
40631             v_r_mark = ((uint64_t)(iop_a_src - io0_a_src));
40632             {
40633               if (a_dst) {
40634                 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
40635               }
40636               if (a_src) {
40637                 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
40638               }
40639               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());
40640               v_zlib_status = t_1;
40641               if (a_dst) {
40642                 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
40643               }
40644               if (a_src) {
40645                 iop_a_src = a_src->data.ptr + a_src->meta.ri;
40646               }
40647             }
40648             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))) & 4294967295))));
40649             io2_a_src = o_1_io2_a_src;
40650             if (a_src) {
40651               a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
40652             }
40653           }
40654           if (wuffs_base__status__is_ok(&v_zlib_status)) {
40655             self->private_impl.f_metadata_is_zlib_compressed = false;
40656             goto label__loop__break;
40657           } else if ( ! wuffs_base__status__is_suspension(&v_zlib_status)) {
40658             status = v_zlib_status;
40659             if (wuffs_base__status__is_error(&status)) {
40660               goto exit;
40661             } else if (wuffs_base__status__is_suspension(&status)) {
40662               status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
40663               goto exit;
40664             }
40665             goto ok;
40666           }
40667           status = v_zlib_status;
40668           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
40669         } else if (self->private_impl.f_chunk_type == 1951945850) {
40670           if (self->private_impl.f_ztxt_ri == self->private_impl.f_ztxt_wi) {
40671             {
40672               wuffs_base__io_buffer* o_2_v_w = v_w;
40673               uint8_t *o_2_iop_v_w = iop_v_w;
40674               uint8_t *o_2_io0_v_w = io0_v_w;
40675               uint8_t *o_2_io1_v_w = io1_v_w;
40676               uint8_t *o_2_io2_v_w = io2_v_w;
40677               v_w = wuffs_base__io_writer__set(
40678                   &u_w,
40679                   &iop_v_w,
40680                   &io0_v_w,
40681                   &io1_v_w,
40682                   &io2_v_w,
40683                   wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024),
40684                   self->private_impl.f_ztxt_hist_pos);
40685               {
40686                 const uint8_t *o_3_io2_a_src = io2_a_src;
40687                 wuffs_base__io_reader__limit(&io2_a_src, iop_a_src,
40688                     ((uint64_t)(self->private_impl.f_chunk_length)));
40689                 if (a_src) {
40690                   a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
40691                 }
40692                 v_w_mark = ((uint64_t)(iop_v_w - io0_v_w));
40693                 v_r_mark = ((uint64_t)(iop_a_src - io0_a_src));
40694                 {
40695                   u_w.meta.wi = ((size_t)(iop_v_w - u_w.data.ptr));
40696                   if (a_src) {
40697                     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
40698                   }
40699                   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());
40700                   v_zlib_status = t_2;
40701                   iop_v_w = u_w.data.ptr + u_w.meta.wi;
40702                   if (a_src) {
40703                     iop_a_src = a_src->data.ptr + a_src->meta.ri;
40704                   }
40705                 }
40706                 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))) & 4294967295))));
40707                 v_num_written = wuffs_base__io__count_since(v_w_mark, ((uint64_t)(iop_v_w - io0_v_w)));
40708                 io2_a_src = o_3_io2_a_src;
40709                 if (a_src) {
40710                   a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
40711                 }
40712               }
40713               v_w = o_2_v_w;
40714               iop_v_w = o_2_iop_v_w;
40715               io0_v_w = o_2_io0_v_w;
40716               io1_v_w = o_2_io1_v_w;
40717               io2_v_w = o_2_io2_v_w;
40718             }
40719             if (v_num_written > 1024) {
40720               status = wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_i_o);
40721               goto exit;
40722             }
40723             self->private_impl.f_ztxt_ri = 0;
40724             self->private_impl.f_ztxt_wi = ((uint32_t)(v_num_written));
40725             wuffs_base__u64__sat_add_indirect(&self->private_impl.f_ztxt_hist_pos, v_num_written);
40726           }
40727           while (self->private_impl.f_ztxt_ri < self->private_impl.f_ztxt_wi) {
40728             v_c2 = WUFFS_PNG__LATIN_1[self->private_data.f_dst_palette[self->private_impl.f_ztxt_ri]];
40729             if (v_c2 == 0) {
40730               status = wuffs_base__make_status(wuffs_png__error__bad_text_chunk_not_latin_1);
40731               goto exit;
40732             } else if (v_c2 <= 127) {
40733               if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
40734                 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
40735                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
40736                 v_c2 = 0;
40737                 goto label__loop__continue;
40738               }
40739               self->private_impl.f_ztxt_ri += 1;
40740               (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)(v_c2))), iop_a_dst += 1);
40741             } else {
40742               if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 1) {
40743                 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
40744                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
40745                 v_c2 = 0;
40746                 goto label__loop__continue;
40747               }
40748               self->private_impl.f_ztxt_ri += 1;
40749               (wuffs_base__poke_u16le__no_bounds_check(iop_a_dst, v_c2), iop_a_dst += 2);
40750             }
40751           }
40752           if (wuffs_base__status__is_ok(&v_zlib_status)) {
40753             self->private_impl.f_metadata_is_zlib_compressed = false;
40754             goto label__loop__break;
40755           } else if ( ! wuffs_base__status__is_suspension(&v_zlib_status)) {
40756             status = v_zlib_status;
40757             if (wuffs_base__status__is_error(&status)) {
40758               goto exit;
40759             } else if (wuffs_base__status__is_suspension(&status)) {
40760               status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
40761               goto exit;
40762             }
40763             goto ok;
40764           } else if (v_zlib_status.repr != wuffs_base__suspension__short_write) {
40765             status = v_zlib_status;
40766             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
40767           }
40768         } else {
40769           status = wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_chunk_type);
40770           goto exit;
40771         }
40772       } else if ((self->private_impl.f_chunk_type == 1951945833) && (self->private_impl.f_metadata_fourcc == 1263947862)) {
40773         while (true) {
40774           if (self->private_impl.f_chunk_length <= 0) {
40775             goto label__loop__break;
40776           } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
40777             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40778             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
40779             goto label__loop__continue;
40780           } else if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
40781             status = wuffs_base__make_status(wuffs_base__suspension__short_write);
40782             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7);
40783             goto label__loop__continue;
40784           }
40785           self->private_impl.f_chunk_length -= 1;
40786           v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
40787           iop_a_src += 1;
40788           (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, v_c), iop_a_dst += 1);
40789         }
40790       } else {
40791         while (true) {
40792           if (self->private_impl.f_chunk_length <= 0) {
40793             if (self->private_impl.f_metadata_fourcc == 1263947851) {
40794               status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
40795               goto exit;
40796             }
40797             goto label__loop__break;
40798           } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
40799             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40800             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8);
40801             goto label__loop__continue;
40802           }
40803           v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
40804           if (v_c == 0) {
40805             self->private_impl.f_chunk_length -= 1;
40806             iop_a_src += 1;
40807             goto label__loop__break;
40808           }
40809           v_c2 = WUFFS_PNG__LATIN_1[v_c];
40810           if (v_c2 == 0) {
40811             status = wuffs_base__make_status(wuffs_png__error__bad_text_chunk_not_latin_1);
40812             goto exit;
40813           } else if (v_c2 <= 127) {
40814             if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
40815               status = wuffs_base__make_status(wuffs_base__suspension__short_write);
40816               WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9);
40817               v_c2 = 0;
40818               goto label__loop__continue;
40819             }
40820             self->private_impl.f_chunk_length -= 1;
40821             iop_a_src += 1;
40822             (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)(v_c2))), iop_a_dst += 1);
40823           } else {
40824             if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 1) {
40825               status = wuffs_base__make_status(wuffs_base__suspension__short_write);
40826               WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10);
40827               v_c2 = 0;
40828               goto label__loop__continue;
40829             }
40830             self->private_impl.f_chunk_length -= 1;
40831             iop_a_src += 1;
40832             (wuffs_base__poke_u16le__no_bounds_check(iop_a_dst, v_c2), iop_a_dst += 2);
40833           }
40834         }
40835       }
40836     }
40837     label__loop__break:;
40838     if (self->private_impl.f_metadata_fourcc == 1263947851) {
40839       self->private_impl.f_metadata_fourcc = 1263947862;
40840       if (self->private_impl.f_chunk_type == 1951945833) {
40841         if (self->private_impl.f_chunk_length <= 1) {
40842           status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
40843           goto exit;
40844         }
40845         self->private_impl.f_chunk_length -= 2;
40846         {
40847           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
40848           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
40849             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40850             goto suspend;
40851           }
40852           uint8_t t_3 = *iop_a_src++;
40853           v_c = t_3;
40854         }
40855         if (v_c == 0) {
40856           self->private_impl.f_metadata_is_zlib_compressed = false;
40857         } else if (v_c == 1) {
40858           self->private_impl.f_metadata_is_zlib_compressed = true;
40859         } else {
40860           status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
40861           goto exit;
40862         }
40863         {
40864           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
40865           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
40866             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40867             goto suspend;
40868           }
40869           uint8_t t_4 = *iop_a_src++;
40870           v_c = t_4;
40871         }
40872         if ((v_c != 0) && self->private_impl.f_metadata_is_zlib_compressed) {
40873           status = wuffs_base__make_status(wuffs_png__error__unsupported_png_compression_method);
40874           goto exit;
40875         }
40876         self->private_impl.f_metadata_fourcc -= 2;
40877         while (self->private_impl.f_metadata_fourcc != 1263947862) {
40878           self->private_impl.f_metadata_fourcc += 1;
40879           while (true) {
40880             if (self->private_impl.f_chunk_length <= 0) {
40881               status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
40882               goto exit;
40883             }
40884             self->private_impl.f_chunk_length -= 1;
40885             {
40886               WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
40887               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
40888                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40889                 goto suspend;
40890               }
40891               uint8_t t_5 = *iop_a_src++;
40892               v_c = t_5;
40893             }
40894             if (v_c == 0) {
40895               goto label__0__break;
40896             }
40897           }
40898           label__0__break:;
40899         }
40900       } else if (self->private_impl.f_chunk_type == 1951945850) {
40901         if (self->private_impl.f_chunk_length <= 0) {
40902           status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
40903           goto exit;
40904         }
40905         self->private_impl.f_chunk_length -= 1;
40906         {
40907           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
40908           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
40909             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40910             goto suspend;
40911           }
40912           uint8_t t_6 = *iop_a_src++;
40913           v_c = t_6;
40914         }
40915         if (v_c != 0) {
40916           status = wuffs_base__make_status(wuffs_png__error__unsupported_png_compression_method);
40917           goto exit;
40918         }
40919         self->private_impl.f_metadata_is_zlib_compressed = true;
40920       }
40921     } else {
40922       if (self->private_impl.f_chunk_length != 0) {
40923         status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
40924         goto exit;
40925       }
40926       self->private_data.s_tell_me_more[0].scratch = 4;
40927       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
40928       if (self->private_data.s_tell_me_more[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
40929         self->private_data.s_tell_me_more[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
40930         iop_a_src = io2_a_src;
40931         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40932         goto suspend;
40933       }
40934       iop_a_src += self->private_data.s_tell_me_more[0].scratch;
40935       self->private_impl.f_metadata_flavor = 0;
40936       self->private_impl.f_metadata_fourcc = 0;
40937       self->private_impl.f_metadata_x = 0;
40938       self->private_impl.f_metadata_y = 0;
40939       self->private_impl.f_metadata_z = 0;
40940     }
40941     self->private_impl.f_call_sequence = 2;
40942     status = wuffs_base__make_status(NULL);
40943     goto ok;
40944 
40945     ok:
40946     self->private_impl.p_tell_me_more[0] = 0;
40947     goto exit;
40948   }
40949 
40950   goto suspend;
40951   suspend:
40952   self->private_impl.p_tell_me_more[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
40953   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 4 : 0;
40954   self->private_data.s_tell_me_more[0].v_zlib_status = v_zlib_status;
40955 
40956   goto exit;
40957   exit:
40958   if (a_dst) {
40959     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
40960   }
40961   if (a_src) {
40962     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
40963   }
40964 
40965   if (wuffs_base__status__is_error(&status)) {
40966     self->private_impl.magic = WUFFS_BASE__DISABLED;
40967   }
40968   return status;
40969 }
40970 
40971 // -------- func png.decoder.workbuf_len
40972 
40973 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_png__decoder__workbuf_len(const wuffs_png__decoder * self)40974 wuffs_png__decoder__workbuf_len(
40975     const wuffs_png__decoder* self) {
40976   if (!self) {
40977     return wuffs_base__utility__empty_range_ii_u64();
40978   }
40979   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
40980       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
40981     return wuffs_base__utility__empty_range_ii_u64();
40982   }
40983 
40984   return wuffs_base__utility__make_range_ii_u64(self->private_impl.f_overall_workbuf_length, self->private_impl.f_overall_workbuf_length);
40985 }
40986 
40987 // -------- func png.decoder.filter_and_swizzle
40988 
40989 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)40990 wuffs_png__decoder__filter_and_swizzle(
40991     wuffs_png__decoder* self,
40992     wuffs_base__pixel_buffer* a_dst,
40993     wuffs_base__slice_u8 a_workbuf) {
40994   return (*self->private_impl.choosy_filter_and_swizzle)(self, a_dst, a_workbuf);
40995 }
40996 
40997 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)40998 wuffs_png__decoder__filter_and_swizzle__choosy_default(
40999     wuffs_png__decoder* self,
41000     wuffs_base__pixel_buffer* a_dst,
41001     wuffs_base__slice_u8 a_workbuf) {
41002   wuffs_base__pixel_format v_dst_pixfmt = {0};
41003   uint32_t v_dst_bits_per_pixel = 0;
41004   uint64_t v_dst_bytes_per_pixel = 0;
41005   uint64_t v_dst_bytes_per_row0 = 0;
41006   uint64_t v_dst_bytes_per_row1 = 0;
41007   wuffs_base__slice_u8 v_dst_palette = {0};
41008   wuffs_base__table_u8 v_tab = {0};
41009   uint32_t v_y = 0;
41010   wuffs_base__slice_u8 v_dst = {0};
41011   uint8_t v_filter = 0;
41012   wuffs_base__slice_u8 v_curr_row = {0};
41013   wuffs_base__slice_u8 v_prev_row = {0};
41014 
41015   v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
41016   v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
41017   if ((v_dst_bits_per_pixel & 7) != 0) {
41018     return wuffs_base__make_status(wuffs_base__error__unsupported_option);
41019   }
41020   v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8)));
41021   v_dst_bytes_per_row0 = (((uint64_t)(self->private_impl.f_frame_rect_x0)) * v_dst_bytes_per_pixel);
41022   v_dst_bytes_per_row1 = (((uint64_t)(self->private_impl.f_frame_rect_x1)) * v_dst_bytes_per_pixel);
41023   v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024));
41024   v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0);
41025   if (v_dst_bytes_per_row1 < ((uint64_t)(v_tab.width))) {
41026     v_tab = wuffs_base__table_u8__subtable_ij(v_tab,
41027         0,
41028         0,
41029         v_dst_bytes_per_row1,
41030         ((uint64_t)(v_tab.height)));
41031   }
41032   if (v_dst_bytes_per_row0 < ((uint64_t)(v_tab.width))) {
41033     v_tab = wuffs_base__table_u8__subtable_ij(v_tab,
41034         v_dst_bytes_per_row0,
41035         0,
41036         ((uint64_t)(v_tab.width)),
41037         ((uint64_t)(v_tab.height)));
41038   } else {
41039     v_tab = wuffs_base__table_u8__subtable_ij(v_tab,
41040         0,
41041         0,
41042         0,
41043         0);
41044   }
41045   v_y = self->private_impl.f_frame_rect_y0;
41046   while (v_y < self->private_impl.f_frame_rect_y1) {
41047     v_dst = wuffs_base__table_u8__row_u32(v_tab, v_y);
41048     if (1 > ((uint64_t)(a_workbuf.len))) {
41049       return wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_workbuf_length);
41050     }
41051     v_filter = a_workbuf.ptr[0];
41052     a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, 1);
41053     if (self->private_impl.f_pass_bytes_per_row > ((uint64_t)(a_workbuf.len))) {
41054       return wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_workbuf_length);
41055     }
41056     v_curr_row = wuffs_base__slice_u8__subslice_j(a_workbuf, self->private_impl.f_pass_bytes_per_row);
41057     a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, self->private_impl.f_pass_bytes_per_row);
41058     if (v_filter == 0) {
41059     } else if (v_filter == 1) {
41060       wuffs_png__decoder__filter_1(self, v_curr_row);
41061     } else if (v_filter == 2) {
41062       wuffs_png__decoder__filter_2(self, v_curr_row, v_prev_row);
41063     } else if (v_filter == 3) {
41064       wuffs_png__decoder__filter_3(self, v_curr_row, v_prev_row);
41065     } else if (v_filter == 4) {
41066       wuffs_png__decoder__filter_4(self, v_curr_row, v_prev_row);
41067     } else {
41068       return wuffs_base__make_status(wuffs_png__error__bad_filter);
41069     }
41070     wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, v_curr_row);
41071     v_prev_row = v_curr_row;
41072     v_y += 1;
41073   }
41074   return wuffs_base__make_status(NULL);
41075 }
41076 
41077 // -------- func png.decoder.filter_and_swizzle_tricky
41078 
41079 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)41080 wuffs_png__decoder__filter_and_swizzle_tricky(
41081     wuffs_png__decoder* self,
41082     wuffs_base__pixel_buffer* a_dst,
41083     wuffs_base__slice_u8 a_workbuf) {
41084   wuffs_base__pixel_format v_dst_pixfmt = {0};
41085   uint32_t v_dst_bits_per_pixel = 0;
41086   uint64_t v_dst_bytes_per_pixel = 0;
41087   uint64_t v_dst_bytes_per_row1 = 0;
41088   wuffs_base__slice_u8 v_dst_palette = {0};
41089   wuffs_base__table_u8 v_tab = {0};
41090   uint64_t v_src_bytes_per_pixel = 0;
41091   uint32_t v_x = 0;
41092   uint32_t v_y = 0;
41093   uint64_t v_i = 0;
41094   wuffs_base__slice_u8 v_dst = {0};
41095   uint8_t v_filter = 0;
41096   wuffs_base__slice_u8 v_s = {0};
41097   wuffs_base__slice_u8 v_curr_row = {0};
41098   wuffs_base__slice_u8 v_prev_row = {0};
41099   uint8_t v_bits_unpacked[8] = {0};
41100   uint8_t v_bits_packed = 0;
41101   uint8_t v_packs_remaining = 0;
41102   uint8_t v_multiplier = 0;
41103   uint8_t v_shift = 0;
41104 
41105   v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
41106   v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
41107   if ((v_dst_bits_per_pixel & 7) != 0) {
41108     return wuffs_base__make_status(wuffs_base__error__unsupported_option);
41109   }
41110   v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8)));
41111   v_dst_bytes_per_row1 = (((uint64_t)(self->private_impl.f_frame_rect_x1)) * v_dst_bytes_per_pixel);
41112   v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024));
41113   v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0);
41114   v_src_bytes_per_pixel = 1;
41115   if (self->private_impl.f_depth >= 8) {
41116     v_src_bytes_per_pixel = (((uint64_t)(WUFFS_PNG__NUM_CHANNELS[self->private_impl.f_color_type])) * ((uint64_t)((self->private_impl.f_depth >> 3))));
41117   }
41118   if (self->private_impl.f_chunk_type_array[0] == 73) {
41119     v_y = ((uint32_t)(WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][5]));
41120   } else {
41121     v_y = self->private_impl.f_frame_rect_y0;
41122   }
41123   while (v_y < self->private_impl.f_frame_rect_y1) {
41124     v_dst = wuffs_base__table_u8__row_u32(v_tab, v_y);
41125     if (v_dst_bytes_per_row1 < ((uint64_t)(v_dst.len))) {
41126       v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row1);
41127     }
41128     if (1 > ((uint64_t)(a_workbuf.len))) {
41129       return wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_workbuf_length);
41130     }
41131     v_filter = a_workbuf.ptr[0];
41132     a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, 1);
41133     if (self->private_impl.f_pass_bytes_per_row > ((uint64_t)(a_workbuf.len))) {
41134       return wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_workbuf_length);
41135     }
41136     v_curr_row = wuffs_base__slice_u8__subslice_j(a_workbuf, self->private_impl.f_pass_bytes_per_row);
41137     a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, self->private_impl.f_pass_bytes_per_row);
41138     if (v_filter == 0) {
41139     } else if (v_filter == 1) {
41140       wuffs_png__decoder__filter_1(self, v_curr_row);
41141     } else if (v_filter == 2) {
41142       wuffs_png__decoder__filter_2(self, v_curr_row, v_prev_row);
41143     } else if (v_filter == 3) {
41144       wuffs_png__decoder__filter_3(self, v_curr_row, v_prev_row);
41145     } else if (v_filter == 4) {
41146       wuffs_png__decoder__filter_4(self, v_curr_row, v_prev_row);
41147     } else {
41148       return wuffs_base__make_status(wuffs_png__error__bad_filter);
41149     }
41150     v_s = v_curr_row;
41151     if (self->private_impl.f_chunk_type_array[0] == 73) {
41152       v_x = ((uint32_t)(WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][2]));
41153     } else {
41154       v_x = self->private_impl.f_frame_rect_x0;
41155     }
41156     if (self->private_impl.f_depth == 8) {
41157       while (v_x < self->private_impl.f_frame_rect_x1) {
41158         v_i = (((uint64_t)(v_x)) * v_dst_bytes_per_pixel);
41159         if (v_i <= ((uint64_t)(v_dst.len))) {
41160           if (self->private_impl.f_color_type == 4) {
41161             if (2 <= ((uint64_t)(v_s.len))) {
41162               v_bits_unpacked[0] = v_s.ptr[0];
41163               v_bits_unpacked[1] = v_s.ptr[0];
41164               v_bits_unpacked[2] = v_s.ptr[0];
41165               v_bits_unpacked[3] = v_s.ptr[1];
41166               v_s = wuffs_base__slice_u8__subslice_i(v_s, 2);
41167               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));
41168             }
41169           } else if (((uint32_t)((self->private_impl.f_remap_transparency & 4294967295))) != 0) {
41170             if (self->private_impl.f_color_type == 0) {
41171               if (1 <= ((uint64_t)(v_s.len))) {
41172                 v_bits_unpacked[0] = v_s.ptr[0];
41173                 v_bits_unpacked[1] = v_s.ptr[0];
41174                 v_bits_unpacked[2] = v_s.ptr[0];
41175                 v_bits_unpacked[3] = 255;
41176                 v_s = wuffs_base__slice_u8__subslice_i(v_s, 1);
41177                 if (((uint32_t)((self->private_impl.f_remap_transparency & 4294967295))) == ((((uint32_t)(v_bits_unpacked[0])) << 0) |
41178                     (((uint32_t)(v_bits_unpacked[1])) << 8) |
41179                     (((uint32_t)(v_bits_unpacked[2])) << 16) |
41180                     (((uint32_t)(v_bits_unpacked[3])) << 24))) {
41181                   v_bits_unpacked[0] = 0;
41182                   v_bits_unpacked[1] = 0;
41183                   v_bits_unpacked[2] = 0;
41184                   v_bits_unpacked[3] = 0;
41185                 }
41186                 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));
41187               }
41188             } else {
41189               if (3 <= ((uint64_t)(v_s.len))) {
41190                 v_bits_unpacked[0] = v_s.ptr[2];
41191                 v_bits_unpacked[1] = v_s.ptr[1];
41192                 v_bits_unpacked[2] = v_s.ptr[0];
41193                 v_bits_unpacked[3] = 255;
41194                 v_s = wuffs_base__slice_u8__subslice_i(v_s, 3);
41195                 if (((uint32_t)((self->private_impl.f_remap_transparency & 4294967295))) == ((((uint32_t)(v_bits_unpacked[0])) << 0) |
41196                     (((uint32_t)(v_bits_unpacked[1])) << 8) |
41197                     (((uint32_t)(v_bits_unpacked[2])) << 16) |
41198                     (((uint32_t)(v_bits_unpacked[3])) << 24))) {
41199                   v_bits_unpacked[0] = 0;
41200                   v_bits_unpacked[1] = 0;
41201                   v_bits_unpacked[2] = 0;
41202                   v_bits_unpacked[3] = 0;
41203                 }
41204                 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));
41205               }
41206             }
41207           } else if (v_src_bytes_per_pixel <= ((uint64_t)(v_s.len))) {
41208             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));
41209             v_s = wuffs_base__slice_u8__subslice_i(v_s, v_src_bytes_per_pixel);
41210           }
41211         }
41212         v_x += (((uint32_t)(1)) << WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][0]);
41213       }
41214     } else if (self->private_impl.f_depth < 8) {
41215       v_multiplier = 1;
41216       if (self->private_impl.f_color_type == 0) {
41217         v_multiplier = WUFFS_PNG__LOW_BIT_DEPTH_MULTIPLIERS[self->private_impl.f_depth];
41218       }
41219       v_shift = ((8 - self->private_impl.f_depth) & 7);
41220       v_packs_remaining = 0;
41221       while (v_x < self->private_impl.f_frame_rect_x1) {
41222         v_i = (((uint64_t)(v_x)) * v_dst_bytes_per_pixel);
41223         if (v_i <= ((uint64_t)(v_dst.len))) {
41224           if ((v_packs_remaining == 0) && (1 <= ((uint64_t)(v_s.len)))) {
41225             v_packs_remaining = WUFFS_PNG__LOW_BIT_DEPTH_NUM_PACKS[self->private_impl.f_depth];
41226             v_bits_packed = v_s.ptr[0];
41227             v_s = wuffs_base__slice_u8__subslice_i(v_s, 1);
41228           }
41229           v_bits_unpacked[0] = ((uint8_t)((v_bits_packed >> v_shift) * v_multiplier));
41230           v_bits_packed = ((uint8_t)(v_bits_packed << self->private_impl.f_depth));
41231           v_packs_remaining = ((uint8_t)(v_packs_remaining - 1));
41232           if (((uint32_t)((self->private_impl.f_remap_transparency & 4294967295))) != 0) {
41233             v_bits_unpacked[1] = v_bits_unpacked[0];
41234             v_bits_unpacked[2] = v_bits_unpacked[0];
41235             v_bits_unpacked[3] = 255;
41236             if (((uint32_t)((self->private_impl.f_remap_transparency & 4294967295))) == ((((uint32_t)(v_bits_unpacked[0])) << 0) |
41237                 (((uint32_t)(v_bits_unpacked[1])) << 8) |
41238                 (((uint32_t)(v_bits_unpacked[2])) << 16) |
41239                 (((uint32_t)(v_bits_unpacked[3])) << 24))) {
41240               v_bits_unpacked[0] = 0;
41241               v_bits_unpacked[1] = 0;
41242               v_bits_unpacked[2] = 0;
41243               v_bits_unpacked[3] = 0;
41244             }
41245             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));
41246           } else {
41247             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));
41248           }
41249         }
41250         v_x += (((uint32_t)(1)) << WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][0]);
41251       }
41252     } else {
41253       while (v_x < self->private_impl.f_frame_rect_x1) {
41254         v_i = (((uint64_t)(v_x)) * v_dst_bytes_per_pixel);
41255         if (v_i <= ((uint64_t)(v_dst.len))) {
41256           if (self->private_impl.f_color_type == 0) {
41257             if (2 <= ((uint64_t)(v_s.len))) {
41258               v_bits_unpacked[0] = v_s.ptr[1];
41259               v_bits_unpacked[1] = v_s.ptr[0];
41260               v_bits_unpacked[2] = v_s.ptr[1];
41261               v_bits_unpacked[3] = v_s.ptr[0];
41262               v_bits_unpacked[4] = v_s.ptr[1];
41263               v_bits_unpacked[5] = v_s.ptr[0];
41264               v_bits_unpacked[6] = 255;
41265               v_bits_unpacked[7] = 255;
41266               v_s = wuffs_base__slice_u8__subslice_i(v_s, 2);
41267               if (self->private_impl.f_remap_transparency == ((((uint64_t)(v_bits_unpacked[0])) << 0) |
41268                   (((uint64_t)(v_bits_unpacked[1])) << 8) |
41269                   (((uint64_t)(v_bits_unpacked[2])) << 16) |
41270                   (((uint64_t)(v_bits_unpacked[3])) << 24) |
41271                   (((uint64_t)(v_bits_unpacked[4])) << 32) |
41272                   (((uint64_t)(v_bits_unpacked[5])) << 40) |
41273                   (((uint64_t)(v_bits_unpacked[6])) << 48) |
41274                   (((uint64_t)(v_bits_unpacked[7])) << 56))) {
41275                 v_bits_unpacked[0] = 0;
41276                 v_bits_unpacked[1] = 0;
41277                 v_bits_unpacked[2] = 0;
41278                 v_bits_unpacked[3] = 0;
41279                 v_bits_unpacked[4] = 0;
41280                 v_bits_unpacked[5] = 0;
41281                 v_bits_unpacked[6] = 0;
41282                 v_bits_unpacked[7] = 0;
41283               }
41284             }
41285           } else if (self->private_impl.f_color_type == 2) {
41286             if (6 <= ((uint64_t)(v_s.len))) {
41287               v_bits_unpacked[0] = v_s.ptr[5];
41288               v_bits_unpacked[1] = v_s.ptr[4];
41289               v_bits_unpacked[2] = v_s.ptr[3];
41290               v_bits_unpacked[3] = v_s.ptr[2];
41291               v_bits_unpacked[4] = v_s.ptr[1];
41292               v_bits_unpacked[5] = v_s.ptr[0];
41293               v_bits_unpacked[6] = 255;
41294               v_bits_unpacked[7] = 255;
41295               v_s = wuffs_base__slice_u8__subslice_i(v_s, 6);
41296               if (self->private_impl.f_remap_transparency == ((((uint64_t)(v_bits_unpacked[0])) << 0) |
41297                   (((uint64_t)(v_bits_unpacked[1])) << 8) |
41298                   (((uint64_t)(v_bits_unpacked[2])) << 16) |
41299                   (((uint64_t)(v_bits_unpacked[3])) << 24) |
41300                   (((uint64_t)(v_bits_unpacked[4])) << 32) |
41301                   (((uint64_t)(v_bits_unpacked[5])) << 40) |
41302                   (((uint64_t)(v_bits_unpacked[6])) << 48) |
41303                   (((uint64_t)(v_bits_unpacked[7])) << 56))) {
41304                 v_bits_unpacked[0] = 0;
41305                 v_bits_unpacked[1] = 0;
41306                 v_bits_unpacked[2] = 0;
41307                 v_bits_unpacked[3] = 0;
41308                 v_bits_unpacked[4] = 0;
41309                 v_bits_unpacked[5] = 0;
41310                 v_bits_unpacked[6] = 0;
41311                 v_bits_unpacked[7] = 0;
41312               }
41313             }
41314           } else if (self->private_impl.f_color_type == 4) {
41315             if (4 <= ((uint64_t)(v_s.len))) {
41316               v_bits_unpacked[0] = v_s.ptr[1];
41317               v_bits_unpacked[1] = v_s.ptr[0];
41318               v_bits_unpacked[2] = v_s.ptr[1];
41319               v_bits_unpacked[3] = v_s.ptr[0];
41320               v_bits_unpacked[4] = v_s.ptr[1];
41321               v_bits_unpacked[5] = v_s.ptr[0];
41322               v_bits_unpacked[6] = v_s.ptr[3];
41323               v_bits_unpacked[7] = v_s.ptr[2];
41324               v_s = wuffs_base__slice_u8__subslice_i(v_s, 4);
41325             }
41326           } else {
41327             if (8 <= ((uint64_t)(v_s.len))) {
41328               v_bits_unpacked[0] = v_s.ptr[5];
41329               v_bits_unpacked[1] = v_s.ptr[4];
41330               v_bits_unpacked[2] = v_s.ptr[3];
41331               v_bits_unpacked[3] = v_s.ptr[2];
41332               v_bits_unpacked[4] = v_s.ptr[1];
41333               v_bits_unpacked[5] = v_s.ptr[0];
41334               v_bits_unpacked[6] = v_s.ptr[7];
41335               v_bits_unpacked[7] = v_s.ptr[6];
41336               v_s = wuffs_base__slice_u8__subslice_i(v_s, 8);
41337             }
41338           }
41339           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));
41340         }
41341         v_x += (((uint32_t)(1)) << WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][0]);
41342       }
41343     }
41344     v_prev_row = v_curr_row;
41345     v_y += (((uint32_t)(1)) << WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][3]);
41346   }
41347   return wuffs_base__make_status(NULL);
41348 }
41349 
41350 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__PNG)
41351 
41352 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP)
41353 
41354 // ---------------- Status Codes Implementations
41355 
41356 const char wuffs_wbmp__error__bad_header[] = "#wbmp: bad header";
41357 
41358 // ---------------- Private Consts
41359 
41360 // ---------------- Private Initializer Prototypes
41361 
41362 // ---------------- Private Function Prototypes
41363 
41364 // ---------------- VTables
41365 
41366 const wuffs_base__image_decoder__func_ptrs
41367 wuffs_wbmp__decoder__func_ptrs_for__wuffs_base__image_decoder = {
41368   (wuffs_base__status(*)(void*,
41369       wuffs_base__pixel_buffer*,
41370       wuffs_base__io_buffer*,
41371       wuffs_base__pixel_blend,
41372       wuffs_base__slice_u8,
41373       wuffs_base__decode_frame_options*))(&wuffs_wbmp__decoder__decode_frame),
41374   (wuffs_base__status(*)(void*,
41375       wuffs_base__frame_config*,
41376       wuffs_base__io_buffer*))(&wuffs_wbmp__decoder__decode_frame_config),
41377   (wuffs_base__status(*)(void*,
41378       wuffs_base__image_config*,
41379       wuffs_base__io_buffer*))(&wuffs_wbmp__decoder__decode_image_config),
41380   (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_wbmp__decoder__frame_dirty_rect),
41381   (uint32_t(*)(const void*))(&wuffs_wbmp__decoder__num_animation_loops),
41382   (uint64_t(*)(const void*))(&wuffs_wbmp__decoder__num_decoded_frame_configs),
41383   (uint64_t(*)(const void*))(&wuffs_wbmp__decoder__num_decoded_frames),
41384   (wuffs_base__status(*)(void*,
41385       uint64_t,
41386       uint64_t))(&wuffs_wbmp__decoder__restart_frame),
41387   (wuffs_base__empty_struct(*)(void*,
41388       uint32_t,
41389       bool))(&wuffs_wbmp__decoder__set_quirk_enabled),
41390   (wuffs_base__empty_struct(*)(void*,
41391       uint32_t,
41392       bool))(&wuffs_wbmp__decoder__set_report_metadata),
41393   (wuffs_base__status(*)(void*,
41394       wuffs_base__io_buffer*,
41395       wuffs_base__more_information*,
41396       wuffs_base__io_buffer*))(&wuffs_wbmp__decoder__tell_me_more),
41397   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_wbmp__decoder__workbuf_len),
41398 };
41399 
41400 // ---------------- Initializer Implementations
41401 
41402 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)41403 wuffs_wbmp__decoder__initialize(
41404     wuffs_wbmp__decoder* self,
41405     size_t sizeof_star_self,
41406     uint64_t wuffs_version,
41407     uint32_t options){
41408   if (!self) {
41409     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
41410   }
41411   if (sizeof(*self) != sizeof_star_self) {
41412     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
41413   }
41414   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
41415       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
41416     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
41417   }
41418 
41419   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
41420     // The whole point of this if-check is to detect an uninitialized *self.
41421     // We disable the warning on GCC. Clang-5.0 does not have this warning.
41422 #if !defined(__clang__) && defined(__GNUC__)
41423 #pragma GCC diagnostic push
41424 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
41425 #endif
41426     if (self->private_impl.magic != 0) {
41427       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
41428     }
41429 #if !defined(__clang__) && defined(__GNUC__)
41430 #pragma GCC diagnostic pop
41431 #endif
41432   } else {
41433     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
41434       memset(self, 0, sizeof(*self));
41435       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
41436     } else {
41437       memset(&(self->private_impl), 0, sizeof(self->private_impl));
41438     }
41439   }
41440 
41441   self->private_impl.magic = WUFFS_BASE__MAGIC;
41442   self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
41443       wuffs_base__image_decoder__vtable_name;
41444   self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
41445       (const void*)(&wuffs_wbmp__decoder__func_ptrs_for__wuffs_base__image_decoder);
41446   return wuffs_base__make_status(NULL);
41447 }
41448 
41449 wuffs_wbmp__decoder*
wuffs_wbmp__decoder__alloc()41450 wuffs_wbmp__decoder__alloc() {
41451   wuffs_wbmp__decoder* x =
41452       (wuffs_wbmp__decoder*)(calloc(sizeof(wuffs_wbmp__decoder), 1));
41453   if (!x) {
41454     return NULL;
41455   }
41456   if (wuffs_wbmp__decoder__initialize(
41457       x, sizeof(wuffs_wbmp__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
41458     free(x);
41459     return NULL;
41460   }
41461   return x;
41462 }
41463 
41464 size_t
sizeof__wuffs_wbmp__decoder()41465 sizeof__wuffs_wbmp__decoder() {
41466   return sizeof(wuffs_wbmp__decoder);
41467 }
41468 
41469 // ---------------- Function Implementations
41470 
41471 // -------- func wbmp.decoder.set_quirk_enabled
41472 
41473 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_wbmp__decoder__set_quirk_enabled(wuffs_wbmp__decoder * self,uint32_t a_quirk,bool a_enabled)41474 wuffs_wbmp__decoder__set_quirk_enabled(
41475     wuffs_wbmp__decoder* self,
41476     uint32_t a_quirk,
41477     bool a_enabled) {
41478   return wuffs_base__make_empty_struct();
41479 }
41480 
41481 // -------- func wbmp.decoder.decode_image_config
41482 
41483 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)41484 wuffs_wbmp__decoder__decode_image_config(
41485     wuffs_wbmp__decoder* self,
41486     wuffs_base__image_config* a_dst,
41487     wuffs_base__io_buffer* a_src) {
41488   if (!self) {
41489     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
41490   }
41491   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
41492     return wuffs_base__make_status(
41493         (self->private_impl.magic == WUFFS_BASE__DISABLED)
41494         ? wuffs_base__error__disabled_by_previous_error
41495         : wuffs_base__error__initialize_not_called);
41496   }
41497   if (!a_src) {
41498     self->private_impl.magic = WUFFS_BASE__DISABLED;
41499     return wuffs_base__make_status(wuffs_base__error__bad_argument);
41500   }
41501   if ((self->private_impl.active_coroutine != 0) &&
41502       (self->private_impl.active_coroutine != 1)) {
41503     self->private_impl.magic = WUFFS_BASE__DISABLED;
41504     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
41505   }
41506   self->private_impl.active_coroutine = 0;
41507   wuffs_base__status status = wuffs_base__make_status(NULL);
41508 
41509   uint8_t v_c = 0;
41510   uint32_t v_i = 0;
41511   uint32_t v_x32 = 0;
41512   uint64_t v_x64 = 0;
41513 
41514   const uint8_t* iop_a_src = NULL;
41515   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41516   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41517   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41518   if (a_src) {
41519     io0_a_src = a_src->data.ptr;
41520     io1_a_src = io0_a_src + a_src->meta.ri;
41521     iop_a_src = io1_a_src;
41522     io2_a_src = io0_a_src + a_src->meta.wi;
41523   }
41524 
41525   uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
41526   if (coro_susp_point) {
41527     v_i = self->private_data.s_decode_image_config[0].v_i;
41528     v_x32 = self->private_data.s_decode_image_config[0].v_x32;
41529   }
41530   switch (coro_susp_point) {
41531     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
41532 
41533     if (self->private_impl.f_call_sequence != 0) {
41534       status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
41535       goto exit;
41536     }
41537     v_i = 0;
41538     while (v_i < 2) {
41539       {
41540         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
41541         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
41542           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
41543           goto suspend;
41544         }
41545         uint8_t t_0 = *iop_a_src++;
41546         v_c = t_0;
41547       }
41548       if (v_c != 0) {
41549         status = wuffs_base__make_status(wuffs_wbmp__error__bad_header);
41550         goto exit;
41551       }
41552       v_i += 1;
41553     }
41554     v_i = 0;
41555     while (v_i < 2) {
41556       v_x32 = 0;
41557       while (true) {
41558         {
41559           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
41560           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
41561             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
41562             goto suspend;
41563           }
41564           uint8_t t_1 = *iop_a_src++;
41565           v_c = t_1;
41566         }
41567         v_x32 |= ((uint32_t)((v_c & 127)));
41568         if ((v_c >> 7) == 0) {
41569           goto label__0__break;
41570         }
41571         v_x64 = (((uint64_t)(v_x32)) << 7);
41572         if (v_x64 > 4294967295) {
41573           status = wuffs_base__make_status(wuffs_wbmp__error__bad_header);
41574           goto exit;
41575         }
41576         v_x32 = ((uint32_t)(v_x64));
41577       }
41578       label__0__break:;
41579       if (v_i == 0) {
41580         self->private_impl.f_width = v_x32;
41581       } else {
41582         self->private_impl.f_height = v_x32;
41583       }
41584       v_i += 1;
41585     }
41586     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)));
41587     if (a_dst != NULL) {
41588       wuffs_base__image_config__set(
41589           a_dst,
41590           2198077448,
41591           0,
41592           self->private_impl.f_width,
41593           self->private_impl.f_height,
41594           self->private_impl.f_frame_config_io_position,
41595           true);
41596     }
41597     self->private_impl.f_call_sequence = 3;
41598 
41599     goto ok;
41600     ok:
41601     self->private_impl.p_decode_image_config[0] = 0;
41602     goto exit;
41603   }
41604 
41605   goto suspend;
41606   suspend:
41607   self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
41608   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
41609   self->private_data.s_decode_image_config[0].v_i = v_i;
41610   self->private_data.s_decode_image_config[0].v_x32 = v_x32;
41611 
41612   goto exit;
41613   exit:
41614   if (a_src) {
41615     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
41616   }
41617 
41618   if (wuffs_base__status__is_error(&status)) {
41619     self->private_impl.magic = WUFFS_BASE__DISABLED;
41620   }
41621   return status;
41622 }
41623 
41624 // -------- func wbmp.decoder.decode_frame_config
41625 
41626 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)41627 wuffs_wbmp__decoder__decode_frame_config(
41628     wuffs_wbmp__decoder* self,
41629     wuffs_base__frame_config* a_dst,
41630     wuffs_base__io_buffer* a_src) {
41631   if (!self) {
41632     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
41633   }
41634   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
41635     return wuffs_base__make_status(
41636         (self->private_impl.magic == WUFFS_BASE__DISABLED)
41637         ? wuffs_base__error__disabled_by_previous_error
41638         : wuffs_base__error__initialize_not_called);
41639   }
41640   if (!a_src) {
41641     self->private_impl.magic = WUFFS_BASE__DISABLED;
41642     return wuffs_base__make_status(wuffs_base__error__bad_argument);
41643   }
41644   if ((self->private_impl.active_coroutine != 0) &&
41645       (self->private_impl.active_coroutine != 2)) {
41646     self->private_impl.magic = WUFFS_BASE__DISABLED;
41647     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
41648   }
41649   self->private_impl.active_coroutine = 0;
41650   wuffs_base__status status = wuffs_base__make_status(NULL);
41651 
41652   const uint8_t* iop_a_src = NULL;
41653   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41654   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41655   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41656   if (a_src) {
41657     io0_a_src = a_src->data.ptr;
41658     io1_a_src = io0_a_src + a_src->meta.ri;
41659     iop_a_src = io1_a_src;
41660     io2_a_src = io0_a_src + a_src->meta.wi;
41661   }
41662 
41663   uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
41664   switch (coro_susp_point) {
41665     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
41666 
41667     if (self->private_impl.f_call_sequence < 3) {
41668       if (a_src) {
41669         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
41670       }
41671       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
41672       status = wuffs_wbmp__decoder__decode_image_config(self, NULL, a_src);
41673       if (a_src) {
41674         iop_a_src = a_src->data.ptr + a_src->meta.ri;
41675       }
41676       if (status.repr) {
41677         goto suspend;
41678       }
41679     } else if (self->private_impl.f_call_sequence == 3) {
41680       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)))) {
41681         status = wuffs_base__make_status(wuffs_base__error__bad_restart);
41682         goto exit;
41683       }
41684     } else if (self->private_impl.f_call_sequence == 4) {
41685       self->private_impl.f_call_sequence = 255;
41686       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
41687       goto ok;
41688     } else {
41689       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
41690       goto ok;
41691     }
41692     if (a_dst != NULL) {
41693       wuffs_base__frame_config__set(
41694           a_dst,
41695           wuffs_base__utility__make_rect_ie_u32(
41696           0,
41697           0,
41698           self->private_impl.f_width,
41699           self->private_impl.f_height),
41700           ((wuffs_base__flicks)(0)),
41701           0,
41702           self->private_impl.f_frame_config_io_position,
41703           0,
41704           true,
41705           false,
41706           4278190080);
41707     }
41708     self->private_impl.f_call_sequence = 4;
41709 
41710     ok:
41711     self->private_impl.p_decode_frame_config[0] = 0;
41712     goto exit;
41713   }
41714 
41715   goto suspend;
41716   suspend:
41717   self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
41718   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
41719 
41720   goto exit;
41721   exit:
41722   if (a_src) {
41723     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
41724   }
41725 
41726   if (wuffs_base__status__is_error(&status)) {
41727     self->private_impl.magic = WUFFS_BASE__DISABLED;
41728   }
41729   return status;
41730 }
41731 
41732 // -------- func wbmp.decoder.decode_frame
41733 
41734 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)41735 wuffs_wbmp__decoder__decode_frame(
41736     wuffs_wbmp__decoder* self,
41737     wuffs_base__pixel_buffer* a_dst,
41738     wuffs_base__io_buffer* a_src,
41739     wuffs_base__pixel_blend a_blend,
41740     wuffs_base__slice_u8 a_workbuf,
41741     wuffs_base__decode_frame_options* a_opts) {
41742   if (!self) {
41743     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
41744   }
41745   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
41746     return wuffs_base__make_status(
41747         (self->private_impl.magic == WUFFS_BASE__DISABLED)
41748         ? wuffs_base__error__disabled_by_previous_error
41749         : wuffs_base__error__initialize_not_called);
41750   }
41751   if (!a_dst || !a_src) {
41752     self->private_impl.magic = WUFFS_BASE__DISABLED;
41753     return wuffs_base__make_status(wuffs_base__error__bad_argument);
41754   }
41755   if ((self->private_impl.active_coroutine != 0) &&
41756       (self->private_impl.active_coroutine != 3)) {
41757     self->private_impl.magic = WUFFS_BASE__DISABLED;
41758     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
41759   }
41760   self->private_impl.active_coroutine = 0;
41761   wuffs_base__status status = wuffs_base__make_status(NULL);
41762 
41763   wuffs_base__status v_status = wuffs_base__make_status(NULL);
41764   wuffs_base__pixel_format v_dst_pixfmt = {0};
41765   uint32_t v_dst_bits_per_pixel = 0;
41766   uint64_t v_dst_bytes_per_pixel = 0;
41767   uint64_t v_dst_x_in_bytes = 0;
41768   uint32_t v_dst_x = 0;
41769   uint32_t v_dst_y = 0;
41770   wuffs_base__table_u8 v_tab = {0};
41771   wuffs_base__slice_u8 v_dst = {0};
41772   uint8_t v_src[1] = {0};
41773   uint8_t v_c = 0;
41774 
41775   const uint8_t* iop_a_src = NULL;
41776   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41777   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41778   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41779   if (a_src) {
41780     io0_a_src = a_src->data.ptr;
41781     io1_a_src = io0_a_src + a_src->meta.ri;
41782     iop_a_src = io1_a_src;
41783     io2_a_src = io0_a_src + a_src->meta.wi;
41784   }
41785 
41786   uint32_t coro_susp_point = self->private_impl.p_decode_frame[0];
41787   if (coro_susp_point) {
41788     v_dst_bytes_per_pixel = self->private_data.s_decode_frame[0].v_dst_bytes_per_pixel;
41789     v_dst_x = self->private_data.s_decode_frame[0].v_dst_x;
41790     v_dst_y = self->private_data.s_decode_frame[0].v_dst_y;
41791     memcpy(v_src, self->private_data.s_decode_frame[0].v_src, sizeof(v_src));
41792     v_c = self->private_data.s_decode_frame[0].v_c;
41793   }
41794   switch (coro_susp_point) {
41795     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
41796 
41797     if (self->private_impl.f_call_sequence < 4) {
41798       if (a_src) {
41799         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
41800       }
41801       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
41802       status = wuffs_wbmp__decoder__decode_frame_config(self, NULL, a_src);
41803       if (a_src) {
41804         iop_a_src = a_src->data.ptr + a_src->meta.ri;
41805       }
41806       if (status.repr) {
41807         goto suspend;
41808       }
41809     } else if (self->private_impl.f_call_sequence == 4) {
41810     } else {
41811       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
41812       goto ok;
41813     }
41814     v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
41815         wuffs_base__pixel_buffer__pixel_format(a_dst),
41816         wuffs_base__pixel_buffer__palette(a_dst),
41817         wuffs_base__utility__make_pixel_format(536870920),
41818         wuffs_base__utility__empty_slice_u8(),
41819         a_blend);
41820     if ( ! wuffs_base__status__is_ok(&v_status)) {
41821       status = v_status;
41822       if (wuffs_base__status__is_error(&status)) {
41823         goto exit;
41824       } else if (wuffs_base__status__is_suspension(&status)) {
41825         status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
41826         goto exit;
41827       }
41828       goto ok;
41829     }
41830     v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
41831     v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
41832     if ((v_dst_bits_per_pixel & 7) != 0) {
41833       status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
41834       goto exit;
41835     }
41836     v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8)));
41837     if (self->private_impl.f_width > 0) {
41838       v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0);
41839       while (v_dst_y < self->private_impl.f_height) {
41840         v_dst = wuffs_base__table_u8__row_u32(v_tab, v_dst_y);
41841         v_dst_x = 0;
41842         while (v_dst_x < self->private_impl.f_width) {
41843           if ((v_dst_x & 7) == 0) {
41844             while (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
41845               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
41846               WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
41847               v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0);
41848               v_dst = wuffs_base__table_u8__row_u32(v_tab, v_dst_y);
41849               v_dst_x_in_bytes = (((uint64_t)(v_dst_x)) * v_dst_bytes_per_pixel);
41850               if (v_dst_x_in_bytes <= ((uint64_t)(v_dst.len))) {
41851                 v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_x_in_bytes);
41852               }
41853             }
41854             v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
41855             iop_a_src += 1;
41856           }
41857           if ((v_c & 128) == 0) {
41858             v_src[0] = 0;
41859           } else {
41860             v_src[0] = 255;
41861           }
41862           v_c = ((uint8_t)(((((uint32_t)(v_c)) << 1) & 255)));
41863           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));
41864           if (v_dst_bytes_per_pixel <= ((uint64_t)(v_dst.len))) {
41865             v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_bytes_per_pixel);
41866           }
41867           v_dst_x += 1;
41868         }
41869         v_dst_y += 1;
41870       }
41871     }
41872     self->private_impl.f_call_sequence = 255;
41873 
41874     ok:
41875     self->private_impl.p_decode_frame[0] = 0;
41876     goto exit;
41877   }
41878 
41879   goto suspend;
41880   suspend:
41881   self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
41882   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
41883   self->private_data.s_decode_frame[0].v_dst_bytes_per_pixel = v_dst_bytes_per_pixel;
41884   self->private_data.s_decode_frame[0].v_dst_x = v_dst_x;
41885   self->private_data.s_decode_frame[0].v_dst_y = v_dst_y;
41886   memcpy(self->private_data.s_decode_frame[0].v_src, v_src, sizeof(v_src));
41887   self->private_data.s_decode_frame[0].v_c = v_c;
41888 
41889   goto exit;
41890   exit:
41891   if (a_src) {
41892     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
41893   }
41894 
41895   if (wuffs_base__status__is_error(&status)) {
41896     self->private_impl.magic = WUFFS_BASE__DISABLED;
41897   }
41898   return status;
41899 }
41900 
41901 // -------- func wbmp.decoder.frame_dirty_rect
41902 
41903 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
wuffs_wbmp__decoder__frame_dirty_rect(const wuffs_wbmp__decoder * self)41904 wuffs_wbmp__decoder__frame_dirty_rect(
41905     const wuffs_wbmp__decoder* self) {
41906   if (!self) {
41907     return wuffs_base__utility__empty_rect_ie_u32();
41908   }
41909   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
41910       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
41911     return wuffs_base__utility__empty_rect_ie_u32();
41912   }
41913 
41914   return wuffs_base__utility__make_rect_ie_u32(
41915       0,
41916       0,
41917       self->private_impl.f_width,
41918       self->private_impl.f_height);
41919 }
41920 
41921 // -------- func wbmp.decoder.num_animation_loops
41922 
41923 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_wbmp__decoder__num_animation_loops(const wuffs_wbmp__decoder * self)41924 wuffs_wbmp__decoder__num_animation_loops(
41925     const wuffs_wbmp__decoder* self) {
41926   if (!self) {
41927     return 0;
41928   }
41929   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
41930       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
41931     return 0;
41932   }
41933 
41934   return 0;
41935 }
41936 
41937 // -------- func wbmp.decoder.num_decoded_frame_configs
41938 
41939 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_wbmp__decoder__num_decoded_frame_configs(const wuffs_wbmp__decoder * self)41940 wuffs_wbmp__decoder__num_decoded_frame_configs(
41941     const wuffs_wbmp__decoder* self) {
41942   if (!self) {
41943     return 0;
41944   }
41945   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
41946       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
41947     return 0;
41948   }
41949 
41950   if (self->private_impl.f_call_sequence > 3) {
41951     return 1;
41952   }
41953   return 0;
41954 }
41955 
41956 // -------- func wbmp.decoder.num_decoded_frames
41957 
41958 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_wbmp__decoder__num_decoded_frames(const wuffs_wbmp__decoder * self)41959 wuffs_wbmp__decoder__num_decoded_frames(
41960     const wuffs_wbmp__decoder* self) {
41961   if (!self) {
41962     return 0;
41963   }
41964   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
41965       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
41966     return 0;
41967   }
41968 
41969   if (self->private_impl.f_call_sequence > 4) {
41970     return 1;
41971   }
41972   return 0;
41973 }
41974 
41975 // -------- func wbmp.decoder.restart_frame
41976 
41977 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)41978 wuffs_wbmp__decoder__restart_frame(
41979     wuffs_wbmp__decoder* self,
41980     uint64_t a_index,
41981     uint64_t a_io_position) {
41982   if (!self) {
41983     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
41984   }
41985   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
41986     return wuffs_base__make_status(
41987         (self->private_impl.magic == WUFFS_BASE__DISABLED)
41988         ? wuffs_base__error__disabled_by_previous_error
41989         : wuffs_base__error__initialize_not_called);
41990   }
41991 
41992   if (self->private_impl.f_call_sequence < 3) {
41993     return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
41994   }
41995   if (a_index != 0) {
41996     return wuffs_base__make_status(wuffs_base__error__bad_argument);
41997   }
41998   self->private_impl.f_call_sequence = 3;
41999   self->private_impl.f_frame_config_io_position = a_io_position;
42000   return wuffs_base__make_status(NULL);
42001 }
42002 
42003 // -------- func wbmp.decoder.set_report_metadata
42004 
42005 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)42006 wuffs_wbmp__decoder__set_report_metadata(
42007     wuffs_wbmp__decoder* self,
42008     uint32_t a_fourcc,
42009     bool a_report) {
42010   return wuffs_base__make_empty_struct();
42011 }
42012 
42013 // -------- func wbmp.decoder.tell_me_more
42014 
42015 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)42016 wuffs_wbmp__decoder__tell_me_more(
42017     wuffs_wbmp__decoder* self,
42018     wuffs_base__io_buffer* a_dst,
42019     wuffs_base__more_information* a_minfo,
42020     wuffs_base__io_buffer* a_src) {
42021   if (!self) {
42022     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
42023   }
42024   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
42025     return wuffs_base__make_status(
42026         (self->private_impl.magic == WUFFS_BASE__DISABLED)
42027         ? wuffs_base__error__disabled_by_previous_error
42028         : wuffs_base__error__initialize_not_called);
42029   }
42030   if (!a_dst || !a_src) {
42031     self->private_impl.magic = WUFFS_BASE__DISABLED;
42032     return wuffs_base__make_status(wuffs_base__error__bad_argument);
42033   }
42034   if ((self->private_impl.active_coroutine != 0) &&
42035       (self->private_impl.active_coroutine != 4)) {
42036     self->private_impl.magic = WUFFS_BASE__DISABLED;
42037     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
42038   }
42039   self->private_impl.active_coroutine = 0;
42040   wuffs_base__status status = wuffs_base__make_status(NULL);
42041 
42042   status = wuffs_base__make_status(wuffs_base__error__no_more_information);
42043   goto exit;
42044 
42045   goto ok;
42046   ok:
42047   goto exit;
42048   exit:
42049   if (wuffs_base__status__is_error(&status)) {
42050     self->private_impl.magic = WUFFS_BASE__DISABLED;
42051   }
42052   return status;
42053 }
42054 
42055 // -------- func wbmp.decoder.workbuf_len
42056 
42057 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_wbmp__decoder__workbuf_len(const wuffs_wbmp__decoder * self)42058 wuffs_wbmp__decoder__workbuf_len(
42059     const wuffs_wbmp__decoder* self) {
42060   if (!self) {
42061     return wuffs_base__utility__empty_range_ii_u64();
42062   }
42063   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
42064       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
42065     return wuffs_base__utility__empty_range_ii_u64();
42066   }
42067 
42068   return wuffs_base__utility__make_range_ii_u64(0, 0);
42069 }
42070 
42071 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP)
42072 
42073 #if defined(__cplusplus) && defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
42074 
42075 // ---------------- Auxiliary - Base
42076 
42077 // Auxiliary code is discussed at
42078 // https://github.com/google/wuffs/blob/main/doc/note/auxiliary-code.md
42079 
42080 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__AUX__BASE)
42081 
42082 namespace wuffs_aux {
42083 
42084 namespace sync_io {
42085 
42086 // --------
42087 
DynIOBuffer(uint64_t max_incl)42088 DynIOBuffer::DynIOBuffer(uint64_t max_incl)
42089     : m_buf(wuffs_base__empty_io_buffer()), m_max_incl(max_incl) {}
42090 
~DynIOBuffer()42091 DynIOBuffer::~DynIOBuffer() {
42092   if (m_buf.data.ptr) {
42093     free(m_buf.data.ptr);
42094   }
42095 }
42096 
42097 void  //
drop()42098 DynIOBuffer::drop() {
42099   if (m_buf.data.ptr) {
42100     free(m_buf.data.ptr);
42101   }
42102   m_buf = wuffs_base__empty_io_buffer();
42103 }
42104 
42105 DynIOBuffer::GrowResult  //
grow(uint64_t min_incl)42106 DynIOBuffer::grow(uint64_t min_incl) {
42107   uint64_t n = round_up(min_incl, m_max_incl);
42108   if (n == 0) {
42109     return ((min_incl == 0) && (m_max_incl == 0))
42110                ? DynIOBuffer::GrowResult::OK
42111                : DynIOBuffer::GrowResult::FailedMaxInclExceeded;
42112   } else if (n > m_buf.data.len) {
42113     uint8_t* ptr = static_cast<uint8_t*>(realloc(m_buf.data.ptr, n));
42114     if (!ptr) {
42115       return DynIOBuffer::GrowResult::FailedOutOfMemory;
42116     }
42117     m_buf.data.ptr = ptr;
42118     m_buf.data.len = n;
42119   }
42120   return DynIOBuffer::GrowResult::OK;
42121 }
42122 
42123 // round_up rounds min_incl up, returning the smallest value x satisfying
42124 // (min_incl <= x) and (x <= max_incl) and some other constraints. It returns 0
42125 // if there is no such x.
42126 //
42127 // When max_incl <= 4096, the other constraints are:
42128 //  - (x == max_incl)
42129 //
42130 // When max_incl >  4096, the other constraints are:
42131 //  - (x == max_incl) or (x is a power of 2)
42132 //  - (x >= 4096)
42133 uint64_t  //
round_up(uint64_t min_incl,uint64_t max_incl)42134 DynIOBuffer::round_up(uint64_t min_incl, uint64_t max_incl) {
42135   if (min_incl > max_incl) {
42136     return 0;
42137   }
42138   uint64_t n = 4096;
42139   if (n >= max_incl) {
42140     return max_incl;
42141   }
42142   while (n < min_incl) {
42143     if (n >= (max_incl / 2)) {
42144       return max_incl;
42145     }
42146     n *= 2;
42147   }
42148   return n;
42149 }
42150 
42151 // --------
42152 
~Input()42153 Input::~Input() {}
42154 
42155 IOBuffer*  //
BringsItsOwnIOBuffer()42156 Input::BringsItsOwnIOBuffer() {
42157   return nullptr;
42158 }
42159 
42160 // --------
42161 
FileInput(FILE * f)42162 FileInput::FileInput(FILE* f) : m_f(f) {}
42163 
42164 std::string  //
CopyIn(IOBuffer * dst)42165 FileInput::CopyIn(IOBuffer* dst) {
42166   if (!m_f) {
42167     return "wuffs_aux::sync_io::FileInput: nullptr file";
42168   } else if (!dst) {
42169     return "wuffs_aux::sync_io::FileInput: nullptr IOBuffer";
42170   } else if (dst->meta.closed) {
42171     return "wuffs_aux::sync_io::FileInput: end of file";
42172   } else {
42173     dst->compact();
42174     size_t n = fread(dst->writer_pointer(), 1, dst->writer_length(), m_f);
42175     dst->meta.wi += n;
42176     dst->meta.closed = feof(m_f);
42177     if (ferror(m_f)) {
42178       return "wuffs_aux::sync_io::FileInput: error reading file";
42179     }
42180   }
42181   return "";
42182 }
42183 
42184 // --------
42185 
MemoryInput(const char * ptr,size_t len)42186 MemoryInput::MemoryInput(const char* ptr, size_t len)
42187     : m_io(wuffs_base__ptr_u8__reader(
42188           static_cast<uint8_t*>(static_cast<void*>(const_cast<char*>(ptr))),
42189           len,
42190           true)) {}
42191 
MemoryInput(const uint8_t * ptr,size_t len)42192 MemoryInput::MemoryInput(const uint8_t* ptr, size_t len)
42193     : m_io(wuffs_base__ptr_u8__reader(const_cast<uint8_t*>(ptr), len, true)) {}
42194 
42195 IOBuffer*  //
BringsItsOwnIOBuffer()42196 MemoryInput::BringsItsOwnIOBuffer() {
42197   return &m_io;
42198 }
42199 
42200 std::string  //
CopyIn(IOBuffer * dst)42201 MemoryInput::CopyIn(IOBuffer* dst) {
42202   if (!dst) {
42203     return "wuffs_aux::sync_io::MemoryInput: nullptr IOBuffer";
42204   } else if (dst->meta.closed) {
42205     return "wuffs_aux::sync_io::MemoryInput: end of file";
42206   } else if (wuffs_base__slice_u8__overlaps(dst->data, m_io.data)) {
42207     // Treat m_io's data as immutable, so don't compact dst or otherwise write
42208     // to it.
42209     return "wuffs_aux::sync_io::MemoryInput: overlapping buffers";
42210   } else {
42211     dst->compact();
42212     size_t nd = dst->writer_length();
42213     size_t ns = m_io.reader_length();
42214     size_t n = (nd < ns) ? nd : ns;
42215     memcpy(dst->writer_pointer(), m_io.reader_pointer(), n);
42216     m_io.meta.ri += n;
42217     dst->meta.wi += n;
42218     dst->meta.closed = m_io.reader_length() == 0;
42219   }
42220   return "";
42221 }
42222 
42223 // --------
42224 
42225 }  // namespace sync_io
42226 
42227 namespace private_impl {
42228 
42229 struct ErrorMessages {
42230   const char* max_incl_metadata_length_exceeded;
42231   const char* out_of_memory;
42232   const char* unexpected_end_of_file;
42233   const char* unsupported_metadata;
42234   const char* unsupported_negative_advance;
42235 
42236   // If adding new "const char*" typed fields to this struct, either add them
42237   // after existing fields or, if re-ordering fields, make sure that you update
42238   // all of the "const private_impl::ErrorMessages FooBarErrorMessages" values
42239   // in all of the sibling *.cc files.
42240 
resolveErrorMessages42241   static inline const char* resolve(const char* s) {
42242     return s ? s : "wuffs_aux::private_impl: unknown error";
42243   };
42244 };
42245 
42246 std::string  //
AdvanceIOBufferTo(const ErrorMessages & error_messages,sync_io::Input & input,IOBuffer & io_buf,uint64_t absolute_position)42247 AdvanceIOBufferTo(const ErrorMessages& error_messages,
42248                   sync_io::Input& input,
42249                   IOBuffer& io_buf,
42250                   uint64_t absolute_position) {
42251   if (absolute_position < io_buf.reader_position()) {
42252     return error_messages.resolve(error_messages.unsupported_negative_advance);
42253   }
42254   while (true) {
42255     uint64_t relative_position = absolute_position - io_buf.reader_position();
42256     if (relative_position <= io_buf.reader_length()) {
42257       io_buf.meta.ri += (size_t)relative_position;
42258       break;
42259     } else if (io_buf.meta.closed) {
42260       return error_messages.resolve(error_messages.unexpected_end_of_file);
42261     }
42262     io_buf.meta.ri = io_buf.meta.wi;
42263     if (!input.BringsItsOwnIOBuffer()) {
42264       io_buf.compact();
42265     }
42266     std::string error_message = input.CopyIn(&io_buf);
42267     if (!error_message.empty()) {
42268       return error_message;
42269     }
42270   }
42271   return "";
42272 }
42273 
42274 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)42275 HandleMetadata(
42276     const ErrorMessages& error_messages,
42277     sync_io::Input& input,
42278     wuffs_base__io_buffer& io_buf,
42279     sync_io::DynIOBuffer& raw,
42280     wuffs_base__status (*tell_me_more_func)(void*,
42281                                             wuffs_base__io_buffer*,
42282                                             wuffs_base__more_information*,
42283                                             wuffs_base__io_buffer*),
42284     void* tell_me_more_receiver,
42285     std::string (*handle_metadata_func)(void*,
42286                                         const wuffs_base__more_information*,
42287                                         wuffs_base__slice_u8),
42288     void* handle_metadata_receiver) {
42289   wuffs_base__more_information minfo = wuffs_base__empty_more_information();
42290   // Reset raw but keep its backing array (the raw.m_buf.data slice).
42291   raw.m_buf.meta = wuffs_base__empty_io_buffer_meta();
42292 
42293   while (true) {
42294     minfo = wuffs_base__empty_more_information();
42295     wuffs_base__status status = (*tell_me_more_func)(
42296         tell_me_more_receiver, &raw.m_buf, &minfo, &io_buf);
42297     switch (minfo.flavor) {
42298       case 0:
42299       case WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_RAW_TRANSFORM:
42300       case WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_PARSED:
42301         break;
42302 
42303       case WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_RAW_PASSTHROUGH: {
42304         wuffs_base__range_ie_u64 r = minfo.metadata_raw_passthrough__range();
42305         if (r.is_empty()) {
42306           break;
42307         }
42308         uint64_t num_to_copy = r.length();
42309         if (num_to_copy > (raw.m_max_incl - raw.m_buf.meta.wi)) {
42310           return error_messages.resolve(
42311               error_messages.max_incl_metadata_length_exceeded);
42312         } else if (num_to_copy > (raw.m_buf.data.len - raw.m_buf.meta.wi)) {
42313           switch (raw.grow(num_to_copy + raw.m_buf.meta.wi)) {
42314             case sync_io::DynIOBuffer::GrowResult::OK:
42315               break;
42316             case sync_io::DynIOBuffer::GrowResult::FailedMaxInclExceeded:
42317               return error_messages.resolve(
42318                   error_messages.max_incl_metadata_length_exceeded);
42319             case sync_io::DynIOBuffer::GrowResult::FailedOutOfMemory:
42320               return error_messages.resolve(error_messages.out_of_memory);
42321           }
42322         }
42323 
42324         if (io_buf.reader_position() > r.min_incl) {
42325           return error_messages.resolve(error_messages.unsupported_metadata);
42326         } else {
42327           std::string error_message =
42328               AdvanceIOBufferTo(error_messages, input, io_buf, r.min_incl);
42329           if (!error_message.empty()) {
42330             return error_message;
42331           }
42332         }
42333 
42334         while (true) {
42335           uint64_t n =
42336               wuffs_base__u64__min(num_to_copy, io_buf.reader_length());
42337           memcpy(raw.m_buf.writer_pointer(), io_buf.reader_pointer(), n);
42338           raw.m_buf.meta.wi += n;
42339           io_buf.meta.ri += n;
42340           num_to_copy -= n;
42341           if (num_to_copy == 0) {
42342             break;
42343           } else if (io_buf.meta.closed) {
42344             return error_messages.resolve(
42345                 error_messages.unexpected_end_of_file);
42346           } else if (!input.BringsItsOwnIOBuffer()) {
42347             io_buf.compact();
42348           }
42349           std::string error_message = input.CopyIn(&io_buf);
42350           if (!error_message.empty()) {
42351             return error_message;
42352           }
42353         }
42354         break;
42355       }
42356 
42357       default:
42358         return error_messages.resolve(error_messages.unsupported_metadata);
42359     }
42360 
42361     if (status.repr == nullptr) {
42362       break;
42363     } else if (status.repr != wuffs_base__suspension__even_more_information) {
42364       if (status.repr != wuffs_base__suspension__short_write) {
42365         return status.message();
42366       }
42367       switch (raw.grow(wuffs_base__u64__sat_add(raw.m_buf.data.len, 1))) {
42368         case sync_io::DynIOBuffer::GrowResult::OK:
42369           break;
42370         case sync_io::DynIOBuffer::GrowResult::FailedMaxInclExceeded:
42371           return error_messages.resolve(
42372               error_messages.max_incl_metadata_length_exceeded);
42373         case sync_io::DynIOBuffer::GrowResult::FailedOutOfMemory:
42374           return error_messages.resolve(error_messages.out_of_memory);
42375       }
42376     }
42377   }
42378 
42379   return (*handle_metadata_func)(handle_metadata_receiver, &minfo,
42380                                  raw.m_buf.reader_slice());
42381 }
42382 
42383 }  // namespace private_impl
42384 
42385 }  // namespace wuffs_aux
42386 
42387 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
42388         // defined(WUFFS_CONFIG__MODULE__AUX__BASE)
42389 
42390 // ---------------- Auxiliary - CBOR
42391 
42392 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__AUX__CBOR)
42393 
42394 #include <utility>
42395 
42396 namespace wuffs_aux {
42397 
DecodeCborResult(std::string && error_message0,uint64_t cursor_position0)42398 DecodeCborResult::DecodeCborResult(std::string&& error_message0,
42399                                    uint64_t cursor_position0)
42400     : error_message(std::move(error_message0)),
42401       cursor_position(cursor_position0) {}
42402 
~DecodeCborCallbacks()42403 DecodeCborCallbacks::~DecodeCborCallbacks() {}
42404 
42405 void  //
Done(DecodeCborResult & result,sync_io::Input & input,IOBuffer & buffer)42406 DecodeCborCallbacks::Done(DecodeCborResult& result,
42407                           sync_io::Input& input,
42408                           IOBuffer& buffer) {}
42409 
DecodeCborArgQuirks(wuffs_base__slice_u32 repr0)42410 DecodeCborArgQuirks::DecodeCborArgQuirks(wuffs_base__slice_u32 repr0)
42411     : repr(repr0) {}
42412 
DecodeCborArgQuirks(uint32_t * ptr0,size_t len0)42413 DecodeCborArgQuirks::DecodeCborArgQuirks(uint32_t* ptr0, size_t len0)
42414     : repr(wuffs_base__make_slice_u32(ptr0, len0)) {}
42415 
42416 DecodeCborArgQuirks  //
DefaultValue()42417 DecodeCborArgQuirks::DefaultValue() {
42418   return DecodeCborArgQuirks(wuffs_base__empty_slice_u32());
42419 }
42420 
42421 DecodeCborResult  //
DecodeCbor(DecodeCborCallbacks & callbacks,sync_io::Input & input,DecodeCborArgQuirks quirks)42422 DecodeCbor(DecodeCborCallbacks& callbacks,
42423            sync_io::Input& input,
42424            DecodeCborArgQuirks quirks) {
42425   // Prepare the wuffs_base__io_buffer and the resultant error_message.
42426   wuffs_base__io_buffer* io_buf = input.BringsItsOwnIOBuffer();
42427   wuffs_base__io_buffer fallback_io_buf = wuffs_base__empty_io_buffer();
42428   std::unique_ptr<uint8_t[]> fallback_io_array(nullptr);
42429   if (!io_buf) {
42430     fallback_io_array = std::unique_ptr<uint8_t[]>(new uint8_t[4096]);
42431     fallback_io_buf = wuffs_base__ptr_u8__writer(fallback_io_array.get(), 4096);
42432     io_buf = &fallback_io_buf;
42433   }
42434   // cursor_index is discussed at
42435   // https://nigeltao.github.io/blog/2020/jsonptr.html#the-cursor-index
42436   size_t cursor_index = 0;
42437   std::string ret_error_message;
42438   std::string io_error_message;
42439 
42440   do {
42441     // Prepare the low-level CBOR decoder.
42442     wuffs_cbor__decoder::unique_ptr dec = wuffs_cbor__decoder::alloc();
42443     if (!dec) {
42444       ret_error_message = "wuffs_aux::DecodeCbor: out of memory";
42445       goto done;
42446     }
42447     for (size_t i = 0; i < quirks.repr.len; i++) {
42448       dec->set_quirk_enabled(quirks.repr.ptr[i], true);
42449     }
42450 
42451     // Prepare the wuffs_base__tok_buffer. 256 tokens is 2KiB.
42452     wuffs_base__token tok_array[256];
42453     wuffs_base__token_buffer tok_buf =
42454         wuffs_base__slice_token__writer(wuffs_base__make_slice_token(
42455             &tok_array[0], (sizeof(tok_array) / sizeof(tok_array[0]))));
42456     wuffs_base__status tok_status = wuffs_base__make_status(nullptr);
42457 
42458     // Prepare other state.
42459     int32_t depth = 0;
42460     std::string str;
42461     int64_t extension_category = 0;
42462     uint64_t extension_detail = 0;
42463 
42464     // Valid token's VBCs range in 0 ..= 15. Values over that are for tokens
42465     // from outside of the base package, such as the CBOR package.
42466     constexpr int64_t EXT_CAT__CBOR_TAG = 16;
42467 
42468     // Loop, doing these two things:
42469     //  1. Get the next token.
42470     //  2. Process that token.
42471     while (true) {
42472       // 1. Get the next token.
42473 
42474       while (tok_buf.meta.ri >= tok_buf.meta.wi) {
42475         if (tok_status.repr == nullptr) {
42476           // No-op.
42477         } else if (tok_status.repr == wuffs_base__suspension__short_write) {
42478           tok_buf.compact();
42479         } else if (tok_status.repr == wuffs_base__suspension__short_read) {
42480           // Read from input to io_buf.
42481           if (!io_error_message.empty()) {
42482             ret_error_message = std::move(io_error_message);
42483             goto done;
42484           } else if (cursor_index != io_buf->meta.ri) {
42485             ret_error_message =
42486                 "wuffs_aux::DecodeCbor: internal error: bad cursor_index";
42487             goto done;
42488           } else if (io_buf->meta.closed) {
42489             ret_error_message =
42490                 "wuffs_aux::DecodeCbor: internal error: io_buf is closed";
42491             goto done;
42492           }
42493           io_buf->compact();
42494           if (io_buf->meta.wi >= io_buf->data.len) {
42495             ret_error_message =
42496                 "wuffs_aux::DecodeCbor: internal error: io_buf is full";
42497             goto done;
42498           }
42499           cursor_index = io_buf->meta.ri;
42500           io_error_message = input.CopyIn(io_buf);
42501         } else {
42502           ret_error_message = tok_status.message();
42503           goto done;
42504         }
42505 
42506         if (WUFFS_CBOR__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE != 0) {
42507           ret_error_message =
42508               "wuffs_aux::DecodeCbor: internal error: bad WORKBUF_LEN";
42509           goto done;
42510         }
42511         wuffs_base__slice_u8 work_buf = wuffs_base__empty_slice_u8();
42512         tok_status = dec->decode_tokens(&tok_buf, io_buf, work_buf);
42513         if ((tok_buf.meta.ri > tok_buf.meta.wi) ||
42514             (tok_buf.meta.wi > tok_buf.data.len) ||
42515             (io_buf->meta.ri > io_buf->meta.wi) ||
42516             (io_buf->meta.wi > io_buf->data.len)) {
42517           ret_error_message =
42518               "wuffs_aux::DecodeCbor: internal error: bad buffer indexes";
42519           goto done;
42520         }
42521       }
42522 
42523       wuffs_base__token token = tok_buf.data.ptr[tok_buf.meta.ri++];
42524       uint64_t token_len = token.length();
42525       if ((io_buf->meta.ri < cursor_index) ||
42526           ((io_buf->meta.ri - cursor_index) < token_len)) {
42527         ret_error_message =
42528             "wuffs_aux::DecodeCbor: internal error: bad token indexes";
42529         goto done;
42530       }
42531       uint8_t* token_ptr = io_buf->data.ptr + cursor_index;
42532       cursor_index += static_cast<size_t>(token_len);
42533 
42534       // 2. Process that token.
42535 
42536       uint64_t vbd = token.value_base_detail();
42537 
42538       if (extension_category != 0) {
42539         int64_t ext = token.value_extension();
42540         if ((ext >= 0) && !token.continued()) {
42541           extension_detail = (extension_detail
42542                               << WUFFS_BASE__TOKEN__VALUE_EXTENSION__NUM_BITS) |
42543                              static_cast<uint64_t>(ext);
42544           switch (extension_category) {
42545             case WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_SIGNED:
42546               extension_category = 0;
42547               ret_error_message =
42548                   callbacks.AppendI64(static_cast<int64_t>(extension_detail));
42549               goto parsed_a_value;
42550             case WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_UNSIGNED:
42551               extension_category = 0;
42552               ret_error_message = callbacks.AppendU64(extension_detail);
42553               goto parsed_a_value;
42554             case EXT_CAT__CBOR_TAG:
42555               extension_category = 0;
42556               ret_error_message = callbacks.AppendCborTag(extension_detail);
42557               if (!ret_error_message.empty()) {
42558                 goto done;
42559               }
42560               continue;
42561           }
42562         }
42563         ret_error_message =
42564             "wuffs_aux::DecodeCbor: internal error: bad extended token";
42565         goto done;
42566       }
42567 
42568       switch (token.value_base_category()) {
42569         case WUFFS_BASE__TOKEN__VBC__FILLER:
42570           continue;
42571 
42572         case WUFFS_BASE__TOKEN__VBC__STRUCTURE: {
42573           if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {
42574             ret_error_message = callbacks.Push(static_cast<uint32_t>(vbd));
42575             if (!ret_error_message.empty()) {
42576               goto done;
42577             }
42578             depth++;
42579             if (depth > WUFFS_CBOR__DECODER_DEPTH_MAX_INCL) {
42580               ret_error_message =
42581                   "wuffs_aux::DecodeCbor: internal error: bad depth";
42582               goto done;
42583             }
42584             continue;
42585           }
42586           ret_error_message = callbacks.Pop(static_cast<uint32_t>(vbd));
42587           depth--;
42588           if (depth < 0) {
42589             ret_error_message =
42590                 "wuffs_aux::DecodeCbor: internal error: bad depth";
42591             goto done;
42592           }
42593           goto parsed_a_value;
42594         }
42595 
42596         case WUFFS_BASE__TOKEN__VBC__STRING: {
42597           if (vbd & WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_0_DST_1_SRC_DROP) {
42598             // No-op.
42599           } else if (vbd &
42600                      WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_1_SRC_COPY) {
42601             const char* ptr =  // Convert from (uint8_t*).
42602                 static_cast<const char*>(static_cast<void*>(token_ptr));
42603             str.append(ptr, static_cast<size_t>(token_len));
42604           } else {
42605             goto fail;
42606           }
42607           if (token.continued()) {
42608             continue;
42609           }
42610           ret_error_message =
42611               (vbd & WUFFS_BASE__TOKEN__VBD__STRING__CHAIN_MUST_BE_UTF_8)
42612                   ? callbacks.AppendTextString(std::move(str))
42613                   : callbacks.AppendByteString(std::move(str));
42614           str.clear();
42615           goto parsed_a_value;
42616         }
42617 
42618         case WUFFS_BASE__TOKEN__VBC__UNICODE_CODE_POINT: {
42619           uint8_t u[WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL];
42620           size_t n = wuffs_base__utf_8__encode(
42621               wuffs_base__make_slice_u8(
42622                   &u[0], WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL),
42623               static_cast<uint32_t>(vbd));
42624           const char* ptr =  // Convert from (uint8_t*).
42625               static_cast<const char*>(static_cast<void*>(&u[0]));
42626           str.append(ptr, n);
42627           if (token.continued()) {
42628             continue;
42629           }
42630           goto fail;
42631         }
42632 
42633         case WUFFS_BASE__TOKEN__VBC__LITERAL: {
42634           if (vbd & WUFFS_BASE__TOKEN__VBD__LITERAL__NULL) {
42635             ret_error_message = callbacks.AppendNull();
42636           } else if (vbd & WUFFS_BASE__TOKEN__VBD__LITERAL__UNDEFINED) {
42637             ret_error_message = callbacks.AppendUndefined();
42638           } else {
42639             ret_error_message = callbacks.AppendBool(
42640                 vbd & WUFFS_BASE__TOKEN__VBD__LITERAL__TRUE);
42641           }
42642           goto parsed_a_value;
42643         }
42644 
42645         case WUFFS_BASE__TOKEN__VBC__NUMBER: {
42646           const uint64_t cfp_fbbe_fifb =
42647               WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_FLOATING_POINT |
42648               WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_BINARY_BIG_ENDIAN |
42649               WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_IGNORE_FIRST_BYTE;
42650           if ((vbd & cfp_fbbe_fifb) == cfp_fbbe_fifb) {
42651             double f;
42652             switch (token_len) {
42653               case 3:
42654                 f = wuffs_base__ieee_754_bit_representation__from_u16_to_f64(
42655                     wuffs_base__peek_u16be__no_bounds_check(token_ptr + 1));
42656                 break;
42657               case 5:
42658                 f = wuffs_base__ieee_754_bit_representation__from_u32_to_f64(
42659                     wuffs_base__peek_u32be__no_bounds_check(token_ptr + 1));
42660                 break;
42661               case 9:
42662                 f = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
42663                     wuffs_base__peek_u64be__no_bounds_check(token_ptr + 1));
42664                 break;
42665               default:
42666                 goto fail;
42667             }
42668             ret_error_message = callbacks.AppendF64(f);
42669             goto parsed_a_value;
42670           }
42671           goto fail;
42672         }
42673 
42674         case WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_SIGNED: {
42675           if (token.continued()) {
42676             extension_category = WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_SIGNED;
42677             extension_detail =
42678                 static_cast<uint64_t>(token.value_base_detail__sign_extended());
42679             continue;
42680           }
42681           ret_error_message =
42682               callbacks.AppendI64(token.value_base_detail__sign_extended());
42683           goto parsed_a_value;
42684         }
42685 
42686         case WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_UNSIGNED: {
42687           if (token.continued()) {
42688             extension_category =
42689                 WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_UNSIGNED;
42690             extension_detail = vbd;
42691             continue;
42692           }
42693           ret_error_message = callbacks.AppendU64(vbd);
42694           goto parsed_a_value;
42695         }
42696       }
42697 
42698       if (token.value_major() == WUFFS_CBOR__TOKEN_VALUE_MAJOR) {
42699         uint64_t value_minor = token.value_minor();
42700         if (value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__MINUS_1_MINUS_X) {
42701           if (token_len == 9) {
42702             ret_error_message = callbacks.AppendMinus1MinusX(
42703                 wuffs_base__peek_u64be__no_bounds_check(token_ptr + 1));
42704             goto parsed_a_value;
42705           }
42706         } else if (value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__SIMPLE_VALUE) {
42707           ret_error_message =
42708               callbacks.AppendCborSimpleValue(static_cast<uint8_t>(
42709                   value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__DETAIL_MASK));
42710           goto parsed_a_value;
42711         } else if (value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__TAG) {
42712           if (token.continued()) {
42713             extension_category = EXT_CAT__CBOR_TAG;
42714             extension_detail =
42715                 value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__DETAIL_MASK;
42716             continue;
42717           }
42718           ret_error_message = callbacks.AppendCborTag(
42719               value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__DETAIL_MASK);
42720           if (!ret_error_message.empty()) {
42721             goto done;
42722           }
42723           continue;
42724         }
42725       }
42726 
42727     fail:
42728       ret_error_message =
42729           "wuffs_aux::DecodeCbor: internal error: unexpected token";
42730       goto done;
42731 
42732     parsed_a_value:
42733       if (!ret_error_message.empty() || (depth == 0)) {
42734         goto done;
42735       }
42736     }
42737   } while (false);
42738 
42739 done:
42740   DecodeCborResult result(
42741       std::move(ret_error_message),
42742       wuffs_base__u64__sat_add(io_buf->meta.pos, cursor_index));
42743   callbacks.Done(result, input, *io_buf);
42744   return result;
42745 }
42746 
42747 }  // namespace wuffs_aux
42748 
42749 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
42750         // defined(WUFFS_CONFIG__MODULE__AUX__CBOR)
42751 
42752 // ---------------- Auxiliary - Image
42753 
42754 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__AUX__IMAGE)
42755 
42756 #include <utility>
42757 
42758 namespace wuffs_aux {
42759 
DecodeImageResult(MemOwner && pixbuf_mem_owner0,wuffs_base__pixel_buffer pixbuf0,std::string && error_message0)42760 DecodeImageResult::DecodeImageResult(MemOwner&& pixbuf_mem_owner0,
42761                                      wuffs_base__pixel_buffer pixbuf0,
42762                                      std::string&& error_message0)
42763     : pixbuf_mem_owner(std::move(pixbuf_mem_owner0)),
42764       pixbuf(pixbuf0),
42765       error_message(std::move(error_message0)) {}
42766 
DecodeImageResult(std::string && error_message0)42767 DecodeImageResult::DecodeImageResult(std::string&& error_message0)
42768     : pixbuf_mem_owner(nullptr, &free),
42769       pixbuf(wuffs_base__null_pixel_buffer()),
42770       error_message(std::move(error_message0)) {}
42771 
~DecodeImageCallbacks()42772 DecodeImageCallbacks::~DecodeImageCallbacks() {}
42773 
AllocPixbufResult(MemOwner && mem_owner0,wuffs_base__pixel_buffer pixbuf0)42774 DecodeImageCallbacks::AllocPixbufResult::AllocPixbufResult(
42775     MemOwner&& mem_owner0,
42776     wuffs_base__pixel_buffer pixbuf0)
42777     : mem_owner(std::move(mem_owner0)), pixbuf(pixbuf0), error_message("") {}
42778 
AllocPixbufResult(std::string && error_message0)42779 DecodeImageCallbacks::AllocPixbufResult::AllocPixbufResult(
42780     std::string&& error_message0)
42781     : mem_owner(nullptr, &free),
42782       pixbuf(wuffs_base__null_pixel_buffer()),
42783       error_message(std::move(error_message0)) {}
42784 
AllocWorkbufResult(MemOwner && mem_owner0,wuffs_base__slice_u8 workbuf0)42785 DecodeImageCallbacks::AllocWorkbufResult::AllocWorkbufResult(
42786     MemOwner&& mem_owner0,
42787     wuffs_base__slice_u8 workbuf0)
42788     : mem_owner(std::move(mem_owner0)), workbuf(workbuf0), error_message("") {}
42789 
AllocWorkbufResult(std::string && error_message0)42790 DecodeImageCallbacks::AllocWorkbufResult::AllocWorkbufResult(
42791     std::string&& error_message0)
42792     : mem_owner(nullptr, &free),
42793       workbuf(wuffs_base__empty_slice_u8()),
42794       error_message(std::move(error_message0)) {}
42795 
42796 wuffs_base__image_decoder::unique_ptr  //
SelectDecoder(uint32_t fourcc,wuffs_base__slice_u8 prefix)42797 DecodeImageCallbacks::SelectDecoder(uint32_t fourcc,
42798                                     wuffs_base__slice_u8 prefix) {
42799   switch (fourcc) {
42800 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BMP)
42801     case WUFFS_BASE__FOURCC__BMP:
42802       return wuffs_bmp__decoder::alloc_as__wuffs_base__image_decoder();
42803 #endif
42804 
42805 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GIF)
42806     case WUFFS_BASE__FOURCC__GIF:
42807       return wuffs_gif__decoder::alloc_as__wuffs_base__image_decoder();
42808 #endif
42809 
42810 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NIE)
42811     case WUFFS_BASE__FOURCC__NIE:
42812       return wuffs_nie__decoder::alloc_as__wuffs_base__image_decoder();
42813 #endif
42814 
42815 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__PNG)
42816     case WUFFS_BASE__FOURCC__PNG: {
42817       auto dec = wuffs_png__decoder::alloc_as__wuffs_base__image_decoder();
42818       // Favor faster decodes over rejecting invalid checksums.
42819       dec->set_quirk_enabled(WUFFS_BASE__QUIRK_IGNORE_CHECKSUM, true);
42820       return dec;
42821     }
42822 #endif
42823 
42824 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP)
42825     case WUFFS_BASE__FOURCC__WBMP:
42826       return wuffs_wbmp__decoder::alloc_as__wuffs_base__image_decoder();
42827 #endif
42828   }
42829 
42830   return wuffs_base__image_decoder::unique_ptr(nullptr, &free);
42831 }
42832 
42833 std::string  //
HandleMetadata(const wuffs_base__more_information & minfo,wuffs_base__slice_u8 raw)42834 DecodeImageCallbacks::HandleMetadata(const wuffs_base__more_information& minfo,
42835                                      wuffs_base__slice_u8 raw) {
42836   return "";
42837 }
42838 
42839 wuffs_base__pixel_format  //
SelectPixfmt(const wuffs_base__image_config & image_config)42840 DecodeImageCallbacks::SelectPixfmt(
42841     const wuffs_base__image_config& image_config) {
42842   return wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL);
42843 }
42844 
42845 DecodeImageCallbacks::AllocPixbufResult  //
AllocPixbuf(const wuffs_base__image_config & image_config,bool allow_uninitialized_memory)42846 DecodeImageCallbacks::AllocPixbuf(const wuffs_base__image_config& image_config,
42847                                   bool allow_uninitialized_memory) {
42848   uint32_t w = image_config.pixcfg.width();
42849   uint32_t h = image_config.pixcfg.height();
42850   if ((w == 0) || (h == 0)) {
42851     return AllocPixbufResult("");
42852   }
42853   uint64_t len = image_config.pixcfg.pixbuf_len();
42854   if ((len == 0) || (SIZE_MAX < len)) {
42855     return AllocPixbufResult(DecodeImage_UnsupportedPixelConfiguration);
42856   }
42857   void* ptr =
42858       allow_uninitialized_memory ? malloc((size_t)len) : calloc((size_t)len, 1);
42859   if (!ptr) {
42860     return AllocPixbufResult(DecodeImage_OutOfMemory);
42861   }
42862   wuffs_base__pixel_buffer pixbuf;
42863   wuffs_base__status status = pixbuf.set_from_slice(
42864       &image_config.pixcfg,
42865       wuffs_base__make_slice_u8((uint8_t*)ptr, (size_t)len));
42866   if (!status.is_ok()) {
42867     free(ptr);
42868     return AllocPixbufResult(status.message());
42869   }
42870   return AllocPixbufResult(MemOwner(ptr, &free), pixbuf);
42871 }
42872 
42873 DecodeImageCallbacks::AllocWorkbufResult  //
AllocWorkbuf(wuffs_base__range_ii_u64 len_range,bool allow_uninitialized_memory)42874 DecodeImageCallbacks::AllocWorkbuf(wuffs_base__range_ii_u64 len_range,
42875                                    bool allow_uninitialized_memory) {
42876   uint64_t len = len_range.max_incl;
42877   if (len == 0) {
42878     return AllocWorkbufResult("");
42879   } else if (SIZE_MAX < len) {
42880     return AllocWorkbufResult(DecodeImage_OutOfMemory);
42881   }
42882   void* ptr =
42883       allow_uninitialized_memory ? malloc((size_t)len) : calloc((size_t)len, 1);
42884   if (!ptr) {
42885     return AllocWorkbufResult(DecodeImage_OutOfMemory);
42886   }
42887   return AllocWorkbufResult(
42888       MemOwner(ptr, &free),
42889       wuffs_base__make_slice_u8((uint8_t*)ptr, (size_t)len));
42890 }
42891 
42892 void  //
Done(DecodeImageResult & result,sync_io::Input & input,IOBuffer & buffer,wuffs_base__image_decoder::unique_ptr image_decoder)42893 DecodeImageCallbacks::Done(
42894     DecodeImageResult& result,
42895     sync_io::Input& input,
42896     IOBuffer& buffer,
42897     wuffs_base__image_decoder::unique_ptr image_decoder) {}
42898 
42899 const char DecodeImage_BufferIsTooShort[] =  //
42900     "wuffs_aux::DecodeImage: buffer is too short";
42901 const char DecodeImage_MaxInclDimensionExceeded[] =  //
42902     "wuffs_aux::DecodeImage: max_incl_dimension exceeded";
42903 const char DecodeImage_MaxInclMetadataLengthExceeded[] =  //
42904     "wuffs_aux::DecodeImage: max_incl_metadata_length exceeded";
42905 const char DecodeImage_OutOfMemory[] =  //
42906     "wuffs_aux::DecodeImage: out of memory";
42907 const char DecodeImage_UnexpectedEndOfFile[] =  //
42908     "wuffs_aux::DecodeImage: unexpected end of file";
42909 const char DecodeImage_UnsupportedImageFormat[] =  //
42910     "wuffs_aux::DecodeImage: unsupported image format";
42911 const char DecodeImage_UnsupportedMetadata[] =  //
42912     "wuffs_aux::DecodeImage: unsupported metadata";
42913 const char DecodeImage_UnsupportedPixelBlend[] =  //
42914     "wuffs_aux::DecodeImage: unsupported pixel blend";
42915 const char DecodeImage_UnsupportedPixelConfiguration[] =  //
42916     "wuffs_aux::DecodeImage: unsupported pixel configuration";
42917 const char DecodeImage_UnsupportedPixelFormat[] =  //
42918     "wuffs_aux::DecodeImage: unsupported pixel format";
42919 
DecodeImageArgQuirks(wuffs_base__slice_u32 repr0)42920 DecodeImageArgQuirks::DecodeImageArgQuirks(wuffs_base__slice_u32 repr0)
42921     : repr(repr0) {}
42922 
DecodeImageArgQuirks(uint32_t * ptr0,size_t len0)42923 DecodeImageArgQuirks::DecodeImageArgQuirks(uint32_t* ptr0, size_t len0)
42924     : repr(wuffs_base__make_slice_u32(ptr0, len0)) {}
42925 
42926 DecodeImageArgQuirks  //
DefaultValue()42927 DecodeImageArgQuirks::DefaultValue() {
42928   return DecodeImageArgQuirks(wuffs_base__empty_slice_u32());
42929 }
42930 
DecodeImageArgFlags(uint64_t repr0)42931 DecodeImageArgFlags::DecodeImageArgFlags(uint64_t repr0) : repr(repr0) {}
42932 
42933 DecodeImageArgFlags  //
DefaultValue()42934 DecodeImageArgFlags::DefaultValue() {
42935   return DecodeImageArgFlags(0);
42936 }
42937 
DecodeImageArgPixelBlend(wuffs_base__pixel_blend repr0)42938 DecodeImageArgPixelBlend::DecodeImageArgPixelBlend(
42939     wuffs_base__pixel_blend repr0)
42940     : repr(repr0) {}
42941 
42942 DecodeImageArgPixelBlend  //
DefaultValue()42943 DecodeImageArgPixelBlend::DefaultValue() {
42944   return DecodeImageArgPixelBlend(WUFFS_BASE__PIXEL_BLEND__SRC);
42945 }
42946 
DecodeImageArgBackgroundColor(wuffs_base__color_u32_argb_premul repr0)42947 DecodeImageArgBackgroundColor::DecodeImageArgBackgroundColor(
42948     wuffs_base__color_u32_argb_premul repr0)
42949     : repr(repr0) {}
42950 
42951 DecodeImageArgBackgroundColor  //
DefaultValue()42952 DecodeImageArgBackgroundColor::DefaultValue() {
42953   return DecodeImageArgBackgroundColor(1);
42954 }
42955 
DecodeImageArgMaxInclDimension(uint32_t repr0)42956 DecodeImageArgMaxInclDimension::DecodeImageArgMaxInclDimension(uint32_t repr0)
42957     : repr(repr0) {}
42958 
42959 DecodeImageArgMaxInclDimension  //
DefaultValue()42960 DecodeImageArgMaxInclDimension::DefaultValue() {
42961   return DecodeImageArgMaxInclDimension(1048575);
42962 }
42963 
DecodeImageArgMaxInclMetadataLength(uint64_t repr0)42964 DecodeImageArgMaxInclMetadataLength::DecodeImageArgMaxInclMetadataLength(
42965     uint64_t repr0)
42966     : repr(repr0) {}
42967 
42968 DecodeImageArgMaxInclMetadataLength  //
DefaultValue()42969 DecodeImageArgMaxInclMetadataLength::DefaultValue() {
42970   return DecodeImageArgMaxInclMetadataLength(16777215);
42971 }
42972 
42973 // --------
42974 
42975 namespace {
42976 
42977 const private_impl::ErrorMessages DecodeImageErrorMessages = {
42978     DecodeImage_MaxInclMetadataLengthExceeded,  //
42979     DecodeImage_OutOfMemory,                    //
42980     DecodeImage_UnexpectedEndOfFile,            //
42981     DecodeImage_UnsupportedMetadata,            //
42982     DecodeImage_UnsupportedImageFormat,         //
42983 };
42984 
42985 std::string  //
DecodeImageAdvanceIOBufferTo(sync_io::Input & input,wuffs_base__io_buffer & io_buf,uint64_t absolute_position)42986 DecodeImageAdvanceIOBufferTo(sync_io::Input& input,
42987                              wuffs_base__io_buffer& io_buf,
42988                              uint64_t absolute_position) {
42989   return private_impl::AdvanceIOBufferTo(DecodeImageErrorMessages, input,
42990                                          io_buf, absolute_position);
42991 }
42992 
42993 wuffs_base__status  //
DIHM0(void * self,wuffs_base__io_buffer * a_dst,wuffs_base__more_information * a_minfo,wuffs_base__io_buffer * a_src)42994 DIHM0(void* self,
42995       wuffs_base__io_buffer* a_dst,
42996       wuffs_base__more_information* a_minfo,
42997       wuffs_base__io_buffer* a_src) {
42998   return wuffs_base__image_decoder__tell_me_more(
42999       static_cast<wuffs_base__image_decoder*>(self), a_dst, a_minfo, a_src);
43000 }
43001 
43002 std::string  //
DIHM1(void * self,const wuffs_base__more_information * minfo,wuffs_base__slice_u8 raw)43003 DIHM1(void* self,
43004       const wuffs_base__more_information* minfo,
43005       wuffs_base__slice_u8 raw) {
43006   return static_cast<DecodeImageCallbacks*>(self)->HandleMetadata(*minfo, raw);
43007 }
43008 
43009 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)43010 DecodeImageHandleMetadata(wuffs_base__image_decoder::unique_ptr& image_decoder,
43011                           DecodeImageCallbacks& callbacks,
43012                           sync_io::Input& input,
43013                           wuffs_base__io_buffer& io_buf,
43014                           sync_io::DynIOBuffer& raw_metadata_buf) {
43015   return private_impl::HandleMetadata(DecodeImageErrorMessages, input, io_buf,
43016                                       raw_metadata_buf, DIHM0,
43017                                       static_cast<void*>(image_decoder.get()),
43018                                       DIHM1, static_cast<void*>(&callbacks));
43019 }
43020 
43021 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)43022 DecodeImage0(wuffs_base__image_decoder::unique_ptr& image_decoder,
43023              DecodeImageCallbacks& callbacks,
43024              sync_io::Input& input,
43025              wuffs_base__io_buffer& io_buf,
43026              wuffs_base__slice_u32 quirks,
43027              uint64_t flags,
43028              wuffs_base__pixel_blend pixel_blend,
43029              wuffs_base__color_u32_argb_premul background_color,
43030              uint32_t max_incl_dimension,
43031              uint64_t max_incl_metadata_length) {
43032   // Check args.
43033   switch (pixel_blend) {
43034     case WUFFS_BASE__PIXEL_BLEND__SRC:
43035     case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
43036       break;
43037     default:
43038       return DecodeImageResult(DecodeImage_UnsupportedPixelBlend);
43039   }
43040 
43041   wuffs_base__image_config image_config = wuffs_base__null_image_config();
43042   sync_io::DynIOBuffer raw_metadata_buf(max_incl_metadata_length);
43043   uint64_t start_pos = io_buf.reader_position();
43044   bool redirected = false;
43045   int32_t fourcc = 0;
43046 redirect:
43047   do {
43048     // Determine the image format.
43049     if (!redirected) {
43050       while (true) {
43051         fourcc = wuffs_base__magic_number_guess_fourcc(io_buf.reader_slice());
43052         if (fourcc > 0) {
43053           break;
43054         } else if ((fourcc == 0) && (io_buf.reader_length() >= 64)) {
43055           break;
43056         } else if (io_buf.meta.closed || (io_buf.writer_length() == 0)) {
43057           fourcc = 0;
43058           break;
43059         }
43060         std::string error_message = input.CopyIn(&io_buf);
43061         if (!error_message.empty()) {
43062           return DecodeImageResult(std::move(error_message));
43063         }
43064       }
43065     } else {
43066       wuffs_base__io_buffer empty = wuffs_base__empty_io_buffer();
43067       wuffs_base__more_information minfo = wuffs_base__empty_more_information();
43068       wuffs_base__status tmm_status =
43069           image_decoder->tell_me_more(&empty, &minfo, &io_buf);
43070       if (tmm_status.repr != nullptr) {
43071         return DecodeImageResult(tmm_status.message());
43072       }
43073       if (minfo.flavor != WUFFS_BASE__MORE_INFORMATION__FLAVOR__IO_REDIRECT) {
43074         return DecodeImageResult(DecodeImage_UnsupportedImageFormat);
43075       }
43076       uint64_t pos = minfo.io_redirect__range().min_incl;
43077       if (pos <= start_pos) {
43078         // Redirects must go forward.
43079         return DecodeImageResult(DecodeImage_UnsupportedImageFormat);
43080       }
43081       std::string error_message =
43082           DecodeImageAdvanceIOBufferTo(input, io_buf, pos);
43083       if (!error_message.empty()) {
43084         return DecodeImageResult(std::move(error_message));
43085       }
43086       fourcc = (int32_t)(minfo.io_redirect__fourcc());
43087       if (fourcc == 0) {
43088         return DecodeImageResult(DecodeImage_UnsupportedImageFormat);
43089       }
43090       image_decoder.reset();
43091     }
43092 
43093     // Select the image decoder.
43094     image_decoder = callbacks.SelectDecoder(
43095         (uint32_t)fourcc,
43096         fourcc ? wuffs_base__empty_slice_u8() : io_buf.reader_slice());
43097     if (!image_decoder) {
43098       return DecodeImageResult(DecodeImage_UnsupportedImageFormat);
43099     }
43100 
43101     // Apply quirks.
43102     for (size_t i = 0; i < quirks.len; i++) {
43103       image_decoder->set_quirk_enabled(quirks.ptr[i], true);
43104     }
43105 
43106     // Apply flags.
43107     if (flags != 0) {
43108       if (flags & DecodeImageArgFlags::REPORT_METADATA_CHRM) {
43109         image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__CHRM, true);
43110       }
43111       if (flags & DecodeImageArgFlags::REPORT_METADATA_GAMA) {
43112         image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__GAMA, true);
43113       }
43114       if (flags & DecodeImageArgFlags::REPORT_METADATA_ICCP) {
43115         image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__ICCP, true);
43116       }
43117       if (flags & DecodeImageArgFlags::REPORT_METADATA_KVP) {
43118         image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__KVP, true);
43119       }
43120       if (flags & DecodeImageArgFlags::REPORT_METADATA_SRGB) {
43121         image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__SRGB, true);
43122       }
43123       if (flags & DecodeImageArgFlags::REPORT_METADATA_XMP) {
43124         image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__XMP, true);
43125       }
43126     }
43127 
43128     // Decode the image config.
43129     while (true) {
43130       wuffs_base__status id_dic_status =
43131           image_decoder->decode_image_config(&image_config, &io_buf);
43132       if (id_dic_status.repr == nullptr) {
43133         break;
43134       } else if (id_dic_status.repr == wuffs_base__note__i_o_redirect) {
43135         if (redirected) {
43136           return DecodeImageResult(DecodeImage_UnsupportedImageFormat);
43137         }
43138         redirected = true;
43139         goto redirect;
43140       } else if (id_dic_status.repr == wuffs_base__note__metadata_reported) {
43141         std::string error_message = DecodeImageHandleMetadata(
43142             image_decoder, callbacks, input, io_buf, raw_metadata_buf);
43143         if (!error_message.empty()) {
43144           return DecodeImageResult(std::move(error_message));
43145         }
43146       } else if (id_dic_status.repr != wuffs_base__suspension__short_read) {
43147         return DecodeImageResult(id_dic_status.message());
43148       } else if (io_buf.meta.closed) {
43149         return DecodeImageResult(DecodeImage_UnexpectedEndOfFile);
43150       } else {
43151         std::string error_message = input.CopyIn(&io_buf);
43152         if (!error_message.empty()) {
43153           return DecodeImageResult(std::move(error_message));
43154         }
43155       }
43156     }
43157   } while (false);
43158   raw_metadata_buf.drop();
43159 
43160   // Select the pixel format.
43161   uint32_t w = image_config.pixcfg.width();
43162   uint32_t h = image_config.pixcfg.height();
43163   if ((w > max_incl_dimension) || (h > max_incl_dimension)) {
43164     return DecodeImageResult(DecodeImage_MaxInclDimensionExceeded);
43165   }
43166   wuffs_base__pixel_format pixel_format = callbacks.SelectPixfmt(image_config);
43167   if (pixel_format.repr != image_config.pixcfg.pixel_format().repr) {
43168     switch (pixel_format.repr) {
43169       case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
43170       case WUFFS_BASE__PIXEL_FORMAT__BGR:
43171       case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
43172       case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
43173       case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
43174       case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
43175       case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
43176         break;
43177       default:
43178         return DecodeImageResult(DecodeImage_UnsupportedPixelFormat);
43179     }
43180     image_config.pixcfg.set(pixel_format.repr,
43181                             WUFFS_BASE__PIXEL_SUBSAMPLING__NONE, w, h);
43182   }
43183 
43184   // Allocate the pixel buffer.
43185   bool valid_background_color =
43186       wuffs_base__color_u32_argb_premul__is_valid(background_color);
43187   DecodeImageCallbacks::AllocPixbufResult alloc_pixbuf_result =
43188       callbacks.AllocPixbuf(image_config, valid_background_color);
43189   if (!alloc_pixbuf_result.error_message.empty()) {
43190     return DecodeImageResult(std::move(alloc_pixbuf_result.error_message));
43191   }
43192   wuffs_base__pixel_buffer pixel_buffer = alloc_pixbuf_result.pixbuf;
43193   if (valid_background_color) {
43194     wuffs_base__status pb_scufr_status = pixel_buffer.set_color_u32_fill_rect(
43195         pixel_buffer.pixcfg.bounds(), background_color);
43196     if (pb_scufr_status.repr != nullptr) {
43197       return DecodeImageResult(pb_scufr_status.message());
43198     }
43199   }
43200 
43201   // Allocate the work buffer. Wuffs' decoders conventionally assume that this
43202   // can be uninitialized memory.
43203   wuffs_base__range_ii_u64 workbuf_len = image_decoder->workbuf_len();
43204   DecodeImageCallbacks::AllocWorkbufResult alloc_workbuf_result =
43205       callbacks.AllocWorkbuf(workbuf_len, true);
43206   if (!alloc_workbuf_result.error_message.empty()) {
43207     return DecodeImageResult(std::move(alloc_workbuf_result.error_message));
43208   } else if (alloc_workbuf_result.workbuf.len < workbuf_len.min_incl) {
43209     return DecodeImageResult(DecodeImage_BufferIsTooShort);
43210   }
43211 
43212   // Decode the frame config.
43213   wuffs_base__frame_config frame_config = wuffs_base__null_frame_config();
43214   while (true) {
43215     wuffs_base__status id_dfc_status =
43216         image_decoder->decode_frame_config(&frame_config, &io_buf);
43217     if (id_dfc_status.repr == nullptr) {
43218       break;
43219     } else if (id_dfc_status.repr != wuffs_base__suspension__short_read) {
43220       return DecodeImageResult(id_dfc_status.message());
43221     } else if (io_buf.meta.closed) {
43222       return DecodeImageResult(DecodeImage_UnexpectedEndOfFile);
43223     } else {
43224       std::string error_message = input.CopyIn(&io_buf);
43225       if (!error_message.empty()) {
43226         return DecodeImageResult(std::move(error_message));
43227       }
43228     }
43229   }
43230 
43231   // Decode the frame (the pixels).
43232   //
43233   // From here on, always returns the pixel_buffer. If we get this far, we can
43234   // still display a partial image, even if we encounter an error.
43235   std::string message("");
43236   if ((pixel_blend == WUFFS_BASE__PIXEL_BLEND__SRC_OVER) &&
43237       frame_config.overwrite_instead_of_blend()) {
43238     pixel_blend = WUFFS_BASE__PIXEL_BLEND__SRC;
43239   }
43240   while (true) {
43241     wuffs_base__status id_df_status =
43242         image_decoder->decode_frame(&pixel_buffer, &io_buf, pixel_blend,
43243                                     alloc_workbuf_result.workbuf, nullptr);
43244     if (id_df_status.repr == nullptr) {
43245       break;
43246     } else if (id_df_status.repr != wuffs_base__suspension__short_read) {
43247       message = id_df_status.message();
43248       break;
43249     } else if (io_buf.meta.closed) {
43250       message = DecodeImage_UnexpectedEndOfFile;
43251       break;
43252     } else {
43253       std::string error_message = input.CopyIn(&io_buf);
43254       if (!error_message.empty()) {
43255         message = std::move(error_message);
43256         break;
43257       }
43258     }
43259   }
43260   return DecodeImageResult(std::move(alloc_pixbuf_result.mem_owner),
43261                            pixel_buffer, std::move(message));
43262 }
43263 
43264 }  // namespace
43265 
43266 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)43267 DecodeImage(DecodeImageCallbacks& callbacks,
43268             sync_io::Input& input,
43269             DecodeImageArgQuirks quirks,
43270             DecodeImageArgFlags flags,
43271             DecodeImageArgPixelBlend pixel_blend,
43272             DecodeImageArgBackgroundColor background_color,
43273             DecodeImageArgMaxInclDimension max_incl_dimension,
43274             DecodeImageArgMaxInclMetadataLength max_incl_metadata_length) {
43275   wuffs_base__io_buffer* io_buf = input.BringsItsOwnIOBuffer();
43276   wuffs_base__io_buffer fallback_io_buf = wuffs_base__empty_io_buffer();
43277   std::unique_ptr<uint8_t[]> fallback_io_array(nullptr);
43278   if (!io_buf) {
43279     fallback_io_array = std::unique_ptr<uint8_t[]>(new uint8_t[32768]);
43280     fallback_io_buf =
43281         wuffs_base__ptr_u8__writer(fallback_io_array.get(), 32768);
43282     io_buf = &fallback_io_buf;
43283   }
43284 
43285   wuffs_base__image_decoder::unique_ptr image_decoder(nullptr, &free);
43286   DecodeImageResult result =
43287       DecodeImage0(image_decoder, callbacks, input, *io_buf, quirks.repr,
43288                    flags.repr, pixel_blend.repr, background_color.repr,
43289                    max_incl_dimension.repr, max_incl_metadata_length.repr);
43290   callbacks.Done(result, input, *io_buf, std::move(image_decoder));
43291   return result;
43292 }
43293 
43294 }  // namespace wuffs_aux
43295 
43296 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
43297         // defined(WUFFS_CONFIG__MODULE__AUX__IMAGE)
43298 
43299 // ---------------- Auxiliary - JSON
43300 
43301 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__AUX__JSON)
43302 
43303 #include <utility>
43304 
43305 namespace wuffs_aux {
43306 
DecodeJsonResult(std::string && error_message0,uint64_t cursor_position0)43307 DecodeJsonResult::DecodeJsonResult(std::string&& error_message0,
43308                                    uint64_t cursor_position0)
43309     : error_message(std::move(error_message0)),
43310       cursor_position(cursor_position0) {}
43311 
~DecodeJsonCallbacks()43312 DecodeJsonCallbacks::~DecodeJsonCallbacks() {}
43313 
43314 void  //
Done(DecodeJsonResult & result,sync_io::Input & input,IOBuffer & buffer)43315 DecodeJsonCallbacks::Done(DecodeJsonResult& result,
43316                           sync_io::Input& input,
43317                           IOBuffer& buffer) {}
43318 
43319 const char DecodeJson_BadJsonPointer[] =  //
43320     "wuffs_aux::DecodeJson: bad JSON Pointer";
43321 const char DecodeJson_NoMatch[] =  //
43322     "wuffs_aux::DecodeJson: no match";
43323 
DecodeJsonArgQuirks(wuffs_base__slice_u32 repr0)43324 DecodeJsonArgQuirks::DecodeJsonArgQuirks(wuffs_base__slice_u32 repr0)
43325     : repr(repr0) {}
43326 
DecodeJsonArgQuirks(uint32_t * ptr0,size_t len0)43327 DecodeJsonArgQuirks::DecodeJsonArgQuirks(uint32_t* ptr0, size_t len0)
43328     : repr(wuffs_base__make_slice_u32(ptr0, len0)) {}
43329 
43330 DecodeJsonArgQuirks  //
DefaultValue()43331 DecodeJsonArgQuirks::DefaultValue() {
43332   return DecodeJsonArgQuirks(wuffs_base__empty_slice_u32());
43333 }
43334 
DecodeJsonArgJsonPointer(std::string repr0)43335 DecodeJsonArgJsonPointer::DecodeJsonArgJsonPointer(std::string repr0)
43336     : repr(repr0) {}
43337 
43338 DecodeJsonArgJsonPointer  //
DefaultValue()43339 DecodeJsonArgJsonPointer::DefaultValue() {
43340   return DecodeJsonArgJsonPointer(std::string());
43341 }
43342 
43343 // --------
43344 
43345 #define WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN                          \
43346   while (tok_buf.meta.ri >= tok_buf.meta.wi) {                              \
43347     if (tok_status.repr == nullptr) {                                       \
43348       goto done;                                                            \
43349     } else if (tok_status.repr == wuffs_base__suspension__short_write) {    \
43350       tok_buf.compact();                                                    \
43351     } else if (tok_status.repr == wuffs_base__suspension__short_read) {     \
43352       if (!io_error_message.empty()) {                                      \
43353         ret_error_message = std::move(io_error_message);                    \
43354         goto done;                                                          \
43355       } else if (cursor_index != io_buf->meta.ri) {                         \
43356         ret_error_message =                                                 \
43357             "wuffs_aux::DecodeJson: internal error: bad cursor_index";      \
43358         goto done;                                                          \
43359       } else if (io_buf->meta.closed) {                                     \
43360         ret_error_message =                                                 \
43361             "wuffs_aux::DecodeJson: internal error: io_buf is closed";      \
43362         goto done;                                                          \
43363       }                                                                     \
43364       io_buf->compact();                                                    \
43365       if (io_buf->meta.wi >= io_buf->data.len) {                            \
43366         ret_error_message =                                                 \
43367             "wuffs_aux::DecodeJson: internal error: io_buf is full";        \
43368         goto done;                                                          \
43369       }                                                                     \
43370       cursor_index = io_buf->meta.ri;                                       \
43371       io_error_message = input.CopyIn(io_buf);                              \
43372     } else {                                                                \
43373       ret_error_message = tok_status.message();                             \
43374       goto done;                                                            \
43375     }                                                                       \
43376     tok_status =                                                            \
43377         dec->decode_tokens(&tok_buf, io_buf, wuffs_base__empty_slice_u8()); \
43378     if ((tok_buf.meta.ri > tok_buf.meta.wi) ||                              \
43379         (tok_buf.meta.wi > tok_buf.data.len) ||                             \
43380         (io_buf->meta.ri > io_buf->meta.wi) ||                              \
43381         (io_buf->meta.wi > io_buf->data.len)) {                             \
43382       ret_error_message =                                                   \
43383           "wuffs_aux::DecodeJson: internal error: bad buffer indexes";      \
43384       goto done;                                                            \
43385     }                                                                       \
43386   }                                                                         \
43387   wuffs_base__token token = tok_buf.data.ptr[tok_buf.meta.ri++];            \
43388   uint64_t token_len = token.length();                                      \
43389   if ((io_buf->meta.ri < cursor_index) ||                                   \
43390       ((io_buf->meta.ri - cursor_index) < token_len)) {                     \
43391     ret_error_message =                                                     \
43392         "wuffs_aux::DecodeJson: internal error: bad token indexes";         \
43393     goto done;                                                              \
43394   }                                                                         \
43395   uint8_t* token_ptr = io_buf->data.ptr + cursor_index;                     \
43396   (void)(token_ptr);                                                        \
43397   cursor_index += static_cast<size_t>(token_len)
43398 
43399 // --------
43400 
43401 namespace {
43402 
43403 // DecodeJson_SplitJsonPointer returns ("bar", 8) for ("/foo/bar/b~1z/qux", 5,
43404 // etc). It returns a 0 size_t when s has invalid JSON Pointer syntax or i is
43405 // out of bounds.
43406 //
43407 // The string returned is unescaped. If calling it again, this time with i=8,
43408 // the "b~1z" substring would be returned as "b/z".
43409 std::pair<std::string, size_t>  //
DecodeJson_SplitJsonPointer(std::string & s,size_t i,bool allow_tilde_n_tilde_r_tilde_t)43410 DecodeJson_SplitJsonPointer(std::string& s,
43411                             size_t i,
43412                             bool allow_tilde_n_tilde_r_tilde_t) {
43413   std::string fragment;
43414   if (i > s.size()) {
43415     return std::make_pair(std::string(), 0);
43416   }
43417   while (i < s.size()) {
43418     char c = s[i];
43419     if (c == '/') {
43420       break;
43421     } else if (c != '~') {
43422       fragment.push_back(c);
43423       i++;
43424       continue;
43425     }
43426     i++;
43427     if (i >= s.size()) {
43428       return std::make_pair(std::string(), 0);
43429     }
43430     c = s[i];
43431     if (c == '0') {
43432       fragment.push_back('~');
43433       i++;
43434       continue;
43435     } else if (c == '1') {
43436       fragment.push_back('/');
43437       i++;
43438       continue;
43439     } else if (allow_tilde_n_tilde_r_tilde_t) {
43440       if (c == 'n') {
43441         fragment.push_back('\n');
43442         i++;
43443         continue;
43444       } else if (c == 'r') {
43445         fragment.push_back('\r');
43446         i++;
43447         continue;
43448       } else if (c == 't') {
43449         fragment.push_back('\t');
43450         i++;
43451         continue;
43452       }
43453     }
43454     return std::make_pair(std::string(), 0);
43455   }
43456   return std::make_pair(std::move(fragment), i);
43457 }
43458 
43459 // --------
43460 
43461 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)43462 DecodeJson_WalkJsonPointerFragment(wuffs_base__token_buffer& tok_buf,
43463                                    wuffs_base__status& tok_status,
43464                                    wuffs_json__decoder::unique_ptr& dec,
43465                                    wuffs_base__io_buffer* io_buf,
43466                                    std::string& io_error_message,
43467                                    size_t& cursor_index,
43468                                    sync_io::Input& input,
43469                                    std::string& json_pointer_fragment) {
43470   std::string ret_error_message;
43471   while (true) {
43472     WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;
43473 
43474     int64_t vbc = token.value_base_category();
43475     uint64_t vbd = token.value_base_detail();
43476     if (vbc == WUFFS_BASE__TOKEN__VBC__FILLER) {
43477       continue;
43478     } else if ((vbc != WUFFS_BASE__TOKEN__VBC__STRUCTURE) ||
43479                !(vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH)) {
43480       return DecodeJson_NoMatch;
43481     } else if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_LIST) {
43482       goto do_list;
43483     }
43484     goto do_dict;
43485   }
43486 
43487 do_dict:
43488   // Alternate between these two things:
43489   //  1. Decode the next dict key (a string). If it matches the fragment, we're
43490   //    done (success). If we've reached the dict's end (VBD__STRUCTURE__POP)
43491   //    so that there was no next dict key, we're done (failure).
43492   //  2. Otherwise, skip the next dict value.
43493   while (true) {
43494     for (std::string str; true;) {
43495       WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;
43496 
43497       int64_t vbc = token.value_base_category();
43498       uint64_t vbd = token.value_base_detail();
43499       switch (vbc) {
43500         case WUFFS_BASE__TOKEN__VBC__FILLER:
43501           continue;
43502 
43503         case WUFFS_BASE__TOKEN__VBC__STRUCTURE:
43504           if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {
43505             goto fail;
43506           }
43507           return DecodeJson_NoMatch;
43508 
43509         case WUFFS_BASE__TOKEN__VBC__STRING: {
43510           if (vbd & WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_0_DST_1_SRC_DROP) {
43511             // No-op.
43512           } else if (vbd &
43513                      WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_1_SRC_COPY) {
43514             const char* ptr =  // Convert from (uint8_t*).
43515                 static_cast<const char*>(static_cast<void*>(token_ptr));
43516             str.append(ptr, static_cast<size_t>(token_len));
43517           } else {
43518             goto fail;
43519           }
43520           break;
43521         }
43522 
43523         case WUFFS_BASE__TOKEN__VBC__UNICODE_CODE_POINT: {
43524           uint8_t u[WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL];
43525           size_t n = wuffs_base__utf_8__encode(
43526               wuffs_base__make_slice_u8(
43527                   &u[0], WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL),
43528               static_cast<uint32_t>(vbd));
43529           const char* ptr =  // Convert from (uint8_t*).
43530               static_cast<const char*>(static_cast<void*>(&u[0]));
43531           str.append(ptr, n);
43532           break;
43533         }
43534 
43535         default:
43536           goto fail;
43537       }
43538 
43539       if (token.continued()) {
43540         continue;
43541       }
43542       if (str == json_pointer_fragment) {
43543         return "";
43544       }
43545       goto skip_the_next_dict_value;
43546     }
43547 
43548   skip_the_next_dict_value:
43549     for (uint32_t skip_depth = 0; true;) {
43550       WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;
43551 
43552       int64_t vbc = token.value_base_category();
43553       uint64_t vbd = token.value_base_detail();
43554       if (token.continued() || (vbc == WUFFS_BASE__TOKEN__VBC__FILLER)) {
43555         continue;
43556       } else if (vbc == WUFFS_BASE__TOKEN__VBC__STRUCTURE) {
43557         if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {
43558           skip_depth++;
43559           continue;
43560         }
43561         skip_depth--;
43562       }
43563 
43564       if (skip_depth == 0) {
43565         break;
43566       }
43567     }  // skip_the_next_dict_value
43568   }    // do_dict
43569 
43570 do_list:
43571   do {
43572     wuffs_base__result_u64 result_u64 = wuffs_base__parse_number_u64(
43573         wuffs_base__make_slice_u8(
43574             static_cast<uint8_t*>(static_cast<void*>(
43575                 const_cast<char*>(json_pointer_fragment.data()))),
43576             json_pointer_fragment.size()),
43577         WUFFS_BASE__PARSE_NUMBER_XXX__DEFAULT_OPTIONS);
43578     if (!result_u64.status.is_ok()) {
43579       return DecodeJson_NoMatch;
43580     }
43581     uint64_t remaining = result_u64.value;
43582     if (remaining == 0) {
43583       goto check_that_a_value_follows;
43584     }
43585     for (uint32_t skip_depth = 0; true;) {
43586       WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;
43587 
43588       int64_t vbc = token.value_base_category();
43589       uint64_t vbd = token.value_base_detail();
43590       if (token.continued() || (vbc == WUFFS_BASE__TOKEN__VBC__FILLER)) {
43591         continue;
43592       } else if (vbc == WUFFS_BASE__TOKEN__VBC__STRUCTURE) {
43593         if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {
43594           skip_depth++;
43595           continue;
43596         }
43597         if (skip_depth == 0) {
43598           return DecodeJson_NoMatch;
43599         }
43600         skip_depth--;
43601       }
43602 
43603       if (skip_depth > 0) {
43604         continue;
43605       }
43606       remaining--;
43607       if (remaining == 0) {
43608         goto check_that_a_value_follows;
43609       }
43610     }
43611   } while (false);  // do_list
43612 
43613 check_that_a_value_follows:
43614   while (true) {
43615     WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;
43616 
43617     int64_t vbc = token.value_base_category();
43618     uint64_t vbd = token.value_base_detail();
43619     if (vbc == WUFFS_BASE__TOKEN__VBC__FILLER) {
43620       continue;
43621     }
43622 
43623     // Undo the last part of WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN, so
43624     // that we're only peeking at the next token.
43625     tok_buf.meta.ri--;
43626     cursor_index -= static_cast<size_t>(token_len);
43627 
43628     if ((vbc == WUFFS_BASE__TOKEN__VBC__STRUCTURE) &&
43629         (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__POP)) {
43630       return DecodeJson_NoMatch;
43631     }
43632     return "";
43633   }  // check_that_a_value_follows
43634 
43635 fail:
43636   return "wuffs_aux::DecodeJson: internal error: unexpected token";
43637 done:
43638   return ret_error_message;
43639 }
43640 
43641 }  // namespace
43642 
43643 // --------
43644 
43645 DecodeJsonResult  //
DecodeJson(DecodeJsonCallbacks & callbacks,sync_io::Input & input,DecodeJsonArgQuirks quirks,DecodeJsonArgJsonPointer json_pointer)43646 DecodeJson(DecodeJsonCallbacks& callbacks,
43647            sync_io::Input& input,
43648            DecodeJsonArgQuirks quirks,
43649            DecodeJsonArgJsonPointer json_pointer) {
43650   // Prepare the wuffs_base__io_buffer and the resultant error_message.
43651   wuffs_base__io_buffer* io_buf = input.BringsItsOwnIOBuffer();
43652   wuffs_base__io_buffer fallback_io_buf = wuffs_base__empty_io_buffer();
43653   std::unique_ptr<uint8_t[]> fallback_io_array(nullptr);
43654   if (!io_buf) {
43655     fallback_io_array = std::unique_ptr<uint8_t[]>(new uint8_t[4096]);
43656     fallback_io_buf = wuffs_base__ptr_u8__writer(fallback_io_array.get(), 4096);
43657     io_buf = &fallback_io_buf;
43658   }
43659   // cursor_index is discussed at
43660   // https://nigeltao.github.io/blog/2020/jsonptr.html#the-cursor-index
43661   size_t cursor_index = 0;
43662   std::string ret_error_message;
43663   std::string io_error_message;
43664 
43665   do {
43666     // Prepare the low-level JSON decoder.
43667     wuffs_json__decoder::unique_ptr dec = wuffs_json__decoder::alloc();
43668     if (!dec) {
43669       ret_error_message = "wuffs_aux::DecodeJson: out of memory";
43670       goto done;
43671     } else if (WUFFS_JSON__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE != 0) {
43672       ret_error_message =
43673           "wuffs_aux::DecodeJson: internal error: bad WORKBUF_LEN";
43674       goto done;
43675     }
43676     bool allow_tilde_n_tilde_r_tilde_t = false;
43677     for (size_t i = 0; i < quirks.repr.len; i++) {
43678       dec->set_quirk_enabled(quirks.repr.ptr[i], true);
43679       if (quirks.repr.ptr[i] ==
43680           WUFFS_JSON__QUIRK_JSON_POINTER_ALLOW_TILDE_N_TILDE_R_TILDE_T) {
43681         allow_tilde_n_tilde_r_tilde_t = true;
43682       }
43683     }
43684 
43685     // Prepare the wuffs_base__tok_buffer. 256 tokens is 2KiB.
43686     wuffs_base__token tok_array[256];
43687     wuffs_base__token_buffer tok_buf =
43688         wuffs_base__slice_token__writer(wuffs_base__make_slice_token(
43689             &tok_array[0], (sizeof(tok_array) / sizeof(tok_array[0]))));
43690     wuffs_base__status tok_status =
43691         dec->decode_tokens(&tok_buf, io_buf, wuffs_base__empty_slice_u8());
43692 
43693     // Prepare other state.
43694     int32_t depth = 0;
43695     std::string str;
43696 
43697     // Walk the (optional) JSON Pointer.
43698     for (size_t i = 0; i < json_pointer.repr.size();) {
43699       if (json_pointer.repr[i] != '/') {
43700         ret_error_message = DecodeJson_BadJsonPointer;
43701         goto done;
43702       }
43703       std::pair<std::string, size_t> split = DecodeJson_SplitJsonPointer(
43704           json_pointer.repr, i + 1, allow_tilde_n_tilde_r_tilde_t);
43705       i = split.second;
43706       if (i == 0) {
43707         ret_error_message = DecodeJson_BadJsonPointer;
43708         goto done;
43709       }
43710       ret_error_message = DecodeJson_WalkJsonPointerFragment(
43711           tok_buf, tok_status, dec, io_buf, io_error_message, cursor_index,
43712           input, split.first);
43713       if (!ret_error_message.empty()) {
43714         goto done;
43715       }
43716     }
43717 
43718     // Loop, doing these two things:
43719     //  1. Get the next token.
43720     //  2. Process that token.
43721     while (true) {
43722       WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;
43723 
43724       int64_t vbc = token.value_base_category();
43725       uint64_t vbd = token.value_base_detail();
43726       switch (vbc) {
43727         case WUFFS_BASE__TOKEN__VBC__FILLER:
43728           continue;
43729 
43730         case WUFFS_BASE__TOKEN__VBC__STRUCTURE: {
43731           if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {
43732             ret_error_message = callbacks.Push(static_cast<uint32_t>(vbd));
43733             if (!ret_error_message.empty()) {
43734               goto done;
43735             }
43736             depth++;
43737             if (depth > WUFFS_JSON__DECODER_DEPTH_MAX_INCL) {
43738               ret_error_message =
43739                   "wuffs_aux::DecodeJson: internal error: bad depth";
43740               goto done;
43741             }
43742             continue;
43743           }
43744           ret_error_message = callbacks.Pop(static_cast<uint32_t>(vbd));
43745           depth--;
43746           if (depth < 0) {
43747             ret_error_message =
43748                 "wuffs_aux::DecodeJson: internal error: bad depth";
43749             goto done;
43750           }
43751           goto parsed_a_value;
43752         }
43753 
43754         case WUFFS_BASE__TOKEN__VBC__STRING: {
43755           if (vbd & WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_0_DST_1_SRC_DROP) {
43756             // No-op.
43757           } else if (vbd &
43758                      WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_1_SRC_COPY) {
43759             const char* ptr =  // Convert from (uint8_t*).
43760                 static_cast<const char*>(static_cast<void*>(token_ptr));
43761             str.append(ptr, static_cast<size_t>(token_len));
43762           } else {
43763             goto fail;
43764           }
43765           if (token.continued()) {
43766             continue;
43767           }
43768           ret_error_message = callbacks.AppendTextString(std::move(str));
43769           str.clear();
43770           goto parsed_a_value;
43771         }
43772 
43773         case WUFFS_BASE__TOKEN__VBC__UNICODE_CODE_POINT: {
43774           uint8_t u[WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL];
43775           size_t n = wuffs_base__utf_8__encode(
43776               wuffs_base__make_slice_u8(
43777                   &u[0], WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL),
43778               static_cast<uint32_t>(vbd));
43779           const char* ptr =  // Convert from (uint8_t*).
43780               static_cast<const char*>(static_cast<void*>(&u[0]));
43781           str.append(ptr, n);
43782           if (token.continued()) {
43783             continue;
43784           }
43785           goto fail;
43786         }
43787 
43788         case WUFFS_BASE__TOKEN__VBC__LITERAL: {
43789           ret_error_message =
43790               (vbd & WUFFS_BASE__TOKEN__VBD__LITERAL__NULL)
43791                   ? callbacks.AppendNull()
43792                   : callbacks.AppendBool(vbd &
43793                                          WUFFS_BASE__TOKEN__VBD__LITERAL__TRUE);
43794           goto parsed_a_value;
43795         }
43796 
43797         case WUFFS_BASE__TOKEN__VBC__NUMBER: {
43798           if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_TEXT) {
43799             if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_SIGNED) {
43800               wuffs_base__result_i64 r = wuffs_base__parse_number_i64(
43801                   wuffs_base__make_slice_u8(token_ptr,
43802                                             static_cast<size_t>(token_len)),
43803                   WUFFS_BASE__PARSE_NUMBER_XXX__DEFAULT_OPTIONS);
43804               if (r.status.is_ok()) {
43805                 ret_error_message = callbacks.AppendI64(r.value);
43806                 goto parsed_a_value;
43807               }
43808             }
43809             if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_FLOATING_POINT) {
43810               wuffs_base__result_f64 r = wuffs_base__parse_number_f64(
43811                   wuffs_base__make_slice_u8(token_ptr,
43812                                             static_cast<size_t>(token_len)),
43813                   WUFFS_BASE__PARSE_NUMBER_XXX__DEFAULT_OPTIONS);
43814               if (r.status.is_ok()) {
43815                 ret_error_message = callbacks.AppendF64(r.value);
43816                 goto parsed_a_value;
43817               }
43818             }
43819           } else if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_NEG_INF) {
43820             ret_error_message = callbacks.AppendF64(
43821                 wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
43822                     0xFFF0000000000000ul));
43823             goto parsed_a_value;
43824           } else if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_POS_INF) {
43825             ret_error_message = callbacks.AppendF64(
43826                 wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
43827                     0x7FF0000000000000ul));
43828             goto parsed_a_value;
43829           } else if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_NEG_NAN) {
43830             ret_error_message = callbacks.AppendF64(
43831                 wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
43832                     0xFFFFFFFFFFFFFFFFul));
43833             goto parsed_a_value;
43834           } else if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_POS_NAN) {
43835             ret_error_message = callbacks.AppendF64(
43836                 wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
43837                     0x7FFFFFFFFFFFFFFFul));
43838             goto parsed_a_value;
43839           }
43840           goto fail;
43841         }
43842       }
43843 
43844     fail:
43845       ret_error_message =
43846           "wuffs_aux::DecodeJson: internal error: unexpected token";
43847       goto done;
43848 
43849     parsed_a_value:
43850       // If an error was encountered, we are done. Otherwise, (depth == 0)
43851       // after parsing a value is equivalent to having decoded the entire JSON
43852       // value (for an empty json_pointer query) or having decoded the
43853       // pointed-to JSON value (for a non-empty json_pointer query). In the
43854       // latter case, we are also done.
43855       //
43856       // However, if quirks like WUFFS_JSON__QUIRK_ALLOW_TRAILING_FILLER or
43857       // WUFFS_JSON__QUIRK_EXPECT_TRAILING_NEW_LINE_OR_EOF are passed, decoding
43858       // the entire JSON value should also consume any trailing filler, in case
43859       // the DecodeJson caller wants to subsequently check that the input is
43860       // completely exhausted (and otherwise raise "valid JSON followed by
43861       // further (unexpected) data"). We aren't done yet. Instead, keep the
43862       // loop running until WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN's
43863       // decode_tokens returns an ok status.
43864       if (!ret_error_message.empty() ||
43865           ((depth == 0) && !json_pointer.repr.empty())) {
43866         goto done;
43867       }
43868     }
43869   } while (false);
43870 
43871 done:
43872   DecodeJsonResult result(
43873       std::move(ret_error_message),
43874       wuffs_base__u64__sat_add(io_buf->meta.pos, cursor_index));
43875   callbacks.Done(result, input, *io_buf);
43876   return result;
43877 }
43878 
43879 #undef WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN
43880 
43881 }  // namespace wuffs_aux
43882 
43883 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
43884         // defined(WUFFS_CONFIG__MODULE__AUX__JSON)
43885 
43886 #endif  // defined(__cplusplus) && defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
43887 
43888 #endif  // WUFFS_IMPLEMENTATION
43889 
43890 #if defined(__GNUC__)
43891 #pragma GCC diagnostic pop
43892 #elif defined(__clang__)
43893 #pragma clang diagnostic pop
43894 #endif
43895 
43896 #endif  // WUFFS_INCLUDE_GUARD
43897